diff --git a/src/battle.c b/src/battle.c index 1bbaaadfe..fb411d778 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1886,7 +1886,13 @@ int skilldiff(troop at, troop dt, int dist) unit *au = af->unit, *du = df->unit; int is_protected = 0, skdiff = 0; weapon *awp = select_weapon(at, true, dist > 1); + static int rc_cache; + static const race *rc_halfling, *rc_goblin; + if (rc_changed(&rc_cache)) { + rc_halfling = get_race(RC_HALFLING); + rc_goblin = get_race(RC_GOBLIN); + } skdiff += af->person[at.index].attack; skdiff -= df->person[dt.index].defence; @@ -1894,11 +1900,10 @@ int skilldiff(troop at, troop dt, int dist) skdiff += 2; /* Effekte durch Rassen */ - if (awp != NULL && u_race(au) == get_race(RC_HALFLING) && dragonrace(u_race(du))) { + if (awp != NULL && u_race(au) == rc_halfling && dragonrace(u_race(du))) { skdiff += 5; } - - if (u_race(au) == get_race(RC_GOBLIN)) { + else if (u_race(au) == rc_goblin) { if (af->side->size[SUM_ROW] >= df->side->size[SUM_ROW] * rule_goblin_bonus) { skdiff += 1; } diff --git a/src/laws.c b/src/laws.c index f854ed7ef..e243378dd 100755 --- a/src/laws.c +++ b/src/laws.c @@ -125,7 +125,13 @@ static bool RemoveNMRNewbie(void) static void age_unit(region * r, unit * u) { - if (u_race(u) == get_race(RC_SPELL)) { + static int rc_cache; + static const race *rc_spell; + + if (rc_changed(&rc_cache)) { + rc_spell = get_race(RC_SPELL); + } + if (u_race(u) == rc_spell) { if (--u->age <= 0) { remove_unit(&r->units, u); } diff --git a/src/magic.c b/src/magic.c index bcf3403aa..0a2c685d4 100644 --- a/src/magic.c +++ b/src/magic.c @@ -1031,9 +1031,8 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord) double spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order *ord) { - curse *c; double force = cast_level; - int elf_power; + static int elf_power, config; const struct resource_type *rtype; if (sp == NULL) { @@ -1046,54 +1045,65 @@ spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order if (btype && btype->flags & BTF_MAGIC) ++force; } - elf_power = config_get_int("rules.magic.elfpower", 0); - - if (elf_power && u_race(u) == get_race(RC_ELF) && r_isforest(r)) { - ++force; + if (config_changed(&config)) { + elf_power = config_get_int("rules.magic.elfpower", 0); + } + if (elf_power) { + static int rc_cache; + static const race *rc_elf; + if (rc_changed(&rc_cache)) { + rc_elf = get_race(RC_ELF); + } + if (u_race(u) == rc_elf && r_isforest(r)) { + ++force; + } } rtype = rt_find("rop"); if (rtype && i_get(u->items, rtype->itype) > 0) { ++force; } - /* Antimagie in der Zielregion */ - c = get_curse(r->attribs, ct_find("antimagiczone")); - if (curse_active(c)) { - unit *mage = c->magician; - force -= curse_geteffect(c); - curse_changevigour(&r->attribs, c, -cast_level); - cmistake(u, ord, 185, MSG_MAGIC); - if (mage != NULL && mage->faction != NULL) { - if (force > 0) { - ADDMSG(&mage->faction->msgs, msg_message("reduce_spell", - "self mage region", mage, u, r)); + if (r->attribs) { + curse *c; + + /* Antimagie in der Zielregion */ + c = get_curse(r->attribs, ct_find("antimagiczone")); + if (curse_active(c)) { + unit *mage = c->magician; + force -= curse_geteffect(c); + curse_changevigour(&r->attribs, c, -cast_level); + cmistake(u, ord, 185, MSG_MAGIC); + if (mage != NULL && mage->faction != NULL) { + if (force > 0) { + ADDMSG(&mage->faction->msgs, msg_message("reduce_spell", + "self mage region", mage, u, r)); + } + else { + ADDMSG(&mage->faction->msgs, msg_message("block_spell", + "self mage region", mage, u, r)); + } } - else { - ADDMSG(&mage->faction->msgs, msg_message("block_spell", - "self mage region", mage, u, r)); + } + + /* Patzerfluch-Effekt: */ + c = get_curse(r->attribs, ct_find("fumble")); + if (curse_active(c)) { + unit *mage = c->magician; + force -= curse_geteffect(c); + curse_changevigour(&u->attribs, c, -1); + cmistake(u, ord, 185, MSG_MAGIC); + if (mage != NULL && mage->faction != NULL) { + if (force > 0) { + ADDMSG(&mage->faction->msgs, msg_message("reduce_spell", + "self mage region", mage, u, r)); + } + else { + ADDMSG(&mage->faction->msgs, msg_message("block_spell", + "self mage region", mage, u, r)); + } } } } - - /* Patzerfluch-Effekt: */ - c = get_curse(r->attribs, ct_find("fumble")); - if (curse_active(c)) { - unit *mage = c->magician; - force -= curse_geteffect(c); - curse_changevigour(&u->attribs, c, -1); - cmistake(u, ord, 185, MSG_MAGIC); - if (mage != NULL && mage->faction != NULL) { - if (force > 0) { - ADDMSG(&mage->faction->msgs, msg_message("reduce_spell", - "self mage region", mage, u, r)); - } - else { - ADDMSG(&mage->faction->msgs, msg_message("block_spell", - "self mage region", mage, u, r)); - } - } - } - return _max(force, 0); } @@ -2784,6 +2794,8 @@ void magic(void) int rank; castorder *co; spellrank spellranks[MAX_SPELLRANK]; + const race *rc_spell = get_race(RC_SPELL); + const race *rc_insect = get_race(RC_INSECT); memset(spellranks, 0, sizeof(spellranks)); @@ -2792,10 +2804,10 @@ void magic(void) for (u = r->units; u; u = u->next) { order *ord; - if (u->number <= 0 || u_race(u) == get_race(RC_SPELL)) + if (u->number <= 0 || u_race(u) == rc_spell) continue; - if (u_race(u) == get_race(RC_INSECT) && r_insectstalled(r) && + if (u_race(u) == rc_insect && r_insectstalled(r) && !is_cursed(u->attribs, C_KAELTESCHUTZ, 0)) continue; diff --git a/src/monsters.c b/src/monsters.c index 2678c284e..258175b43 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -269,21 +269,27 @@ static direction_t richest_neighbour(region * r, faction * f, int absolut) static bool room_for_race_in_region(region * r, const race * rc) { - unit *u; - int c = 0; + if (rc->splitsize > 0) { + unit *u; + int c = 0; - for (u = r->units; u; u = u->next) { - if (u_race(u) == rc) - c += u->number; + for (u = r->units; u; u = u->next) { + if (u_race(u) == rc) { + c += u->number; + if (c > rc->splitsize * 2) { + return false; + } + } + } } - - return (c <= (rc->splitsize * 2)); + return true; } static direction_t random_neighbour(region * r, unit * u) { int i; - region * next[MAXDIRECTIONS]; + region *next[MAXDIRECTIONS], *backup[MAXDIRECTIONS]; + region **pick; int rr, c = 0, c2 = 0; const race *rc = u_race(u); @@ -298,19 +304,22 @@ static direction_t random_neighbour(region * r, unit * u) } else { next[i] = NULL; } + backup[i] = rn; c2++; } else { next[i] = NULL; + backup[i] = NULL; } } + pick = next; if (c == 0) { if (c2 == 0) { return NODIRECTION; } else { + pick = backup; c = c2; - c2 = 0; /* c2 == 0 -> room_for_race nicht beachten */ } } @@ -320,14 +329,14 @@ static direction_t random_neighbour(region * r, unit * u) /* Durchzählen */ - c = -1; + c = 0; for (i = 0; i != MAXDIRECTIONS; i++) { - region *rn = next[i]; + region *rn = pick[i]; if (rn) { - c++; if (c == rr) { return (direction_t)i; } + c++; } } @@ -543,19 +552,21 @@ static order *monster_learn(unit * u) return NULL; } -static bool check_overpopulated(unit * u) +static bool check_overpopulated(const unit * u) { - unit *u2; - int c = 0; + const race *rc = u_race(u); + if (rc->splitsize > 0) { + unit *u2; + int c = 0; - for (u2 = u->region->units; u2; u2 = u2->next) { - if (u_race(u2) == u_race(u) && u != u2) - c += u2->number; + for (u2 = u->region->units; u2; u2 = u2->next) { + if (u != u2 && u_race(u2) == rc) { + c += u2->number; + if (c > rc->splitsize * 2) + return true; + } + } } - - if (c > u_race(u)->splitsize * 2) - return true; - return false; } diff --git a/src/randenc.c b/src/randenc.c index 85c3dd8d3..0fe76e883 100644 --- a/src/randenc.c +++ b/src/randenc.c @@ -731,11 +731,16 @@ static void orc_growth(void) static void demon_skillchanges(void) { region *r; + static const race *rc_demon; + static int rc_cache; + if (rc_changed(&rc_cache)) { + rc_demon = get_race(RC_DAEMON); + } for (r = regions; r; r = r->next) { unit *u; for (u = r->units; u; u = u->next) { - if (u_race(u) == get_race(RC_DAEMON)) { + if (u_race(u) == rc_demon) { demon_skillchange(u); } } diff --git a/src/study.c b/src/study.c index 027f67dde..1ddaf8dfe 100644 --- a/src/study.c +++ b/src/study.c @@ -546,6 +546,12 @@ int study_cmd(unit * u, order * ord) int maxalchemy = 0; int speed_rule = (study_rule_t)config_get_int("study.speedup", 0); bool learn_newskills = config_get_int("study.newskills", 1) != 0; + static const race *rc_snotling; + static int rc_cache; + + if (rc_changed(&rc_cache)) { + rc_snotling = get_race(RC_SNOTLING); + } if (!unit_can_study(u)) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_race_nolearn", "race", @@ -575,7 +581,7 @@ int study_cmd(unit * u, order * ord) } /* snotlings koennen Talente nur bis T8 lernen */ - if (u_race(u) == get_race(RC_SNOTLING)) { + if (u_race(u) == rc_snotling) { if (get_level(u, sk) >= 8) { cmistake(u, ord, 308, MSG_EVENT); return 0;