Skip to content

Commit

Permalink
testing cursed and notlost behavior
Browse files Browse the repository at this point in the history
some mild refactoring, but no real changes.
  • Loading branch information
ennorehling committed Sep 4, 2023
1 parent 9a31ded commit 1ae0050
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 19 deletions.
2 changes: 1 addition & 1 deletion res/core/common/items.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
</resource>

<resource name="presspass">
<item weight="0" score="6000" cursed="yes"/>
<item cursed="yes" weight="0" score="6000"/>
</resource>

<resource name="aurafocus">
Expand Down
4 changes: 2 additions & 2 deletions res/eressea/items.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
</resource>

<resource name="ring_of_levitation" appearance="ring">
<item notlost="yes" weight="0" cursed="true" use="yes" />
<item cursed="true" notlost="yes" weight="0" use="yes" />
</resource>

<resource name="birthdaycake">
Expand Down Expand Up @@ -74,7 +74,7 @@
<!-- gimmicks, etc. -->
<resource name="aog">
<!-- Amulett des Treffens -->
<item notlost="yes" cursed="true" weight="0"/>
<item cursed="true" notlost="yes" weight="0"/>
</resource>

<resource name="aoc" appearance="amulet">
Expand Down
10 changes: 5 additions & 5 deletions scripts/tests/pool.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function setup()
eressea.settings.set("rules.magic.playerschools", "")
conf = [[{
"races": {
"human" : { "flags" : [ "giveitem", "getitem" ] }
"human" : { "flags" : [ "getitem" ] }
},
"terrains" : {
"plain": { "flags" : [ "land" ] }
Expand All @@ -35,7 +35,7 @@ end

function test_give_nopool()
local r = region.create(1, 1, "plain")
local f = faction.create("human", "test@example.com", "de")
local f = faction.create("human")
local u1 = unit.create(f, r, 1)
local u2 = unit.create(f, r, 1)
u1:add_item("money", 100)
Expand All @@ -47,7 +47,7 @@ end

function test_give_from_faction()
local r = region.create(1, 1, "plain")
local f = faction.create("human", "test@example.com", "de")
local f = faction.create("human")
local u1 = unit.create(f, r, 1)
local u2 = unit.create(f, r, 1)
local u3 = unit.create(f, r, 1)
Expand All @@ -64,8 +64,8 @@ function test_give_divisor()
eressea.settings.set("rules.items.give_divisor", 2)
eressea.settings.set("GiveRestriction", 0)
local r = region.create(1, 1, "plain")
local f1 = faction.create("human", "test@example.com", "de")
local f2 = faction.create("human", "test@example.com", "de")
local f1 = faction.create("human")
local f2 = faction.create("human")
local u1 = unit.create(f1, r, 1)
local u2 = unit.create(f2, r, 1)
u2:add_order("KONTAKTIERE " .. itoa36(u1.id))
Expand Down
27 changes: 18 additions & 9 deletions src/battle.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ bool meffect_blocked(battle * b, meffect * s, side * as)

/* rmfighter wird schon im PRAECOMBAT gebraucht, da gibt es noch keine
* troops */
void rmfighter(fighter * df, int i)
void reduce_fighter(fighter * df, int i)
{
side *ds = df->side;

Expand All @@ -853,12 +853,22 @@ void rmfighter(fighter * df, int i)
df->alive -= i;
}

void flee_all(fighter *fig)
{
unit *u = fig->unit;
fig->run.hp = u->hp;
fig->run.number = u->number;
fig->side->flee += u->number;
setguard(u, false);
reduce_fighter(fig, u->number);
}

static void rmtroop(troop dt)
{
fighter *df = dt.fighter;

/* troop ist immer eine einzelne Person */
rmfighter(df, 1);
reduce_fighter(df, 1);

assert(dt.index >= 0 && dt.index < df->unit->number);
if (dt.index != df->alive - df->removed) {
Expand Down Expand Up @@ -1150,7 +1160,7 @@ static void destroy_items(troop dt) {
for (pitm = &du->items; *pitm;) {
item *itm = *pitm;
const item_type *itype = itm->type;
if (!(itype->flags & (ITF_CURSED | ITF_NOTLOST)) && dt.index < itm->number) {
if (!(itype->flags & ITF_NOTLOST) && dt.index < itm->number) {
/* 25% Grundchance, dass ein Item kaputtgeht. */
if (rng_int() % 4 < 1) {
i_change(pitm, itype, -1);
Expand Down Expand Up @@ -2424,6 +2434,9 @@ static int loot_quota(const unit * src, const unit * dst,
const item_type * type, int n)
{
UNUSED_ARG(type);
if (loot_divisor <= 0) {
return 0;
}
if (dst && src && src->faction != dst->faction) {
assert(loot_divisor <= 0 || loot_divisor >= 1);
if (loot_divisor > 1) {
Expand Down Expand Up @@ -2466,7 +2479,7 @@ void loot_items(fighter * corpse)
int looting = 0;
int maxrow = 0;
/* mustloot: we absolutely, positively must have somebody loot this thing */
bool mustloot = 0 != (itm->type->flags & (ITF_CURSED | ITF_NOTLOST));
bool mustloot = 0 != (itm->type->flags & (ITF_CURSED|ITF_NOTLOST));

item_add(itm, -loot);
maxloot -= loot;
Expand Down Expand Up @@ -3822,11 +3835,7 @@ static bool start_battle(region * r, battle ** bp)
int effect = get_effect(u2, it_mistletoe);
if (effect >= u->number) {
change_effect(u2, it_mistletoe, -u2->number);
c2->run.hp = u2->hp;
c2->run.number = u2->number;
c2->side->flee += u2->number;
setguard(u2, false);
rmfighter(c2, u2->number);
flee_all(c2);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,12 @@ typedef bool(*select_fun)(const struct side* vs, const struct fighter* fig, void
struct selist* select_fighters(struct battle* b, const struct side* vs, int mask, select_fun cb, void* cbdata);
struct selist* fighters(struct battle* b, const struct side* vs,
int minrow, int maxrow, int mask);
void flee_all(struct fighter *fig);

int count_allies(const struct side* as, int minrow, int maxrow,
int select, int allytype);
bool helping(const struct side* as, const struct side* ds);
void rmfighter(fighter* df, int i);
void reduce_fighter(fighter* df, int i);
struct fighter* select_corpse(struct battle* b, struct fighter* af);
int statusrow(int status);
void drain_exp(struct unit* u, int d);
Expand Down
164 changes: 164 additions & 0 deletions src/battle.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,44 @@ static void test_battle_skilldiff(CuTest *tc)
}

static void test_loot_items(CuTest* tc)
{
troop ta, td;
region* r;
faction *f;
unit* ua, * ud;
battle* b = NULL;
const resource_type* rtype;
race* rc;

test_setup();
config_set_int("rules.items.loot_divisor", 1); // everything is looted 100%
test_create_horse();
rc = test_create_race("ghost");
rc->flags |= RCF_FLY; /* bug 2887 */

r = test_create_plain(0, 0);
ud = test_create_unit(f = test_create_faction(), r);
ud->status = ST_FLEE; /* bug 2887 */
ua = test_create_unit(f, r);
u_setrace(ua, rc);
td.fighter = setup_fighter(&b, ud);
td.index = 0;
ta.fighter = setup_fighter(&b, ua);
ta.index = 0;

ta.fighter->alive = 0;

rtype = get_resourcetype(R_HORSE);
i_change(&ua->items, rtype->itype, 1);
loot_items(ta.fighter);
CuAssertIntEquals(tc, 1, i_get(td.fighter->loot, rtype->itype));
CuAssertIntEquals(tc, 0, i_get(ua->items, rtype->itype));

free_battle(b);
test_teardown();
}

static void test_loot_notlost_items(CuTest* tc)
{
troop ta, td;
region* r;
Expand All @@ -659,6 +697,7 @@ static void test_loot_items(CuTest* tc)
race* rc;

test_setup();
config_set_int("rules.items.loot_divisor", 0); // nothing is looted
test_create_horse();
rc = test_create_race("ghost");
rc->flags |= RCF_FLY; /* bug 2887 */
Expand Down Expand Up @@ -692,6 +731,127 @@ static void test_loot_items(CuTest* tc)
test_teardown();
}

static void test_loot_cursed_items_self(CuTest* tc)
{
troop ta, td;
region* r;
faction *f;
unit* ua, * ud;
battle* b = NULL;
const resource_type* rtype;
race* rc;

test_setup();
config_set_int("rules.items.loot_divisor", 1); // everything is looted
test_create_horse();
rc = test_create_race("ghost");
rc->flags |= RCF_FLY; /* bug 2887 */

r = test_create_plain(0, 0);
ud = test_create_unit(f = test_create_faction(), r);
ud->status = ST_FLEE; /* bug 2887 */
ua = test_create_unit(f, r);
u_setrace(ua, rc);
td.fighter = setup_fighter(&b, ud);
td.index = 0;
ta.fighter = setup_fighter(&b, ua);
ta.index = 0;

ta.fighter->alive = 0;

rtype = get_resourcetype(R_HORSE);
rtype->itype->flags |= ITF_CURSED; /* must be looted by own faction */
i_change(&ua->items, rtype->itype, 1);
loot_items(ta.fighter);
CuAssertIntEquals(tc, 1, i_get(td.fighter->loot, rtype->itype));
CuAssertIntEquals(tc, 0, i_get(ua->items, rtype->itype));

free_battle(b);
test_teardown();
}

static void test_loot_cursed_items_other(CuTest* tc)
{
troop ta, td;
region* r;
unit* ua, * ud;
battle* b = NULL;
const resource_type* rtype;
race* rc;

test_setup();
config_set_int("rules.items.loot_divisor", 1); // everything is looted
test_create_horse();
rc = test_create_race("ghost");
rc->flags |= RCF_FLY; /* bug 2887 */

r = test_create_plain(0, 0);
ud = test_create_unit(test_create_faction(), r);
ud->status = ST_FLEE; /* bug 2887 */
ua = test_create_unit(test_create_faction(), r);
u_setrace(ua, rc);
td.fighter = setup_fighter(&b, ud);
td.index = 0;
ta.fighter = setup_fighter(&b, ua);
ta.index = 0;

ta.fighter->alive = 0;

rtype = get_resourcetype(R_HORSE);
rtype->itype->flags |= ITF_CURSED; /* must not be looted */
i_change(&ua->items, rtype->itype, 1);
loot_items(ta.fighter);
CuAssertIntEquals(tc, 0, i_get(td.fighter->loot, rtype->itype));
CuAssertIntEquals(tc, 0, i_get(ua->items, rtype->itype));

free_battle(b);
test_teardown();
}

static void test_no_loot_from_fleeing(CuTest* tc)
{
troop ta, td;
region* r;
unit* ua, * ud;
battle* b = NULL;
const resource_type* rtype;
race* rc;

test_setup();
test_create_horse();
rc = test_create_race("ghost");
rc->flags |= RCF_FLY; /* bug 2887 */

r = test_create_plain(0, 0);
ud = test_create_unit(test_create_faction(), r);
ud->status = ST_FLEE; /* bug 2887 */
ua = test_create_unit(test_create_faction(), r);
u_setrace(ua, rc);
td.fighter = setup_fighter(&b, ud);
td.index = 0;
ta.fighter = setup_fighter(&b, ua);
ta.index = 0;

ta.fighter->side->relations[td.fighter->side->index] |= E_ENEMY;
ta.fighter->side->enemies[0] = td.fighter->side;
ta.fighter->side->enemies[1] = NULL;
td.fighter->side->relations[ta.fighter->side->index] |= E_ENEMY;
td.fighter->side->enemies[0] = ta.fighter->side;
td.fighter->side->enemies[1] = NULL;

flee_all(ta.fighter);

rtype = get_resourcetype(R_HORSE);
rtype->itype->flags |= ITF_NOTLOST; /* must always be looted */
i_change(&ua->items, rtype->itype, 1);
loot_items(ta.fighter);
CuAssertIntEquals(tc, 0, i_get(td.fighter->loot, rtype->itype));
CuAssertIntEquals(tc, 1, i_get(ua->items, rtype->itype));

free_battle(b);
test_teardown();
}

static void test_terminate(CuTest * tc)
{
troop at, dt;
Expand Down Expand Up @@ -1026,6 +1186,10 @@ CuSuite *get_battle_suite(void)
SUITE_ADD_TEST(suite, test_tactics_chance);
SUITE_ADD_TEST(suite, test_terminate);
SUITE_ADD_TEST(suite, test_loot_items);
SUITE_ADD_TEST(suite, test_loot_notlost_items);
SUITE_ADD_TEST(suite, test_loot_cursed_items_self);
SUITE_ADD_TEST(suite, test_loot_cursed_items_other);
SUITE_ADD_TEST(suite, test_no_loot_from_fleeing);
DISABLE_TEST(suite, test_drain_exp);
return suite;
}
2 changes: 1 addition & 1 deletion src/spells/combatspells.c
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,7 @@ int sp_appeasement(struct castorder * co)
fi->run.hp = mage->hp;
fi->run.number = mage->number;
/* fighter leeren */
rmfighter(fi, mage->number);
reduce_fighter(fi, mage->number);

m = msg_message("cast_escape_effect", "mage spell", fi->unit, sp);
message_all(b, m);
Expand Down

0 comments on commit 1ae0050

Please sign in to comment.