diff --git a/conf/e3/config.json b/conf/e3/config.json index 421a962a7..a6685a06f 100644 --- a/conf/e3/config.json +++ b/conf/e3/config.json @@ -57,7 +57,7 @@ "rules.owners.force_leave": false, "rules.monsters.attack_chance": 0.1, "rules.transfermen": false, - "rules.stealth.faction": true, + "stealth.faction.other": false, "rules.stealth.anon_battle": false, "rules.check_overload": false, "rules.combat.goblinbonus": 3, diff --git a/conf/e4/config.json b/conf/e4/config.json index ffa11443c..90c60d72b 100644 --- a/conf/e4/config.json +++ b/conf/e4/config.json @@ -55,7 +55,7 @@ "rules.reserve.twophase": true, "rules.owners.force_leave": false, "rules.transfermen": false, - "rules.stealth.faction": true, + "stealth.faction.other": false, "rules.stealth.anon_battle": false, "rules.check_overload": false, "rules.combat.goblinbonus": 3, diff --git a/scripts/tests/e2/stealth.lua b/scripts/tests/e2/stealth.lua index 7644b3c6c..ab4320bb1 100644 --- a/scripts/tests/e2/stealth.lua +++ b/scripts/tests/e2/stealth.lua @@ -19,36 +19,33 @@ end function setup() eressea.game.reset() set_rule('rules.food.flags', '4') - set_rule('rules.magic.playerschools', '') local r = region.create(0,0, "plain") f = faction.create("stealthy@eressea.de", "human", "de") u = unit.create(f, r, 1) f = faction.create("stealth@eressea.de", "human", "de") + unit.create(f, r, 1) -- TARNE PARTEI NUMMER must have a unit in the region end function teardown() set_rule('rules.food.flags') - set_rule('rules.magic.playerschools') - set_rule('rules.stealth.faction') end function test_stealth_faction_on() u:clear_orders() u:add_order("TARNEN PARTEI") - set_rule("rules.stealth.faction", 1) process_orders() assert_not_match("Partei", report.report_unit(u, f)) assert_match("anonym", report.report_unit(u, f)) end -function test_stealth_faction_off() +function test_stealth_faction_other() + u.name = "Enno" u:clear_orders() - u:add_order("TARNEN PARTEI") + u:add_order("TARNEN PARTEI NUMMER " .. itoa36(f.id)) - set_rule("rules.stealth.faction", 0) process_orders() - assert_match("Partei", report.report_unit(u, f)) + assert_match(itoa36(f.id), report.report_unit(u, f)) assert_not_match("anonym", report.report_unit(u, f)) end diff --git a/scripts/tests/e3/stealth.lua b/scripts/tests/e3/stealth.lua index bc78db006..38ca7d8ea 100644 --- a/scripts/tests/e3/stealth.lua +++ b/scripts/tests/e3/stealth.lua @@ -6,31 +6,29 @@ local f local u function setup() - eressea.game.reset() - eressea.settings.set("rules.food.flags", "4") + eressea.game.reset() + eressea.settings.set("rules.food.flags", "4") - local r = region.create(0,0, "plain") - f = faction.create("stealth1@eressea.de", "human", "de") - u = unit.create(f, r, 1) - f = faction.create("stealth2@eressea.de", "human", "de") + local r = region.create(0,0, "plain") + f = faction.create("stealth1@eressea.de", "human", "de") + u = unit.create(f, r, 1) + f = faction.create("stealth2@eressea.de", "human", "de") end function test_stealth_faction_on() - u:clear_orders() - u:add_order("TARNE PARTEI") + u:clear_orders() + u:add_order("TARNE PARTEI") - eressea.settings.set("rules.stealth.faction", 1) - process_orders() - assert_not_match("Partei", report.report_unit(u, f)) - assert_match("anonym", report.report_unit(u, f)) + process_orders() + assert_not_match("Partei", report.report_unit(u, f)) + assert_match("anonym", report.report_unit(u, f)) end -function test_stealth_faction_off() - u:clear_orders() - u:add_order("TARNE PARTEI") +function test_stealth_faction_other() + u:clear_orders() + u:add_order("TARNE PARTEI " .. itoa36(f.id)) - eressea.settings.set("rules.stealth.faction", 0) - process_orders() - assert_match("Partei", report.report_unit(u, f)) - assert_not_match("anonym", report.report_unit(u, f)) + process_orders() + assert_not_match("anonym", report.report_unit(u, f)) + assert_not_match(itoa36(f.id), report.report_unit(u, f)) end diff --git a/src/attributes/CMakeLists.txt b/src/attributes/CMakeLists.txt index b095f2abb..954f55443 100644 --- a/src/attributes/CMakeLists.txt +++ b/src/attributes/CMakeLists.txt @@ -1,6 +1,7 @@ PROJECT(attributes C) SET(_TEST_FILES stealth.test.c +otherfaction.test.c ) SET(_FILES diff --git a/src/attributes/otherfaction.c b/src/attributes/otherfaction.c index 0c225b256..76d035dd1 100644 --- a/src/attributes/otherfaction.c +++ b/src/attributes/otherfaction.c @@ -40,13 +40,9 @@ void write_of(const struct attrib *a, const void *owner, struct storage *store) int read_of(struct attrib *a, void *owner, struct storage *store) { /* return 1 on success, 0 if attrib needs removal */ int of; - static int rule = -1; - if (rule < 0) { - rule = rule_stealth_faction(); - } READ_INT(store, &of); - if (rule & 2) { + if (rule_stealth_other()) { a->data.v = findfaction(of); if (a->data.v) { return AT_READ_OK; diff --git a/src/attributes/otherfaction.h b/src/attributes/otherfaction.h index 5400d6077..726d86b0e 100644 --- a/src/attributes/otherfaction.h +++ b/src/attributes/otherfaction.h @@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif + struct unit; struct faction; struct attrib; extern struct attrib_type at_otherfaction; diff --git a/src/attributes/otherfaction.test.c b/src/attributes/otherfaction.test.c new file mode 100644 index 000000000..0b38901eb --- /dev/null +++ b/src/attributes/otherfaction.test.c @@ -0,0 +1,57 @@ +#include + +#include "otherfaction.h" + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +static void test_rules(CuTest *tc) { + test_cleanup(); + set_param(&global.parameters, "stealth.faction.other", NULL); + CuAssertIntEquals(tc, true, rule_stealth_other()); + set_param(&global.parameters, "stealth.faction.other", "0"); + CuAssertIntEquals(tc, false, rule_stealth_other()); + set_param(&global.parameters, "stealth.faction.other", "1"); + CuAssertIntEquals(tc, true, rule_stealth_other()); + + set_param(&global.parameters, "stealth.faction.anon", NULL); + CuAssertIntEquals(tc, true, rule_stealth_anon()); + set_param(&global.parameters, "stealth.faction.anon", "0"); + CuAssertIntEquals(tc, false, rule_stealth_anon()); + set_param(&global.parameters, "stealth.faction.anon", "1"); + CuAssertIntEquals(tc, true, rule_stealth_anon()); + test_cleanup(); +} + +static void test_otherfaction(CuTest *tc) { + unit *u; + faction *f; + + test_cleanup(); + u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); + f = test_create_faction(0); + set_param(&global.parameters, "stealth.faction.other", "1"); + CuAssertIntEquals(tc, true, rule_stealth_other()); + CuAssertPtrEquals(tc, u->faction, visible_faction(f, u)); + a_add(&u->attribs, make_otherfaction(f)); + CuAssertPtrEquals(tc, f, visible_faction(f, u)); + test_cleanup(); +} + +CuSuite *get_otherfaction_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_rules); + SUITE_ADD_TEST(suite, test_otherfaction); + return suite; +} diff --git a/src/attributes/stealth.test.c b/src/attributes/stealth.test.c index 90ee66872..818633d06 100644 --- a/src/attributes/stealth.test.c +++ b/src/attributes/stealth.test.c @@ -11,12 +11,11 @@ #include #include -void test_stealth(CuTest *tc) { +static void test_stealth(CuTest *tc) { unit *u; test_cleanup(); - test_create_world(); - u = test_create_unit(test_create_faction(test_create_race("human")), findregion(0, 0)); + u = test_create_unit(test_create_faction(test_create_race("human")), test_create_region(0, 0, 0)); set_level(u, SK_STEALTH, 2); CuAssertIntEquals(tc, -1, u_geteffstealth(u)); CuAssertIntEquals(tc, 2, eff_stealth(u, u->region)); diff --git a/src/battle.test.c b/src/battle.test.c index 8d8f83b8a..02213d35b 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -25,8 +25,8 @@ static void test_make_fighter(CuTest * tc) const resource_type *rtype; test_cleanup(); - test_create_world(); - r = findregion(0, 0); + test_create_horse(); + r = test_create_region(0, 0, 0); f = test_create_faction(NULL); au = test_create_unit(f, r); enable_skill(SK_MAGIC, true); @@ -75,8 +75,7 @@ static void test_defenders_get_building_bonus(CuTest * tc) building_type * btype; test_cleanup(); - test_create_world(); - r = findregion(0, 0); + r = test_create_region(0, 0, 0); btype = bt_get_or_create("castle"); btype->protection = &add_two; bld = test_create_building(r, btype); @@ -120,8 +119,7 @@ static void test_attackers_get_no_building_bonus(CuTest * tc) building_type * btype; test_cleanup(); - test_create_world(); - r = findregion(0, 0); + r = test_create_region(0, 0, 0); btype = bt_get_or_create("castle"); btype->protection = &add_two; bld = test_create_building(r, btype); @@ -151,8 +149,7 @@ static void test_building_bonus_respects_size(CuTest * tc) faction * f; test_cleanup(); - test_create_world(); - r = findregion(0, 0); + r = test_create_region(0, 0, 0); btype = bt_get_or_create("castle"); btype->protection = &add_two; bld = test_create_building(r, btype); diff --git a/src/give.test.c b/src/give.test.c index 517411c4c..76726c044 100644 --- a/src/give.test.c +++ b/src/give.test.c @@ -308,7 +308,7 @@ static void test_give_okay(CuTest * tc) { env.f2 = env.f1 = test_create_faction(0); setup_give(&env); - set_param(&global.parameters, "rules.give", "0"); + set_param(&global.parameters, "rules.give.flags", "0"); CuAssertPtrEquals(tc, 0, check_give(env.src, env.dst, 0)); test_cleanup(); } @@ -322,7 +322,7 @@ static void test_give_denied_by_rules(CuTest * tc) { env.f2 = test_create_faction(0); setup_give(&env); - set_param(&global.parameters, "rules.give", "0"); + set_param(&global.parameters, "rules.give.flags", "0"); CuAssertPtrNotNull(tc, msg = check_give(env.src, env.dst, 0)); msg_release(msg); test_cleanup(); diff --git a/src/kernel/build.c b/src/kernel/build.c index c81e610d7..76821a190 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -821,7 +821,7 @@ build_building(unit * u, const building_type * btype, int id, int want, order * /* gebäude fertig */ new_order = default_order(lang); } - else if (want != INT_MAX) { + else if (want != INT_MAX && btname) { /* reduzierte restgröße */ const char *hasspace = strchr(btname, ' '); if (hasspace) { diff --git a/src/kernel/build.test.c b/src/kernel/build.test.c index b879295e1..8e26d86c5 100644 --- a/src/kernel/build.test.c +++ b/src/kernel/build.test.c @@ -27,10 +27,14 @@ typedef struct build_fixture { static unit * setup_build(build_fixture *bf) { test_cleanup(); - test_create_world(); + init_resources(); + + test_create_itemtype("stone"); + test_create_buildingtype("castle"); bf->rc = test_create_race("human"); - bf->r = findregion(0, 0); + bf->r = test_create_region(0, 0, 0); bf->f = test_create_faction(bf->rc); + bf->f->locale = get_or_create_locale("de"); assert(bf->rc && bf->f && bf->r); bf->u = test_create_unit(bf->f, bf->r); assert(bf->u); @@ -134,6 +138,7 @@ static void test_build_limits(CuTest *tc) { u = setup_build(&bf); rtype = bf.cons.materials[0].rtype; + assert(rtype); i_change(&u->items, rtype->itype, 1); set_level(u, SK_ARMORER, bf.cons.minskill); CuAssertIntEquals(tc, 1, build(u, &bf.cons, 0, 10)); diff --git a/src/kernel/config.c b/src/kernel/config.c index 69d09b040..14ca56242 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -1160,11 +1160,13 @@ void set_param(struct param **p, const char *key, const char *data) } p = &(*p)->next; } - par = malloc(sizeof(param)); - par->name = _strdup(key); - par->data = _strdup(data); - par->next = *p; - *p = par; + if (data) { + par = malloc(sizeof(param)); + par->name = _strdup(key); + par->data = _strdup(data); + par->next = *p; + *p = par; + } } void kernel_done(void) @@ -1327,12 +1329,24 @@ int cmp_current_owner(const building * b, const building * a) return -1; } -bool rule_stealth_faction(void) +bool rule_stealth_other(void) { static int gamecookie = -1; static int rule = -1; if (rule < 0 || gamecookie != global.cookie) { - rule = get_param_int(global.parameters, "rules.stealth.faction", 1); + rule = get_param_int(global.parameters, "stealth.faction.other", 1); + gamecookie = global.cookie; + assert(rule >= 0); + } + return rule != 0; +} + +bool rule_stealth_anon(void) +{ + static int gamecookie = -1; + static int rule = -1; + if (rule < 0 || gamecookie != global.cookie) { + rule = get_param_int(global.parameters, "stealth.faction.anon", 1); gamecookie = global.cookie; assert(rule >= 0); } @@ -1351,13 +1365,13 @@ bool rule_region_owners(void) return rule!=0; } -int rule_auto_taxation(void) +bool rule_auto_taxation(void) { static int gamecookie = -1; static int rule = -1; if (rule < 0 || gamecookie != global.cookie) { rule = - get_param_int(global.parameters, "rules.economy.taxation", TAX_ORDER); + get_param_int(global.parameters, "rules.economy.taxation", 0); gamecookie = global.cookie; assert(rule >= 0); } @@ -1659,10 +1673,10 @@ int entertainmoney(const region * r) int rule_give(void) { - return get_param_int(global.parameters, "rules.give", GIVE_DEFAULT); + return get_param_int(global.parameters, "rules.give.flags", GIVE_DEFAULT); } -int markets_module(void) +bool markets_module(void) { return get_param_int(global.parameters, "modules.markets", 0); } diff --git a/src/kernel/config.h b/src/kernel/config.h index 9449744ef..5eddd1ff3 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -153,15 +153,14 @@ extern "C" { bool rule_transfermen(void); bool rule_region_owners(void); - bool rule_stealth_faction(void); + bool rule_stealth_other(void); // units can pretend to be another faction, TARNE PARTEI + bool rule_stealth_anon(void); // units can anonymize their faction, TARNE PARTEI [NICHT] int rule_alliance_limit(void); int rule_faction_limit(void); #define HARVEST_WORK 0x00 #define HARVEST_TAXES 0x01 int rule_blessed_harvest(void); -#define TAX_ORDER 0x00 -#define TAX_OWNER 0x01 - int rule_auto_taxation(void); + bool rule_auto_taxation(void); #define GIVE_SELF 1 #define GIVE_PEASANTS 2 #define GIVE_LUXURIES 4 @@ -227,7 +226,7 @@ extern "C" { int besieged(const struct unit *u); int maxworkingpeasants(const struct region *r); bool has_horses(const struct unit *u); - int markets_module(void); + bool markets_module(void); int wage(const struct region *r, const struct faction *f, const struct race *rc, int in_turn); int maintenance_cost(const struct unit *u); diff --git a/src/kernel/faction.c b/src/kernel/faction.c index fe4a7ad38..c5ecbcb43 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -402,16 +402,16 @@ void destroyfaction(faction * f) /* units of other factions that were disguised as this faction * have their disguise replaced by ordinary faction hiding. */ - if (rule_stealth_faction()) { + if (rule_stealth_other()) { region *rc; for (rc = regions; rc; rc = rc->next) { for (u = rc->units; u; u = u->next) { attrib *a = a_find(u->attribs, &at_otherfaction); - if (!a) - continue; - if (get_otherfaction(a) == f) { + if (a && get_otherfaction(a) == f) { a_removeall(&u->attribs, &at_otherfaction); - fset(u, UFL_ANON_FACTION); + if (rule_stealth_anon()) { + fset(u, UFL_ANON_FACTION); + } } } } diff --git a/src/kernel/save.c b/src/kernel/save.c index cdec5f9a4..201b710aa 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -687,7 +687,7 @@ unit *read_unit(struct gamedata *data) setstatus(u, n); READ_INT(data->store, &u->flags); u->flags &= UFL_SAVEMASK; - if ((u->flags & UFL_ANON_FACTION) && !rule_stealth_faction()) { + if ((u->flags & UFL_ANON_FACTION) && !rule_stealth_anon()) { /* if this rule is broken, then fix broken units */ u->flags -= UFL_ANON_FACTION; log_warning("%s was anonymous.\n", unitname(u)); @@ -1929,6 +1929,7 @@ gamedata *gamedata_open(const char *filename, const char *mode) { return data; } } + log_error("could not open %s: %s", filename, strerror(errno)); return 0; } diff --git a/src/spells.c b/src/spells.c index 48b86a9b4..4a3b81d7a 100644 --- a/src/spells.c +++ b/src/spells.c @@ -2188,7 +2188,7 @@ static int sp_ironkeeper(castorder * co) guard(keeper, GUARD_MINING); fset(keeper, UFL_ISNEW); /* Parteitarnen, damit man nicht sofort weiß, wer dahinter steckt */ - if (rule_stealth_faction()) { + if (rule_stealth_anon()) { fset(keeper, UFL_ANON_FACTION); } @@ -3630,7 +3630,7 @@ static int sp_charmingsong(castorder * co) /* setze Parteitarnung, damit nicht sofort klar ist, wer dahinter * steckt */ - if (rule_stealth_faction()) { + if (rule_stealth_anon()) { fset(target, UFL_ANON_FACTION); } @@ -4377,7 +4377,7 @@ static int sp_raisepeasants(castorder * co) LOC(mage->faction->locale, "furious_mob"), mage); fset(u2, UFL_LOCKED); - if (rule_stealth_faction()) { + if (rule_stealth_anon()) { fset(u2, UFL_ANON_FACTION); } diff --git a/src/spy.c b/src/spy.c index 6249ab6b8..e25ff1e85 100644 --- a/src/spy.c +++ b/src/spy.c @@ -215,7 +215,7 @@ int setstealth_cmd(unit * u, struct order *ord) { char token[64]; const char *s; - int level, rule; + int level; init_order(ord); s = gettoken(token, sizeof(token)); @@ -288,13 +288,8 @@ int setstealth_cmd(unit * u, struct order *ord) switch (findparam(s, u->faction->locale)) { case P_FACTION: /* TARNE PARTEI [NICHT|NUMMER abcd] */ - rule = rule_stealth_faction(); - if (!rule) { - /* TARNE PARTEI is disabled */ - break; - } s = gettoken(token, sizeof(token)); - if (rule & 1) { + if (rule_stealth_anon()) { if (!s || *s == 0) { fset(u, UFL_ANON_FACTION); break; @@ -304,7 +299,7 @@ int setstealth_cmd(unit * u, struct order *ord) break; } } - if (rule & 2) { + if (rule_stealth_other()) { if (get_keyword(s, u->faction->locale) == K_NUMBER) { s = gettoken(token, sizeof(token)); int nr = -1; diff --git a/src/test_eressea.c b/src/test_eressea.c index 2a0bf04eb..c04764992 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -121,6 +121,7 @@ int RunAllTests(int argc, char *argv[]) ADD_SUITE(move); ADD_SUITE(piracy); ADD_SUITE(stealth); + ADD_SUITE(otherfaction); ADD_SUITE(upkeep); ADD_SUITE(vortex); ADD_SUITE(wormhole); diff --git a/src/tests.c b/src/tests.c index 4e0206189..8cf97bede 100644 --- a/src/tests.c +++ b/src/tests.c @@ -45,7 +45,7 @@ struct region *test_create_region(int x, int y, const terrain_type *terrain) if (!terrain) { terrain_type *t = get_or_create_terrain("plain"); t->size = 1000; - fset(t, LAND_REGION); + fset(t, LAND_REGION|CAVALRY_REGION|FOREST_REGION); terraform_region(r, t); } else terraform_region(r, terrain); @@ -196,6 +196,16 @@ void test_translate_param(const struct locale *lang, param_t param, const char * add_translation(cb, text, param); } + +item_type *test_create_horse(void) { + item_type * itype; + itype = test_create_itemtype("horse"); + itype->flags |= ITF_BIG | ITF_ANIMAL; + itype->weight = 5000; + itype->capacity = 7000; + return itype; +} + /** creates a small world and some stuff in it. * two terrains: 'plain' and 'ocean' * one race: 'human' @@ -216,10 +226,7 @@ void test_create_world(void) locale_setstring(loc, "money", "SILBER"); init_resources(); - itype = test_create_itemtype("horse"); - itype->flags |= ITF_BIG | ITF_ANIMAL; - itype->weight = 5000; - itype->capacity = 7000; + test_create_horse(); itype = test_create_itemtype("cart"); itype->flags |= ITF_BIG | ITF_VEHICLE; diff --git a/src/tests.h b/src/tests.h index ba33dd5a7..f0b64729b 100644 --- a/src/tests.h +++ b/src/tests.h @@ -34,6 +34,7 @@ extern "C" { struct faction *test_create_faction(const struct race *rc); struct unit *test_create_unit(struct faction *f, struct region *r); void test_create_world(void); + struct item_type * test_create_horse(void); struct building * test_create_building(struct region * r, const struct building_type * btype); struct ship * test_create_ship(struct region * r, const struct ship_type * stype); struct item_type * test_create_itemtype(const char * name);