diff --git a/src/battle.c b/src/battle.c index e06d45979..73c0a74ec 100644 --- a/src/battle.c +++ b/src/battle.c @@ -4235,6 +4235,52 @@ static void battle_flee(battle * b) } } +static bool is_enemy(battle *b, unit *u1, unit *u2) { + if (u1->faction != u2->faction) { + if (b) { + side *es, *s1 = 0, *s2 = 0; + for (es = b->sides; es != b->sides + b->nsides; ++es) { + if (!s1 && es->faction == u1->faction) s1 = es; + else if (!s2 && es->faction == u2->faction) s2 = es; + if (s1 && s2) break; + } + return enemy(s1, s2); + } + else { + return !help_enter(u1, u2); + } + } + return false; +} + +void force_leave(region *r, battle *b) { + unit *u; + + for (u = r->units; u; u = u->next) { + unit *uo = NULL; + if (u->building) { + uo = building_owner(u->building); + } + if (u->ship && r->land) { + uo = ship_owner(u->ship); + } + if (uo && is_enemy(b, uo, u)) { + message *msg = NULL; + if (u->building) { + msg = msg_message("force_leave_building", "unit owner building", u, uo, u->building); + } + else { + msg = msg_message("force_leave_ship", "unit owner ship", u, uo, u->ship); + } + if (msg) { + ADDMSG(&u->faction->msgs, msg); + } + leave(u, false); + } + } +} + + void do_battle(region * r) { battle *b = NULL; @@ -4307,7 +4353,7 @@ void do_battle(region * r) /* Auswirkungen berechnen: */ aftermath(b); if (rule_force_leave(FORCE_LEAVE_POSTCOMBAT)) { - force_leave(b->region); + force_leave(b->region, b); } /* Hier ist das Gefecht beendet, und wir können die * Hilfsstrukturen * wieder löschen: */ diff --git a/src/battle.h b/src/battle.h index 075edf496..8d29d733a 100644 --- a/src/battle.h +++ b/src/battle.h @@ -270,6 +270,7 @@ extern "C" { const struct group * g, unsigned int flags, const struct faction * stealthfaction); int skilldiff(troop at, troop dt, int dist); + void force_leave(struct region *r, struct battle *b); #ifdef __cplusplus } diff --git a/src/laws.c b/src/laws.c index 46c471cd5..fb4daa76f 100755 --- a/src/laws.c +++ b/src/laws.c @@ -4307,34 +4307,12 @@ static void enter_2(region * r) do_enter(r, 1); } -static bool help_enter(unit *uo, unit *u) { +bool help_enter(unit *uo, unit *u) { return uo->faction == u->faction || alliedunit(uo, u->faction, HELP_GUARD); } -void force_leave(region *r) { - unit *u; - for (u = r->units; u; u = u->next) { - unit *uo = NULL; - if (u->building) { - uo = building_owner(u->building); - } - if (u->ship && r->land) { - uo = ship_owner(u->ship); - } - if (uo && !help_enter(uo, u)) { - message *msg = NULL; - if (u->building) { - msg = msg_message("force_leave_building", "unit owner building", u, uo, u->building); - } - else { - msg = msg_message("force_leave_ship", "unit owner ship", u, uo, u->ship); - } - if (msg) { - ADDMSG(&u->faction->msgs, msg); - } - leave(u, false); - } - } +static void do_force_leave(region *r) { + force_leave(r, NULL); } bool rule_force_leave(int flags) { @@ -4450,7 +4428,7 @@ void init_processor(void) p += 10; /* rest rng again before economics */ if (rule_force_leave(FORCE_LEAVE_ALL)) { - add_proc_region(p, force_leave, "kick non-allies out of buildings/ships"); + add_proc_region(p, do_force_leave, "kick non-allies out of buildings/ships"); } add_proc_region(p, economics, "Zerstoeren, Geben, Rekrutieren, Vergessen"); add_proc_order(p, K_PROMOTION, promotion_cmd, 0, "Heldenbefoerderung"); diff --git a/src/laws.h b/src/laws.h index 6da5ed5de..7eec612e3 100755 --- a/src/laws.h +++ b/src/laws.h @@ -110,7 +110,7 @@ extern "C" { #define FORCE_LEAVE_POSTCOMBAT 1 #define FORCE_LEAVE_ALL 2 bool rule_force_leave(int flag); - void force_leave(struct region *r); + bool help_enter(struct unit *uo, struct unit *u); #ifdef __cplusplus } diff --git a/src/laws.test.c b/src/laws.test.c index 4c9f43ba5..8a02d6ef4 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1,5 +1,6 @@ #include #include "laws.h" +#include "battle.h" #include #include @@ -261,8 +262,8 @@ static void test_force_leave_buildings(CuTest *tc) { building_set_owner(u1); u_set_building(u2, b); u_set_building(u3, b); - force_leave(r); - CuAssertPtrEquals_Msg(tc, "owner should not be forecd to leave", b, u1->building); + force_leave(r, NULL); + CuAssertPtrEquals_Msg(tc, "owner should not be forced to leave", b, u1->building); CuAssertPtrEquals_Msg(tc, "same faction should not be forced to leave", b, u2->building); CuAssertPtrEquals_Msg(tc, "non-allies should be forced to leave", NULL, u3->building); msg = test_get_last_message(u3->faction->msgs); @@ -271,7 +272,7 @@ static void test_force_leave_buildings(CuTest *tc) { u_set_building(u3, b); al = ally_add(&u1->faction->allies, u3->faction); al->status = HELP_GUARD; - force_leave(r); + force_leave(r, NULL); CuAssertPtrEquals_Msg(tc, "allies should not be forced to leave", b, u3->building); test_cleanup(); } @@ -289,7 +290,7 @@ static void test_force_leave_ships(CuTest *tc) { u_set_ship(u1, sh); u_set_ship(u2, sh); ship_set_owner(u1); - force_leave(r); + force_leave(r, NULL); CuAssertPtrEquals_Msg(tc, "non-allies should be forced to leave", NULL, u2->ship); msg = test_get_last_message(u2->faction->msgs); CuAssertStrEquals(tc, "force_leave_ship", test_get_messagetype(msg)); @@ -308,7 +309,7 @@ static void test_force_leave_ships_on_ocean(CuTest *tc) { u_set_ship(u1, sh); u_set_ship(u2, sh); ship_set_owner(u1); - force_leave(r); + force_leave(r, NULL); CuAssertPtrEquals_Msg(tc, "no forcing out of ships on oceans", sh, u2->ship); test_cleanup(); }