From 92f43a7b5105d847ca21ee3900a8167e1565670f Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 24 Jun 2014 22:44:05 -0700 Subject: [PATCH] eliminate it_find calls, replace it_find with something backed by rt_find --- src/bind_faction.c | 6 +- src/items/weapons.c | 13 +- src/kernel/alchemy.c | 9 +- src/kernel/alliance.c | 6 +- src/kernel/battle.c | 22 +-- src/kernel/battle.test.c | 72 ++++---- src/kernel/config.c | 39 +++-- src/kernel/item.c | 91 ++++++---- src/kernel/item.h | 9 +- src/kernel/item.test.c | 14 +- src/kernel/jsonconf.c | 31 ++++ src/kernel/magic.c | 370 +++++++++++++++++++-------------------- src/kernel/move.c | 12 +- src/kernel/save.c | 63 ++++--- src/kernel/unit.c | 48 ++--- src/laws.c | 28 +-- src/laws.test.c | 149 ++++++++-------- src/monster.c | 6 +- src/races/races.c | 73 ++++---- src/tests.test.c | 12 +- 20 files changed, 566 insertions(+), 507 deletions(-) diff --git a/src/bind_faction.c b/src/bind_faction.c index a13c5f1f4..166a70acd 100644 --- a/src/bind_faction.c +++ b/src/bind_faction.c @@ -66,9 +66,9 @@ int tolua_faction_add_item(lua_State * L) int result = -1; if (iname != NULL) { - const item_type *itype = it_find(iname); - if (itype != NULL) { - item *i = i_change(&self->items, itype, number); + const resource_type *rtype = rt_find(iname); + if (rtype && rtype->itype) { + item *i = i_change(&self->items, rtype->itype, number); result = i ? i->number : 0; } /* if (itype!=NULL) */ } diff --git a/src/items/weapons.c b/src/items/weapons.c index acb14fb18..5dab42fa3 100644 --- a/src/items/weapons.c +++ b/src/items/weapons.c @@ -94,15 +94,13 @@ attack_catapult(const troop * at, const struct weapon_type *wtype, troop dt; int d = 0, enemies; weapon *wp = af->person[at->index].missile; - item_type *it_catapultammo = NULL; + const resource_type *rtype = rt_find("catapultammo"); assert(wp->type == wtype); assert(af->person[at->index].reload == 0); - it_catapultammo = it_find("catapultammo"); - if (it_catapultammo != NULL) { - if (get_pooled(au, it_catapultammo->rtype, - GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, 1) <= 0) { + if (rtype) { + if (get_pooled(au, rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, 1) <= 0) { /* No ammo. Use other weapon if available. */ return true; } @@ -128,9 +126,8 @@ attack_catapult(const troop * at, const struct weapon_type *wtype, af->catmsg = 0; } - if (it_catapultammo != NULL) { - use_pooled(au, it_catapultammo->rtype, - GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, 1); + if (rtype) { + use_pooled(au, rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, 1); } while (--enemies >= 0) { diff --git a/src/kernel/alchemy.c b/src/kernel/alchemy.c index 0851f66e3..bce078899 100644 --- a/src/kernel/alchemy.c +++ b/src/kernel/alchemy.c @@ -278,19 +278,18 @@ a_writeeffect(const attrib * a, const void *owner, struct storage *store) static int a_readeffect(attrib * a, void *owner, struct storage *store) { int power; - const item_type *itype; + const resource_type *rtype; effect_data *edata = (effect_data *) a->data.v; char zText[32]; READ_TOK(store, zText, sizeof(zText)); - itype = it_find(zText); + rtype = rt_find(zText); READ_INT(store, &power); - if (itype == NULL || itype->rtype == NULL || itype->rtype->ptype == NULL - || power <= 0) { + if (rtype == NULL || rtype->ptype == NULL || power <= 0) { return AT_READ_FAIL; } - edata->type = itype->rtype->ptype; + edata->type = rtype->ptype; edata->value = power; return AT_READ_OK; } diff --git a/src/kernel/alliance.c b/src/kernel/alliance.c index 1e8143380..3fc91fefa 100644 --- a/src/kernel/alliance.c +++ b/src/kernel/alliance.c @@ -445,18 +445,18 @@ int victorycondition(const alliance * al, const char *name) const char **igem; for (igem = gems; *igem; ++igem) { - const struct item_type *itype = it_find(*igem); + const struct resource_type *rtype = rt_find(*igem); quicklist *flist = al->members; int qi; bool found = false; - assert(itype != NULL); + assert(rtype); for (qi = 0; flist && !found; ql_advance(&flist, &qi, 1)) { faction *f = (faction *) ql_get(flist, 0); unit *u; for (u = f->units; u; u = u->nextF) { - if (i_get(u->items, itype) > 0) { + if (i_get(u->items, rtype->itype) > 0) { found = true; break; } diff --git a/src/kernel/battle.c b/src/kernel/battle.c index b0bc49e39..7bf9a6162 100644 --- a/src/kernel/battle.c +++ b/src/kernel/battle.c @@ -840,8 +840,8 @@ static const armor_type *select_armor(troop t, bool shield) * - Zauber Rindenhaut gibt Rüstung +3 */ static int trollbelts(const unit *u) { - const struct item_type *belt = it_find("trollbelt"); - return belt ? i_get(u->items, belt) : 0; + const struct resource_type *belt = rt_find("trollbelt"); + return belt ? i_get(u->items, belt->itype) : 0; } int select_magicarmor(troop t) @@ -3368,15 +3368,15 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack) fig->horses = fig->unit->number; fig->elvenhorses = 0; } else { - const item_type *it_horse = 0; - const item_type *it_elvenhorse = 0; - it_elvenhorse = it_find("elvenhorse"); - it_horse = it_find("charger"); - if (!it_horse) { - it_horse = it_find("horse"); - } - fig->horses = i_get(u->items, it_horse); - fig->elvenhorses = i_get(u->items, it_elvenhorse); + const resource_type *rt_horse = 0; + const resource_type *rt_elvenhorse = 0; + rt_elvenhorse = get_resourcetype(R_UNICORN); + rt_horse = get_resourcetype(R_CHARGER); + if (!rt_horse) { + rt_horse = get_resourcetype(R_HORSE); + } + fig->horses = rt_horse ? i_get(u->items, rt_horse->itype) : 0; + fig->elvenhorses = rt_elvenhorse ? i_get(u->items, rt_elvenhorse->itype) : 0; } if (u_race(u)->battle_flags & BF_EQUIPMENT) { diff --git a/src/kernel/battle.test.c b/src/kernel/battle.test.c index 1719ff516..efe1d8623 100644 --- a/src/kernel/battle.test.c +++ b/src/kernel/battle.test.c @@ -14,42 +14,44 @@ static void test_make_fighter(CuTest * tc) { - unit *au; - region *r; - fighter *af; - battle *b; - side *as; - faction * f; + unit *au; + region *r; + fighter *af; + battle *b; + side *as; + faction * f; + const resource_type *rtype; - test_cleanup(); - test_create_world(); - r = findregion(0, 0); - f = test_create_faction(rc_find("human")); - au = test_create_unit(f, r); - enable_skill(SK_MAGIC, true); - enable_skill(SK_RIDING, true); - set_level(au, SK_MAGIC, 3); - set_level(au, SK_RIDING, 3); - au->status = ST_BEHIND; - i_change(&au->items, it_find("horse"), 1); - - b = make_battle(r); - as = make_side(b, au->faction, 0, 0, 0); - af = make_fighter(b, au, as, false); - - CuAssertIntEquals(tc, 1, b->nfighters); - CuAssertPtrEquals(tc, 0, af->building); - CuAssertPtrEquals(tc, as, af->side); - CuAssertIntEquals(tc, 0, af->run.hp); - CuAssertIntEquals(tc, ST_BEHIND, af->status); - CuAssertIntEquals(tc, 0, af->run.number); - CuAssertIntEquals(tc, au->hp, af->person[0].hp); - CuAssertIntEquals(tc, 1, af->person[0].speed); - CuAssertIntEquals(tc, au->number, af->alive); - CuAssertIntEquals(tc, 0, af->removed); - CuAssertIntEquals(tc, 3, af->magic); - CuAssertIntEquals(tc, 1, af->horses); - CuAssertIntEquals(tc, 0, af->elvenhorses); + test_cleanup(); + test_create_world(); + r = findregion(0, 0); + f = test_create_faction(rc_find("human")); + au = test_create_unit(f, r); + enable_skill(SK_MAGIC, true); + enable_skill(SK_RIDING, true); + set_level(au, SK_MAGIC, 3); + set_level(au, SK_RIDING, 3); + au->status = ST_BEHIND; + rtype = get_resourcetype(R_HORSE); + i_change(&au->items, rtype->itype, 1); + + b = make_battle(r); + as = make_side(b, au->faction, 0, 0, 0); + af = make_fighter(b, au, as, false); + + CuAssertIntEquals(tc, 1, b->nfighters); + CuAssertPtrEquals(tc, 0, af->building); + CuAssertPtrEquals(tc, as, af->side); + CuAssertIntEquals(tc, 0, af->run.hp); + CuAssertIntEquals(tc, ST_BEHIND, af->status); + CuAssertIntEquals(tc, 0, af->run.number); + CuAssertIntEquals(tc, au->hp, af->person[0].hp); + CuAssertIntEquals(tc, 1, af->person[0].speed); + CuAssertIntEquals(tc, au->number, af->alive); + CuAssertIntEquals(tc, 0, af->removed); + CuAssertIntEquals(tc, 3, af->magic); + CuAssertIntEquals(tc, 1, af->horses); + CuAssertIntEquals(tc, 0, af->elvenhorses); } static int add_two(building * b, unit * u) { diff --git a/src/kernel/config.c b/src/kernel/config.c index bb7d1e19b..b09aa3fff 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -2099,24 +2099,27 @@ bool faction_id_is_unused(int id) int weight(const unit * u) { - int w, n = 0, in_bag = 0; - - item *itm; - for (itm = u->items; itm; itm = itm->next) { - w = itm->type->weight * itm->number; - n += w; - if (!fval(itm->type, ITF_BIG)) - in_bag += w; - } - - n += u->number * u_race(u)->weight; - - w = i_get(u->items, it_find("magicbag")) * BAGCAPACITY; - if (w > in_bag) - w = in_bag; - n -= w; - - return n; + int w, n = 0, in_bag = 0; + const resource_type *rtype = get_resourcetype(R_SACK_OF_CONSERVATION); + item *itm; + + for (itm = u->items; itm; itm = itm->next) { + w = itm->type->weight * itm->number; + n += w; + if (rtype && !fval(itm->type, ITF_BIG)) { + in_bag += w; + } + } + + n += u->number * u_race(u)->weight; + + if (rtype) { + w = i_get(u->items, rtype->itype) * BAGCAPACITY; + if (w > in_bag) w = in_bag; + } + n -= w; + + return n; } void make_undead_unit(unit * u) diff --git a/src/kernel/item.c b/src/kernel/item.c index 5617b84eb..729a94679 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -148,6 +148,18 @@ const char *resourcename(const resource_type * rtype, int flags) return "none"; } +resource_type *rt_get_or_create(const char *name) { + resource_type *rtype = rt_find(name); + if (!rtype) { + rtype = (resource_type *)calloc(sizeof(resource_type), 1); + rtype->_name[0] = _strdup(name); + rtype->_name[1] = (char *)malloc(strlen(name)+3); + sprintf(rtype->_name[1], "%s_p", name); + rt_register(rtype); + } + return rtype; +} + resource_type *new_resourcetype(const char **names, const char **appearances, int flags) { @@ -187,6 +199,49 @@ void it_register(item_type * itype) } } +static const char *it_aliases[][2] = { + {"Runenschwert", "runesword"}, + {"p12", "truthpotion"}, + {"p1", "goliathwater"}, + {"p4", "ointment"}, + {"p5", "peasantblood"}, + {"p8", "nestwarmth"}, + {"diamond", "adamantium"}, + {"diamondaxe", "adamantiumaxe"}, + {"diamondplate", "adamantiumplate"}, + {"aoh", "ao_healing"}, + {NULL, NULL}, +}; + +static const char *it_alias(const char *zname) +{ + int i; + for (i = 0; it_aliases[i][0]; ++i) { + if (strcmp(it_aliases[i][0], zname) == 0) + return it_aliases[i][1]; + } + return zname; +} + +item_type *it_find(const char *zname) +{ + const char *name = it_alias(zname); + resource_type *result = rt_find(name); + return result ? result->itype : 0; +} + +item_type *it_get_or_create(resource_type *rtype) { + item_type * itype; + assert(rtype); + itype = it_find(rtype->_name[0]); + assert(!itype); + itype = (item_type *)calloc(sizeof(item_type), 1); + itype->rtype = rtype; + rtype->flags |= RTF_ITEM; + it_register(itype); + return itype; +} + item_type *new_itemtype(resource_type * rtype, int iflags, int weight, int capacity) { @@ -361,42 +416,6 @@ resource_type *rt_find(const char *name) return result; } -static const char *it_aliases[][2] = { - {"Runenschwert", "runesword"}, - {"p12", "truthpotion"}, - {"p1", "goliathwater"}, - {"p4", "ointment"}, - {"p5", "peasantblood"}, - {"p8", "nestwarmth"}, - {"diamond", "adamantium"}, - {"diamondaxe", "adamantiumaxe"}, - {"diamondplate", "adamantiumplate"}, - {"aoh", "ao_healing"}, - {NULL, NULL}, -}; - -static const char *it_alias(const char *zname) -{ - int i; - for (i = 0; it_aliases[i][0]; ++i) { - if (strcmp(it_aliases[i][0], zname) == 0) - return it_aliases[i][1]; - } - return zname; -} - -item_type *it_find(const char *zname) -{ - const char *name = it_alias(zname); - const void * matches; - item_type *result = 0; - - if (cb_find_prefix(&cb_items, name, strlen(name)+1, &matches, 1, 0)) { - cb_get_kv(matches, &result, sizeof(result)); - } - return result; -} - item **i_find(item ** i, const item_type * it) { while (*i && (*i)->type != it) diff --git a/src/kernel/item.h b/src/kernel/item.h index 7105c050c..8a1b19e45 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -226,8 +226,8 @@ extern "C" { } weapon_type; extern void rt_register(resource_type * it); - extern resource_type *rt_find(const char *name); - extern item_type *it_find(const char *name); + resource_type *rt_find(const char *name); + item_type *it_find(const char *name); extern void it_register(item_type * it); extern void wt_register(weapon_type * wt); @@ -253,8 +253,9 @@ extern "C" { extern int i_get(const item * i, const item_type * it); /* creation */ - extern resource_type *new_resourcetype(const char **names, - const char **appearances, int flags); + resource_type *rt_get_or_create(const char *name); + resource_type *new_resourcetype(const char **names, const char **appearances, int flags); + item_type *it_get_or_create(resource_type *rtype); extern item_type *new_itemtype(resource_type * rtype, int iflags, int weight, int capacity); extern luxury_type *new_luxurytype(item_type * itype, int price); diff --git a/src/kernel/item.test.c b/src/kernel/item.test.c index e33cc3015..626090eae 100644 --- a/src/kernel/item.test.c +++ b/src/kernel/item.test.c @@ -66,13 +66,13 @@ void test_resource_type(CuTest * tc) names[0] = names[1] = "herpes"; test_create_itemtype(names); - CuAssertPtrEquals(tc, itype, it_find("herp")); CuAssertPtrEquals(tc, itype->rtype, rt_find("herp")); } void test_finditemtype(CuTest * tc) { - const item_type *itype, *iresult; + const item_type *itype; + const resource_type *rtype; struct locale * lang; test_cleanup(); @@ -80,10 +80,10 @@ void test_finditemtype(CuTest * tc) lang = get_locale("de"); locale_setstring(lang, "horse", "Pferd"); - itype = it_find("horse"); - iresult = finditemtype("Pferd", lang); - CuAssertPtrNotNull(tc, iresult); - CuAssertPtrEquals(tc, (void*)itype, (void*)iresult); + rtype = get_resourcetype(R_HORSE); + itype = finditemtype("Pferd", lang); + CuAssertPtrNotNull(tc, itype); + CuAssertPtrEquals(tc, (void*)rtype->itype, (void*)itype); } void test_findresourcetype(CuTest * tc) @@ -98,7 +98,7 @@ void test_findresourcetype(CuTest * tc) locale_setstring(lang, "horse", "Pferd"); locale_setstring(lang, "peasant", "Bauer"); - rtype = rt_find("horse"); + rtype = get_resourcetype(R_HORSE); rresult = findresourcetype("Pferd", lang); CuAssertPtrNotNull(tc, rresult); CuAssertPtrEquals(tc, (void*)rtype, (void*)rresult); diff --git a/src/kernel/jsonconf.c b/src/kernel/jsonconf.c index a7fbadd06..b8db55d5b 100644 --- a/src/kernel/jsonconf.c +++ b/src/kernel/jsonconf.c @@ -139,6 +139,21 @@ void json_building(cJSON *json, building_type *bt) { } } +void json_item(cJSON *json, item_type *st) { + cJSON *child; + if (json->type!=cJSON_Object) { + log_error_n("ship %s is not a json object: %d", json->string, json->type); + return; + } + for (child=json->child;child;child=child->next) { + switch(child->type) { + case cJSON_Object: + default: + log_error_n("item %s contains unknown attribute %s", json->string, child->string); + } + } +} + void json_ship(cJSON *json, ship_type *st) { cJSON *child, *iter; if (json->type!=cJSON_Object) { @@ -267,6 +282,22 @@ void json_buildings(cJSON *json) { } } +void json_items(cJSON *json) { + cJSON *child; + if (json->type!=cJSON_Object) { + log_error_n("items is not a json object: %d", json->type); + return; + } + for (child=json->child;child;child=child->next) { + resource_type *rtype = rt_get_or_create(child->string); + item_type *itype = rtype->itype; + if (!itype) { + rtype->itype = itype = it_get_or_create(rtype); + } + json_item(child, itype); + } +} + void json_ships(cJSON *json) { cJSON *child; if (json->type!=cJSON_Object) { diff --git a/src/kernel/magic.c b/src/kernel/magic.c index 9b1682bfa..a2dcb9ea1 100644 --- a/src/kernel/magic.c +++ b/src/kernel/magic.c @@ -715,34 +715,36 @@ 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 potenz = 2.1; - double divisor = 1.2; + int sk; + double n, msp; + double potenz = 2.1; + double divisor = 1.2; + const struct resource_type *rtype; - sk = eff_skill(u, SK_MAGIC, r); - msp = u_race(u)->maxaura * (pow(sk, potenz) / divisor + 1) + get_spchange(u); - - if (i_get(u->items, it_find("aurafocus")) > 0) { - msp += use_item_aura(r, u); - } - n = get_curseeffect(u->attribs, C_AURA, 0); - if (n > 0) - msp = (msp * n) / 100; - - return _max((int)msp, 0); + sk = eff_skill(u, SK_MAGIC, r); + msp = u_race(u)->maxaura * (pow(sk, potenz) / divisor + 1) + get_spchange(u); + + rtype = rt_find("aurafocus"); + if (rtype && i_get(u->items, rtype->itype) > 0) { + msp += use_item_aura(r, u); + } + n = get_curseeffect(u->attribs, C_AURA, 0); + if (n > 0) { + msp = (msp * n) / 100; + } + return _max((int)msp, 0); } int change_maxspellpoints(unit * u, int csp) { - sc_mage *m; + sc_mage *m; - m = get_mage(u); - if (!m) - return 0; - - m->spchange += csp; - return max_spellpoints(u->region, u); + m = get_mage(u); + if (!m) { + return 0; + } + m->spchange += csp; + return max_spellpoints(u->region, u); } /* ------------------------------------------------------------- */ @@ -1009,31 +1011,31 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord) */ float -spellpower(region * r, unit * u, const spell * sp, int cast_level, - struct order *ord) +spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order *ord) { - curse *c; - float force = (float)cast_level; - int elf_power = -1; + curse *c; + float force = (float)cast_level; + int elf_power; + const struct resource_type *rtype; - if (sp == NULL) { - return 0; - } else { - /* Bonus durch Magieturm und gesegneten Steinkreis */ - struct building *b = inside_building(u); - const struct building_type *btype = b ? b->type : NULL; - if (btype && btype->flags & BTF_MAGIC) - ++force; - } + if (sp == NULL) { + return 0; + } else { + /* Bonus durch Magieturm und gesegneten Steinkreis */ + struct building *b = inside_building(u); + const struct building_type *btype = b ? b->type : NULL; + if (btype && btype->flags & BTF_MAGIC) ++force; + } - if (i_get(u->items, it_find("rop")) > 0) - ++force; - if (elf_power < 0) { elf_power = get_param_int(global.parameters, "rules.magic.elfpower", 0); - } - if (elf_power && u_race(u) == new_race[RC_ELF] && r_isforest(r)) { - ++force; - } + + if (elf_power && u_race(u) == new_race[RC_ELF] && r_isforest(r)) { + ++force; + } + rtype = rt_find("rop"); + if (rtype && i_get(u->items, rtype->itype) > 0) { + ++force; + } /* Antimagie in der Zielregion */ c = get_curse(r->attribs, ct_find("antimagiczone")); @@ -1110,67 +1112,68 @@ static int farcasting(unit * magician, region * r) * reduziert magischen Schaden */ double magic_resistance(unit * target) { - attrib *a; - curse *c; - int n; - const curse_type * ct_goodresist = 0, * ct_badresist = 0; + attrib *a; + curse *c; + int n; + const curse_type * ct_goodresist = 0, * ct_badresist = 0; + const resource_type *rtype; + double probability = u_race(target)->magres; - /* Bonus durch Rassenmagieresistenz */ - double probability = u_race(target)->magres; - assert(target->number > 0); + assert(target->number > 0); + /* Magier haben einen Resistenzbonus vom Magietalent * 5% */ + probability += effskill(target, SK_MAGIC) * 0.05; - /* Magier haben einen Resistenzbonus vom Magietalent * 5% */ - probability += effskill(target, SK_MAGIC) * 0.05; - - /* Auswirkungen von Zaubern auf der Einheit */ - c = get_curse(target->attribs, ct_find("magicresistance")); - if (c) { - probability += 0.01 * curse_geteffect(c) * get_cursedmen(target, c); - } - - /* Unicorn +10 */ - n = i_get(target->items, it_find("elvenhorse")); - if (n) - probability += n * 0.1 / target->number; - - /* Auswirkungen von Zaubern auf der Region */ - a = a_find(target->region->attribs, &at_curse); - if (a) { - ct_badresist = ct_find("badmagicresistancezone"); - ct_goodresist = ct_find("goodmagicresistancezone"); - } - while (a && a->type == &at_curse) { - curse *c = (curse *) a->data.v; - unit *mage = c->magician; - - if (mage != NULL) { - if (ct_goodresist && c->type == ct_goodresist) { - if (alliedunit(mage, target->faction, HELP_GUARD)) { - probability += curse_geteffect(c) * 0.01; - ct_goodresist = 0; /* only one effect per region */ - } - } else if (ct_badresist && c->type == ct_badresist) { - if (!alliedunit(mage, target->faction, HELP_GUARD)) { - probability -= curse_geteffect(c) * 0.01; - ct_badresist = 0; /* only one effect per region */ - } - } + /* Auswirkungen von Zaubern auf der Einheit */ + c = get_curse(target->attribs, ct_find("magicresistance")); + if (c) { + probability += 0.01 * curse_geteffect(c) * get_cursedmen(target, c); } - a = a->next; - } - /* Bonus durch Artefakte */ - /* TODO (noch gibs keine) */ - /* Bonus durch Gebäude */ - { - struct building *b = inside_building(target); - const struct building_type *btype = b ? b->type : NULL; - - /* gesegneter Steinkreis gibt 30% dazu */ - if (btype) - probability += btype->magresbonus * 0.01; - } - return probability; + /* Unicorn +10 */ + rtype = get_resourcetype(R_UNICORN); + n = i_get(target->items, rtype->itype); + if (n) { + probability += n * 0.1 / target->number; + } + + /* Auswirkungen von Zaubern auf der Region */ + a = a_find(target->region->attribs, &at_curse); + if (a) { + ct_badresist = ct_find("badmagicresistancezone"); + ct_goodresist = ct_find("goodmagicresistancezone"); + } + while (a && a->type == &at_curse) { + curse *c = (curse *) a->data.v; + unit *mage = c->magician; + + if (mage != NULL) { + if (ct_goodresist && c->type == ct_goodresist) { + if (alliedunit(mage, target->faction, HELP_GUARD)) { + probability += curse_geteffect(c) * 0.01; + ct_goodresist = 0; /* only one effect per region */ + } + } else if (ct_badresist && c->type == ct_badresist) { + if (!alliedunit(mage, target->faction, HELP_GUARD)) { + probability -= curse_geteffect(c) * 0.01; + ct_badresist = 0; /* only one effect per region */ + } + } + } + a = a->next; + } + /* Bonus durch Artefakte */ + /* TODO (noch gibs keine) */ + + /* Bonus durch Gebäude */ + { + struct building *b = inside_building(target); + const struct building_type *btype = b ? b->type : NULL; + + /* gesegneter Steinkreis gibt 30% dazu */ + if (btype) + probability += btype->magresbonus * 0.01; + } + return probability; } /* ------------------------------------------------------------- */ @@ -1329,94 +1332,87 @@ static void fumble_default(castorder * co) static void do_fumble(castorder * co) { - curse *c; - region *r = co_get_region(co); - unit *u = co->magician.u; - const spell *sp = co->sp; - int level = co->level; - int duration; - float effect; - - ADDMSG(&u->faction->msgs, msg_message("patzer", "unit region spell", - u, r, sp)); - switch (rng_int() % 10) { - case 0: - /* wenn vorhanden spezieller Patzer, ansonsten nix */ - if (sp->fumble) { - sp->fumble(co); - } - else { - fumble_default(co); + curse *c; + region *r = co_get_region(co); + unit *u = co->magician.u; + const spell *sp = co->sp; + int level = co->level; + int duration; + float effect; + + ADDMSG(&u->faction->msgs, + msg_message("patzer", "unit region spell", u, r, sp)); + switch (rng_int() % 10) { + case 0: + /* wenn vorhanden spezieller Patzer, ansonsten nix */ + if (sp->fumble) { + sp->fumble(co); + } + else { + fumble_default(co); + } + break; + + case 1: /* toad */ + { + /* one or two things will happen: the toad changes her race back, + * and may or may not get toadslime. + * The list of things to happen are attached to a timeout + * trigger and that's added to the triggerlit of the mage gone toad. + */ + trigger *trestore = trigger_changerace(u, u_race(u), u->irace); + if (chance(0.7)) { + const resource_type *rtype = rt_find("toadslime"); + if (rtype) { + t_add(&trestore, trigger_giveitem(u, rtype->itype, 1)); + } + } + duration = rng_int() % level / 2; + if (duration < 2) duration = 2; + add_trigger(&u->attribs, "timer", trigger_timeout(duration, trestore)); + u_setrace(u, new_race[RC_TOAD]); + u->irace = NULL; + ADDMSG(&r->msgs, msg_message("patzer6", "unit region spell", u, r, sp)); + break; + } + /* fall-through is intentional! */ + + case 2: + /* temporary skill loss */ + duration = _max(rng_int() % level / 2, 2); + effect = -(float)level/2; + c = create_curse(u, &u->attribs, ct_find("skillmod"), (float)level, + duration, effect, 1); + c->data.i = SK_MAGIC; + ADDMSG(&u->faction->msgs, msg_message("patzer2", "unit region", u, r)); + break; + case 3: + case 4: + /* Spruch schlägt fehl, alle Magiepunkte weg */ + set_spellpoints(u, 0); + ADDMSG(&u->faction->msgs, msg_message("patzer3", "unit region spell", + u, r, sp)); + break; + + case 5: + case 6: + /* Spruch gelingt, aber alle Magiepunkte weg */ + co->level = sp->cast(co); + set_spellpoints(u, 0); + ADDMSG(&u->faction->msgs, msg_message("patzer4", "unit region spell", + u, r, sp)); + break; + + case 7: + case 8: + case 9: + default: + /* Spruch gelingt, alle nachfolgenden Sprüche werden 2^4 so teuer */ + co->level = sp->cast(co); + ADDMSG(&u->faction->msgs, msg_message("patzer5", "unit region spell", + u, r, sp)); + countspells(u, 3); } - break; - - case 1: - /* Kröte */ - { - /* one or two things will happen: the toad changes her race back, - * and may or may not get toadslime. - * The list of things to happen are attached to a timeout - * trigger and that's added to the triggerlit of the mage gone toad. - */ - trigger *trestore = trigger_changerace(u, u_race(u), u->irace); - - if (chance(0.7)) { - const item_type *it_toadslime = it_find("toadslime"); - if (it_toadslime != NULL) { - t_add(&trestore, trigger_giveitem(u, it_toadslime, 1)); - } - } - - duration = rng_int() % level / 2; - if (duration < 2) - duration = 2; - add_trigger(&u->attribs, "timer", trigger_timeout(duration, trestore)); - u_setrace(u, new_race[RC_TOAD]); - u->irace = NULL; - ADDMSG(&r->msgs, msg_message("patzer6", "unit region spell", u, r, sp)); - break; - } - /* fall-through is intentional! */ - - case 2: - /* temporärer Stufenverlust */ - duration = _max(rng_int() % level / 2, 2); - effect = -(float)level/2; - c = - create_curse(u, &u->attribs, ct_find("skillmod"), (float)level, - duration, effect, 1); - c->data.i = SK_MAGIC; - ADDMSG(&u->faction->msgs, msg_message("patzer2", "unit region", u, r)); - break; - case 3: - case 4: - /* Spruch schlägt fehl, alle Magiepunkte weg */ - set_spellpoints(u, 0); - ADDMSG(&u->faction->msgs, msg_message("patzer3", "unit region spell", - u, r, sp)); - break; - - case 5: - case 6: - /* Spruch gelingt, aber alle Magiepunkte weg */ - co->level = sp->cast(co); - set_spellpoints(u, 0); - ADDMSG(&u->faction->msgs, msg_message("patzer4", "unit region spell", - u, r, sp)); - break; - - case 7: - case 8: - case 9: - default: - /* Spruch gelingt, alle nachfolgenden Sprüche werden 2^4 so teuer */ - co->level = sp->cast(co); - ADDMSG(&u->faction->msgs, msg_message("patzer5", "unit region spell", - u, r, sp)); - countspells(u, 3); - } - - return; } /* ------------------------------------------------------------- */ diff --git a/src/kernel/move.c b/src/kernel/move.c index 2dfebc02e..df9fc4af0 100644 --- a/src/kernel/move.c +++ b/src/kernel/move.c @@ -274,8 +274,8 @@ int walkingcapacity(const struct unit *u) int wagen_ohne_pferde, wagen_mit_pferden, wagen_mit_trollen; int vehicles = 0, vcap = 0; int animals = 0, acap = 0; - const struct item_type *ihorse = it_find("horse"); - const struct item_type *ibelt = it_find("trollbelt"); + const struct resource_type *rhorse = rt_find("horse"); + const struct resource_type *rbelt = rt_find("trollbelt"); get_transporters(u->items, &animals, &acap, &vehicles, &vcap); @@ -311,18 +311,18 @@ int walkingcapacity(const struct unit *u) n += animals * acap; n += people * personcapacity(u); /* Goliathwasser */ - if (ihorse) { + if (rhorse) { int tmp = get_effect(u, oldpotiontype[P_STRONG]); if (tmp > 0) { - int horsecap = ihorse->capacity; + int horsecap = rhorse->itype->capacity; if (tmp > people) { tmp = people; } n += tmp * (horsecap - personcapacity(u)); } } - if (ibelt) { - int tmp = i_get(u->items, ibelt); + if (rbelt) { + int tmp = i_get(u->items, rbelt->itype); n += _min(people, tmp) * (STRENGTHMULTIPLIER - 1) * personcapacity(u); } diff --git a/src/kernel/save.c b/src/kernel/save.c index 68efdc7c1..263e5eee3 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -399,23 +399,23 @@ void read_items(struct storage *store, item ** ilist) { for (;;) { char ibuf[32]; - const item_type *itype; + const resource_type *rtype; int i; READ_STR(store, ibuf, sizeof(ibuf)); if (!strcmp("end", ibuf)) { break; } - itype = it_find(ibuf); + rtype = rt_find(ibuf); READ_INT(store, &i); if (i <= 0) { - log_error("data contains an entry with %d %s\n", i, itype->rtype->_name[1]); + log_error("data contains an entry with %d %s\n", i, rtype->_name[1]); } else { - if (itype != NULL) { - i_change(ilist, itype, i); + if (rtype && rtype->itype) { + i_change(ilist, rtype->itype, i); } else { log_error("data contains unknown item type %s.\n", ibuf); } - assert(itype != NULL); + assert(rtype && rtype->itype); } } } @@ -991,33 +991,32 @@ static region *readregion(struct gamedata *data, int x, int y) assert(rpeasants(r) >= 0); assert(rmoney(r) >= 0); - if (r->land) { - int n; - for (;;) { - const struct item_type *itype; - READ_STR(data->store, token, sizeof(token)); - if (!strcmp(token, "end")) - break; - itype = it_find(token); - assert(itype->rtype->ltype); - READ_INT(data->store, &n); - r_setdemand(r, itype->rtype->ltype, n); + if (r->land) { + int n; + for (;;) { + const struct resource_type *rtype; + READ_STR(data->store, token, sizeof(token)); + if (!strcmp(token, "end")) + break; + rtype = rt_find(token); + assert(rtype && rtype->ltype); + READ_INT(data->store, &n); + r_setdemand(r, rtype->ltype, n); + } + if (data->version >= REGIONITEMS_VERSION) { + read_items(data->store, &r->land->items); + } + if (data->version >= REGIONOWNER_VERSION) { + READ_INT(data->store, &n); + r->land->morale = (short)n; + if (r->land->morale < 0) { + r->land->morale = 0; + } + read_owner(data, &r->land->ownership); + } } - if (data->version >= REGIONITEMS_VERSION) { - read_items(data->store, &r->land->items); - } - if (data->version >= REGIONOWNER_VERSION) { - READ_INT(data->store, &n); - r->land->morale = (short)n; - if (r->land->morale < 0) { - r->land->morale = 0; - } - read_owner(data, &r->land->ownership); - } - } - a_read(data->store, &r->attribs, r); - - return r; + a_read(data->store, &r->attribs, r); + return r; } void writeregion(struct gamedata *data, const region * r) diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 7b11c7175..f2d9cc86d 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -221,6 +221,7 @@ static buddy *get_friends(const unit * u, int *numfriends) int gift_items(unit * u, int flags) { const struct resource_type *rsilver = get_resourcetype(R_SILVER); + const struct resource_type *rhorse = get_resourcetype(R_HORSE); region *r = u->region; item **itm_p = &u->items; int retval = 0; @@ -308,7 +309,7 @@ int gift_items(unit * u, int flags) rsetmoney(r, rmoney(r) + itm->number); itm->number = 0; } - else if (itm->type == it_find("horse")) { + else if (itm->type->rtype == rhorse) { rsethorses(r, rhorses(r) + itm->number); itm->number = 0; } @@ -1210,16 +1211,22 @@ bool has_skill(const unit * u, skill_t sk) return false; } +static int item_invis(const unit *u) { + const struct resource_type *rring = get_resourcetype(R_RING_OF_INVISIBILITY); + const struct resource_type *rsphere = get_resourcetype(R_SPHERE_OF_INVISIBILITY); + return i_get(u->items, rring->itype) + + i_get(u->items, rsphere->itype) * 100; +} + static int item_modification(const unit * u, skill_t sk, int val) { - if (sk == SK_STEALTH) { + if (sk == SK_STEALTH) { #if NEWATSROI == 1 - if (i_get(u->items, it_find("roi")) - + 100 * i_get(u->items, it_find("sphereofinv")) >= u->number) { - val += ROIBONUS; - } + 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); @@ -1355,22 +1362,21 @@ int eff_skill_study(const unit * u, skill_t sk, const region * r) int invisible(const unit * target, const unit * viewer) { #if NEWATSROI == 1 - return 0; -#else - if (viewer && viewer->faction == target->faction) return 0; - else { - int hidden = - i_get(target->items, it_find("roi")) + 100 * i_get(target->items, - it_find("sphereofinv")); - if (hidden) { - hidden = _min(hidden, target->number); - if (viewer) { - hidden -= i_get(viewer->items, it_find("aots")); - } +#else + if (viewer && viewer->faction == target->faction) + return 0; + else { + int hidden = item_invis(target); + if (hidden) { + hidden = _min(hidden, target->number); + if (viewer) { + const resource_type *rtype = get_resourcetype(R_AMULET_OF_TRUE_SEEING); + hidden -= i_get(viewer->items, rtype->itype); + } + } + return hidden; } - return hidden; - } #endif } diff --git a/src/laws.c b/src/laws.c index 9d2bf7398..1cdfc28d4 100755 --- a/src/laws.c +++ b/src/laws.c @@ -293,9 +293,9 @@ void get_food(region * r) /* use peasantblood before eating the peasants themselves */ const struct potion_type *pt_blood = 0; - const item_type *it_blood = it_find("peasantblood"); - if (it_blood) { - pt_blood = it_blood->rtype->ptype; + const resource_type *rt_blood = rt_find("peasantblood"); + if (rt_blood) { + pt_blood = rt_blood->ptype; } if (pt_blood) { /* always start with the unit itself, then the first known unit that may have some blood */ @@ -3257,7 +3257,7 @@ static building *age_building(building * b) { const struct building_type *bt_blessed; const struct curse_type *ct_astralblock; - const struct item_type *itype = it_find("elvenhorse"); + const struct resource_type *rtype = get_resourcetype(R_UNICORN); bt_blessed = bt_find("blessedstonecircle"); ct_astralblock = ct_find("astralblock"); @@ -3269,7 +3269,7 @@ static building *age_building(building * b) * * TODO: this would be nicer in a btype->age function, but we don't have it. */ - if (itype && ct_astralblock && bt_blessed && b->type == bt_blessed) { + if (rtype && ct_astralblock && bt_blessed && b->type == bt_blessed) { region *r = b->region; region *rt = r_standard_to_astral(r); unit *u, *mage = NULL; @@ -3282,13 +3282,13 @@ static building *age_building(building * b) int n, unicorns = 0; for (n = 0; n != u->number; ++n) { if (chance(0.02)) { - i_change(&u->items, itype, 1); + i_change(&u->items, rtype->itype, 1); ++unicorns; } if (unicorns) { ADDMSG(&u->faction->msgs, msg_message("scunicorn", "unit amount rtype", - u, unicorns, itype->rtype)); + u, unicorns, rtype)); } } } @@ -4332,8 +4332,8 @@ int siege_cmd(unit * u, order * ord) int d, pooled; int bewaffnete, katapultiere = 0; const curse_type *magicwalls_ct; - item_type *it_catapultammo = NULL; - item_type *it_catapult = NULL; + resource_type *rt_catapultammo = NULL; + resource_type *rt_catapult = NULL; init_tokens(ord); skip_token(); @@ -4352,12 +4352,12 @@ int siege_cmd(unit * u, order * ord) /* schaden durch katapulte */ magicwalls_ct = ct_find("magicwalls"); - it_catapultammo = it_find("catapultammo"); - it_catapult = it_find("catapult"); + rt_catapultammo = rt_find("catapultammo"); + rt_catapult = rt_find("catapult"); - d = i_get(u->items, it_catapult); + d = i_get(u->items, rt_catapult->itype); d = _min(u->number, d); - pooled = get_pooled(u, it_catapultammo->rtype, GET_DEFAULT, d); + pooled = get_pooled(u, rt_catapultammo, GET_DEFAULT, d); d = _min(pooled, d); if (eff_skill(u, SK_CATAPULT, r) >= 1) { katapultiere = d; @@ -4393,7 +4393,7 @@ int siege_cmd(unit * u, order * ord) /* meldung, schaden anrichten */ if (d && !curse_active(get_curse(b->attribs, magicwalls_ct))) { b->size -= d; - use_pooled(u, it_catapultammo->rtype, + use_pooled(u, rt_catapultammo, GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, d); /* send message to the entire region */ ADDMSG(&r->msgs, msg_message("siege_catapults", diff --git a/src/laws.test.c b/src/laws.test.c index 0fc15d500..39065aac2 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -84,36 +84,37 @@ static void test_rename_building_twice(CuTest * tc) static void test_fishing_feeds_2_people(CuTest * tc) { - region *r; - faction *f; - unit *u; - ship *sh; + const resource_type *rtype; + region *r; + faction *f; + unit *u; + ship *sh; + + test_cleanup(); + test_create_world(); + r = findregion(-1, 0); + CuAssertStrEquals(tc, "ocean", r->terrain->_name); /* test_create_world needs coverage */ + f = test_create_faction(rc_find("human")); + u = test_create_unit(f, r); + sh = new_ship(st_find("boat"), r, 0); + u_set_ship(u, sh); + rtype = get_resourcetype(R_SILVER); + i_change(&u->items, rtype->itype, 42); + + scale_number(u, 1); + sh->flags |= SF_FISHING; + get_food(r); + CuAssertIntEquals(tc, 42, i_get(u->items, rtype->itype)); - test_cleanup(); - test_create_world(); - r = findregion(-1, 0); - CuAssertStrEquals(tc, "ocean", r->terrain->_name); /* test_create_world needs coverage */ - f = test_create_faction(rc_find("human")); - u = test_create_unit(f, r); - sh = new_ship(st_find("boat"), r, 0); - u_set_ship(u, sh); - i_change(&u->items, it_find("money"), 42); - - scale_number(u, 1); - sh->flags |= SF_FISHING; - get_food(r); - CuAssertIntEquals(tc, 42, i_get(u->items, it_find("money"))); - - scale_number(u, 2); - sh->flags |= SF_FISHING; - get_food(r); - CuAssertIntEquals(tc, 42, i_get(u->items, it_find("money"))); - - scale_number(u, 3); - sh->flags |= SF_FISHING; - get_food(r); - CuAssertIntEquals(tc, 32, i_get(u->items, it_find("money"))); + scale_number(u, 2); + sh->flags |= SF_FISHING; + get_food(r); + CuAssertIntEquals(tc, 42, i_get(u->items, rtype->itype)); + scale_number(u, 3); + sh->flags |= SF_FISHING; + get_food(r); + CuAssertIntEquals(tc, 32, i_get(u->items, rtype->itype)); } static int not_so_hungry(const unit * u) @@ -123,56 +124,58 @@ static int not_so_hungry(const unit * u) static void test_fishing_does_not_give_goblins_money(CuTest * tc) { - region *r; - faction *f; - unit *u; - ship *sh; - - test_cleanup(); - test_create_world(); - - r = findregion(-1, 0); - CuAssertStrEquals(tc, "ocean", r->terrain->_name); /* test_create_world needs coverage */ - f = test_create_faction(rc_find("human")); - u = test_create_unit(f, r); - sh = new_ship(st_find("boat"), r, 0); - u_set_ship(u, sh); - i_change(&u->items, it_find("money"), 42); - - global.functions.maintenance = not_so_hungry; - scale_number(u, 2); - sh->flags |= SF_FISHING; - get_food(r); - CuAssertIntEquals(tc, 42, i_get(u->items, it_find("money"))); + const resource_type *rtype; + region *r; + faction *f; + unit *u; + ship *sh; + + test_cleanup(); + test_create_world(); + rtype = get_resourcetype(R_SILVER); + + r = findregion(-1, 0); + CuAssertStrEquals(tc, "ocean", r->terrain->_name); /* test_create_world needs coverage */ + f = test_create_faction(rc_find("human")); + u = test_create_unit(f, r); + sh = new_ship(st_find("boat"), r, 0); + u_set_ship(u, sh); + i_change(&u->items, rtype->itype, 42); + global.functions.maintenance = not_so_hungry; + scale_number(u, 2); + sh->flags |= SF_FISHING; + get_food(r); + CuAssertIntEquals(tc, 42, i_get(u->items, rtype->itype)); } static void test_fishing_gets_reset(CuTest * tc) { - region *r; - faction *f; - unit *u; - ship *sh; - - test_cleanup(); - test_create_world(); - r = findregion(-1, 0); - CuAssertStrEquals(tc, "ocean", r->terrain->_name); /* test_create_world needs coverage */ - f = test_create_faction(rc_find("human")); - u = test_create_unit(f, r); - sh = new_ship(st_find("boat"), r, 0); - u_set_ship(u, sh); - i_change(&u->items, it_find("money"), 42); - - scale_number(u, 1); - sh->flags |= SF_FISHING; - get_food(r); - CuAssertIntEquals(tc, 42, i_get(u->items, it_find("money"))); - - scale_number(u, 1); - get_food(r); - CuAssertIntEquals(tc, 32, i_get(u->items, it_find("money"))); - + const resource_type *rtype; + region *r; + faction *f; + unit *u; + ship *sh; + + test_cleanup(); + test_create_world(); + rtype = get_resourcetype(R_SILVER); + r = findregion(-1, 0); + CuAssertStrEquals(tc, "ocean", r->terrain->_name); /* test_create_world needs coverage */ + f = test_create_faction(rc_find("human")); + u = test_create_unit(f, r); + sh = new_ship(st_find("boat"), r, 0); + u_set_ship(u, sh); + i_change(&u->items, rtype->itype, 42); + + scale_number(u, 1); + sh->flags |= SF_FISHING; + get_food(r); + CuAssertIntEquals(tc, 42, i_get(u->items, rtype->itype)); + + scale_number(u, 1); + get_food(r); + CuAssertIntEquals(tc, 32, i_get(u->items, rtype->itype)); } static void test_unit_limit(CuTest * tc) diff --git a/src/monster.c b/src/monster.c index 0c49f1239..b0d6d897a 100644 --- a/src/monster.c +++ b/src/monster.c @@ -82,7 +82,7 @@ static void eaten_by_monster(unit * u) static double multi = 0.0; int n = 0; int horse = -1; - + const resource_type *rhorse = get_resourcetype(R_HORSE); if (multi == 0.0) { multi = RESOURCE_QUANTITY * newterrain(T_PLAIN)->size / 10000.0; } @@ -101,7 +101,7 @@ static void eaten_by_monster(unit * u) n = rng_int() % (u->number / 20 + 1); horse = 0; } - horse = horse ? i_get(u->items, it_find("horse")) : 0; + horse = horse ? i_get(u->items, rhorse->itype) : 0; n = (int)(n * multi); if (n > 0) { @@ -115,7 +115,7 @@ static void eaten_by_monster(unit * u) } } if (horse > 0) { - i_change(&u->items, it_find("horse"), -horse); + i_change(&u->items, rhorse->itype, -horse); ADDMSG(&u->region->msgs, msg_message("eathorse", "unit amount", u, horse)); } } diff --git a/src/races/races.c b/src/races/races.c index 95a6cc5b9..441f0f974 100644 --- a/src/races/races.c +++ b/src/races/races.c @@ -50,42 +50,45 @@ static void oldfamiliars(unit * u) static void equip_newunits(const struct equipment *eq, struct unit *u) { - struct region *r = u->region; - - switch (old_race(u_race(u))) { - case RC_ELF: - set_show_item(u->faction, it_find("fairyboot")); - break; - case RC_GOBLIN: - set_show_item(u->faction, it_find("roi")); - set_number(u, 10); - break; - case RC_HUMAN: - if (u->building == NULL) { - const building_type *btype = bt_find("castle"); - if (btype != NULL) { - building *b = new_building(btype, r, u->faction->locale); - b->size = 10; - u_set_building(u, b); - building_set_owner(u); - } - } - break; - case RC_CAT: - set_show_item(u->faction, it_find("roi")); - break; - case RC_AQUARIAN: - { - ship *sh = new_ship(st_find("boat"), r, u->faction->locale); - sh->size = sh->type->construction->maxsize; - u_set_ship(u, sh); - } - break; - case RC_CENTAUR: - rsethorses(r, 250 + rng_int() % 51 + rng_int() % 51); - break; - default: + struct region *r = u->region; + const struct resource_type *rtype; + switch (old_race(u_race(u))) { + case RC_ELF: + rtype = rt_find("fairyboot"); + set_show_item(u->faction, rtype->itype); + break; + case RC_GOBLIN: + rtype = rt_find("roi"); + set_show_item(u->faction, rtype->itype); + set_number(u, 10); break; + case RC_HUMAN: + if (u->building == NULL) { + const building_type *btype = bt_find("castle"); + if (btype != NULL) { + building *b = new_building(btype, r, u->faction->locale); + b->size = 10; + u_set_building(u, b); + building_set_owner(u); + } + } + break; + case RC_CAT: + rtype = rt_find("roi"); + set_show_item(u->faction, rtype->itype); + break; + case RC_AQUARIAN: + { + ship *sh = new_ship(st_find("boat"), r, u->faction->locale); + sh->size = sh->type->construction->maxsize; + u_set_ship(u, sh); + } + break; + case RC_CENTAUR: + rsethorses(r, 250 + rng_int() % 51 + rng_int() % 51); + break; + default: + break; } } diff --git a/src/tests.test.c b/src/tests.test.c index 186f190ec..e0fb05990 100644 --- a/src/tests.test.c +++ b/src/tests.test.c @@ -31,19 +31,19 @@ static void test_recreate_world(CuTest * tc) { test_cleanup(); CuAssertPtrEquals(tc, 0, get_locale("de")); - CuAssertPtrEquals(tc, 0, it_find("horse")); + CuAssertPtrEquals(tc, 0, (void *)rt_find("horse")); CuAssertPtrNotNull(tc, get_resourcetype(R_LIFE)); CuAssertPtrNotNull(tc, get_resourcetype(R_PERMAURA)); CuAssertPtrNotNull(tc, get_resourcetype(R_AURA)); - CuAssertPtrNotNull(tc, it_find("money")); + CuAssertPtrNotNull(tc, (void *)rt_find("money")); test_create_world(); CuAssertPtrEquals(tc, default_locale, get_locale("de")); CuAssertPtrNotNull(tc, default_locale); CuAssertPtrNotNull(tc, findregion(0, 0)); - CuAssertPtrNotNull(tc, it_find("horse")); + CuAssertPtrNotNull(tc, (void *)rt_find("horse")); CuAssertPtrNotNull(tc, get_resourcetype(R_HORSE)); - CuAssertPtrNotNull(tc, it_find("money")); + CuAssertPtrNotNull(tc, (void *)rt_find("money")); CuAssertPtrNotNull(tc, get_resourcetype(R_LIFE)); CuAssertPtrNotNull(tc, get_resourcetype(R_SILVER)); CuAssertPtrNotNull(tc, get_resourcetype(R_AURA)); @@ -53,9 +53,9 @@ static void test_recreate_world(CuTest * tc) test_cleanup(); CuAssertPtrEquals(tc, 0, get_locale("de")); - CuAssertPtrEquals(tc, 0, (void*)it_find("horse")); + CuAssertPtrEquals(tc, 0, (void*)rt_find("horse")); CuAssertPtrEquals(tc, 0, (void*)get_resourcetype(R_HORSE)); - CuAssertPtrNotNull(tc, it_find("money")); + CuAssertPtrNotNull(tc, (void *)rt_find("money")); CuAssertPtrNotNull(tc, get_resourcetype(R_LIFE)); CuAssertPtrNotNull(tc, get_resourcetype(R_SILVER)); CuAssertPtrNotNull(tc, get_resourcetype(R_AURA));