diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f04c0cffc..b64ae7072 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -70,6 +70,7 @@ set (ERESSEA_SRC upkeep.c vortex.c names.c + lighthouse.c reports.c eressea.c callback.c diff --git a/src/attributes/CMakeLists.txt b/src/attributes/CMakeLists.txt index 7bb3f91ba..3317f49b1 100644 --- a/src/attributes/CMakeLists.txt +++ b/src/attributes/CMakeLists.txt @@ -7,7 +7,6 @@ SET(_FILES attributes.c fleechance.c follow.c -gm.c hate.c iceberg.c key.c diff --git a/src/attributes/aggressive.h b/src/attributes/aggressive.h deleted file mode 100644 index c653b12bd..000000000 --- a/src/attributes/aggressive.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright (c) 1998-2010, Enno Rehling - Katja Zedel - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -**/ - -#ifndef H_ATTRIBUTE_AGGRESSIVE -#define H_ATTRIBUTE_AGGRESSIVE -#ifdef __cplusplus -extern "C" { -#endif - - extern struct attrib_type at_aggressive; - extern struct attrib *make_aggressive(double probability); - extern void init_aggressive(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index b078d062f..37c7418dc 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -22,7 +22,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* attributes includes */ #include "follow.h" -#include "gm.h" #include "hate.h" #include "iceberg.h" #include "key.h" @@ -62,7 +61,7 @@ void register_attributes(void) at_register(&at_raceprefix); at_register(&at_iceberg); at_register(&at_key); - at_register(&at_gm); + at_deprecate("gm", a_readint); at_register(&at_follow); at_register(&at_targetregion); at_register(&at_orcification); diff --git a/src/attributes/gm.c b/src/attributes/gm.c deleted file mode 100644 index f5cde3801..000000000 --- a/src/attributes/gm.c +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (c) 1998-2010, Enno Rehling - Katja Zedel - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -**/ - -#include -#include -#include "gm.h" - -/* kernel includes */ -#include - -/* util includes */ -#include - -#include - -static void write_gm(const attrib * a, const void *owner, struct storage *store) -{ - write_plane_reference((plane *) a->data.v, store); -} - -static int read_gm(attrib * a, void *owner, struct storage *store) -{ - plane *pl; - int result = read_plane_reference(&pl, store); - a->data.v = pl; - return result; -} - -attrib_type at_gm = { - "gm", - NULL, - NULL, - NULL, - write_gm, - read_gm, -}; - -attrib *make_gm(const struct plane * pl) -{ - attrib *a = a_new(&at_gm); - a->data.v = (void *)pl; - return a; -} diff --git a/src/kernel/build.c b/src/kernel/build.c index 808f7f87d..6c0b8c76e 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -25,6 +25,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "move.h" #include "laws.h" #include "skill.h" +#include "lighthouse.h" /* kernel includes */ #include diff --git a/src/kernel/building.c b/src/kernel/building.c index ffed936a2..0fcce549e 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -30,6 +30,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "region.h" #include "skill.h" #include "save.h" +#include "lighthouse.h" #include "version.h" /* util includes */ diff --git a/src/kernel/config.c b/src/kernel/config.c index cdc30618a..5821896c1 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -21,7 +21,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* attributes includes */ #include -#include /* kernel includes */ #include "alliance.h" @@ -508,12 +507,10 @@ int shipspeed(const ship * sh, const unit * u) k *= SHIPSPEED; #endif -#ifdef SHIPDAMAGE if (sh->damage) k = (k * (sh->size * DAMAGE_SCALE - sh->damage) + sh->size * DAMAGE_SCALE - 1) / (sh->size * DAMAGE_SCALE); -#endif return (int)k; } @@ -614,39 +611,11 @@ bool unit_has_cursed_item(const unit * u) return false; } -static void init_gms(void) -{ - faction *f; - - for (f = factions; f; f = f->next) { - attrib *a = a_find(f->attribs, &at_gm); - - if (a != NULL) - fset(f, FFL_GM); - } -} - static int autoalliance(const plane * pl, const faction * sf, const faction * f2) { - static bool init = false; - if (!init) { - init_gms(); - init = true; - } if (pl && (pl->flags & PFL_FRIENDLY)) return HELP_ALL; - /* if f2 is a gm in this plane, everyone has an auto-help to it */ - if (fval(f2, FFL_GM)) { - attrib *a = a_find(f2->attribs, &at_gm); - - while (a) { - const plane *p = (const plane *)a->data.v; - if (p == pl) - return HELP_ALL; - a = a->next; - } - } if (f_get_alliance(sf) != NULL && AllianceAuto()) { if (sf->alliance == f2->alliance) @@ -733,56 +702,6 @@ int alliedunit(const unit * u, const faction * f2, int mode) return 0; } -static attrib_type at_lighthouse = { - "lighthouse" - /* Rest ist NULL; temporäres, nicht alterndes Attribut */ -}; - -/* update_lighthouse: call this function whenever the size of a lighthouse changes - * it adds temporary markers to the surrounding regions. - * The existence of markers says nothing about the quality of the observer in - * the lighthouse, for this may change more frequently. - */ -void update_lighthouse(building * lh) -{ - const struct building_type *bt_lighthouse = bt_find("lighthouse"); - if (bt_lighthouse && lh->type == bt_lighthouse) { - region *r = lh->region; - int d = (int)log10(lh->size) + 1; - int x; - - if (lh->size > 0) { - r->flags |= RF_LIGHTHOUSE; - } - - for (x = -d; x <= d; ++x) { - int y; - for (y = -d; y <= d; ++y) { - attrib *a; - region *r2; - int px = r->x + x, py = r->y + y; - pnormalize(&px, &py, rplane(r)); - r2 = findregion(px, py); - if (!r2 || !fval(r2->terrain, SEA_REGION)) - continue; - if (distance(r, r2) > d) - continue; - a = a_find(r2->attribs, &at_lighthouse); - while (a && a->type == &at_lighthouse) { - building *b = (building *)a->data.v; - if (b == lh) - break; - a = a->next; - } - if (!a) { - a = a_add(&r2->attribs, a_new(&at_lighthouse)); - a->data.v = (void *)lh; - } - } - } - } -} - int count_faction(const faction * f, int flags) { unit *u; @@ -1181,158 +1100,6 @@ int maxworkingpeasants(const struct region *r) return _max(size-treespace, _min(size / 10 , 200)); } -int lighthouse_range(const building * b, const faction * f) -{ - int d = 0; - if (fval(b, BLD_WORKING) && b->size >= 10) { - int maxd = (int)log10(b->size) + 1; - - if (skill_enabled(SK_PERCEPTION)) { - region *r = b->region; - int c = 0; - unit *u; - for (u = r->units; u; u = u->next) { - if (u->building == b || u == building_owner(b)) { - if (u->building == b) { - c += u->number; - } - if (c > buildingcapacity(b)) - break; - if (f == NULL || u->faction == f) { - int sk = eff_skill(u, SK_PERCEPTION, r) / 3; - d = _max(d, sk); - d = _min(maxd, d); - if (d == maxd) - break; - } - } - else if (c) - break; /* first unit that's no longer in the house ends the search */ - } - } - else { - /* E3A rule: no perception req'd */ - return maxd; - } - } - return d; -} - -bool check_leuchtturm(region * r, faction * f) -{ - attrib *a; - - if (!fval(r->terrain, SEA_REGION)) - return false; - - for (a = a_find(r->attribs, &at_lighthouse); a && a->type == &at_lighthouse; - a = a->next) { - building *b = (building *)a->data.v; - - assert(b->type == bt_find("lighthouse")); - if (fval(b, BLD_WORKING) && b->size >= 10) { - int maxd = (int)log10(b->size) + 1; - - if (skill_enabled(SK_PERCEPTION) && f) { - region *r2 = b->region; - unit *u; - int c = 0; - int d = 0; - - for (u = r2->units; u; u = u->next) { - if (u->building == b) { - c += u->number; - if (c > buildingcapacity(b)) - break; - if (f == NULL || u->faction == f) { - if (!d) - d = distance(r, r2); - if (maxd < d) - break; - if (eff_skill(u, SK_PERCEPTION, r) >= d * 3) - return true; - } - } - else if (c) - break; /* first unit that's no longer in the house ends the search */ - } - } - else { - /* E3A rule: no perception req'd */ - return maxd; - } - } - } - - return false; -} - -region *lastregion(faction * f) -{ -#ifdef SMART_INTERVALS - unit *u = f->units; - region *r = f->last; - - if (u == NULL) - return NULL; - if (r != NULL) - return r->next; - - /* it is safe to start in the region of the first unit. */ - f->last = u->region; - /* if regions have indices, we can skip ahead: */ - for (u = u->nextF; u != NULL; u = u->nextF) { - r = u->region; - if (r->index > f->last->index) - f->last = r; - } - - /* we continue from the best region and look for travelthru etc. */ - for (r = f->last->next; r; r = r->next) { - plane *p = rplane(r); - - /* search the region for travelthru-attributes: */ - if (fval(r, RF_TRAVELUNIT)) { - attrib *ru = a_find(r->attribs, &at_travelunit); - while (ru && ru->type == &at_travelunit) { - u = (unit *)ru->data.v; - if (u->faction == f) { - f->last = r; - break; - } - ru = ru->next; - } - } - if (f->last == r) - continue; - if (check_leuchtturm(r, f)) - f->last = r; - if (p && is_watcher(p, f)) { - f->last = r; - } - } - return f->last->next; -#else - return NULL; -#endif -} - -region *firstregion(faction * f) -{ -#ifdef SMART_INTERVALS - region *r = f->first; - - if (f->units == NULL) - return NULL; - if (r != NULL) - return r; - - return f->first = regions; -#else - return regions; -#endif -} - void **blk_list[1024]; int list_index; int blk_index; @@ -1771,41 +1538,6 @@ bool has_horses(const struct unit * u) return false; } -void plagues(region * r, bool ismagic) -{ - int peasants; - int i; - int dead = 0; - - /* Seuchenwahrscheinlichkeit in % */ - - if (!ismagic) { - double mwp = _max(maxworkingpeasants(r), 1); - double prob = - pow(rpeasants(r) / (mwp * wage(r, NULL, NULL, turn) * 0.13), 4.0) - * PLAGUE_CHANCE; - - if (rng_double() >= prob) - return; - } - - peasants = rpeasants(r); - dead = (int)(0.5F + PLAGUE_VICTIMS * peasants); - for (i = dead; i != 0; i--) { - if (rng_double() < PLAGUE_HEALCHANCE && rmoney(r) >= PLAGUE_HEALCOST) { - rsetmoney(r, rmoney(r) - PLAGUE_HEALCOST); - --dead; - } - } - - if (dead > 0) { - message *msg = add_message(&r->msgs, msg_message("pest", "dead", dead)); - msg_release(msg); - deathcounts(r, dead); - rsetpeasants(r, peasants - dead); - } -} - /* Lohn bei den einzelnen Burgstufen für Normale Typen, Orks, Bauern, * Modifikation für Städter. */ diff --git a/src/kernel/config.h b/src/kernel/config.h index 0e00110a6..9a44e7540 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -30,7 +30,6 @@ extern "C" { /* TODO: move these settings to settings.h or into configuration files */ #define GOBLINKILL /* Goblin-Spezialklau kann tödlich enden */ #define HERBS_ROT /* herbs owned by units have a chance to rot. */ -#define SHIPDAMAGE /* Schiffsbeschädigungen */ #define INSECT_POTION /* Spezialtrank für Insekten */ #define ORCIFICATION /* giving snotlings to the peasants gets counted */ @@ -54,13 +53,6 @@ extern "C" { #define MAXMAGICIANS 3 #define MAXALCHEMISTS 3 - /** Plagues **/ -#define PLAGUE_CHANCE 0.1F /* Seuchenwahrscheinlichkeit (siehe plagues()) */ -#define PLAGUE_VICTIMS 0.2F /* % Betroffene */ -#define PLAGUE_HEALCHANCE 0.25F /* Wahrscheinlichkeit Heilung */ -#define PLAGUE_HEALCOST 30 /* Heilkosten */ - - /* getunit results: */ #define GET_UNIT 0 #define GET_NOTFOUND 1 @@ -93,7 +85,6 @@ extern "C" { * von struct unitname, etc. zurückgegeben werden. ohne die 0 */ #define BAGCAPACITY 20000 /* soviel paßt in einen Bag of Holding */ -#define STRENGTHCAPACITY 50000 /* zusätzliche Tragkraft beim Kraftzauber (deprecated) */ #define STRENGTHMULTIPLIER 50 /* multiplier for trollbelt */ /* ----------------- Befehle ----------------------------------- */ @@ -112,12 +103,6 @@ extern "C" { bool faction_id_is_unused(int); int max_magicians(const struct faction * f); - /* leuchtturm */ - bool check_leuchtturm(struct region *r, struct faction *f); - void update_lighthouse(struct building *lh); - int lighthouse_range(const struct building *b, - const struct faction *f); - int findoption(const char *s, const struct locale *lang); /* special units */ @@ -234,10 +219,6 @@ extern "C" { int weight(const struct unit *u); void changeblockchaos(void); - /* intervall, in dem die regionen der partei zu finden sind */ - struct region *firstregion(struct faction *f); - struct region *lastregion(struct faction *f); - bool idle(struct faction *f); bool unit_has_cursed_item(const struct unit *u); @@ -352,7 +333,6 @@ extern "C" { struct order *default_order(const struct locale *lang); int entertainmoney(const struct region *r); - void plagues(struct region *r, bool ismagic); void free_gamedata(void); #define GIVE_SELF 1 diff --git a/src/kernel/faction.c b/src/kernel/faction.c index dbbd24aa0..f300a11c8 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -200,9 +200,9 @@ static int unused_faction_id(void) int id = rng_int() % MAX_FACTION_ID; while (!faction_id_is_unused(id)) { - id++; - if (id == MAX_FACTION_ID) + if (++id == MAX_FACTION_ID) { id = 0; + } } return id; diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 3c110424c..c8764392d 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -50,9 +50,7 @@ extern "C" { #define FFL_NPC (1<<25) /* eine Partei mit Monstern */ #define FFL_DBENTRY (1<<28) /* Partei ist in Datenbank eingetragen */ -#define FFL_GM (1<<30) /* eine Partei mit Sonderrechten */ - -#define FFL_SAVEMASK (FFL_DEFENDER|FFL_NEWID|FFL_GM|FFL_NPC|FFL_DBENTRY|FFL_NOIDLEOUT) +#define FFL_SAVEMASK (FFL_DEFENDER|FFL_NEWID|FFL_NPC|FFL_DBENTRY|FFL_NOIDLEOUT) typedef struct faction { struct faction *next; diff --git a/src/kernel/save.c b/src/kernel/save.c index c390a6640..c4ea62b63 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -46,6 +46,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "terrain.h" #include "terrainid.h" /* only for conversion code */ #include "unit.h" +#include "lighthouse.h" #include "version.h" /* attributes includes */ diff --git a/src/kernel/ship.c b/src/kernel/ship.c index 8e2c00100..8f29737dd 100644 --- a/src/kernel/ship.c +++ b/src/kernel/ship.c @@ -274,11 +274,9 @@ int shipcapacity(const ship * sh) if (sh->type->construction && sh->size != sh->type->construction->maxsize) return 0; -#ifdef SHIPDAMAGE if (sh->damage) { i = (int)ceil(i * (1.0 - sh->damage / sh->size / (double)DAMAGE_SCALE)); } -#endif return i; } diff --git a/src/laws.c b/src/laws.c index 2d04606dd..a83fb93a7 100755 --- a/src/laws.c +++ b/src/laws.c @@ -717,7 +717,14 @@ void demographics(void) calculate_emigration(r); peasants(r); if (r->age > 20) { - plagues(r, false); + double mwp = _max(maxworkingpeasants(r), 1); + double prob = + pow(rpeasants(r) / (mwp * wage(r, NULL, NULL, turn) * 0.13), 4.0) + * PLAGUE_CHANCE; + + if (rng_double() < prob) { + plagues(r); + } } horses(r); if (plant_rules == 0) { /* E1 */ diff --git a/src/lighthouse.c b/src/lighthouse.c new file mode 100644 index 000000000..f05687e69 --- /dev/null +++ b/src/lighthouse.c @@ -0,0 +1,150 @@ +#include +#include "lighthouse.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static attrib_type at_lighthouse = { + "lighthouse" + /* Rest ist NULL; temporäres, nicht alterndes Attribut */ +}; + +/* update_lighthouse: call this function whenever the size of a lighthouse changes +* it adds temporary markers to the surrounding regions. +* The existence of markers says nothing about the quality of the observer in +* the lighthouse, for this may change more frequently. +*/ +void update_lighthouse(building * lh) +{ + const struct building_type *bt_lighthouse = bt_find("lighthouse"); + if (bt_lighthouse && lh->type == bt_lighthouse) { + region *r = lh->region; + int d = (int)log10(lh->size) + 1; + int x; + + if (lh->size > 0) { + r->flags |= RF_LIGHTHOUSE; + } + + for (x = -d; x <= d; ++x) { + int y; + for (y = -d; y <= d; ++y) { + attrib *a; + region *r2; + int px = r->x + x, py = r->y + y; + pnormalize(&px, &py, rplane(r)); + r2 = findregion(px, py); + if (!r2 || !fval(r2->terrain, SEA_REGION)) + continue; + if (distance(r, r2) > d) + continue; + a = a_find(r2->attribs, &at_lighthouse); + while (a && a->type == &at_lighthouse) { + building *b = (building *)a->data.v; + if (b == lh) + break; + a = a->next; + } + if (!a) { + a = a_add(&r2->attribs, a_new(&at_lighthouse)); + a->data.v = (void *)lh; + } + } + } + } +} + +int lighthouse_range(const building * b, const faction * f) +{ + int d = 0; + if (fval(b, BLD_WORKING) && b->size >= 10) { + int maxd = (int)log10(b->size) + 1; + + if (skill_enabled(SK_PERCEPTION)) { + region *r = b->region; + int c = 0; + unit *u; + for (u = r->units; u; u = u->next) { + if (u->building == b || u == building_owner(b)) { + if (u->building == b) { + c += u->number; + } + if (c > buildingcapacity(b)) + break; + if (f == NULL || u->faction == f) { + int sk = eff_skill(u, SK_PERCEPTION, r) / 3; + d = _max(d, sk); + d = _min(maxd, d); + if (d == maxd) + break; + } + } + else if (c) + break; /* first unit that's no longer in the house ends the search */ + } + } + else { + /* E3A rule: no perception req'd */ + return maxd; + } + } + return d; +} + +bool check_leuchtturm(region * r, faction * f) +{ + attrib *a; + + if (!fval(r->terrain, SEA_REGION)) + return false; + + for (a = a_find(r->attribs, &at_lighthouse); a && a->type == &at_lighthouse; + a = a->next) { + building *b = (building *)a->data.v; + + assert(b->type == bt_find("lighthouse")); + if (fval(b, BLD_WORKING) && b->size >= 10) { + int maxd = (int)log10(b->size) + 1; + + if (skill_enabled(SK_PERCEPTION) && f) { + region *r2 = b->region; + unit *u; + int c = 0; + int d = 0; + + for (u = r2->units; u; u = u->next) { + if (u->building == b) { + c += u->number; + if (c > buildingcapacity(b)) + break; + if (f == NULL || u->faction == f) { + if (!d) + d = distance(r, r2); + if (maxd < d) + break; + if (eff_skill(u, SK_PERCEPTION, r) >= d * 3) + return true; + } + } + else if (c) + break; /* first unit that's no longer in the house ends the search */ + } + } + else { + /* E3A rule: no perception req'd */ + return maxd; + } + } + } + + return false; +} diff --git a/src/attributes/gm.h b/src/lighthouse.h similarity index 67% rename from src/attributes/gm.h rename to src/lighthouse.h index e1a17bef6..6000248ba 100644 --- a/src/attributes/gm.h +++ b/src/lighthouse.h @@ -1,7 +1,7 @@ /* Copyright (c) 1998-2010, Enno Rehling - Katja Zedel +Katja Zedel Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -16,18 +16,23 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. **/ -#ifndef H_ATTRIBUTE_GM -#define H_ATTRIBUTE_GM +#ifndef LIGHTHOUSE_H +#define LIGHTHOUSE_H + #ifdef __cplusplus extern "C" { #endif -/* this is an attribute used by the kernel (isallied) */ - struct plane; - extern struct attrib_type at_gm; + struct faction; + struct region; + struct building; + /* leuchtturm */ + bool check_leuchtturm(struct region *r, struct faction *f); + void update_lighthouse(struct building *lh); + int lighthouse_range(const struct building *b, + const struct faction *f); - extern struct attrib *make_gm(const struct plane *pl); #ifdef __cplusplus } diff --git a/src/move.c b/src/move.c index 5ace63929..0e9111de4 100644 --- a/src/move.c +++ b/src/move.c @@ -25,6 +25,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "alchemy.h" #include "vortex.h" #include "monster.h" +#include "lighthouse.h" #include #include diff --git a/src/randenc.c b/src/randenc.c index 0c024bd6c..0db285459 100644 --- a/src/randenc.c +++ b/src/randenc.c @@ -1181,3 +1181,26 @@ void randomevents(void) dissolve_units(); } + +void plagues(region * r) +{ + int peasants; + int i; + int dead = 0; + + peasants = rpeasants(r); + dead = (int)(0.5F + PLAGUE_VICTIMS * peasants); + for (i = dead; i != 0; i--) { + if (rng_double() < PLAGUE_HEALCHANCE && rmoney(r) >= PLAGUE_HEALCOST) { + rsetmoney(r, rmoney(r) - PLAGUE_HEALCOST); + --dead; + } + } + + if (dead > 0) { + message *msg = add_message(&r->msgs, msg_message("pest", "dead", dead)); + msg_release(msg); + deathcounts(r, dead); + rsetpeasants(r, peasants - dead); + } +} diff --git a/src/randenc.h b/src/randenc.h index 0f39d9c61..be3e9d9ca 100644 --- a/src/randenc.h +++ b/src/randenc.h @@ -1,7 +1,7 @@ /* Copyright (c) 1998-2010, Enno Rehling - Katja Zedel +Katja Zedel Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -22,8 +22,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif - extern void encounters(void); - extern void randomevents(void); + struct region; + + /** Plagues **/ +#define PLAGUE_CHANCE 0.1F /* Seuchenwahrscheinlichkeit (siehe plagues()) */ +#define PLAGUE_VICTIMS 0.2F /* % Betroffene */ +#define PLAGUE_HEALCHANCE 0.25F /* Wahrscheinlichkeit Heilung */ +#define PLAGUE_HEALCOST 30 /* Heilkosten */ + void plagues(struct region *r); + void encounters(void); + void randomevents(void); #ifdef __cplusplus } diff --git a/src/reports.c b/src/reports.c index ad43fdfe9..c01a49bf2 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 "lighthouse.h" /* kernel includes */ #include @@ -1600,6 +1601,72 @@ static void prepare_reports(void) } } +static region *lastregion(faction * f) +{ +#ifdef SMART_INTERVALS + unit *u = f->units; + region *r = f->last; + + if (u == NULL) + return NULL; + if (r != NULL) + return r->next; + + /* it is safe to start in the region of the first unit. */ + f->last = u->region; + /* if regions have indices, we can skip ahead: */ + for (u = u->nextF; u != NULL; u = u->nextF) { + r = u->region; + if (r->index > f->last->index) + f->last = r; + } + + /* we continue from the best region and look for travelthru etc. */ + for (r = f->last->next; r; r = r->next) { + plane *p = rplane(r); + + /* search the region for travelthru-attributes: */ + if (fval(r, RF_TRAVELUNIT)) { + attrib *ru = a_find(r->attribs, &at_travelunit); + while (ru && ru->type == &at_travelunit) { + u = (unit *)ru->data.v; + if (u->faction == f) { + f->last = r; + break; + } + ru = ru->next; + } + } + if (f->last == r) + continue; + if (check_leuchtturm(r, f)) + f->last = r; + if (p && is_watcher(p, f)) { + f->last = r; + } + } + return f->last->next; +#else + return NULL; +#endif +} + +static region *firstregion(faction * f) +{ +#ifdef SMART_INTERVALS + region *r = f->first; + + if (f->units == NULL) + return NULL; + if (r != NULL) + return r; + + return f->first = regions; +#else + return regions; +#endif +} + static seen_region **prepare_report(faction * f) { struct seen_region *sr; diff --git a/src/spells.c b/src/spells.c index 908b6fbec..913403341 100644 --- a/src/spells.c +++ b/src/spells.c @@ -20,6 +20,7 @@ #include "laws.h" #include "spells.h" #include "direction.h" +#include "randenc.h" #include "monster.h" #include @@ -2974,7 +2975,7 @@ static int sp_plague(castorder * co) unit *mage = co->magician.u; int cast_level = co->level; - plagues(r, true); + plagues(r); ADDMSG(&mage->faction->msgs, msg_message("plague_spell", "region mage", r, mage));