Merge pull request #465 from eressea/feature/issue-464-stonecircles

fix crash when aging stone circles without an astral plane
This commit is contained in:
Enno Rehling 2016-01-31 14:20:16 +01:00
commit cebea47720
2 changed files with 54 additions and 53 deletions

View file

@ -3019,74 +3019,75 @@ int renumber_cmd(unit * u, order * ord)
return 0; return 0;
} }
static building *age_building(building * b) /* blesses stone circles create an astral protection in the astral region
{ * above the shield, which prevents chaos suction and other spells.
const struct building_type *bt_blessed; * The shield is created when a magician enters the blessed stone circle,
const struct curse_type *ct_astralblock; * and lasts for as long as his skill level / 2 is, at no mana cost.
*
* TODO: this would be nicer in a btype->age function, but we don't have it.
*/
static void age_stonecircle(building *b) {
const struct resource_type *rtype = get_resourcetype(R_UNICORN); const struct resource_type *rtype = get_resourcetype(R_UNICORN);
region *r = b->region;
unit *u, *mage = NULL;
bt_blessed = bt_find("blessedstonecircle"); /* step 1: give unicorns to people in the building,
ct_astralblock = ct_find("astralblock"); * find out if there's a magician in there. */
for (u = r->units; u; u = u->next) {
/* blesses stone circles create an astral protection in the astral region if (b == u->building && inside_building(u)) {
* above the shield, which prevents chaos suction and other spells. if (!mage && is_mage(u)) {
* The shield is created when a magician enters the blessed stone circle, mage = u;
* and lasts for as long as his skill level / 2 is, at no mana cost. }
* if (rtype && (u_race(u)->ec_flags & ECF_KEEP_ITEM) == 0) {
* TODO: this would be nicer in a btype->age function, but we don't have it. int n, unicorns = 0;
*/ for (n = 0; n != u->number; ++n) {
if (rtype && ct_astralblock && bt_blessed && b->type == bt_blessed) { if (chance(0.02)) {
region *r = b->region; i_change(&u->items, rtype->itype, 1);
region *rt = r_standard_to_astral(r); ++unicorns;
unit *u, *mage = NULL; }
if (unicorns) {
/* step 1: give unicorns to people in the building, ADDMSG(&u->faction->msgs, msg_message("scunicorn",
* find out if there's a magician in there. */ "unit amount rtype",
for (u = r->units; u; u = u->next) { u, unicorns, rtype));
if (b == u->building && inside_building(u)) {
if ((u_race(u)->ec_flags & ECF_KEEP_ITEM) == 0) {
int n, unicorns = 0;
for (n = 0; n != u->number; ++n) {
if (chance(0.02)) {
i_change(&u->items, rtype->itype, 1);
++unicorns;
}
if (unicorns) {
ADDMSG(&u->faction->msgs, msg_message("scunicorn",
"unit amount rtype",
u, unicorns, rtype));
}
} }
}
if (mage == NULL && is_mage(u)) {
mage = u;
} }
} }
} }
}
/* if there's a magician, and a connection to astral space, create the /* step 2: if there's a magician, and a connection to astral space, create the
* curse. */ * curse. */
if (rt && !fval(rt->terrain, FORBIDDEN_REGION) && mage != NULL) { 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 == NULL) { if (!c) {
if (mage != NULL) { int sk = effskill(mage, SK_MAGIC, 0);
int sk = effskill(mage, SK_MAGIC, 0); float effect = 100;
float effect = 100; /* the mage reactivates the circle */
/* 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);
(float)_max(1, sk), _max(1, sk / 2), effect, 0); ADDMSG(&r->msgs,
ADDMSG(&r->msgs, msg_message("astralshield_activate", "region unit", r, mage));
msg_message("astralshield_activate", "region unit", r, mage));
}
} }
else if (mage != NULL) { else {
int sk = effskill(mage, SK_MAGIC, 0); int sk = effskill(mage, SK_MAGIC, 0);
c->duration = _max(c->duration, sk / 2); c->duration = _max(c->duration, sk / 2);
c->vigour = _max(c->vigour, (float)sk); c->vigour = _max(c->vigour, (float)sk);
} }
} }
} }
}
static building *age_building(building * b)
{
const struct building_type *bt_blessed;
bt_blessed = bt_find("blessedstonecircle");
if (bt_blessed && b->type == bt_blessed) {
age_stonecircle(b);
}
a_age(&b->attribs, b); a_age(&b->attribs, b);
handle_event(b->attribs, "timer", b); handle_event(b->attribs, "timer", b);

View file

@ -96,7 +96,7 @@ region_list *astralregions(const region * r, bool(*valid) (const region *))
region *r_standard_to_astral(const region * r) region *r_standard_to_astral(const region * r)
{ {
assert(!rplane(r)); assert(!is_astral(r));
return tpregion(r); return tpregion(r);
} }