eliminate it_find calls, replace it_find with something backed by rt_find

This commit is contained in:
Enno Rehling 2014-06-24 22:44:05 -07:00
parent 9d24c3c291
commit 92f43a7b51
20 changed files with 566 additions and 507 deletions

View File

@ -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) */
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);
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);
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);
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) {

View File

@ -2099,24 +2099,27 @@ bool faction_id_is_unused(int id)
int weight(const unit * u)
{
int w, n = 0, in_bag = 0;
int w, n = 0, in_bag = 0;
const resource_type *rtype = get_resourcetype(R_SACK_OF_CONSERVATION);
item *itm;
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;
}
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;
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;
if (rtype) {
w = i_get(u->items, rtype->itype) * BAGCAPACITY;
if (w > in_bag) w = in_bag;
}
n -= w;
return n;
return n;
}
void make_undead_unit(unit * u)

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -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);
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);
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;
/* Unicorn +10 */
rtype = get_resourcetype(R_UNICORN);
n = i_get(target->items, rtype->itype);
if (n) {
probability += n * 0.1 / target->number;
}
/* gesegneter Steinkreis gibt 30% dazu */
if (btype)
probability += btype->magresbonus * 0.01;
}
return probability;
/* 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;
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);
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);
}
else {
fumble_default(co);
}
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;
}
/* ------------------------------------------------------------- */

View File

@ -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);
}

View File

@ -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)

View File

@ -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
}

View File

@ -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",

View File

@ -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);
i_change(&u->items, it_find("money"), 42);
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, it_find("money")));
scale_number(u, 1);
sh->flags |= SF_FISHING;
get_food(r);
CuAssertIntEquals(tc, 42, i_get(u->items, rtype->itype));
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;
const resource_type *rtype;
region *r;
faction *f;
unit *u;
ship *sh;
test_cleanup();
test_create_world();
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, 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")));
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;
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);
i_change(&u->items, it_find("money"), 42);
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, it_find("money")));
scale_number(u, 1);
get_food(r);
CuAssertIntEquals(tc, 32, i_get(u->items, it_find("money")));
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)

View File

@ -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));
}
}

View File

@ -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;
}
}

View File

@ -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));