From 4c32fe19ee16a750eb6f0a5036bde2ba1476df7e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 21 Aug 2015 10:54:09 +0200 Subject: [PATCH 1/9] eliminate some dead code that was still marked with TODO. --- src/battle.c | 9 ----- src/bindings.c | 93 -------------------------------------------------- src/laws.c | 4 --- 3 files changed, 106 deletions(-) diff --git a/src/battle.c b/src/battle.c index ebfde1548..c6e90a9c8 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1223,11 +1223,6 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile) res -= magic_resistance(du) * 3.0; if (u_race(du)->battle_flags & BF_EQUIPMENT) { -#ifdef TODO_RUNESWORD - /* Runenschwert gibt im Kampf 80% Resistenzbonus */ - if (dwp == WP_RUNESWORD) - res -= 0.80; -#endif /* der Effekt von Laen steigt nicht linear */ if (armor && fval(armor, ATF_LAEN)) res *= (1 - armor->magres); @@ -1304,10 +1299,6 @@ terminate(troop dt, troop at, int type, const char *damage, bool missile) da, ar, df->person[dt.index].hp + rda, df->person[dt.index].hp); } if (u_race(au) == get_race(RC_DAEMON)) { -#ifdef TODO_RUNESWORD - if (select_weapon(dt, 0, -1) == WP_RUNESWORD) - continue; -#endif if (!(df->person[dt.index].flags & (FL_COURAGE | FL_DAZZLED))) { df->person[dt.index].flags |= FL_DAZZLED; df->person[dt.index].defence--; diff --git a/src/bindings.c b/src/bindings.c index 3e842ba92..0240a5b49 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -681,80 +681,6 @@ static int tolua_set_alliance_name(lua_State * L) return 0; } -#ifdef WRITE_SPELLS -#include -#include -#include -#include -static int tolua_write_spells(lua_State * L) -{ - spell_f fun = (spell_f) get_function("lua_castspell"); - const char *filename = "magic.xml"; - xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); - xmlNodePtr root = xmlNewNode(NULL, BAD_CAST "spells"); - quicklist *ql; - int qi; - for (ql = spells, qi = 0; ql; ql_advance(&ql, &qi, 1)) { - spell *sp = (spell *) ql_get(ql, qi); - if (sp->cast != fun) { - int combat = 0; - xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "spell"); - xmlNewProp(node, BAD_CAST "name", BAD_CAST sp->sname); - xmlNewProp(node, BAD_CAST "type", BAD_CAST magic_school[sp->magietyp]); - xmlNewProp(node, BAD_CAST "rank", xml_i(sp->rank)); - xmlNewProp(node, BAD_CAST "level", xml_i(sp->level)); - xmlNewProp(node, BAD_CAST "index", xml_i(sp->id)); - if (sp->syntax) - xmlNewProp(node, BAD_CAST "syntax", BAD_CAST sp->syntax); - if (sp->parameter) - xmlNewProp(node, BAD_CAST "parameters", BAD_CAST sp->parameter); - if (sp->components) { - spell_component *comp = sp->components; - for (; comp->type != 0; ++comp) { - static const char *costs[] = { "fixed", "level", "linear" }; - xmlNodePtr cnode = xmlNewNode(NULL, BAD_CAST "resource"); - xmlNewProp(cnode, BAD_CAST "name", BAD_CAST comp->type->_name); - xmlNewProp(cnode, BAD_CAST "amount", xml_i(comp->amount)); - xmlNewProp(cnode, BAD_CAST "cost", BAD_CAST costs[comp->cost]); - xmlAddChild(node, cnode); - }} - if (sp->sptyp & TESTCANSEE) { - xmlNewProp(node, BAD_CAST "los", BAD_CAST "true"); - } - if (sp->sptyp & ONSHIPCAST) { - xmlNewProp(node, BAD_CAST "ship", BAD_CAST "true"); - } - if (sp->sptyp & OCEANCASTABLE) { - xmlNewProp(node, BAD_CAST "ocean", BAD_CAST "true"); - } - if (sp->sptyp & FARCASTING) { - xmlNewProp(node, BAD_CAST "far", BAD_CAST "true"); - } - if (sp->sptyp & SPELLLEVEL) { - xmlNewProp(node, BAD_CAST "variable", BAD_CAST "true"); - } - if (sp->sptyp & POSTCOMBATSPELL) - combat = 3; - - else if (sp->sptyp & COMBATSPELL) - combat = 2; - - else if (sp->sptyp & PRECOMBATSPELL) - combat = 1; - if (combat) { - xmlNewProp(node, BAD_CAST "combat", xml_i(combat)); - } - xmlAddChild(root, node); - } - } - xmlDocSetRootElement(doc, root); - xmlKeepBlanksDefault(0); - xmlSaveFormatFileEnc(filename, doc, "utf-8", 1); - xmlFreeDoc(doc); - return 0; -} -#endif - static int config_get_ships(lua_State * L) { quicklist *ql; @@ -973,22 +899,6 @@ static int tolua_get_spell_text(lua_State * L) return 1; } -#ifdef TODO -static int tolua_get_spell_school(lua_State * L) -{ - spell *self = (spell *) tolua_tousertype(L, 1, 0); - lua_pushstring(L, magic_school[self->magietyp]); - return 1; -} - -static int tolua_get_spell_level(lua_State * L) -{ - spell *self = (spell *) tolua_tousertype(L, 1, 0); - lua_pushinteger(L, self->level); - return 1; -} -#endif - static int tolua_get_spell_name(lua_State * L) { spell *self = (spell *)tolua_tousertype(L, 1, 0); @@ -1204,9 +1114,6 @@ int tolua_bindings_open(lua_State * L) tolua_function(L, TOLUA_CAST "translate", &tolua_translate); tolua_function(L, TOLUA_CAST "rng_int", tolua_rng_int); tolua_function(L, TOLUA_CAST "spells", tolua_get_spells); -#ifdef WRITE_SPELLS - tolua_function(L, TOLUA_CAST "write_spells", tolua_write_spells); -#endif tolua_function(L, TOLUA_CAST "read_xml", tolua_read_xml); } tolua_endmodule(L); return 1; diff --git a/src/laws.c b/src/laws.c index a04655439..372cbf4ef 100755 --- a/src/laws.c +++ b/src/laws.c @@ -2817,10 +2817,6 @@ void sinkships(struct region * r) } } -/* The following functions do not really belong here: */ -#include -#include - static attrib_type at_number = { "faction_renum", NULL, NULL, NULL, NULL, NULL, From bc1c3dd7125b1bcddd1143d986162e99005a254f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Aug 2015 19:59:11 +0200 Subject: [PATCH 2/9] move NEWATSROI out of item_modification --- src/kernel/unit.c | 10 +++++----- src/settings.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/kernel/unit.c b/src/kernel/unit.c index b2601e75e..7bddd00cf 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1254,25 +1254,23 @@ static int item_invis(const unit *u) { + (rsphere ? i_get(u->items, rsphere->itype) * 100 : 0); } +#ifdef NEWATSROI static int item_modification(const unit * u, skill_t sk, int val) { if (sk == SK_STEALTH) { -#if NEWATSROI == 1 if (item_invis(u) >= u->number) { val += ROIBONUS; } -#endif } -#if NEWATSROI == 1 if (sk == SK_PERCEPTION) { const struct resource_type *rtype = get_resourcetype(R_AMULET_OF_TRUE_SEEING); if (i_get(u->items, rtype->itype) >= u->number) { val += ATSBONUS; } } -#endif return val; } +#endif static int att_modification(const unit * u, skill_t sk) { @@ -1345,9 +1343,11 @@ int get_modifier(const unit * u, skill_t sk, int level, const region * r, bool n skill += rc_skillmod(u_race(u), r, sk); skill += att_modification(u, sk); +#ifdef NEWATSROI if (!noitem) { skill = item_modification(u, sk, skill); } +#endif skill = skillmod(u->attribs, u, r, sk, skill, SMF_ALWAYS); if (hunger_red_skill == -1) { @@ -1398,7 +1398,7 @@ int eff_skill_study(const unit * u, skill_t sk, const region * r) int invisible(const unit * target, const unit * viewer) { -#if NEWATSROI == 1 +#ifdef NEWATSROI return 0; #else if (viewer && viewer->faction == target->faction) diff --git a/src/settings.h b/src/settings.h index 81f9f7074..d31dbccbf 100644 --- a/src/settings.h +++ b/src/settings.h @@ -21,7 +21,7 @@ #define RESOURCE_QUANTITY 0.5 #define RECRUITFRACTION 40 /* 100/RECRUITFRACTION% */ #define COMBAT_TURNS 5 -#define NEWATSROI 0 +#undef NEWATSROI /* Vermehrungsrate Bauern in 1/10000. * TODO: Evt. Berechnungsfehler, reale Vermehrungsraten scheinen höher. */ From eb26cc971f458b810794dd651ce8ccfa15c5c798 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 26 Aug 2015 21:19:14 +0200 Subject: [PATCH 3/9] Testing bufunit with skills and different viewers. --- src/reports.test.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/reports.test.c b/src/reports.test.c index b30c3214b..c155188dd 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -229,6 +229,46 @@ static void test_write_travelthru(CuTest *tc) { test_cleanup(); } +static void test_write_unit(CuTest *tc) { + unit *u; + faction *f; + race *rc; + struct locale *lang; + char buffer[1024]; + + test_cleanup(); + rc = rc_get_or_create("human"); + rc->bonus[SK_ALCHEMY] = 1; + lang = get_or_create_locale("de"); + locale_setstring(lang, "nr_skills", "Talente"); + locale_setstring(lang, "skill::sailing", "Segeln"); + locale_setstring(lang, "skill::alchemy", "Alchemie"); + init_skills(lang); + u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0)); + u->faction->locale = lang; + faction_setname(u->faction, "UFO"); + renumber_faction(u->faction, 1); + unit_setname(u, "Hodor"); + unit_setid(u, 1); + + bufunit(u->faction, u, 0, 0, buffer, sizeof(buffer)); + CuAssertStrEquals(tc, "Hodor (1), 1 human, status_aggressive.", buffer); + + set_level(u, SK_SAILING, 1); + bufunit(u->faction, u, 0, 0, buffer, sizeof(buffer)); + CuAssertStrEquals(tc, "Hodor (1), 1 human, status_aggressive, Talente: Segeln 1.", buffer); + + set_level(u, SK_ALCHEMY, 1); + bufunit(u->faction, u, 0, 0, buffer, sizeof(buffer)); + CuAssertStrEquals(tc, "Hodor (1), 1 human, status_aggressive, Talente: Segeln 1, Alchemie 2.", buffer); + + f = test_create_faction(0); + f->locale = get_or_create_locale("de"); + bufunit(f, u, 0, 0, buffer, sizeof(buffer)); + CuAssertStrEquals(tc, "Hodor (1), UFO (1), 1 human.", buffer); + test_cleanup(); +} + CuSuite *get_reports_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -240,5 +280,6 @@ CuSuite *get_reports_suite(void) SUITE_ADD_TEST(suite, test_write_many_spaces); SUITE_ADD_TEST(suite, test_sparagraph); SUITE_ADD_TEST(suite, test_write_travelthru); + SUITE_ADD_TEST(suite, test_write_unit); return suite; } From 71dea1eca790b9a0cfafe2143f20474a95e3516e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 27 Aug 2015 13:19:58 +0200 Subject: [PATCH 4/9] backfill missing tests for herbsearch (alchemy). --- src/CMakeLists.txt | 1 + src/alchemy.h | 2 +- src/alchemy.test.c | 91 +++++++++++++++++++++++++++++++++++++++++++ src/kernel/messages.h | 2 +- src/kernel/unit.h | 4 +- src/test_eressea.c | 1 + 6 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 src/alchemy.test.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a67ad35b4..922417b03 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -175,6 +175,7 @@ target_link_libraries(eressea set(TESTS_SRC wormhole.test.c + alchemy.test.c test_eressea.c tests.c battle.test.c diff --git a/src/alchemy.h b/src/alchemy.h index ead8ab09e..79f771b45 100644 --- a/src/alchemy.h +++ b/src/alchemy.h @@ -56,7 +56,7 @@ extern "C" { MAX_POTIONS }; - extern void herbsearch(struct region *r, struct unit *u, int max); + void herbsearch(struct region *r, struct unit *u, int max); extern int use_potion(struct unit *u, const struct item_type *itype, int amount, struct order *); extern int use_potion_delayed(struct unit *u, const struct item_type *itype, diff --git a/src/alchemy.test.c b/src/alchemy.test.c new file mode 100644 index 000000000..16811725a --- /dev/null +++ b/src/alchemy.test.c @@ -0,0 +1,91 @@ +#include + +#include "alchemy.h" +#include "move.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "tests.h" + +static void test_herbsearch(CuTest * tc) +{ + faction *f; + race *rc; + unit *u, *u2; + region *r; + const item_type *itype; + + test_cleanup(); + r = test_create_region(0, 0, 0); + rc = rc_get_or_create("dragon"); + rc->flags |= RCF_UNARMEDGUARD; + u2 = test_create_unit(test_create_faction(rc), r); + guard(u2, GUARD_PRODUCE); + + f = test_create_faction(0); + u = test_create_unit(f, r); + itype = test_create_itemtype("rosemary"); + + herbsearch(r, u, INT_MAX); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error59")); + free_messagelist(f->msgs); + f->msgs = 0; + + set_level(u, SK_HERBALISM, 1); + CuAssertPtrEquals(tc, u2, is_guarded(r, u, GUARD_PRODUCE)); + herbsearch(r, u, INT_MAX); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error70")); + CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59")); + free_messagelist(f->msgs); + f->msgs = 0; + + guard(u2, GUARD_NONE); + CuAssertPtrEquals(tc, 0, is_guarded(r, u, GUARD_PRODUCE)); + CuAssertPtrEquals(tc, 0, (void *)rherbtype(r)); + herbsearch(r, u, INT_MAX); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error108")); + CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error70")); + CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59")); + free_messagelist(f->msgs); + f->msgs = 0; + + rsetherbtype(r, itype); + CuAssertPtrEquals(tc, (void *)itype, (void *)rherbtype(r)); + CuAssertIntEquals(tc, 0, rherbs(r)); + herbsearch(r, u, INT_MAX); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "researchherb_none")); + CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error108")); + CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error70")); + CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59")); + free_messagelist(f->msgs); + f->msgs = 0; + + rsetherbs(r, 100); + CuAssertIntEquals(tc, 100, rherbs(r)); + herbsearch(r, u, INT_MAX); + CuAssertIntEquals(tc, 99, rherbs(r)); + CuAssertIntEquals(tc, 1, i_get(u->items, itype)); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "herbfound")); + CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "researchherb_none")); + CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error108")); + CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error70")); + CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59")); + free_messagelist(f->msgs); + f->msgs = 0; + + test_cleanup(); +} + +CuSuite *get_alchemy_suite(void) +{ + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_herbsearch); + return suite; +} diff --git a/src/kernel/messages.h b/src/kernel/messages.h index 75d1f23b1..6891de586 100644 --- a/src/kernel/messages.h +++ b/src/kernel/messages.h @@ -37,7 +37,7 @@ extern "C" { struct mlist *begin, **end; } message_list; - extern void free_messagelist(message_list * msgs); + void free_messagelist(message_list * msgs); typedef struct msglevel { /* used to set specialized msg-levels */ diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 631809bf9..3a5261d94 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -164,8 +164,8 @@ extern "C" { int produceexp(struct unit *u, skill_t sk, int n); int SkillCap(skill_t sk); - extern void set_level(struct unit *u, skill_t id, int level); - extern int get_level(const struct unit *u, skill_t id); + void set_level(struct unit *u, skill_t id, int level); + int get_level(const struct unit *u, skill_t id); extern void transfermen(struct unit *u, struct unit *u2, int n); extern int eff_skill(const struct unit *u, skill_t sk, diff --git a/src/test_eressea.c b/src/test_eressea.c index cef5193cd..1ae1dfe85 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -67,6 +67,7 @@ int RunAllTests(void) RUN_TESTS(suite, equipment); RUN_TESTS(suite, item); RUN_TESTS(suite, magic); + RUN_TESTS(suite, alchemy); RUN_TESTS(suite, reports); RUN_TESTS(suite, save); RUN_TESTS(suite, ship); From 6889cb0c8086bb76c040784120d64f470f6b87bb Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 27 Aug 2015 14:46:08 +0200 Subject: [PATCH 5/9] remove superfluous argument from herbsearch use effskill, not eff_skill --- src/alchemy.c | 10 ++++++---- src/alchemy.h | 2 +- src/alchemy.test.c | 10 +++++----- src/economy.c | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/alchemy.c b/src/alchemy.c index edd4746bc..3403d7c46 100644 --- a/src/alchemy.c +++ b/src/alchemy.c @@ -47,12 +47,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* ------------------------------------------------------------- */ -void herbsearch(region * r, unit * u, int max) +void herbsearch(unit * u, int max) { + region * r = u->region; int herbsfound; const item_type *whichherb; + int effsk = effskill(u, SK_HERBALISM); - if (eff_skill(u, SK_HERBALISM, r) == 0) { + if (effsk == 0) { cmistake(u, u->thisorder, 59, MSG_PRODUCE); return; } @@ -72,7 +74,7 @@ void herbsearch(region * r, unit * u, int max) max = _min(max, rherbs(r)); else max = rherbs(r); - herbsfound = ntimespprob(eff_skill(u, SK_HERBALISM, r) * u->number, + herbsfound = ntimespprob(effsk * u->number, (double)rherbs(r) / 100.0F, -0.01F); herbsfound = _min(herbsfound, max); rsetherbs(r, rherbs(r) - herbsfound); @@ -85,7 +87,7 @@ void herbsearch(region * r, unit * u, int max) } else { ADDMSG(&u->faction->msgs, msg_message("researchherb_none", - "unit region", u, u->region)); + "unit region", u, r)); } } diff --git a/src/alchemy.h b/src/alchemy.h index 79f771b45..6dec4120b 100644 --- a/src/alchemy.h +++ b/src/alchemy.h @@ -56,7 +56,7 @@ extern "C" { MAX_POTIONS }; - void herbsearch(struct region *r, struct unit *u, int max); + void herbsearch(struct unit *u, int max); extern int use_potion(struct unit *u, const struct item_type *itype, int amount, struct order *); extern int use_potion_delayed(struct unit *u, const struct item_type *itype, diff --git a/src/alchemy.test.c b/src/alchemy.test.c index 16811725a..fed4946f2 100644 --- a/src/alchemy.test.c +++ b/src/alchemy.test.c @@ -33,14 +33,14 @@ static void test_herbsearch(CuTest * tc) u = test_create_unit(f, r); itype = test_create_itemtype("rosemary"); - herbsearch(r, u, INT_MAX); + herbsearch(u, INT_MAX); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error59")); free_messagelist(f->msgs); f->msgs = 0; set_level(u, SK_HERBALISM, 1); CuAssertPtrEquals(tc, u2, is_guarded(r, u, GUARD_PRODUCE)); - herbsearch(r, u, INT_MAX); + herbsearch(u, INT_MAX); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error70")); CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59")); free_messagelist(f->msgs); @@ -49,7 +49,7 @@ static void test_herbsearch(CuTest * tc) guard(u2, GUARD_NONE); CuAssertPtrEquals(tc, 0, is_guarded(r, u, GUARD_PRODUCE)); CuAssertPtrEquals(tc, 0, (void *)rherbtype(r)); - herbsearch(r, u, INT_MAX); + herbsearch(u, INT_MAX); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error108")); CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error70")); CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error59")); @@ -59,7 +59,7 @@ static void test_herbsearch(CuTest * tc) rsetherbtype(r, itype); CuAssertPtrEquals(tc, (void *)itype, (void *)rherbtype(r)); CuAssertIntEquals(tc, 0, rherbs(r)); - herbsearch(r, u, INT_MAX); + herbsearch(u, INT_MAX); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "researchherb_none")); CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error108")); CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error70")); @@ -69,7 +69,7 @@ static void test_herbsearch(CuTest * tc) rsetherbs(r, 100); CuAssertIntEquals(tc, 100, rherbs(r)); - herbsearch(r, u, INT_MAX); + herbsearch(u, INT_MAX); CuAssertIntEquals(tc, 99, rherbs(r)); CuAssertIntEquals(tc, 1, i_get(u->items, itype)); CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "herbfound")); diff --git a/src/economy.c b/src/economy.c index 8cf46845b..f580f10b0 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1546,7 +1546,7 @@ int make_cmd(unit * u, struct order *ord) return 0; } else if (p == P_HERBS) { - herbsearch(r, u, m); + herbsearch(u, m); return 0; } From de808bf146d8ddcc63d60a947762b6b2825ab23d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 27 Aug 2015 16:16:55 +0200 Subject: [PATCH 6/9] change effskill signature to take a region, change eff_skill to work on a skill * to avoid multiple lookups. --- src/alchemy.c | 2 +- src/attributes/stealth.c | 4 +++- src/battle.c | 31 ++++++++++++------------- src/bind_unit.c | 2 +- src/creport.c | 11 ++++----- src/economy.c | 50 ++++++++++++++++++++++------------------ src/kernel/build.c | 29 ++++++++++++----------- src/kernel/connection.c | 3 +-- src/kernel/item.c | 2 +- src/kernel/save.c | 2 +- src/kernel/ship.c | 4 ++-- src/kernel/unit.c | 49 ++++++++++++++++++++++++--------------- src/kernel/unit.h | 12 ++++------ src/laws.c | 31 +++++++++++++------------ src/lighthouse.c | 4 ++-- src/magic.c | 30 ++++++++++++------------ src/monsters.c | 2 +- src/move.c | 31 +++++++++++++------------ src/randenc.c | 16 ++++++------- src/reports.c | 12 +++++----- src/spells.c | 12 +++++----- src/spy.c | 24 +++++++++---------- src/study.c | 18 +++++++-------- src/summary.c | 2 +- 24 files changed, 199 insertions(+), 184 deletions(-) diff --git a/src/alchemy.c b/src/alchemy.c index 3403d7c46..9042fee9b 100644 --- a/src/alchemy.c +++ b/src/alchemy.c @@ -52,7 +52,7 @@ void herbsearch(unit * u, int max) region * r = u->region; int herbsfound; const item_type *whichherb; - int effsk = effskill(u, SK_HERBALISM); + int effsk = effskill(u, SK_HERBALISM, 0); if (effsk == 0) { cmistake(u, u->thisorder, 59, MSG_PRODUCE); diff --git a/src/attributes/stealth.c b/src/attributes/stealth.c index 9d76ffb29..e4da1ec5c 100644 --- a/src/attributes/stealth.c +++ b/src/attributes/stealth.c @@ -5,6 +5,7 @@ #include #include +#include #include attrib_type at_stealth = { @@ -49,9 +50,10 @@ int eff_stealth(const unit * u, const region * r) { int e = 0; + assert(u->region == r); // TODO: param r is useless /* Auf Schiffen keine Tarnung! */ if (!u->ship && skill_enabled(SK_STEALTH)) { - e = eff_skill(u, SK_STEALTH, r); + e = effskill(u, SK_STEALTH, r); if (u->flags & UFL_STEALTH) { int es = u_geteffstealth(u); diff --git a/src/battle.c b/src/battle.c index c6e90a9c8..22a439493 100644 --- a/src/battle.c +++ b/src/battle.c @@ -504,7 +504,7 @@ const armor_type * sh) if (tohit < 0.5) tohit = 0.5; if (chance(tohit)) { - int defense = effskill(dt.fighter->unit, SK_STAMINA); + int defense = effskill(dt.fighter->unit, SK_STAMINA, dt.fighter->unit->region); double tosave = defense * 0.05; return !chance(tosave); } @@ -586,12 +586,12 @@ weapon_skill(const weapon_type * wtype, const unit * u, bool attacking) int skill; if (wtype == NULL) { - skill = effskill(u, SK_WEAPONLESS); + skill = effskill(u, SK_WEAPONLESS, 0); if (skill <= 0) { /* wenn kein waffenloser kampf, dann den rassen-defaultwert */ if (u_race(u) == get_race(RC_ORC)) { - int sword = effskill(u, SK_MELEE); - int spear = effskill(u, SK_SPEAR); + int sword = effskill(u, SK_MELEE, 0); + int spear = effskill(u, SK_SPEAR, 0); skill = _max(sword, spear) - 3; if (attacking) { skill = _max(skill, u_race(u)->at_default); @@ -636,7 +636,7 @@ weapon_skill(const weapon_type * wtype, const unit * u, bool attacking) /* changed: if we own a weapon, we have at least a skill of 0 */ if (!i_canuse(u, wtype->itype)) return -1; - skill = effskill(u, wtype->skill); + skill = effskill(u, wtype->skill, 0); if (skill < wtype->minskill) skill = 0; if (skill > 0) { @@ -683,7 +683,7 @@ static int CavalryBonus(const unit * u, troop enemy, int type) } else { /* new rule, chargers in Eressea 1.1 */ - int skl = effskill(u, SK_RIDING); + int skl = effskill(u, SK_RIDING, 0); /* only half against trolls */ if (skl > 0) { if (type == BONUS_DAMAGE) { @@ -1031,7 +1031,7 @@ static int natural_armor(unit * du) bonus[u_race(du)->index] = -1; } if (bonus[u_race(du)->index] > 0) { - int sk = effskill(du, SK_STAMINA); + int sk = effskill(du, SK_STAMINA, 0); sk /= bonus[u_race(du)->index]; an += sk; } @@ -1686,7 +1686,7 @@ void do_combatmagic(battle * b, combatmagic_t was) if (fig->alive <= 0) continue; /* fighter kann im Kampf getötet worden sein */ - level = eff_skill(mage, SK_MAGIC, r); + level = effskill(mage, SK_MAGIC, r); if (level > 0) { double power; const spell *sp; @@ -2330,7 +2330,7 @@ void do_regenerate(fighter * af) while (ta.index--) { struct person *p = af->person + ta.index; - p->hp += effskill(au, SK_STAMINA); + p->hp += effskill(au, SK_STAMINA, 0); p->hp = _min(unit_max_hp(au), p->hp); } } @@ -2353,7 +2353,7 @@ static double horsebonus(const unit * u) const item_type *it_horse, *it_elvenhorse, *it_charger; int n1 = 0, n2 = 0, n3 = 0; item *itm; - int skl = eff_skill(u, SK_RIDING, u->region); + int skl = effskill(u, SK_RIDING, 0); const resource_type *rtype; if (skl < 1) return 0.0; @@ -2384,11 +2384,10 @@ static double horsebonus(const unit * u) double fleechance(unit * u) { double c = 0.20; /* Fluchtwahrscheinlichkeit in % */ - region *r = u->region; attrib *a = a_find(u->attribs, &at_fleechance); /* Einheit u versucht, dem Getümmel zu entkommen */ - c += (eff_skill(u, SK_STEALTH, r) * 0.05); + c += (effskill(u, SK_STEALTH, 0) * 0.05); c += horsebonus(u); if (u_race(u) == get_race(RC_HALFLING)) { @@ -3188,7 +3187,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack) region *r = b->region; item *itm; fighter *fig = NULL; - int h, i, tactics = eff_skill(u, SK_TACTICS, r); + int h, i, tactics = effskill(u, SK_TACTICS, 0); int berserk; int strongmen; int speeded = 0, speed = 1; @@ -3432,17 +3431,17 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack) * keine addierten boni. */ /* Zuerst mal die Spezialbehandlung gewisser Sonderfälle. */ - fig->magic = eff_skill(u, SK_MAGIC, r); + fig->magic = effskill(u, SK_MAGIC, 0); if (fig->horses) { if (!fval(r->terrain, CAVALRY_REGION) || r_isforest(r) - || eff_skill(u, SK_RIDING, r) < CavalrySkill() + || effskill(u, SK_RIDING, 0) < CavalrySkill() || u_race(u) == get_race(RC_TROLL) || fval(u, UFL_WERE)) fig->horses = 0; } if (fig->elvenhorses) { - if (eff_skill(u, SK_RIDING, r) < 5 || u_race(u) == get_race(RC_TROLL) + if (effskill(u, SK_RIDING, 0) < 5 || u_race(u) == get_race(RC_TROLL) || fval(u, UFL_WERE)) fig->elvenhorses = 0; } diff --git a/src/bind_unit.c b/src/bind_unit.c index 845d3ddf0..fc5ee0d8f 100755 --- a/src/bind_unit.c +++ b/src/bind_unit.c @@ -425,7 +425,7 @@ static int tolua_unit_effskill(lua_State * L) unit *self = (unit *)tolua_tousertype(L, 1, 0); const char *skname = tolua_tostring(L, 2, 0); skill_t sk = findskill(skname); - int value = (sk == NOSKILL) ? -1 : eff_skill(self, sk, self->region); + int value = (sk == NOSKILL) ? -1 : effskill(self, sk, 0); lua_pushinteger(L, value); return 1; } diff --git a/src/creport.c b/src/creport.c index 55e2bccce..d0dce03db 100644 --- a/src/creport.c +++ b/src/creport.c @@ -832,7 +832,7 @@ void cr_output_unit(stream *out, const region * r, const faction * f, prefix))); } if (u->faction != f && a_fshidden - && a_fshidden->data.ca[0] == 1 && effskill(u, SK_STEALTH) >= 6) { + && a_fshidden->data.ca[0] == 1 && effskill(u, SK_STEALTH, 0) >= 6) { stream_printf(out, "-1;Anzahl\n"); } else { @@ -942,14 +942,13 @@ void cr_output_unit(stream *out, const region * r, const faction * f, pr = 0; for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { if (sv->level > 0) { - skill_t sk = sv->id; - int esk = eff_skill(u, sk, r); + int esk = eff_skill(u, sv, r); if (!pr) { pr = 1; stream_printf(out, "TALENTE\n"); } stream_printf(out, "%d %d;%s\n", u->number * level_days(sv->level), esk, - translate(mkname("skill", skillnames[sk]), skillname(sk, + translate(mkname("skill", skillnames[sv->id]), skillname(sv->id, f->locale))); } } @@ -957,7 +956,7 @@ void cr_output_unit(stream *out, const region * r, const faction * f, /* spells that this unit can cast */ mage = get_mage(u); if (mage) { - int i, maxlevel = effskill(u, SK_MAGIC); + int i, maxlevel = effskill(u, SK_MAGIC, 0); cr_output_spells(out, u, maxlevel); for (i = 0; i != MAXCOMBATSPELLS; ++i) { @@ -979,7 +978,7 @@ void cr_output_unit(stream *out, const region * r, const faction * f, show = u->items; } else if (!itemcloak && mode >= see_unit && !(a_fshidden - && a_fshidden->data.ca[1] == 1 && effskill(u, SK_STEALTH) >= 3)) { + && a_fshidden->data.ca[1] == 1 && effskill(u, SK_STEALTH, 0) >= 3)) { int n = report_items(u->items, result, MAX_INVENTORY, u, f); assert(n >= 0); if (n > 0) diff --git a/src/economy.c b/src/economy.c index f580f10b0..ea37c1e8b 100644 --- a/src/economy.c +++ b/src/economy.c @@ -999,7 +999,7 @@ static void manufacture(unit * u, const item_type * itype, int want) int minskill = itype->construction->minskill; skill_t sk = itype->construction->skill; - skill = effskill(u, sk); + skill = effskill(u, sk, 0); skill = skillmod(itype->rtype->attribs, u, u->region, sk, skill, SMF_PRODUCTION); @@ -1159,7 +1159,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) assert(itype->construction->skill != 0 || "limited resource needs a required skill for making it"); - skill = eff_skill(u, itype->construction->skill, u->region); + skill = effskill(u, itype->construction->skill, 0); if (skill == 0) { skill_t sk = itype->construction->skill; add_message(&u->faction->msgs, @@ -1282,7 +1282,7 @@ leveled_allocation(const resource_type * rtype, region * r, allocation * alist) if (!fval(al, AFL_DONE)) { int req = required(al->want - al->get, al->save); assert(al->get <= al->want && al->get >= 0); - if (eff_skill(al->unit, itype->construction->skill, r) + if (effskill(al->unit, itype->construction->skill, 0) >= rm->level + itype->construction->minskill - 1) { if (req) { norders += req; @@ -1817,7 +1817,7 @@ static void buy(unit * u, request ** buyorders, struct order *ord) } /* Ein Händler kann nur 10 Güter pro Talentpunkt handeln. */ - k = u->number * 10 * eff_skill(u, SK_TRADE, r); + k = u->number * 10 * effskill(u, SK_TRADE, 0); /* hat der Händler bereits gehandelt, muss die Menge der bereits * verkauften/gekauften Güter abgezogen werden */ @@ -2134,7 +2134,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord) /* Ein Händler kann nur 10 Güter pro Talentpunkt verkaufen. */ - n = _min(n, u->number * 10 * eff_skill(u, SK_TRADE, r)); + n = _min(n, u->number * 10 * effskill(u, SK_TRADE, 0)); if (!n) { cmistake(u, ord, 54, MSG_COMMERCE); @@ -2181,7 +2181,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord) * existiert, so dass man arrays von orders machen kann. */ /* Ein Händler kann nur 10 Güter pro Talentpunkt handeln. */ - k = u->number * 10 * eff_skill(u, SK_TRADE, r); + k = u->number * 10 * effskill(u, SK_TRADE, 0); /* hat der Händler bereits gehandelt, muss die Menge der bereits * verkauften/gekauften Güter abgezogen werden */ @@ -2280,7 +2280,7 @@ static void plant(region * r, unit * u, int raw) } /* Skill prüfen */ - skill = eff_skill(u, SK_HERBALISM, r); + skill = effskill(u, SK_HERBALISM, 0); itype = rherbtype(r); if (skill < 6) { ADDMSG(&u->faction->msgs, @@ -2325,6 +2325,7 @@ static void planttrees(region * r, unit * u, int raw) int n, i, skill, planted = 0; const resource_type *rtype; + assert(r == u->region); // TODO: param r is unnecessary if (!fval(r->terrain, LAND_REGION)) { return; } @@ -2333,7 +2334,7 @@ static void planttrees(region * r, unit * u, int raw) rtype = get_resourcetype(fval(r, RF_MALLORN) ? R_MALLORNSEED : R_SEED); /* Skill prüfen */ - skill = eff_skill(u, SK_HERBALISM, r); + skill = effskill(u, SK_HERBALISM, 0); if (skill < 6) { ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "plant_skills", @@ -2380,6 +2381,7 @@ static void breedtrees(region * r, unit * u, int raw) static int gamecookie = -1; static int current_season; + assert(r == u->region); // TODO: param r is unnecessary if (gamecookie != global.cookie) { gamedate date; get_gamedate(turn, &date); @@ -2401,7 +2403,7 @@ static void breedtrees(region * r, unit * u, int raw) rtype = get_resourcetype(fval(r, RF_MALLORN) ? R_MALLORNSEED : R_SEED); /* Skill prüfen */ - skill = eff_skill(u, SK_HERBALISM, r); + skill = effskill(u, SK_HERBALISM, 0); if (skill < 12) { planttrees(r, u, raw); return; @@ -2440,8 +2442,9 @@ static void breedhorses(region * r, unit * u) struct building *b = inside_building(u); const struct building_type *btype = b ? b->type : NULL; const struct resource_type *rhorse = get_resourcetype(R_HORSE); - int horses; + int horses, effsk; assert(rhorse && rhorse->itype); + assert(r == u->region); // TODO: param r is unnecessary if (btype != bt_find("stables")) { cmistake(u, u->thisorder, 122, MSG_PRODUCE); return; @@ -2451,11 +2454,12 @@ static void breedhorses(region * r, unit * u) cmistake(u, u->thisorder, 107, MSG_PRODUCE); return; } - n = u->number * eff_skill(u, SK_HORSE_TRAINING, r); + effsk = effskill(u, SK_HORSE_TRAINING, 0); + n = u->number * effsk; n = _min(n, horses); for (c = 0; c < n; c++) { - if (rng_int() % 100 < eff_skill(u, SK_HORSE_TRAINING, r)) { + if (rng_int() % 100 < effsk) { i_change(&u->items, rhorse->itype, 1); ++breed; } @@ -2551,7 +2555,7 @@ static void research_cmd(unit * u, struct order *ord) kwd = init_order(ord); assert(kwd == K_RESEARCH); - if (eff_skill(u, SK_HERBALISM, r) < 7) { + if (effskill(u, SK_HERBALISM, 0) < 7) { cmistake(u, ord, 227, MSG_EVENT); return; } @@ -2584,8 +2588,9 @@ static int max_skill(region * r, faction * f, skill_t sk) for (u = r->units; u; u = u->next) { if (u->faction == f) { - if (eff_skill(u, sk, r) > w) { - w = eff_skill(u, sk, r); + int effsk = effskill(u, sk, 0); + if (effsk > w) { + w = effsk; } } } @@ -2614,7 +2619,7 @@ message * check_steal(const unit * u, struct order *ord) { static void steal_cmd(unit * u, struct order *ord, request ** stealorders) { const resource_type *rring = get_resourcetype(R_RING_OF_NIMBLEFINGER); - int n, i, id; + int n, i, id, effsk; bool goblin = false; request *o; unit *u2 = NULL; @@ -2671,11 +2676,12 @@ static void steal_cmd(unit * u, struct order *ord, request ** stealorders) return; } - n = eff_skill(u, SK_STEALTH, r) - max_skill(r, f, SK_PERCEPTION); + effsk = effskill(u, SK_STEALTH, 0); + n = effsk - max_skill(r, f, SK_PERCEPTION); if (n <= 0) { /* Wahrnehmung == Tarnung */ - if (u_race(u) != get_race(RC_GOBLIN) || eff_skill(u, SK_STEALTH, r) <= 3) { + if (u_race(u) != get_race(RC_GOBLIN) || effsk <= 3) { ADDMSG(&u->faction->msgs, msg_message("stealfail", "unit target", u, u2)); if (n == 0) { ADDMSG(&u2->faction->msgs, msg_message("stealdetect", "unit", u2)); @@ -2771,7 +2777,7 @@ void entertain_cmd(unit * u, struct order *ord) cmistake(u, ord, 58, MSG_INCOME); return; } - if (!effskill(u, SK_ENTERTAINMENT)) { + if (!effskill(u, SK_ENTERTAINMENT, 0)) { cmistake(u, ord, 58, MSG_INCOME); return; } @@ -2788,7 +2794,7 @@ void entertain_cmd(unit * u, struct order *ord) return; } - u->wants = u->number * (entertainbase + effskill(u, SK_ENTERTAINMENT) + u->wants = u->number * (entertainbase + effskill(u, SK_ENTERTAINMENT, 0) * entertainperlevel); max_e = getuint(); @@ -3002,7 +3008,7 @@ void tax_cmd(unit * u, struct order *ord, request ** taxorders) u->wants = _min(income(u), max); } else { - u->wants = _min(n * eff_skill(u, SK_TAXING, r) * 20, max); + u->wants = _min(n * effskill(u, SK_TAXING, 0) * 20, max); } u2 = is_guarded(r, u, GUARD_TAX); @@ -3077,7 +3083,7 @@ void loot_cmd(unit * u, struct order *ord, request ** lootorders) } else { /* For player start with 20 Silver +10 every 5 level of close combat skill*/ - int skbonus = (_max(eff_skill(u, SK_MELEE, r), eff_skill(u, SK_SPEAR, r)) * 2 / 10) + 2; + int skbonus = (_max(effskill(u, SK_MELEE, 0), effskill(u, SK_SPEAR, 0)) * 2 / 10) + 2; u->wants = _min(n * skbonus * 10, max); } diff --git a/src/kernel/build.c b/src/kernel/build.c index 37006e968..a8c42063d 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -123,7 +123,7 @@ static void destroy_road(unit * u, int nmax, struct order *ord) n = _min(n, road); if (n != 0) { region *r2 = rconnect(r, d); - int willdo = eff_skill(u, SK_ROAD_BUILDING, r) * u->number; + int willdo = effskill(u, SK_ROAD_BUILDING, 0) * u->number; willdo = _min(willdo, n); if (willdo == 0) { /* TODO: error message */ @@ -263,11 +263,13 @@ int destroy_cmd(unit * u, struct order *ord) void build_road(region * r, unit * u, int size, direction_t d) { - int n, left; + int n, left, effsk; region *rn = rconnect(r, d); assert(u->number); - if (!eff_skill(u, SK_ROAD_BUILDING, r)) { + assert(r == u->region); // TODO: param r is unnecessary + effsk = effskill(u, SK_ROAD_BUILDING, 0); + if (!effsk) { cmistake(u, u->thisorder, 103, MSG_PRODUCE); return; } @@ -337,7 +339,7 @@ void build_road(region * r, unit * u, int size, direction_t d) left = _min(n, left); /* n = maximum by skill. try to maximize it */ - n = u->number * eff_skill(u, SK_ROAD_BUILDING, r); + n = u->number * effsk; if (n < left) { const resource_type *ring = get_resourcetype(R_RING_OF_NIMBLEFINGER); item *itm = ring ? *i_find(&u->items, ring->itype) : 0; @@ -349,12 +351,11 @@ void build_road(region * r, unit * u, int size, direction_t d) if (n < left) { int dm = get_effect(u, oldpotiontype[P_DOMORE]); if (dm != 0) { - int sk = eff_skill(u, SK_ROAD_BUILDING, r); - int todo = (left - n + sk - 1) / sk; + int todo = (left - n + effsk - 1) / effsk; todo = _min(todo, u->number); dm = _min(dm, todo); change_effect(u, oldpotiontype[P_DOMORE], -dm); - n += dm * sk; + n += dm * effsk; } /* Auswirkung Schaffenstrunk */ } @@ -456,7 +457,7 @@ int build(unit * u, const construction * ctype, int completed, int want) int dm = get_effect(u, oldpotiontype[P_DOMORE]); assert(u->number); - basesk = effskill(u, type->skill); + basesk = effskill(u, type->skill, 0); if (basesk == 0) return ENEEDSKILL; @@ -676,7 +677,7 @@ build_building(unit * u, const building_type * btype, int id, int want, order * assert(u->number); assert(btype->construction); - if (eff_skill(u, SK_BUILDING, r) == 0) { + if (effskill(u, SK_BUILDING, 0) == 0) { cmistake(u, ord, 101, MSG_PRODUCE); return 0; } @@ -887,7 +888,8 @@ order * ord) const construction *cons = newtype->construction; order *new_order; - if (!eff_skill(u, SK_SHIPBUILDING, r)) { + assert(u->region == r); // TODO: param r is unnecessary + if (!effskill(u, SK_SHIPBUILDING, 0)) { cmistake(u, ord, 100, MSG_PRODUCE); return; } @@ -897,7 +899,7 @@ order * ord) } /* check if skill and material for 1 size is available */ - if (eff_skill(u, cons->skill, r) < cons->minskill) { + if (effskill(u, cons->skill, 0) < cons->minskill) { ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_build_skill_low", "value", cons->minskill)); return; @@ -935,7 +937,8 @@ void continue_ship(region * r, unit * u, int want) ship *sh; int msize; - if (!eff_skill(u, SK_SHIPBUILDING, r)) { + assert(u->region == r); // TODO: param r is unnecessary + if (!effskill(u, SK_SHIPBUILDING, 0)) { cmistake(u, u->thisorder, 100, MSG_PRODUCE); return; } @@ -956,7 +959,7 @@ void continue_ship(region * r, unit * u, int want) cmistake(u, u->thisorder, 16, MSG_PRODUCE); return; } - if (eff_skill(u, cons->skill, r) < cons->minskill) { + if (effskill(u, cons->skill, 0) < cons->minskill) { ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_build_skill_low", "value", cons->minskill)); return; diff --git a/src/kernel/connection.c b/src/kernel/connection.c index e839bb1ec..5bccfafd6 100644 --- a/src/kernel/connection.c +++ b/src/kernel/connection.c @@ -434,10 +434,9 @@ static bool b_blockfogwall(const connection * b, const unit * u, const region * r) { unused_arg(b); - unused_arg(r); if (!u) return true; - return (bool)(effskill(u, SK_PERCEPTION) > 4); /* Das ist die alte Nebelwand */ + return (bool)(effskill(u, SK_PERCEPTION, r) > 4); /* Das ist die alte Nebelwand */ } /** Legacy type used in old Eressea games, no longer in use. */ diff --git a/src/kernel/item.c b/src/kernel/item.c index 2e4c7da74..f801cf226 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -825,7 +825,7 @@ int amount, struct order *ord) "")); return ECUSTOM; } - if (effskill(u, SK_STEALTH) <= effskill(target, SK_PERCEPTION)) { + if (effskill(u, SK_STEALTH, 0) <= effskill(target, SK_PERCEPTION, 0)) { cmistake(u, ord, 64, MSG_EVENT); return ECUSTOM; } diff --git a/src/kernel/save.c b/src/kernel/save.c index 3e0ede885..fc348acac 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1671,7 +1671,7 @@ int readgame(const char *filename, bool backup) sc_mage *mage = get_mage(u); if (mage) { faction *f = u->faction; - int skl = effskill(u, SK_MAGIC); + int skl = effskill(u, SK_MAGIC, 0); if (f->magiegebiet == M_GRAY) { log_error("faction %s had magic=gray, fixing (%s)\n", factionname(f), magic_school[mage->magietyp]); f->magiegebiet = mage->magietyp; diff --git a/src/kernel/ship.c b/src/kernel/ship.c index dc1e228af..d33ac5aaf 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -273,7 +273,7 @@ static int ShipSpeedBonus(const unit * u) int level = get_param_int(global.parameters, "movement.shipspeed.skillbonus", 0); if (level > 0) { ship *sh = u->ship; - int skl = effskill(u, SK_SAILING); + int skl = effskill(u, SK_SAILING, 0); int minsk = (sh->type->cptskill + 1) / 2; return (skl - minsk) / level; } @@ -288,7 +288,7 @@ int crew_skill(const ship *sh) { for (u = sh->region->units; u; u = u->next) { if (u->ship == sh) { - n += eff_skill(u, SK_SAILING, sh->region) * u->number; + n += effskill(u, SK_SAILING, 0) * u->number; } } return n; diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 7bddd00cf..52904287b 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1365,31 +1365,31 @@ int get_modifier(const unit * u, skill_t sk, int level, const region * r, bool n return skill - bskill; } -int eff_skill(const unit * u, skill_t sk, const region * r) +int eff_skill(const unit * u, const skill *sv, const region *r) { - if (skill_enabled(sk)) { - int level = get_level(u, sk); - if (level > 0) { - int mlevel = level + get_modifier(u, sk, level, r, false); + assert(u); + if (!r) r = u->region; + if (sv && sv->level>0) { + int mlevel = sv->level + get_modifier(u, sv->id, sv->level, r, false); - if (mlevel > 0) { - int skillcap = SkillCap(sk); - if (skillcap && mlevel > skillcap) { - return skillcap; - } - return mlevel; + if (mlevel > 0) { + int skillcap = SkillCap(sv->id); + if (skillcap && mlevel > skillcap) { + return skillcap; } + return mlevel; } } return 0; } -int eff_skill_study(const unit * u, skill_t sk, const region * r) +int effskill_study(const unit * u, skill_t sk, const region * r) { - int level = get_level(u, sk); - if (level > 0) { - int mlevel = level + get_modifier(u, sk, level, r, true); - + skill *sv = unit_skill(u, sk); + if (sv && sv->level > 0) { + int mlevel = sv->level; + if (!r) r = u->region; + mlevel += get_modifier(u, sv->id, sv->level, r, true); if (mlevel > 0) return mlevel; } @@ -1741,7 +1741,7 @@ int unit_max_hp(const unit * u) h = u_race(u)->hitpoints; if (rules_stamina & 1) { - p = pow(effskill(u, SK_STAMINA) / 2.0, 1.5) * 0.2; + p = pow(effskill(u, SK_STAMINA, u->region) / 2.0, 1.5) * 0.2; h += (int)(h * p + 0.5); } @@ -1852,9 +1852,20 @@ struct spellbook * unit_get_spellbook(const struct unit * u) return 0; } -int effskill(const unit * u, skill_t sk) +int effskill(const unit * u, skill_t sk, const region *r) { - return eff_skill(u, sk, u->region); + assert(u); + + if (skill_enabled(sk)) { + skill *sv = u->skills; + while (sv != u->skills + u->skill_size) { + if (sv->id == sk) { + return eff_skill(u, sv, r); + } + ++sv; + } + } + return 0; } void remove_empty_units_in_region(region * r) diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 3a5261d94..dcb7ad6e3 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -160,7 +160,7 @@ extern "C" { void remove_skill(struct unit *u, skill_t sk); struct skill *unit_skill(const struct unit *u, skill_t id); bool has_skill(const unit * u, skill_t sk); - int effskill(const struct unit *u, skill_t sk); + int effskill(const struct unit *u, skill_t sk, const struct region *r); int produceexp(struct unit *u, skill_t sk, int n); int SkillCap(skill_t sk); @@ -168,14 +168,12 @@ extern "C" { int get_level(const struct unit *u, skill_t id); extern void transfermen(struct unit *u, struct unit *u2, int n); - extern int eff_skill(const struct unit *u, skill_t sk, - const struct region *r); - extern int eff_skill_study(const struct unit *u, skill_t sk, - const struct region *r); + int eff_skill(const struct unit *u, const struct skill *sv, const struct region *r); + int effskill_study(const struct unit *u, skill_t sk, const struct region *r); - extern int get_modifier(const struct unit *u, skill_t sk, int lvl, + int get_modifier(const struct unit *u, skill_t sk, int level, const struct region *r, bool noitem); - extern int remove_unit(struct unit **ulist, struct unit *u); + int remove_unit(struct unit **ulist, struct unit *u); #define GIFT_SELF 1<<0 #define GIFT_FRIENDS 1<<1 diff --git a/src/laws.c b/src/laws.c index 372cbf4ef..dfa97a34b 100755 --- a/src/laws.c +++ b/src/laws.c @@ -894,7 +894,7 @@ static int slipthru(const region * r, const unit * u, const building * b) /* u wird am hinein- oder herausschluepfen gehindert, wenn STEALTH <= * OBSERVATION +2 der belagerer u2 ist */ - n = eff_skill(u, SK_STEALTH, r); + n = effskill(u, SK_STEALTH, r); for (u2 = r->units; u2; u2 = u2->next) { if (usiege(u2) == b) { @@ -902,7 +902,7 @@ static int slipthru(const region * r, const unit * u, const building * b) if (invisible(u, u2) >= u->number) continue; - o = eff_skill(u2, SK_PERCEPTION, r); + o = effskill(u2, SK_PERCEPTION, r); if (o + 2 >= n) { return 0; /* entdeckt! */ @@ -2290,7 +2290,7 @@ static bool display_potion(faction * f, unit * u, const potion_type * ptype) return false; else { int i = i_get(u->items, ptype->itype); - if (i == 0 && 2 * ptype->level > effskill(u, SK_ALCHEMY)) { + if (i == 0 && 2 * ptype->level > effskill(u, SK_ALCHEMY, 0)) { return false; } } @@ -2465,7 +2465,7 @@ static void reshow(unit * u, struct order *ord, const char *s, param_t p) a_removeall(&u->faction->attribs, &at_seenspell); break; case P_POTIONS: - skill = effskill(u, SK_ALCHEMY); + skill = effskill(u, SK_ALCHEMY, 0); c = 0; for (ptype = potiontypes; ptype != NULL; ptype = ptype->next) { if (ptype->level * 2 <= skill) { @@ -3138,7 +3138,7 @@ static building *age_building(building * b) curse *c = get_curse(rt->attribs, ct_astralblock); if (c == NULL) { if (mage != NULL) { - int sk = effskill(mage, SK_MAGIC); + int sk = effskill(mage, SK_MAGIC, 0); float effect = 100; /* the mage reactivates the circle */ c = create_curse(mage, &rt->attribs, ct_astralblock, @@ -3148,7 +3148,7 @@ static building *age_building(building * b) } } else if (mage != NULL) { - int sk = effskill(mage, SK_MAGIC); + int sk = effskill(mage, SK_MAGIC, 0); c->duration = _max(c->duration, sk / 2); c->vigour = _max(c->vigour, (float)sk); } @@ -3693,7 +3693,7 @@ static int faction_getmages(faction * f, unit ** results, int numresults) if (u->number > 0) { sc_mage *mage = get_mage(u); if (mage) { - int level = eff_skill(u, SK_MAGIC, u->region); + int level = effskill(u, SK_MAGIC, 0); if (level > maxlevel) { maxlevel = level; } @@ -3752,7 +3752,7 @@ static void update_spells(void) unit * u = mages[i]; sc_mage *mage = get_mage(u); if (mage && mage->spellbook) { - int level = effskill(u, SK_MAGIC); + int level = effskill(u, SK_MAGIC, 0); show_new_spells(f, level, mage->spellbook); } } @@ -4182,7 +4182,7 @@ int armedmen(const unit * u, bool siege_weapons) item *itm; int n = 0; if (!(urace(u)->flags & RCF_NOWEAPONS)) { - if (effskill(u, SK_WEAPONLESS) >= 1) { + if (effskill(u, SK_WEAPONLESS, 0) >= 1) { /* kann ohne waffen bewachen: fuer drachen */ n = u->number; } @@ -4193,7 +4193,7 @@ int armedmen(const unit * u, bool siege_weapons) const weapon_type *wtype = resource2weapon(itm->type->rtype); if (wtype == NULL || (!siege_weapons && (wtype->flags & WTF_SIEGE))) continue; - if (effskill(u, wtype->skill) >= wtype->minskill) + if (effskill(u, wtype->skill, 0) >= wtype->minskill) n += itm->number; /* if (effskill(u, wtype->skill) >= wtype->minskill) n += itm->number; */ if (n > u->number) @@ -4238,9 +4238,9 @@ int siege_cmd(unit * u, order * ord) d = _min(u->number, d); pooled = get_pooled(u, rt_catapultammo, GET_DEFAULT, d); d = _min(pooled, d); - if (eff_skill(u, SK_CATAPULT, r) >= 1) { + if (effskill(u, SK_CATAPULT, 0) >= 1) { katapultiere = d; - d *= eff_skill(u, SK_CATAPULT, r); + d *= effskill(u, SK_CATAPULT, 0); } else { d = 0; @@ -4604,6 +4604,7 @@ cansee(const faction * f, const region * r, const unit * u, int modifier) int stealth, rings; unit *u2 = r->units; + assert(u->region == r); // TODO: param r is unnecessary if (u->faction == f || omniscient(f)) { return true; } @@ -4640,7 +4641,7 @@ cansee(const faction * f, const region * r, const unit * u, int modifier) while (u2) { if (rings < u->number || invisible(u, u2) < u->number) { if (skill_enabled(SK_PERCEPTION)) { - int observation = eff_skill(u2, SK_PERCEPTION, r); + int observation = effskill(u2, SK_PERCEPTION, 0); if (observation >= stealth) { return true; @@ -4684,7 +4685,7 @@ bool cansee_unit(const unit * u, const unit * target, int modifier) return false; } if (skill_enabled(SK_PERCEPTION)) { - o = eff_skill(u, SK_PERCEPTION, target->region); + o = effskill(u, SK_PERCEPTION, target->region); if (o >= n) { return true; } @@ -4730,7 +4731,7 @@ int modifier) if (rings && invisible(u, u2) >= u->number) continue; - o = eff_skill(u2, SK_PERCEPTION, r); + o = effskill(u2, SK_PERCEPTION, 0); if (o >= n) { return true; diff --git a/src/lighthouse.c b/src/lighthouse.c index da9d489dd..88193ecc7 100644 --- a/src/lighthouse.c +++ b/src/lighthouse.c @@ -81,7 +81,7 @@ int lighthouse_range(const building * b, const faction * f) if (c > buildingcapacity(b)) break; if (f == NULL || u->faction == f) { - int sk = eff_skill(u, SK_PERCEPTION, r) / 3; + int sk = effskill(u, SK_PERCEPTION, 0) / 3; d = _max(d, sk); d = _min(maxd, d); if (d == maxd) @@ -131,7 +131,7 @@ bool check_leuchtturm(region * r, faction * f) d = distance(r, r2); if (maxd < d) break; - if (eff_skill(u, SK_PERCEPTION, r) >= d * 3) + if (effskill(u, SK_PERCEPTION, 0) >= d * 3) return true; } } diff --git a/src/magic.c b/src/magic.c index a02eff09f..2e9b7199c 100644 --- a/src/magic.c +++ b/src/magic.c @@ -517,7 +517,7 @@ int u_hasspell(const unit *u, const struct spell *sp) spellbook * book = unit_get_spellbook(u); spellbook_entry * sbe = book ? spellbook_get(book, sp) : 0; if (sbe) { - return sbe->level <= effskill(u, SK_MAGIC); + return sbe->level <= effskill(u, SK_MAGIC, 0); } return 0; } @@ -531,7 +531,7 @@ int get_combatspelllevel(const unit * u, int nr) assert(nr < MAXCOMBATSPELLS); if (m) { - int level = eff_skill(u, SK_MAGIC, u->region); + int level = effskill(u, SK_MAGIC, 0); return _min(m->combatspells[nr].level, level); } return -1; @@ -703,7 +703,7 @@ static int use_item_aura(const region * r, const unit * u) { int sk, n; - sk = eff_skill(u, SK_MAGIC, r); + sk = effskill(u, SK_MAGIC, r); n = (int)(sk * sk * u_race(u)->maxaura / 4); return n; @@ -717,7 +717,7 @@ int max_spellpoints(const region * r, const unit * u) double divisor = 1.2; const struct resource_type *rtype; - sk = eff_skill(u, SK_MAGIC, r); + sk = effskill(u, SK_MAGIC, r); msp = u_race(u)->maxaura * (pow(sk, potenz) / divisor + 1) + get_spchange(u); rtype = rt_find("aurafocus"); @@ -950,7 +950,7 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord) return false; } /* reicht die Stufe aus? */ - if (eff_skill(u, SK_MAGIC, u->region) < level) { + if (effskill(u, SK_MAGIC, 0) < level) { /* die Einheit ist nicht erfahren genug für diesen Zauber */ cmistake(u, ord, 169, MSG_MAGIC); return false; @@ -1123,7 +1123,7 @@ double magic_resistance(unit * target) assert(target->number > 0); /* Magier haben einen Resistenzbonus vom Magietalent * 5% */ - probability += effskill(target, SK_MAGIC) * 0.05; + probability += effskill(target, SK_MAGIC, 0) * 0.05; /* Auswirkungen von Zaubern auf der Einheit */ c = get_curse(target->attribs, ct_find("magicresistance")); @@ -1207,10 +1207,10 @@ target_resists_magic(unit * magician, void *obj, int objtyp, int t_bonus) skill *sv; unit *u = (unit *)obj; - at = effskill(magician, SK_MAGIC); + at = effskill(magician, SK_MAGIC, 0); for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { - int sk = effskill(u, sv->id); + int sk = eff_skill(u, sv, 0); if (pa < sk) pa = sk; } @@ -1282,7 +1282,7 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade) * */ int rnd = 0; - double x = (double)cast_grade / (double)eff_skill(u, SK_MAGIC, r); + double x = (double)cast_grade / (double)effskill(u, SK_MAGIC, r); int fumble_chance = (int)(((double)x * 40.0) - 20.0); struct building *b = inside_building(u); const struct building_type *btype = b ? b->type : NULL; @@ -1432,7 +1432,7 @@ static double regeneration(unit * u) double potenz = 1.5; double divisor = 2.0; - sk = effskill(u, SK_MAGIC); + sk = effskill(u, SK_MAGIC, 0); /* Rassenbonus/-malus */ d = pow(sk, potenz) * u_race(u)->regaura / divisor; d++; @@ -2149,7 +2149,7 @@ static int sm_familiar(const unit * u, const region * r, skill_t sk, int value) /* the familiar is dead */ return value; } - mod = eff_skill(familiar, sk, r) / 2; + mod = effskill(familiar, sk, r) / 2; if (r != familiar->region) { mod /= distance(r, familiar->region); } @@ -2515,7 +2515,7 @@ static castorder *cast_cmd(unit * u, order * ord) cmistake(u, ord, 269, MSG_MAGIC); return 0; } - level = eff_skill(u, SK_MAGIC, r); + level = effskill(u, SK_MAGIC, 0); init_order(ord); s = gettoken(token, sizeof(token)); @@ -2648,7 +2648,7 @@ static castorder *cast_cmd(unit * u, order * ord) } /* Stufenangabe bei nicht Stufenvariierbaren Sprüchen abfangen */ if (!(sp->sptyp & SPELLLEVEL)) { - int ilevel = eff_skill(u, SK_MAGIC, u->region); + int ilevel = effskill(u, SK_MAGIC, 0); if (ilevel != level) { level = ilevel; ADDMSG(&u->faction->msgs, msg_message("spellfail::nolevel", @@ -2674,7 +2674,7 @@ static castorder *cast_cmd(unit * u, order * ord) "mage", caster)); return 0; } - if (distance(caster->region, r) > eff_skill(caster, SK_MAGIC, caster->region)) { + if (distance(caster->region, r) > effskill(caster, SK_MAGIC, 0)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "familiar_toofar", "mage", caster)); return 0; @@ -2684,7 +2684,7 @@ static castorder *cast_cmd(unit * u, order * ord) * löschen, zaubern kann er noch */ range *= 2; set_order(&caster->thisorder, NULL); - level = _min(level, eff_skill(caster, SK_MAGIC, caster->region) / 2); + level = _min(level, effskill(caster, SK_MAGIC, 0) / 2); } } /* Weitere Argumente zusammenbasteln */ diff --git a/src/monsters.c b/src/monsters.c index d81ba7f81..e010ee7ff 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -853,7 +853,7 @@ void plan_monsters(faction * f) /* Einheiten, die Waffenlosen Kampf lernen könnten, lernen es um * zu bewachen: */ if (u_race(u)->bonus[SK_WEAPONLESS] != -99) { - if (eff_skill(u, SK_WEAPONLESS, u->region) < 1) { + if (effskill(u, SK_WEAPONLESS, 0) < 1) { long_order = create_order(K_STUDY, f->locale, "'%s'", skillname(SK_WEAPONLESS, f->locale)); diff --git a/src/move.c b/src/move.c index f775acb79..99e87c061 100644 --- a/src/move.c +++ b/src/move.c @@ -251,7 +251,7 @@ static int ridingcapacity(unit * u) ** tragen nichts (siehe walkingcapacity). Ein Wagen zählt nur, wenn er ** von zwei Pferden gezogen wird */ - animals = _min(animals, effskill(u, SK_RIDING) * u->number * 2); + animals = _min(animals, effskill(u, SK_RIDING, 0) * u->number * 2); if (fval(u_race(u), RCF_HORSE)) animals += u->number; @@ -275,7 +275,7 @@ int walkingcapacity(const struct unit *u) /* Das Gewicht, welches die Pferde tragen, plus das Gewicht, welches * die Leute tragen */ - pferde_fuer_wagen = _min(animals, effskill(u, SK_RIDING) * u->number * 4); + pferde_fuer_wagen = _min(animals, effskill(u, SK_RIDING, 0) * u->number * 4); if (fval(u_race(u), RCF_HORSE)) { animals += u->number; people = 0; @@ -338,7 +338,7 @@ static int canwalk(unit * u) int maxwagen, maxpferde; int vehicles = 0, vcap = 0; int animals = 0, acap = 0; - + int effsk; /* workaround: monsters are too stupid to drop items, therefore they have * infinite carrying capacity */ @@ -347,11 +347,12 @@ static int canwalk(unit * u) get_transporters(u->items, &animals, &acap, &vehicles, &vcap); - maxwagen = effskill(u, SK_RIDING) * u->number * 2; + effsk = effskill(u, SK_RIDING, 0); + maxwagen = effsk * u->number * 2; if (u_race(u) == get_race(RC_TROLL)) { maxwagen = _max(maxwagen, u->number / 4); } - maxpferde = effskill(u, SK_RIDING) * u->number * 4 + u->number; + maxpferde = effsk * u->number * 4 + u->number; if (animals > maxpferde) return E_CANWALK_TOOMANYHORSES; @@ -375,7 +376,7 @@ static int canwalk(unit * u) bool canfly(unit * u) { - if (i_get(u->items, it_find("pegasus")) >= u->number && effskill(u, SK_RIDING) >= 4) + if (i_get(u->items, it_find("pegasus")) >= u->number && effskill(u, SK_RIDING, 0) >= 4) return true; if (fval(u_race(u), RCF_FLY)) @@ -389,7 +390,7 @@ bool canfly(unit * u) bool canswim(unit * u) { - if (i_get(u->items, it_find("dolphin")) >= u->number && effskill(u, SK_RIDING) >= 4) + if (i_get(u->items, it_find("dolphin")) >= u->number && effskill(u, SK_RIDING, 0) >= 4) return true; if (u_race(u)->flags & RCF_FLY) @@ -410,7 +411,7 @@ bool canswim(unit * u) static int canride(unit * u) { int horses = 0, maxhorses, unicorns = 0, maxunicorns; - int skill = effskill(u, SK_RIDING); + int skill = effskill(u, SK_RIDING, 0); item *itm; const item_type *it_horse, *it_elvenhorse, *it_charger; const resource_type *rtype; @@ -483,7 +484,7 @@ static ship *do_maelstrom(region * r, unit * u) int damage; ship *sh = u->ship; - damage = rng_int() % 75 + rng_int() % 75 - eff_skill(u, SK_SAILING, r) * 4; + damage = rng_int() % 75 + rng_int() % 75 - effskill(u, SK_SAILING, r) * 4; if (damage <= 0) { return sh; @@ -606,7 +607,7 @@ ship *move_ship(ship * sh, region * from, region * to, region_list * route) ulist = &u->next; u->ship = sh; /* undo the trick -- do not use u_set_ship here */ } - if (route && eff_skill(u, SK_SAILING, from) >= 1) { + if (route && effskill(u, SK_SAILING, from) >= 1) { produceexp(u, SK_SAILING, u->number); } } @@ -739,7 +740,7 @@ static void drifting_ships(region * r) continue; if (firstu == NULL) firstu = captain; - if (eff_skill(captain, SK_SAILING, r) >= sh->type->cptskill) { + if (effskill(captain, SK_SAILING, r) >= sh->type->cptskill) { break; } } @@ -869,7 +870,7 @@ static unit *bewegung_blockiert_von(unit * reisender, region * r) return NULL; for (u = r->units; u; u = u->next) { if (is_guard(u, GUARD_TRAVELTHRU)) { - int sk = eff_skill(u, SK_PERCEPTION, r); + int sk = effskill(u, SK_PERCEPTION, r); if (invisible(reisender, u) >= reisender->number) continue; if (!(u_race(u)->flags & RCF_FLY) && u_race(reisender)->flags & RCF_FLY) @@ -1717,7 +1718,7 @@ static bool ship_ready(const region * r, unit * u) cmistake(u, u->thisorder, 146, MSG_MOVE); return false; } - if (eff_skill(u, SK_SAILING, r) < u->ship->type->cptskill) { + if (effskill(u, SK_SAILING, r) < u->ship->type->cptskill) { ADDMSG(&u->faction->msgs, msg_feedback(u, u->thisorder, "error_captain_skill_low", "value ship", u->ship->type->cptskill, u->ship)); @@ -2060,11 +2061,11 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep) for (u2 = current_point->units; u2; u2 = u2->next) { if (u2->ship == sh && !alliedunit(harbourmaster, u->faction, HELP_GUARD)) { - if (effskill(harbourmaster, SK_PERCEPTION) > effskill(u2, SK_STEALTH)) { + if (effskill(harbourmaster, SK_PERCEPTION, 0) > effskill(u2, SK_STEALTH, 0)) { for (itm = u2->items; itm; itm = itm->next) { const luxury_type *ltype = resource2luxury(itm->type->rtype); if (ltype != NULL && itm->number > 0) { - int st = itm->number * effskill(harbourmaster, SK_TRADE) / 50; + int st = itm->number * effskill(harbourmaster, SK_TRADE, 0) / 50; st = _min(itm->number, st); if (st > 0) { diff --git a/src/randenc.c b/src/randenc.c index 12b1aec58..cdf7b9380 100644 --- a/src/randenc.c +++ b/src/randenc.c @@ -291,9 +291,9 @@ static void get_allies(region * r, unit * u) break; } else { - if (eff_skill(u, SK_LONGBOW, r) < 3 - && eff_skill(u, SK_HERBALISM, r) < 2 - && eff_skill(u, SK_MAGIC, r) < 2) { + if (effskill(u, SK_LONGBOW, r) < 3 + && effskill(u, SK_HERBALISM, r) < 2 + && effskill(u, SK_MAGIC, r) < 2) { return; } name = "random_forest_men"; @@ -303,7 +303,7 @@ static void get_allies(region * r, unit * u) break; case T_SWAMP: - if (eff_skill(u, SK_MELEE, r) <= 1) { + if (effskill(u, SK_MELEE, r) <= 1) { return; } name = "random_swamp_men"; @@ -312,7 +312,7 @@ static void get_allies(region * r, unit * u) break; case T_DESERT: - if (eff_skill(u, SK_RIDING, r) <= 2) { + if (effskill(u, SK_RIDING, r) <= 2) { return; } name = "random_desert_men"; @@ -321,7 +321,7 @@ static void get_allies(region * r, unit * u) break; case T_HIGHLAND: - if (eff_skill(u, SK_MELEE, r) <= 1) { + if (effskill(u, SK_MELEE, r) <= 1) { return; } name = "random_highland_men"; @@ -330,7 +330,7 @@ static void get_allies(region * r, unit * u) break; case T_MOUNTAIN: - if (eff_skill(u, SK_MELEE, r) <= 1 || eff_skill(u, SK_TRADE, r) <= 2) { + if (effskill(u, SK_MELEE, r) <= 1 || effskill(u, SK_TRADE, r) <= 2) { return; } name = "random_mountain_men"; @@ -339,7 +339,7 @@ static void get_allies(region * r, unit * u) break; case T_GLACIER: - if (eff_skill(u, SK_MELEE, r) <= 1 || eff_skill(u, SK_TRADE, r) <= 1) { + if (effskill(u, SK_MELEE, r) <= 1 || effskill(u, SK_TRADE, r) <= 1) { return; } name = "random_glacier_men"; diff --git a/src/reports.c b/src/reports.c index 9d4d7f21c..58b6144e3 100644 --- a/src/reports.c +++ b/src/reports.c @@ -420,7 +420,7 @@ const faction * viewer) const unit *u; for (u = r->units; visible != res->amount && u != NULL; u = u->next) { if (u->faction == viewer) { - int s = eff_skill(u, itype->construction->skill, r); + int s = effskill(u, itype->construction->skill, 0); if (s > maxskill) { maxskill = s; visible = res->type->visible(res, maxskill); @@ -515,7 +515,7 @@ size_t size) bufp = STRLCPY(bufp, ", ", size); if (u->faction != f && a_fshidden && a_fshidden->data.ca[0] == 1 - && effskill(u, SK_STEALTH) >= 6) { + && effskill(u, SK_STEALTH, 0) >= 6) { bufp = STRLCPY(bufp, "? ", size); } else { @@ -602,7 +602,7 @@ size_t size) show = u->items; } else if (!itemcloak && mode >= see_unit && !(a_fshidden - && a_fshidden->data.ca[1] == 1 && effskill(u, SK_STEALTH) >= 3)) { + && a_fshidden->data.ca[1] == 1 && effskill(u, SK_STEALTH, 0) >= 3)) { int n = report_items(u->items, results, MAX_INVENTORY, u, f); assert(n >= 0); if (n > 0) @@ -641,7 +641,7 @@ size_t size) if (book) { quicklist *ql = book->spells; - int qi, header, maxlevel = effskill(u, SK_MAGIC); + int qi, header, maxlevel = effskill(u, SK_MAGIC, 0); int result = _snprintf(bufp, size, ". Aura %d/%d", get_spellpoints(u), max_spellpoints(u->region, u)); if (wrptr(&bufp, &size, result) != 0) { WARN_STATIC_BUFFER(); @@ -810,7 +810,7 @@ const struct unit * u, struct skill * sv, int *dh, int days) } } - effsk = effskill(u, sv->id); + effsk = eff_skill(u, sv, 0); if (wrptr(&bufp, &size, _snprintf(bufp, size, "%d", effsk)) != 0) WARN_STATIC_BUFFER(); @@ -1351,7 +1351,7 @@ static void view_regatta(struct seen_region **seen, region * r, faction * f) int skill = 0; for (u = r->units; u; u = u->next) { if (u->faction == f) { - int es = effskill(u, SK_PERCEPTION); + int es = effskill(u, SK_PERCEPTION, 0); if (es > skill) skill = es; } diff --git a/src/spells.c b/src/spells.c index 8833497d5..eee154ffe 100644 --- a/src/spells.c +++ b/src/spells.c @@ -2516,7 +2516,7 @@ static int sp_fumblecurse(castorder * co) target = pa->param[0]->data.u; rx = rng_int() % 3; - sx = cast_level - effskill(target, SK_MAGIC); + sx = cast_level - effskill(target, SK_MAGIC, 0); duration = _max(sx, rx) + 1; effect = force / 2; @@ -3254,7 +3254,7 @@ static int sp_bloodsacrifice(castorder * co) unit *mage = co->magician.u; int cast_level = co->level; int aura; - int skill = eff_skill(mage, SK_MAGIC, mage->region); + int skill = effskill(mage, SK_MAGIC, 0); int hp = (int)(co->force * 8); if (hp <= 0) { @@ -3591,11 +3591,11 @@ static int sp_charmingsong(castorder * co) } /* Magieresistensbonus fuer hoehere Talentwerte */ for (i = 0; i < MAXSKILLS; i++) { - int sk = effskill(target, i); + int sk = effskill(target, i, 0); if (tb < sk) tb = sk; } - tb -= effskill(mage, SK_MAGIC); + tb -= effskill(mage, SK_MAGIC, 0); if (tb > 0) { resist_bonus += tb * 15; } @@ -4143,7 +4143,7 @@ static int sp_pump(castorder * co) create_unit(rt, mage->faction, RS_FARVISION, get_race(RC_SPELL), 0, "spell/pump", NULL); u->age = 2; - set_level(u, SK_PERCEPTION, eff_skill(target, SK_PERCEPTION, u->region)); + set_level(u, SK_PERCEPTION, effskill(target, SK_PERCEPTION, 0)); return cast_level; } @@ -4795,7 +4795,7 @@ int sp_dreamreading(castorder * co) "spell/dreamreading", NULL); set_number(u2, 1); u2->age = 2; /* Nur fuer diese Runde. */ - set_level(u2, SK_PERCEPTION, eff_skill(u, SK_PERCEPTION, u2->region)); + set_level(u2, SK_PERCEPTION, effskill(u, SK_PERCEPTION, u2->region)); msg = msg_message("sp_dreamreading_effect", "mage unit region", mage, u, diff --git a/src/spy.c b/src/spy.c index 8264fcabf..7343213c9 100644 --- a/src/spy.c +++ b/src/spy.c @@ -99,7 +99,7 @@ void spy_message(int spy, const unit * u, const unit * target) strncat(buf, (const char *)skillname((skill_t)sv->id, u->faction->locale), sizeof(buf) - 1); strncat(buf, " ", sizeof(buf) - 1); - strncat(buf, itoa10(eff_skill(target, (skill_t)sv->id, target->region)), + strncat(buf, itoa10(eff_skill(target, sv, target->region)), sizeof(buf) - 1); } } @@ -134,14 +134,14 @@ int spy_cmd(unit * u, struct order *ord) cmistake(u, u->thisorder, 24, MSG_EVENT); return 0; } - if (eff_skill(u, SK_SPY, r) < 1) { + if (effskill(u, SK_SPY, 0) < 1) { cmistake(u, u->thisorder, 39, MSG_EVENT); return 0; } /* Die Grundchance fuer einen erfolgreichen Spionage-Versuch ist 10%. * Fuer jeden Talentpunkt, den das Spionagetalent das Tarnungstalent * des Opfers uebersteigt, erhoeht sich dieses um 5%*/ - spy = eff_skill(u, SK_SPY, r) - eff_skill(target, SK_STEALTH, r); + spy = effskill(u, SK_SPY, 0) - effskill(target, SK_STEALTH, r); spychance = 0.1 + _max(spy * 0.05, 0.0); if (chance(spychance)) { @@ -154,8 +154,8 @@ int spy_cmd(unit * u, struct order *ord) /* der Spion kann identifiziert werden, wenn das Opfer bessere * Wahrnehmung als das Ziel Tarnung + Spionage/2 hat */ - observe = eff_skill(target, SK_PERCEPTION, r) - - (effskill(u, SK_STEALTH) + eff_skill(u, SK_SPY, r) / 2); + observe = effskill(target, SK_PERCEPTION, r) + - (effskill(u, SK_STEALTH, 0) + effskill(u, SK_SPY, 0) / 2); if (invisible(u, target) >= u->number) { observe = _min(observe, 0); @@ -164,8 +164,8 @@ int spy_cmd(unit * u, struct order *ord) /* Anschliessend wird - unabhaengig vom Erfolg - gewuerfelt, ob der * Spionageversuch bemerkt wurde. Die Wahrscheinlich dafuer ist (100 - * SpionageSpion*5 + WahrnehmungOpfer*2)%. */ - observechance = 1.0 - (eff_skill(u, SK_SPY, r) * 0.05) - + (eff_skill(target, SK_PERCEPTION, r) * 0.02); + observechance = 1.0 - (effskill(u, SK_SPY, 0) * 0.05) + + (effskill(target, SK_PERCEPTION, 0) * 0.02); if (chance(observechance)) { ADDMSG(&target->faction->msgs, msg_message("spydetect", @@ -228,7 +228,7 @@ int setstealth_cmd(unit * u, struct order *ord) if (isdigit(s[0])) { /* Tarnungslevel setzen */ level = atoi((const char *)s); - if (level > effskill(u, SK_STEALTH)) { + if (level > effskill(u, SK_STEALTH, 0)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_lowstealth", "")); return 0; } @@ -352,7 +352,7 @@ static int top_skill(region * r, faction * f, ship * sh, skill_t sk) for (u = r->units; u; u = u->next) { if (u->ship == sh && u->faction == f) { - int s = eff_skill(u, sk, r); + int s = effskill(u, sk, 0); value = _max(s, value); } } @@ -498,7 +498,6 @@ int sabotage_cmd(unit * u, struct order *ord) param_t p; ship *sh; unit *u2; - region *r; int skdiff = INT_MAX; assert(u); @@ -517,13 +516,12 @@ int sabotage_cmd(unit * u, struct order *ord) return 0; } u2 = ship_owner(sh); - r = u->region; if (u2->faction != u->faction) { skdiff = - eff_skill(u, SK_SPY, r) - top_skill(r, u2->faction, sh, SK_PERCEPTION); + effskill(u, SK_SPY, 0) - top_skill(u->region, u2->faction, sh, SK_PERCEPTION); } if (try_destruction(u, u2, sh, skdiff)) { - sink_ship(r, sh, u); + sink_ship(u->region, sh, u); } break; default: diff --git a/src/study.c b/src/study.c index 08bb749b2..3a0f38921 100644 --- a/src/study.c +++ b/src/study.c @@ -347,8 +347,7 @@ int teach_cmd(unit * u, struct order *ord) sk = teachskill[i]; } if (sk != NOSKILL - && eff_skill_study(u, sk, - r) - TEACHDIFFERENCE > eff_skill_study(student, sk, r)) { + && effskill_study(u, sk, 0) - TEACHDIFFERENCE > effskill_study(student, sk, 0)) { teaching -= teach_unit(u, student, teaching, sk, true, &academy); } } @@ -366,8 +365,7 @@ int teach_cmd(unit * u, struct order *ord) init_order(student->thisorder); sk = getskill(student->faction->locale); if (sk != NOSKILL - && eff_skill_study(u, sk, r) - TEACHDIFFERENCE >= eff_skill(student, - sk, r)) { + && effskill_study(u, sk, 0) - TEACHDIFFERENCE >= effskill(student, sk, 0)) { teaching -= teach_unit(u, student, teaching, sk, true, &academy); } } @@ -454,8 +452,8 @@ int teach_cmd(unit * u, struct order *ord) } /* u is teacher, u2 is student */ - if (eff_skill_study(u2, sk, r) > eff_skill_study(u, sk, - r) - TEACHDIFFERENCE) { + if (effskill_study(u2, sk, 0) > effskill_study(u, sk, 0) + - TEACHDIFFERENCE) { if (feedback) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "teach_asgood", "student", u2)); @@ -565,7 +563,7 @@ int study_cmd(unit * u, order * ord) cmistake(u, ord, 77, MSG_EVENT); return 0; } - if (SkillCap(sk) && SkillCap(sk) <= effskill(u, sk)) { + if (SkillCap(sk) && SkillCap(sk) <= effskill(u, sk, 0)) { cmistake(u, ord, 771, MSG_EVENT); return 0; } @@ -684,7 +682,7 @@ int study_cmd(unit * u, order * ord) } } if (sk == SK_ALCHEMY) { - maxalchemy = eff_skill(u, SK_ALCHEMY, r); + maxalchemy = effskill(u, SK_ALCHEMY, 0); if (!has_skill(u, SK_ALCHEMY)) { int amax = skill_limit(u->faction, SK_ALCHEMY); if (count_skill(u->faction, SK_ALCHEMY) + u->number > amax) { @@ -779,7 +777,7 @@ int study_cmd(unit * u, order * ord) if (feedback) { ADDMSG(&teacher->faction->msgs, msg_message("teach_teacher", "teacher student skill level", teacher, u, sk, - effskill(u, sk))); + effskill(u, sk, 0))); } ADDMSG(&u->faction->msgs, msg_message("teach_student", "teacher student skill", teacher, u, sk)); @@ -796,7 +794,7 @@ int study_cmd(unit * u, order * ord) if (sk == SK_ALCHEMY) { const potion_type *ptype; faction *f = u->faction; - int skill = eff_skill(u, SK_ALCHEMY, r); + int skill = effskill(u, SK_ALCHEMY, 0); if (skill > maxalchemy) { for (ptype = potiontypes; ptype; ptype = ptype->next) { if (skill == ptype->level * 2) { diff --git a/src/summary.c b/src/summary.c index cd6e912e0..43c540e55 100644 --- a/src/summary.c +++ b/src/summary.c @@ -440,7 +440,7 @@ summary *make_summary(void) for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { skill_t sk = sv->id; - int aktskill = eff_skill(u, sk, r); + int aktskill = effskill(u, sk, r); if (aktskill > s->maxskill) s->maxskill = aktskill; } From 66d8e3c7bad4292f32ac49f482cdcec22094465c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 27 Aug 2015 16:23:30 +0200 Subject: [PATCH 7/9] fix linux build, kill invalid assert --- src/alchemy.test.c | 2 ++ src/attributes/stealth.c | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/alchemy.test.c b/src/alchemy.test.c index fed4946f2..2a639243b 100644 --- a/src/alchemy.test.c +++ b/src/alchemy.test.c @@ -11,6 +11,8 @@ #include #include +#include + #include #include "tests.h" diff --git a/src/attributes/stealth.c b/src/attributes/stealth.c index e4da1ec5c..7ec85e4f6 100644 --- a/src/attributes/stealth.c +++ b/src/attributes/stealth.c @@ -5,7 +5,6 @@ #include #include -#include #include attrib_type at_stealth = { @@ -49,8 +48,6 @@ int u_geteffstealth(const unit *u) int eff_stealth(const unit * u, const region * r) { int e = 0; - - assert(u->region == r); // TODO: param r is useless /* Auf Schiffen keine Tarnung! */ if (!u->ship && skill_enabled(SK_STEALTH)) { e = effskill(u, SK_STEALTH, r); From 564a041b0d67ba491eba5a56f69b0af4ae6d334e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 27 Aug 2015 16:53:36 +0200 Subject: [PATCH 8/9] eliminate invalid assertions, remove unnecessary arguments (plant/breed/trees) --- src/attributes/stealth.c | 2 +- src/economy.c | 21 +++++++++++---------- src/laws.c | 8 ++++---- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/attributes/stealth.c b/src/attributes/stealth.c index e4da1ec5c..6f133f01c 100644 --- a/src/attributes/stealth.c +++ b/src/attributes/stealth.c @@ -46,11 +46,11 @@ int u_geteffstealth(const unit *u) return -1; } +/* r != u->region when called by cansee (see comment there) */ int eff_stealth(const unit * u, const region * r) { int e = 0; - assert(u->region == r); // TODO: param r is useless /* Auf Schiffen keine Tarnung! */ if (!u->ship && skill_enabled(SK_STEALTH)) { e = effskill(u, SK_STEALTH, r); diff --git a/src/economy.c b/src/economy.c index ea37c1e8b..8e790f666 100644 --- a/src/economy.c +++ b/src/economy.c @@ -2264,11 +2264,12 @@ static void expandstealing(region * r, request * stealorders) } /* ------------------------------------------------------------- */ -static void plant(region * r, unit * u, int raw) +static void plant(unit * u, int raw) { int n, i, skill, planted = 0; const item_type *itype; const resource_type *rt_water = get_resourcetype(R_WATER_OF_LIFE); + region *r = u->region; assert(rt_water != NULL); if (!fval(r->terrain, LAND_REGION)) { @@ -2320,12 +2321,12 @@ static void plant(region * r, unit * u, int raw) u, r, planted, itype->rtype)); } -static void planttrees(region * r, unit * u, int raw) +static void planttrees(unit * u, int raw) { int n, i, skill, planted = 0; const resource_type *rtype; + region * r = u->region; - assert(r == u->region); // TODO: param r is unnecessary if (!fval(r->terrain, LAND_REGION)) { return; } @@ -2374,14 +2375,14 @@ static void planttrees(region * r, unit * u, int raw) } /* züchte bäume */ -static void breedtrees(region * r, unit * u, int raw) +static void breedtrees(unit * u, int raw) { int n, i, skill, planted = 0; const resource_type *rtype; static int gamecookie = -1; static int current_season; + region *r = u->region; - assert(r == u->region); // TODO: param r is unnecessary if (gamecookie != global.cookie) { gamedate date; get_gamedate(turn, &date); @@ -2391,7 +2392,7 @@ static void breedtrees(region * r, unit * u, int raw) /* Bäume züchten geht nur im Frühling */ if (current_season != SEASON_SPRING) { - planttrees(r, u, raw); + planttrees(u, raw); return; } @@ -2405,7 +2406,7 @@ static void breedtrees(region * r, unit * u, int raw) /* Skill prüfen */ skill = effskill(u, SK_HERBALISM, 0); if (skill < 12) { - planttrees(r, u, raw); + planttrees(u, raw); return; } @@ -2506,16 +2507,16 @@ static void breed_cmd(unit * u, struct order *ord) switch (p) { case P_HERBS: - plant(r, u, m); + plant(u, m); break; case P_TREES: - breedtrees(r, u, m); + breedtrees(u, m); break; default: if (p != P_ANY) { rtype = findresourcetype(s, u->faction->locale); if (rtype == get_resourcetype(R_SEED) || rtype == get_resourcetype(R_MALLORNSEED)) { - breedtrees(r, u, m); + breedtrees(u, m); break; } else if (rtype != get_resourcetype(R_HORSE)) { diff --git a/src/laws.c b/src/laws.c index dfa97a34b..6e42bc736 100755 --- a/src/laws.c +++ b/src/laws.c @@ -4597,14 +4597,14 @@ void update_subscriptions(void) bool cansee(const faction * f, const region * r, const unit * u, int modifier) -/* r kann != u->region sein, wenn es um durchreisen geht */ -/* und es muss niemand aus f in der region sein, wenn sie vom Turm -* erblickt wird */ +/* r kann != u->region sein, wenn es um Durchreisen geht, + * oder Zauber (sp_generous, sp_fetchastral). + * Es muss auch niemand aus f in der region sein, wenn sie vom Turm + * erblickt wird */ { int stealth, rings; unit *u2 = r->units; - assert(u->region == r); // TODO: param r is unnecessary if (u->faction == f || omniscient(f)) { return true; } From e4026e0f6bc537df7591387113d59be52b81cf83 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 27 Aug 2015 16:59:39 +0200 Subject: [PATCH 9/9] eliminate more non-critical arguments. --- src/economy.c | 12 ++++++------ src/kernel/build.c | 12 ++++++------ src/kernel/build.h | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/economy.c b/src/economy.c index 8e790f666..e01d7b79b 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1526,7 +1526,7 @@ int make_cmd(unit * u, struct order *ord) const char * s = gettoken(token, sizeof(token)); direction_t d = s ? get_direction(s, u->faction->locale) : NODIRECTION; if (d != NODIRECTION) { - build_road(r, u, m, d); + build_road(u, m, d); } else { /* Die Richtung wurde nicht erkannt */ @@ -1541,7 +1541,7 @@ int make_cmd(unit * u, struct order *ord) cmistake(u, ord, 276, MSG_PRODUCE); } else { - continue_ship(r, u, m); + continue_ship(u, m); } return 0; } @@ -1597,7 +1597,7 @@ int make_cmd(unit * u, struct order *ord) cmistake(u, ord, 276, MSG_PRODUCE); } else { - create_ship(r, u, stype, m, ord); + create_ship(u, stype, m, ord); } } else if (btype != NOBUILDING) { @@ -2437,15 +2437,15 @@ static void breedtrees(unit * u, int raw) } /* züchte pferde */ -static void breedhorses(region * r, unit * u) +static void breedhorses(unit * u) { int n, c, breed = 0; struct building *b = inside_building(u); const struct building_type *btype = b ? b->type : NULL; const struct resource_type *rhorse = get_resourcetype(R_HORSE); int horses, effsk; + assert(rhorse && rhorse->itype); - assert(r == u->region); // TODO: param r is unnecessary if (btype != bt_find("stables")) { cmistake(u, u->thisorder, 122, MSG_PRODUCE); return; @@ -2524,7 +2524,7 @@ static void breed_cmd(unit * u, struct order *ord) break; } } - breedhorses(r, u); + breedhorses(u); break; } } diff --git a/src/kernel/build.c b/src/kernel/build.c index a8c42063d..4ce08c39a 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -261,13 +261,13 @@ int destroy_cmd(unit * u, struct order *ord) /* ------------------------------------------------------------- */ -void build_road(region * r, unit * u, int size, direction_t d) +void build_road(unit * u, int size, direction_t d) { + region *r = u->region; int n, left, effsk; region *rn = rconnect(r, d); assert(u->number); - assert(r == u->region); // TODO: param r is unnecessary effsk = effskill(u, SK_ROAD_BUILDING, 0); if (!effsk) { cmistake(u, u->thisorder, 103, MSG_PRODUCE); @@ -880,15 +880,15 @@ static void build_ship(unit * u, ship * sh, int want) } void -create_ship(region * r, unit * u, const struct ship_type *newtype, int want, +create_ship(unit * u, const struct ship_type *newtype, int want, order * ord) { ship *sh; int msize; const construction *cons = newtype->construction; order *new_order; + region * r = u->region; - assert(u->region == r); // TODO: param r is unnecessary if (!effskill(u, SK_SHIPBUILDING, 0)) { cmistake(u, ord, 100, MSG_PRODUCE); return; @@ -931,13 +931,13 @@ order * ord) build_ship(u, sh, want); } -void continue_ship(region * r, unit * u, int want) +void continue_ship(unit * u, int want) { const construction *cons; ship *sh; int msize; + region * r = u->region; - assert(u->region == r); // TODO: param r is unnecessary if (!effskill(u, SK_SHIPBUILDING, 0)) { cmistake(u, u->thisorder, 100, MSG_PRODUCE); return; diff --git a/src/kernel/build.h b/src/kernel/build.h index 1e3d59bd5..5e231b198 100644 --- a/src/kernel/build.h +++ b/src/kernel/build.h @@ -68,10 +68,10 @@ extern "C" { extern int destroy_cmd(struct unit *u, struct order *ord); extern int leave_cmd(struct unit *u, struct order *ord); - void build_road(struct region *r, struct unit *u, int size, direction_t d); - void create_ship(struct region *r, struct unit *u, - const struct ship_type *newtype, int size, struct order *ord); - void continue_ship(struct region *r, struct unit *u, int size); + void build_road(struct unit *u, int size, direction_t d); + void create_ship(struct unit *u, const struct ship_type *newtype, + int size, struct order *ord); + void continue_ship(struct unit *u, int size); struct building *getbuilding(const struct region *r); struct ship *getship(const struct region *r);