From 7750297dc2a340a256bf773a39697f0cfacb1ef1 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Feb 2017 10:57:32 +0100 Subject: [PATCH 01/14] express race.magres as percentage, not probability (double->int) --- res/e3a/races.xml | 102 ++++++++++++++--------------- res/eressea/races.xml | 130 ++++++++++++++++++------------------- res/races/aquarian.xml | 2 +- res/races/cat.xml | 2 +- res/races/demon.xml | 2 +- res/races/dragon.xml | 2 +- res/races/dwarf.xml | 2 +- res/races/elf.xml | 2 +- res/races/goblin-2.xml | 2 +- res/races/goblin-3.xml | 2 +- res/races/goblin.xml | 2 +- res/races/halfling.xml | 2 +- res/races/human.xml | 2 +- res/races/insect.xml | 2 +- res/races/orc.xml | 2 +- res/races/troll.xml | 2 +- res/races/wyrm.xml | 2 +- res/races/youngdragon.xml | 2 +- res/races/zombie.xml | 2 +- src/battle.test.c | 4 +- src/kernel/jsonconf.c | 2 +- src/kernel/jsonconf.test.c | 5 +- src/kernel/race.c | 4 ++ src/kernel/race.h | 3 +- src/kernel/race.test.c | 3 +- src/kernel/xmlreader.c | 2 +- src/magic.c | 2 +- src/magic.test.c | 6 +- 28 files changed, 152 insertions(+), 145 deletions(-) diff --git a/res/e3a/races.xml b/res/e3a/races.xml index 2b0f68b9d..3402fdb73 100644 --- a/res/e3a/races.xml +++ b/res/e3a/races.xml @@ -8,7 +8,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -47,7 +47,7 @@ - + @@ -76,7 +76,7 @@ - + @@ -104,7 +104,7 @@ - + @@ -124,7 +124,7 @@ - + @@ -144,7 +144,7 @@ - + @@ -167,7 +167,7 @@ - + @@ -192,7 +192,7 @@ - + @@ -219,7 +219,7 @@ - + @@ -241,7 +241,7 @@ - + @@ -263,7 +263,7 @@ - + @@ -287,7 +287,7 @@ - + @@ -311,7 +311,7 @@ - + @@ -334,7 +334,7 @@ - + @@ -361,7 +361,7 @@ - + @@ -384,7 +384,7 @@ - + @@ -409,7 +409,7 @@ - + @@ -435,7 +435,7 @@ - + @@ -460,7 +460,7 @@ - + @@ -484,7 +484,7 @@ - + @@ -507,7 +507,7 @@ - + @@ -535,7 +535,7 @@ - + @@ -559,7 +559,7 @@ - + @@ -582,7 +582,7 @@ - + @@ -607,16 +607,16 @@ - + - + - + @@ -624,7 +624,7 @@ - + @@ -672,47 +672,47 @@ - + - + - + - + - + - + - + - + @@ -720,21 +720,21 @@ - + - + - + @@ -742,7 +742,7 @@ - + @@ -768,7 +768,7 @@ - + @@ -787,7 +787,7 @@ - + @@ -806,7 +806,7 @@ - + @@ -823,7 +823,7 @@ - + @@ -839,7 +839,7 @@ - + @@ -855,7 +855,7 @@ - + @@ -871,13 +871,13 @@ - + - + @@ -890,7 +890,7 @@ - + @@ -898,7 +898,7 @@ - + diff --git a/res/eressea/races.xml b/res/eressea/races.xml index 2ef5950c9..e4e22d0c3 100644 --- a/res/eressea/races.xml +++ b/res/eressea/races.xml @@ -1,7 +1,7 @@ - - + @@ -27,7 +27,7 @@ - + @@ -61,7 +61,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -118,7 +118,7 @@ - + @@ -148,7 +148,7 @@ - + @@ -178,7 +178,7 @@ - + @@ -209,7 +209,7 @@ - + @@ -244,7 +244,7 @@ - + @@ -275,7 +275,7 @@ - + @@ -308,7 +308,7 @@ - + @@ -339,7 +339,7 @@ - + @@ -370,7 +370,7 @@ - + @@ -401,7 +401,7 @@ - + @@ -431,7 +431,7 @@ - + @@ -463,7 +463,7 @@ - + @@ -495,7 +495,7 @@ - + @@ -525,7 +525,7 @@ - + @@ -558,7 +558,7 @@ - + @@ -589,16 +589,16 @@ - + - + - @@ -607,7 +607,7 @@ - + @@ -671,66 +671,66 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -742,7 +742,7 @@ - + @@ -755,7 +755,7 @@ - + @@ -769,20 +769,20 @@ - + - + - + @@ -801,7 +801,7 @@ - + @@ -827,7 +827,7 @@ - + @@ -860,7 +860,7 @@ - + @@ -889,7 +889,7 @@ - + @@ -921,7 +921,7 @@ - + @@ -978,7 +978,7 @@ - + @@ -1011,11 +1011,11 @@ - + - + @@ -1023,7 +1023,7 @@ - + @@ -1037,7 +1037,7 @@ - + @@ -1055,7 +1055,7 @@ - + @@ -1073,7 +1073,7 @@ - + @@ -1089,7 +1089,7 @@ - + @@ -1104,7 +1104,7 @@ - + @@ -1119,7 +1119,7 @@ - + @@ -1134,12 +1134,12 @@ - + - + @@ -1151,7 +1151,7 @@ - @@ -1182,7 +1182,7 @@ - + @@ -1209,7 +1209,7 @@ - + @@ -1241,7 +1241,7 @@ - + @@ -1271,7 +1271,7 @@ - + @@ -1285,13 +1285,13 @@ - + - + @@ -1300,7 +1300,7 @@ - + diff --git a/res/races/aquarian.xml b/res/races/aquarian.xml index 776f17e93..a0e1189b7 100644 --- a/res/races/aquarian.xml +++ b/res/races/aquarian.xml @@ -1,5 +1,5 @@ - + diff --git a/res/races/cat.xml b/res/races/cat.xml index 818b24b36..75bc8019a 100644 --- a/res/races/cat.xml +++ b/res/races/cat.xml @@ -1,5 +1,5 @@ - + diff --git a/res/races/demon.xml b/res/races/demon.xml index a350fef4a..0ce4c86ff 100644 --- a/res/races/demon.xml +++ b/res/races/demon.xml @@ -1,5 +1,5 @@ - - + diff --git a/res/races/elf.xml b/res/races/elf.xml index dfbd2f2ec..ee1278a26 100644 --- a/res/races/elf.xml +++ b/res/races/elf.xml @@ -1,5 +1,5 @@ - + diff --git a/res/races/goblin-2.xml b/res/races/goblin-2.xml index 9a9c265be..ae90c1918 100644 --- a/res/races/goblin-2.xml +++ b/res/races/goblin-2.xml @@ -1,5 +1,5 @@ - - - - + diff --git a/res/races/human.xml b/res/races/human.xml index 2e4b94af2..8f1ad5cb4 100644 --- a/res/races/human.xml +++ b/res/races/human.xml @@ -1,5 +1,5 @@ - + diff --git a/res/races/insect.xml b/res/races/insect.xml index cecbf0193..dc9faa06d 100644 --- a/res/races/insect.xml +++ b/res/races/insect.xml @@ -1,5 +1,5 @@ - + diff --git a/res/races/orc.xml b/res/races/orc.xml index d9d26ab25..4f4d96ed5 100644 --- a/res/races/orc.xml +++ b/res/races/orc.xml @@ -1,5 +1,5 @@ - + diff --git a/res/races/troll.xml b/res/races/troll.xml index a2341851b..c70020fa2 100644 --- a/res/races/troll.xml +++ b/res/races/troll.xml @@ -1,5 +1,5 @@ - -magres = 0.5; /* gets added to skill bonus */ + rc->_magres = 50; /* percentage, gets added to skill bonus */ calculate_armor(dt, 0, 0, &magres); CuAssertDblEquals_Msg(tc, "race bonus", 0.6, magic_resistance(du), 0.01); CuAssertDblEquals_Msg(tc, "race reduction", 0.4, magres, 0.01); - rc->magres = 1.5; /* should not cause negative damage multiplier */ + rc->_magres = 150; /* should not cause negative damage multiplier */ CuAssertDblEquals_Msg(tc, "magic resistance is never > 0.9", 0.9, magic_resistance(du), 0.01); calculate_armor(dt, 0, 0, &magres); CuAssertDblEquals_Msg(tc, "damage reduction is never < 0.1", 0.1, magres, 0.01); diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index 03e210ce0..0cfba4e34 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -458,7 +458,7 @@ static void json_race(cJSON *json, race *rc) { break; case cJSON_Number: if (strcmp(child->string, "magres") == 0) { - rc->magres = (float)child->valuedouble; + rc->_magres = child->valueint; } else if (strcmp(child->string, "maxaura") == 0) { rc->maxaura = (float)child->valuedouble; diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index 93fcd8d10..7ac6a93cc 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -136,7 +136,7 @@ static void test_races(CuTest * tc) { const char * data = "{\"races\": { \"orc\" : { " "\"damage\" : \"1d4\"," - "\"magres\" : 1.0," + "\"magres\" : 100," "\"maxaura\" : 2.0," "\"regaura\" : 3.0," "\"speed\" : 4.0," @@ -163,7 +163,8 @@ static void test_races(CuTest * tc) CuAssertPtrNotNull(tc, rc); CuAssertIntEquals(tc, RCF_NPC | RCF_WALK | RCF_UNDEAD, rc->flags); CuAssertStrEquals(tc, "1d4", rc->def_damage); - CuAssertDblEquals(tc, 1.0, rc->magres, 0.0); + CuAssertIntEquals(tc, 100, rc->_magres); + CuAssertDblEquals(tc, 1.0, rc_magres(rc), 0.0); CuAssertDblEquals(tc, 2.0, rc->maxaura, 0.0); CuAssertDblEquals(tc, 3.0, rc->regaura, 0.0); CuAssertDblEquals(tc, 4.0, rc->speed, 0.0); diff --git a/src/kernel/race.c b/src/kernel/race.c index 1bdba8a1b..3dc708ed1 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -282,6 +282,10 @@ bool r_insectstalled(const region * r) return fval(r->terrain, ARCTIC_REGION); } +double rc_magres(const struct race *rc) { + return rc->_magres / 100.0; +} + const char* rc_name(const race * rc, name_t n, char *name, size_t size) { const char * postfix = 0; if (!rc) { diff --git a/src/kernel/race.h b/src/kernel/race.h index 19b7b7ad3..72e1269c9 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -116,7 +116,7 @@ extern "C" { typedef struct race { char *_name; - float magres; + int _magres; float healing; double maxaura; /* Faktor auf Maximale Aura */ double regaura; /* Faktor auf Regeneration */ @@ -184,6 +184,7 @@ extern "C" { const char * rc_name_s(const race *rc, name_t n); const char * rc_name(const race *rc, name_t n, char *name, size_t size); + double rc_magres(const struct race *rc); /* Flags. Do not reorder these without changing json_race() in jsonconf.c */ #define RCF_NPC (1<<0) /* cannot be the race for a player faction (and other limits?) */ #define RCF_KILLPEASANTS (1<<1) /* a monster that eats peasants */ diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index 663a538ee..d40f252bc 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -23,7 +23,8 @@ static void test_rc_defaults(CuTest *tc) { test_setup(); rc = rc_get_or_create("human"); CuAssertStrEquals(tc, "human", rc->_name); - CuAssertDblEquals(tc, 0.0, rc->magres, 0.0); + CuAssertIntEquals(tc, 0, rc->_magres); + CuAssertDblEquals(tc, 0.0, rc_magres(rc), 0.0); CuAssertDblEquals(tc, 0.0, rc->maxaura, 0.0); CuAssertDblEquals(tc, 1.0, rc->recruit_multi, 0.0); CuAssertDblEquals(tc, 1.0, rc->regaura, 0.0); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 854a6dd4c..3d7276bf3 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1635,7 +1635,7 @@ static int parse_races(xmlDocPtr doc) rc->def_damage = strdup((const char *)propValue); xmlFree(propValue); - rc->magres = (float)xml_fvalue(node, "magres", rc->magres); + rc->_magres = xml_ivalue(node, "magres", rc->_magres); rc->healing = (float)xml_fvalue(node, "healing", rc->healing); rc->maxaura = (float)xml_fvalue(node, "maxaura", rc->maxaura); rc->regaura = (float)xml_fvalue(node, "regaura", rc->regaura); diff --git a/src/magic.c b/src/magic.c index 7e820f9c3..e48ec6d5d 100644 --- a/src/magic.c +++ b/src/magic.c @@ -1149,7 +1149,7 @@ double magic_resistance(unit * target) const curse_type * ct_goodresist = 0, *ct_badresist = 0; const resource_type *rtype; const race *rc = u_race(target); - double probability = rc->magres; + double probability = rc_magres(rc); const plane *pl = rplane(target->region); if (rc == get_race(RC_HIRNTOETER) && !pl) { diff --git a/src/magic.test.c b/src/magic.test.c index befd1986d..29534b33b 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -413,11 +413,11 @@ static void test_magic_resistance(CuTest *tc) { test_setup(); rc = test_create_race("human"); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); - CuAssertDblEquals(tc, rc->magres, magic_resistance(u), 0.01); - rc->magres = 1.0; + CuAssertDblEquals(tc, rc->_magres/100.0, magic_resistance(u), 0.01); + rc->_magres = 100; CuAssertDblEquals_Msg(tc, "magic resistance is capped at 0.9", 0.9, magic_resistance(u), 0.01); rc = test_create_race("braineater"); - rc->magres = 1.0; + rc->_magres = 100; u_setrace(u, rc); CuAssertDblEquals_Msg(tc, "brain eaters outside astral space have 50% magres", 0.5, magic_resistance(u), 0.01); u->region->_plane = get_astralplane(); From fd9583df3d5b72715344fd80fa732c6a9368ce13 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Feb 2017 17:43:40 +0100 Subject: [PATCH 02/14] fix healing for elves in a forest. rename _magres back to magres. rc->parameters is not linked to config_changed invalidation. add tests. --- src/battle.test.c | 4 ++-- src/kernel/jsonconf.c | 2 +- src/kernel/jsonconf.test.c | 2 +- src/kernel/race.c | 2 +- src/kernel/race.h | 2 +- src/kernel/race.test.c | 3 ++- src/kernel/unit.c | 22 ++++++++++++++++++++++ src/kernel/unit.h | 1 + src/kernel/unit.test.c | 28 ++++++++++++++++++++++++++++ src/kernel/xmlreader.c | 2 +- src/laws.c | 26 +------------------------- src/magic.test.c | 6 +++--- src/tests.c | 3 +++ 13 files changed, 67 insertions(+), 36 deletions(-) diff --git a/src/battle.test.c b/src/battle.test.c index 155b3ae0c..03535e16e 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -352,12 +352,12 @@ static void test_magic_resistance(CuTest *tc) calculate_armor(dt, 0, 0, &magres); CuAssertDblEquals_Msg(tc, "skill bonus", 0.1, magic_resistance(du), 0.01); CuAssertDblEquals_Msg(tc, "skill reduction", 0.9, magres, 0.01); - rc->_magres = 50; /* percentage, gets added to skill bonus */ + rc->magres = 50; /* percentage, gets added to skill bonus */ calculate_armor(dt, 0, 0, &magres); CuAssertDblEquals_Msg(tc, "race bonus", 0.6, magic_resistance(du), 0.01); CuAssertDblEquals_Msg(tc, "race reduction", 0.4, magres, 0.01); - rc->_magres = 150; /* should not cause negative damage multiplier */ + rc->magres = 150; /* should not cause negative damage multiplier */ CuAssertDblEquals_Msg(tc, "magic resistance is never > 0.9", 0.9, magic_resistance(du), 0.01); calculate_armor(dt, 0, 0, &magres); CuAssertDblEquals_Msg(tc, "damage reduction is never < 0.1", 0.1, magres, 0.01); diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index 0cfba4e34..dcc4c9c0c 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -458,7 +458,7 @@ static void json_race(cJSON *json, race *rc) { break; case cJSON_Number: if (strcmp(child->string, "magres") == 0) { - rc->_magres = child->valueint; + rc->magres = child->valueint; } else if (strcmp(child->string, "maxaura") == 0) { rc->maxaura = (float)child->valuedouble; diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index 7ac6a93cc..5b0590bf8 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -163,7 +163,7 @@ static void test_races(CuTest * tc) CuAssertPtrNotNull(tc, rc); CuAssertIntEquals(tc, RCF_NPC | RCF_WALK | RCF_UNDEAD, rc->flags); CuAssertStrEquals(tc, "1d4", rc->def_damage); - CuAssertIntEquals(tc, 100, rc->_magres); + CuAssertIntEquals(tc, 100, rc->magres); CuAssertDblEquals(tc, 1.0, rc_magres(rc), 0.0); CuAssertDblEquals(tc, 2.0, rc->maxaura, 0.0); CuAssertDblEquals(tc, 3.0, rc->regaura, 0.0); diff --git a/src/kernel/race.c b/src/kernel/race.c index 3dc708ed1..16eff8695 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -283,7 +283,7 @@ bool r_insectstalled(const region * r) } double rc_magres(const struct race *rc) { - return rc->_magres / 100.0; + return rc->magres / 100.0; } const char* rc_name(const race * rc, name_t n, char *name, size_t size) { diff --git a/src/kernel/race.h b/src/kernel/race.h index 72e1269c9..853e1041f 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -116,7 +116,7 @@ extern "C" { typedef struct race { char *_name; - int _magres; + int magres; float healing; double maxaura; /* Faktor auf Maximale Aura */ double regaura; /* Faktor auf Regeneration */ diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index d40f252bc..c07808099 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -23,8 +23,9 @@ static void test_rc_defaults(CuTest *tc) { test_setup(); rc = rc_get_or_create("human"); CuAssertStrEquals(tc, "human", rc->_name); - CuAssertIntEquals(tc, 0, rc->_magres); + CuAssertIntEquals(tc, 0, rc->magres); CuAssertDblEquals(tc, 0.0, rc_magres(rc), 0.0); + CuAssertDblEquals(tc, 0.0, rc->healing, 0.0); CuAssertDblEquals(tc, 0.0, rc->maxaura, 0.0); CuAssertDblEquals(tc, 1.0, rc->recruit_multi, 0.0); CuAssertDblEquals(tc, 1.0, rc->regaura, 0.0); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 29766d4ef..354a52a06 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -2047,3 +2047,25 @@ bool has_limited_skills(const struct unit * u) return false; } +double u_heal_factor(const unit * u) +{ + const race * rc = u_race(u); + if (rc->healing>0) { + return rc->healing; + } + if (r_isforest(u->region)) { + static int rc_cache; + static const race *rc_elf; + if (rc_changed(&rc_cache)) { + rc_elf = get_race(RC_ELF); + } + if (rc == rc_elf) { + double elf_regen = 1.0; + if (rc->parameters) { + elf_regen = get_param_flt(rc->parameters, "regen.forest", elf_regen); + } + return elf_regen; + } + } + return 1.0; +} diff --git a/src/kernel/unit.h b/src/kernel/unit.h index e846ca1f4..14096c872 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -190,6 +190,7 @@ extern "C" { bool leave(struct unit *u, bool force); bool can_leave(struct unit *u); + double u_heal_factor(const struct unit * u); void u_set_building(struct unit * u, struct building * b); void u_set_ship(struct unit * u, struct ship * sh); void leave_ship(struct unit * u); diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index b0a2891c5..ad4e1761a 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -483,6 +484,32 @@ static void test_name_unit(CuTest *tc) { test_cleanup(); } +static void test_heal_factor(CuTest *tc) { + unit * u; + region *r; + race *rc; + terrain_type *t_plain; + + test_setup(); + t_plain = test_create_terrain("plain", LAND_REGION|FOREST_REGION); + rc = rc_get_or_create("human"); + u = test_create_unit(test_create_faction(rc), r = test_create_region(0, 0, t_plain)); + rsettrees(r, 1, r->terrain->size / TREESIZE); + rsettrees(r, 2, 0); + CuAssertTrue(tc, r_isforest(r)); + CuAssertDblEquals(tc, 1.0, u_heal_factor(u), 0.0); + rc->healing = 2.0; + CuAssertDblEquals(tc, 2.0, u_heal_factor(u), 0.0); + rc->healing = 0.0; + rc = rc_get_or_create("elf"); + CuAssertPtrEquals(tc, (void *)rc, (void *)get_race(RC_ELF)); + u_setrace(u, get_race(RC_ELF)); + CuAssertDblEquals(tc, 1.0, u_heal_factor(u), 0.0); + set_param(&rc->parameters, "regen.forest", "1.5"); + CuAssertDblEquals(tc, 1.5, u_heal_factor(u), 0.0); + test_cleanup(); +} + CuSuite *get_unit_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -507,5 +534,6 @@ CuSuite *get_unit_suite(void) SUITE_ADD_TEST(suite, test_limited_skills); SUITE_ADD_TEST(suite, test_renumber_unit); SUITE_ADD_TEST(suite, test_name_unit); + SUITE_ADD_TEST(suite, test_heal_factor); return suite; } diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 3d7276bf3..87771ba6b 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1635,7 +1635,7 @@ static int parse_races(xmlDocPtr doc) rc->def_damage = strdup((const char *)propValue); xmlFree(propValue); - rc->_magres = xml_ivalue(node, "magres", rc->_magres); + rc->magres = xml_ivalue(node, "magres", rc->magres); rc->healing = (float)xml_fvalue(node, "healing", rc->healing); rc->maxaura = (float)xml_fvalue(node, "maxaura", rc->maxaura); rc->regaura = (float)xml_fvalue(node, "regaura", rc->regaura); diff --git a/src/laws.c b/src/laws.c index 6b0bfda8d..98ff5d9f6 100644 --- a/src/laws.c +++ b/src/laws.c @@ -3271,30 +3271,6 @@ static int use_item(unit * u, const item_type * itype, int amount, struct order } } -static double heal_factor(const unit * u) -{ - const race * rc = u_race(u); - if (rc->healing>0) { - return rc->healing; - } - if (r_isforest(u->region)) { - static int rc_cache; - static const race *rc_elf; - if (rc_changed(&rc_cache)) { - rc_elf = get_race(RC_ELF); - } - if (rc==rc_elf) { - static int config; - static double elf_regen = 1.0; - if (config_changed(&config)) { - elf_regen = get_param_flt(u_race(u)->parameters, "regen.forest", 1.0F); - } - return elf_regen; - } - } - return 1.0; -} - void monthly_healing(void) { region *r; @@ -3334,7 +3310,7 @@ void monthly_healing(void) continue; } - p *= heal_factor(u); + p *= u_heal_factor(u); if (u->hp < umhp) { double maxheal = MAX(u->number, umhp / 20.0); int addhp; diff --git a/src/magic.test.c b/src/magic.test.c index 29534b33b..b32211fd4 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -413,11 +413,11 @@ static void test_magic_resistance(CuTest *tc) { test_setup(); rc = test_create_race("human"); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); - CuAssertDblEquals(tc, rc->_magres/100.0, magic_resistance(u), 0.01); - rc->_magres = 100; + CuAssertDblEquals(tc, rc->magres/100.0, magic_resistance(u), 0.01); + rc->magres = 100; CuAssertDblEquals_Msg(tc, "magic resistance is capped at 0.9", 0.9, magic_resistance(u), 0.01); rc = test_create_race("braineater"); - rc->_magres = 100; + rc->magres = 100; u_setrace(u, rc); CuAssertDblEquals_Msg(tc, "brain eaters outside astral space have 50% magres", 0.5, magic_resistance(u), 0.01); u->region->_plane = get_astralplane(); diff --git a/src/tests.c b/src/tests.c index eb2631afe..5c9ce821d 100644 --- a/src/tests.c +++ b/src/tests.c @@ -217,6 +217,9 @@ terrain_type * test_create_terrain(const char * name, unsigned int flags) { terrain_type * t = get_or_create_terrain(name); + if (flags & LAND_REGION) { + t->size = 1000; + } t->flags = flags; return t; } From 1c347ca5ba8e765246435d361e44f9451ddbc94b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Feb 2017 18:18:55 +0100 Subject: [PATCH 03/14] race.healing is now an int percentage, not a float multiplier --- src/kernel/race.h | 2 +- src/kernel/race.test.c | 2 +- src/kernel/unit.c | 2 +- src/kernel/unit.test.c | 4 ++-- src/kernel/xmlreader.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/kernel/race.h b/src/kernel/race.h index 853e1041f..a7d495f6b 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -117,7 +117,7 @@ extern "C" { typedef struct race { char *_name; int magres; - float healing; + int healing; double maxaura; /* Faktor auf Maximale Aura */ double regaura; /* Faktor auf Regeneration */ double recruit_multi; /* Faktor f�r Bauernverbrauch */ diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index c07808099..01ce41443 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -25,7 +25,7 @@ static void test_rc_defaults(CuTest *tc) { CuAssertStrEquals(tc, "human", rc->_name); CuAssertIntEquals(tc, 0, rc->magres); CuAssertDblEquals(tc, 0.0, rc_magres(rc), 0.0); - CuAssertDblEquals(tc, 0.0, rc->healing, 0.0); + CuAssertIntEquals(tc, 0, rc->healing); CuAssertDblEquals(tc, 0.0, rc->maxaura, 0.0); CuAssertDblEquals(tc, 1.0, rc->recruit_multi, 0.0); CuAssertDblEquals(tc, 1.0, rc->regaura, 0.0); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 354a52a06..329a523c6 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -2051,7 +2051,7 @@ double u_heal_factor(const unit * u) { const race * rc = u_race(u); if (rc->healing>0) { - return rc->healing; + return rc->healing / 100.0; } if (r_isforest(u->region)) { static int rc_cache; diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index ad4e1761a..bf4e9a389 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -498,9 +498,9 @@ static void test_heal_factor(CuTest *tc) { rsettrees(r, 2, 0); CuAssertTrue(tc, r_isforest(r)); CuAssertDblEquals(tc, 1.0, u_heal_factor(u), 0.0); - rc->healing = 2.0; + rc->healing = 200; CuAssertDblEquals(tc, 2.0, u_heal_factor(u), 0.0); - rc->healing = 0.0; + rc->healing = 0; rc = rc_get_or_create("elf"); CuAssertPtrEquals(tc, (void *)rc, (void *)get_race(RC_ELF)); u_setrace(u, get_race(RC_ELF)); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 87771ba6b..638dae189 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1636,7 +1636,7 @@ static int parse_races(xmlDocPtr doc) xmlFree(propValue); rc->magres = xml_ivalue(node, "magres", rc->magres); - rc->healing = (float)xml_fvalue(node, "healing", rc->healing); + rc->healing = (int)(xml_fvalue(node, "healing", rc->healing) * 100); // TODO: store as int in XML rc->maxaura = (float)xml_fvalue(node, "maxaura", rc->maxaura); rc->regaura = (float)xml_fvalue(node, "regaura", rc->regaura); rc->recruitcost = xml_ivalue(node, "recruitcost", rc->recruitcost); From f22cc3b419bb1349f46eedd9e35a85e138842c6f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Feb 2017 19:47:30 +0100 Subject: [PATCH 04/14] add a test for max_spellpoints --- src/magic.test.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/magic.test.c b/src/magic.test.c index b32211fd4..e2c25bf81 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -425,6 +425,29 @@ static void test_magic_resistance(CuTest *tc) { test_cleanup(); } +static void test_max_spellpoints(CuTest *tc) { + unit *u; + race *rc; + + test_setup(); + rc = test_create_race("human"); + u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); + CuAssertIntEquals(tc, 1, max_spellpoints(u->region, u)); + rc->maxaura = 1.0; + CuAssertIntEquals(tc, 1, max_spellpoints(u->region, u)); + rc->maxaura = 2.0; + CuAssertIntEquals(tc, 2, max_spellpoints(u->region, u)); + create_mage(u, M_GRAY); + set_level(u, SK_MAGIC, 1); + CuAssertIntEquals(tc, 3, max_spellpoints(u->region, u)); + set_level(u, SK_MAGIC, 2); + CuAssertIntEquals(tc, 9, max_spellpoints(u->region, u)); + // permanent aura loss: + CuAssertIntEquals(tc, 7, change_maxspellpoints(u, -2)); + CuAssertIntEquals(tc, 7, max_spellpoints(u->region, u)); + test_cleanup(); +} + CuSuite *get_magic_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -441,5 +464,6 @@ CuSuite *get_magic_suite(void) SUITE_ADD_TEST(suite, test_set_post_combatspell); SUITE_ADD_TEST(suite, test_hasspell); SUITE_ADD_TEST(suite, test_magic_resistance); + SUITE_ADD_TEST(suite, test_max_spellpoints); return suite; } From e51742da9052b018c0fb0020d4652b4045c69940 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Feb 2017 19:50:48 +0100 Subject: [PATCH 05/14] use rc_maxaura wrapper everywhere. --- src/kernel/race.c | 6 +++++- src/kernel/race.h | 1 + src/kernel/race.test.c | 2 +- src/magic.c | 6 +++--- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/kernel/race.c b/src/kernel/race.c index 16eff8695..75ff16436 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -282,10 +282,14 @@ bool r_insectstalled(const region * r) return fval(r->terrain, ARCTIC_REGION); } -double rc_magres(const struct race *rc) { +double rc_magres(const race *rc) { return rc->magres / 100.0; } +double rc_maxaura(const race *rc) { + return rc->maxaura; +} + const char* rc_name(const race * rc, name_t n, char *name, size_t size) { const char * postfix = 0; if (!rc) { diff --git a/src/kernel/race.h b/src/kernel/race.h index a7d495f6b..7acc7fea5 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -185,6 +185,7 @@ extern "C" { const char * rc_name(const race *rc, name_t n, char *name, size_t size); double rc_magres(const struct race *rc); + double rc_maxaura(const struct race *rc); /* Flags. Do not reorder these without changing json_race() in jsonconf.c */ #define RCF_NPC (1<<0) /* cannot be the race for a player faction (and other limits?) */ #define RCF_KILLPEASANTS (1<<1) /* a monster that eats peasants */ diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index 01ce41443..eaf497168 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -26,7 +26,7 @@ static void test_rc_defaults(CuTest *tc) { CuAssertIntEquals(tc, 0, rc->magres); CuAssertDblEquals(tc, 0.0, rc_magres(rc), 0.0); CuAssertIntEquals(tc, 0, rc->healing); - CuAssertDblEquals(tc, 0.0, rc->maxaura, 0.0); + CuAssertDblEquals(tc, 0.0, rc_maxaura(rc), 0.0); CuAssertDblEquals(tc, 1.0, rc->recruit_multi, 0.0); CuAssertDblEquals(tc, 1.0, rc->regaura, 0.0); CuAssertDblEquals(tc, 1.0, rc->speed, 0.0); diff --git a/src/magic.c b/src/magic.c index e48ec6d5d..89774e96a 100644 --- a/src/magic.c +++ b/src/magic.c @@ -719,7 +719,7 @@ static int use_item_aura(const region * r, const unit * u) int sk, n; sk = effskill(u, SK_MAGIC, r); - n = (int)(sk * sk * u_race(u)->maxaura / 4); + n = (int)(sk * sk * rc_maxaura(u_race(u)) / 4); return n; } @@ -727,13 +727,13 @@ static int use_item_aura(const region * r, const unit * u) int max_spellpoints(const region * r, const unit * u) { int sk; - double n, msp; + double n, msp = 0; double potenz = 2.1; double divisor = 1.2; const struct resource_type *rtype; sk = effskill(u, SK_MAGIC, r); - msp = u_race(u)->maxaura * (pow(sk, potenz) / divisor + 1) + get_spchange(u); + msp = rc_maxaura(u_race(u)) * (pow(sk, potenz) / divisor + 1) + get_spchange(u); rtype = rt_find("aurafocus"); if (rtype && i_get(u->items, rtype->itype) > 0) { From 250227cad245707c8ed17857eabb9143c6b6ca07 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Feb 2017 20:06:01 +0100 Subject: [PATCH 06/14] store maxaura as an integer, not a float. --- src/kernel/jsonconf.c | 2 +- src/kernel/jsonconf.test.c | 5 +++-- src/kernel/race.c | 2 +- src/kernel/race.h | 2 +- src/kernel/xmlreader.c | 2 +- src/magic.test.c | 4 ++-- src/tests.c | 2 +- 7 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index dcc4c9c0c..7a074a410 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -461,7 +461,7 @@ static void json_race(cJSON *json, race *rc) { rc->magres = child->valueint; } else if (strcmp(child->string, "maxaura") == 0) { - rc->maxaura = (float)child->valuedouble; + rc->maxaura = child->valueint; } else if (strcmp(child->string, "regaura") == 0) { rc->regaura = (float)child->valuedouble; diff --git a/src/kernel/jsonconf.test.c b/src/kernel/jsonconf.test.c index 5b0590bf8..7c591f075 100644 --- a/src/kernel/jsonconf.test.c +++ b/src/kernel/jsonconf.test.c @@ -137,7 +137,7 @@ static void test_races(CuTest * tc) const char * data = "{\"races\": { \"orc\" : { " "\"damage\" : \"1d4\"," "\"magres\" : 100," - "\"maxaura\" : 2.0," + "\"maxaura\" : 200," "\"regaura\" : 3.0," "\"speed\" : 4.0," "\"recruitcost\" : 1," @@ -165,7 +165,8 @@ static void test_races(CuTest * tc) CuAssertStrEquals(tc, "1d4", rc->def_damage); CuAssertIntEquals(tc, 100, rc->magres); CuAssertDblEquals(tc, 1.0, rc_magres(rc), 0.0); - CuAssertDblEquals(tc, 2.0, rc->maxaura, 0.0); + CuAssertIntEquals(tc, 200, rc->maxaura); + CuAssertDblEquals(tc, 2.0, rc_maxaura(rc), 0.0); CuAssertDblEquals(tc, 3.0, rc->regaura, 0.0); CuAssertDblEquals(tc, 4.0, rc->speed, 0.0); CuAssertIntEquals(tc, 1, rc->recruitcost); diff --git a/src/kernel/race.c b/src/kernel/race.c index 75ff16436..59d263108 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -287,7 +287,7 @@ double rc_magres(const race *rc) { } double rc_maxaura(const race *rc) { - return rc->maxaura; + return rc->maxaura / 100.0; } const char* rc_name(const race * rc, name_t n, char *name, size_t size) { diff --git a/src/kernel/race.h b/src/kernel/race.h index 7acc7fea5..82d8cdf69 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -118,7 +118,7 @@ extern "C" { char *_name; int magres; int healing; - double maxaura; /* Faktor auf Maximale Aura */ + int maxaura; /* Faktor auf Maximale Aura */ double regaura; /* Faktor auf Regeneration */ double recruit_multi; /* Faktor f�r Bauernverbrauch */ int index; diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 638dae189..d75a6583f 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1637,7 +1637,7 @@ static int parse_races(xmlDocPtr doc) rc->magres = xml_ivalue(node, "magres", rc->magres); rc->healing = (int)(xml_fvalue(node, "healing", rc->healing) * 100); // TODO: store as int in XML - rc->maxaura = (float)xml_fvalue(node, "maxaura", rc->maxaura); + rc->maxaura = (int)(xml_fvalue(node, "maxaura", rc->maxaura) * 100); // TODO: store as int in XML rc->regaura = (float)xml_fvalue(node, "regaura", rc->regaura); rc->recruitcost = xml_ivalue(node, "recruitcost", rc->recruitcost); rc->maintenance = xml_ivalue(node, "maintenance", rc->maintenance); diff --git a/src/magic.test.c b/src/magic.test.c index e2c25bf81..4a6078589 100644 --- a/src/magic.test.c +++ b/src/magic.test.c @@ -433,9 +433,9 @@ static void test_max_spellpoints(CuTest *tc) { rc = test_create_race("human"); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); CuAssertIntEquals(tc, 1, max_spellpoints(u->region, u)); - rc->maxaura = 1.0; + rc->maxaura = 100; CuAssertIntEquals(tc, 1, max_spellpoints(u->region, u)); - rc->maxaura = 2.0; + rc->maxaura = 200; CuAssertIntEquals(tc, 2, max_spellpoints(u->region, u)); create_mage(u, M_GRAY); set_level(u, SK_MAGIC, 1); diff --git a/src/tests.c b/src/tests.c index 5c9ce821d..6a43e6e79 100644 --- a/src/tests.c +++ b/src/tests.c @@ -40,7 +40,7 @@ struct race *test_create_race(const char *name) race *rc = rc_get_or_create(name); rc->maintenance = 10; rc->hitpoints = 20; - rc->maxaura = 1.0; + rc->maxaura = 100; rc->ec_flags |= GETITEM; rc->battle_flags = BF_EQUIPMENT; return rc; From 70b12ae6ca9fc34ed124db53d8e1b41a78736e16 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Feb 2017 20:16:44 +0100 Subject: [PATCH 07/14] refactor handling of race.param in XML --- src/kernel/faction.c | 2 +- src/kernel/xmlreader.c | 23 +++++++++++------------ src/upkeep.c | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/kernel/faction.c b/src/kernel/faction.c index b7115c62f..e3cb4508a 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -758,7 +758,7 @@ int count_migrants(const faction * f) int count_maxmigrants(const faction * f) { - int formula = get_param_int(f->race->parameters, "migrants.formula", 0); + int formula = f->race->parameters ? get_param_int(f->race->parameters, "migrants.formula", MIGRANTS_NONE) : MIGRANTS_NONE; if (formula == MIGRANTS_LOG10) { int nsize = count_all(f); diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index d75a6583f..9b1f5532c 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1573,17 +1573,6 @@ static int parse_spells(xmlDocPtr doc) return 0; } -static void parse_param(struct param **params, xmlNodePtr node) -{ - xmlChar *propName = xmlGetProp(node, BAD_CAST "name"); - xmlChar *propValue = xmlGetProp(node, BAD_CAST "value"); - - set_param(params, (const char *)propName, (const char *)propValue); - - xmlFree(propName); - xmlFree(propValue); -} - static void parse_ai(race * rc, xmlNodePtr node) { int n; @@ -1737,12 +1726,22 @@ static int parse_races(xmlDocPtr doc) if (xml_bvalue(node, "noattack", false)) rc->battle_flags |= BF_NO_ATTACK; + rc->recruit_multi = 1.0; for (child = node->children; child; child = child->next) { if (strcmp((const char *)child->name, "ai") == 0) { parse_ai(rc, child); } else if (strcmp((const char *)child->name, "param") == 0) { - parse_param(&rc->parameters, child); + xmlChar *propName = xmlGetProp(child, BAD_CAST "name"); + xmlChar *propValue = xmlGetProp(child, BAD_CAST "value"); + if (strcmp((const char *)propName, "recruit_multi")==0) { + rc->recruit_multi = atof((const char *)propValue); + } + else { + set_param(&rc->parameters, (const char *)propName, (const char *)propValue); + } + xmlFree(propName); + xmlFree(propValue); } } rc->recruit_multi = get_param_flt(rc->parameters, "recruit_multi", 1.0); diff --git a/src/upkeep.c b/src/upkeep.c index 94cbc341d..c53c321d0 100644 --- a/src/upkeep.c +++ b/src/upkeep.c @@ -59,7 +59,7 @@ static void help_feed(unit * donor, unit * u, int *need_p) } static const char *hunger_damage(const race *rc) { - const char * damage = get_param(rc->parameters, "hunger.damage"); + const char * damage = rc->parameters ? get_param(rc->parameters, "hunger.damage") : NULL; if (!damage) { damage = config_get("hunger.damage"); } From bb37e423e1f434d2b8c707d9e4b5f16d8cc7c0de Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Feb 2017 20:35:15 +0100 Subject: [PATCH 08/14] use UFL_FOLLOWED for optimization. --- src/move.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/move.c b/src/move.c index 0184d22ca..f06a0b901 100644 --- a/src/move.c +++ b/src/move.c @@ -2061,7 +2061,9 @@ static const region_list *travel_i(unit * u, const region_list * route_begin, route_end = cap_route(r, route_begin, route_end, movement_speed(u)); route_end = travel_route(u, route_begin, route_end, ord, mode); - get_followers(u, r, route_end, followers); + if (u->flags&UFL_FOLLOWED) { + get_followers(u, r, route_end, followers); + } /* transportation */ for (ord = u->orders; ord; ord = ord->next) { From 644a6019a62382246aee125c15f8d702acf0f094 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Feb 2017 21:19:39 +0100 Subject: [PATCH 09/14] do not call isdigit with a negative value. http://bugs.eressea.de/view.php?id=1987#c6941 --- src/spy.c | 2 +- src/util/base36.c | 4 ++-- src/util/dice.c | 2 +- src/util/parser.c | 4 ++-- src/util/translation.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/spy.c b/src/spy.c index eb58f792a..0ca3050c2 100644 --- a/src/spy.c +++ b/src/spy.c @@ -229,7 +229,7 @@ int setstealth_cmd(unit * u, struct order *ord) return 0; } - if (isdigit(s[0])) { + if (isdigit(*(const unsigned char *)s)) { /* Tarnungslevel setzen */ level = atoi((const char *)s); if (level > effskill(u, SK_STEALTH, 0)) { diff --git a/src/util/base36.c b/src/util/base36.c index 7edb46027..285e9760e 100644 --- a/src/util/base36.c +++ b/src/util/base36.c @@ -39,9 +39,9 @@ int atoi36(const char *str) while (isalnum(*(unsigned char *)s)) { if (isupper(*(unsigned char *)s)) i = i * 36 + (*s) - 'A' + 10; - else if (islower(*(unsigned char *)s)) + else if (islower(*s)) i = i * 36 + (*s) - 'a' + 10; - else if (isdigit(*(unsigned char *)s)) + else if (isdigit(*s)) i = i * 36 + (*s) - '0'; else break; diff --git a/src/util/dice.c b/src/util/dice.c index e28a4bccd..6fa50261d 100644 --- a/src/util/dice.c +++ b/src/util/dice.c @@ -49,7 +49,7 @@ static int term_eval(const char **sptr) int state = 1; for (;;) { - if (isdigit(*(unsigned char *)c)) { + if (isdigit(*(const unsigned char *)c)) { k = k * 10 + (*c - '0'); } else if (*c == '+' || *c == '-' || *c == 0 || *c == '*' || *c == ')' diff --git a/src/util/parser.c b/src/util/parser.c index bbdb5ac7e..fca066cb1 100644 --- a/src/util/parser.c +++ b/src/util/parser.c @@ -6,7 +6,6 @@ #include #include -#include #include #include @@ -251,7 +250,8 @@ unsigned int atoip(const char *s) int n; assert(s); - n = isdigit(s[0]) ? atoi(s) : 0; + n = (s[0] >='0' && s[0]<='9'); + n = n ? atoi(s) : 0; if (n < 0) n = 0; diff --git a/src/util/translation.c b/src/util/translation.c index c733cc272..fb89a5af9 100644 --- a/src/util/translation.c +++ b/src/util/translation.c @@ -354,7 +354,7 @@ static const char *parse(opstack ** stack, const char *inn, return parse_symbol(stack, ++b, userdata); break; default: - if (isdigit(*(unsigned char *)b) || *b == '-' || *b == '+') { + if (isdigit(*(const unsigned char *)b) || *b == '-' || *b == '+') { return parse_int(stack, b); } else From 2be1868ff0471a9278abf510f6ac02756178286a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 3 Feb 2017 21:48:03 +0100 Subject: [PATCH 10/14] Antiemagiekristall Meldung geht an die Region. Nicht nur an die Partei, die es zaubert. http://bugs.eressea.de/view.php?id=1987 --- res/core/messages.xml | 5 ++--- src/items.c | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/res/core/messages.xml b/res/core/messages.xml index 6892ec4e5..c28670d65 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -1910,10 +1910,9 @@ - - "$unit($unit) benutzt in $region($region) einen Antimagiekristall." - "$unit($unit) uses an antimagic crystal in $region($region)." + "$unit($unit) benutzt einen Antimagiekristall." + "$unit($unit) uses an antimagic crystal." diff --git a/src/items.c b/src/items.c index 6e995edaa..bb5009038 100644 --- a/src/items.c +++ b/src/items.c @@ -167,8 +167,7 @@ struct order *ord) } } use_pooled(u, rt_crystal, GET_DEFAULT, amount); - ADDMSG(&u->faction->msgs, msg_message("use_antimagiccrystal", - "unit region", u, r)); + ADDMSG(&u->region->msgs, msg_message("use_antimagiccrystal", "unit", u)); return 0; } From 2ecbf89f1a6e4145956e416007a8d22e771aaed3 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 4 Feb 2017 23:16:16 +0100 Subject: [PATCH 11/14] clean up and test various race.parameters --- src/battle.c | 6 +----- src/battle.test.c | 3 +++ src/kernel/faction.c | 5 +---- src/kernel/faction.test.c | 21 ++++++++++++++++++++- src/kernel/race.c | 9 +++++++++ src/kernel/race.h | 6 ++++++ src/kernel/race.test.c | 1 + src/market.c | 4 ++-- src/market.h | 4 ++++ src/market.test.c | 14 ++++++++++++++ 10 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/battle.c b/src/battle.c index ad613a69f..9316d35dd 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1014,17 +1014,13 @@ static void vampirism(troop at, int damage) #define MAXRACES 128 -static int armor_bonus(const race *rc) { - return get_param_int(rc->parameters, "armor.stamina", -1); -} - int natural_armor(unit * du) { const race *rc = u_race(du); int an; assert(rc); - an = armor_bonus(rc); + an = rc_armor_bonus(rc); if (an > 0) { int sk = effskill(du, SK_STAMINA, 0); return rc->armor + sk / an; diff --git a/src/battle.test.c b/src/battle.test.c index 03535e16e..e8187c772 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -223,10 +223,13 @@ static void test_natural_armor(CuTest * tc) rc = test_create_race("human"); u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); set_level(u, SK_STAMINA, 2); + CuAssertIntEquals(tc, 0, rc_armor_bonus(rc)); CuAssertIntEquals(tc, 0, natural_armor(u)); set_param(&rc->parameters, "armor.stamina", "1"); + CuAssertIntEquals(tc, 1, rc_armor_bonus(rc)); CuAssertIntEquals(tc, 2, natural_armor(u)); set_param(&rc->parameters, "armor.stamina", "2"); + CuAssertIntEquals(tc, 2, rc_armor_bonus(rc)); CuAssertIntEquals(tc, 1, natural_armor(u)); test_cleanup(); } diff --git a/src/kernel/faction.c b/src/kernel/faction.c index e3cb4508a..1c8ff4cb8 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -753,12 +753,9 @@ int count_migrants(const faction * f) return count_faction(f, COUNT_MIGRANTS); } -#define MIGRANTS_NONE 0 -#define MIGRANTS_LOG10 1 - int count_maxmigrants(const faction * f) { - int formula = f->race->parameters ? get_param_int(f->race->parameters, "migrants.formula", MIGRANTS_NONE) : MIGRANTS_NONE; + int formula = rc_migrants_formula(f->race); if (formula == MIGRANTS_LOG10) { int nsize = count_all(f); diff --git a/src/kernel/faction.test.c b/src/kernel/faction.test.c index b18121e2d..43956df59 100644 --- a/src/kernel/faction.test.c +++ b/src/kernel/faction.test.c @@ -3,9 +3,10 @@ #include #include #include +#include #include #include -#include +#include #include #include #include @@ -191,9 +192,27 @@ static void test_set_origin_bug(CuTest *tc) { test_cleanup(); } +static void test_max_migrants(CuTest *tc) { + faction *f; + unit *u; + race *rc; + + test_setup(); + rc = test_create_race("human"); + f = test_create_faction(rc); + u = test_create_unit(f, test_create_region(0, 0, 0)); + CuAssertIntEquals(tc, 0, count_maxmigrants(f)); + set_param(&rc->parameters, "migrants.formula", "1"); + CuAssertIntEquals(tc, 0, count_maxmigrants(f)); + scale_number(u, 250); + CuAssertIntEquals(tc, 13, count_maxmigrants(f)); + test_cleanup(); +} + CuSuite *get_faction_suite(void) { CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_max_migrants); SUITE_ADD_TEST(suite, test_addfaction); SUITE_ADD_TEST(suite, test_remove_empty_factions); SUITE_ADD_TEST(suite, test_destroyfaction_allies); diff --git a/src/kernel/race.c b/src/kernel/race.c index 59d263108..123d64022 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -290,6 +290,15 @@ double rc_maxaura(const race *rc) { return rc->maxaura / 100.0; } +int rc_armor_bonus(const race *rc) { + return get_param_int(rc->parameters, "armor.stamina", 0); +} + +int rc_migrants_formula(const race *rc) +{ + return rc->parameters ? get_param_int(rc->parameters, "migrants.formula", MIGRANTS_NONE) : MIGRANTS_NONE; +} + const char* rc_name(const race * rc, name_t n, char *name, size_t size) { const char * postfix = 0; if (!rc) { diff --git a/src/kernel/race.h b/src/kernel/race.h index 82d8cdf69..7c4600ae5 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -186,6 +186,12 @@ extern "C" { double rc_magres(const struct race *rc); double rc_maxaura(const struct race *rc); + int rc_armor_bonus(const struct race *rc); + +#define MIGRANTS_NONE 0 +#define MIGRANTS_LOG10 1 + int rc_migrants_formula(const race *rc); + /* Flags. Do not reorder these without changing json_race() in jsonconf.c */ #define RCF_NPC (1<<0) /* cannot be the race for a player faction (and other limits?) */ #define RCF_KILLPEASANTS (1<<1) /* a monster that eats peasants */ diff --git a/src/kernel/race.test.c b/src/kernel/race.test.c index eaf497168..b730676a4 100644 --- a/src/kernel/race.test.c +++ b/src/kernel/race.test.c @@ -23,6 +23,7 @@ static void test_rc_defaults(CuTest *tc) { test_setup(); rc = rc_get_or_create("human"); CuAssertStrEquals(tc, "human", rc->_name); + CuAssertIntEquals(tc, 0, rc_armor_bonus(rc)); CuAssertIntEquals(tc, 0, rc->magres); CuAssertDblEquals(tc, 0.0, rc_magres(rc), 0.0); CuAssertIntEquals(tc, 0, rc->healing); diff --git a/src/market.c b/src/market.c index 42819325f..254d3a483 100644 --- a/src/market.c +++ b/src/market.c @@ -66,7 +66,7 @@ attrib_type at_market = { NULL, NULL, NULL, ATF_UNIQUE }; -static int rc_luxury_trade(const struct race *rc) +int rc_luxury_trade(const struct race *rc) { if (rc) { return get_param_int(rc->parameters, "luxury_trade", 1000); @@ -74,7 +74,7 @@ static int rc_luxury_trade(const struct race *rc) return 1000; } -static int rc_herb_trade(const struct race *rc) +int rc_herb_trade(const struct race *rc) { if (rc) { return get_param_int(rc->parameters, "herb_trade", 500); diff --git a/src/market.h b/src/market.h index 74dc8db17..8f1d39eb4 100644 --- a/src/market.h +++ b/src/market.h @@ -19,10 +19,14 @@ without prior permission by the authors of Eressea. extern "C" { #endif struct building; + struct race; bool markets_module(void); void do_markets(void); + int rc_luxury_trade(const struct race *rc); + int rc_herb_trade(const struct race *rc); + #ifdef __cplusplus } #endif diff --git a/src/market.test.c b/src/market.test.c index 6f1d74b88..1e0195a57 100644 --- a/src/market.test.c +++ b/src/market.test.c @@ -80,9 +80,23 @@ static void test_market_curse(CuTest * tc) CuAssertIntEquals(tc, 35, i_get(u->items, ltype)); } +static void test_rc_trade(CuTest *tc) { + race *rc; + test_setup(); + rc = test_create_race("human"); + CuAssertIntEquals(tc, 1000, rc_luxury_trade(rc)); + CuAssertIntEquals(tc, 500, rc_herb_trade(rc)); + set_param(&rc->parameters, "luxury_trade", "100"); + set_param(&rc->parameters, "herb_trade", "50"); + CuAssertIntEquals(tc, 100, rc_luxury_trade(rc)); + CuAssertIntEquals(tc, 50, rc_herb_trade(rc)); + test_cleanup(); +} + CuSuite *get_market_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_market_curse); + SUITE_ADD_TEST(suite, test_rc_trade); return suite; } From 3b3e39a3192953e63281b5c7ce00972d20a6930f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 4 Feb 2017 23:21:36 +0100 Subject: [PATCH 12/14] optimization: elf-special "regen.forest" is now a config. this is an E3 feature eliminates rc.parameters for elves allows use of a local cached static --- conf/e3/config.json | 1 + res/e3a/races.xml | 1 - src/kernel/unit.c | 7 ++++--- src/kernel/unit.test.c | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/conf/e3/config.json b/conf/e3/config.json index 8783055b8..1cecc89d2 100644 --- a/conf/e3/config.json +++ b/conf/e3/config.json @@ -42,6 +42,7 @@ "nmr.timeout": 5, "nmr.removenewbie": 0, "GiveRestriction": 3, + "healing.forest": 2.0, "hunger.long": false, "hunger.damage": "1d9+9", "hunger.demons.skill": true, diff --git a/res/e3a/races.xml b/res/e3a/races.xml index 3402fdb73..4fcc76e4f 100644 --- a/res/e3a/races.xml +++ b/res/e3a/races.xml @@ -127,7 +127,6 @@ - diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 329a523c6..27a296a15 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -2060,9 +2060,10 @@ double u_heal_factor(const unit * u) rc_elf = get_race(RC_ELF); } if (rc == rc_elf) { - double elf_regen = 1.0; - if (rc->parameters) { - elf_regen = get_param_flt(rc->parameters, "regen.forest", elf_regen); + static int cache; + static double elf_regen; + if (config_changed(&cache)) { + elf_regen = config_get_flt("healing.forest", 1.0); } return elf_regen; } diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index bf4e9a389..1ddf6282e 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -505,7 +505,7 @@ static void test_heal_factor(CuTest *tc) { CuAssertPtrEquals(tc, (void *)rc, (void *)get_race(RC_ELF)); u_setrace(u, get_race(RC_ELF)); CuAssertDblEquals(tc, 1.0, u_heal_factor(u), 0.0); - set_param(&rc->parameters, "regen.forest", "1.5"); + config_set("healing.forest", "1.5"); CuAssertDblEquals(tc, 1.5, u_heal_factor(u), 0.0); test_cleanup(); } From bdb50eab7545e76c686416ed8579ad8b391f809c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 4 Feb 2017 23:42:50 +0100 Subject: [PATCH 13/14] make migrants.formula a flag. lookup in race.parameters was slow. there is only one formula, anyhow. --- src/kernel/faction.c | 2 +- src/kernel/faction.test.c | 2 +- src/kernel/race.c | 2 +- src/kernel/race.h | 1 + src/kernel/xmlreader.c | 5 +++++ 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 1c8ff4cb8..28ac2e203 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -565,7 +565,7 @@ bool valid_race(const struct faction *f, const struct race *rc) else { const char *str = get_param(f->race->parameters, "other_race"); if (str) - return (bool)(rc_find(str) == rc); + return rc_find(str) == rc; return false; } } diff --git a/src/kernel/faction.test.c b/src/kernel/faction.test.c index 43956df59..1b1a0236b 100644 --- a/src/kernel/faction.test.c +++ b/src/kernel/faction.test.c @@ -202,7 +202,7 @@ static void test_max_migrants(CuTest *tc) { f = test_create_faction(rc); u = test_create_unit(f, test_create_region(0, 0, 0)); CuAssertIntEquals(tc, 0, count_maxmigrants(f)); - set_param(&rc->parameters, "migrants.formula", "1"); + rc->flags |= RCF_MIGRANTS; CuAssertIntEquals(tc, 0, count_maxmigrants(f)); scale_number(u, 250); CuAssertIntEquals(tc, 13, count_maxmigrants(f)); diff --git a/src/kernel/race.c b/src/kernel/race.c index 123d64022..7f6fe15c2 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -296,7 +296,7 @@ int rc_armor_bonus(const race *rc) { int rc_migrants_formula(const race *rc) { - return rc->parameters ? get_param_int(rc->parameters, "migrants.formula", MIGRANTS_NONE) : MIGRANTS_NONE; + return (rc->flags&RCF_MIGRANTS) ? MIGRANTS_LOG10 : MIGRANTS_NONE; } const char* rc_name(const race * rc, name_t n, char *name, size_t size) { diff --git a/src/kernel/race.h b/src/kernel/race.h index 7c4600ae5..67eea00f4 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -223,6 +223,7 @@ extern "C" { #define RCF_STONEGOLEM (1<<27) /* race gets stonegolem properties */ #define RCF_IRONGOLEM (1<<28) /* race gets irongolem properties */ #define RCF_ATTACK_MOVED (1<<29) /* may attack if it has moved */ +#define RCF_MIGRANTS (1<<30) /* may have migrant units (human bonus) */ /* Economic flags */ #define ECF_KEEP_ITEM (1<<1) /* gibt Gegenst�nde weg */ diff --git a/src/kernel/xmlreader.c b/src/kernel/xmlreader.c index 9b1f5532c..a0172313a 100644 --- a/src/kernel/xmlreader.c +++ b/src/kernel/xmlreader.c @@ -1737,6 +1737,11 @@ static int parse_races(xmlDocPtr doc) if (strcmp((const char *)propName, "recruit_multi")==0) { rc->recruit_multi = atof((const char *)propValue); } + else if (strcmp((const char *)propName, "migrants.formula") == 0) { + if (propValue[0] == '1') { + rc->flags |= RCF_MIGRANTS; + } + } else { set_param(&rc->parameters, (const char *)propName, (const char *)propValue); } From 0b3d15f4b3deb5f6d62df40ef9176eb28359f5fa Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 4 Feb 2017 23:46:26 +0100 Subject: [PATCH 14/14] eliminate unused other_cost parameter. cost of other races is defined by their recruitcost. --- res/e3a/races.xml | 3 --- res/races/goblin-2.xml | 1 - res/races/goblin-3.xml | 1 - src/economy.c | 1 - 4 files changed, 6 deletions(-) diff --git a/res/e3a/races.xml b/res/e3a/races.xml index 4fcc76e4f..7e75f3fd4 100644 --- a/res/e3a/races.xml +++ b/res/e3a/races.xml @@ -36,7 +36,6 @@ - @@ -51,7 +50,6 @@ - @@ -80,7 +78,6 @@ - diff --git a/res/races/goblin-2.xml b/res/races/goblin-2.xml index ae90c1918..f8964d7c0 100644 --- a/res/races/goblin-2.xml +++ b/res/races/goblin-2.xml @@ -8,7 +8,6 @@ getitem="yes" equipment="yes" healing="2.0"> - diff --git a/res/races/goblin-3.xml b/res/races/goblin-3.xml index aa0c8fddb..4ad83967d 100644 --- a/res/races/goblin-3.xml +++ b/res/races/goblin-3.xml @@ -8,7 +8,6 @@ getitem="yes" equipment="yes" healing="2.0"> - diff --git a/src/economy.c b/src/economy.c index 16b201555..2d9fe6666 100644 --- a/src/economy.c +++ b/src/economy.c @@ -427,7 +427,6 @@ static int recruit_cost(const faction * f, const race * rc) } else if (valid_race(f, rc)) { return rc->recruitcost; - /* return get_param_int(f->race->parameters, "other_cost", -1); */ } return -1; }