From 30cfe2c0c0c4306f7a1f4f2f61dbc7575eca8a3d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 24 May 2017 08:18:55 +0200 Subject: [PATCH] convert RC_SPELL to at_observer during readgame. --- src/attributes/attributes.c | 90 ++++++++++++++++++++++++++++++++++ src/attributes/attributes.h | 6 +++ src/kernel/save.c | 27 +++++++---- src/reports.c | 1 + src/reports.test.c | 4 +- src/spells.c | 97 ++----------------------------------- src/spells.h | 3 -- src/spells.test.c | 10 ++-- 8 files changed, 128 insertions(+), 110 deletions(-) diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index f699fdb57..610bea684 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -56,9 +56,98 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include +#include +typedef struct obs_data { + faction *f; + int skill; + int timer; +} obs_data; + +static void obs_init(struct attrib *a) +{ + a->data.v = malloc(sizeof(obs_data)); +} + +static void obs_done(struct attrib *a) +{ + free(a->data.v); +} + +static int obs_age(struct attrib *a, void *owner) +{ + obs_data *od = (obs_data *)a->data.v; + update_interval(od->f, (region *)owner); + return --od->timer; +} + +static void obs_write(const struct attrib *a, const void *owner, struct storage *store) +{ + obs_data *od = (obs_data *)a->data.v; + write_faction_reference(od->f, store); + WRITE_INT(store, od->skill); + WRITE_INT(store, od->timer); +} + +static int obs_read(struct attrib *a, void *owner, struct gamedata *data) +{ + obs_data *od = (obs_data *)a->data.v; + + read_reference(&od->f, data, read_faction_reference, resolve_faction); + READ_INT(data->store, &od->skill); + READ_INT(data->store, &od->timer); + return AT_READ_OK; +} + +attrib_type at_observer = { "observer", obs_init, obs_done, obs_age, obs_write, obs_read }; + +static attrib *make_observer(faction *f, int perception) +{ + attrib * a = a_new(&at_observer); + obs_data *od = (obs_data *)a->data.v; + od->f = f; + od->skill = perception; + od->timer = 2; + return a; +} + +int get_observer(region *r, faction *f) { + if (fval(r, RF_OBSERVER)) { + attrib *a = a_find(r->attribs, &at_observer); + while (a && a->type == &at_observer) { + obs_data *od = (obs_data *)a->data.v; + if (od->f == f) { + return od->skill; + } + a = a->next; + } + } + return -1; +} + +void set_observer(region *r, faction *f, int skill, int turns) +{ + update_interval(f, r); + if (fval(r, RF_OBSERVER)) { + attrib *a = a_find(r->attribs, &at_observer); + while (a && a->type == &at_observer) { + obs_data *od = (obs_data *)a->data.v; + if (od->f == f && od->skill < skill) { + od->skill = skill; + od->timer = turns; + return; + } + a = a->nexttype; + } + } + else { + fset(r, RF_OBSERVER); + } + a_add(&r->attribs, make_observer(f, skill)); +} attrib_type at_unitdissolve = { "unitdissolve", NULL, NULL, NULL, a_writechars, a_readchars @@ -123,6 +212,7 @@ void register_attributes(void) at_register(&at_stealth); at_register(&at_dict); at_register(&at_unitdissolve); + at_register(&at_observer); at_register(&at_overrideroads); at_register(&at_raceprefix); at_register(&at_iceberg); diff --git a/src/attributes/attributes.h b/src/attributes/attributes.h index 4ec3150ec..19b371dbb 100644 --- a/src/attributes/attributes.h +++ b/src/attributes/attributes.h @@ -23,8 +23,14 @@ extern "C" { #endif struct attrib_type; + struct region; + struct faction; + extern void register_attributes(void); + void set_observer(struct region *r, struct faction *f, int perception, int turns); + int get_observer(struct region *r, struct faction *f); + #ifdef __cplusplus } #endif diff --git a/src/kernel/save.c b/src/kernel/save.c index 39f2a129f..983190e7d 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -48,6 +48,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "lighthouse.h" /* attributes includes */ +#include #include #include @@ -1621,6 +1622,7 @@ int read_game(gamedata *data) { int rmax = maxregions; storage * store = data->store; const struct building_type *bt_lighthouse = bt_find("lighthouse"); + const struct race *rc_spell = rc_find("spell"); if (data->version >= SAVEGAMEID_VERSION) { int gameid; @@ -1705,19 +1707,24 @@ int read_game(gamedata *data) { while (--p >= 0) { unit *u = read_unit(data); - if (data->version < JSON_REPORT_VERSION) { - if (u->_name && fval(u->faction, FFL_NPC)) { - if (!u->_name[0] || unit_name_equals_race(u)) { - unit_setname(u, NULL); + if (u_race(u) == rc_spell) { + set_observer(r, u->faction, get_level(u, SK_PERCEPTION), u->age); + free_unit(u); + } + else { + if (data->version < JSON_REPORT_VERSION) { + if (u->_name && fval(u->faction, FFL_NPC)) { + if (!u->_name[0] || unit_name_equals_race(u)) { + unit_setname(u, NULL); + } } } + assert(u->region == NULL); + u->region = r; + *up = u; + up = &u->next; + update_interval(u->faction, r); } - assert(u->region == NULL); - u->region = r; - *up = u; - up = &u->next; - - update_interval(u->faction, r); } if ((nread & 0x3FF) == 0) { /* das spart extrem Zeit */ diff --git a/src/reports.c b/src/reports.c index 934a5ae36..10a21af8d 100644 --- a/src/reports.c +++ b/src/reports.c @@ -70,6 +70,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include /* attributes includes */ +#include #include #include #include diff --git a/src/reports.test.c b/src/reports.test.c index aed0b4cb8..74750e9b5 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -722,8 +723,7 @@ static void test_report_far_vision(CuTest *tc) { r1 = test_create_region(0, 0, 0); test_create_unit(f, r1); r2 = test_create_region(10, 0, 0); - test_create_race("spell"); - set_observer(r2, f, 10); + set_observer(r2, f, 10, 2); CuAssertPtrEquals(tc, r1, f->first); CuAssertPtrEquals(tc, r2, f->last); report_context ctx; diff --git a/src/spells.c b/src/spells.c index da60bfc57..36a7656c6 100644 --- a/src/spells.c +++ b/src/spells.c @@ -25,6 +25,8 @@ #include "monsters.h" #include "teleport.h" +#include + #include #include #include @@ -4115,94 +4117,6 @@ static int sp_bigrecruit(castorder * co) return cast_level; } -typedef struct obs_data { - faction *f; - int skill; - int timer; -} obs_data; - -static void obs_init(struct attrib *a) -{ - a->data.v = malloc(sizeof(obs_data)); -} - -static void obs_done(struct attrib *a) -{ - free(a->data.v); -} - -static int obs_age(struct attrib *a, void *owner) -{ - obs_data *od = (obs_data *)a->data.v; - update_interval(od->f, (region *)owner); - return --od->timer; -} - -static void obs_write(const struct attrib *a, const void *owner, struct storage *store) -{ - obs_data *od = (obs_data *)a->data.v; - write_faction_reference(od->f, store); - WRITE_INT(store, od->skill); - WRITE_INT(store, od->timer); -} - -static int obs_read(struct attrib *a, void *owner, struct gamedata *data) -{ - obs_data *od = (obs_data *)a->data.v; - - read_reference(&od->f, data, read_faction_reference, resolve_faction); - READ_INT(data->store, &od->skill); - READ_INT(data->store, &od->timer); - return AT_READ_OK; -} - -attrib_type at_observer = { "observer", obs_init, obs_done, obs_age, obs_write, obs_read }; - -static attrib *make_observer(faction *f, int perception) -{ - attrib * a = a_new(&at_observer); - obs_data *od = (obs_data *)a->data.v; - od->f = f; - od->skill = perception; - od->timer = 2; - return a; -} - -int get_observer(region *r, faction *f) { - if (fval(r, RF_OBSERVER)) { - attrib *a = a_find(r->attribs, &at_observer); - while (a && a->type == &at_observer) { - obs_data *od = (obs_data *)a->data.v; - if (od->f == f) { - return od->skill; - } - a = a->next; - } - } - return -1; -} - -void set_observer(region *r, faction *f, int skill) -{ - update_interval(f, r); - if (fval(r, RF_OBSERVER)) { - attrib *a = a_find(r->attribs, &at_observer); - while (a && a->type == &at_observer) { - obs_data *od = (obs_data *)a->data.v; - if (od->f == f && od->skill < skill) { - od->skill = skill; - od->timer = 2; - return; - } - a = a->nexttype; - } - } - else { - fset(r, RF_OBSERVER); - } - a_add(&r->attribs, make_observer(f, skill)); -} - /* ------------------------------------------------------------- */ /* Name: Aushorchen * Stufe: 7 @@ -4259,7 +4173,7 @@ static int sp_pump(castorder * co) return cast_level / 2; } - set_observer(rt, mage->faction, effskill(target, SK_PERCEPTION, 0)); + set_observer(rt, mage->faction, effskill(target, SK_PERCEPTION, 0), 2); return cast_level; } @@ -4892,7 +4806,7 @@ int sp_dreamreading(castorder * co) return 0; } - set_observer(u->region, mage->faction, effskill(u, SK_PERCEPTION, u->region)); + set_observer(u->region, mage->faction, effskill(u, SK_PERCEPTION, u->region), 2); msg = msg_message("sp_dreamreading_effect", "mage unit region", mage, u, @@ -5765,7 +5679,7 @@ int sp_viewreality(castorder * co) for (rl2 = rl; rl2; rl2 = rl2->next) { region *rt = rl2->data; if (!is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) { - set_observer(rt, mage->faction, co->level / 2); + set_observer(rt, mage->faction, co->level / 2, 2); } } @@ -6848,7 +6762,6 @@ void register_spells(void) #ifdef COMPAT_DEATHCLOUD at_deprecate("zauber_todeswolke", dc_read_compat); #endif - at_register(&at_observer); /* init_firewall(); */ ct_register(&ct_firewall); diff --git a/src/spells.h b/src/spells.h index d45f04d68..33a263733 100644 --- a/src/spells.h +++ b/src/spells.h @@ -32,9 +32,6 @@ extern "C" { void register_magicresistance(void); void register_spells(void); - void set_observer(struct region *r, struct faction *f, int perception); - int get_observer(struct region *r, struct faction *f); - int sp_baddreams(castorder * co); int sp_gooddreams(castorder * co); diff --git a/src/spells.test.c b/src/spells.test.c index 3a048e021..00a88cbf8 100644 --- a/src/spells.test.c +++ b/src/spells.test.c @@ -1,4 +1,7 @@ #include + +#include "spells.h" + #include #include #include @@ -10,7 +13,8 @@ #include #include #include -#include "spells.h" + +#include #include #include @@ -116,9 +120,9 @@ static void test_watch_region(CuTest *tc) { r = test_create_region(0, 0, 0); f = test_create_faction(0); CuAssertIntEquals(tc, -1, get_observer(r, f)); - set_observer(r, f, 0); + set_observer(r, f, 0, 2); CuAssertIntEquals(tc, 0, get_observer(r, f)); - set_observer(r, f, 10); + set_observer(r, f, 10, 2); CuAssertIntEquals(tc, 10, get_observer(r, f)); CuAssertIntEquals(tc, RF_OBSERVER, fval(r, RF_OBSERVER)); CuAssertPtrNotNull(tc, r->attribs);