diff --git a/src/battle.c b/src/battle.c index 1c698d320..be513f288 100644 --- a/src/battle.c +++ b/src/battle.c @@ -28,6 +28,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "skill.h" #include "study.h" +#include +#include +#include + #include #include #include @@ -55,7 +59,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include -#include /* util includes */ #include @@ -139,15 +142,10 @@ static int rule_nat_armor; static int rule_cavalry_mode; static int rule_vampire; -static const curse_type *peace_ct, *slave_ct, *calm_ct; - /** initialize rules from configuration. */ static void init_rules(void) { - peace_ct = ct_find("peacezone"); - slave_ct = ct_find("slavery"); - calm_ct = ct_find("calmmonster"); rule_nat_armor = config_get_int("rules.combat.nat_armor", 0); rule_tactics_formula = config_get_int("rules.tactics.formula", 0); rule_goblin_bonus = config_get_int("rules.combat.goblinbonus", 10); @@ -1904,14 +1902,11 @@ int skilldiff(troop at, troop dt, int dist) if (df->building) { building *b = df->building; if (b->attribs) { - const curse_type *strongwall_ct = ct_find("strongwall"); - if (strongwall_ct) { - curse *c = get_curse(b->attribs, strongwall_ct); - if (curse_active(c)) { - /* wirkt auf alle Geb�ude */ - skdiff -= curse_geteffect_int(c); - is_protected = 2; - } + curse *c = get_curse(b->attribs, &ct_strongwall); + if (curse_active(c)) { + /* wirkt auf alle Geb�ude */ + skdiff -= curse_geteffect_int(c); + is_protected = 2; } } if (b->type->flags & BTF_FORTIFICATION) { @@ -3188,14 +3183,10 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack) /* Effekte von Spr�chen */ if (u->attribs) { - const curse_type *speed_ct; - speed_ct = ct_find("speed"); - if (speed_ct) { - curse *c = get_curse(u->attribs, speed_ct); - if (c) { - speeded = get_cursedmen(u, c); - speed = curse_geteffect_int(c); - } + curse *c = get_curse(u->attribs, &ct_speed); + if (c) { + speeded = get_cursedmen(u, c); + speed = curse_geteffect_int(c); } } @@ -3763,6 +3754,21 @@ static void flee(const troop dt) kill_troop(dt); } +static bool is_calmed(const unit *u, const faction *f) { + attrib *a = a_find(u->attribs, &at_curse); + + while (a && a->type == &at_curse) { + curse *c = (curse *)a->data.v; + if (c->type == &ct_calmmonster && curse_geteffect_int(c) == f->subscription) { + if (curse_active(c)) { + return true; + } + } + a = a->next; + } + return false; +} + static bool start_battle(region * r, battle ** bp) { battle *b = NULL; @@ -3809,12 +3815,12 @@ static bool start_battle(region * r, battle ** bp) if (fval(u, UFL_LONGACTION)) continue; - if (peace_ct && curse_active(get_curse(r->attribs, peace_ct))) { + if (curse_active(get_curse(r->attribs, &ct_peacezone))) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "peace_active", "")); continue; } - if (slave_ct && curse_active(get_curse(u->attribs, slave_ct))) { + if (curse_active(get_curse(u->attribs, &ct_slavery))) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "slave_active", "")); continue; } @@ -3862,26 +3868,11 @@ static bool start_battle(region * r, battle ** bp) NewbieImmunity())); continue; } - /* Fehler: "Die Einheit ist mit uns alliert" */ - if (calm_ct) { - attrib *a = a_find(u->attribs, &at_curse); - bool calm = false; - while (a && a->type == &at_curse) { - curse *c = (curse *)a->data.v; - if (c->type == calm_ct - && curse_geteffect_int(c) == u2->faction->subscription) { - if (curse_active(c)) { - calm = true; - break; - } - } - a = a->next; - } - if (calm) { - cmistake(u, ord, 47, MSG_BATTLE); - continue; - } + /* Fehler: "Die Einheit ist mit uns alliert" */ + if (is_calmed(u, u2->faction)) { + cmistake(u, ord, 47, MSG_BATTLE); + continue; } /* Ende Fehlerbehandlung */ if (b == NULL) { diff --git a/src/battle.test.c b/src/battle.test.c index 466d890bd..3669f25d1 100644 --- a/src/battle.test.c +++ b/src/battle.test.c @@ -471,11 +471,9 @@ static void test_battle_skilldiff_building(CuTest *tc) unit *ua, *ud; battle *b = NULL; building_type *btype; - const curse_type *strongwall_ct; test_setup(); btype = setup_castle(); - strongwall_ct = ct_find("strongwall"); r = test_create_region(0, 0, 0); ud = test_create_unit(test_create_faction(0), r); @@ -494,7 +492,7 @@ static void test_battle_skilldiff_building(CuTest *tc) create_curse(NULL, &ud->building->attribs, &ct_magicwalls, 1, 1, 1, 1); CuAssertIntEquals(tc, -2, skilldiff(ta, td, 0)); - create_curse(NULL, &ud->building->attribs, strongwall_ct, 1, 1, 2, 1); + create_curse(NULL, &ud->building->attribs, &ct_strongwall, 1, 1, 2, 1); CuAssertIntEquals(tc, -4, skilldiff(ta, td, 0)); free_battle(b); diff --git a/src/bind_monsters.c b/src/bind_monsters.c index 4ac15aa24..082d940ae 100644 --- a/src/bind_monsters.c +++ b/src/bind_monsters.c @@ -2,6 +2,8 @@ #include "spells/shipcurse.h" #include "monsters.h" +#include + #include #include #include @@ -9,8 +11,6 @@ #include #include -#include - #include #include diff --git a/src/creport.c b/src/creport.c index 00d55b6ce..57ba12ee0 100644 --- a/src/creport.c +++ b/src/creport.c @@ -20,6 +20,8 @@ without prior permission by the authors of Eressea. #define BUFFERSIZE 32768 #define RESOURCECOMPAT +#include + /* modules include */ #include @@ -1361,7 +1363,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r) if (skill_enabled(SK_ENTERTAINMENT)) { fprintf(F, "%d;Unterh\n", entertainmoney(r)); } - if (is_cursed(r->attribs, C_RIOT, 0)) { + if (is_cursed(r->attribs, &ct_riotzone)) { fputs("0;Rekruten\n", F); } else { @@ -1419,7 +1421,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r) cr_output_curses_compat(F, f, r, TYP_REGION); cr_borders(r, f, r->seen.mode, F); if (r->seen.mode >= seen_unit && is_astral(r) - && !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) { + && !is_cursed(r->attribs, &ct_astralblock)) { /* Sonderbehandlung Teleport-Ebene */ region_list *rl = astralregions(r, inhabitable); diff --git a/src/economy.c b/src/economy.c index 1cae19b1c..4122fa6a1 100644 --- a/src/economy.c +++ b/src/economy.c @@ -36,6 +36,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "reports.h" #include "calendar.h" +#include +#include +#include +#include +#include + /* kernel includes */ #include #include @@ -67,10 +73,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include -#include -#include - /* libs includes */ #include #include @@ -117,14 +119,14 @@ int entertainmoney(const region * r) { double n; - if (is_cursed(r->attribs, C_DEPRESSION, 0)) { + if (is_cursed(r->attribs, &ct_depression)) { return 0; } n = rmoney(r) / (double)ENTERTAINFRACTION; - if (is_cursed(r->attribs, C_GENEROUS, 0)) { - n *= get_curseeffect(r->attribs, C_GENEROUS, 0); + if (is_cursed(r->attribs, &ct_generous)) { + n *= get_curseeffect(r->attribs, &ct_generous); } return (int)n; @@ -501,7 +503,7 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders) return; } } - if (is_cursed(r->attribs, C_RIOT, 0)) { + if (is_cursed(r->attribs, &ct_riotzone)) { /* Die Region befindet sich in Aufruhr */ cmistake(u, ord, 237, MSG_EVENT); return; @@ -651,7 +653,7 @@ static int forget_cmd(unit * u, order * ord) skill_t sk; const char *s; - if (is_cursed(u->attribs, C_SLAVE, 0)) { + if (is_cursed(u->attribs, &ct_slavery)) { /* charmed units shouldn't be losing their skills */ return 0; } @@ -729,13 +731,12 @@ static int maintain(building * b) void maintain_buildings(region * r) { - const curse_type *nocost_ct = ct_find("nocostbuilding"); building **bp = &r->buildings; while (*bp) { building *b = *bp; int flags = BLD_MAINTAINED; - if (!curse_active(get_curse(b->attribs, nocost_ct))) { + if (!curse_active(get_curse(b->attribs, &ct_nocostbuilding))) { flags = maintain(b); } fset(b, flags); @@ -2589,7 +2590,7 @@ void entertain_cmd(unit * u, struct order *ord) cmistake(u, ord, 69, MSG_INCOME); return; } - if (is_cursed(r->attribs, C_DEPRESSION, 0)) { + if (is_cursed(r->attribs, &ct_depression)) { cmistake(u, ord, 28, MSG_INCOME); return; } @@ -3026,7 +3027,7 @@ void produce(struct region *r) continue; if (u_race(u) == rc_insect && r_insectstalled(r) && - !is_cursed(u->attribs, C_KAELTESCHUTZ, 0)) + !is_cursed(u->attribs, &ct_insectfur)) continue; if (fval(u, UFL_LONGACTION) && u->thisorder == NULL) { diff --git a/src/give.c b/src/give.c index d147c41f8..b55e6687b 100644 --- a/src/give.c +++ b/src/give.c @@ -17,7 +17,12 @@ #include "economy.h" #include "laws.h" -/* kernel includes */ +#include + + /* attributes includes */ +#include + + /* kernel includes */ #include #include #include @@ -33,9 +38,6 @@ #include #include -/* attributes includes */ -#include - /* util includes */ #include #include @@ -286,7 +288,7 @@ static bool can_give_men(const unit *u, const unit *dst, order *ord, message **m /* hungry people cannot be given away */ if (msg) *msg = msg_error(u, ord, 73); } - else if (fval(u, UFL_LOCKED) || is_cursed(u->attribs, C_SLAVE, 0)) { + else if (fval(u, UFL_LOCKED) || is_cursed(u->attribs, &ct_slavery)) { if (msg) *msg = msg_error(u, ord, 74); } else { @@ -329,7 +331,7 @@ message * give_men(int n, unit * u, unit * u2, struct order *ord) else if (unit_has_cursed_item(u2)) { error = 78; } - else if (fval(u2, UFL_LOCKED) || is_cursed(u2->attribs, C_SLAVE, 0)) { + else if (fval(u2, UFL_LOCKED) || is_cursed(u2->attribs, &ct_slavery)) { error = 75; } else if (!ucontact(u2, u)) { diff --git a/src/items.c b/src/items.c index e33aed1bc..dd4abe1ac 100644 --- a/src/items.c +++ b/src/items.c @@ -7,6 +7,12 @@ #include "move.h" #include "magic.h" +#include + +#include +#include +#include + #include #include #include @@ -21,9 +27,6 @@ #include #include -#include -#include - /* triggers includes */ #include #include @@ -167,7 +170,7 @@ struct order *ord) } if (force > 0) { - create_curse(u, &r->attribs, ct_find("antimagiczone"), force, duration, + create_curse(u, &r->attribs, &ct_antimagiczone, force, duration, effect, 0); } } @@ -185,7 +188,7 @@ int amount, struct order *ord) { int money; - if (get_curse(u->region->attribs, ct_find("depression"))) { + if (get_curse(u->region->attribs, &ct_depression)) { cmistake(u, ord, 58, MSG_MAGIC); return -1; } @@ -194,7 +197,7 @@ int amount, struct order *ord) change_money(u, money); rsetmoney(u->region, rmoney(u->region) - money); - create_curse(u, &u->region->attribs, ct_find("depression"), + create_curse(u, &u->region->attribs, &ct_depression, 20, BAGPIPEDURATION, 0.0, 0); ADDMSG(&u->faction->msgs, msg_message("bagpipeoffear_faction", @@ -354,7 +357,7 @@ use_tacticcrystal(unit * u, const struct item_type *itype, int amount, der vor den Antimagiezaubern passiert */ effect = (float)(rng_int() % 6 - 1); - c = create_curse(u, &u->attribs, ct_find("skillmod"), power, + c = create_curse(u, &u->attribs, &ct_skillmod, power, duration, effect, u->number); c->data.i = SK_TACTICS; UNUSED_ARG(ord); diff --git a/src/kernel/building.c b/src/kernel/building.c index 520807933..45faccdab 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -21,6 +21,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "building.h" +#include +#include + /* kernel includes */ #include "curse.h" #include "item.h" @@ -54,10 +57,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -/* attributes includes */ -#include -#include - typedef struct building_typelist { struct building_typelist *next; building_type *type; @@ -681,12 +680,7 @@ default_wage(const region * r, const faction * f, const race * rc, int in_turn) building *b = largestbuilding(r, cmp_wage, false); int esize = 0; double wage; - static int ct_cache; - static const struct curse_type *drought_ct; - if (ct_changed(&ct_cache)) { - drought_ct = ct_find("drought"); - } if (b != NULL) { /* TODO: this reveals imaginary castles */ esize = buildingeffsize(b, false); @@ -717,18 +711,18 @@ default_wage(const region * r, const faction * f, const race * rc, int in_turn) if (r->attribs) { attrib *a; - const struct curse_type *ctype; + curse *c; + /* Godcurse: Income -10 */ - ctype = ct_find("godcursezone"); - if (ctype && curse_active(get_curse(r->attribs, ctype))) { + c = get_curse(r->attribs, &ct_godcursezone); + if (c && curse_active(c)) { wage = MAX(0, wage - 10); } /* Bei einer D�rre verdient man nur noch ein Viertel */ - if (drought_ct) { - curse *c = get_curse(r->attribs, drought_ct); - if (curse_active(c)) - wage /= curse_geteffect(c); + c = get_curse(r->attribs, &ct_drought); + if (c && curse_active(c)) { + wage /= curse_geteffect(c); } a = a_find(r->attribs, &at_reduceproduction); diff --git a/src/kernel/curse.c b/src/kernel/curse.c index c79454cc8..b0367484d 100644 --- a/src/kernel/curse.c +++ b/src/kernel/curse.c @@ -141,10 +141,11 @@ static int read_ccompat(const char *cursename, struct storage *store) struct compat { const char *name; const char *tokens; - } *seek, old_curses[] = { { - "disorientationzone", "" }, { - "shipdisorientation", "" }, { - NULL, NULL } }; + } *seek, old_curses[] = { + { "disorientationzone", "" }, + { "shipdisorientation", "" }, + { NULL, NULL } + }; for (seek = old_curses; seek->name; ++seek) { if (strcmp(seek->tokens, cursename) == 0) { const char *p; @@ -232,7 +233,7 @@ int curse_read(attrib * a, void *owner, gamedata *data) if (c->type->typ == CURSETYP_REGION) { int rr = read_reference(&c->data.v, data, read_region_reference, - RESOLVE_REGION(data->version)); + RESOLVE_REGION(data->version)); if (ur == 0 && rr == 0 && !c->data.v) { return AT_READ_FAIL; } @@ -284,27 +285,15 @@ attrib_type at_curse = { #define MAXCTHASH 128 static selist *cursetypes[MAXCTHASH]; -static int ct_changes = 1; - -bool ct_changed(int *cache) -{ - assert(cache); - if (*cache != ct_changes) { - *cache = ct_changes; - return true; - } - return false; -} void ct_register(const curse_type * ct) { unsigned int hash = tolower(ct->cname[0]) & 0xFF; selist **ctlp = cursetypes + hash; - assert(ct->age==NULL || (ct->flags&CURSE_NOAGE) == 0); + assert(ct->age == NULL || (ct->flags&CURSE_NOAGE) == 0); assert((ct->flags&CURSE_ISNEW) == 0); selist_set_insert(ctlp, (void *)ct, NULL); - ++ct_changes; } void ct_remove(const char *c) @@ -320,7 +309,6 @@ void ct_remove(const char *c) if (strcmp(c, type->cname) == 0) { selist_delete(&ctl, qi); - ++ct_changes; break; } } @@ -479,7 +467,7 @@ int curse_geteffect_int(const curse * c) /* ------------------------------------------------------------- */ static void set_curseingmagician(struct unit *magician, struct attrib *ap_target, -const curse_type * ct) + const curse_type * ct) { curse *c = get_curse(ap_target, ct); if (c) { @@ -731,51 +719,6 @@ bool is_cursed_with(const attrib * ap, const curse * c) return false; } -/* ------------------------------------------------------------- */ -/* cursedata */ -/* ------------------------------------------------------------- */ - -static const char *oldnames[MAXCURSE] = { - /* OBS: when removing curses, remember to update read_ccompat() */ - "fogtrap", - "antimagiczone", - "farvision", - "gbdream", - "auraboost", - "maelstrom", - "blessedharvest", - "drought", - "badlearn", - "stormwind", - "flyingship", - "nodrift", - "depression", - "magicwalls", - "strongwall", - "astralblock", - "generous", - "peacezone", - "magicstreet", - "magicrunes", - "badmagicresistancezone", - "goodmagicresistancezone", - "slavery", - "calmmonster", - "oldrace", - "fumble", - "riotzone", - "godcursezone", - "speed", - "orcish", - "magicboost", - "insectfur" -}; - -const char *oldcursename(int id) -{ - return oldnames[id]; -} - /* ------------------------------------------------------------- */ message *cinfo_simple(const void *obj, objtype_t typ, const struct curse * c, int self) @@ -840,5 +783,4 @@ void curses_done(void) { selist_free(cursetypes[i]); cursetypes[i] = 0; } - ++ct_changes; } diff --git a/src/kernel/curse.h b/src/kernel/curse.h index 9adb2845f..9b6113d96 100644 --- a/src/kernel/curse.h +++ b/src/kernel/curse.h @@ -285,7 +285,6 @@ extern "C" { struct curse *get_curse(struct attrib *ap, const curse_type * ctype); const curse_type *ct_find(const char *c); - bool ct_changed(int *cache); void ct_register(const curse_type *); void ct_remove(const char *c); void ct_checknames(void); @@ -304,14 +303,13 @@ extern "C" { bool curse_active(const struct curse *c); /*** COMPATIBILITY MACROS. DO NOT USE FOR NEW CODE, REPLACE IN OLD CODE: */ - const char *oldcursename(int id); struct message *cinfo_simple(const void *obj, objtype_t typ, const struct curse *c, int self); int curse_cansee(const struct curse *c, const struct faction *viewer, objtype_t typ, const void *obj, int self); -#define is_cursed(a, id, id2) \ - (a && curse_active(get_curse(a, ct_find(oldcursename(id))))) -#define get_curseeffect(a, id, id2) \ - curse_geteffect(get_curse(a, ct_find(oldcursename(id)))) +#define is_cursed(a, ctype) \ + (a && curse_active(get_curse(a, ctype))) +#define get_curseeffect(a, ctype) \ + curse_geteffect(get_curse(a, ctype)) /* eressea-defined attribute-type flags */ #define ATF_CURSE ATF_USER_DEFINED diff --git a/src/kernel/curse.test.c b/src/kernel/curse.test.c index a9271f897..10c03a991 100644 --- a/src/kernel/curse.test.c +++ b/src/kernel/curse.test.c @@ -159,24 +159,6 @@ static void test_write_flag(CuTest *tc) { cleanup_curse(&fix); } -static void test_curse_cache(CuTest *tc) -{ - int cache = 0; - const curse_type ct_dummy = { "dummy", CURSETYP_NORM, 0, M_SUMEFFECT, NULL }; - test_setup(); - CuAssertIntEquals(tc, true, ct_changed(&cache)); - CuAssertIntEquals(tc, false, ct_changed(&cache)); - CuAssertPtrEquals(tc, NULL, (void *)ct_find(ct_dummy.cname)); - ct_register(&ct_dummy); - CuAssertIntEquals(tc, true, ct_changed(&cache)); - CuAssertPtrEquals(tc, (void *)&ct_dummy, (void *)ct_find(ct_dummy.cname)); - ct_remove(ct_dummy.cname); - CuAssertIntEquals(tc, true, ct_changed(&cache)); - CuAssertIntEquals(tc, false, ct_changed(&cache)); - CuAssertPtrEquals(tc, NULL, (void *)ct_find(ct_dummy.cname)); - test_cleanup(); -} - static void test_curse_ids(CuTest *tc) { const curse_type ct_dummy = { "dummy", CURSETYP_NORM, 0, M_SUMEFFECT, NULL }; curse *c1, *c2; @@ -218,7 +200,6 @@ CuSuite *get_curse_suite(void) { CuSuite *suite = CuSuiteNew(); SUITE_ADD_TEST(suite, test_curse); - SUITE_ADD_TEST(suite, test_curse_cache); SUITE_ADD_TEST(suite, test_magicstreet); SUITE_ADD_TEST(suite, test_magicstreet_warning); SUITE_ADD_TEST(suite, test_good_dreams); diff --git a/src/kernel/faction.c b/src/kernel/faction.c index 74d64962a..736c9f4e6 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -33,6 +33,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "terrain.h" #include "unit.h" +#include +#include + /* util includes */ #include #include @@ -49,8 +52,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include - #include #include @@ -729,7 +730,7 @@ int count_faction(const faction * f, int flags) } } else if (flags&COUNT_MIGRANTS) { - if (!is_cursed(u->attribs, C_SLAVE, 0)) { + if (!is_cursed(u->attribs, &ct_slavery)) { n += x; } } diff --git a/src/kernel/region.c b/src/kernel/region.c index 0eabc298c..7e6104406 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -37,6 +37,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "terrainid.h" #include "unit.h" +#include + /* util includes */ #include #include @@ -157,7 +159,7 @@ void deathcounts(region * r, int fallen) if (fallen == 0) return; if (r->attribs) { - const curse_type *ctype = ct_find("holyground"); + const curse_type *ctype = &ct_holyground; if (ctype && curse_active(get_curse(r->attribs, ctype))) return; a = a_find(r->attribs, &at_deathcount); @@ -1242,8 +1244,9 @@ int production(const region * r) { /* muß rterrain(r) sein, nicht rterrain() wegen rekursion */ int p = r->terrain->size; - if (curse_active(get_curse(r->attribs, ct_find("drought")))) + if (curse_active(get_curse(r->attribs, &ct_drought))) { p /= 2; + } return p; } diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 234a91631..764500b50 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -20,6 +20,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "ship.h" +#include +#include + /* kernel includes */ #include "build.h" #include "curse.h" @@ -41,9 +44,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include -#include - #include #include #include @@ -332,10 +332,10 @@ int shipspeed(const ship * sh, const unit * u) return 0; if (sh->attribs) { - if (curse_active(get_curse(sh->attribs, ct_find("stormwind")))) { + if (curse_active(get_curse(sh->attribs, &ct_stormwind))) { k *= 2; } - if (curse_active(get_curse(sh->attribs, ct_find("nodrift")))) { + if (curse_active(get_curse(sh->attribs, &ct_nodrift))) { k += 1; } } diff --git a/src/kernel/ship.test.c b/src/kernel/ship.test.c index 541ddee9a..ce55f55af 100644 --- a/src/kernel/ship.test.c +++ b/src/kernel/ship.test.c @@ -432,8 +432,11 @@ static void test_shipspeed_stormwind(CuTest *tc) { register_shipcurse(); assert(sh && cap && crew); - create_curse(0, &sh->attribs, ct_find("stormwind"), 1, 1, 1, 0); + create_curse(0, &sh->attribs, &ct_stormwind, 1, 1, 1, 0); + CuAssertPtrNotNull(tc, sh->attribs); CuAssertIntEquals_Msg(tc, "stormwind doubles ship range", sh->type->range * 2, shipspeed(sh, cap)); + a_age(&sh->attribs, sh); + CuAssertPtrEquals(tc, NULL, sh->attribs); test_cleanup(); } @@ -447,7 +450,7 @@ static void test_shipspeed_nodrift(CuTest *tc) { register_shipcurse(); assert(sh && cap && crew); - create_curse(0, &sh->attribs, ct_find("nodrift"), 1, 1, 1, 0); + create_curse(0, &sh->attribs, &ct_nodrift, 1, 1, 1, 0); CuAssertIntEquals_Msg(tc, "nodrift adds +1 to range", sh->type->range + 1, shipspeed(sh, cap)); test_cleanup(); } diff --git a/src/kernel/terrain.c b/src/kernel/terrain.c index 3d6f4c313..e9f448f97 100644 --- a/src/kernel/terrain.c +++ b/src/kernel/terrain.c @@ -18,14 +18,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include #include "terrain.h" -#include "terrainid.h" + +#include +#include /* kernel includes */ #include "curse.h" #include "region.h" #include "resources.h" +#include "terrainid.h" #include #include @@ -160,7 +162,7 @@ const char *terrain_name(const struct region *r) return r->terrain->name(r); } else if (fval(r->terrain, SEA_REGION)) { - if (curse_active(get_curse(r->attribs, ct_find("maelstrom")))) { + if (curse_active(get_curse(r->attribs, &ct_maelstrom))) { return "maelstrom"; } } diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 821514cd0..9c08f9dc1 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -43,6 +43,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include +#include + #include "guard.h" /* util includes */ @@ -923,8 +926,7 @@ bool can_survive(const unit * u, const region * r) return false; if (r->attribs) { - const curse_type *ctype = ct_find("holyground"); - if (fval(u_race(u), RCF_UNDEAD) && curse_active(get_curse(r->attribs, ctype))) + if (fval(u_race(u), RCF_UNDEAD) && curse_active(get_curse(r->attribs, &ct_holyground))) return false; } return true; @@ -1255,52 +1257,45 @@ static int att_modification(const unit * u, skill_t sk) if (u->attribs) { curse *c; - static int cache; - static const curse_type *skillmod_ct, *worse_ct; - if (ct_changed(&cache)) { - skillmod_ct = ct_find("skillmod"); - worse_ct = ct_find("worse"); - } - c = get_curse(u->attribs, worse_ct); - if (c != NULL) + attrib *a; + + c = get_curse(u->attribs, &ct_worse); + if (c != NULL) { result += curse_geteffect(c); - if (skillmod_ct) { - attrib *a = a_find(u->attribs, &at_curse); - while (a && a->type == &at_curse) { - curse *c = (curse *)a->data.v; - if (c->type == skillmod_ct && c->data.i == sk) { - result += curse_geteffect(c); - break; - } - a = a->next; + } + + a = a_find(u->attribs, &at_curse); + while (a && a->type == &at_curse) { + c = (curse *)a->data.v; + if (c->type == &ct_skillmod && c->data.i == sk) { + result += curse_geteffect(c); + break; } + a = a->next; } } /* TODO hier kann nicht mit get/iscursed gearbeitet werden, da nur der * jeweils erste vom Typ C_GBDREAM zurueckgegen wird, wir aber alle * durchsuchen und aufaddieren muessen */ if (u->region && u->region->attribs) { - const curse_type *gbdream_ct = ct_find("gbdream"); - if (gbdream_ct) { - int bonus = 0, malus = 0; - attrib *a = a_find(u->region->attribs, &at_curse); - while (a && a->type == &at_curse) { - curse *c = (curse *)a->data.v; + int bonus = 0, malus = 0; + attrib *a = a_find(u->region->attribs, &at_curse); + while (a && a->type == &at_curse) { + curse *c = (curse *)a->data.v; - if (c->magician && curse_active(c) && c->type == gbdream_ct) { - int effect = curse_geteffect_int(c); - bool allied = alliedunit(c->magician, u->faction, HELP_GUARD); - if (allied) { - if (effect > bonus) bonus = effect; - } - else { - if (effect < malus) malus = effect; - } + if (c->magician && curse_active(c) && c->type == &ct_gbdream) { + int effect = curse_geteffect_int(c); + bool allied = alliedunit(c->magician, u->faction, HELP_GUARD); + if (allied) { + if (effect > bonus) bonus = effect; + } + else { + if (effect < malus) malus = effect; } - a = a->next; } - result = result + bonus + malus; + a = a->next; } + result = result + bonus + malus; } return (int)result; @@ -1728,16 +1723,9 @@ int unit_max_hp(const unit * u) /* der healing curse veraendert die maximalen hp */ if (u->region && u->region->attribs) { - static int cache; - static const curse_type *heal_ct; - if (ct_changed(&cache)) { - heal_ct = ct_find("healingzone"); - } - if (heal_ct) { - curse *c = get_curse(u->region->attribs, heal_ct); - if (c) { - h = (int)(h * (1.0 + (curse_geteffect(c) / 100))); - } + curse *c = get_curse(u->region->attribs, &ct_healing); + if (c) { + h = (int)(h * (1.0 + (curse_geteffect(c) / 100))); } } return h; diff --git a/src/laws.c b/src/laws.c index 29fc53ed3..c3c7d968e 100644 --- a/src/laws.c +++ b/src/laws.c @@ -42,6 +42,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "calendar.h" #include "guard.h" +/* attributes includes */ +#include +#include +#include + +#include +#include +#include + /* kernel includes */ #include #include @@ -66,12 +75,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* for volcanoes in emigration (needs a flag) */ #include -/* attributes includes */ -#include -#include -#include -#include - /* util includes */ #include #include @@ -415,7 +418,7 @@ static void horses(region * r) maxhorses = MAX(0, maxhorses); horses = rhorses(r); if (horses > 0) { - if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) { + if (is_cursed(r->attribs, &ct_godcursezone)) { rsethorses(r, (int)(horses * 0.9)); } else if (maxhorses) { @@ -568,7 +571,7 @@ growing_trees(region * r, const int current_season, const int last_weeks_season) a_removeall(&r->attribs, &at_germs); } - if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) { + if (is_cursed(r->attribs, &ct_godcursezone)) { rsettrees(r, 1, (int)(rtrees(r, 1) * 0.9)); rsettrees(r, 2, (int)(rtrees(r, 2) * 0.9)); return; @@ -625,7 +628,7 @@ growing_trees(region * r, const int current_season, const int last_weeks_season) } else if (current_season == SEASON_SPRING) { - if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) + if (is_cursed(r->attribs, &ct_godcursezone)) return; /* in at_germs merken uns die Zahl der Samen und Sprößlinge, die @@ -2846,13 +2849,12 @@ static void age_stonecircle(building *b) { if (get_astralplane()) { region *rt = r_standard_to_astral(r); if (mage && rt && !fval(rt->terrain, FORBIDDEN_REGION)) { - const struct curse_type *ct_astralblock = ct_find("astralblock"); - curse *c = get_curse(rt->attribs, ct_astralblock); + curse *c = get_curse(rt->attribs, &ct_astralblock); if (!c) { int sk = effskill(mage, SK_MAGIC, 0); float effect = 100; /* the mage reactivates the circle */ - c = create_curse(mage, &rt->attribs, ct_astralblock, + c = create_curse(mage, &rt->attribs, &ct_astralblock, (float)MAX(1, sk), MAX(1, sk / 2), effect, 0); ADDMSG(&r->msgs, msg_message("astralshield_activate", "region unit", r, mage)); @@ -2909,11 +2911,13 @@ static void ageing(void) change_effect(u, oldpotiontype[P_BERSERK], -1 * MIN(u->number, i)); } - if (is_cursed(u->attribs, C_OLDRACE, 0)) { - curse *c = get_curse(u->attribs, ct_find("oldrace")); - if (c->duration == 1 && !(c_flags(c) & CURSE_NOAGE)) { - u_setrace(u, get_race(curse_geteffect_int(c))); - u->irace = NULL; + if (u->attribs) { + curse * c = get_curse(u->attribs, &ct_oldrace); + if (c && curse_active(c)) { + if (c->duration == 1 && !(c_flags(c) & CURSE_NOAGE)) { + u_setrace(u, get_race(curse_geteffect_int(c))); + u->irace = NULL; + } } } } @@ -3221,15 +3225,14 @@ static int use_item(unit * u, const item_type * itype, int amount, struct order void monthly_healing(void) { region *r; - const curse_type *heal_ct = ct_find("healingzone"); for (r = regions; r; r = r->next) { unit *u; double healingcurse = 0; - if (r->attribs && heal_ct) { + if (r->attribs) { /* bonus zurücksetzen */ - curse *c = get_curse(r->attribs, heal_ct); + curse *c = get_curse(r->attribs, &ct_healing); if (c != NULL) { healingcurse = curse_geteffect(c); } @@ -3775,7 +3778,7 @@ void process(void) } else if (u_race(u) == get_race(RC_INSECT) && r_insectstalled(r) - && !is_cursed(u->attribs, C_KAELTESCHUTZ, 0)) { + && !is_cursed(u->attribs, &ct_insectfur)) { ord = NULL; } else if (LongHunger(u)) { diff --git a/src/magic.c b/src/magic.c index ad6248ae1..16ee37e60 100644 --- a/src/magic.c +++ b/src/magic.c @@ -25,6 +25,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "study.h" #include "helpers.h" #include "laws.h" +#include "spells.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include #include #include @@ -46,13 +58,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include -#include -#include -#include -#include -#include - /* util includes */ #include #include @@ -695,7 +700,7 @@ int max_spellpoints(const region * r, const unit * u) if (rtype && i_get(u->items, rtype->itype) > 0) { msp += use_item_aura(r, u); } - n = get_curseeffect(u->attribs, C_AURA, 0); + n = get_curseeffect(u->attribs, &ct_auraboost); if (n > 0) { msp = (msp * n) / 100; } @@ -1024,7 +1029,7 @@ spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order curse *c; /* Antimagie in der Zielregion */ - c = get_curse(r->attribs, ct_find("antimagiczone")); + c = get_curse(r->attribs, &ct_antimagiczone); if (curse_active(c)) { unit *mage = c->magician; force -= curse_geteffect(c); @@ -1043,7 +1048,7 @@ spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order } /* Patzerfluch-Effekt: */ - c = get_curse(r->attribs, ct_find("fumble")); + c = get_curse(r->attribs, &ct_fumble); if (curse_active(c)) { unit *mage = c->magician; force -= curse_geteffect(c); @@ -1100,21 +1105,22 @@ variant magic_resistance(unit * target) { attrib *a; curse *c; - const curse_type * ct_goodresist = 0, *ct_badresist = 0; const resource_type *rtype; const race *rc = u_race(target); variant v, prob = rc_magres(rc); const plane *pl = rplane(target->region); + bool good_resist = true; + bool bad_resist = true; if (rc == get_race(RC_HIRNTOETER) && !pl) { - prob = frac_mul(prob, frac_make(1, 2)); + prob = frac_mul(prob, frac_make(1, 2)); } assert(target->number > 0); /* Magier haben einen Resistenzbonus vom Magietalent * 5% */ prob = frac_add(prob, frac_make(effskill(target, SK_MAGIC, 0), 20)); /* Auswirkungen von Zaubern auf der Einheit */ - c = get_curse(target->attribs, ct_find("magicresistance")); + c = get_curse(target->attribs, &ct_magicresistance); if (c) { /* TODO: legacy. magicresistance-effect is an integer-percentage stored in a double */ int effect = curse_geteffect_int(c) * get_cursedmen(target, c); @@ -1132,27 +1138,23 @@ variant magic_resistance(unit * target) /* 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 (good_resist && c->type == &ct_goodmagicresistancezone) { if (alliedunit(mage, target->faction, HELP_GUARD)) { /* TODO: legacy. magicresistance-effect is an integer-percentage stored in a double */ prob = frac_add(prob, frac_make(curse_geteffect_int(c), 100)); - ct_goodresist = 0; /* only one effect per region */ + good_resist = false; /* only one effect per region */ } } - else if (ct_badresist && c->type == ct_badresist) { + else if (bad_resist && c->type == &ct_badmagicresistancezone) { if (!alliedunit(mage, target->faction, HELP_GUARD)) { /* TODO: legacy. magicresistance-effect is an integer-percentage stored in a double */ prob = frac_sub(prob, frac_make(curse_geteffect_int(c), 100)); - ct_badresist = 0; /* only one effect per region */ + bad_resist = false; /* only one effect per region */ } } } @@ -1247,8 +1249,7 @@ target_resists_magic(unit * magician, void *obj, int objtyp, int t_bonus) } if (a) { - const struct curse_type *ct_resist = ct_find(oldcursename(C_RESIST_MAGIC)); - curse * c = get_curse(a, ct_resist); + curse * c = get_curse(a, &ct_magicrunes); int effect = curse_geteffect_int(c); prob = frac_add(prob, frac_make(effect, 100)); } @@ -1316,10 +1317,10 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade) if (mage->magietyp == M_DRAIG) { fumble_chance += CHAOSPATZERCHANCE; } - if (is_cursed(u->attribs, C_MBOOST, 0)) { + if (is_cursed(u->attribs, &ct_magicboost)) { fumble_chance += CHAOSPATZERCHANCE; } - if (is_cursed(u->attribs, C_FUMBLE, 0)) { + if (is_cursed(u->attribs, &ct_fumble)) { fumble_chance += CHAOSPATZERCHANCE; } @@ -1407,7 +1408,7 @@ static void do_fumble(castorder * co) /* temporary skill loss */ duration = MAX(rng_int() % level / 2, 2); effect = level / -2.0; - c = create_curse(u, &u->attribs, ct_find("skillmod"), level, + c = create_curse(u, &u->attribs, &ct_skillmod, level, duration, effect, 1); c->data.i = SK_MAGIC; ADDMSG(&u->faction->msgs, msg_message("patzer2", "unit region", u, r)); @@ -1499,7 +1500,7 @@ void regenerate_aura(void) reg_aura *= btype->auraregen; /* Bonus/Malus durch Zauber */ - mod = get_curseeffect(u->attribs, C_AURA, 0); + mod = get_curseeffect(u->attribs, &ct_auraboost); if (mod > 0) { reg_aura = (reg_aura * mod) / 100.0; } @@ -2790,7 +2791,7 @@ void magic(void) continue; if (u_race(u) == rc_insect && r_insectstalled(r) && - !is_cursed(u->attribs, C_KAELTESCHUTZ, 0)) + !is_cursed(u->attribs, &ct_insectfur)) continue; if (fval(u, UFL_WERE | UFL_LONGACTION)) { diff --git a/src/monsters.c b/src/monsters.c index ffc04b52e..57b557999 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -34,6 +34,8 @@ #include #include +#include + /* kernel includes */ #include #include @@ -904,13 +906,12 @@ void spawn_undead(void) { region *r; faction *monsters = get_monsters(); - const curse_type *ctype = ct_find("holyground"); for (r = regions; r; r = r->next) { int unburied = deathcount(r); - if (r->attribs && ctype) { - if (curse_active(get_curse(r->attribs, ctype))) { + if (r->attribs) { + if (curse_active(get_curse(r->attribs, &ct_holyground))) { continue; } } diff --git a/src/morale.c b/src/morale.c index 8b0a8c6ee..a8a7cc9d9 100644 --- a/src/morale.c +++ b/src/morale.c @@ -20,6 +20,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "morale.h" +#include + #include #include #include @@ -53,7 +55,7 @@ void morale_update(region *r) { if (stability > MORALE_COOLDOWN && r->land->ownership->owner && morale < MORALE_MAX) { double ch = popularity(); - if (is_cursed(r->attribs, C_GENEROUS, 0)) { + if (is_cursed(r->attribs, &ct_generous)) { ch *= 1.2; /* 20% improvement */ } if (stability >= MORALE_AVERAGE * 2 || chance(ch)) { diff --git a/src/move.c b/src/move.c index 8ad25bc5a..33ed38126 100644 --- a/src/move.c +++ b/src/move.c @@ -31,6 +31,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "lighthouse.h" #include "piracy.h" +#include +#include +#include +#include + +/* attributes includes */ +#include +#include +#include +#include + +/* kernel includes */ #include #include #include @@ -49,8 +61,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -#include - #include "teleport.h" #include "direction.h" #include "calendar.h" @@ -71,12 +81,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include -/* attributes includes */ -#include -#include -#include -#include - /* libc includes */ #include #include @@ -670,7 +674,7 @@ static bool is_freezing(const unit * u) { if (u_race(u) != get_race(RC_INSECT)) return false; - if (is_cursed(u->attribs, C_KAELTESCHUTZ, 0)) + if (is_cursed(u->attribs, &ct_insectfur)) return false; return true; } @@ -829,7 +833,7 @@ static void drifting_ships(region * r) } /* Schiff schon abgetrieben oder durch Zauber geschützt? */ - if (!drift || fval(sh, SF_DRIFTED) || is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) { + if (!drift || fval(sh, SF_DRIFTED) || is_cursed(sh->attribs, &ct_nodrift)) { shp = &sh->next; continue; } @@ -1001,7 +1005,7 @@ bool move_blocked(const unit * u, const region * r, const region * r2) } if (r->attribs) { - const curse_type *fogtrap_ct = ct_find("fogtrap"); + const curse_type *fogtrap_ct = &ct_fogtrap; curse *c = get_curse(r->attribs, fogtrap_ct); return curse_active(c); } @@ -1253,7 +1257,7 @@ static bool roadto(const region * r, direction_t dir) return false; } if (r->attribs || r2->attribs) { - const curse_type *roads_ct = ct_find("magicstreet"); + const curse_type *roads_ct = &ct_magicstreet; if (roads_ct != NULL) { if (get_curse(r->attribs, roads_ct) != NULL) return true; @@ -1415,13 +1419,10 @@ static int movement_speed(unit * u) } if (u->attribs) { - const curse_type *speed_ct = ct_find("speed"); - if (speed_ct) { - curse *c = get_curse(u->attribs, speed_ct); - if (c != NULL) { - int men = get_cursedmen(u, c); - dk *= 1.0 + (double)men / (double)u->number; - } + curse *c = get_curse(u->attribs, &ct_speed); + if (c != NULL) { + int men = get_cursedmen(u, c); + dk *= 1.0 + (double)men / (double)u->number; } } @@ -1580,7 +1581,7 @@ static const region_list *travel_route(unit * u, /* illusionary units disappear in antimagic zones */ if (fval(u_race(u), RCF_ILLUSIONARY)) { - curse *c = get_curse(next->attribs, ct_find("antimagiczone")); + curse *c = get_curse(next->attribs, &ct_antimagiczone); if (curse_active(c)) { curse_changevigour(&next->attribs, c, (float)-u->number); ADDMSG(&u->faction->msgs, msg_message("illusionantimagic", "unit", u)); @@ -1803,7 +1804,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting) } if (rng_int() % 10000 < stormchance * sh->type->storm && fval(current_point->terrain, SEA_REGION)) { - if (!is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) { + if (!is_cursed(sh->attribs, &ct_nodrift)) { region *rnext = NULL; bool storm = true; int d_offset = rng_int() % MAXDIRECTIONS; @@ -1894,7 +1895,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting) break; } - if (curse_active(get_curse(next_point->attribs, ct_find("maelstrom")))) { + if (curse_active(get_curse(next_point->attribs, &ct_maelstrom))) { if (do_maelstrom(next_point, u) == NULL) break; } @@ -1920,9 +1921,10 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting) last_point = current_point; current_point = next_point; - if (!fval(current_point->terrain, SEA_REGION) - && !is_cursed(sh->attribs, C_SHIP_FLYING, 0)) + if (!fval(next_point->terrain, SEA_REGION) + && !is_cursed(sh->attribs, &ct_flyingship)) { break; + } token = getstrtoken(); error = movewhere(u, token, current_point, &next_point); if (error || next_point == NULL) { @@ -1958,7 +1960,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting) set_order(&u->thisorder, NULL); set_coast(sh, last_point, current_point); - if (is_cursed(sh->attribs, C_SHIP_FLYING, 0)) { + if (is_cursed(sh->attribs, &ct_flyingship)) { ADDMSG(&f->msgs, msg_message("shipfly", "ship from to", sh, starting_point, current_point)); } diff --git a/src/randenc.c b/src/randenc.c index d2099e49c..2b46499e6 100644 --- a/src/randenc.c +++ b/src/randenc.c @@ -27,6 +27,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "chaos.h" #include "study.h" +#include +#include + +/* attributes includes */ +#include +#include + /* kernel includes */ #include #include @@ -44,10 +51,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -/* attributes includes */ -#include -#include - /* util includes */ #include #include @@ -649,7 +652,7 @@ static void godcurse(void) region *r; for (r = regions; r; r = r->next) { - if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) { + if (is_cursed(r->attribs, &ct_godcursezone)) { unit *u; for (u = r->units; u; u = u->next) { skill *sv = u->skills; @@ -692,32 +695,28 @@ static void orc_growth(void) for (u = r->units; u; u = u->next) { if (u->attribs && !has_skill(u, SK_MAGIC) && !has_skill(u, SK_ALCHEMY) && !fval(u, UFL_HERO)) { - const curse_type *ct_orcish = ct_find("orcish"); + curse *c = get_curse(u->attribs, &ct_orcish); + if (c) { + int n; + int increase = 0; + int num = get_cursedmen(u, c); + double prob = curse_geteffect(c); + const item_type * it_chastity = it_find("ao_chastity"); - if (ct_orcish) { - curse *c = get_curse(u->attribs, ct_orcish); - if (c) { - int n; - int increase = 0; - int num = get_cursedmen(u, c); - double prob = curse_geteffect(c); - const item_type * it_chastity = it_find("ao_chastity"); + if (it_chastity) { + num -= i_get(u->items, it_chastity); + } + for (n = num; n > 0; n--) { + if (chance(prob)) { + ++increase; + } + } + if (increase) { + unit *u2 = create_unit(r, u->faction, increase, u_race(u), 0, NULL, u); + transfermen(u2, u, u2->number); - if (it_chastity) { - num -= i_get(u->items, it_chastity); - } - for (n = num; n > 0; n--) { - if (chance(prob)) { - ++increase; - } - } - if (increase) { - unit *u2 = create_unit(r, u->faction, increase, u_race(u), 0, NULL, u); - transfermen(u2, u, u2->number); - - ADDMSG(&u->faction->msgs, msg_message("orcgrowth", - "unit amount race", u, increase, u_race(u))); - } + ADDMSG(&u->faction->msgs, msg_message("orcgrowth", + "unit amount race", u, increase, u_race(u))); } } } diff --git a/src/report.c b/src/report.c index 2e11b4e09..2cafe3157 100644 --- a/src/report.c +++ b/src/report.c @@ -29,6 +29,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "monsters.h" #include "travelthru.h" +#include +#include + /* modules includes */ #include @@ -1185,7 +1188,7 @@ void report_region(struct stream *out, const region * r, faction * f) paragraph(out, buf, 0, 0, 0); if (r->seen.mode >= seen_unit && is_astral(r) && - !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) { + !is_cursed(r->attribs, &ct_astralblock)) { /* Sonderbehandlung Teleport-Ebene */ region_list *rl = astralregions(r, inhabitable); region_list *rl2; @@ -1390,7 +1393,6 @@ report_template(const char *filename, report_context * ctx, const char *bom) char buf[8192], *bufp; size_t size; int bytes; - const curse_type *nocost_ct = ct_find("nocostbuilding"); if (F == NULL) { perror(filename); @@ -1459,7 +1461,7 @@ report_template(const char *filename, report_context * ctx, const char *bom) WARN_STATIC_BUFFER(); if (u->building && building_owner(u->building) == u) { building *b = u->building; - if (!curse_active(get_curse(b->attribs, nocost_ct))) { + if (!curse_active(get_curse(b->attribs, &ct_nocostbuilding))) { int cost = buildingmaintenance(b, rsilver); if (cost > 0) { bytes = (int)strlcpy(bufp, ",U", size); diff --git a/src/reports.c b/src/reports.c index e989aee40..cc11f4006 100644 --- a/src/reports.c +++ b/src/reports.c @@ -26,6 +26,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "lighthouse.h" #include "donations.h" +/* attributes includes */ +#include +#include +#include +#include +#include + +#include + /* kernel includes */ #include #include @@ -69,13 +78,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -/* attributes includes */ -#include -#include -#include -#include -#include - #include "move.h" #if defined(_MSC_VER) && _MSC_VER >= 1900 @@ -306,12 +308,9 @@ report_items(const unit *u, item * result, int size, const unit * owner, assert(size); if (u->attribs) { - const curse_type *itemcloak_ct = ct_find("itemcloak"); - if (itemcloak_ct) { - curse * cu = get_curse(u->attribs, itemcloak_ct); - if (cu && curse_active(cu)) { - return 0; - } + curse * cu = get_curse(u->attribs, &ct_itemcloak); + if (cu && curse_active(cu)) { + return 0; } } for (itm = items; itm; itm = itm->next) { diff --git a/src/spells.c b/src/spells.c index e620c0a78..31d75c6b3 100644 --- a/src/spells.c +++ b/src/spells.c @@ -827,7 +827,7 @@ static int sp_goodwinds(castorder * co) /* keine Probleme mit C_SHIP_SPEEDUP und C_SHIP_FLYING */ /* NODRIFT bewirkt auch +1 Geschwindigkeit */ - create_curse(mage, &sh->attribs, ct_find("nodrift"), power, duration, + create_curse(mage, &sh->attribs, &ct_nodrift, power, duration, zero_effect, 0); /* melden, 1x pro Partei */ @@ -874,7 +874,7 @@ static int sp_magicstreet(castorder * co) } /* wirkt schon in der Zauberrunde! */ - create_curse(mage, &r->attribs, ct_find("magicstreet"), co->force, + create_curse(mage, &r->attribs, &ct_magicstreet, co->force, co->level + 1, zero_effect, 0); /* melden, 1x pro Partei */ @@ -1024,7 +1024,7 @@ static int sp_maelstrom(castorder * co) /* Attribut auf Region. * Existiert schon ein curse, so wird dieser verstaerkt * (Max(Dauer), Max(Staerke))*/ - c = create_curse(mage, &r->attribs, ct_find("maelstrom"), co->force, duration, co->force, 0); + c = create_curse(mage, &r->attribs, &ct_maelstrom, co->force, duration, co->force, 0); /* melden, 1x pro Partei */ if (c) { @@ -1104,7 +1104,7 @@ static int sp_blessedharvest(castorder * co) * Existiert schon ein curse, so wird dieser verstaerkt * (Max(Dauer), Max(Staerke))*/ - if (create_curse(mage, &r->attribs, ct_find("blessedharvest"), co->force, + if (create_curse(mage, &r->attribs, &ct_blessedharvest, co->force, duration, 1.0, 0)) { const char * effect = co->sp->sname[0]=='b' ? "harvest_effect" : "raindance_effect"; message *seen = msg_message(effect, "mage", mage); @@ -1407,7 +1407,7 @@ static int sp_kaelteschutz(castorder * co) } effect = 1; - create_curse(mage, &u->attribs, ct_find("insectfur"), (float)cast_level, + create_curse(mage, &u->attribs, &ct_insectfur, (float)cast_level, duration, effect, men); force -= u->number; @@ -1457,7 +1457,7 @@ static int sp_sparkle(castorder * co) u = pa->param[0]->data.u; effect = (float)(rng_int() % 0xffffff); - create_curse(mage, &u->attribs, ct_find("sparkle"), (float)cast_level, + create_curse(mage, &u->attribs, &ct_sparkle, (float)cast_level, duration, effect, u->number); ADDMSG(&mage->faction->msgs, msg_message("sparkle_effect", "mage target", @@ -1661,7 +1661,7 @@ static int sp_great_drought(castorder * co) /* Arbeitslohn = 1/4 */ effect = 4.0; /* curses: higher is stronger */ - create_curse(mage, &r->attribs, ct_find("drought"), force, duration, effect, + create_curse(mage, &r->attribs, &ct_drought, force, duration, effect, 0); /* terraforming */ @@ -1787,7 +1787,7 @@ static int sp_treewalkenter(castorder * co) } rt = r_standard_to_astral(r); - if (rt == NULL || is_cursed(rt->attribs, C_ASTRALBLOCK, 0) + if (rt == NULL || is_cursed(rt->attribs, &ct_astralblock) || fval(rt->terrain, FORBIDDEN_REGION)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); @@ -1903,7 +1903,7 @@ static int sp_treewalkexit(castorder * co) "spellfail_astralonly", "")); return 0; } - if (is_cursed(r->attribs, C_ASTRALBLOCK, 0)) { + if (is_cursed(r->attribs, &ct_astralblock)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); return 0; @@ -2038,7 +2038,7 @@ static int sp_holyground(castorder * co) report_spell(mage, r, msg); msg_release(msg); - ctype = ct_find("holyground"); + ctype = &ct_holyground; create_curse(mage, &r->attribs, ctype, power * power, 1, zero_effect, 0); a_removeall(&r->attribs, &at_deathcount); @@ -2085,7 +2085,7 @@ static int sp_homestone(castorder * co) /* Magieresistenz der Burg erhoeht sich um 50% */ effect = 50.0F; c = create_curse(mage, &mage->building->attribs, - ct_find("magicresistance"), force * force, 1, effect, 0); + &ct_magicresistance, force * force, 1, effect, 0); c_setflag(c, CURSE_NOAGE); /* melden, 1x pro Partei in der Burg */ @@ -2143,7 +2143,7 @@ static int sp_drought(castorder * co) * hoch (evtl dauert dann die Duerre laenger). Ansonsten volle * Auswirkungen. */ - c = get_curse(r->attribs, ct_find("drought")); + c = get_curse(r->attribs, &ct_drought); if (c) { c->vigour = MAX(c->vigour, power); c->duration = MAX(c->duration, (int)power); @@ -2156,7 +2156,7 @@ static int sp_drought(castorder * co) rsettrees(r, 0, rtrees(r, 0) / 2); rsethorses(r, rhorses(r) / 2); - create_curse(mage, &r->attribs, ct_find("drought"), power, duration, effect, + create_curse(mage, &r->attribs, &ct_drought, power, duration, effect, 0); } return cast_level; @@ -2266,19 +2266,19 @@ static int sp_stormwinds(castorder * co) sh = pa->param[n]->data.sh; /* mit C_SHIP_NODRIFT haben wir kein Problem */ - if (is_cursed(sh->attribs, C_SHIP_FLYING, 0)) { + if (is_cursed(sh->attribs, &ct_flyingship)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_spell_on_flying_ship", "ship", sh)) continue; } - if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0)) { + if (is_cursed(sh->attribs, &ct_shipspeedup)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_spell_on_ship_already", "ship", sh)) continue; } /* Duration = 1, nur diese Runde */ - create_curse(mage, &sh->attribs, ct_find("stormwind"), power, 1, + create_curse(mage, &sh->attribs, &ct_stormwind, power, 1, zero_effect, 0); /* Da der Spruch nur diese Runde wirkt wird er nie im Report * erscheinen */ @@ -2340,7 +2340,7 @@ static int sp_earthquake(castorder * co) while (*blist) { building *burg = *blist; - if (burg->size != 0 && !is_cursed(burg->attribs, C_MAGICWALLS, 0)) { + if (burg->size != 0 && !is_cursed(burg->attribs, &ct_magicwalls)) { /* Magieresistenz */ if (!target_resists_magic(mage, burg, TYP_BUILDING, 0)) { kaputt = MIN(10 * cast_level, burg->size / 4); @@ -2540,7 +2540,7 @@ static int sp_fumblecurse(castorder * co) duration = MAX(sx, rx) + 1; effect = force / 2; - c = create_curse(mage, &target->attribs, ct_find("fumble"), + c = create_curse(mage, &target->attribs, &ct_fumble, force, duration, effect, 0); if (c == NULL) { report_failure(mage, co->order); @@ -2563,7 +2563,7 @@ void patzer_fumblecurse(const castorder * co) curse *c; effect = force / 2; - c = create_curse(mage, &mage->attribs, ct_find("fumble"), force, + c = create_curse(mage, &mage->attribs, &ct_fumble, force, duration, effect, 0); if (c != NULL) { ADDMSG(&mage->faction->msgs, msg_message("magic_fumble", @@ -2800,7 +2800,7 @@ static int sp_unholypower(castorder * co) * korrekt abgefangen wird. Besser (aber nicht gerade einfach) * waere es, eine solche Konstruktion irgendwie zu kapseln. */ if (fval(u, UFL_LOCKED) || fval(u, UFL_HUNGER) - || is_cursed(u->attribs, C_SLAVE, 0)) { + || is_cursed(u->attribs, &ct_slavery)) { cmistake(mage, co->order, 74, MSG_MAGIC); continue; } @@ -3188,7 +3188,7 @@ static int sp_chaossuction(castorder * co) cmistake(mage, co->order, 216, MSG_MAGIC); return 0; } - else if (is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) { + else if (is_cursed(rt->attribs, &ct_astralblock)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); return 0; @@ -3233,28 +3233,21 @@ static int sp_magicboost(castorder * co) double power = co->force; double effect; trigger *tsummon; - const curse_type *ct_auraboost; - const curse_type *ct_magicboost; - - ct_auraboost = ct_find("auraboost"); - ct_magicboost = ct_find("magicboost"); - assert(ct_auraboost != NULL); - assert(ct_magicboost != NULL); /* fehler, wenn schon ein boost */ - if (is_cursed(mage->attribs, C_MBOOST, 0)) { + if (is_cursed(mage->attribs, &ct_magicboost)) { report_failure(mage, co->order); return 0; } effect = 6; - create_curse(mage, &mage->attribs, ct_magicboost, power, 10, effect, 1); + create_curse(mage, &mage->attribs, &ct_magicboost, power, 10, effect, 1); /* one aura boost with 200% aura now: */ effect = 200; - c = create_curse(mage, &mage->attribs, ct_auraboost, power, 4, effect, 1); + c = create_curse(mage, &mage->attribs, &ct_auraboost, power, 4, effect, 1); /* and one aura boost with 50% aura in 5 weeks: */ - tsummon = trigger_createcurse(mage, mage, ct_auraboost, power, 6, 50, 1); + tsummon = trigger_createcurse(mage, mage, &ct_auraboost, power, 6, 50, 1); add_trigger(&mage->attribs, "timer", trigger_timeout(5, tsummon)); ADDMSG(&mage->faction->msgs, msg_message("magicboost_effect", @@ -3649,7 +3642,7 @@ static int sp_charmingsong(castorder * co) add_trigger(&mage->faction->attribs, "destroy", trigger_killunit(target)); } /* sperre ATTACKIERE, GIB PERSON und ueberspringe Migranten */ - create_curse(mage, &target->attribs, ct_find("slavery"), force, duration, zero_effect, 0); + create_curse(mage, &target->attribs, &ct_slavery, force, duration, zero_effect, 0); /* setze Partei um und loesche langen Befehl aus Sicherheitsgruenden */ u_setfaction(target, mage->faction); @@ -3687,7 +3680,7 @@ static int sp_song_resistmagic(castorder * co) double force = co->force; int duration = (int)force + 1; - create_curse(mage, &r->attribs, ct_find("goodmagicresistancezone"), + create_curse(mage, &r->attribs, &ct_goodmagicresistancezone, force, duration, 15, 0); /* Erfolg melden */ @@ -3716,7 +3709,7 @@ static int sp_song_susceptmagic(castorder * co) double force = co->force; int duration = (int)force + 1; - create_curse(mage, &r->attribs, ct_find("badmagicresistancezone"), + create_curse(mage, &r->attribs, &ct_badmagicresistancezone, force, duration, 15, 0); ADDMSG(&mage->faction->msgs, msg_message("regionmagic_effect", @@ -3757,7 +3750,7 @@ static int sp_rallypeasantmob(castorder * co) } } - c = get_curse(r->attribs, ct_find(oldcursename(C_RIOT))); + c = get_curse(r->attribs, &ct_riotzone); if (c != NULL) { remove_curse(&r->attribs, c); } @@ -3824,7 +3817,7 @@ static int sp_raisepeasantmob(castorder * co) a->data.ca[1] = 15; /* 15% */ a_add(&u->attribs, a); - create_curse(mage, &r->attribs, ct_find("riotzone"), (float)cast_level, duration, + create_curse(mage, &r->attribs, &ct_riotzone, (float)cast_level, duration, (float)anteil, 0); msg = msg_message("sp_raisepeasantmob_effect", "mage region", mage, r); @@ -3923,7 +3916,7 @@ static int sp_song_of_peace(castorder * co) int duration = 2 + lovar(force / 2); message *msg[2] = { NULL, NULL }; - create_curse(mage, &r->attribs, ct_find("peacezone"), force, duration, + create_curse(mage, &r->attribs, &ct_peacezone, force, duration, zero_effect, 0); for (u = r->units; u; u = u->next) @@ -3973,14 +3966,14 @@ static int sp_generous(castorder * co) double effect; message *msg[2] = { NULL, NULL }; - if (is_cursed(r->attribs, C_DEPRESSION, 0)) { + if (is_cursed(r->attribs, &ct_depression)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_generous", "")); return 0; } effect = 2; - create_curse(mage, &r->attribs, ct_find("generous"), force, duration, effect, + create_curse(mage, &r->attribs, &ct_generous, force, duration, effect, 0); for (u = r->units; u; u = u->next) @@ -4292,7 +4285,7 @@ static int sp_calm_monster(castorder * co) } effect = mage->faction->subscription; - c = create_curse(mage, &target->attribs, ct_find("calmmonster"), force, + c = create_curse(mage, &target->attribs, &ct_calmmonster, force, (int)force, effect, 0); if (c == NULL) { report_failure(mage, co->order); @@ -4440,7 +4433,7 @@ static int sp_depression(castorder * co) int duration = (int)force + 1; message *msg; - create_curse(mage, &r->attribs, ct_find("depression"), force, duration, + create_curse(mage, &r->attribs, &ct_depression, force, duration, zero_effect, 0); msg = msg_message("sp_depression_effect", "mage region", mage, r); @@ -4666,7 +4659,29 @@ int sp_analysedream(castorder * co) return cast_level; } -static int sp_gbdreams(castorder * co, const char *curse_name, int effect); +static int sp_gbdreams(castorder * co, int effect) +{ + int duration; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + region *r = co_get_region(co); + + /* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken, + * also duration+2 */ + duration = (int)MAX(1, power / 2); /* Stufe 1 macht sonst mist */ + duration = 2 + rng_int() % duration; + + /* Nichts machen als ein entsprechendes Attribut in die Region legen. */ + create_curse(mage, &r->attribs, &ct_gbdream, power, duration, effect, 0); + + /* Erfolg melden */ + ADDMSG(&mage->faction->msgs, msg_message("regionmagic_effect", + "unit region command", mage, mage->region, co->order)); + + return cast_level; +} + /* ------------------------------------------------------------- */ /* Name: Schlechte Traeume @@ -4683,7 +4698,7 @@ static int sp_gbdreams(castorder * co, const char *curse_name, int effect); * */ int sp_baddreams(castorder * co) { - return sp_gbdreams(co, "gbdream", -1); + return sp_gbdreams(co, -1); } /* ------------------------------------------------------------- */ @@ -4700,30 +4715,7 @@ int sp_baddreams(castorder * co) */ int sp_gooddreams(castorder * co) { - return sp_gbdreams(co, "gbdream", 1); -} - -static int sp_gbdreams(castorder * co, const char *curse_name, int effect) -{ - int duration; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - region *r = co_get_region(co); - - /* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken, - * also duration+2 */ - duration = (int)MAX(1, power / 2); /* Stufe 1 macht sonst mist */ - duration = 2 + rng_int() % duration; - - /* Nichts machen als ein entsprechendes Attribut in die Region legen. */ - create_curse(mage, &r->attribs, ct_find(curse_name), power, duration, effect, 0); - - /* Erfolg melden */ - ADDMSG(&mage->faction->msgs, msg_message("regionmagic_effect", - "unit region command", mage, mage->region, co->order)); - - return cast_level; + return sp_gbdreams(co, 1); } /* ------------------------------------------------------------- */ @@ -4854,7 +4846,7 @@ int sp_sweetdreams(castorder * co) /* Nichts machen als ein entsprechendes Attribut an die Einheit legen. */ effect = 0.05f; - create_curse(mage, &u->attribs, ct_find("orcish"), power, duration, effect, men); + create_curse(mage, &u->attribs, &ct_orcish, power, duration, effect, men); msg = msg_message("sp_sweetdreams_effect", "mage unit region", mage, u, r); r_addmessage(r, mage->faction, msg); @@ -4877,7 +4869,7 @@ int sp_disturbingdreams(castorder * co) double effect; effect = 10; - create_curse(mage, &r->attribs, ct_find("badlearn"), power, duration, effect, 0); + create_curse(mage, &r->attribs, &ct_badlearn, power, duration, effect, 0); ADDMSG(&mage->faction->msgs, msg_message("sp_disturbingdreams_effect", "mage region", mage, r)); @@ -4971,7 +4963,7 @@ int sp_itemcloak(castorder * co) /* Zieleinheit */ target = pa->param[0]->data.u; - create_curse(mage, &target->attribs, ct_find("itemcloak"), power, duration, + create_curse(mage, &target->attribs, &ct_itemcloak, power, duration, zero_effect, 0); ADDMSG(&mage->faction->msgs, msg_message("itemcloak", "mage target", mage, target)); @@ -5023,7 +5015,7 @@ int sp_resist_magic_bonus(castorder * co) m = MIN(u->number, victims); victims -= m; - create_curse(mage, &u->attribs, ct_find("magicresistance"), + create_curse(mage, &u->attribs, &ct_magicresistance, power, duration, 20, m); msg = msg_message("magicresistance_effect", "unit", u); @@ -5074,8 +5066,8 @@ int sp_enterastral(castorder * co) return 0; } - if (is_cursed(rt->attribs, C_ASTRALBLOCK, 0) - || is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) { + if (is_cursed(rt->attribs, &ct_astralblock) + || is_cursed(ro->attribs, &ct_astralblock)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); return 0; @@ -5201,8 +5193,8 @@ int sp_pullastral(castorder * co) return 0; } - if (is_cursed(rt->attribs, C_ASTRALBLOCK, 0) - || is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) { + if (is_cursed(rt->attribs, &ct_astralblock) + || is_cursed(ro->attribs, &ct_astralblock)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); return 0; @@ -5345,8 +5337,8 @@ int sp_leaveastral(castorder * co) return 0; } - if (ro == NULL || is_cursed(ro->attribs, C_ASTRALBLOCK, 0) - || is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) { + if (ro == NULL || is_cursed(ro->attribs, &ct_astralblock) + || is_cursed(rt->attribs, &ct_astralblock)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); return 0; @@ -5485,7 +5477,7 @@ int sp_fetchastral(castorder * co) ro = u->region; } - if (is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) { + if (is_cursed(ro->attribs, &ct_astralblock)) { ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); continue; @@ -5598,7 +5590,7 @@ int sp_showastral(castorder * co) for (rl2 = rl; rl2; rl2 = rl2->next) { region *r2 = rl2->data; - if (!is_cursed(r2->attribs, C_ASTRALBLOCK, 0)) { + if (!is_cursed(r2->attribs, &ct_astralblock)) { for (u = r2->units; u; u = u->next) { n++; } @@ -5618,7 +5610,7 @@ int sp_showastral(castorder * co) "Nebel zu erkennen sind ", unitname(mage)); for (rl2 = rl; rl2; rl2 = rl2->next) { - if (!is_cursed(rl2->data->attribs, C_ASTRALBLOCK, 0)) { + if (!is_cursed(rl2->data->attribs, &ct_astralblock)) { for (u = rl2->data->units; u; u = u->next) { c++; scat(unitname(u)); @@ -5674,7 +5666,7 @@ int sp_viewreality(castorder * co) /* Irgendwann mal auf Curses u/o Attribut umstellen. */ for (rl2 = rl; rl2; rl2 = rl2->next) { region *rt = rl2->data; - if (!is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) { + if (!is_cursed(rt->attribs, &ct_astralblock)) { set_observer(rt, mage->faction, co->level / 2, 2); } } @@ -5728,7 +5720,7 @@ int sp_disruptastral(castorder * co) int inhab_regions = 0; region_list *trl = NULL; - if (is_cursed(r2->attribs, C_ASTRALBLOCK, 0)) + if (is_cursed(r2->attribs, &ct_astralblock)) continue; if (r2->units != NULL) { @@ -5777,7 +5769,7 @@ int sp_disruptastral(castorder * co) /* Kontakt unterbinden */ effect = 100; - create_curse(mage, &rl2->data->attribs, ct_find("astralblock"), + create_curse(mage, &rl2->data->attribs, &ct_astralblock, power, duration, effect, 0); } @@ -5813,7 +5805,7 @@ static int sp_eternizewall(castorder * co) return 0; b = pa->param[0]->data.b; - c = create_curse(mage, &b->attribs, ct_find("nocostbuilding"), + c = create_curse(mage, &b->attribs, &ct_nocostbuilding, power * power, 1, zero_effect, 0); if (c == NULL) { /* ist bereits verzaubert */ @@ -6091,7 +6083,7 @@ int sp_antimagiczone(castorder * co) /* Reduziert die Staerke jedes Spruchs um effect */ effect = cast_level; - create_curse(mage, &r->attribs, ct_find("antimagiczone"), power, duration, + create_curse(mage, &r->attribs, &ct_antimagiczone, power, duration, effect, 0); /* Erfolg melden */ @@ -6151,7 +6143,7 @@ static int sp_magicrunes(castorder * co) b = pa->param[0]->data.b; /* Magieresistenz der Burg erhoeht sich um 20% */ - create_curse(mage, &b->attribs, ct_find("magicrunes"), force, + create_curse(mage, &b->attribs, &ct_magicrunes, force, duration, effect, 0); /* Erfolg melden */ @@ -6165,7 +6157,7 @@ static int sp_magicrunes(castorder * co) ship *sh; sh = pa->param[0]->data.sh; /* Magieresistenz des Schiffs erhoeht sich um 20% */ - create_curse(mage, &sh->attribs, ct_find("magicrunes"), force, + create_curse(mage, &sh->attribs, &ct_magicrunes, force, duration, effect, 0); /* Erfolg melden */ @@ -6217,7 +6209,7 @@ int sp_speed2(castorder * co) men = MIN(maxmen, u->number); effect = 2; - create_curse(mage, &u->attribs, ct_find("speed"), force, dur, effect, men); + create_curse(mage, &u->attribs, &ct_speed, force, dur, effect, men); maxmen -= men; used += men; } diff --git a/src/spells.h b/src/spells.h index 33a263733..3b6280e83 100644 --- a/src/spells.h +++ b/src/spells.h @@ -22,13 +22,15 @@ extern "C" { #endif - struct ship; - struct curse; + struct curse_type; + struct region; struct unit; struct faction; struct region; struct message; + extern const struct curse_type ct_magicresistance; + void register_magicresistance(void); void register_spells(void); diff --git a/src/spells.test.c b/src/spells.test.c index 00a88cbf8..cd72f0177 100644 --- a/src/spells.test.c +++ b/src/spells.test.c @@ -44,7 +44,7 @@ static void test_good_dreams(CuTest *tc) { level = sp_gooddreams(&co); CuAssertIntEquals(tc, 10, level); - curse = get_curse(r->attribs, ct_find("gbdream")); + curse = get_curse(r->attribs, &ct_gbdream); CuAssertTrue(tc, curse && curse->duration > 1); CuAssertTrue(tc, curse->effect == 1); @@ -101,7 +101,7 @@ static void test_bad_dreams(CuTest *tc) { level = sp_baddreams(&co); CuAssertIntEquals(tc, 10, level); - curse = get_curse(r->attribs, ct_find("gbdream")); + curse = get_curse(r->attribs, &ct_gbdream); CuAssertTrue(tc, curse && curse->duration > 1); CuAssertTrue(tc, curse->effect == -1); diff --git a/src/spells/buildingcurse.c b/src/spells/buildingcurse.c index f1a3b3773..06c62e1c4 100644 --- a/src/spells/buildingcurse.c +++ b/src/spells/buildingcurse.c @@ -70,7 +70,7 @@ static message *cinfo_magicrunes(const void *obj, objtype_t typ, const curse * c return msg; } -static struct curse_type ct_magicrunes = { "magicrunes", +const struct curse_type ct_magicrunes = { "magicrunes", CURSETYP_NORM, 0, M_SUMEFFECT, cinfo_magicrunes }; @@ -80,12 +80,12 @@ CURSETYP_NORM, CURSE_ONLYONE|CURSE_NOAGE, NO_MERGE, cinfo_building }; /* Feste Mauer - Präkampfzauber, wirkt nur 1 Runde */ -static struct curse_type ct_strongwall = { "strongwall", +const struct curse_type ct_strongwall = { "strongwall", CURSETYP_NORM, 0, NO_MERGE, NULL }; /* Ewige Mauern-Zauber */ -static struct curse_type ct_nocostbuilding = { "nocostbuilding", +const struct curse_type ct_nocostbuilding = { "nocostbuilding", CURSETYP_NORM, CURSE_NOAGE | CURSE_ONLYONE, NO_MERGE, cinfo_building }; diff --git a/src/spells/buildingcurse.h b/src/spells/buildingcurse.h index 2150dc3b6..03fc46a63 100644 --- a/src/spells/buildingcurse.h +++ b/src/spells/buildingcurse.h @@ -24,6 +24,9 @@ extern "C" { struct curse_type; extern const struct curse_type ct_magicwalls; + extern const struct curse_type ct_strongwall; + extern const struct curse_type ct_magicrunes; + extern const struct curse_type ct_nocostbuilding; extern void register_buildingcurse(void); struct message *cinfo_building(const void *obj, objtype_t typ, const struct curse * c, int self); diff --git a/src/spells/combatspells.c b/src/spells/combatspells.c index 1f3ad47e4..da2d52182 100644 --- a/src/spells/combatspells.c +++ b/src/spells/combatspells.c @@ -12,7 +12,9 @@ #include #include "combatspells.h" -/* kernel includes */ +#include + + /* kernel includes */ #include #include #include @@ -880,7 +882,7 @@ int sp_strong_wall(struct castorder * co) burg = mage->building; effect = power / 4; - create_curse(mage, &burg->attribs, ct_find("strongwall"), power, 1, effect, 0); + create_curse(mage, &burg->attribs, &ct_strongwall, power, 1, effect, 0); msg = msg_message("sp_strongwalls_effect", "mage building", mage, mage->building); diff --git a/src/spells/flyingship.c b/src/spells/flyingship.c index eac2043dd..e23f6906b 100644 --- a/src/spells/flyingship.c +++ b/src/spells/flyingship.c @@ -1,6 +1,8 @@ #include #include "flyingship.h" +#include + #include #include #include @@ -13,8 +15,6 @@ #include -#include - #include /* libc includes */ @@ -66,11 +66,11 @@ int sp_flying_ship(castorder * co) cno = levitate_ship(sh, mage, power, 1); if (cno == 0) { - if (is_cursed(sh->attribs, C_SHIP_FLYING, 0)) { + if (is_cursed(sh->attribs, &ct_flyingship)) { /* Auf dem Schiff befindet liegt bereits so ein Zauber. */ cmistake(mage, co->order, 211, MSG_MAGIC); } - else if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0)) { + else if (is_cursed(sh->attribs, &ct_shipspeedup)) { /* Es ist zu gefaehrlich, ein sturmgepeitschtes Schiff fliegen zu lassen. */ cmistake(mage, co->order, 210, MSG_MAGIC); } @@ -127,7 +127,7 @@ static int flyingship_age(curse * c) return 0; } -static struct curse_type ct_flyingship = { "flyingship", +const struct curse_type ct_flyingship = { "flyingship", CURSETYP_NORM, 0, NO_MERGE, cinfo_ship, NULL, flyingship_read, flyingship_write, NULL, flyingship_age }; @@ -153,7 +153,7 @@ static curse *shipcurse_flyingship(ship * sh, unit * mage, double power, int dur if (curse_active(get_curse(sh->attribs, &ct_flyingship))) { return NULL; } - if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0)) { + if (is_cursed(sh->attribs, &ct_shipspeedup)) { return NULL; } } diff --git a/src/spells/flyingship.h b/src/spells/flyingship.h index 52013ac13..4a03e6b71 100644 --- a/src/spells/flyingship.h +++ b/src/spells/flyingship.h @@ -12,6 +12,9 @@ extern "C" { struct castorder; struct ship; struct unit; + struct curse_type; + + extern const struct curse_type ct_flyingship; int sp_flying_ship(struct castorder * co); diff --git a/src/spells/magicresistance.c b/src/spells/magicresistance.c index 7b0c1413d..6f2ec49ec 100644 --- a/src/spells/magicresistance.c +++ b/src/spells/magicresistance.c @@ -22,7 +22,7 @@ static struct message *cinfo_magicresistance(const void *obj, objtype_t typ, con return 0; } -static struct curse_type ct_magicresistance = { +const struct curse_type ct_magicresistance = { "magicresistance", CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN, cinfo_magicresistance }; diff --git a/src/spells/magicresistance.test.c b/src/spells/magicresistance.test.c index 621d2c3b4..7576911af 100644 --- a/src/spells/magicresistance.test.c +++ b/src/spells/magicresistance.test.c @@ -36,7 +36,7 @@ static void test_magicresistance_unit(CuTest *tc) { f2 = test_create_faction(NULL); u2 = test_create_unit(f2, r); - c = create_curse(u1, &u2->attribs, ct_find("magicresistance"), 10, 20, 30, u2->number); + c = create_curse(u1, &u2->attribs, &ct_magicresistance, 10, 20, 30, u2->number); CuAssertPtrNotNull(tc, u2->attribs); CuAssertPtrEquals(tc, (void *)&at_curse, (void *)u2->attribs->type); msg = c->type->curseinfo(u2, TYP_UNIT, c, 1); @@ -62,7 +62,7 @@ static void test_magicresistance_building(CuTest *tc) { b1 = test_create_building(r, NULL); - c = create_curse(u1, &b1->attribs, ct_find("magicresistance"), 10, 20, 30, 0); + c = create_curse(u1, &b1->attribs, &ct_magicresistance, 10, 20, 30, 0); CuAssertPtrNotNull(tc, b1->attribs); CuAssertPtrEquals(tc, (void *)&at_curse, (void *)b1->attribs->type); msg = c->type->curseinfo(b1, TYP_BUILDING, c, 1); diff --git a/src/spells/regioncurse.c b/src/spells/regioncurse.c index eca8b1798..8ac3eea8c 100644 --- a/src/spells/regioncurse.c +++ b/src/spells/regioncurse.c @@ -52,7 +52,7 @@ static message *cinfo_cursed_by_the_gods(const void *obj, objtype_t typ, return msg_message("curseinfo::godcurse", "id", c->no); } -static struct curse_type ct_godcursezone = { +const struct curse_type ct_godcursezone = { "godcursezone", CURSETYP_NORM, CURSE_IMMUNE, (NO_MERGE), cinfo_cursed_by_the_gods, @@ -78,7 +78,7 @@ static message *cinfo_dreamcurse(const void *obj, objtype_t typ, const curse * c } } -static struct curse_type ct_gbdream = { +const struct curse_type ct_gbdream = { "gbdream", CURSETYP_NORM, 0, (NO_MERGE), cinfo_dreamcurse }; @@ -103,7 +103,7 @@ static message *cinfo_magicstreet(const void *obj, objtype_t typ, const curse * return msg_message("curseinfo::magicstreetwarn", "id", c->no); } -static struct curse_type ct_magicstreet = { +const struct curse_type ct_magicstreet = { "magicstreet", CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), cinfo_magicstreet @@ -154,7 +154,7 @@ const curse * c, int self) return self; } -static struct curse_type ct_antimagiczone = { +const struct curse_type ct_antimagiczone = { "antimagiczone", CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), cinfo_antimagiczone, NULL, NULL, NULL, cansee_antimagiczone @@ -185,19 +185,19 @@ static struct curse_type ct_farvision = { /* --------------------------------------------------------------------- */ -static struct curse_type ct_fogtrap = { +const struct curse_type ct_fogtrap = { "fogtrap", CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), cinfo_simple }; -static struct curse_type ct_maelstrom = { +const struct curse_type ct_maelstrom = { "maelstrom", CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), cinfo_simple }; -static struct curse_type ct_blessedharvest = { +const struct curse_type ct_blessedharvest = { "blessedharvest", CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), cinfo_simple @@ -219,41 +219,41 @@ int harvest_effect(const struct region *r) { return 0; } -static struct curse_type ct_drought = { +const struct curse_type ct_drought = { "drought", CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), cinfo_simple }; -static struct curse_type ct_badlearn = { +const struct curse_type ct_badlearn = { "badlearn", CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), cinfo_simple }; /* Trübsal-Zauber */ -static struct curse_type ct_depression = { +const struct curse_type ct_depression = { "depression", CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), cinfo_simple }; /* Astralblock, auf Astralregion */ -static struct curse_type ct_astralblock = { +const struct curse_type ct_astralblock = { "astralblock", CURSETYP_NORM, 0, NO_MERGE, cinfo_simple }; /* Unterhaltungsanteil vermehren */ -static struct curse_type ct_generous = { +const struct curse_type ct_generous = { "generous", CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR | M_MAXEFFECT), cinfo_simple }; /* verhindert Attackiere regional */ -static struct curse_type ct_peacezone = { +const struct curse_type ct_peacezone = { "peacezone", CURSETYP_NORM, 0, NO_MERGE, cinfo_simple @@ -261,7 +261,7 @@ static struct curse_type ct_peacezone = { /* erniedigt Magieresistenz von nicht-aliierten Einheiten, wirkt nur 1x * pro Einheit */ -static struct curse_type ct_badmagicresistancezone = { +const struct curse_type ct_badmagicresistancezone = { "badmagicresistancezone", CURSETYP_NORM, 0, NO_MERGE, cinfo_simple @@ -269,25 +269,25 @@ static struct curse_type ct_badmagicresistancezone = { /* erhöht Magieresistenz von aliierten Einheiten, wirkt nur 1x pro * Einheit */ -static struct curse_type ct_goodmagicresistancezone = { +const struct curse_type ct_goodmagicresistancezone = { "goodmagicresistancezone", CURSETYP_NORM, 0, NO_MERGE, cinfo_simple }; -static struct curse_type ct_riotzone = { +const struct curse_type ct_riotzone = { "riotzone", CURSETYP_NORM, 0, (M_DURATION), cinfo_simple }; -static struct curse_type ct_holyground = { +const struct curse_type ct_holyground = { "holyground", CURSETYP_NORM, CURSE_NOAGE, (M_VIGOUR_ADD), cinfo_simple }; -static struct curse_type ct_healing = { +const struct curse_type ct_healing = { "healingzone", CURSETYP_NORM, 0, (M_VIGOUR | M_DURATION), cinfo_simple diff --git a/src/spells/regioncurse.h b/src/spells/regioncurse.h index a1ee182c1..467c1fb57 100644 --- a/src/spells/regioncurse.h +++ b/src/spells/regioncurse.h @@ -18,6 +18,26 @@ extern "C" { #endif struct region; + struct curse_type; + + extern const struct curse_type ct_peacezone; + extern const struct curse_type ct_drought; + extern const struct curse_type ct_blessedharvest; + extern const struct curse_type ct_godcursezone; + extern const struct curse_type ct_gbdream; + extern const struct curse_type ct_healing; + extern const struct curse_type ct_antimagiczone; + extern const struct curse_type ct_depression; + extern const struct curse_type ct_astralblock; + extern const struct curse_type ct_badmagicresistancezone; + extern const struct curse_type ct_goodmagicresistancezone; + extern const struct curse_type ct_holyground; + extern const struct curse_type ct_fogtrap; + extern const struct curse_type ct_magicstreet; + extern const struct curse_type ct_maelstrom; + extern const struct curse_type ct_riotzone; + extern const struct curse_type ct_generous; + extern const struct curse_type ct_badlearn; int harvest_effect(const struct region *r); void register_regioncurse(void); diff --git a/src/spells/shipcurse.c b/src/spells/shipcurse.c index 0295695a1..180c84eea 100644 --- a/src/spells/shipcurse.c +++ b/src/spells/shipcurse.c @@ -72,11 +72,11 @@ static message *cinfo_shipnodrift(const void *obj, objtype_t typ, const curse * return msg_message("curseinfo::shipnodrift_0", "ship id", sh, c->no); } -static struct curse_type ct_stormwind = { "stormwind", -CURSETYP_NORM, CURSE_NOAGE, NO_MERGE, cinfo_ship +const struct curse_type ct_stormwind = { "stormwind", +CURSETYP_NORM, 0, NO_MERGE, cinfo_ship }; -static struct curse_type ct_nodrift = { "nodrift", +const struct curse_type ct_nodrift = { "nodrift", CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), cinfo_shipnodrift }; diff --git a/src/spells/shipcurse.h b/src/spells/shipcurse.h index a41f9edee..8bb98bcbe 100644 --- a/src/spells/shipcurse.h +++ b/src/spells/shipcurse.h @@ -21,8 +21,11 @@ extern "C" { struct message; struct curse; + struct curse_type; extern const struct curse_type ct_shipspeedup; + extern const struct curse_type ct_stormwind; + extern const struct curse_type ct_nodrift; struct message *cinfo_ship(const void *obj, objtype_t typ, const struct curse *c, int self); diff --git a/src/spells/unitcurse.c b/src/spells/unitcurse.c index 0a19629f1..4f8d69f64 100644 --- a/src/spells/unitcurse.c +++ b/src/spells/unitcurse.c @@ -60,14 +60,14 @@ static message *cinfo_auraboost(const void *obj, objtype_t typ, const curse * c, return NULL; } -static struct curse_type ct_auraboost = { +const struct curse_type ct_auraboost = { "auraboost", CURSETYP_NORM, CURSE_SPREADMODULO, (NO_MERGE), cinfo_auraboost }; /* Magic Boost - Gabe des Chaos */ -static struct curse_type ct_magicboost = { +const struct curse_type ct_magicboost = { "magicboost", CURSETYP_UNIT, CURSE_SPREADMODULO | CURSE_IMMUNE, M_MEN, cinfo_simple }; @@ -92,7 +92,7 @@ static message *cinfo_slave(const void *obj, objtype_t typ, const curse * c, return NULL; } -static struct curse_type ct_slavery = { "slavery", +const struct curse_type ct_slavery = { "slavery", CURSETYP_NORM, 0, NO_MERGE, cinfo_slave }; @@ -120,7 +120,7 @@ static message *cinfo_calm(const void *obj, objtype_t typ, const curse * c, return NULL; } -static struct curse_type ct_calmmonster = { +const struct curse_type ct_calmmonster = { "calmmonster", CURSETYP_NORM, CURSE_SPREADNEVER | CURSE_ONLYONE, NO_MERGE, cinfo_calm @@ -144,7 +144,7 @@ static message *cinfo_speed(const void *obj, objtype_t typ, const curse * c, return NULL; } -static struct curse_type ct_speed = { +const struct curse_type ct_speed = { "speed", CURSETYP_UNIT, CURSE_SPREADNEVER, M_MEN, cinfo_speed @@ -168,7 +168,7 @@ message *cinfo_unit(const void *obj, objtype_t typ, const curse * c, int self) return NULL; } -static struct curse_type ct_orcish = { +const struct curse_type ct_orcish = { "orcish", CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN, cinfo_unit @@ -192,7 +192,7 @@ static message *cinfo_kaelteschutz(const void *obj, objtype_t typ, const curse * return NULL; } -static struct curse_type ct_insectfur = { +const struct curse_type ct_insectfur = { "insectfur", CURSETYP_UNIT, CURSE_SPREADMODULO, (M_MEN | M_DURATION), cinfo_kaelteschutz @@ -259,7 +259,7 @@ static message *cinfo_sparkle(const void *obj, objtype_t typ, const curse * c, } } -static struct curse_type ct_sparkle = { "sparkle", +const struct curse_type ct_sparkle = { "sparkle", CURSETYP_UNIT, CURSE_SPREADMODULO, (M_MEN | M_DURATION), cinfo_sparkle }; @@ -275,7 +275,7 @@ CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN, cinfo_simple /* * C_ALLSKILLS (Alp) */ -static struct curse_type ct_worse = { +const struct curse_type ct_worse = { "worse", CURSETYP_UNIT, CURSE_SPREADMODULO | CURSE_NOAGE, M_MEN, cinfo_unit }; @@ -284,20 +284,20 @@ static struct curse_type ct_worse = { /* * C_ITEMCLOAK */ -static struct curse_type ct_itemcloak = { +const struct curse_type ct_itemcloak = { "itemcloak", CURSETYP_UNIT, CURSE_SPREADNEVER, M_DURATION, cinfo_unit }; /* ------------------------------------------------------------- */ -static struct curse_type ct_fumble = { +const struct curse_type ct_fumble = { "fumble", CURSETYP_NORM, CURSE_SPREADNEVER | CURSE_ONLYONE, NO_MERGE, cinfo_unit }; /* ------------------------------------------------------------- */ -static struct curse_type ct_oldrace = { +const struct curse_type ct_oldrace = { "oldrace", CURSETYP_NORM, CURSE_SPREADALWAYS, NO_MERGE, NULL }; @@ -339,7 +339,7 @@ static message *cinfo_skillmod(const void *obj, objtype_t typ, const curse * c, return NULL; } -static struct curse_type ct_skillmod = { +const struct curse_type ct_skillmod = { "skillmod", CURSETYP_NORM, CURSE_SPREADMODULO, M_MEN, cinfo_skillmod, NULL, read_skill, write_skill }; diff --git a/src/spells/unitcurse.h b/src/spells/unitcurse.h index 15d535cab..681fa32de 100644 --- a/src/spells/unitcurse.h +++ b/src/spells/unitcurse.h @@ -20,8 +20,24 @@ extern "C" { #endif struct curse; + struct curse_type; struct message; - extern struct message *cinfo_unit(const void *obj, objtype_t typ, + + extern const struct curse_type ct_slavery; + extern const struct curse_type ct_calmmonster; + extern const struct curse_type ct_speed; + extern const struct curse_type ct_worse; + extern const struct curse_type ct_skillmod; + extern const struct curse_type ct_oldrace; + extern const struct curse_type ct_fumble; + extern const struct curse_type ct_orcish; + extern const struct curse_type ct_itemcloak; + extern const struct curse_type ct_insectfur; + extern const struct curse_type ct_sparkle; + extern const struct curse_type ct_magicboost; + extern const struct curse_type ct_auraboost; + + struct message *cinfo_unit(const void *obj, objtype_t typ, const struct curse *c, int self); extern void register_unitcurse(void); diff --git a/src/study.c b/src/study.c index 85ff0b436..ea71b9376 100644 --- a/src/study.c +++ b/src/study.c @@ -28,6 +28,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "alchemy.h" #include "academy.h" +#include + #include #include #include @@ -52,6 +54,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include + #include /* libc includes */ @@ -285,13 +288,11 @@ int teach_cmd(unit * teacher, struct order *ord) skill_t sk_academy = NOSKILL; int teaching, i, j, count, academy = 0; - if (teacher->region->attribs) { - const curse_type *gbdream_ct = ct_find("gbdream"); - if (gbdream_ct) { - if (get_curse(teacher->region->attribs, gbdream_ct)) { - ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "gbdream_noteach", "")); - return 0; - } + if (r->attribs) { + if (get_curse(r->attribs, &ct_gbdream)) { + ADDMSG(&teacher->faction->msgs, + msg_feedback(teacher, ord, "gbdream_noteach", "")); + return 0; } } if ((u_race(teacher)->flags & RCF_NOTEACH) || fval(teacher, UFL_WERE)) { @@ -768,7 +769,7 @@ int study_cmd(unit * u, order * ord) teach->value += u->number * EXPERIENCEDAYS; } - if (is_cursed(r->attribs, C_BADLEARN, 0)) { + if (is_cursed(r->attribs, &ct_badlearn)) { teach->value -= u->number * EXPERIENCEDAYS; }