From 87873702ca18de73a3711917ad2b0780469bed09 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 24 Sep 2016 20:31:31 +0200 Subject: [PATCH 01/12] eliminate RS_FARVISION enum, there is no other kind of RC_SPELL. --- src/battle.c | 75 +++++++++++++++++++++++++-------------------- src/kernel/config.h | 1 + src/magic.h | 6 ---- src/main.c | 3 ++ src/reports.c | 19 ++---------- src/reports.test.c | 24 +++++++++++++++ src/spells.c | 7 ++--- 7 files changed, 75 insertions(+), 60 deletions(-) diff --git a/src/battle.c b/src/battle.c index 1bbaaadfe..aa0c486eb 100644 --- a/src/battle.c +++ b/src/battle.c @@ -1649,11 +1649,51 @@ static castorder * create_castorder_combat(castorder *co, fighter *fig, const sp return co; } +#ifdef FFL_CURSED +static void summon_igjarjuk(battle *b, spellrank spellranks[]) { + side *s; + castorder *co; + + for (s = b->sides; s != b->sides + b->nsides; ++s) { + fighter *fig = 0; + if (s->bf->attacker && fval(s->faction, FFL_CURSED)) { + spell *sp = find_spell("igjarjuk"); + if (sp) { + int si; + for (si = 0; s->enemies[si]; ++si) { + side *se = s->enemies[si]; + if (se && !fval(se->faction, FFL_NPC)) { + fighter *fi; + for (fi = se->fighters; fi; fi = fi->next) { + if (fi && (!fig || fig->unit->number > fi->unit->number)) { + fig = fi; + if (fig->unit->number == 1) { + break; + } + } + } + if (fig && fig->unit->number == 1) { + break; + } + } + } + if (fig) { + co = create_castorder_combat(0, fig, sp, 10, 10); + co->magician.fig = fig; + add_castorder(&spellranks[sp->rank], co); + break; + } + } + } + } +} +#endif + void do_combatmagic(battle * b, combatmagic_t was) { side *s; - region *r = b->region; castorder *co; + region *r = b->region; int level, rank, sl; spellrank spellranks[MAX_SPELLRANK]; @@ -1661,38 +1701,7 @@ void do_combatmagic(battle * b, combatmagic_t was) #ifdef FFL_CURSED if (was == DO_PRECOMBATSPELL) { - for (s = b->sides; s != b->sides + b->nsides; ++s) { - fighter *fig = 0; - if (s->bf->attacker && fval(s->faction, FFL_CURSED)) { - spell *sp = find_spell("igjarjuk"); - if (sp) { - int si; - for (si = 0; s->enemies[si]; ++si) { - side *se = s->enemies[si]; - if (se && !fval(se->faction, FFL_NPC)) { - fighter *fi; - for (fi = se->fighters; fi; fi = fi->next) { - if (fi && (!fig || fig->unit->number > fi->unit->number)) { - fig = fi; - if (fig->unit->number == 1) { - break; - } - } - } - if (fig && fig->unit->number == 1) { - break; - } - } - } - if (fig) { - co = create_castorder_combat(0, fig, sp, 10, 10); - co->magician.fig = fig; - add_castorder(&spellranks[sp->rank], co); - break; - } - } - } - } + summon_igjarjuk(b, spellranks); } #endif for (s = b->sides; s != b->sides + b->nsides; ++s) { diff --git a/src/kernel/config.h b/src/kernel/config.h index 74565e25e..c3b758f48 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -159,6 +159,7 @@ struct param; unsigned int data_turn; void *vm_state; int data_version; /* TODO: eliminate in favor of gamedata.version */ + int debug; struct _dictionary_ *inifile; struct global_functions { int(*wage) (const struct region * r, const struct faction * f, diff --git a/src/magic.h b/src/magic.h index 257ba11c4..59ef92475 100644 --- a/src/magic.h +++ b/src/magic.h @@ -184,12 +184,6 @@ extern "C" { SPC_LINEAR /* Komponenten pro Level und müssen vorhanden sein */ }; - enum { - RS_DUMMY, - RS_FARVISION, - MAX_REGIONSPELLS - }; - /* ------------------------------------------------------------- */ /* Prototypen */ diff --git a/src/main.c b/src/main.c index 58a15edc0..086197d29 100644 --- a/src/main.c +++ b/src/main.c @@ -184,6 +184,9 @@ static int parse_args(int argc, char **argv, int *exitcode) else { const char *arg; switch (argi[1]) { + case 'd': // check configuration for consistency + i = get_arg(argc, argv, 2, i, &arg, 0); + global.debug = arg ? atoi(arg) : 0xff; case 'r': i = get_arg(argc, argv, 2, i, &arg, 0); config_set("config.rules", arg); diff --git a/src/reports.c b/src/reports.c index ff076a866..dc0edf1b3 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1308,17 +1308,6 @@ static void cb_add_seen(region *r, unit *u, void *cbdata) { } } -static bool unit_cansee(const unit *u) -{ - const race *rc = u_race(u); - static const race *rc_spell; - static int rc_cache; - if (rc_changed(&rc_cache)) { - rc_spell = get_race(RC_SPELL); - } - return (rc!=rc_spell || u->number == RS_FARVISION); -} - /** set region.seen based on visibility by one faction. * * this function may also update ctx->last and ctx->first for potential @@ -1355,9 +1344,7 @@ void prepare_report(report_context *ctx, faction *f) u = building_owner(b); if (u && u->faction==f) { prepare_lighthouse(b, ctx); - if (unit_cansee(u)) { - add_seen_nb(f, r, seen_unit); - } + add_seen_nb(f, r, seen_unit); } } } @@ -1366,9 +1353,7 @@ void prepare_report(report_context *ctx, faction *f) } for (u = r->units; u; u = u->next) { if (u->faction==f) { - if (unit_cansee(u)) { - add_seen_nb(f, r, seen_unit); - } + add_seen_nb(f, r, seen_unit); if (fval(r, RF_LIGHTHOUSE)) { if (u->building && u->building->type == bt_lighthouse && inside_building(u)) { /* we are in a lighthouse. add the regions we can see from here! */ diff --git a/src/reports.test.c b/src/reports.test.c index d9b427ff2..d5801ebab 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -425,6 +425,29 @@ static void test_seen_travelthru(CuTest *tc) { test_cleanup(); } +static void test_report_far_vision(CuTest *tc) { + unit *u1, *u2; + faction *f; + region *r1, *r2; + const race *rc; + test_setup(); + f = test_create_faction(0); + r1 = test_create_region(0, 0, 0); + u1 = test_create_unit(f, r1); + r2 = test_create_region(10, 0, 0); + rc = test_create_race("spell"); + u2 = create_unit(r2, u1->faction, 1, rc, 0, "spell/dreamreading", NULL); + set_number(u2, 1); + report_context ctx; + prepare_report(&ctx, f); + CuAssertPtrEquals(tc, r1, ctx.first); + CuAssertPtrEquals(tc, 0, ctx.last); + CuAssertIntEquals(tc, seen_unit, r1->seen.mode); + CuAssertIntEquals(tc, seen_unit, r2->seen.mode); + finish_reports(&ctx); + test_cleanup(); +} + CuSuite *get_reports_suite(void) { CuSuite *suite = CuSuiteNew(); @@ -434,6 +457,7 @@ CuSuite *get_reports_suite(void) SUITE_ADD_TEST(suite, test_prepare_lighthouse); SUITE_ADD_TEST(suite, test_prepare_lighthouse_capacity); SUITE_ADD_TEST(suite, test_prepare_travelthru); + SUITE_ADD_TEST(suite, test_report_far_vision); SUITE_ADD_TEST(suite, test_reorder_units); SUITE_ADD_TEST(suite, test_seen_faction); SUITE_ADD_TEST(suite, test_regionid); diff --git a/src/spells.c b/src/spells.c index 4f2d49d9d..84700926c 100644 --- a/src/spells.c +++ b/src/spells.c @@ -4168,7 +4168,7 @@ static int sp_pump(castorder * co) } u = - create_unit(rt, mage->faction, RS_FARVISION, get_race(RC_SPELL), 0, + create_unit(rt, mage->faction, 1, get_race(RC_SPELL), 0, "spell/pump", NULL); u->age = 2; set_level(u, SK_PERCEPTION, effskill(target, SK_PERCEPTION, 0)); @@ -4812,9 +4812,8 @@ int sp_dreamreading(castorder * co) } u2 = - create_unit(u->region, mage->faction, RS_FARVISION, get_race(RC_SPELL), 0, + create_unit(u->region, mage->faction, 1, get_race(RC_SPELL), 0, "spell/dreamreading", NULL); - set_number(u2, 1); u2->age = 2; /* Nur fuer diese Runde. */ set_level(u2, SK_PERCEPTION, effskill(u, SK_PERCEPTION, u2->region)); @@ -5691,7 +5690,7 @@ int sp_viewreality(castorder * co) region *rt = rl2->data; if (!is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) { u = - create_unit(rt, mage->faction, RS_FARVISION, get_race(RC_SPELL), 0, + create_unit(rt, mage->faction, 1, get_race(RC_SPELL), 0, "spell/viewreality", NULL); set_level(u, SK_PERCEPTION, co->level / 2); u->age = 2; From de58fa6aa08bf69b76e5b07d287b54061d55f550 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 24 Sep 2016 20:50:35 +0200 Subject: [PATCH 02/12] harmless refactoring: create RC_SPELL units from a common function. --- src/spells.c | 34 ++++++++++++++-------------------- src/spells.h | 1 - 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/spells.c b/src/spells.c index 84700926c..ce0a8d980 100644 --- a/src/spells.c +++ b/src/spells.c @@ -4111,6 +4111,14 @@ static int sp_bigrecruit(castorder * co) return cast_level; } +static void watch_region(region *r, faction *f, int perception) { + unit *u; + + u = create_unit(r, f, 1, get_race(RC_SPELL), 0, NULL, NULL); + u->age = 2; + set_level(u, SK_PERCEPTION, perception); +} + /* ------------------------------------------------------------- */ /* Name: Aushorchen * Stufe: 7 @@ -4167,12 +4175,7 @@ static int sp_pump(castorder * co) return cast_level / 2; } - u = - create_unit(rt, mage->faction, 1, get_race(RC_SPELL), 0, - "spell/pump", NULL); - u->age = 2; - set_level(u, SK_PERCEPTION, effskill(target, SK_PERCEPTION, 0)); - + watch_region(rt, mage->faction, effskill(target, SK_PERCEPTION, 0)); return cast_level; } @@ -4778,7 +4781,7 @@ int sp_clonecopy(castorder * co) /* ------------------------------------------------------------- */ int sp_dreamreading(castorder * co) { - unit *u, *u2; + unit *u; region *r = co_get_region(co); unit *mage = co->magician.u; int cast_level = co->level; @@ -4811,11 +4814,7 @@ int sp_dreamreading(castorder * co) return 0; } - u2 = - create_unit(u->region, mage->faction, 1, get_race(RC_SPELL), 0, - "spell/dreamreading", NULL); - u2->age = 2; /* Nur fuer diese Runde. */ - set_level(u2, SK_PERCEPTION, effskill(u, SK_PERCEPTION, u2->region)); + watch_region(u->region, mage->faction, effskill(u, SK_PERCEPTION, u->region)); msg = msg_message("sp_dreamreading_effect", "mage unit region", mage, u, @@ -5612,7 +5611,7 @@ int sp_showastral(castorder * co) region *r2 = rl2->data; if (!is_cursed(r2->attribs, C_ASTRALBLOCK, 0)) { for (u = r2->units; u; u = u->next) { - if (u_race(u) != get_race(RC_SPECIAL) && u_race(u) != get_race(RC_SPELL)) + if (u_race(u) != get_race(RC_SPELL)) n++; } } @@ -5632,7 +5631,7 @@ int sp_showastral(castorder * co) for (rl2 = rl; rl2; rl2 = rl2->next) { if (!is_cursed(rl2->data->attribs, C_ASTRALBLOCK, 0)) { for (u = rl2->data->units; u; u = u->next) { - if (u_race(u) != get_race(RC_SPECIAL) && u_race(u) != get_race(RC_SPELL)) { + if (u_race(u) != get_race(RC_SPELL)) { c++; scat(unitname(u)); scat(" ("); @@ -5670,7 +5669,6 @@ int sp_showastral(castorder * co) int sp_viewreality(castorder * co) { region_list *rl, *rl2; - unit *u; region *r = co_get_region(co); unit *mage = co->magician.u; int cast_level = co->level; @@ -5689,11 +5687,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)) { - u = - create_unit(rt, mage->faction, 1, get_race(RC_SPELL), 0, - "spell/viewreality", NULL); - set_level(u, SK_PERCEPTION, co->level / 2); - u->age = 2; + watch_region(rt, mage->faction, co->level / 2); } } diff --git a/src/spells.h b/src/spells.h index 65270a164..1ad68e131 100644 --- a/src/spells.h +++ b/src/spells.h @@ -28,7 +28,6 @@ extern "C" { struct message; void register_spells(void); - void set_spelldata(struct spell *sp); int sp_baddreams(castorder * co); int sp_gooddreams(castorder * co); From 4353773c3ba5b6f1c8b17254815a06ad6e635bc9 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sat, 24 Sep 2016 21:09:15 +0200 Subject: [PATCH 03/12] far_vision test uses watch_region, checkes faction.interval --- src/reports.test.c | 8 +++++--- src/spells.c | 3 ++- src/spells.h | 4 ++++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/reports.test.c b/src/reports.test.c index d5801ebab..91e052683 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -6,6 +6,7 @@ #include "lighthouse.h" #include "travelthru.h" #include "keyword.h" +#include "spells.h" #include #include @@ -426,7 +427,7 @@ static void test_seen_travelthru(CuTest *tc) { } static void test_report_far_vision(CuTest *tc) { - unit *u1, *u2; + unit *u1; faction *f; region *r1, *r2; const race *rc; @@ -436,8 +437,9 @@ static void test_report_far_vision(CuTest *tc) { u1 = test_create_unit(f, r1); r2 = test_create_region(10, 0, 0); rc = test_create_race("spell"); - u2 = create_unit(r2, u1->faction, 1, rc, 0, "spell/dreamreading", NULL); - set_number(u2, 1); + watch_region(r2, f, 10); + CuAssertPtrEquals(tc, r1, f->first); + CuAssertPtrEquals(tc, r2, f->last); report_context ctx; prepare_report(&ctx, f); CuAssertPtrEquals(tc, r1, ctx.first); diff --git a/src/spells.c b/src/spells.c index ce0a8d980..b14b588ee 100644 --- a/src/spells.c +++ b/src/spells.c @@ -4111,7 +4111,8 @@ static int sp_bigrecruit(castorder * co) return cast_level; } -static void watch_region(region *r, faction *f, int perception) { +void watch_region(region *r, faction *f, int perception) +{ unit *u; u = create_unit(r, f, 1, get_race(RC_SPELL), 0, NULL, NULL); diff --git a/src/spells.h b/src/spells.h index 1ad68e131..c10ee1c6c 100644 --- a/src/spells.h +++ b/src/spells.h @@ -25,10 +25,14 @@ extern "C" { struct ship; struct curse; struct unit; + struct faction; + struct region; struct message; void register_spells(void); + void watch_region(struct region *r, struct faction *f, int perception); + int sp_baddreams(castorder * co); int sp_gooddreams(castorder * co); From 15702daf995009b97b8dfad6b22347a08ab3f54e Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 25 Sep 2016 13:01:51 +0200 Subject: [PATCH 04/12] Add a new attribute and RF_OBSERVER flag. --- src/creport.c | 4 +- src/kernel/region.h | 2 +- src/kernel/types.h | 2 +- src/report.c | 25 ++-- src/reports.c | 10 +- src/reports.test.c | 4 +- src/spells.c | 280 ++++++++++++++++++++++++++++---------------- src/spells.h | 3 +- src/spells.test.c | 20 ++++ 9 files changed, 226 insertions(+), 124 deletions(-) diff --git a/src/creport.c b/src/creport.c index 5e7442030..373cff2dc 100644 --- a/src/creport.c +++ b/src/creport.c @@ -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_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)) { /* Sonderbehandlung Teleport-Ebene */ 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); - if (r->seen.mode == seen_unit || r->seen.mode == seen_travel) { + if (r->seen.mode >= seen_travel) { message_list *mlist = r_getmessages(r, f); cr_output_messages(F, r->msgs, f); if (mlist) { diff --git a/src/kernel/region.h b/src/kernel/region.h index 6e231529d..f68a58fc5 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -34,7 +34,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define RF_MALLORN (1<<1) /* 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_5 (1<<5) #define RF_UNUSED_6 (1<<6) diff --git a/src/kernel/types.h b/src/kernel/types.h index e0521635e..99daaf521 100644 --- a/src/kernel/types.h +++ b/src/kernel/types.h @@ -79,8 +79,8 @@ typedef enum { seen_neighbour, seen_lighthouse, seen_travel, - seen_far, seen_unit, + seen_spell, seen_battle } seen_mode; diff --git a/src/report.c b/src/report.c index c7093da73..ed448190c 100644 --- a/src/report.c +++ b/src/report.c @@ -992,7 +992,7 @@ static void describe(stream *out, const region * r, faction * f) } /* iron & stone */ - if (r->seen.mode == seen_unit) { + if (r->seen.mode >= seen_unit) { resource_report result[MAX_RAWMATERIALS]; 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; 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)) { /* Sonderbehandlung Teleport-Ebene */ region_list *rl = astralregions(r, inhabitable); @@ -2285,7 +2285,7 @@ report_plaintext(const char *filename, report_context * ctx, continue; /* Beschreibung */ - if (r->seen.mode == seen_unit) { + if (r->seen.mode >= seen_unit) { anyunits = 1; describe(out, r, f); if (markets_module() && r->land) { @@ -2317,27 +2317,18 @@ report_plaintext(const char *filename, report_context * ctx, 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 { - describe(out, r, f); - newline(out); - write_travelthru(out, r, f); - } + describe(out, r, f); + newline(out); + write_travelthru(out, r, f); } /* Statistik */ - if (wants_stats && r->seen.mode == seen_unit) + if (wants_stats && r->seen.mode >= seen_unit) statistics(out, r, f); /* 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 message_list *mlist = r_getmessages(r, f); if (mlist) { diff --git a/src/reports.c b/src/reports.c index dc0edf1b3..92955e448 100644 --- a/src/reports.c +++ b/src/reports.c @@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "reports.h" #include "laws.h" +#include "spells.h" #include "travelthru.h" #include "lighthouse.h" #include "donations.h" @@ -92,6 +93,7 @@ const char *visibility[] = { "travel", "far", "unit", + "spell", "battle" }; @@ -943,9 +945,9 @@ const struct unit *ucansee(const struct faction *f, const struct unit *u, int stealth_modifier(seen_mode mode) { switch (mode) { + case seen_spell: case seen_unit: return 0; - case seen_far: case seen_lighthouse: return -2; 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) { 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)) { /* region owners get the report from lighthouses */ if (rule_region_owners && bt_lighthouse) { diff --git a/src/reports.test.c b/src/reports.test.c index 91e052683..72c8e46eb 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -437,7 +437,7 @@ static void test_report_far_vision(CuTest *tc) { u1 = test_create_unit(f, r1); r2 = test_create_region(10, 0, 0); rc = test_create_race("spell"); - watch_region(r2, f, 10); + set_observer(r2, f, 10); CuAssertPtrEquals(tc, r1, f->first); CuAssertPtrEquals(tc, r2, f->last); report_context ctx; @@ -445,7 +445,7 @@ static void test_report_far_vision(CuTest *tc) { CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, 0, ctx.last); CuAssertIntEquals(tc, seen_unit, r1->seen.mode); - CuAssertIntEquals(tc, seen_unit, r2->seen.mode); + CuAssertIntEquals(tc, seen_spell, r2->seen.mode); finish_reports(&ctx); test_cleanup(); } diff --git a/src/spells.c b/src/spells.c index b14b588ee..8e3887fd9 100644 --- a/src/spells.c +++ b/src/spells.c @@ -1,4 +1,4 @@ -/* +/* * * * Eressea PB(E)M host Copyright (C) 1998-2015 @@ -32,7 +32,7 @@ #include #include -/* kernel includes */ + /* kernel includes */ #include #include #include @@ -440,40 +440,40 @@ report_effect(region * r, unit * mage, message * seen, message * unseen) * */ -/* ------------------------------------------------------------- */ -/* Name: Vertrauter - * Stufe: 10 - * - * Wirkung: - * Der Magier beschwoert einen Vertrauten, ein kleines Tier, welches - * dem Magier zu Diensten ist. Der Magier kann durch die Augen des - * Vertrauten sehen, und durch den Vertrauten zaubern, allerdings nur - * mit seiner halben Stufe. Je nach Vertrautem erhaelt der Magier - * evtl diverse Skillmodifikationen. Der Typ des Vertrauten ist - * zufaellig bestimmt, wird aber durch Magiegebiet und Rasse beeinflußt. - * "Tierische" Vertraute brauchen keinen Unterhalt. - * - * Ein paar Moeglichkeiten: - * Magieg. Rasse Besonderheiten - * Eule Tybied -/- fliegt, Auraregeneration - * Rabe Ilaun -/- fliegt - * Imp Draig -/- Magieresistenz? - * Fuchs Gwyrrd -/- Wahrnehmung - * ???? Cerddor -/- ???? (Singvogel?, Papagei?) - * Adler -/- -/- fliegt, +Wahrnehmung, =^=Adlerauge-Spruch? - * Kraehe -/- -/- fliegt, +Tarnung (weil unauffaellig) - * Delphin -/- Meerm. schwimmt - * Wolf -/- Ork - * Hund -/- Mensch kann evtl BEWACHE ausfuehren - * Ratte -/- Goblin - * Albatros -/- -/- fliegt, kann auf Ozean "landen" - * Affe -/- -/- kann evtl BEKLAUE ausfuehren - * Goblin -/- !Goblin normale Einheit - * Katze -/- !Katze normale Einheit - * Daemon -/- !Daemon normale Einheit - * - * Spezielle V. fuer Katzen, Trolle, Elfen, Daemonen, Insekten, Zwerge? - */ + /* ------------------------------------------------------------- */ + /* Name: Vertrauter + * Stufe: 10 + * + * Wirkung: + * Der Magier beschwoert einen Vertrauten, ein kleines Tier, welches + * dem Magier zu Diensten ist. Der Magier kann durch die Augen des + * Vertrauten sehen, und durch den Vertrauten zaubern, allerdings nur + * mit seiner halben Stufe. Je nach Vertrautem erhaelt der Magier + * evtl diverse Skillmodifikationen. Der Typ des Vertrauten ist + * zufaellig bestimmt, wird aber durch Magiegebiet und Rasse beeinflußt. + * "Tierische" Vertraute brauchen keinen Unterhalt. + * + * Ein paar Moeglichkeiten: + * Magieg. Rasse Besonderheiten + * Eule Tybied -/- fliegt, Auraregeneration + * Rabe Ilaun -/- fliegt + * Imp Draig -/- Magieresistenz? + * Fuchs Gwyrrd -/- Wahrnehmung + * ???? Cerddor -/- ???? (Singvogel?, Papagei?) + * Adler -/- -/- fliegt, +Wahrnehmung, =^=Adlerauge-Spruch? + * Kraehe -/- -/- fliegt, +Tarnung (weil unauffaellig) + * Delphin -/- Meerm. schwimmt + * Wolf -/- Ork + * Hund -/- Mensch kann evtl BEWACHE ausfuehren + * Ratte -/- Goblin + * Albatros -/- -/- fliegt, kann auf Ozean "landen" + * Affe -/- -/- kann evtl BEKLAUE ausfuehren + * Goblin -/- !Goblin normale Einheit + * Katze -/- !Katze normale Einheit + * Daemon -/- !Daemon normale Einheit + * + * Spezielle V. fuer Katzen, Trolle, Elfen, Daemonen, Insekten, Zwerge? + */ static const race *select_familiar(const race * magerace, magic_t magiegebiet) { @@ -604,7 +604,7 @@ static int sp_summon_familiar(castorder * co) if (dh == 0) { bytes = strlcpy(bufp, (const char *)LOC(mage->faction->locale, - "list_and"), size); + "list_and"), size); } else { bytes = strlcpy(bufp, (const char *)", ", size); @@ -615,7 +615,7 @@ static int sp_summon_familiar(castorder * co) } bytes = strlcpy(bufp, (const char *)skillname((skill_t)sk, mage->faction->locale), - size); + size); assert(bytes <= INT_MAX); if (wrptr(&bufp, &size, (int)bytes) != 0) WARN_STATIC_BUFFER(); @@ -1246,7 +1246,7 @@ static void fumble_ents(const castorder * co) * Flag: * (FARCASTING | SPELLLEVEL | UNITSPELL | TESTCANSEE | TESTRESISTANCE) */ -/* Syntax: ZAUBER [REGION x y] [STUFE 2] "Rosthauch" 1111 2222 3333 */ + /* Syntax: ZAUBER [REGION x y] [STUFE 2] "Rosthauch" 1111 2222 3333 */ typedef struct iron_weapon { const struct item_type *type; @@ -1259,7 +1259,7 @@ static iron_weapon *ironweapons = NULL; void add_ironweapon(const struct item_type *type, const struct item_type *rusty, -float chance) + float chance) { iron_weapon *iweapon = malloc(sizeof(iron_weapon)); assert_alloc(iweapon); @@ -1366,7 +1366,7 @@ static int sp_rosthauch(castorder * co) * Flag: * (UNITSPELL | SPELLLEVEL | ONSHIPCAST | TESTCANSEE) */ -/* Syntax: ZAUBER [STUFE n] "Kaelteschutz" eh1 [eh2 [eh3 [...]]] */ + /* Syntax: ZAUBER [STUFE n] "Kaelteschutz" eh1 [eh2 [eh3 [...]]] */ static int sp_kaelteschutz(castorder * co) { @@ -1410,7 +1410,7 @@ static int sp_kaelteschutz(castorder * co) u)); if (u->faction != mage->faction) ADDMSG(&u->faction->msgs, msg_message("heat_effect", "mage target", - cansee(u->faction, r, mage, 0) ? mage : NULL, u)); + cansee(u->faction, r, mage, 0) ? mage : NULL, u)); i = cast_level; } /* Erstattung? */ @@ -1430,7 +1430,7 @@ static int sp_kaelteschutz(castorder * co) * Flag: * (UNITSPELL | TESTCANSEE | SPELLLEVEL) */ -/* Syntax: ZAUBER "Funkenregen" eh1 */ + /* Syntax: ZAUBER "Funkenregen" eh1 */ static int sp_sparkle(castorder * co) { @@ -1503,11 +1503,11 @@ static int sp_create_irongolem(castorder * co) int number = lovar(force * 8 * RESOURCE_QUANTITY); static int cache; static const race * golem_rc; - + if (rc_changed(&cache)) { golem_rc = rc_find("irongolem"); } - + if (number < 1) { number = 1; } @@ -1529,8 +1529,8 @@ static int sp_create_irongolem(castorder * co) ADDMSG(&mage->faction->msgs, msg_message("magiccreate_effect", "region command unit amount object", - mage->region, co->order, mage, number, - LOC(mage->faction->locale, rc_name_s(golem_rc, (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); + mage->region, co->order, mage, number, + LOC(mage->faction->locale, rc_name_s(golem_rc, (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); return cast_level; } @@ -1572,7 +1572,7 @@ static int sp_create_stonegolem(castorder * co) int number = lovar(co->force * 5 * RESOURCE_QUANTITY); static int cache; static const race * golem_rc; - + if (rc_changed(&cache)) { golem_rc = rc_find("stonegolem"); } @@ -1596,8 +1596,8 @@ static int sp_create_stonegolem(castorder * co) ADDMSG(&mage->faction->msgs, msg_message("magiccreate_effect", "region command unit amount object", - mage->region, co->order, mage, number, - LOC(mage->faction->locale, rc_name_s(golem_rc, (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); + mage->region, co->order, mage, number, + LOC(mage->faction->locale, rc_name_s(golem_rc, (u2->number == 1) ? NAME_SINGULAR : NAME_PLURAL)))); return cast_level; } @@ -2203,17 +2203,17 @@ static int sp_ironkeeper(castorder * co) fset(keeper, UFL_ANON_FACTION); } - { - trigger *tkill = trigger_killunit(keeper); - add_trigger(&keeper->attribs, "timer", trigger_timeout(cast_level + 2, - tkill)); - } + { + trigger *tkill = trigger_killunit(keeper); + add_trigger(&keeper->attribs, "timer", trigger_timeout(cast_level + 2, + tkill)); + } - msg = msg_message("summon_effect", "mage amount race", mage, 1, u_race(keeper)); - r_addmessage(r, NULL, msg); - msg_release(msg); + msg = msg_message("summon_effect", "mage amount race", mage, 1, u_race(keeper)); + r_addmessage(r, NULL, msg); + msg_release(msg); - return cast_level; + return cast_level; } /* ------------------------------------------------------------- */ @@ -2384,7 +2384,7 @@ void patzer_peasantmob(const castorder * co) u = create_unit(r, f, n, get_race(RC_PEASANT), 0, LOC(f->locale, "angry_mob"), - NULL); + NULL); fset(u, UFL_ISNEW); /* guard(u, GUARD_ALL); hier zu frueh! Befehl BEWACHE setzten */ addlist(&u->orders, create_order(K_GUARD, lang, NULL)); @@ -2457,7 +2457,7 @@ static int sp_forest_fire(castorder * co) freset(u->faction, FFL_SELECT); msg = msg_message("forestfire_effect", "mage region amount", mage, r, - destroyed + vernichtet_schoesslinge); + destroyed + vernichtet_schoesslinge); r_addmessage(r, NULL, msg); add_message(&mage->faction->msgs, msg); msg_release(msg); @@ -2627,10 +2627,10 @@ static int sp_summondragon(castorder * co) number = 6; break; } - { - trigger *tsummon = trigger_createunit(r, f, race, number); - add_trigger(&r->attribs, "timer", trigger_timeout(time, tsummon)); - } + { + trigger *tsummon = trigger_createunit(r, f, race, number); + add_trigger(&r->attribs, "timer", trigger_timeout(time, tsummon)); + } } } @@ -2705,15 +2705,15 @@ static int sp_firewall(castorder * co) } /* melden, 1x pro Partei */ - { - message *seen = msg_message("firewall_effect", "mage region", mage, r); - message *unseen = msg_message("firewall_effect", "mage region", NULL, r); - report_effect(r, mage, seen, unseen); - msg_release(seen); - msg_release(unseen); - } + { + message *seen = msg_message("firewall_effect", "mage region", mage, r); + message *unseen = msg_message("firewall_effect", "mage region", NULL, r); + report_effect(r, mage, seen, unseen); + msg_release(seen); + msg_release(unseen); + } - return cast_level; + return cast_level; } /* ------------------------------------------------------------- */ @@ -2861,7 +2861,7 @@ static int dc_age(struct curse *c) damage *= (1.0 - magic_resistance(u)); hp = change_hitpoints(u, -(int)damage); - ADDMSG(&u->faction->msgs, msg_message((hp>0)?"poison_damage":"poison_death", "region unit", r, u)); + ADDMSG(&u->faction->msgs, msg_message((hp > 0) ? "poison_damage" : "poison_death", "region unit", r, u)); if (*up == u) up = &u->next; } @@ -2916,7 +2916,7 @@ static int dc_read_compat(struct attrib *a, void *target, gamedata *data) effect = strength; c = create_curse(u, &r->attribs, &ct_deathcloud, strength * 2, duration, - effect, 0); + effect, 0); c->data.v = r; if (u == NULL) { ur_add(var, &c->magician, resolve_unit); @@ -3123,7 +3123,7 @@ static bool chaosgate_valid(const connection * b) } static struct region *chaosgate_move(const connection * b, struct unit *u, -struct region *from, struct region *to, bool routing) + struct region *from, struct region *to, bool routing) { if (!routing) { int maxhp = u->hp / 4; @@ -3317,7 +3317,7 @@ static int sp_bloodsacrifice(castorder * co) change_spellpoints(mage, aura); ADDMSG(&mage->faction->msgs, msg_message("sp_bloodsacrifice_effect", - "unit region command amount", mage, mage->region, co->order, aura)); + "unit region command amount", mage, mage->region, co->order, aura)); return cast_level; } @@ -3811,7 +3811,7 @@ static int sp_raisepeasantmob(castorder * co) u = create_unit(r, monsters, n, get_race(RC_PEASANT), 0, LOC(monsters->locale, - "furious_mob"), NULL); + "furious_mob"), NULL); fset(u, UFL_ISNEW); guard(u, GUARD_ALL); a = a_new(&at_unitdissolve); @@ -4111,13 +4111,92 @@ static int sp_bigrecruit(castorder * co) return cast_level; } -void watch_region(region *r, faction *f, int perception) -{ - unit *u; +typedef struct obs_data { + faction *f; + int skill; + int timer; +} obs_data; - u = create_unit(r, f, 1, get_race(RC_SPELL), 0, NULL, NULL); - u->age = 2; - set_level(u, SK_PERCEPTION, perception); +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)); } /* ------------------------------------------------------------- */ @@ -4133,7 +4212,7 @@ void watch_region(region *r, faction *f, int perception) * (UNITSPELL | TESTCANSEE) */ -/* restistenz der einheit pruefen */ + /* restistenz der einheit pruefen */ static int sp_pump(castorder * co) { unit *u, *target; @@ -4176,7 +4255,7 @@ static int sp_pump(castorder * co) 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; } @@ -4400,7 +4479,7 @@ static int sp_raisepeasants(castorder * co) u2 = create_unit(r, mage->faction, bauern, get_race(RC_PEASANT), 0, - LOC(mage->faction->locale, "furious_mob"), mage); + LOC(mage->faction->locale, "furious_mob"), mage); fset(u2, UFL_LOCKED); if (rule_stealth_anon()) { @@ -4414,7 +4493,7 @@ static int sp_raisepeasants(castorder * co) msg = msg_message("sp_raisepeasants_effect", "mage region amount", mage, r, - u2->number); + u2->number); r_addmessage(r, NULL, msg); if (mage->region != r) { add_message(&mage->faction->msgs, msg); @@ -4527,7 +4606,7 @@ int sp_icastle(castorder * co) if (type == bt_illusion) { b->size = (rng_int() % (int)((power * power) + 1) * 10); } - else if (type->maxsize >0) { + else if (type->maxsize > 0) { b->size = type->maxsize; } else { @@ -4766,7 +4845,7 @@ int sp_clonecopy(castorder * co) "clone_of"), unitname(mage)); clone = create_unit(target_region, mage->faction, 1, get_race(RC_CLONE), 0, name, - mage); + mage); setstatus(clone, ST_FLEE); fset(clone, UFL_LOCKED); @@ -4815,11 +4894,11 @@ int sp_dreamreading(castorder * co) 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_message("sp_dreamreading_effect", "mage unit region", mage, u, - u->region); + u->region); r_addmessage(r, mage->faction, msg); msg_release(msg); return cast_level; @@ -5622,7 +5701,8 @@ int sp_showastral(castorder * co) /* sprintf(buf, "%s kann niemanden im astralen Nebel entdecken.", unitname(mage)); */ cmistake(mage, co->order, 220, MSG_MAGIC); - } else { + } + else { /* Ausgeben */ @@ -5642,13 +5722,14 @@ int sp_showastral(castorder * co) } icat(u->number); scat(" "); - scat(LOC(mage->faction->locale, rc_name_s(u_race(u), (u->number==1) ? NAME_SINGULAR:NAME_PLURAL))); + scat(LOC(mage->faction->locale, rc_name_s(u_race(u), (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL))); scat(", Entfernung "); icat(distance(rl2->data, rt)); scat(")"); if (c == n - 1) { scat(" und "); - } else if (c < n - 1) { + } + else if (c < n - 1) { scat(", "); } } @@ -5688,7 +5769,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)) { - watch_region(rt, mage->faction, co->level / 2); + set_observer(rt, mage->faction, co->level / 2); } } @@ -6262,8 +6343,8 @@ int sp_speed2(castorder * co) * Flags: * (FARCASTING | SPELLLEVEL | ONSHIPCAST | TESTCANSEE) */ -/* Jeder gebrochene Zauber verbraucht c->vigour an Zauberkraft - * (force) */ + /* Jeder gebrochene Zauber verbraucht c->vigour an Zauberkraft + * (force) */ int sp_q_antimagie(castorder * co) { attrib **ap; @@ -6411,7 +6492,7 @@ int sp_break_curse(castorder * co) /* Es wurde kein Ziel gefunden */ ADDMSG(&mage->faction->msgs, msg_message("spelltargetnotfound", "unit region command", - mage, mage->region, co->order)); + mage, mage->region, co->order)); } /* curse aufloesen, wenn zauber staerker (force > vigour) */ @@ -6718,6 +6799,7 @@ void register_spells(void) register_borders(); at_register(&at_wdwpyramid); + at_register(&at_observer); at_register(&at_deathcloud_compat); /* init_firewall(); */ diff --git a/src/spells.h b/src/spells.h index c10ee1c6c..6e1b194e6 100644 --- a/src/spells.h +++ b/src/spells.h @@ -31,7 +31,8 @@ extern "C" { 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_gooddreams(castorder * co); diff --git a/src/spells.test.c b/src/spells.test.c index 3c773d489..a3f624d40 100644 --- a/src/spells.test.c +++ b/src/spells.test.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -106,9 +107,28 @@ static void test_bad_dreams(CuTest *tc) { 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 *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_watch_region); SUITE_ADD_TEST(suite, test_good_dreams); SUITE_ADD_TEST(suite, test_bad_dreams); SUITE_ADD_TEST(suite, test_dreams); From 0755830754f7249957e0c6ce017f08e24d95410c Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Sun, 21 May 2017 23:47:54 +0200 Subject: [PATCH 05/12] fix compilation, test still fails --- src/laws.test.c | 4 ---- src/reports.test.c | 6 ++---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/laws.test.c b/src/laws.test.c index 7e5df0b56..4d6adbfe9 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -1446,10 +1446,6 @@ static void test_show_both(CuTest *tc) { test_cleanup(); } -static int low_wage(const region * r, const faction * f, const race * rc, int in_turn) { - return 1; -} - static void test_immigration(CuTest * tc) { region *r; diff --git a/src/reports.test.c b/src/reports.test.c index dd27ee360..f602ade46 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -714,16 +714,14 @@ static void test_region_distance_ql(CuTest *tc) { } static void test_report_far_vision(CuTest *tc) { - unit *u1; faction *f; region *r1, *r2; - const race *rc; test_setup(); f = test_create_faction(0); r1 = test_create_region(0, 0, 0); - u1 = test_create_unit(f, r1); + test_create_unit(f, r1); r2 = test_create_region(10, 0, 0); - rc = test_create_race("spell"); + test_create_race("spell"); set_observer(r2, f, 10); CuAssertPtrEquals(tc, r1, f->first); CuAssertPtrEquals(tc, r2, f->last); From 17ed46e6a8b15205793f666d383178d09fbb3738 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 22 May 2017 19:50:18 +0200 Subject: [PATCH 06/12] fix test --- src/reports.test.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/reports.test.c b/src/reports.test.c index dd27ee360..88219a5d5 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -547,6 +547,7 @@ static void test_prepare_lighthouse_owners(CuTest *tc) const struct terrain_type *t_ocean, *t_plain; test_setup(); + enable_skill(SK_PERCEPTION, false); config_set("rules.region_owner_pay_building", "lighthouse"); config_set("rules.region_owners", "1"); t_ocean = test_create_terrain("ocean", SEA_REGION); @@ -555,6 +556,7 @@ static void test_prepare_lighthouse_owners(CuTest *tc) r1 = test_create_region(0, 0, t_plain); r2 = test_create_region(1, 0, t_ocean); r3 = test_create_region(2, 0, t_ocean); + r3 = test_create_region(3, 0, t_ocean); btype = test_create_buildingtype("lighthouse"); b = test_create_building(r1, btype); b->flags |= BLD_MAINTAINED; @@ -564,8 +566,7 @@ static void test_prepare_lighthouse_owners(CuTest *tc) u = test_create_unit(test_create_faction(0), r1); u->building = b; region_set_owner(b->region, f, 0); - set_level(u, SK_PERCEPTION, 3); - CuAssertIntEquals(tc, 2, lighthouse_range(b, f, NULL)); + CuAssertIntEquals(tc, 2, lighthouse_range(b, NULL, NULL)); prepare_report(&ctx, f); CuAssertPtrEquals(tc, r1, ctx.first); CuAssertPtrEquals(tc, NULL, ctx.last); From 51f8f87072f9197fa589b9cf7bbdc94dd172263a Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 22 May 2017 21:15:42 +0200 Subject: [PATCH 07/12] eliminate the O(n) lighthouse/inside complexity from prepare_report --- src/reports.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/reports.c b/src/reports.c index 146a8529f..934a5ae36 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1425,7 +1425,8 @@ void prepare_report(report_context *ctx, faction *f) for (r = ctx->first; r!=ctx->last; r = r->next) { unit *u; - int range = 0; + building *b; + int br = 0, c = 0, range = 0; if (fval(r, RF_OBSERVER)) { int skill = get_observer(r, f); if (skill >= 0) { @@ -1435,7 +1436,6 @@ void prepare_report(report_context *ctx, faction *f) if (fval(r, RF_LIGHTHOUSE)) { /* region owners get the report from lighthouses */ if (rule_region_owners && f == region_get_owner(r)) { - building *b; for (b = rbuildings(r); b; b = b->next) { if (b && b->type == bt_lighthouse) { /* region owners get maximm range */ @@ -1445,6 +1445,8 @@ void prepare_report(report_context *ctx, faction *f) } } } + + b = NULL; for (u = r->units; u; u = u->next) { /* if we have any unit in this region, then we get seen_unit access */ if (u->faction == f) { @@ -1453,13 +1455,27 @@ void prepare_report(report_context *ctx, faction *f) * or the size, if perception is not a skill */ if (!fval(r, RF_LIGHTHOUSE)) { - /* it's enough to mark the region once, and if there are + /* it's enough to add the region once, and if there are * no lighthouses, there is no need to look at more units */ break; } - if (range == 0 && u->building && u->building->type == bt_lighthouse && inside_building(u)) { - int br = lighthouse_range(u->building, f, u); - if (br > range) range = br; + } + if (range == 0 && u->building && u->building->type == bt_lighthouse) { + if (u->building && b != u->building) { + b = u->building; + c = buildingcapacity(b); + br = 0; + } + c -= u->number; + if (u->faction == f && c >= 0) { + /* unit is one of ours, and inside the current lighthouse */ + if (br == 0) { + /* lazy-calculate the range */ + br = lighthouse_range(u->building, f, u); + } + if (br > range) { + range = br; + } } } } From 95a9bb4ab904b579058c2607d65ceeaddc477f69 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 22 May 2017 21:53:10 +0200 Subject: [PATCH 08/12] register missing attribute. --- src/spells.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/spells.c b/src/spells.c index fa3d9a368..da60bfc57 100644 --- a/src/spells.c +++ b/src/spells.c @@ -6848,7 +6848,8 @@ 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); ct_register(&ct_deathcloud); From 611d69908fb82079d83071566978f6717301faef Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 22 May 2017 22:08:18 +0200 Subject: [PATCH 09/12] remove unnecessary code. --- src/spells.test.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/spells.test.c b/src/spells.test.c index b6d3a2ab7..3a048e021 100644 --- a/src/spells.test.c +++ b/src/spells.test.c @@ -113,8 +113,6 @@ 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)); From 30cfe2c0c0c4306f7a1f4f2f61dbc7575eca8a3d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 24 May 2017 08:18:55 +0200 Subject: [PATCH 10/12] 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); From 18daa9db2f14a8d25d718195480581fbdee4cdd6 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 24 May 2017 08:52:19 +0200 Subject: [PATCH 11/12] entirely remove RC_SPELL --- src/chaos.c | 10 ++---- src/economy.c | 5 ++- src/give.c | 7 +---- src/kernel/race.c | 2 +- src/kernel/race.h | 3 +- src/kernel/save.c | 6 ++-- src/kernel/unit.c | 3 +- src/kernel/unit.test.c | 21 ------------- src/laws.c | 22 +++---------- src/magic.c | 6 +--- src/randenc.c | 2 +- src/spells.c | 71 ++++++++++++++++++++---------------------- src/util/gamedata.h | 3 +- src/volcano.c | 2 +- 14 files changed, 54 insertions(+), 109 deletions(-) diff --git a/src/chaos.c b/src/chaos.c index 58cd7af73..5628b68f4 100644 --- a/src/chaos.c +++ b/src/chaos.c @@ -112,9 +112,7 @@ static unit *random_unit(const region * r) unit *u; for (u = r->units; u; u = u->next) { - if (u_race(u) != get_race(RC_SPELL)) { - c += u->number; - } + c += u->number; } if (c == 0) { @@ -125,9 +123,7 @@ static unit *random_unit(const region * r) u = r->units; while (u && c < n) { - if (u_race(u) != get_race(RC_SPELL)) { - c += u->number; - } + c += u->number; u = u->next; } @@ -203,7 +199,7 @@ static void chaos(region * r) for (up = &r->units; *up;) { unit *u = *up; - if (u_race(u) != get_race(RC_SPELL) && u->ship == 0 && !canfly(u)) { + if (u->ship == 0 && !canfly(u)) { ADDMSG(&u->faction->msgs, msg_message("tidalwave_kill", "region unit", r, u)); remove_unit(up, u); diff --git a/src/economy.c b/src/economy.c index 0bc056b56..3e13f0643 100644 --- a/src/economy.c +++ b/src/economy.c @@ -2978,13 +2978,12 @@ void produce(struct region *r) static int bt_cache; static const struct building_type *caravan_bt; static int rc_cache; - static const race *rc_spell, *rc_insect, *rc_aquarian; + static const race *rc_insect, *rc_aquarian; if (bt_changed(&bt_cache)) { caravan_bt = bt_find("caravan"); } if (rc_changed(&rc_cache)) { - rc_spell = get_race(RC_SPELL); rc_insect = get_race(RC_INSECT); rc_aquarian = get_race(RC_AQUARIAN); } @@ -3022,7 +3021,7 @@ void produce(struct region *r) bool trader = false; keyword_t todo; - if (u_race(u) == rc_spell || fval(u, UFL_LONGACTION)) + if (fval(u, UFL_LONGACTION)) continue; if (u_race(u) == rc_insect && r_insectstalled(r) && diff --git a/src/give.c b/src/give.c index 060ecbbb9..26b193d0d 100644 --- a/src/give.c +++ b/src/give.c @@ -667,12 +667,7 @@ void give_cmd(unit * u, order * ord) return; } - if (u2 && u_race(u2) == get_race(RC_SPELL)) { - ADDMSG(&u->faction->msgs, msg_feedback(u, ord, - "feedback_unit_not_found", "")); - return; - } - else if (u2 && !alliedunit(u2, u->faction, HELP_GIVE) && !ucontact(u2, u)) { + if (u2 && !alliedunit(u2, u->faction, HELP_GIVE) && !ucontact(u2, u)) { cmistake(u, ord, 40, MSG_COMMERCE); return; } diff --git a/src/kernel/race.c b/src/kernel/race.c index a2c37d87d..14fb66331 100644 --- a/src/kernel/race.c +++ b/src/kernel/race.c @@ -69,7 +69,7 @@ const char *racenames[MAXRACES] = { "dwarf", "elf", NULL, "goblin", "human", "troll", "demon", "insect", "halfling", "cat", "aquarian", "orc", "snotling", "undead", NULL, "youngdragon", "dragon", "wyrm", "ent", "catdragon", "dracoid", - NULL, "spell", "irongolem", "stonegolem", "shadowdemon", + NULL, NULL, "irongolem", "stonegolem", "shadowdemon", "shadowmaster", "mountainguard", "alp", "toad", "braineater", "peasant", "wolf", NULL, NULL, NULL, NULL, "songdragon", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/kernel/race.h b/src/kernel/race.h index 5c320ea05..a8933dae8 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -72,8 +72,7 @@ extern "C" { RC_BIRTHDAYDRAGON, RC_DRACOID, - RC_SPELL = 22, - RC_IRONGOLEM, + RC_IRONGOLEM = 23, RC_STONEGOLEM, RC_SHADOW, RC_SHADOWLORD, diff --git a/src/kernel/save.c b/src/kernel/save.c index 983190e7d..7a9e12286 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -132,8 +132,6 @@ static unit *unitorders(FILE * F, int enc, struct faction *f) i = getid(); u = findunitg(i, NULL); - if (u && u_race(u) == get_race(RC_SPELL)) - return NULL; if (u && u->faction == f) { order **ordp; @@ -852,7 +850,7 @@ void write_unit(struct gamedata *data, const unit * u) WRITE_SECTION(data->store); write_items(data->store, u->items); WRITE_SECTION(data->store); - if (u->hp == 0 && u_race(u)!= get_race(RC_SPELL)) { + if (u->hp == 0 && data->version < NORCSPELL_VERSION) { log_error("unit %s has 0 hitpoints, adjusting.", itoa36(u->no)); ((unit *)u)->hp = u->number; } @@ -1707,7 +1705,7 @@ int read_game(gamedata *data) { while (--p >= 0) { unit *u = read_unit(data); - if (u_race(u) == rc_spell) { + if (data->version < NORCSPELL_VERSION && u_race(u) == rc_spell) { set_observer(r, u->faction, get_level(u, SK_PERCEPTION), u->age); free_unit(u); } diff --git a/src/kernel/unit.c b/src/kernel/unit.c index ab5f72f35..4a9540ba9 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -1891,8 +1891,7 @@ void remove_empty_units_in_region(region * r) set_number(u, 0); } } - if ((u->number == 0 && u_race(u) != get_race(RC_SPELL)) || (u->age <= 0 - && u_race(u) == get_race(RC_SPELL))) { + if (u->number == 0) { remove_unit(up, u); } if (*up == u) diff --git a/src/kernel/unit.test.c b/src/kernel/unit.test.c index 096da9d62..54b07b63f 100644 --- a/src/kernel/unit.test.c +++ b/src/kernel/unit.test.c @@ -97,26 +97,6 @@ static void test_remove_units_with_dead_faction(CuTest *tc) { test_cleanup(); } -static void test_remove_units_ignores_spells(CuTest *tc) { - unit *u; - int uid; - - test_cleanup(); - test_create_world(); - - u = create_unit(findregion(0, 0), test_create_faction(test_create_race("human")), 1, test_create_race("spell"), 0, 0, 0); - uid = u->no; - u->number = 0; - u->age = 1; - remove_empty_units_in_region(u->region); - CuAssertPtrNotNull(tc, findunit(uid)); - CuAssertPtrNotNull(tc, u->region); - u->age = 0; - remove_empty_units_in_region(u->region); - CuAssertPtrEquals(tc, 0, findunit(uid)); - test_cleanup(); -} - static void test_scale_number(CuTest *tc) { unit *u; const struct potion_type *ptype; @@ -555,7 +535,6 @@ CuSuite *get_unit_suite(void) SUITE_ADD_TEST(suite, test_update_monster_name); SUITE_ADD_TEST(suite, test_remove_unit); SUITE_ADD_TEST(suite, test_remove_empty_units); - SUITE_ADD_TEST(suite, test_remove_units_ignores_spells); SUITE_ADD_TEST(suite, test_remove_units_without_faction); SUITE_ADD_TEST(suite, test_remove_units_with_dead_faction); SUITE_ADD_TEST(suite, test_remove_empty_units_in_region); diff --git a/src/laws.c b/src/laws.c index e16cbd583..01da6f4ee 100644 --- a/src/laws.c +++ b/src/laws.c @@ -154,22 +154,11 @@ static bool RemoveNMRNewbie(void) static void age_unit(region * r, unit * u) { static int rc_cache; - static const race *rc_spell; + const race *rc = u_race(u); - if (rc_changed(&rc_cache)) { - rc_spell = get_race(RC_SPELL); - } - if (u_race(u) == rc_spell) { - if (--u->age <= 0) { - remove_unit(&r->units, u); - } - } - else { - const race *rc = u_race(u); - ++u->age; - if (u->number > 0 && rc->age_unit) { - rc->age_unit(u); - } + ++u->age; + if (u->number > 0 && rc->age_unit) { + rc->age_unit(u); } if (u->region && is_astral(u->region)) { item **itemp = &u->items; @@ -2676,8 +2665,7 @@ int guard_on_cmd(unit * u, struct order *ord) if (fval(u, UFL_MOVED)) { cmistake(u, ord, 187, MSG_EVENT); } - else if (fval(u_race(u), RCF_ILLUSIONARY) - || u_race(u) == get_race(RC_SPELL)) { + else if (fval(u_race(u), RCF_ILLUSIONARY)) { cmistake(u, ord, 95, MSG_EVENT); } else { diff --git a/src/magic.c b/src/magic.c index a20fbc477..1af357a7c 100644 --- a/src/magic.c +++ b/src/magic.c @@ -1209,9 +1209,6 @@ target_resists_magic(unit * magician, void *obj, int objtyp, int t_bonus) skill *sv; unit *u = (unit *)obj; - if (u_race(u)==get_race(RC_SPELL)) { - return true; - } at = effskill(magician, SK_MAGIC, 0); for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { @@ -2780,7 +2777,6 @@ void magic(void) int rank; castorder *co; spellrank spellranks[MAX_SPELLRANK]; - const race *rc_spell = get_race(RC_SPELL); const race *rc_insect = get_race(RC_INSECT); memset(spellranks, 0, sizeof(spellranks)); @@ -2790,7 +2786,7 @@ void magic(void) for (u = r->units; u; u = u->next) { order *ord; - if (u->number <= 0 || u_race(u) == rc_spell) + if (u->number <= 0) continue; if (u_race(u) == rc_insect && r_insectstalled(r) && diff --git a/src/randenc.c b/src/randenc.c index ab51d64b1..e46d5fa24 100644 --- a/src/randenc.c +++ b/src/randenc.c @@ -418,7 +418,7 @@ void drown(region * r) while (*up) { unit *u = *up; - if (!(u->ship || u_race(u) == get_race(RC_SPELL) || u->number == 0 || canswim(u) || canfly(u))) { + if (!(u->ship || u->number == 0 || canswim(u) || canfly(u))) { scale_number(u, 0); ADDMSG(&u->faction->msgs, msg_message("drown", "unit region", u, r)); } diff --git a/src/spells.c b/src/spells.c index 36a7656c6..fc8c445b7 100644 --- a/src/spells.c +++ b/src/spells.c @@ -1694,7 +1694,7 @@ static int sp_great_drought(castorder * co) rsetterrain(r, T_OCEAN); /* Einheiten duerfen hier auf keinen Fall geloescht werden! */ for (u = r->units; u; u = u->next) { - if (u_race(u) != get_race(RC_SPELL) && u->ship == 0) { + if (!u->ship) { set_number(u, 0); } } @@ -5601,8 +5601,7 @@ int sp_showastral(castorder * co) region *r2 = rl2->data; if (!is_cursed(r2->attribs, C_ASTRALBLOCK, 0)) { for (u = r2->units; u; u = u->next) { - if (u_race(u) != get_race(RC_SPELL)) - n++; + n++; } } } @@ -5622,26 +5621,24 @@ int sp_showastral(castorder * co) for (rl2 = rl; rl2; rl2 = rl2->next) { if (!is_cursed(rl2->data->attribs, C_ASTRALBLOCK, 0)) { for (u = rl2->data->units; u; u = u->next) { - if (u_race(u) != get_race(RC_SPELL)) { - c++; - scat(unitname(u)); - scat(" ("); - if (!fval(u, UFL_ANON_FACTION)) { - scat(factionname(u->faction)); - scat(", "); - } - icat(u->number); - scat(" "); - scat(LOC(mage->faction->locale, rc_name_s(u_race(u), (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL))); - scat(", Entfernung "); - icat(distance(rl2->data, rt)); - scat(")"); - if (c == n - 1) { - scat(" und "); - } - else if (c < n - 1) { - scat(", "); - } + c++; + scat(unitname(u)); + scat(" ("); + if (!fval(u, UFL_ANON_FACTION)) { + scat(factionname(u->faction)); + scat(", "); + } + icat(u->number); + scat(" "); + scat(LOC(mage->faction->locale, rc_name_s(u_race(u), (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL))); + scat(", Entfernung "); + icat(distance(rl2->data, rt)); + scat(")"); + if (c == n - 1) { + scat(" und "); + } + else if (c < n - 1) { + scat(", "); } } } @@ -5758,24 +5755,22 @@ int sp_disruptastral(castorder * co) if (trl != NULL) { for (u = r2->units; u; u = u->next) { - if (u_race(u) != get_race(RC_SPELL)) { - region_list *trl2 = trl; - region *tr; - int c = rng_int() % inhab_regions; + region_list *trl2 = trl; + region *tr; + int c = rng_int() % inhab_regions; - /* Zufaellige Zielregion suchen */ - while (c-- != 0) - trl2 = trl2->next; - tr = trl2->data; + /* Zufaellige Zielregion suchen */ + while (c-- != 0) + trl2 = trl2->next; + tr = trl2->data; - if (!is_magic_resistant(mage, u, 0) && can_survive(u, tr)) { - message *msg = msg_message("disrupt_astral", "unit region", u, tr); - add_message(&u->faction->msgs, msg); - add_message(&tr->msgs, msg); - msg_release(msg); + if (!is_magic_resistant(mage, u, 0) && can_survive(u, tr)) { + message *msg = msg_message("disrupt_astral", "unit region", u, tr); + add_message(&u->faction->msgs, msg); + add_message(&tr->msgs, msg); + msg_release(msg); - move_unit(u, tr, NULL); - } + move_unit(u, tr, NULL); } } free_regionlist(trl); diff --git a/src/util/gamedata.h b/src/util/gamedata.h index 452a6e527..f4983a981 100644 --- a/src/util/gamedata.h +++ b/src/util/gamedata.h @@ -34,10 +34,11 @@ #define NOWATCH_VERSION 354 /* plane->watchers is gone */ #define KEYVAL_VERSION 355 /* at_keys has values */ #define NOLANDITEM_VERSION 356 /* land_region has no items */ +#define NORCSPELL_VERSION 357 /* data contains no RC_SPELL units */ /* unfinished: */ #define CRYPT_VERSION 400 /* passwords are encrypted */ -#define RELEASE_VERSION NOLANDITEM_VERSION /* current datafile */ +#define RELEASE_VERSION NORCSPELL_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 */ diff --git a/src/volcano.c b/src/volcano.c index 9734bb2cd..db7166de0 100644 --- a/src/volcano.c +++ b/src/volcano.c @@ -82,7 +82,7 @@ damage_unit(unit * u, const char *dam, bool physical, bool magic) int i, dead = 0, hp_rem = 0, heiltrank; assert(u->number); - if (fval(u_race(u), RCF_ILLUSIONARY) || u_race(u) == get_race(RC_SPELL)) { + if (fval(u_race(u), RCF_ILLUSIONARY)) { return 0; } From 153039fdefb48863ae40fd3d3d0be5c07e4923a7 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 24 May 2017 08:58:46 +0200 Subject: [PATCH 12/12] fix gcc compilation, unused variable --- src/laws.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/laws.c b/src/laws.c index 01da6f4ee..ba088a8bb 100644 --- a/src/laws.c +++ b/src/laws.c @@ -153,7 +153,6 @@ static bool RemoveNMRNewbie(void) static void age_unit(region * r, unit * u) { - static int rc_cache; const race *rc = u_race(u); ++u->age;