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/event.h>
#include <util/gamedata.h>
#include <util/resolve.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 = {
"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);

View File

@ -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

View File

@ -48,6 +48,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "lighthouse.h"
/* attributes includes */
#include <attributes/attributes.h>
#include <attributes/key.h>
#include <triggers/timeout.h>
@ -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 */

View File

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

View File

@ -27,6 +27,7 @@
#include <util/lists.h>
#include <util/message.h>
#include <attributes/attributes.h>
#include <attributes/key.h>
#include <attributes/otherfaction.h>
@ -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;

View File

@ -25,6 +25,8 @@
#include "monsters.h"
#include "teleport.h"
#include <attributes/attributes.h>
#include <spells/borders.h>
#include <spells/buildingcurse.h>
#include <spells/regioncurse.h>
@ -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);

View File

@ -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);

View File

@ -1,4 +1,7 @@
#include <platform.h>
#include "spells.h"
#include <kernel/config.h>
#include <kernel/curse.h>
#include <kernel/faction.h>
@ -10,7 +13,8 @@
#include <util/language.h>
#include <util/attrib.h>
#include <spells/regioncurse.h>
#include "spells.h"
#include <attributes/attributes.h>
#include <CuTest.h>
#include <tests.h>
@ -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);