diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c
index 16b0b39c9..b8de0baaf 100644
--- a/src/common/gamecode/creport.c
+++ b/src/common/gamecode/creport.c
@@ -766,10 +766,12 @@ cr_output_unit(FILE * F, const region * r,
add_translation(zRace, locale_string(f->locale, zRace)));
}
} else {
- const char * zRace = rc_name(u->irace, 1);
+ const race * irace = u_irace(u);
+ const char * zRace = rc_name(irace, 1);
fprintf(F, "\"%s\";Typ\n",
add_translation(zRace, locale_string(f->locale, zRace)));
- if (u->faction==f && u->irace!=u->race) {
+ if (u->faction==f && irace!=u->race) {
+ assert(skill_enabled[SK_STEALTH] || !"we're resetting this on load, so.. ircase should never be used");
zRace = rc_name(u->race, 1);
fprintf(F, "\"%s\";wahrerTyp\n",
add_translation(zRace, locale_string(f->locale, zRace)));
diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c
index 99591c283..e690c3dad 100644
--- a/src/common/gamecode/laws.c
+++ b/src/common/gamecode/laws.c
@@ -268,14 +268,12 @@ get_food(region *r)
if (food_rules&2) {
/* the owner of the region is the first faction to help out when you're hungry */
- if (r->land->ownership) {
- faction * owner = r->land->ownership->owner;
- if (owner && owner!=u->faction) {
- for (v=r->units;v;v=v->next) {
- if (v->faction==owner && alliedunit(v, f, HELP_MONEY) && help_money(v)) {
- help_feed(v, u, &need);
- break;
- }
+ faction * owner = region_get_owner(r);
+ if (owner && owner!=u->faction) {
+ for (v=r->units;v;v=v->next) {
+ if (v->faction==owner && alliedunit(v, f, HELP_MONEY) && help_money(v)) {
+ help_feed(v, u, &need);
+ break;
}
}
}
@@ -3048,7 +3046,7 @@ ageing(void)
curse *c = get_curse(u->attribs, ct_find("oldrace"));
if (c->duration == 1 && !(c_flags(c) & CURSE_NOAGE)) {
u->race = new_race[curse_geteffect(c)];
- u->irace = new_race[curse_geteffect(c)];
+ u->irace = NULL;
}
}
}
diff --git a/src/common/gamecode/randenc.c b/src/common/gamecode/randenc.c
index af0c91dbc..143c8a3dd 100644
--- a/src/common/gamecode/randenc.c
+++ b/src/common/gamecode/randenc.c
@@ -344,8 +344,8 @@ get_allies(region * r, unit * u)
u_setfaction(newunit, u->faction);
set_racename(&newunit->attribs, get_racename(u->attribs));
- if(u->race->flags & RCF_SHAPESHIFT) {
- newunit->irace = u->irace;
+ if (u->race->flags & RCF_SHAPESHIFT) {
+ newunit->irace = u->irace;
}
if (fval(u, UFL_PARTEITARNUNG)) fset(newunit, UFL_PARTEITARNUNG);
fset(newunit, UFL_ISNEW);
diff --git a/src/common/kernel/border.c b/src/common/kernel/border.c
index f4d5eb371..487f3b4b9 100644
--- a/src/common/kernel/border.c
+++ b/src/common/kernel/border.c
@@ -82,15 +82,16 @@ find_border(unsigned int id)
int
resolve_borderid(variant id, void * addr)
{
+ int result = 0;
border * b = NULL;
if (id.i!=0) {
b = find_border(id.i);
if (b==NULL) {
- return -1;
+ result = -1;
}
}
*(border**)addr = b;
- return 0;
+ return result;
}
static border **
diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c
index 8962fa6d8..b25827b23 100644
--- a/src/common/kernel/building.c
+++ b/src/common/kernel/building.c
@@ -427,15 +427,16 @@ write_building_reference(const struct building * b, struct storage * store)
int
resolve_building(variant id, void * address)
{
+ int result = 0;
building * b = NULL;
if (id.i!=0) {
b = findbuilding(id.i);
if (b==NULL) {
- return -1;
+ result = -1;
}
}
*(building**)address = b;
- return 0;
+ return result;
}
variant
diff --git a/src/common/kernel/curse.c b/src/common/kernel/curse.c
index bb275183e..a09cc5d18 100644
--- a/src/common/kernel/curse.c
+++ b/src/common/kernel/curse.c
@@ -714,15 +714,16 @@ is_cursed_with(const attrib *ap, const curse *c)
int
resolve_curse(variant id, void * address)
{
+ int result = 0;
curse * c = NULL;
if (id.i!=0) {
c = cfindhash(id.i);
if (c==NULL) {
- return -1;
+ result = -1;
}
}
*(curse**)address = c;
- return 0;
+ return result;
}
static const char * oldnames[MAXCURSE] = {
diff --git a/src/common/kernel/faction.c b/src/common/kernel/faction.c
index f9a14b156..5df5bddef 100644
--- a/src/common/kernel/faction.c
+++ b/src/common/kernel/faction.c
@@ -151,15 +151,16 @@ factionname(const faction * f)
int
resolve_faction(variant id, void * address) {
+ int result = 0;
faction * f = NULL;
if (id.i!=0) {
f = findfaction(id.i);
if (f==NULL) {
- return -1;
+ result = -1;
}
}
*(faction**)address = f;
- return 0;
+ return result;
}
#define MAX_FACTION_ID (36*36*36*36)
diff --git a/src/common/kernel/item.c b/src/common/kernel/item.c
index 7b064980a..31e68f7c4 100644
--- a/src/common/kernel/item.c
+++ b/src/common/kernel/item.c
@@ -861,19 +861,23 @@ use_bloodpotion(struct unit *u, const struct item_type *itype, int amount, struc
{
if (u->race == new_race[RC_DAEMON]) {
change_effect(u, itype->rtype->ptype, 100*amount);
- } else if (u->irace == u->race) {
- static race * rcfailure;
- if (!rcfailure) {
- rcfailure = rc_find("smurf");
- if (!rcfailure) rcfailure = rc_find("toad");
- }
- if (rcfailure) {
- trigger * trestore = trigger_changerace(u, u->race, u->irace);
- if (trestore) {
- int duration = 2 + rng_int() % 8;
+ } else {
+ const race * irace = u_irace(u);
+ if (irace == u->race) {
+ static race * rcfailure;
+ if (!rcfailure) {
+ rcfailure = rc_find("smurf");
+ if (!rcfailure) rcfailure = rc_find("toad");
+ }
+ if (rcfailure) {
+ trigger * trestore = trigger_changerace(u, u->race, irace);
+ if (trestore) {
+ int duration = 2 + rng_int() % 8;
- add_trigger(&u->attribs, "timer", trigger_timeout(duration, trestore));
- u->irace = u->race = rcfailure;
+ add_trigger(&u->attribs, "timer", trigger_timeout(duration, trestore));
+ u->irace = NULL;
+ u->race = rcfailure;
+ }
}
}
}
diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c
index 5ab2b7b15..b329fdb5d 100644
--- a/src/common/kernel/magic.c
+++ b/src/common/kernel/magic.c
@@ -1400,7 +1400,7 @@ do_fumble(castorder *co)
case 1:
/* Kröte */
- if (u->irace == u->race) {
+ {
/* one or two things will happen: the toad changes her race back,
* and may or may not get toadslime.
* The list of things to happen are attached to a timeout
@@ -1419,7 +1419,7 @@ do_fumble(castorder *co)
if (duration<2) duration = 2;
add_trigger(&u->attribs, "timer", trigger_timeout(duration, trestore));
u->race = new_race[RC_TOAD];
- u->irace = new_race[RC_TOAD];
+ u->irace = NULL;
ADDMSG(&r->msgs, msg_message("patzer6", "unit region spell",
u, r, sp));
break;
@@ -2294,8 +2294,8 @@ resolve_familiar(variant data, void * addr)
unit * mage = (unit *)a->data.v;
set_familiar(mage, familiar);
}
- *(unit**)addr = familiar;
}
+ *(unit**)addr = familiar;
return result;
}
@@ -2373,8 +2373,8 @@ resolve_clone(variant data, void * addr)
unit * mage = (unit *)a->data.v;
set_clone(mage, clone);
}
- *(unit**)addr = clone;
}
+ *(unit**)addr = clone;
return result;
}
@@ -2401,8 +2401,8 @@ resolve_mage(variant data, void * addr)
unit * familiar = (unit *)a->data.v;
set_familiar(mage, familiar);
}
- *(unit **)addr = mage;
}
+ *(unit **)addr = mage;
return result;
}
diff --git a/src/common/kernel/plane.c b/src/common/kernel/plane.c
index 1fa75e0d5..c2ec54337 100644
--- a/src/common/kernel/plane.c
+++ b/src/common/kernel/plane.c
@@ -279,15 +279,16 @@ rel_to_abs(const struct plane *pl, const struct faction * f, int rel, unsigned c
int
resolve_plane(variant id, void * addr)
{
+ int result = 0;
plane * pl = NULL;
if (id.i!=0) {
pl = getplanebyid(id.i);
if (pl==NULL) {
- return -1;
+ result = -1;
}
}
*(plane**)addr = pl;
- return 0;
+ return result;
}
void
diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c
index ce8fd5101..f09406bbe 100644
--- a/src/common/kernel/region.c
+++ b/src/common/kernel/region.c
@@ -1370,6 +1370,7 @@ resolve_region_coor(variant id, void * address) {
*(region**)address = r;
return 0;
}
+ *(region**)address = NULL;
return -1;
}
@@ -1380,6 +1381,7 @@ resolve_region_id(variant id, void * address)
if (id.i!=0) {
r = findregionbyid((unsigned int)id.i);
if (r==NULL) {
+ *(region**)address = NULL;
return -1;
}
}
diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c
index d89c925f8..a9660dea4 100644
--- a/src/common/kernel/reports.c
+++ b/src/common/kernel/reports.c
@@ -302,8 +302,9 @@ void
report_race(const struct unit * u, const char ** name, const char ** illusion)
{
if (illusion) {
- if (u->irace && u->irace!=u->race) {
- *illusion = u->irace->_name[0];
+ const race * irace = u_irace(u);
+ if (irace!=u->race) {
+ *illusion = irace->_name[0];
}
else {
*illusion = NULL;
@@ -533,9 +534,10 @@ bufunit(const faction * f, const unit * u, int indent, int mode, char * buf, siz
}
}
} else {
- bytes = (int)strlcpy(bufp, racename(f->locale, u, u->irace), size);
+ const race * irace = u_irace(u);
+ bytes = (int)strlcpy(bufp, racename(f->locale, u, irace), size);
if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER();
- if (u->faction==f && u->irace!=u->race) {
+ if (u->faction==f && irace!=u->race) {
bytes = (int)strlcpy(bufp, " (", size);
if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER();
bytes = (int)strlcpy(bufp, racename(f->locale, u, u->race), size);
diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c
index e7027ac40..f983bd2c6 100644
--- a/src/common/kernel/save.c
+++ b/src/common/kernel/save.c
@@ -713,8 +713,8 @@ read_unit(struct storage * store)
} else {
store->r_tok_buf(store, rname, sizeof(rname));
}
- if (rname[0]) u->irace = rc_find(rname);
- else u->irace = u->race;
+ if (rname[0] && skill_enabled[SK_STEALTH]) u->irace = rc_find(rname);
+ else u->irace = NULL;
if (u->race->describe) {
const char * rcdisp = u->race->describe(u, u->faction->locale);
@@ -822,6 +822,7 @@ write_unit(struct storage * store, const unit * u)
{
order * ord;
int i, p = 0;
+ const race * irace = u_irace(u);
write_unit_reference(u, store);
write_faction_reference(u->faction, store);
store->w_str(store, (const char *)u->name);
@@ -829,7 +830,7 @@ write_unit(struct storage * store, const unit * u)
store->w_int(store, u->number);
store->w_int(store, u->age);
store->w_tok(store, u->race->_name[0]);
- store->w_tok(store, u->irace!=u->race?u->irace->_name[0]:"");
+ store->w_tok(store, irace!=u->race?u->irace->_name[0]:"");
write_building_reference(u->building, store);
write_ship_reference(u->ship, store);
store->w_int(store, u->status);
@@ -1536,9 +1537,17 @@ readgame(const char * filename, int mode, int backup)
update_interval(u->faction, u->region);
mage = get_mage(u);
- if (mage && mage->spellcount<0) {
- mage->spellcount = 0;
- updatespelllist(u);
+ if (mage) {
+ faction * f = u->faction;
+ if (!is_monsters(f) && f->magiegebiet==M_GRAY) {
+ log_error(("faction %s had magic=gray, fixing (%s)\n",
+ factionname(f), magic_school[mage->magietyp]));
+ f->magiegebiet = mage->magietyp;
+ }
+ if (mage->spellcount<0) {
+ mage->spellcount = 0;
+ updatespelllist(u);
+ }
}
}
}
diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c
index 7eb566630..2f84019dd 100644
--- a/src/common/kernel/unit.c
+++ b/src/common/kernel/unit.c
@@ -309,7 +309,8 @@ make_zombie(unit * u)
{
u_setfaction(u, get_monsters());
scale_number(u, 1);
- u->race = u->irace = new_race[RC_ZOMBIE];
+ u->race = new_race[RC_ZOMBIE];
+ u->irace = NULL;
}
/** remove the unit from the list of active units.
@@ -642,6 +643,7 @@ resolve_unit(variant id, void * address)
if (id.i!=0) {
u = findunit(id.i);
if (u==NULL) {
+ *(unit**)address = NULL;
return -1;
}
}
@@ -1451,7 +1453,7 @@ create_unit(region * r, faction * f, int number, const struct race *urace, int i
addlist(&u->orders, deford);
u_seteffstealth(u, -1);
u->race = urace;
- u->irace = urace;
+ u->irace = NULL;
set_number(u, number);
@@ -1728,3 +1730,11 @@ scale_number (unit * u, int n)
set_number(u, n);
}
+
+const struct race * u_irace(const struct unit * u)
+{
+ if (skill_enabled[SK_STEALTH]) {
+ return u->irace;
+ }
+ return u->race;
+}
\ No newline at end of file
diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h
index f2967b243..a51ac50e0 100644
--- a/src/common/kernel/unit.h
+++ b/src/common/kernel/unit.h
@@ -134,7 +134,7 @@ extern struct attrib_type at_stealth;
void u_seteffstealth(struct unit * u, int value);
int u_geteffstealth(const struct unit * u);
-
+const struct race * u_irace(const struct unit * u);
struct building * usiege(const struct unit * u);
void usetsiege(struct unit * u, const struct building * b);
diff --git a/src/common/modules/wormhole.c b/src/common/modules/wormhole.c
index 099a20a5d..779f91bb9 100644
--- a/src/common/modules/wormhole.c
+++ b/src/common/modules/wormhole.c
@@ -119,6 +119,7 @@ resolve_exit(variant id, void * address)
*rp = b->region;
return 0;
}
+ *rp = NULL;
return -1;
}
diff --git a/src/common/races/dragons.c b/src/common/races/dragons.c
index 39f4d1776..23d8874a0 100644
--- a/src/common/races/dragons.c
+++ b/src/common/races/dragons.c
@@ -34,7 +34,7 @@ age_firedragon(unit *u)
if (u->number>0 && rng_int()%100 < age_chance(u->age, DRAGONAGE, 1)) {
double q = (double) u->hp / (double) (unit_max_hp(u) * u->number);
u->race = new_race[RC_DRAGON];
- u->irace = new_race[RC_DRAGON];
+ u->irace = NULL;
scale_number(u,1);
u->hp = (int) (unit_max_hp(u) * u->number * q);
}
@@ -46,7 +46,7 @@ age_dragon(unit *u)
if (u->number>0 && rng_int()%100 < age_chance(u->age, WYRMAGE, 1)) {
double q = (double) u->hp / (double) (unit_max_hp(u) * u->number);
u->race = new_race[RC_WYRM];
- u->irace = new_race[RC_WYRM];
+ u->irace = NULL;
u->hp = (int) (unit_max_hp(u) * u->number * q);
}
}
diff --git a/src/common/races/zombies.c b/src/common/races/zombies.c
index f6d59f6cd..258bca5b2 100644
--- a/src/common/races/zombies.c
+++ b/src/common/races/zombies.c
@@ -64,7 +64,7 @@ age_skeleton(unit *u)
int n = MAX(1,u->number/2);
double q = (double) u->hp / (double) (unit_max_hp(u) * u->number);
u->race = new_race[RC_SKELETON_LORD];
- u->irace = new_race[RC_SKELETON_LORD];
+ u->irace = NULL;
scale_number(u,n);
u->hp = (int) (unit_max_hp(u) * u->number * q);
}
@@ -77,7 +77,7 @@ age_zombie(unit *u)
int n = MAX(1,u->number/2);
double q = (double) u->hp / (double) (unit_max_hp(u) * u->number);
u->race = new_race[RC_ZOMBIE_LORD];
- u->irace = new_race[RC_ZOMBIE_LORD];
+ u->irace = NULL;
scale_number(u,n);
u->hp = (int) (unit_max_hp(u) * u->number * q);
}
@@ -90,7 +90,7 @@ age_ghoul(unit *u)
int n = MAX(1,u->number/2);
double q = (double) u->hp / (double) (unit_max_hp(u) * u->number);
u->race = new_race[RC_GHOUL_LORD];
- u->irace = new_race[RC_GHOUL_LORD];
+ u->irace = NULL;
scale_number(u,n);
u->hp = (int) (unit_max_hp(u) * u->number * q);
}
diff --git a/src/common/spells/spells.c b/src/common/spells/spells.c
index f0156db49..66cfdc88c 100644
--- a/src/common/spells/spells.c
+++ b/src/common/spells/spells.c
@@ -2732,6 +2732,7 @@ resolve_buddy(variant data, void * addr)
} else {
/* fail, object does not exist (but if you're still loading then
* you may want to try again later) */
+ *(curse**)addr = NULL;
return -1;
}
}
@@ -3065,7 +3066,8 @@ sp_unholypower(castorder *co)
if (u->number <= n) {
n -= u->number;
- u->race = u->irace = target_race;
+ u->irace = NULL;
+ u->race = target_race;
u->hp = unit_max_hp(u)*u->number - wounds;
ADDMSG(&co->rt->msgs, msg_message("unholypower_effect",
"mage target race", mage, u, target_race));
@@ -4858,6 +4860,7 @@ sp_illusionary_shapeshift(castorder *co)
int cast_level = co->level;
double power = co->force;
spellparameter *pa = co->par;
+ const race * irace;
/* wenn kein Ziel gefunden, Zauber abbrechen */
if (pa->param[0]->flag == TARGET_NOTFOUND) return 0;
@@ -4879,8 +4882,9 @@ sp_illusionary_shapeshift(castorder *co)
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "sp_shapeshift_fail", "target race", u, rc));
return 0;
}
- if (u->irace == u->race) {
- trigger * trestore = trigger_changerace(u, NULL, u->irace);
+ irace = u_irace(u);
+ if (irace == u->race) {
+ trigger * trestore = trigger_changerace(u, NULL, irace);
add_trigger(&u->attribs, "timer", trigger_timeout((int)power+2, trestore));
u->irace = rc;
}
diff --git a/src/common/spells/unitcurse.c b/src/common/spells/unitcurse.c
index 799d37bad..5fcc611be 100644
--- a/src/common/spells/unitcurse.c
+++ b/src/common/spells/unitcurse.c
@@ -109,7 +109,7 @@ cinfo_calm(const void * obj, typ_t typ, const curse *c, int self)
unit *u = (unit *)obj;
if (f==NULL || self == 0) {
- const struct race * rc = c->magician->irace;
+ const struct race * rc = u_irace(c->magician);
return msg_message("curseinfo::calm_0", "unit race id", u, rc, c->no);
}
return msg_message("curseinfo::calm_1", "unit faction id", u, f, c->no);
diff --git a/src/common/triggers/changerace.c b/src/common/triggers/changerace.c
index f5875f435..37f12d55f 100644
--- a/src/common/triggers/changerace.c
+++ b/src/common/triggers/changerace.c
@@ -105,12 +105,13 @@ trigger_type tt_changerace = {
trigger *
trigger_changerace(struct unit * u, const struct race * prace, const struct race * irace)
{
- trigger * t = t_new(&tt_changerace);
- changerace_data * td = (changerace_data*)t->data.v;
+ const race * uirace = u_irace(u);
+ trigger * t = t_new(&tt_changerace);
+ changerace_data * td = (changerace_data*)t->data.v;
- assert(u->race==u->irace || "!changerace-triggers cannot stack!");
- td->u = u;
- td->race = prace;
- td->irace = irace;
- return t;
+ assert(u->race==uirace || "!changerace-triggers cannot stack!");
+ td->u = u;
+ td->race = prace;
+ td->irace = irace;
+ return t;
}
diff --git a/src/eressea/eressea-lua.vcproj b/src/eressea/eressea-lua.vcproj
index 41ac4a3ad..4f517a28e 100644
--- a/src/eressea/eressea-lua.vcproj
+++ b/src/eressea/eressea-lua.vcproj
@@ -390,13 +390,17 @@
>
+
+
diff --git a/src/eressea/korrektur.c b/src/eressea/korrektur.c
index 1c01406bb..15c7c2373 100644
--- a/src/eressea/korrektur.c
+++ b/src/eressea/korrektur.c
@@ -236,7 +236,7 @@ no_teurefremde(boolean convert)
log_warning(("Teurer Migrant: %s, Partei %s\n", unitname(u), factionname(f)));
if (convert) {
u->race = f->race;
- u->irace = f->race;
+ u->irace = NULL;
ADDMSG(&u->faction->msgs, msg_message("migrant_conversion", "unit", u));
}
}
diff --git a/src/eressea/tolua/bind_unit.c b/src/eressea/tolua/bind_unit.c
index ad5937e2d..616b6a21f 100644
--- a/src/eressea/tolua/bind_unit.c
+++ b/src/eressea/tolua/bind_unit.c
@@ -836,7 +836,7 @@ static int tolua_unit_set_race(lua_State* L)
race * rc = rc_find(rcname);
if (rc!=NULL) {
if (count_unit(self)) --self->faction->no_units;
- if (self->irace==self->race) self->irace = rc;
+ if (self->irace==self->race) self->irace = NULL;
self->race = rc;
if (count_unit(self)) --self->faction->no_units;
}