From a789cd131f9063dfc95e6449786d474305835aa3 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 21 Sep 2026 19:59:38 +0200 Subject: [PATCH] Bug 3120: BEWACHE-Tricks mit TEMP-Einheiten MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bei Übergabe von Personen wird das UFL_FLEEING Flag übertragen, Problem gelöst. Solange eine Person in der Einheit aus einer unbefangenen Einheit kommt, kann sie trotzdem bewachen. --- src/guard.test.c | 25 +++++++++++++++++++++++++ src/kernel/unit.c | 10 ++++++++++ src/kernel/unit.test.c | 38 +++++++++++++++++++++++++++++++++++++- 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/guard.test.c b/src/guard.test.c index b9678030c..b5f3b88ec 100644 --- a/src/guard.test.c +++ b/src/guard.test.c @@ -277,6 +277,30 @@ static void test_guard_checks_allowed_weapon(CuTest *tc) test_teardown(); } +static void test_fleeing_temp_cant_guard(CuTest *tc) +{ + unit *ug, *u; + region *r; + item_type *itype; + + test_setup(); + itype = it_get_or_create(rt_get_or_create("sword")); + new_weapontype(itype, 0, frac_zero, NULL, 0, 0, 0, SK_MELEE); + r = test_create_plain(0, 0); + u = test_create_unit(test_create_faction(), r); + fset(u, UFL_FLEEING); + ug = test_create_unit(u->faction, r); + set_number(ug, 0); + i_change(&ug->items, itype, 1); + set_level(u, SK_MELEE, 1); + transfermen(u, ug, 1); + CuAssertIntEquals(tc, UFL_FLEEING, ug->flags & UFL_FLEEING); + CuAssertIntEquals(tc, E_GUARD_FLEEING, can_start_guarding(ug)); + CuAssertIntEquals(tc, E_GUARD_FLEEING, can_start_guarding(u)); + + test_teardown(); +} + CuSuite *get_guard_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -289,5 +313,6 @@ CuSuite *get_guard_suite(void) SUITE_ADD_TEST(suite, test_guard_unarmed); SUITE_ADD_TEST(suite, test_guard_monsters); SUITE_ADD_TEST(suite, test_update_guard); + SUITE_ADD_TEST(suite, test_fleeing_temp_cant_guard); return suite; } diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 5815a4000..b2dad23c2 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -813,6 +813,16 @@ void transfermen(unit* u, unit* dst, int n) dst->flags |= u->flags & (UFL_LONGACTION | UFL_NOTMOVING | UFL_HUNGER | UFL_MOVED | UFL_ENTER); + if (u->flags & UFL_FLEEING) { + if (dst->number == 0) { + /* after transfer, dst consists entirely of men fleeing from a fight (cannot guard) */ + dst->flags |= UFL_FLEEING; + } + } + else { + /* after transfer, dst contains men not fleeing from a fight (can guard) */ + dst->flags &= ~UFL_FLEEING; + } if (u->attribs) { transfer_curse(u, dst, n); transfer_effects(u, dst, n); diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index 346fde8c8..6b1d74359 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -670,7 +670,8 @@ static void test_transfermen_bug_2386(CuTest *tc) { test_teardown(); } -static void test_transfermen_bug_2886(CuTest *tc) { +static void test_transfermen_bug_2886(CuTest *tc) +{ unit *u1, *u2; region *r; faction *f; @@ -689,6 +690,40 @@ static void test_transfermen_bug_2886(CuTest *tc) { test_teardown(); } +static void test_transfermen_bug_3120(CuTest *tc) +{ + unit *u1, *u2, *u3; + region *r; + faction *f; + + test_setup(); + r = test_create_plain(0, 0); + f = test_create_faction(); + /* u1 is a unit that survived combat, but can't guard */ + u1 = test_create_unit(f, r); + set_number(u1, 2); + fset(u1, UFL_FLEEING); + + /* u2 is an empty unit that receives men from u1, so it can't guard either */ + u2 = test_create_unit(f, r); + set_number(u2, 0); + transfermen(u1, u2, 1); + CuAssertIntEquals(tc, UFL_FLEEING, u2->flags & UFL_FLEEING); + + /* u2 is a non-empty unit that receives men from u1, but it can still guard */ + u3 = test_create_unit(f, r); + transfermen(u1, u3, 1); + CuAssertIntEquals(tc, 0, u3->flags & UFL_FLEEING); + + /* u2 is a tainted unit that receives men from a non-tainted one, so it can guard */ + CuAssertIntEquals(tc, UFL_FLEEING, u2->flags & UFL_FLEEING); + CuAssertIntEquals(tc, 0, u3->flags & UFL_FLEEING); + transfermen(u3, u2, 1); + CuAssertIntEquals(tc, 0, u2->flags & UFL_FLEEING); + + test_teardown(); +} + static void test_transfermen(CuTest *tc) { unit *u1, *u2; region *r; @@ -1121,6 +1156,7 @@ CuSuite *get_unit_suite(void) SUITE_ADD_TEST(suite, test_change_faction_clears_private); SUITE_ADD_TEST(suite, test_transfermen_bug_2386); SUITE_ADD_TEST(suite, test_transfermen_bug_2886); + SUITE_ADD_TEST(suite, test_transfermen_bug_3120); SUITE_ADD_TEST(suite, test_remove_unit); SUITE_ADD_TEST(suite, test_remove_empty_units); SUITE_ADD_TEST(suite, test_remove_units_without_faction);