forked from github/server
Add a new attribute and RF_OBSERVER flag.
This commit is contained in:
parent
4353773c3b
commit
15702daf99
|
@ -1404,7 +1404,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r)
|
||||||
}
|
}
|
||||||
cr_output_curses_compat(F, f, r, TYP_REGION);
|
cr_output_curses_compat(F, f, r, TYP_REGION);
|
||||||
cr_borders(r, f, r->seen.mode, F);
|
cr_borders(r, f, r->seen.mode, F);
|
||||||
if (r->seen.mode == seen_unit && is_astral(r)
|
if (r->seen.mode >= seen_unit && is_astral(r)
|
||||||
&& !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
&& !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
||||||
/* Sonderbehandlung Teleport-Ebene */
|
/* Sonderbehandlung Teleport-Ebene */
|
||||||
region_list *rl = astralregions(r, inhabitable);
|
region_list *rl = astralregions(r, inhabitable);
|
||||||
|
@ -1427,7 +1427,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r)
|
||||||
}
|
}
|
||||||
|
|
||||||
cr_output_travelthru(F, r, f);
|
cr_output_travelthru(F, r, f);
|
||||||
if (r->seen.mode == seen_unit || r->seen.mode == seen_travel) {
|
if (r->seen.mode >= seen_travel) {
|
||||||
message_list *mlist = r_getmessages(r, f);
|
message_list *mlist = r_getmessages(r, f);
|
||||||
cr_output_messages(F, r->msgs, f);
|
cr_output_messages(F, r->msgs, f);
|
||||||
if (mlist) {
|
if (mlist) {
|
||||||
|
|
|
@ -34,7 +34,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#define RF_MALLORN (1<<1) /* persistent */
|
#define RF_MALLORN (1<<1) /* persistent */
|
||||||
#define RF_BLOCKED (1<<2) /* persistent */
|
#define RF_BLOCKED (1<<2) /* persistent */
|
||||||
|
|
||||||
#define RF_UNUSED_3 (1<<3)
|
#define RF_OBSERVER (1<<3) /* persistent */
|
||||||
#define RF_UNUSED_4 (1<<4)
|
#define RF_UNUSED_4 (1<<4)
|
||||||
#define RF_UNUSED_5 (1<<5)
|
#define RF_UNUSED_5 (1<<5)
|
||||||
#define RF_UNUSED_6 (1<<6)
|
#define RF_UNUSED_6 (1<<6)
|
||||||
|
|
|
@ -79,8 +79,8 @@ typedef enum {
|
||||||
seen_neighbour,
|
seen_neighbour,
|
||||||
seen_lighthouse,
|
seen_lighthouse,
|
||||||
seen_travel,
|
seen_travel,
|
||||||
seen_far,
|
|
||||||
seen_unit,
|
seen_unit,
|
||||||
|
seen_spell,
|
||||||
seen_battle
|
seen_battle
|
||||||
} seen_mode;
|
} seen_mode;
|
||||||
|
|
||||||
|
|
19
src/report.c
19
src/report.c
|
@ -992,7 +992,7 @@ static void describe(stream *out, const region * r, faction * f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* iron & stone */
|
/* iron & stone */
|
||||||
if (r->seen.mode == seen_unit) {
|
if (r->seen.mode >= seen_unit) {
|
||||||
resource_report result[MAX_RAWMATERIALS];
|
resource_report result[MAX_RAWMATERIALS];
|
||||||
int n, numresults = report_resources(r, result, MAX_RAWMATERIALS, f, true);
|
int n, numresults = report_resources(r, result, MAX_RAWMATERIALS, f, true);
|
||||||
|
|
||||||
|
@ -1190,7 +1190,7 @@ static void describe(stream *out, const region * r, faction * f)
|
||||||
*bufp = 0;
|
*bufp = 0;
|
||||||
paragraph(out, buf, 0, 0, 0);
|
paragraph(out, buf, 0, 0, 0);
|
||||||
|
|
||||||
if (r->seen.mode == seen_unit && is_astral(r) &&
|
if (r->seen.mode >= seen_unit && is_astral(r) &&
|
||||||
!is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
!is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
||||||
/* Sonderbehandlung Teleport-Ebene */
|
/* Sonderbehandlung Teleport-Ebene */
|
||||||
region_list *rl = astralregions(r, inhabitable);
|
region_list *rl = astralregions(r, inhabitable);
|
||||||
|
@ -2285,7 +2285,7 @@ report_plaintext(const char *filename, report_context * ctx,
|
||||||
continue;
|
continue;
|
||||||
/* Beschreibung */
|
/* Beschreibung */
|
||||||
|
|
||||||
if (r->seen.mode == seen_unit) {
|
if (r->seen.mode >= seen_unit) {
|
||||||
anyunits = 1;
|
anyunits = 1;
|
||||||
describe(out, r, f);
|
describe(out, r, f);
|
||||||
if (markets_module() && r->land) {
|
if (markets_module() && r->land) {
|
||||||
|
@ -2316,28 +2316,19 @@ report_plaintext(const char *filename, report_context * ctx,
|
||||||
newline(out);
|
newline(out);
|
||||||
write_travelthru(out, r, f);
|
write_travelthru(out, r, f);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (r->seen.mode == seen_far) {
|
|
||||||
describe(out, r, f);
|
|
||||||
newline(out);
|
|
||||||
guards(out, r, f);
|
|
||||||
newline(out);
|
|
||||||
write_travelthru(out, r, f);
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
describe(out, r, f);
|
describe(out, r, f);
|
||||||
newline(out);
|
newline(out);
|
||||||
write_travelthru(out, r, f);
|
write_travelthru(out, r, f);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* Statistik */
|
/* Statistik */
|
||||||
|
|
||||||
if (wants_stats && r->seen.mode == seen_unit)
|
if (wants_stats && r->seen.mode >= seen_unit)
|
||||||
statistics(out, r, f);
|
statistics(out, r, f);
|
||||||
|
|
||||||
/* Nachrichten an REGION in der Region */
|
/* Nachrichten an REGION in der Region */
|
||||||
|
|
||||||
if (r->seen.mode == seen_unit || r->seen.mode == seen_travel) {
|
if (r->seen.mode >= seen_travel) {
|
||||||
// TODO: Bug 2073
|
// TODO: Bug 2073
|
||||||
message_list *mlist = r_getmessages(r, f);
|
message_list *mlist = r_getmessages(r, f);
|
||||||
if (mlist) {
|
if (mlist) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
#include "reports.h"
|
#include "reports.h"
|
||||||
#include "laws.h"
|
#include "laws.h"
|
||||||
|
#include "spells.h"
|
||||||
#include "travelthru.h"
|
#include "travelthru.h"
|
||||||
#include "lighthouse.h"
|
#include "lighthouse.h"
|
||||||
#include "donations.h"
|
#include "donations.h"
|
||||||
|
@ -92,6 +93,7 @@ const char *visibility[] = {
|
||||||
"travel",
|
"travel",
|
||||||
"far",
|
"far",
|
||||||
"unit",
|
"unit",
|
||||||
|
"spell",
|
||||||
"battle"
|
"battle"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -943,9 +945,9 @@ const struct unit *ucansee(const struct faction *f, const struct unit *u,
|
||||||
int stealth_modifier(seen_mode mode)
|
int stealth_modifier(seen_mode mode)
|
||||||
{
|
{
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
|
case seen_spell:
|
||||||
case seen_unit:
|
case seen_unit:
|
||||||
return 0;
|
return 0;
|
||||||
case seen_far:
|
|
||||||
case seen_lighthouse:
|
case seen_lighthouse:
|
||||||
return -2;
|
return -2;
|
||||||
case seen_travel:
|
case seen_travel:
|
||||||
|
@ -1336,6 +1338,12 @@ void prepare_report(report_context *ctx, faction *f)
|
||||||
for (r = ctx->first; r!=ctx->last; r = r->next) {
|
for (r = ctx->first; r!=ctx->last; r = r->next) {
|
||||||
unit *u;
|
unit *u;
|
||||||
|
|
||||||
|
if (fval(r, RF_OBSERVER)) {
|
||||||
|
int skill = get_observer(r, f);
|
||||||
|
if (skill >= 0) {
|
||||||
|
add_seen_nb(f, r, seen_spell);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (fval(r, RF_LIGHTHOUSE)) {
|
if (fval(r, RF_LIGHTHOUSE)) {
|
||||||
/* region owners get the report from lighthouses */
|
/* region owners get the report from lighthouses */
|
||||||
if (rule_region_owners && bt_lighthouse) {
|
if (rule_region_owners && bt_lighthouse) {
|
||||||
|
|
|
@ -437,7 +437,7 @@ static void test_report_far_vision(CuTest *tc) {
|
||||||
u1 = test_create_unit(f, r1);
|
u1 = test_create_unit(f, r1);
|
||||||
r2 = test_create_region(10, 0, 0);
|
r2 = test_create_region(10, 0, 0);
|
||||||
rc = test_create_race("spell");
|
rc = test_create_race("spell");
|
||||||
watch_region(r2, f, 10);
|
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;
|
||||||
|
@ -445,7 +445,7 @@ static void test_report_far_vision(CuTest *tc) {
|
||||||
CuAssertPtrEquals(tc, r1, ctx.first);
|
CuAssertPtrEquals(tc, r1, ctx.first);
|
||||||
CuAssertPtrEquals(tc, 0, ctx.last);
|
CuAssertPtrEquals(tc, 0, ctx.last);
|
||||||
CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
|
CuAssertIntEquals(tc, seen_unit, r1->seen.mode);
|
||||||
CuAssertIntEquals(tc, seen_unit, r2->seen.mode);
|
CuAssertIntEquals(tc, seen_spell, r2->seen.mode);
|
||||||
finish_reports(&ctx);
|
finish_reports(&ctx);
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
104
src/spells.c
104
src/spells.c
|
@ -4111,13 +4111,92 @@ static int sp_bigrecruit(castorder * co)
|
||||||
return cast_level;
|
return cast_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
void watch_region(region *r, faction *f, int perception)
|
typedef struct obs_data {
|
||||||
{
|
faction *f;
|
||||||
unit *u;
|
int skill;
|
||||||
|
int timer;
|
||||||
|
} obs_data;
|
||||||
|
|
||||||
u = create_unit(r, f, 1, get_race(RC_SPELL), 0, NULL, NULL);
|
static void obs_init(struct attrib *a)
|
||||||
u->age = 2;
|
{
|
||||||
set_level(u, SK_PERCEPTION, perception);
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
@ -4176,7 +4255,7 @@ static int sp_pump(castorder * co)
|
||||||
return cast_level / 2;
|
return cast_level / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
watch_region(rt, mage->faction, effskill(target, SK_PERCEPTION, 0));
|
set_observer(rt, mage->faction, effskill(target, SK_PERCEPTION, 0));
|
||||||
return cast_level;
|
return cast_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4815,7 +4894,7 @@ int sp_dreamreading(castorder * co)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
watch_region(u->region, mage->faction, effskill(u, SK_PERCEPTION, u->region));
|
set_observer(u->region, mage->faction, effskill(u, SK_PERCEPTION, u->region));
|
||||||
|
|
||||||
msg =
|
msg =
|
||||||
msg_message("sp_dreamreading_effect", "mage unit region", mage, u,
|
msg_message("sp_dreamreading_effect", "mage unit region", mage, u,
|
||||||
|
@ -5622,7 +5701,8 @@ int sp_showastral(castorder * co)
|
||||||
/* sprintf(buf, "%s kann niemanden im astralen Nebel entdecken.",
|
/* sprintf(buf, "%s kann niemanden im astralen Nebel entdecken.",
|
||||||
unitname(mage)); */
|
unitname(mage)); */
|
||||||
cmistake(mage, co->order, 220, MSG_MAGIC);
|
cmistake(mage, co->order, 220, MSG_MAGIC);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
/* Ausgeben */
|
/* Ausgeben */
|
||||||
|
|
||||||
|
@ -5648,7 +5728,8 @@ int sp_showastral(castorder * co)
|
||||||
scat(")");
|
scat(")");
|
||||||
if (c == n - 1) {
|
if (c == n - 1) {
|
||||||
scat(" und ");
|
scat(" und ");
|
||||||
} else if (c < n - 1) {
|
}
|
||||||
|
else if (c < n - 1) {
|
||||||
scat(", ");
|
scat(", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5688,7 +5769,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)) {
|
||||||
watch_region(rt, mage->faction, co->level / 2);
|
set_observer(rt, mage->faction, co->level / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6718,6 +6799,7 @@ void register_spells(void)
|
||||||
register_borders();
|
register_borders();
|
||||||
|
|
||||||
at_register(&at_wdwpyramid);
|
at_register(&at_wdwpyramid);
|
||||||
|
at_register(&at_observer);
|
||||||
at_register(&at_deathcloud_compat);
|
at_register(&at_deathcloud_compat);
|
||||||
|
|
||||||
/* init_firewall(); */
|
/* init_firewall(); */
|
||||||
|
|
|
@ -31,7 +31,8 @@ extern "C" {
|
||||||
|
|
||||||
void register_spells(void);
|
void register_spells(void);
|
||||||
|
|
||||||
void watch_region(struct region *r, struct faction *f, int perception);
|
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);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <kernel/curse.h>
|
#include <kernel/curse.h>
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
#include <kernel/order.h>
|
#include <kernel/order.h>
|
||||||
|
#include <kernel/race.h>
|
||||||
#include <kernel/region.h>
|
#include <kernel/region.h>
|
||||||
#include <kernel/spell.h>
|
#include <kernel/spell.h>
|
||||||
#include <kernel/unit.h>
|
#include <kernel/unit.h>
|
||||||
|
@ -106,9 +107,28 @@ static void test_bad_dreams(CuTest *tc) {
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_watch_region(CuTest *tc) {
|
||||||
|
region *r;
|
||||||
|
faction *f;
|
||||||
|
test_setup();
|
||||||
|
test_create_race("spell");
|
||||||
|
CuAssertPtrNotNull(tc, get_race(RC_SPELL));
|
||||||
|
r = test_create_region(0, 0, 0);
|
||||||
|
f = test_create_faction(0);
|
||||||
|
CuAssertIntEquals(tc, -1, get_observer(r, f));
|
||||||
|
set_observer(r, f, 0);
|
||||||
|
CuAssertIntEquals(tc, 0, get_observer(r, f));
|
||||||
|
set_observer(r, f, 10);
|
||||||
|
CuAssertIntEquals(tc, 10, get_observer(r, f));
|
||||||
|
CuAssertIntEquals(tc, RF_OBSERVER, fval(r, RF_OBSERVER));
|
||||||
|
CuAssertPtrNotNull(tc, r->attribs);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_spells_suite(void)
|
CuSuite *get_spells_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
SUITE_ADD_TEST(suite, test_watch_region);
|
||||||
SUITE_ADD_TEST(suite, test_good_dreams);
|
SUITE_ADD_TEST(suite, test_good_dreams);
|
||||||
SUITE_ADD_TEST(suite, test_bad_dreams);
|
SUITE_ADD_TEST(suite, test_bad_dreams);
|
||||||
SUITE_ADD_TEST(suite, test_dreams);
|
SUITE_ADD_TEST(suite, test_dreams);
|
||||||
|
|
Loading…
Reference in New Issue