forked from github/server
Merge pull request #82 from badgerman/remove-at-gm
remove old at_gm feature (player-operated quests)
This commit is contained in:
commit
077af5c52c
21 changed files with 284 additions and 402 deletions
|
@ -70,6 +70,7 @@ set (ERESSEA_SRC
|
|||
upkeep.c
|
||||
vortex.c
|
||||
names.c
|
||||
lighthouse.c
|
||||
reports.c
|
||||
eressea.c
|
||||
callback.c
|
||||
|
|
|
@ -7,7 +7,6 @@ SET(_FILES
|
|||
attributes.c
|
||||
fleechance.c
|
||||
follow.c
|
||||
gm.c
|
||||
hate.c
|
||||
iceberg.c
|
||||
key.c
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
|
||||
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
|
|
@ -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);
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
|
||||
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 <platform.h>
|
||||
#include <kernel/config.h>
|
||||
#include "gm.h"
|
||||
|
||||
/* kernel includes */
|
||||
#include <kernel/plane.h>
|
||||
|
||||
/* util includes */
|
||||
#include <util/attrib.h>
|
||||
|
||||
#include <storage.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -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 <kernel/alliance.h>
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -21,7 +21,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
/* attributes includes */
|
||||
#include <attributes/reduceproduction.h>
|
||||
#include <attributes/gm.h>
|
||||
|
||||
/* 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. */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
150
src/lighthouse.c
Normal file
150
src/lighthouse.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
#include <platform.h>
|
||||
#include "lighthouse.h"
|
||||
|
||||
#include <kernel/config.h>
|
||||
#include <kernel/building.h>
|
||||
#include <kernel/faction.h>
|
||||
#include <kernel/plane.h>
|
||||
#include <kernel/region.h>
|
||||
#include <kernel/terrain.h>
|
||||
#include <kernel/unit.h>
|
||||
#include <util/attrib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
|
||||
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
|
||||
}
|
|
@ -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 <kernel/build.h>
|
||||
#include <kernel/building.h>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
Katja Zedel <katze@felidae.kn-bremen.de
|
||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <kernel/config.h>
|
||||
#include "reports.h"
|
||||
#include "laws.h"
|
||||
#include "lighthouse.h"
|
||||
|
||||
/* kernel includes */
|
||||
#include <kernel/alliance.h>
|
||||
|
@ -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;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "laws.h"
|
||||
#include "spells.h"
|
||||
#include "direction.h"
|
||||
#include "randenc.h"
|
||||
#include "monster.h"
|
||||
|
||||
#include <spells/borders.h>
|
||||
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue