convert RC_SPELL to at_observer during readgame.

This commit is contained in:
Enno Rehling 2017-05-24 08:18:55 +02:00
parent 86974df332
commit 30cfe2c0c0
8 changed files with 128 additions and 110 deletions

View file

@ -56,9 +56,98 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/attrib.h> #include <util/attrib.h>
#include <util/event.h> #include <util/event.h>
#include <util/gamedata.h> #include <util/gamedata.h>
#include <util/resolve.h>
#include <storage.h> #include <storage.h>
#include <stdlib.h>
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 = { attrib_type at_unitdissolve = {
"unitdissolve", NULL, NULL, NULL, a_writechars, a_readchars "unitdissolve", NULL, NULL, NULL, a_writechars, a_readchars
@ -123,6 +212,7 @@ void register_attributes(void)
at_register(&at_stealth); at_register(&at_stealth);
at_register(&at_dict); at_register(&at_dict);
at_register(&at_unitdissolve); at_register(&at_unitdissolve);
at_register(&at_observer);
at_register(&at_overrideroads); at_register(&at_overrideroads);
at_register(&at_raceprefix); at_register(&at_raceprefix);
at_register(&at_iceberg); at_register(&at_iceberg);

View file

@ -23,8 +23,14 @@ extern "C" {
#endif #endif
struct attrib_type; struct attrib_type;
struct region;
struct faction;
extern void register_attributes(void); 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -48,6 +48,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "lighthouse.h" #include "lighthouse.h"
/* attributes includes */ /* attributes includes */
#include <attributes/attributes.h>
#include <attributes/key.h> #include <attributes/key.h>
#include <triggers/timeout.h> #include <triggers/timeout.h>
@ -1621,6 +1622,7 @@ int read_game(gamedata *data) {
int rmax = maxregions; int rmax = maxregions;
storage * store = data->store; storage * store = data->store;
const struct building_type *bt_lighthouse = bt_find("lighthouse"); const struct building_type *bt_lighthouse = bt_find("lighthouse");
const struct race *rc_spell = rc_find("spell");
if (data->version >= SAVEGAMEID_VERSION) { if (data->version >= SAVEGAMEID_VERSION) {
int gameid; int gameid;
@ -1705,6 +1707,11 @@ int read_game(gamedata *data) {
while (--p >= 0) { while (--p >= 0) {
unit *u = read_unit(data); unit *u = read_unit(data);
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 (data->version < JSON_REPORT_VERSION) {
if (u->_name && fval(u->faction, FFL_NPC)) { if (u->_name && fval(u->faction, FFL_NPC)) {
if (!u->_name[0] || unit_name_equals_race(u)) { if (!u->_name[0] || unit_name_equals_race(u)) {
@ -1716,9 +1723,9 @@ int read_game(gamedata *data) {
u->region = r; u->region = r;
*up = u; *up = u;
up = &u->next; up = &u->next;
update_interval(u->faction, r); update_interval(u->faction, r);
} }
}
if ((nread & 0x3FF) == 0) { /* das spart extrem Zeit */ if ((nread & 0x3FF) == 0) { /* das spart extrem Zeit */
log_debug(" - Einzulesende Regionen: %d/%d * %d,%d \r", rmax, nread, r->x, r->y); log_debug(" - Einzulesende Regionen: %d/%d * %d,%d \r", rmax, nread, r->x, r->y);

View file

@ -70,6 +70,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <time.h> #include <time.h>
/* attributes includes */ /* attributes includes */
#include <attributes/attributes.h>
#include <attributes/follow.h> #include <attributes/follow.h>
#include <attributes/otherfaction.h> #include <attributes/otherfaction.h>
#include <attributes/racename.h> #include <attributes/racename.h>

View file

@ -27,6 +27,7 @@
#include <util/lists.h> #include <util/lists.h>
#include <util/message.h> #include <util/message.h>
#include <attributes/attributes.h>
#include <attributes/key.h> #include <attributes/key.h>
#include <attributes/otherfaction.h> #include <attributes/otherfaction.h>
@ -722,8 +723,7 @@ static void test_report_far_vision(CuTest *tc) {
r1 = test_create_region(0, 0, 0); r1 = test_create_region(0, 0, 0);
test_create_unit(f, r1); test_create_unit(f, r1);
r2 = test_create_region(10, 0, 0); r2 = test_create_region(10, 0, 0);
test_create_race("spell"); set_observer(r2, f, 10, 2);
set_observer(r2, f, 10);
CuAssertPtrEquals(tc, r1, f->first); CuAssertPtrEquals(tc, r1, f->first);
CuAssertPtrEquals(tc, r2, f->last); CuAssertPtrEquals(tc, r2, f->last);
report_context ctx; report_context ctx;

View file

@ -25,6 +25,8 @@
#include "monsters.h" #include "monsters.h"
#include "teleport.h" #include "teleport.h"
#include <attributes/attributes.h>
#include <spells/borders.h> #include <spells/borders.h>
#include <spells/buildingcurse.h> #include <spells/buildingcurse.h>
#include <spells/regioncurse.h> #include <spells/regioncurse.h>
@ -4115,94 +4117,6 @@ static int sp_bigrecruit(castorder * co)
return cast_level; 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 /* Name: Aushorchen
* Stufe: 7 * Stufe: 7
@ -4259,7 +4173,7 @@ static int sp_pump(castorder * co)
return cast_level / 2; 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; return cast_level;
} }
@ -4892,7 +4806,7 @@ int sp_dreamreading(castorder * co)
return 0; 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 =
msg_message("sp_dreamreading_effect", "mage unit region", mage, u, 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) { for (rl2 = rl; rl2; rl2 = rl2->next) {
region *rt = rl2->data; region *rt = rl2->data;
if (!is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) { 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 #ifdef COMPAT_DEATHCLOUD
at_deprecate("zauber_todeswolke", dc_read_compat); at_deprecate("zauber_todeswolke", dc_read_compat);
#endif #endif
at_register(&at_observer);
/* init_firewall(); */ /* init_firewall(); */
ct_register(&ct_firewall); ct_register(&ct_firewall);

View file

@ -32,9 +32,6 @@ extern "C" {
void register_magicresistance(void); void register_magicresistance(void);
void register_spells(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_baddreams(castorder * co);
int sp_gooddreams(castorder * co); int sp_gooddreams(castorder * co);

View file

@ -1,4 +1,7 @@
#include <platform.h> #include <platform.h>
#include "spells.h"
#include <kernel/config.h> #include <kernel/config.h>
#include <kernel/curse.h> #include <kernel/curse.h>
#include <kernel/faction.h> #include <kernel/faction.h>
@ -10,7 +13,8 @@
#include <util/language.h> #include <util/language.h>
#include <util/attrib.h> #include <util/attrib.h>
#include <spells/regioncurse.h> #include <spells/regioncurse.h>
#include "spells.h"
#include <attributes/attributes.h>
#include <CuTest.h> #include <CuTest.h>
#include <tests.h> #include <tests.h>
@ -116,9 +120,9 @@ static void test_watch_region(CuTest *tc) {
r = test_create_region(0, 0, 0); r = test_create_region(0, 0, 0);
f = test_create_faction(0); f = test_create_faction(0);
CuAssertIntEquals(tc, -1, get_observer(r, f)); 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)); 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, 10, get_observer(r, f));
CuAssertIntEquals(tc, RF_OBSERVER, fval(r, RF_OBSERVER)); CuAssertIntEquals(tc, RF_OBSERVER, fval(r, RF_OBSERVER));
CuAssertPtrNotNull(tc, r->attribs); CuAssertPtrNotNull(tc, r->attribs);