move more things out of config.c.

- lighthouses into their own module.
- lastregion/firstregion into reports.c.
This commit is contained in:
Enno Rehling 2014-12-17 17:22:26 +01:00
parent fb0eb4dce6
commit 8971f59ecc
12 changed files with 260 additions and 220 deletions

View File

@ -70,6 +70,7 @@ set (ERESSEA_SRC
upkeep.c
vortex.c
names.c
lighthouse.c
reports.c
eressea.c
callback.c

View File

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

View File

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

View File

@ -508,12 +508,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;
}
@ -733,56 +731,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 +1129,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;

View File

@ -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 */
@ -86,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 ----------------------------------- */
@ -105,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 */
@ -227,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);

View File

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

View File

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

View File

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

150
src/lighthouse.c Normal file
View 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;
}

36
src/lighthouse.h Normal file
View File

@ -0,0 +1,36 @@
/*
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 LIGHTHOUSE_H
#define LIGHTHOUSE_H
#ifdef __cplusplus
extern "C" {
#endif
/* 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);
#ifdef __cplusplus
}
#endif
#endif

View File

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

View File

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