cannibalism: don't lose victims' items.

add a test for i_merge since we're using it.
This commit is contained in:
Enno Rehling 2021-06-24 22:01:40 +02:00
parent adde06980d
commit e7de928757
4 changed files with 63 additions and 23 deletions

View File

@ -3852,10 +3852,6 @@ static void battle_flee(battle * b)
int runhp = (int)(0.9 + unit_max_hp(u) * hpflee(u->status));
if (runhp > 600) runhp = 600;
if (u->ship && fval(u->region->terrain, SEA_REGION)) {
/* keine Flucht von Schiffen auf hoher See */
continue;
}
if (fval(u_race(u), RCF_UNDEAD) || u_race(u) == get_race(RC_SHADOWKNIGHT)) {
/* Untote fliehen nicht. Warum eigentlich? */
continue;

View File

@ -406,25 +406,30 @@ item *i_add(item ** pi, item * i)
void i_merge(item ** pi, item ** si)
{
item *i = *si;
while (i) {
item *itmp;
while (*pi) {
int d = strcmp((*pi)->type->rtype->_name, i->type->rtype->_name);
if (d >= 0)
break;
pi = &(*pi)->next;
}
if (*pi && (*pi)->type == i->type) {
(*pi)->number += i->number;
assert((*pi)->number >= 0);
i_free(i_remove(&i, i));
}
else {
itmp = i->next;
i->next = *pi;
*pi = i;
i = itmp;
if (*pi == NULL) {
*pi = *si;
}
else {
item *i = *si;
while (i) {
item *itmp;
while (*pi) {
int d = strcmp((*pi)->type->rtype->_name, i->type->rtype->_name);
if (d >= 0)
break;
pi = &(*pi)->next;
}
if (*pi && (*pi)->type == i->type) {
(*pi)->number += i->number;
assert((*pi)->number >= 0);
i_free(i_remove(&i, i));
}
else {
itmp = i->next;
i->next = *pi;
*pi = i;
i = itmp;
}
}
}
*si = NULL;

View File

@ -65,6 +65,43 @@ static void test_uchange(CuTest * tc, unit * u, const resource_type * rtype) {
test_log_stop(log, sl);
}
void test_merge_items(CuTest *tc)
{
item *src = NULL, *dst = NULL;
const struct item_type *itype, *ihorse;
test_setup();
itype = test_create_itemtype("iron");
ihorse = test_create_itemtype("horse");
i_merge(&dst, &src);
CuAssertPtrEquals(tc, NULL, dst);
CuAssertPtrEquals(tc, NULL, src);
i_change(&src, itype, 1);
CuAssertIntEquals(tc, 1, i_get(src, itype));
i_merge(&dst, &src);
CuAssertPtrEquals(tc, NULL, src);
CuAssertIntEquals(tc, 1, i_get(dst, itype));
i_change(&src, itype, 1);
CuAssertIntEquals(tc, 1, i_get(src, itype));
i_merge(&dst, &src);
CuAssertPtrEquals(tc, NULL, src);
CuAssertIntEquals(tc, 2, i_get(dst, itype));
i_change(&src, itype, 1);
i_change(&src, ihorse, 1);
CuAssertIntEquals(tc, 1, i_get(src, itype));
CuAssertIntEquals(tc, 1, i_get(src, ihorse));
i_merge(&dst, &src);
CuAssertPtrEquals(tc, NULL, src);
CuAssertIntEquals(tc, 3, i_get(dst, itype));
CuAssertIntEquals(tc, 1, i_get(dst, ihorse));
test_teardown();
}
void test_change_item(CuTest * tc)
{
unit * u;
@ -197,6 +234,7 @@ CuSuite *get_item_suite(void)
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_resourcename_no_appearance);
SUITE_ADD_TEST(suite, test_resourcename_with_appearance);
SUITE_ADD_TEST(suite, test_merge_items);
SUITE_ADD_TEST(suite, test_change_item);
SUITE_ADD_TEST(suite, test_get_resource);
SUITE_ADD_TEST(suite, test_resource_type);

View File

@ -763,6 +763,7 @@ void monster_cannibalism(unit *u)
for (u2 = u->next; u2; u2 = u2->next) {
if (u2->_race == u->_race) {
i_merge(&u->items, &u2->items);
stats_count("monsters.cannibalism", u2->number);
u2->number = 0;
}