From fa55f84b414f28065d6bde0581c784f368ea0ef5 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 16 Dec 2015 13:32:02 +0100 Subject: [PATCH 1/9] remove unnecessary assert that prevents throwing away money on an ocean github issue #437 https://bugs.eressea.de/view.php?id=2173#c6411 --- src/kernel/item.c | 4 +++- src/kernel/region.c | 12 ++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/kernel/item.c b/src/kernel/item.c index aa975fb8e..e484e6c35 100644 --- a/src/kernel/item.c +++ b/src/kernel/item.c @@ -588,7 +588,9 @@ struct order *ord) use += use_pooled(s, item2resource(itype), GET_RESERVE | GET_POOLED_SLACK, n - use); - rsetmoney(s->region, rmoney(s->region) + use); + if (s->region->land) { + rsetmoney(s->region, rmoney(s->region) + use); + } return 0; } return -1; /* use the mechanism */ diff --git a/src/kernel/region.c b/src/kernel/region.c index aa4c86425..ed56851ee 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -603,8 +603,7 @@ void rsetpeasants(region * r, int value) if (r->land) { assert(value >= 0); r->land->peasants = value; - } else - assert(value == 0); + } } int rmoney(const region * r) @@ -617,8 +616,7 @@ void rsethorses(const region * r, int value) if (r->land) { assert(value >= 0); r->land->horses = value; - } else - assert(value == 0); + } } int rhorses(const region * r) @@ -631,8 +629,7 @@ void rsetmoney(region * r, int value) if (r->land) { assert(value >= 0); r->land->money = value; - } else - assert(value == 0); + } } int rherbs(const struct region *r) @@ -645,8 +642,7 @@ void rsetherbs(const struct region *r, int value) if (r->land) { assert(value >= 0); r->land->herbs = (short)(value); - } else - assert(value == 0); + } } From c66d6c7457427be56793e36703d1f6da63aa1b7b Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 16 Dec 2015 16:55:52 +0100 Subject: [PATCH 2/9] Address MS Visual Studio 2015 update 1 breaking changes --- src/bind_tolua.c | 1 + src/kernel/save.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bind_tolua.c b/src/bind_tolua.c index c6df54a10..9a5b8e184 100644 --- a/src/bind_tolua.c +++ b/src/bind_tolua.c @@ -8,6 +8,7 @@ #include "log.pkg.c" #include "process.pkg.c" #include "settings.pkg.c" +#pragma warning(pop) void tolua_bind_open(lua_State * L) { tolua_eressea_open(L); diff --git a/src/kernel/save.c b/src/kernel/save.c index 0fae07bb4..d4df2b6f8 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "save.h" -#include "../buildno.h" +#include #include "alchemy.h" #include "alliance.h" From fadccb5bd615d30667f7b7e72c1bc0f3f2891c2c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 16 Dec 2015 17:02:29 +0100 Subject: [PATCH 3/9] MS Visual Studio 2015 update 1 breaking changes (relative include files) --- src/triggers/shock.test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/triggers/shock.test.c b/src/triggers/shock.test.c index 8957c33fc..eae2a5004 100644 --- a/src/triggers/shock.test.c +++ b/src/triggers/shock.test.c @@ -1,7 +1,7 @@ #include #include "shock.h" -#include "../magic.h" +#include #include #include #include From 5187788f3cc2e044d4781ea7c130be5bbf00bea8 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 16 Dec 2015 22:18:44 +0100 Subject: [PATCH 4/9] pass the parent of an attribute into a_age and attrib_type::age --- src/alchemy.c | 3 ++- src/attributes/hate.c | 3 ++- src/attributes/moved.c | 3 ++- src/attributes/movement.c | 3 ++- src/attributes/reduceproduction.c | 17 ++++++++++++++--- src/building_action.c | 5 +++-- src/items/artrewards.c | 3 ++- src/kernel/curse.c | 3 ++- src/kernel/curse.h | 2 +- src/kernel/unit.c | 3 ++- src/kernel/unit.test.c | 6 +++--- src/laws.c | 10 +++++----- src/magic.c | 9 ++++++--- src/magic.h | 2 +- src/modules/arena.c | 3 ++- src/move.c | 3 ++- src/move.test.c | 4 ++-- src/spells.test.c | 6 +++--- src/spells/alp.c | 5 +++-- src/util/attrib.c | 4 ++-- src/util/attrib.h | 4 ++-- src/vortex.c | 7 ++++--- src/wormhole.c | 5 +++-- 23 files changed, 70 insertions(+), 43 deletions(-) diff --git a/src/alchemy.c b/src/alchemy.c index a1dd86c0a..3d37af6a7 100644 --- a/src/alchemy.c +++ b/src/alchemy.c @@ -238,9 +238,10 @@ static void free_potiondelay(attrib * a) free(a->data.v); } -static int age_potiondelay(attrib * a) +static int age_potiondelay(attrib * a, void *owner) { potiondelay *pd = (potiondelay *)a->data.v; + unused_arg(owner); pd->amount = do_potion(pd->u, pd->r, pd->ptype, pd->amount); return AT_AGE_REMOVE; } diff --git a/src/attributes/hate.c b/src/attributes/hate.c index dd228b132..84768944a 100644 --- a/src/attributes/hate.c +++ b/src/attributes/hate.c @@ -28,8 +28,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include -static int verify_hate(attrib * a) +static int verify_hate(attrib * a, void *owner) { + unused_arg(owner); if (a->data.v == NULL) { return 0; } diff --git a/src/attributes/moved.c b/src/attributes/moved.c index 781162ea2..b671646c1 100644 --- a/src/attributes/moved.c +++ b/src/attributes/moved.c @@ -24,8 +24,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include -static int age_moved(attrib * a) +static int age_moved(attrib * a, void *owner) { + unused_arg(owner); --a->data.i; return a->data.i > 0; } diff --git a/src/attributes/movement.c b/src/attributes/movement.c index beb3998f0..ca8b6fc2f 100644 --- a/src/attributes/movement.c +++ b/src/attributes/movement.c @@ -65,8 +65,9 @@ void set_movement(attrib ** alist, int type) a->data.i |= type; } -static int age_speedup(attrib * a) +static int age_speedup(attrib * a, void *owner) { + unused_arg(owner); if (a->data.sa[0] > 0) { assert(a->data.sa[0] - a->data.sa[1] >= SHRT_MIN); assert(a->data.sa[0] - a->data.sa[1] <= SHRT_MAX); diff --git a/src/attributes/reduceproduction.c b/src/attributes/reduceproduction.c index 4472a5288..ecf9e4b01 100644 --- a/src/attributes/reduceproduction.c +++ b/src/attributes/reduceproduction.c @@ -20,15 +20,26 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "reduceproduction.h" #include +#include +#include +#include #include +#include -static int age_reduceproduction(attrib * a) +static int age_reduceproduction(attrib * a, void *owner) { + region * r = (region *)owner; int reduce = 100 - (5 * --a->data.sa[1]); - if (reduce < 10) + assert(r); + if (reduce < 10) { reduce = 10; + } a->data.sa[0] = (short)reduce; - return (a->data.sa[1] > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE; + if (a->data.sa[1] > 0) { + ADDMSG(&r->msgs, msg_message("reduceproduction", "")); + return AT_AGE_KEEP; + } + return AT_AGE_REMOVE; } attrib_type at_reduceproduction = { diff --git a/src/building_action.c b/src/building_action.c index 940edb2f1..f5cc19bf8 100644 --- a/src/building_action.c +++ b/src/building_action.c @@ -28,12 +28,12 @@ without prior permission by the authors of Eressea. #include typedef struct building_action { - struct building *b; + struct building *b; // TODO: remove, use attribute-owner? char *fname; char *param; } building_action; -static int lc_age(struct attrib *a) +static int lc_age(struct attrib *a, void *owner) { building_action *data = (building_action *)a->data.v; const char *fname = data->fname; @@ -42,6 +42,7 @@ static int lc_age(struct attrib *a) int result = -1; assert(b != NULL); + assert(owner == b); if (fname != NULL) { lua_State *L = (lua_State *)global.vm_state; diff --git a/src/items/artrewards.c b/src/items/artrewards.c index a5aeb64c2..8b6288f61 100644 --- a/src/items/artrewards.c +++ b/src/items/artrewards.c @@ -45,8 +45,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define HORNDURATION 3 #define HORNIMMUNITY 30 -static int age_peaceimmune(attrib * a) +static int age_peaceimmune(attrib * a, void *owner) { + unused_arg(owner); return (--a->data.i > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE; } diff --git a/src/kernel/curse.c b/src/kernel/curse.c index 09fcdb1d1..3cb39ebab 100644 --- a/src/kernel/curse.c +++ b/src/kernel/curse.c @@ -112,11 +112,12 @@ void curse_init(attrib * a) a->data.v = calloc(1, sizeof(curse)); } -int curse_age(attrib * a) +int curse_age(attrib * a, void *owner) { curse *c = (curse *)a->data.v; int result = 0; + unused_arg(owner); c_clearflag(c, CURSE_ISNEW); if (c_flags(c) & CURSE_NOAGE) { diff --git a/src/kernel/curse.h b/src/kernel/curse.h index 143e73d27..263b66125 100644 --- a/src/kernel/curse.h +++ b/src/kernel/curse.h @@ -291,7 +291,7 @@ extern "C" { void curse_init(struct attrib *a); void curse_done(struct attrib *a); - int curse_age(struct attrib *a); + int curse_age(struct attrib *a, void *owner); double destr_curse(struct curse *c, int cast_level, double force); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 16f874b80..d82ad47ed 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -742,10 +742,11 @@ void set_level(unit * u, skill_t sk, int value) sk_set(add_skill(u, sk), value); } -static int leftship_age(struct attrib *a) +static int leftship_age(struct attrib *a, void *owner) { /* must be aged, so it doesn't affect report generation (cansee) */ unused_arg(a); + unused_arg(owner); return AT_AGE_REMOVE; /* remove me */ } diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index fc0336c71..e72f4caed 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -331,12 +331,12 @@ static void test_age_familiar(CuTest *tc) { CuAssertIntEquals(tc, true, create_newfamiliar(mag, fam)); CuAssertPtrEquals(tc, fam, get_familiar(mag)); CuAssertPtrEquals(tc, mag, get_familiar_mage(fam)); - a_age(&fam->attribs); - a_age(&mag->attribs); + a_age(&fam->attribs, fam); + a_age(&mag->attribs, mag); CuAssertPtrEquals(tc, fam, get_familiar(mag)); CuAssertPtrEquals(tc, mag, get_familiar_mage(fam)); set_number(fam, 0); - a_age(&mag->attribs); + a_age(&mag->attribs, mag); CuAssertPtrEquals(tc, 0, get_familiar(mag)); test_cleanup(); } diff --git a/src/laws.c b/src/laws.c index 7dc6cd0af..5ba995e72 100755 --- a/src/laws.c +++ b/src/laws.c @@ -3087,7 +3087,7 @@ static building *age_building(building * b) } } - a_age(&b->attribs); + a_age(&b->attribs, b); handle_event(b->attribs, "timer", b); if (b->type->age) { @@ -3099,7 +3099,7 @@ static building *age_building(building * b) static void age_region(region * r) { - a_age(&r->attribs); + a_age(&r->attribs, r); handle_event(r->attribs, "timer", r); if (!r->land) @@ -3144,7 +3144,7 @@ static void ageing(void) /* Factions */ for (f = factions; f; f = f->next) { - a_age(&f->attribs); + a_age(&f->attribs, f); handle_event(f->attribs, "timer", f); } @@ -3159,7 +3159,7 @@ static void ageing(void) /* Einheiten */ for (up = &r->units; *up;) { unit *u = *up; - a_age(&u->attribs); + a_age(&u->attribs, u); if (u == *up) handle_event(u->attribs, "timer", u); if (u == *up) @@ -3169,7 +3169,7 @@ static void ageing(void) /* Schiffe */ for (sp = &r->ships; *sp;) { ship *s = *sp; - a_age(&s->attribs); + a_age(&s->attribs, s); if (s == *sp) handle_event(s->attribs, "timer", s); if (s == *sp) diff --git a/src/magic.c b/src/magic.c index 0de7aa831..949565c31 100644 --- a/src/magic.c +++ b/src/magic.c @@ -145,17 +145,19 @@ static void a_writeicastle(const attrib * a, const void *owner, struct storage *store) { icastle_data *data = (icastle_data *)a->data.v; + assert(owner == data->building); WRITE_TOK(store, data->type->_name); WRITE_INT(store, data->building->no); WRITE_INT(store, data->time); } -static int a_ageicastle(struct attrib *a) +static int a_ageicastle(struct attrib *a, void *owner) { icastle_data *data = (icastle_data *)a->data.v; if (data->time <= 0) { - building *b = data->building; + building *b = data->building; // TODO: use owner region *r = b->region; + assert(owner == b); ADDMSG(&r->msgs, msg_message("icastle_dissolve", "building", b)); /* remove_building lets units leave the building */ remove_building(&r->buildings, b); @@ -2384,10 +2386,11 @@ static int read_magician(attrib * a, void *owner, struct storage *store) return AT_READ_OK; } -static int age_unit(attrib * a) +static int age_unit(attrib * a, void *owner) /* if unit is gone or dead, remove the attribute */ { unit *u = (unit *)a->data.v; + unused_arg(owner); return (u != NULL && u->number > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE; } diff --git a/src/magic.h b/src/magic.h index c33d9917e..3a1854cfb 100644 --- a/src/magic.h +++ b/src/magic.h @@ -208,7 +208,7 @@ extern "C" { typedef struct icastle_data { const struct building_type *type; - struct building *building; /* reverse pointer to dissolve the object */ + struct building *building; // TODO: remove, use owner argument int time; } icastle_data; diff --git a/src/modules/arena.c b/src/modules/arena.c index 3b7e7c7f9..6b76a3434 100644 --- a/src/modules/arena.c +++ b/src/modules/arena.c @@ -212,11 +212,12 @@ order * ord) /** * Tempel der Schreie, Demo-Gebäude **/ -static int age_hurting(attrib * a) +static int age_hurting(attrib * a, void *owner) { building *b = (building *)a->data.v; unit *u; int active = 0; + assert(owner == b); if (b == NULL) return AT_AGE_REMOVE; for (u = b->region->units; u; u = u->next) { diff --git a/src/move.c b/src/move.c index cb4d935a8..01a521391 100644 --- a/src/move.c +++ b/src/move.c @@ -145,9 +145,10 @@ static void shiptrail_finalize(attrib * a) free(a->data.v); } -static int shiptrail_age(attrib * a) +static int shiptrail_age(attrib * a, void *owner) { traveldir *t = (traveldir *)(a->data.v); + unused_arg(owner); t->age--; return (t->age > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE; diff --git a/src/move.test.c b/src/move.test.c index 2688178d0..c4e9944c9 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -271,9 +271,9 @@ static void test_age_trails(CuTest *tc) { move_ship(sh, r1, r2, route); CuAssertPtrNotNull(tc, r1->attribs); - a_age(&r1->attribs); + a_age(&r1->attribs, r1); CuAssertPtrNotNull(tc, r1->attribs); - a_age(&r1->attribs); + a_age(&r1->attribs, r1); CuAssertPtrEquals(tc, 0, r1->attribs); free_regionlist(route); test_cleanup(); diff --git a/src/spells.test.c b/src/spells.test.c index 58886d991..3c773d489 100644 --- a/src/spells.test.c +++ b/src/spells.test.c @@ -42,7 +42,7 @@ static void test_good_dreams(CuTest *tc) { CuAssertTrue(tc, curse && curse->duration > 1); CuAssertTrue(tc, curse->effect == 1); - a_age(&r->attribs); + a_age(&r->attribs, r); CuAssertIntEquals_Msg(tc, "good dreams give +1 to allies", 1, get_modifier(u1, SK_MELEE, 11, r, false)); CuAssertIntEquals_Msg(tc, "good dreams have no effect on non-allies", 0, get_modifier(u2, SK_MELEE, 11, r, false)); free_castorder(&co); @@ -67,7 +67,7 @@ static void test_dreams(CuTest *tc) { sp_gooddreams(&co); sp_baddreams(&co); - a_age(&r->attribs); + a_age(&r->attribs, r); CuAssertIntEquals_Msg(tc, "good dreams in same region as bad dreams", 1, get_modifier(u1, SK_MELEE, 11, r, false)); CuAssertIntEquals_Msg(tc, "bad dreams in same region as good dreams", -1, get_modifier(u2, SK_MELEE, 11, r, false)); @@ -98,7 +98,7 @@ static void test_bad_dreams(CuTest *tc) { CuAssertTrue(tc, curse && curse->duration > 1); CuAssertTrue(tc, curse->effect == -1); - a_age(&r->attribs); + a_age(&r->attribs, r); CuAssertIntEquals_Msg(tc, "bad dreams have no effect on allies", 0, get_modifier(u1, SK_MELEE, 11, r, false)); CuAssertIntEquals_Msg(tc, "bad dreams give -1 to non-allies", -1, get_modifier(u2, SK_MELEE, 11, r, false)); diff --git a/src/spells/alp.c b/src/spells/alp.c index f86695194..d443aa063 100644 --- a/src/spells/alp.c +++ b/src/spells/alp.c @@ -46,7 +46,7 @@ extern const char *directions[]; typedef struct alp_data { unit *mage; - unit *target; + unit *target; // TODO: remove, use attribute-owner? } alp_data; static void alp_init(attrib * a) @@ -59,9 +59,10 @@ static void alp_done(attrib * a) free(a->data.v); } -static int alp_verify(attrib * a) +static int alp_verify(attrib * a, void *owner) { alp_data *ad = (alp_data *)a->data.v; + unused_arg(owner); if (ad->mage && ad->target) return 1; return 0; /* remove the attribute */ diff --git a/src/util/attrib.c b/src/util/attrib.c index 5c92b691e..9db46836a 100644 --- a/src/util/attrib.c +++ b/src/util/attrib.c @@ -252,7 +252,7 @@ attrib *a_new(const attrib_type * at) return a; } -int a_age(attrib ** p) +int a_age(attrib ** p, void *owner) { attrib **ap = p; /* Attribute altern, und die Entfernung (age()==0) eines Attributs @@ -260,7 +260,7 @@ int a_age(attrib ** p) while (*ap) { attrib *a = *ap; if (a->type->age) { - int result = a->type->age(a); + int result = a->type->age(a, owner); assert(result >= 0 || !"age() returned a negative value"); if (result == AT_AGE_REMOVE) { a_remove(p, a); diff --git a/src/util/attrib.h b/src/util/attrib.h index c235fd67a..2703de0cb 100644 --- a/src/util/attrib.h +++ b/src/util/attrib.h @@ -52,7 +52,7 @@ extern "C" { const char *name; void(*initialize) (struct attrib *); void(*finalize) (struct attrib *); - int(*age) (struct attrib *); + int(*age) (struct attrib *, void *owner); /* age returns 0 if the attribute needs to be removed, !=0 otherwise */ void(*write) (const struct attrib *, const void *owner, struct storage *); int(*read) (struct attrib *, void *owner, struct storage *); /* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */ @@ -74,7 +74,7 @@ extern "C" { extern void a_removeall(attrib ** a, const attrib_type * at); extern attrib *a_new(const attrib_type * at); - extern int a_age(attrib ** attribs); + extern int a_age(attrib ** attribs, void *owner); extern int a_read(struct storage *store, attrib ** attribs, void *owner); extern void a_write(struct storage *store, const attrib * attribs, const void *owner); diff --git a/src/vortex.c b/src/vortex.c index ab391f012..1d558bb49 100644 --- a/src/vortex.c +++ b/src/vortex.c @@ -66,9 +66,10 @@ static void a_freedirection(attrib * a) free(d); } -static int a_agedirection(attrib * a) +static int a_agedirection(attrib * a, void *owner) { spec_direction *d = (spec_direction *)(a->data.v); + unused_arg(owner); --d->duration; return (d->duration > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE; } @@ -78,7 +79,7 @@ static int a_readdirection(attrib * a, void *owner, struct storage *store) spec_direction *d = (spec_direction *)(a->data.v); char lbuf[32]; - (void)owner; + unused_arg(owner); READ_INT(store, &d->x); READ_INT(store, &d->y); READ_INT(store, &d->duration); @@ -95,7 +96,7 @@ a_writedirection(const attrib * a, const void *owner, struct storage *store) { spec_direction *d = (spec_direction *)(a->data.v); - (void)owner; + unused_arg(owner); WRITE_INT(store, d->x); WRITE_INT(store, d->y); WRITE_INT(store, d->duration); diff --git a/src/wormhole.c b/src/wormhole.c index 421201790..198983344 100644 --- a/src/wormhole.c +++ b/src/wormhole.c @@ -56,7 +56,7 @@ static int cmp_age(const void *v1, const void *v2) } typedef struct wormhole_data { - building *entry; + building *entry; // TODO: remove, use attribute-owner region *exit; } wormhole_data; @@ -70,13 +70,14 @@ static void wormhole_done(struct attrib *a) free(a->data.v); } -static int wormhole_age(struct attrib *a) +static int wormhole_age(struct attrib *a, void *owner) { wormhole_data *data = (wormhole_data *)a->data.v; int maxtransport = data->entry->size; region *r = data->entry->region; unit *u = r->units; + unused_arg(owner); for (; u != NULL && maxtransport != 0; u = u->next) { if (u->building == data->entry) { message *m = NULL; From 9e4344e3c3f70e91d9a592a74d69786e9e99ba71 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 17 Dec 2015 12:23:07 +0100 Subject: [PATCH 5/9] resolve a TODO, make attribute (and data) a little bit smaller. --- src/building_action.c | 24 +++++++++++++----------- src/kernel/version.h | 3 ++- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/building_action.c b/src/building_action.c index f5cc19bf8..4b0c21246 100644 --- a/src/building_action.c +++ b/src/building_action.c @@ -28,7 +28,6 @@ without prior permission by the authors of Eressea. #include typedef struct building_action { - struct building *b; // TODO: remove, use attribute-owner? char *fname; char *param; } building_action; @@ -38,11 +37,10 @@ static int lc_age(struct attrib *a, void *owner) building_action *data = (building_action *)a->data.v; const char *fname = data->fname; const char *fparam = data->param; - building *b = data->b; + building *b = (building *)owner; int result = -1; assert(b != NULL); - assert(owner == b); if (fname != NULL) { lua_State *L = (lua_State *)global.vm_state; @@ -94,9 +92,10 @@ lc_write(const struct attrib *a, const void *owner, struct storage *store) building_action *data = (building_action *)a->data.v; const char *fname = data->fname; const char *fparam = data->param; - building *b = data->b; - write_building_reference(b, store); +#if RELEASE_VERSION < ATTRIBOWNER_VERSION + write_building_reference((building *)owner, store); +#endif WRITE_TOK(store, fname); WRITE_TOK(store, fparam ? fparam : NULLSTRING); } @@ -105,13 +104,17 @@ static int lc_read(struct attrib *a, void *owner, struct storage *store) { char name[NAMESIZE]; building_action *data = (building_action *)a->data.v; - int result = - read_reference(&data->b, store, read_building_reference, resolve_building); + building *b = (building *)owner; + int result = 0; + if (global.data_version < ATTRIBOWNER_VERSION) { + result = read_reference(&b, store, read_building_reference, resolve_building); + assert(b == owner); + } READ_TOK(store, name, sizeof(name)); if (strcmp(name, "tunnel_action") == 0) { /* E2: Weltentor has a new module, doesn't need this any longer */ result = 0; - data->b = 0; + b = 0; } else { data->fname = _strdup(name); @@ -120,14 +123,14 @@ static int lc_read(struct attrib *a, void *owner, struct storage *store) if (strcmp(name, "tnnL") == 0) { /* tunnel_action was the old Weltentore, their code has changed. ignore this object */ result = 0; - data->b = 0; + b = 0; } if (strcmp(name, NULLSTRING) == 0) data->param = 0; else { data->param = _strdup(name); } - if (result == 0 && !data->b) { + if (result == 0 && !b) { return AT_READ_FAIL; } return AT_READ_OK; @@ -144,7 +147,6 @@ void building_addaction(building * b, const char *fname, const char *param) { attrib *a = a_add(&b->attribs, a_new(&at_building_action)); building_action *data = (building_action *)a->data.v; - data->b = b; data->fname = _strdup(fname); if (param) { data->param = _strdup(param); diff --git a/src/kernel/version.h b/src/kernel/version.h index 81f490f34..19c564c1e 100644 --- a/src/kernel/version.h +++ b/src/kernel/version.h @@ -32,8 +32,9 @@ #define EXPLICIT_CURSE_ISNEW_VERSION 347 /* CURSE_ISNEW is not reset in read/write, but in age() */ #define SPELL_LEVEL_VERSION 348 /* f->max_spelllevel gets stored, not calculated */ #define OWNER_3_VERSION 349 /* regions store last owner, not last alliance */ +#define ATTRIBOWNER_VERSION 350 /* all attrib_type functions know who owns the attribute */ -#define RELEASE_VERSION OWNER_3_VERSION /* current datafile */ +#define RELEASE_VERSION ATTRIBOWNER_VERSION /* current datafile */ #define MIN_VERSION INTPAK_VERSION /* minimal datafile we support */ #define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */ From a02d71bfefcdc69ca29e1b34221e598060bc165d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 17 Dec 2015 12:40:22 +0100 Subject: [PATCH 6/9] https://bugs.eressea.de/view.php?id=2176 generate the reduced production message before writing reports, so it shows in the CR. --- res/core/de/strings.xml | 5 ----- res/core/messages.xml | 5 +++++ src/attributes/reduceproduction.c | 2 +- src/report.c | 8 +------- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/res/core/de/strings.xml b/res/core/de/strings.xml index 1b84e5a6a..ec6862fdb 100644 --- a/res/core/de/strings.xml +++ b/res/core/de/strings.xml @@ -7511,11 +7511,6 @@ - - Die Region ist verwüstet, der Boden karg. - The region is ravaged, the ground infertile. - - Einheit-Nr unitid diff --git a/res/core/messages.xml b/res/core/messages.xml index 3e16e8301..00f0107e9 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -1,5 +1,10 @@ + + Die Region ist verwüstet, der Boden karg. + The region is ravaged, the ground infertile. + + diff --git a/src/attributes/reduceproduction.c b/src/attributes/reduceproduction.c index ecf9e4b01..58436bc8e 100644 --- a/src/attributes/reduceproduction.c +++ b/src/attributes/reduceproduction.c @@ -36,7 +36,7 @@ static int age_reduceproduction(attrib * a, void *owner) } a->data.sa[0] = (short)reduce; if (a->data.sa[1] > 0) { - ADDMSG(&r->msgs, msg_message("reduceproduction", "")); + ADDMSG(&r->msgs, msg_message("reduced_production", "")); return AT_AGE_KEEP; } return AT_AGE_REMOVE; diff --git a/src/report.c b/src/report.c index 6e13e834f..7b04e020f 100644 --- a/src/report.c +++ b/src/report.c @@ -1235,13 +1235,6 @@ static void describe(stream *out, const seen_region * sr, faction * f) nr_curses(out, 0, f, TYP_REGION, r); n = 0; - /* Produktionsreduktion */ - a = a_find(r->attribs, &at_reduceproduction); - if (a) { - const char *str = LOC(f->locale, "nr_reduced_production"); - paragraph(out, str, 0, 0, 0); - } - if (edges) newline(out); for (e = edges; e; e = e->next) { @@ -1268,6 +1261,7 @@ static void describe(stream *out, const seen_region * sr, faction * f) first = false; } // TODO name is localized? Works for roads anyway... + // TODO: creating messages during reporting makes them not show up in CR? msg = msg_message("nr_borderlist_postfix", "transparent object", e->transparent, e->name); bytes = (int)nr_render(msg, f->locale, bufp, size, f); From 74d8b53ba8e6489cdca619e53fb511b68304a884 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 17 Dec 2015 12:59:12 +0100 Subject: [PATCH 7/9] fix a TODO, reduce size of icastle_data --- src/building_action.c | 4 +--- src/magic.c | 31 +++++++++++++++++++++---------- src/magic.h | 7 ++----- src/reports.c | 3 +-- src/spells.c | 9 +-------- 5 files changed, 26 insertions(+), 28 deletions(-) diff --git a/src/building_action.c b/src/building_action.c index 4b0c21246..29c20a99d 100644 --- a/src/building_action.c +++ b/src/building_action.c @@ -93,9 +93,7 @@ lc_write(const struct attrib *a, const void *owner, struct storage *store) const char *fname = data->fname; const char *fparam = data->param; -#if RELEASE_VERSION < ATTRIBOWNER_VERSION - write_building_reference((building *)owner, store); -#endif + unused_arg(owner); WRITE_TOK(store, fname); WRITE_TOK(store, fparam ? fparam : NULLSTRING); } diff --git a/src/magic.c b/src/magic.c index 949565c31..dc6d6e9dc 100644 --- a/src/magic.c +++ b/src/magic.c @@ -124,19 +124,20 @@ static double MagicPower(double force) return 0; } +typedef struct icastle_data { + const struct building_type *type; + int time; +} icastle_data; + static int a_readicastle(attrib * a, void *owner, struct storage *store) { icastle_data *data = (icastle_data *)a->data.v; - variant bno; char token[32]; READ_TOK(store, token, sizeof(token)); - READ_INT(store, &bno.i); - READ_INT(store, &data->time); - data->building = findbuilding(bno.i); - if (!data->building) { - /* this shouldn't happen, but just in case it does: */ - ur_add(bno, &data->building, resolve_building); + if (global.data_version < ATTRIBOWNER_VERSION) { + READ_INT(store, NULL); } + READ_INT(store, &data->time); data->type = bt_find(token); return AT_READ_OK; } @@ -145,9 +146,8 @@ static void a_writeicastle(const attrib * a, const void *owner, struct storage *store) { icastle_data *data = (icastle_data *)a->data.v; - assert(owner == data->building); + unused_arg(owner); WRITE_TOK(store, data->type->_name); - WRITE_INT(store, data->building->no); WRITE_INT(store, data->time); } @@ -155,7 +155,7 @@ static int a_ageicastle(struct attrib *a, void *owner) { icastle_data *data = (icastle_data *)a->data.v; if (data->time <= 0) { - building *b = data->building; // TODO: use owner + building *b = (building *)owner; region *r = b->region; assert(owner == b); ADDMSG(&r->msgs, msg_message("icastle_dissolve", "building", b)); @@ -187,6 +187,17 @@ attrib_type at_icastle = { a_readicastle }; +void make_icastle(building *b, const building_type *btype, int timeout) { + attrib *a = a_add(&b->attribs, a_new(&at_icastle)); + icastle_data *data = (icastle_data *)a->data.v; + data->type = btype; + data->time = timeout; +} + +const building_type *icastle_type(const struct attrib *a) { + icastle_data *icastle = (icastle_data *)a->data.v; + return icastle->type; +} /* ------------------------------------------------------------- */ extern int dice(int count, int value); diff --git a/src/magic.h b/src/magic.h index 3a1854cfb..257ba11c4 100644 --- a/src/magic.h +++ b/src/magic.h @@ -206,11 +206,8 @@ extern "C" { extern struct attrib_type at_reportspell; extern struct attrib_type at_icastle; - typedef struct icastle_data { - const struct building_type *type; - struct building *building; // TODO: remove, use owner argument - int time; - } icastle_data; + void make_icastle(struct building *b, const struct building_type *btype, int timeout); + const struct building_type *icastle_type(const struct attrib *a); /* ------------------------------------------------------------- */ /* Kommentare: diff --git a/src/reports.c b/src/reports.c index 24ff6dcb2..99b9f755c 100644 --- a/src/reports.c +++ b/src/reports.c @@ -356,8 +356,7 @@ const char **illusion) if (bt_illusion && b->type == bt_illusion) { const attrib *a = a_findc(b->attribs, &at_icastle); if (a != NULL) { - icastle_data *icastle = (icastle_data *)a->data.v; - *illusion = buildingtype(icastle->type, b, b->size); + *illusion = buildingtype(icastle_type(a), b, b->size); } } } diff --git a/src/spells.c b/src/spells.c index 4a3b81d7a..1445598d9 100644 --- a/src/spells.c +++ b/src/spells.c @@ -4477,13 +4477,11 @@ int sp_icastle(castorder * co) { building *b; const building_type *type; - attrib *a; region *r = co_get_region(co); unit *mage = co->magician.u; int cast_level = co->level; double power = co->force; spellparameter *pa = co->par; - icastle_data *data; const char *bname; message *msg; const building_type *bt_illusion = bt_find("illusioncastle"); @@ -4519,12 +4517,7 @@ int sp_icastle(castorder * co) building_setname(b, bname); /* TODO: Auf timeout und action_destroy umstellen */ - a = a_add(&b->attribs, a_new(&at_icastle)); - data = (icastle_data *)a->data.v; - data->type = type; - data->building = b; - data->time = - 2 + (rng_int() % (int)(power)+1) * (rng_int() % (int)(power)+1); + make_icastle(b, type, 2 + (rng_int() % (int)(power)+1) * (rng_int() % (int)(power)+1)); if (mage->region == r) { if (leave(mage, false)) { From 9d1b5dccb8ee9b9f90fedd8418903cbee49c4301 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 17 Dec 2015 13:04:51 +0100 Subject: [PATCH 8/9] resolve a TODO by reducing wormhole data size --- src/wormhole.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/wormhole.c b/src/wormhole.c index 198983344..bbdec417e 100644 --- a/src/wormhole.c +++ b/src/wormhole.c @@ -56,7 +56,6 @@ static int cmp_age(const void *v1, const void *v2) } typedef struct wormhole_data { - building *entry; // TODO: remove, use attribute-owner region *exit; } wormhole_data; @@ -73,13 +72,14 @@ static void wormhole_done(struct attrib *a) static int wormhole_age(struct attrib *a, void *owner) { wormhole_data *data = (wormhole_data *)a->data.v; - int maxtransport = data->entry->size; - region *r = data->entry->region; + building *b = (building *)owner; + int maxtransport = b->size; + region *r = b->region; unit *u = r->units; unused_arg(owner); for (; u != NULL && maxtransport != 0; u = u->next) { - if (u->building == data->entry) { + if (u->building == b) { message *m = NULL; if (u->number > maxtransport || has_limited_skills(u)) { m = msg_message("wormhole_requirements", "unit region", u, u->region); @@ -97,7 +97,7 @@ static int wormhole_age(struct attrib *a, void *owner) } } - remove_building(&r->buildings, data->entry); + remove_building(&r->buildings, b); ADDMSG(&r->msgs, msg_message("wormhole_dissolve", "region", r)); /* age returns 0 if the attribute needs to be removed, !=0 otherwise */ @@ -107,7 +107,6 @@ static int wormhole_age(struct attrib *a, void *owner) static void wormhole_write(const struct attrib *a, const void *owner, struct storage *store) { wormhole_data *data = (wormhole_data *)a->data.v; - write_building_reference(data->entry, store); write_region_reference(data->exit, store); } @@ -132,12 +131,11 @@ static int wormhole_read(struct attrib *a, void *owner, struct storage *store) read_fun reader = (global.data_version < UIDHASH_VERSION) ? read_building_reference : read_region_reference; - int rb = - read_reference(&data->entry, store, read_building_reference, - resolve_building); - int rr = read_reference(&data->exit, store, reader, resolver); - if (rb == 0 && rr == 0) { - if (!data->exit || !data->entry) { + if (global.data_version < ATTRIBOWNER_VERSION) { + READ_INT(store, NULL); + } + if (read_reference(&data->exit, store, reader, resolver) == 0) { + if (!data->exit) { return AT_READ_FAIL; } } @@ -163,8 +161,6 @@ make_wormhole(const building_type * bt_wormhole, region * r1, region * r2) attrib *a2 = a_add(&b2->attribs, a_new(&at_wormhole)); wormhole_data *d1 = (wormhole_data *)a1->data.v; wormhole_data *d2 = (wormhole_data *)a2->data.v; - d1->entry = b1; - d2->entry = b2; d1->exit = b2->region; d2->exit = b1->region; b1->size = bt_wormhole->maxsize; From beb12372e08745306b5a3c9e28302a99d8dc54d3 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 17 Dec 2015 13:10:09 +0100 Subject: [PATCH 9/9] remove wormhole_data struct now that it's nearly empty --- src/wormhole.c | 53 +++++++++++++++++--------------------------------- 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/src/wormhole.c b/src/wormhole.c index bbdec417e..684cb8f4d 100644 --- a/src/wormhole.c +++ b/src/wormhole.c @@ -55,40 +55,26 @@ static int cmp_age(const void *v1, const void *v2) return 0; } -typedef struct wormhole_data { - region *exit; -} wormhole_data; - -static void wormhole_init(struct attrib *a) -{ - a->data.v = calloc(1, sizeof(wormhole_data)); -} - -static void wormhole_done(struct attrib *a) -{ - free(a->data.v); -} - static int wormhole_age(struct attrib *a, void *owner) { - wormhole_data *data = (wormhole_data *)a->data.v; - building *b = (building *)owner; - int maxtransport = b->size; - region *r = b->region; + building *entry = (building *)owner; + region *exit = (region *)a->data.v; + int maxtransport = entry->size; + region *r = entry->region; unit *u = r->units; unused_arg(owner); for (; u != NULL && maxtransport != 0; u = u->next) { - if (u->building == b) { + if (u->building == entry) { message *m = NULL; if (u->number > maxtransport || has_limited_skills(u)) { m = msg_message("wormhole_requirements", "unit region", u, u->region); } - else if (data->exit != NULL) { - move_unit(u, data->exit, NULL); + else if (exit != NULL) { + move_unit(u, exit, NULL); maxtransport -= u->number; - m = msg_message("wormhole_exit", "unit region", u, data->exit); - add_message(&data->exit->msgs, m); + m = msg_message("wormhole_exit", "unit region", u, exit); + add_message(&exit->msgs, m); } if (m != NULL) { add_message(&u->faction->msgs, m); @@ -97,7 +83,7 @@ static int wormhole_age(struct attrib *a, void *owner) } } - remove_building(&r->buildings, b); + remove_building(&r->buildings, entry); ADDMSG(&r->msgs, msg_message("wormhole_dissolve", "region", r)); /* age returns 0 if the attribute needs to be removed, !=0 otherwise */ @@ -106,8 +92,8 @@ static int wormhole_age(struct attrib *a, void *owner) static void wormhole_write(const struct attrib *a, const void *owner, struct storage *store) { - wormhole_data *data = (wormhole_data *)a->data.v; - write_region_reference(data->exit, store); + region *exit = (region *)a->data.v; + write_region_reference(exit, store); } /** conversion code, turn 573, 2008-05-23 */ @@ -125,7 +111,6 @@ static int resolve_exit(variant id, void *address) static int wormhole_read(struct attrib *a, void *owner, struct storage *store) { - wormhole_data *data = (wormhole_data *)a->data.v; resolve_fun resolver = (global.data_version < UIDHASH_VERSION) ? resolve_exit : resolve_region_id; read_fun reader = (global.data_version < UIDHASH_VERSION) @@ -134,8 +119,8 @@ static int wormhole_read(struct attrib *a, void *owner, struct storage *store) if (global.data_version < ATTRIBOWNER_VERSION) { READ_INT(store, NULL); } - if (read_reference(&data->exit, store, reader, resolver) == 0) { - if (!data->exit) { + if (read_reference(&a->data.v, store, reader, resolver) == 0) { + if (!a->data.v) { return AT_READ_FAIL; } } @@ -144,8 +129,8 @@ static int wormhole_read(struct attrib *a, void *owner, struct storage *store) static attrib_type at_wormhole = { "wormhole", - wormhole_init, - wormhole_done, + NULL, + NULL, wormhole_age, wormhole_write, wormhole_read, @@ -159,10 +144,8 @@ make_wormhole(const building_type * bt_wormhole, region * r1, region * r2) building *b2 = new_building(bt_wormhole, r2, default_locale); attrib *a1 = a_add(&b1->attribs, a_new(&at_wormhole)); attrib *a2 = a_add(&b2->attribs, a_new(&at_wormhole)); - wormhole_data *d1 = (wormhole_data *)a1->data.v; - wormhole_data *d2 = (wormhole_data *)a2->data.v; - d1->exit = b2->region; - d2->exit = b1->region; + a1->data.v = b2->region; + a2->data.v = b1->region; b1->size = bt_wormhole->maxsize; b2->size = bt_wormhole->maxsize; ADDMSG(&r1->msgs, msg_message("wormhole_appear", "region", r1));