diff --git a/src/economy.c b/src/economy.c index acccca8f1..c6e0d360a 100644 --- a/src/economy.c +++ b/src/economy.c @@ -1101,7 +1101,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) for (; mod->flags != 0; ++mod) { if (mod->flags & RMF_REQUIREDBUILDING) { struct building *b = inside_building(u); - const struct building_type *btype = b ? b->type : NULL; + const struct building_type *btype = building_is_active(b) ? b->type : NULL; if (mod->btype && mod->btype != btype) { cmistake(u, u->thisorder, 104, MSG_PRODUCE); return; @@ -1157,7 +1157,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) } else { struct building *b = inside_building(u); - const struct building_type *btype = b ? b->type : NULL; + const struct building_type *btype = building_is_active(b) ? b->type : NULL; if (rdata->modifiers) { resource_mod *mod = rdata->modifiers; @@ -1213,7 +1213,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want) if (rdata->modifiers) { struct building *b = inside_building(u); - const struct building_type *btype = b ? b->type : NULL; + const struct building_type *btype = building_is_active(b) ? b->type : NULL; resource_mod *mod = rdata->modifiers; for (; mod->flags != 0; ++mod) { @@ -2422,7 +2422,7 @@ static void breedhorses(unit * u) { int n, c, breed = 0; struct building *b = inside_building(u); - const struct building_type *btype = b ? b->type : NULL; + const struct building_type *btype = building_is_active(b) ? b->type : NULL; const struct resource_type *rhorse = get_resourcetype(R_HORSE); int horses, effsk; diff --git a/src/kernel/build.c b/src/kernel/build.c index 924dccf49..e38d76641 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -448,8 +448,9 @@ int build(unit * u, const construction * ctype, int completed, int want) return EBUILDINGREQ; } b = inside_building(u); - if (b == NULL) + if (!b || !building_is_active(b)) { return EBUILDINGREQ; + } } if (type->skill != NOSKILL) { @@ -462,7 +463,7 @@ int build(unit * u, const construction * ctype, int completed, int want) return ENEEDSKILL; effsk = basesk; - if (inside_building(u)) { + if (building_is_active(u->building) && inside_building(u)) { effsk = skillmod(u->building->type->attribs, u, u->region, type->skill, effsk, SMF_PRODUCTION); } @@ -558,7 +559,7 @@ int build(unit * u, const construction * ctype, int completed, int want) int need, prebuilt; int canuse = get_pooled(u, rtype, GET_DEFAULT, INT_MAX); - if (inside_building(u)) { + if (building_is_active(u->building) && inside_building(u)) { canuse = matmod(u->building->type->attribs, u, rtype, canuse); } @@ -597,8 +598,9 @@ int build(unit * u, const construction * ctype, int completed, int want) required(completed + n, type->reqsize, type->materials[c].number); int multi = 1; int canuse = 100; /* normalization */ - if (inside_building(u)) + if (building_is_active(u->building) && inside_building(u)) { canuse = matmod(u->building->type->attribs, u, rtype, canuse); + } if (canuse < 0) return canuse; /* pass errors to caller */ canuse = matmod(type->attribs, u, rtype, canuse); diff --git a/src/kernel/building.c b/src/kernel/building.c index da4f58867..d63ada88e 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -642,6 +642,10 @@ region *building_getregion(const building * b) return b->region; } +bool building_is_active(const struct building *b) { + return b && fval(b, BLD_WORKING); +} + void building_setregion(building * b, region * r) { building **blist = &b->region->buildings; diff --git a/src/kernel/building.h b/src/kernel/building.h index b4bb23efa..c0796b352 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -78,6 +78,7 @@ extern "C" { } building_type; extern struct quicklist *buildingtypes; + extern struct attrib_type at_building_action; building_type *bt_get_or_create(const char *name); const building_type *bt_find(const char *name); @@ -163,7 +164,7 @@ extern "C" { extern void building_set_owner(struct unit * u); extern void building_update_owner(struct building * bld); - extern struct attrib_type at_building_action; + bool building_is_active(const struct building *b); #ifdef WDW_PYRAMID extern int wdw_pyramid_level(const struct building *b); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 5e9b39705..23919eeac 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1072,11 +1072,7 @@ void transfermen(unit * u, unit * dst, int n) struct building *inside_building(const struct unit *u) { - if (u->building == NULL) - return NULL; - - if (!fval(u->building, BLD_WORKING)) { - /* Unterhalt nicht bezahlt */ + if (!u->building || !building_is_active(u->building)) { return NULL; } else if (u->building->size < u->building->type->maxsize) { diff --git a/src/kernel/unit.h b/src/kernel/unit.h index 606bccbcf..89fb90d9b 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -183,36 +183,36 @@ extern "C" { void make_zombie(unit * u); /* see resolve.h */ - extern int resolve_unit(variant data, void *address); - extern void write_unit_reference(const struct unit *u, struct storage *store); - extern variant read_unit_reference(struct storage *store); + int resolve_unit(variant data, void *address); + void write_unit_reference(const struct unit *u, struct storage *store); + variant read_unit_reference(struct storage *store); - extern bool leave(struct unit *u, bool force); - extern bool can_leave(struct unit *u); + bool leave(struct unit *u, bool force); + bool can_leave(struct unit *u); - extern void u_set_building(struct unit * u, struct building * b); - extern void u_set_ship(struct unit * u, struct ship * sh); - extern void leave_ship(struct unit * u); - extern void leave_building(struct unit * u); + void u_set_building(struct unit * u, struct building * b); + void u_set_ship(struct unit * u, struct ship * sh); + void leave_ship(struct unit * u); + void leave_building(struct unit * u); - extern void set_leftship(struct unit *u, struct ship *sh); - extern struct ship *leftship(const struct unit *); - extern bool can_survive(const struct unit *u, const struct region *r); - extern void move_unit(struct unit *u, struct region *target, - struct unit **ulist); + void set_leftship(struct unit *u, struct ship *sh); + struct ship *leftship(const struct unit *); + bool can_survive(const struct unit *u, const struct region *r); + void move_unit(struct unit *u, struct region *target, + struct unit **ulist); - extern struct building *inside_building(const struct unit *u); + struct building *inside_building(const struct unit *u); /* cleanup code for this module */ - extern void free_units(void); - extern struct faction *dfindhash(int no); - extern void u_setfaction(struct unit *u, struct faction *f); - extern void set_number(struct unit *u, int count); + void free_units(void); + struct faction *dfindhash(int no); + void u_setfaction(struct unit *u, struct faction *f); + void set_number(struct unit *u, int count); - extern bool learn_skill(struct unit *u, skill_t sk, double chance); + bool learn_skill(struct unit *u, skill_t sk, double chance); - extern int invisible(const struct unit *target, const struct unit *viewer); - extern void free_unit(struct unit *u); + int invisible(const struct unit *target, const struct unit *viewer); + void free_unit(struct unit *u); extern void name_unit(struct unit *u); extern struct unit *create_unit(struct region *r1, struct faction *f, diff --git a/src/laws.c b/src/laws.c index d3cdcaba4..3b4cc6fca 100755 --- a/src/laws.c +++ b/src/laws.c @@ -3545,7 +3545,7 @@ void monthly_healing(void) double maxheal = _max(u->number, umhp / 20.0); int addhp; struct building *b = inside_building(u); - const struct building_type *btype = b ? b->type : NULL; + const struct building_type *btype = building_is_active(b) ? b->type : NULL; if (btype == bt_find("inn")) { p *= 1.5; } diff --git a/src/magic.c b/src/magic.c index 52d85f435..e0a5ca921 100644 --- a/src/magic.c +++ b/src/magic.c @@ -1025,7 +1025,7 @@ spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order else { /* Bonus durch Magieturm und gesegneten Steinkreis */ struct building *b = inside_building(u); - const struct building_type *btype = b ? b->type : NULL; + const struct building_type *btype = building_is_active(b) ? b->type : NULL; if (btype && btype->flags & BTF_MAGIC) ++force; } @@ -1170,7 +1170,7 @@ double magic_resistance(unit * target) /* Bonus durch Gebäude */ { struct building *b = inside_building(target); - const struct building_type *btype = b ? b->type : NULL; + const struct building_type *btype = building_is_active(b) ? b->type : NULL; /* gesegneter Steinkreis gibt 30% dazu */ if (btype) @@ -1284,7 +1284,7 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade) int fumble_chance, rnd = 0; int effsk = effskill(u, SK_MAGIC, r); struct building *b = inside_building(u); - const struct building_type *btype = b ? b->type : NULL; + const struct building_type *btype = building_is_active(b) ? b->type : NULL; int fumble_enabled = get_param_int(global.parameters, "magic.fumble.enable", 1); sc_mage * mage; @@ -1468,7 +1468,7 @@ void regenerate_aura(void) auramax = max_spellpoints(r, u); if (aura < auramax) { struct building *b = inside_building(u); - const struct building_type *btype = b ? b->type : NULL; + const struct building_type *btype = building_is_active(b) ? b->type : NULL; reg_aura = regeneration(u); /* Magierturm erhöht die Regeneration um 75% */ diff --git a/src/study.c b/src/study.c index 5edba9168..b798277ca 100644 --- a/src/study.c +++ b/src/study.c @@ -175,6 +175,13 @@ static int study_days(unit * student, skill_t sk) return student->number * speed; } +static building *active_building(const unit *u, const struct building_type *btype) { + if (u->building && u->building->type == btype && building_is_active(u->building)) { + return inside_building(u); + } + return 0; +} + static int teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk, bool report, int *academy) @@ -205,8 +212,7 @@ bool report, int *academy) n = _min(n, nteaching); if (n != 0) { - struct building *b = inside_building(teacher); - const struct building_type *btype = b ? b->type : NULL; + const struct building_type *btype = bt_find("academy"); int index = 0; if (teach == NULL) { @@ -229,8 +235,7 @@ bool report, int *academy) /* Solange Akademien groessenbeschraenkt sind, sollte Lehrer und * Student auch in unterschiedlichen Gebaeuden stehen duerfen */ - if (btype == bt_find("academy") - && student->building && student->building->type == bt_find("academy")) { + if (active_building(teacher, btype) && active_building(student, btype)) { int j = study_cost(student, sk); j = _max(50, j * 2); /* kann Einheit das zahlen? */ @@ -542,7 +547,7 @@ int study_cmd(unit * u, order * ord) int speed_rule = (study_rule_t)get_param_int(global.parameters, "study.speedup", 0); static int learn_newskills = -1; struct building *b = inside_building(u); - const struct building_type *btype = b ? b->type : NULL; + const struct building_type *btype = building_is_active(b) ? b->type : NULL; if (learn_newskills < 0) { const char *str = get_param(global.parameters, "study.newskills"); @@ -606,7 +611,7 @@ int study_cmd(unit * u, order * ord) } /* Akademie: */ b = inside_building(u); - btype = b ? b->type : NULL; + btype = building_is_active(b) ? b->type : NULL; if (btype && btype == bt_find("academy")) { studycost = _max(50, studycost * 2);