From 879d791a60b1f57dc1bd37e9e938964eff872e7e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 2 Oct 2016 14:30:27 +0200 Subject: [PATCH 01/11] seems like I forgot to commit this change, which is making the test fail. why only on my mac, though? --- scripts/eressea/xmasitems.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/eressea/xmasitems.lua b/scripts/eressea/xmasitems.lua index b31691d72..a05e023b8 100644 --- a/scripts/eressea/xmasitems.lua +++ b/scripts/eressea/xmasitems.lua @@ -62,9 +62,7 @@ end function use_snowman(u, amount) if amount>0 and u.region.terrain == "glacier" then - local man = unit.create(u.faction, u.region) - man.race = "snowman" - man.number = amount + local man = unit.create(u.faction, u.region, amount, "snowman") return amount end return -4 From f6beda43f447baf9f3ccc5af1c23261dc420aa26 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 3 Oct 2016 16:16:17 +0200 Subject: [PATCH 02/11] fix small typo --- s/travis-build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/s/travis-build b/s/travis-build index 011e9e7de..9293ac12d 100755 --- a/s/travis-build +++ b/s/travis-build @@ -10,7 +10,7 @@ $BUILD/iniparser/inifile eressea.ini add lua:paths lunit:scripts fi } -integraton_tests() { +integration_tests() { cd tests ./write-reports.sh ./run-turn.sh @@ -24,4 +24,4 @@ cd $ROOT inifile s/runtests -integraton_tests +integration_tests From 42e75007c32bf5ef6daa255c919c16f7f3b770dc Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 3 Oct 2016 16:26:40 +0200 Subject: [PATCH 03/11] little bit of refactoring and better variable names. --- .gitignore | 1 + src/monsters.c | 21 ++++++++++----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 8e19d4018..24219490f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.vscode/ *.orig eressea.ini Debug diff --git a/src/monsters.c b/src/monsters.c index ecf768cab..72decb304 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -277,27 +277,26 @@ static bool room_for_race_in_region(region * r, const race * rc) c += u->number; } - if (c > (rc->splitsize * 2)) - return false; - - return true; + return (c <= (rc->splitsize * 2)); } static direction_t random_neighbour(region * r, unit * u) { int i; - region *rc; region * next[MAXDIRECTIONS]; int rr, c = 0, c2 = 0; + const race *rc = u_race(u); get_neighbours(r, next); /* Nachsehen, wieviele Regionen in Frage kommen */ for (i = 0; i != MAXDIRECTIONS; i++) { - rc = next[i]; - if (rc && can_survive(u, rc)) { - if (room_for_race_in_region(rc, u_race(u))) { + region *rn = next[i]; + if (rn && can_survive(u, rn)) { + if (room_for_race_in_region(rn, rc)) { c++; + } else { + next[i] = NULL; } c2++; } @@ -321,12 +320,12 @@ static direction_t random_neighbour(region * r, unit * u) c = -1; for (i = 0; i != MAXDIRECTIONS; i++) { - rc = next[i]; - if (rc && can_survive(u, rc)) { + region *rn = next[i]; + if (rn && can_survive(u, rn)) { if (c2 == 0) { c++; } - else if (room_for_race_in_region(rc, u_race(u))) { + else if (room_for_race_in_region(rn, rc)) { c++; } if (c == rr) From ef43aaa830f54cd7faa195c53c286f3228d3f262 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 3 Oct 2016 16:28:18 +0200 Subject: [PATCH 04/11] eliminate some duplicate calculations. --- src/monsters.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/monsters.c b/src/monsters.c index 72decb304..4e3e47623 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -322,14 +322,10 @@ static direction_t random_neighbour(region * r, unit * u) for (i = 0; i != MAXDIRECTIONS; i++) { region *rn = next[i]; if (rn && can_survive(u, rn)) { - if (c2 == 0) { - c++; - } - else if (room_for_race_in_region(rn, rc)) { - c++; - } - if (c == rr) + c++; + if (c == rr) { return (direction_t)i; + } } } From 26a416c5badf08a2820b3df1d8a2f664bff115c0 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 3 Oct 2016 16:38:17 +0200 Subject: [PATCH 05/11] do not call can_survive all this much. --- src/monsters.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/monsters.c b/src/monsters.c index 4e3e47623..2678c284e 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -299,6 +299,8 @@ static direction_t random_neighbour(region * r, unit * u) next[i] = NULL; } c2++; + } else { + next[i] = NULL; } } @@ -321,7 +323,7 @@ static direction_t random_neighbour(region * r, unit * u) c = -1; for (i = 0; i != MAXDIRECTIONS; i++) { region *rn = next[i]; - if (rn && can_survive(u, rn)) { + if (rn) { c++; if (c == rr) { return (direction_t)i; From fbdf845cb99f850665f90b95f5c7389d9bb5d2f6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 3 Oct 2016 20:15:38 +0200 Subject: [PATCH 06/11] fix overpopulation-checks and movement based on splitsize. --- src/monsters.c | 55 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/src/monsters.c b/src/monsters.c index 2678c284e..258175b43 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -269,21 +269,27 @@ static direction_t richest_neighbour(region * r, faction * f, int absolut) static bool room_for_race_in_region(region * r, const race * rc) { - unit *u; - int c = 0; + if (rc->splitsize > 0) { + unit *u; + int c = 0; - for (u = r->units; u; u = u->next) { - if (u_race(u) == rc) - c += u->number; + for (u = r->units; u; u = u->next) { + if (u_race(u) == rc) { + c += u->number; + if (c > rc->splitsize * 2) { + return false; + } + } + } } - - return (c <= (rc->splitsize * 2)); + return true; } static direction_t random_neighbour(region * r, unit * u) { int i; - region * next[MAXDIRECTIONS]; + region *next[MAXDIRECTIONS], *backup[MAXDIRECTIONS]; + region **pick; int rr, c = 0, c2 = 0; const race *rc = u_race(u); @@ -298,19 +304,22 @@ static direction_t random_neighbour(region * r, unit * u) } else { next[i] = NULL; } + backup[i] = rn; c2++; } else { next[i] = NULL; + backup[i] = NULL; } } + pick = next; if (c == 0) { if (c2 == 0) { return NODIRECTION; } else { + pick = backup; c = c2; - c2 = 0; /* c2 == 0 -> room_for_race nicht beachten */ } } @@ -320,14 +329,14 @@ static direction_t random_neighbour(region * r, unit * u) /* Durchzählen */ - c = -1; + c = 0; for (i = 0; i != MAXDIRECTIONS; i++) { - region *rn = next[i]; + region *rn = pick[i]; if (rn) { - c++; if (c == rr) { return (direction_t)i; } + c++; } } @@ -543,19 +552,21 @@ static order *monster_learn(unit * u) return NULL; } -static bool check_overpopulated(unit * u) +static bool check_overpopulated(const unit * u) { - unit *u2; - int c = 0; + const race *rc = u_race(u); + if (rc->splitsize > 0) { + unit *u2; + int c = 0; - for (u2 = u->region->units; u2; u2 = u2->next) { - if (u_race(u2) == u_race(u) && u != u2) - c += u2->number; + for (u2 = u->region->units; u2; u2 = u2->next) { + if (u != u2 && u_race(u2) == rc) { + c += u2->number; + if (c > rc->splitsize * 2) + return true; + } + } } - - if (c > u_race(u)->splitsize * 2) - return true; - return false; } From 8f1a1fc8c35dc2572142e5aeb7e2c7bcb2180300 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 3 Oct 2016 20:27:36 +0200 Subject: [PATCH 07/11] tighten up some lookups. --- src/magic.c | 96 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/src/magic.c b/src/magic.c index bcf3403aa..0a2c685d4 100644 --- a/src/magic.c +++ b/src/magic.c @@ -1031,9 +1031,8 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord) double spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order *ord) { - curse *c; double force = cast_level; - int elf_power; + static int elf_power, config; const struct resource_type *rtype; if (sp == NULL) { @@ -1046,54 +1045,65 @@ spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order if (btype && btype->flags & BTF_MAGIC) ++force; } - elf_power = config_get_int("rules.magic.elfpower", 0); - - if (elf_power && u_race(u) == get_race(RC_ELF) && r_isforest(r)) { - ++force; + if (config_changed(&config)) { + elf_power = config_get_int("rules.magic.elfpower", 0); + } + if (elf_power) { + static int rc_cache; + static const race *rc_elf; + if (rc_changed(&rc_cache)) { + rc_elf = get_race(RC_ELF); + } + if (u_race(u) == rc_elf && r_isforest(r)) { + ++force; + } } rtype = rt_find("rop"); if (rtype && i_get(u->items, rtype->itype) > 0) { ++force; } - /* Antimagie in der Zielregion */ - c = get_curse(r->attribs, ct_find("antimagiczone")); - if (curse_active(c)) { - unit *mage = c->magician; - force -= curse_geteffect(c); - curse_changevigour(&r->attribs, c, -cast_level); - cmistake(u, ord, 185, MSG_MAGIC); - if (mage != NULL && mage->faction != NULL) { - if (force > 0) { - ADDMSG(&mage->faction->msgs, msg_message("reduce_spell", - "self mage region", mage, u, r)); + if (r->attribs) { + curse *c; + + /* Antimagie in der Zielregion */ + c = get_curse(r->attribs, ct_find("antimagiczone")); + if (curse_active(c)) { + unit *mage = c->magician; + force -= curse_geteffect(c); + curse_changevigour(&r->attribs, c, -cast_level); + cmistake(u, ord, 185, MSG_MAGIC); + if (mage != NULL && mage->faction != NULL) { + if (force > 0) { + ADDMSG(&mage->faction->msgs, msg_message("reduce_spell", + "self mage region", mage, u, r)); + } + else { + ADDMSG(&mage->faction->msgs, msg_message("block_spell", + "self mage region", mage, u, r)); + } } - else { - ADDMSG(&mage->faction->msgs, msg_message("block_spell", - "self mage region", mage, u, r)); + } + + /* Patzerfluch-Effekt: */ + c = get_curse(r->attribs, ct_find("fumble")); + if (curse_active(c)) { + unit *mage = c->magician; + force -= curse_geteffect(c); + curse_changevigour(&u->attribs, c, -1); + cmistake(u, ord, 185, MSG_MAGIC); + if (mage != NULL && mage->faction != NULL) { + if (force > 0) { + ADDMSG(&mage->faction->msgs, msg_message("reduce_spell", + "self mage region", mage, u, r)); + } + else { + ADDMSG(&mage->faction->msgs, msg_message("block_spell", + "self mage region", mage, u, r)); + } } } } - - /* Patzerfluch-Effekt: */ - c = get_curse(r->attribs, ct_find("fumble")); - if (curse_active(c)) { - unit *mage = c->magician; - force -= curse_geteffect(c); - curse_changevigour(&u->attribs, c, -1); - cmistake(u, ord, 185, MSG_MAGIC); - if (mage != NULL && mage->faction != NULL) { - if (force > 0) { - ADDMSG(&mage->faction->msgs, msg_message("reduce_spell", - "self mage region", mage, u, r)); - } - else { - ADDMSG(&mage->faction->msgs, msg_message("block_spell", - "self mage region", mage, u, r)); - } - } - } - return _max(force, 0); } @@ -2784,6 +2794,8 @@ void magic(void) int rank; castorder *co; spellrank spellranks[MAX_SPELLRANK]; + const race *rc_spell = get_race(RC_SPELL); + const race *rc_insect = get_race(RC_INSECT); memset(spellranks, 0, sizeof(spellranks)); @@ -2792,10 +2804,10 @@ void magic(void) for (u = r->units; u; u = u->next) { order *ord; - if (u->number <= 0 || u_race(u) == get_race(RC_SPELL)) + if (u->number <= 0 || u_race(u) == rc_spell) continue; - if (u_race(u) == get_race(RC_INSECT) && r_insectstalled(r) && + if (u_race(u) == rc_insect && r_insectstalled(r) && !is_cursed(u->attribs, C_KAELTESCHUTZ, 0)) continue; From 63f60a2465c88d3fb61bc68c794240ceb56a93ba Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 3 Oct 2016 20:36:46 +0200 Subject: [PATCH 08/11] cache some more get_race calls, especially for RC_SPELL. --- src/battle.c | 11 ++++++++--- src/laws.c | 8 +++++++- src/randenc.c | 7 ++++++- src/study.c | 8 +++++++- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/battle.c b/src/battle.c index 1bbaaadfe..fb411d778 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1886,7 +1886,13 @@ int skilldiff(troop at, troop dt, int dist) unit *au = af->unit, *du = df->unit; int is_protected = 0, skdiff = 0; weapon *awp = select_weapon(at, true, dist > 1); + static int rc_cache; + static const race *rc_halfling, *rc_goblin; + if (rc_changed(&rc_cache)) { + rc_halfling = get_race(RC_HALFLING); + rc_goblin = get_race(RC_GOBLIN); + } skdiff += af->person[at.index].attack; skdiff -= df->person[dt.index].defence; @@ -1894,11 +1900,10 @@ int skilldiff(troop at, troop dt, int dist) skdiff += 2; /* Effekte durch Rassen */ - if (awp != NULL && u_race(au) == get_race(RC_HALFLING) && dragonrace(u_race(du))) { + if (awp != NULL && u_race(au) == rc_halfling && dragonrace(u_race(du))) { skdiff += 5; } - - if (u_race(au) == get_race(RC_GOBLIN)) { + else if (u_race(au) == rc_goblin) { if (af->side->size[SUM_ROW] >= df->side->size[SUM_ROW] * rule_goblin_bonus) { skdiff += 1; } diff --git a/src/laws.c b/src/laws.c index f854ed7ef..e243378dd 100755 --- a/src/laws.c +++ b/src/laws.c @@ -125,7 +125,13 @@ static bool RemoveNMRNewbie(void) static void age_unit(region * r, unit * u) { - if (u_race(u) == get_race(RC_SPELL)) { + static int rc_cache; + static const race *rc_spell; + + if (rc_changed(&rc_cache)) { + rc_spell = get_race(RC_SPELL); + } + if (u_race(u) == rc_spell) { if (--u->age <= 0) { remove_unit(&r->units, u); } diff --git a/src/randenc.c b/src/randenc.c index 85c3dd8d3..0fe76e883 100644 --- a/src/randenc.c +++ b/src/randenc.c @@ -731,11 +731,16 @@ static void orc_growth(void) static void demon_skillchanges(void) { region *r; + static const race *rc_demon; + static int rc_cache; + if (rc_changed(&rc_cache)) { + rc_demon = get_race(RC_DAEMON); + } for (r = regions; r; r = r->next) { unit *u; for (u = r->units; u; u = u->next) { - if (u_race(u) == get_race(RC_DAEMON)) { + if (u_race(u) == rc_demon) { demon_skillchange(u); } } diff --git a/src/study.c b/src/study.c index 027f67dde..1ddaf8dfe 100644 --- a/src/study.c +++ b/src/study.c @@ -546,6 +546,12 @@ int study_cmd(unit * u, order * ord) int maxalchemy = 0; int speed_rule = (study_rule_t)config_get_int("study.speedup", 0); bool learn_newskills = config_get_int("study.newskills", 1) != 0; + static const race *rc_snotling; + static int rc_cache; + + if (rc_changed(&rc_cache)) { + rc_snotling = get_race(RC_SNOTLING); + } if (!unit_can_study(u)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_race_nolearn", "race", @@ -575,7 +581,7 @@ int study_cmd(unit * u, order * ord) } /* snotlings koennen Talente nur bis T8 lernen */ - if (u_race(u) == get_race(RC_SNOTLING)) { + if (u_race(u) == rc_snotling) { if (get_level(u, sk) >= 8) { cmistake(u, ord, 308, MSG_EVENT); return 0; From d3efc265c3f26f4f34bcf64525908d45c11de3b7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 4 Oct 2016 09:14:49 +0200 Subject: [PATCH 09/11] calculating income for dragons is no longer hard-coded --- res/races/dragon.xml | 3 ++- res/races/wyrm.xml | 6 +++++- res/races/youngdragon.xml | 6 +++++- src/economy.c | 16 ++-------------- src/economy.test.c | 14 ++++++++++++++ src/kernel/jsonconf.c | 3 +++ src/kernel/jsonconf.test.c | 2 ++ src/kernel/race.c | 1 + src/kernel/race.h | 1 + src/kernel/race.test.c | 1 + src/kernel/xmlreader.c | 1 + 11 files changed, 37 insertions(+), 17 deletions(-) diff --git a/res/races/dragon.xml b/res/races/dragon.xml index 907ff90a7..e4a1a7fec 100644 --- a/res/races/dragon.xml +++ b/res/races/dragon.xml @@ -1,7 +1,8 @@ +income="1000" walk="yes" teach="no" getitem="yes" resistbash="yes" +dragon="yes"> diff --git a/res/races/wyrm.xml b/res/races/wyrm.xml index b5d3bd7a2..b9f95d9ef 100644 --- a/res/races/wyrm.xml +++ b/res/races/wyrm.xml @@ -1,4 +1,8 @@ - + diff --git a/res/races/youngdragon.xml b/res/races/youngdragon.xml index d1b3a4752..71bc4214b 100644 --- a/res/races/youngdragon.xml +++ b/res/races/youngdragon.xml @@ -1,4 +1,8 @@ - + diff --git a/src/economy.c b/src/economy.c index 099e9786d..8f6a1afa1 100644 --- a/src/economy.c +++ b/src/economy.c @@ -114,20 +114,8 @@ static void recruit_init(void) int income(const unit * u) { - // TODO: make this a property, like race.income, no hard-coding of values - if (fval(u_race(u), RCF_DRAGON)) { - switch (old_race(u_race(u))) { - case RC_FIREDRAGON: - return 150 * u->number; - case RC_DRAGON: - return 1000 * u->number; - case RC_WYRM: - return 5000 * u->number; - default: - break; - } - } - return 20 * u->number; + const race *rc = u_race(u); + return rc->income * u->number; } static void scramble(void *data, unsigned int n, size_t width) diff --git a/src/economy.test.c b/src/economy.test.c index 7f48df289..3c4a5f257 100644 --- a/src/economy.test.c +++ b/src/economy.test.c @@ -328,11 +328,25 @@ static void test_recruit(CuTest *tc) { test_cleanup(); } +static void test_income(CuTest *tc) +{ + race *rc; + unit *u; + test_setup(); + rc = test_create_race("nerd"); + u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); + CuAssertIntEquals(tc, 20, income(u)); + u->number = 5; + CuAssertIntEquals(tc, 100, income(u)); + test_cleanup(); +} + CuSuite *get_economy_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_give_control_building); SUITE_ADD_TEST(suite, test_give_control_ship); + SUITE_ADD_TEST(suite, test_income); SUITE_ADD_TEST(suite, test_steal_okay); SUITE_ADD_TEST(suite, test_steal_ocean); SUITE_ADD_TEST(suite, test_steal_nosteal); diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index 9e6001f8d..6e60fc90c 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -481,6 +481,9 @@ static void json_race(cJSON *json, race *rc) { else if (strcmp(child->string, "capacity") == 0) { rc->capacity = child->valueint; } + else if (strcmp(child->string, "income") == 0) { + rc->income = child->valueint; + } else if (strcmp(child->string, "hp") == 0) { rc->hitpoints = child->valueint; } diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index 3fac3478a..76784ed56 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -141,6 +141,7 @@ static void test_races(CuTest * tc) "\"maintenance\" : 2," "\"weight\" : 3," "\"capacity\" : 4," + "\"income\" : 30," "\"hp\" : 5," "\"ac\" : 6," "\"flags\" : [ \"npc\", \"walk\", \"undead\" ]" @@ -167,6 +168,7 @@ static void test_races(CuTest * tc) CuAssertIntEquals(tc, 2, rc->maintenance); CuAssertIntEquals(tc, 3, rc->weight); CuAssertIntEquals(tc, 4, rc->capacity); + CuAssertIntEquals(tc, 30, rc->income); CuAssertIntEquals(tc, 5, rc->hitpoints); CuAssertIntEquals(tc, 6, rc->armor); cJSON_Delete(json); diff --git a/src/kernel/race.c b/src/kernel/race.c index 4003c701e..57ebe972a 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -173,6 +173,7 @@ race *rc_create(const char *zName) rc->hitpoints = 1; rc->weight = PERSON_WEIGHT; rc->capacity = 540; + rc->income = 20; rc->recruit_multi = 1.0F; rc->regaura = 1.0F; rc->speed = 1.0F; diff --git a/src/kernel/race.h b/src/kernel/race.h index 17c2bc61f..214f2738d 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -124,6 +124,7 @@ extern "C" { int splitsize; int weight; int capacity; + int income; float speed; float aggression; /* chance that a monster will attack */ int hitpoints; diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index ec4b40f92..7bccdbba8 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -32,6 +32,7 @@ static void test_rc_defaults(CuTest *tc) { CuAssertIntEquals(tc, 0, rc->recruitcost); CuAssertIntEquals(tc, 0, rc->maintenance); CuAssertIntEquals(tc, 540, rc->capacity); + CuAssertIntEquals(tc, 20, rc->income); CuAssertIntEquals(tc, 1, rc->hitpoints); CuAssertIntEquals(tc, 0, rc->armor); CuAssertIntEquals(tc, 0, rc->at_bonus); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 06363de48..894647f89 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1656,6 +1656,7 @@ static int parse_races(xmlDocPtr doc) rc->maintenance = xml_ivalue(node, "maintenance", rc->maintenance); rc->weight = xml_ivalue(node, "weight", rc->weight); rc->capacity = xml_ivalue(node, "capacity", rc->capacity); + rc->income = xml_ivalue(node, "income", rc->income); rc->speed = (float)xml_fvalue(node, "speed", rc->speed); rc->hitpoints = xml_ivalue(node, "hp", rc->hitpoints); rc->armor = (char)xml_ivalue(node, "ac", rc->armor); From 61f76e6722c809de2ead96bb027cd4f77df0ac04 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 4 Oct 2016 10:34:18 +0200 Subject: [PATCH 10/11] make old_race a little bit less awful. --- src/kernel/config.c | 10 ---------- src/kernel/race.c | 44 ++++++++++++++++++++++++++++++++++++++++++ src/kernel/race.test.c | 16 +++++++++++++++ 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/kernel/config.c b/src/kernel/config.c index f7eb0e303..ba69f142e 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -137,16 +137,6 @@ int NMRTimeout(void) return config_get_int("nmr.timeout", 0); } -race_t old_race(const struct race * rc) -{ - race_t i; - // TODO: this sucks so bad! - for (i = 0; i != MAXRACES; ++i) { - if (get_race(i) == rc) return i; - } - return NORACE; -} - helpmode helpmodes[] = { { "all", HELP_ALL } , diff --git a/src/kernel/race.c b/src/kernel/race.c index 57ebe972a..ce13d1ef7 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -86,6 +86,50 @@ const struct race *get_race(race_t rt) { return rc_find(name); } +typedef struct xref { + race_t id; + const race *rc; +} rc_xref; + +int cmp_xref(const void *a, const void *b) +{ + const rc_xref *l = (const rc_xref *)a; + const rc_xref *r = (const rc_xref *)b; + if (l->rcrc) return -1; + if (l->rc>r->rc) return 1; + return 0; +} + +race_t old_race(const struct race * rc) +{ + static int cache; + static rc_xref *xrefs; + int i, l, r; + + if (rc_changed(&cache)) { + if (!xrefs) { + xrefs = malloc(sizeof(rc_xref) * MAXRACES); + } + for (i = 0; i != MAXRACES; ++i) { + xrefs[i].rc = get_race(i); + xrefs[i].id = (race_t)i; + } + qsort(xrefs, MAXRACES, sizeof(rc_xref), cmp_xref); + } + l=0; r=MAXRACES-1; + while (l<=r) { + int m = (l+r)/2; + if (rcxrefs[m].rc) { + l = m+1; + } else { + return (race_t)xrefs[m].id; + } + } + return NORACE; +} + race_list *get_familiarraces(void) { static int init = 0; diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index 7bccdbba8..663a538ee 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -66,10 +66,26 @@ static void test_race_get(CuTest *tc) { test_cleanup(); } +static void test_old_race(CuTest *tc) +{ + race * rc1, *rc2; + test_setup(); + test_create_race("dwarf"); + rc1 = test_create_race("elf"); + rc2 = test_create_race("onkel"); + CuAssertIntEquals(tc, RC_ELF, old_race(rc1)); + CuAssertIntEquals(tc, NORACE, old_race(rc2)); + rc2 = test_create_race("human"); + CuAssertIntEquals(tc, RC_ELF, old_race(rc1)); + CuAssertIntEquals(tc, RC_HUMAN, old_race(rc2)); + test_cleanup(); +} + CuSuite *get_race_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_race_get); + SUITE_ADD_TEST(suite, test_old_race); SUITE_ADD_TEST(suite, test_rc_name); SUITE_ADD_TEST(suite, test_rc_defaults); SUITE_ADD_TEST(suite, test_rc_find); From e79b36bc366c235dd42f75cb4eef0bb85daa598d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 4 Oct 2016 10:51:37 +0200 Subject: [PATCH 11/11] introduced a memory leak i last commit --- src/kernel/race.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/kernel/race.c b/src/kernel/race.c index ce13d1ef7..5b991eca6 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -100,10 +100,10 @@ int cmp_xref(const void *a, const void *b) return 0; } +static rc_xref *xrefs; race_t old_race(const struct race * rc) { static int cache; - static rc_xref *xrefs; int i, l, r; if (rc_changed(&cache)) { @@ -170,6 +170,8 @@ void free_races(void) { while (races) { race * rc = races->next; free_params(&races->parameters); + free(xrefs); + xrefs = 0; free(races->_name); free(races->def_damage); free(races);