Merge pull request #92 from badgerman/master

miscellaneous refactoring
This commit is contained in:
Enno Rehling 2014-12-29 07:33:16 +01:00
commit f8fd0bed39
27 changed files with 2085 additions and 2152 deletions

View File

@ -22,6 +22,7 @@ end
local eternath = {} local eternath = {}
function eternath.update() function eternath.update()
local size = 1
if b1 and b2 then if b1 and b2 then
local size = 5 local size = 5
local units1 = gates.units(b1, size) local units1 = gates.units(b1, size)

View File

@ -54,6 +54,7 @@ attrib_type at_unitdissolve = {
void register_attributes(void) void register_attributes(void)
{ {
at_deprecate("gm", a_readint);
at_register(&at_stealth); at_register(&at_stealth);
at_register(&at_object); at_register(&at_object);
at_register(&at_unitdissolve); at_register(&at_unitdissolve);
@ -61,7 +62,6 @@ void register_attributes(void)
at_register(&at_raceprefix); at_register(&at_raceprefix);
at_register(&at_iceberg); at_register(&at_iceberg);
at_register(&at_key); at_register(&at_key);
at_deprecate("gm", a_readint);
at_register(&at_follow); at_register(&at_follow);
at_register(&at_targetregion); at_register(&at_targetregion);
at_register(&at_orcification); at_register(&at_orcification);
@ -69,6 +69,7 @@ void register_attributes(void)
at_register(&at_reduceproduction); at_register(&at_reduceproduction);
at_register(&at_otherfaction); at_register(&at_otherfaction);
at_register(&at_racename); at_register(&at_racename);
at_register(&at_speedup);
at_register(&at_movement); at_register(&at_movement);
at_register(&at_moved); at_register(&at_moved);
} }

View File

@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/config.h> #include <kernel/config.h>
#include "movement.h" #include "movement.h"
#include <kernel/save.h>
#include <util/attrib.h> #include <util/attrib.h>
#include <storage.h> #include <storage.h>
@ -60,3 +61,20 @@ void set_movement(attrib ** alist, int type)
a = a_add(alist, a_new(&at_movement)); a = a_add(alist, a_new(&at_movement));
a->data.i |= type; a->data.i |= type;
} }
static int age_speedup(attrib * a)
{
if (a->data.sa[0] > 0) {
a->data.sa[0] = a->data.sa[0] - a->data.sa[1];
}
return (a->data.sa[0] > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE;
}
attrib_type at_speedup = {
"speedup",
NULL, NULL,
age_speedup,
a_writeint,
a_readint
};

View File

@ -22,10 +22,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern "C" { extern "C" {
#endif #endif
extern bool get_movement(struct attrib *const *alist, int type); bool get_movement(struct attrib *const *alist, int type);
extern void set_movement(struct attrib **alist, int type); void set_movement(struct attrib **alist, int type);
extern struct attrib_type at_movement; extern struct attrib_type at_movement;
extern struct attrib_type at_speedup;
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,3 +1,3 @@
#define VERSION_MAJOR 3 #define VERSION_MAJOR 3
#define VERSION_MINOR 4 #define VERSION_MINOR 4
#define VERSION_BUILD 694 #define VERSION_BUILD 695

View File

@ -156,20 +156,20 @@ static void chaos(region * r)
case 0: case 0:
mfac = 100; mfac = 100;
u = u =
createunit(r, get_monsters(), rng_int() % 8 + 1, create_unit(r, get_monsters(), rng_int() % 8 + 1,
get_race(RC_FIREDRAGON)); get_race(RC_FIREDRAGON), 0, NULL, NULL);
break; break;
case 1: case 1:
mfac = 500; mfac = 500;
u = u =
createunit(r, get_monsters(), rng_int() % 4 + 1, create_unit(r, get_monsters(), rng_int() % 4 + 1,
get_race(RC_DRAGON)); get_race(RC_DRAGON), 0, NULL, NULL);
break; break;
default: default:
mfac = 1000; mfac = 1000;
u = u =
createunit(r, get_monsters(), rng_int() % 2 + 1, create_unit(r, get_monsters(), rng_int() % 2 + 1,
get_race(RC_WYRM)); get_race(RC_WYRM), 0, NULL, NULL);
break; break;
} }
if (mfac) if (mfac)

View File

@ -1647,17 +1647,16 @@ static void expandbuying(region * r, request * buyorders)
const luxury_type *type; const luxury_type *type;
int number; int number;
int multi; int multi;
} *trades, *trade; } trades[MAXLUXURIES], *trade;
static int ntrades = 0; static int ntrades = 0;
int i, j; int i, j;
const luxury_type *ltype; const luxury_type *ltype;
if (ntrades == 0) { if (ntrades == 0) {
for (ltype = luxurytypes; ltype; ltype = ltype->next) for (ntrades = 0, ltype = luxurytypes; ltype; ltype = ltype->next) {
++ntrades; assert(ntrades < MAXLUXURIES);
trades = gc_add(calloc(sizeof(struct trade), ntrades)); trades[ntrades++].type = ltype;
for (i = 0, ltype = luxurytypes; i != ntrades; ++i, ltype = ltype->next) }
trades[i].type = ltype;
} }
for (i = 0; i != ntrades; ++i) { for (i = 0; i != ntrades; ++i) {
trades[i].number = 0; trades[i].number = 0;
@ -1887,18 +1886,17 @@ static void expandselling(region * r, request * sellorders, int limit)
building *b; building *b;
unit *u; unit *u;
unit *hafenowner; unit *hafenowner;
static int *counter; static int counter[MAXLUXURIES];
static int ncounter = 0; static int ncounter = 0;
if (ncounter == 0) { if (ncounter == 0) {
const luxury_type *ltype; const luxury_type *ltype;
for (ltype = luxurytypes; ltype; ltype = ltype->next) for (ltype = luxurytypes; ltype; ltype = ltype->next) {
assert(ncounter < MAXLUXURIES);
++ncounter; ++ncounter;
counter = (int *)gc_add(calloc(sizeof(int), ncounter));
} }
else { }
memset(counter, 0, sizeof(int) * ncounter); memset(counter, 0, sizeof(int) * ncounter);
}
if (!sellorders) { /* NEIN, denn Insekten können in || !r->buildings) */ if (!sellorders) { /* NEIN, denn Insekten können in || !r->buildings) */
return; /* Sümpfen und Wüsten auch so handeln */ return; /* Sümpfen und Wüsten auch so handeln */
@ -1958,6 +1956,7 @@ static void expandselling(region * r, request * sellorders, int limit)
int i; int i;
int use = 0; int use = 0;
for (i = 0, search = luxurytypes; search != ltype; search = search->next) { for (i = 0, search = luxurytypes; search != ltype; search = search->next) {
// TODO: this is slow and lame!
++i; ++i;
} }
if (counter[i] >= limit) if (counter[i] >= limit)

View File

@ -29,7 +29,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/ship.h> #include <kernel/ship.h>
#include <kernel/unit.h> #include <kernel/unit.h>
#include <move.h> #include <attributes/movement.h>
/* util includes */ /* util includes */
#include <util/attrib.h> #include <util/attrib.h>

View File

@ -26,10 +26,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "alliance.h" #include "alliance.h"
#include "ally.h" #include "ally.h"
#include "alchemy.h" #include "alchemy.h"
#include "curse.h"
#include "connection.h" #include "connection.h"
#include "building.h" #include "building.h"
#include "calendar.h" #include "calendar.h"
#include "curse.h"
#include "direction.h" #include "direction.h"
#include "faction.h" #include "faction.h"
#include "group.h" #include "group.h"
@ -442,117 +442,8 @@ int verbosity = 1;
FILE *debug; FILE *debug;
static int ShipSpeedBonus(const unit * u)
{
static int level = -1;
if (level == -1) {
level =
get_param_int(global.parameters, "movement.shipspeed.skillbonus", 0);
}
if (level > 0) {
ship *sh = u->ship;
int skl = effskill(u, SK_SAILING);
int minsk = (sh->type->cptskill + 1) / 2;
return (skl - minsk) / level;
}
return 0;
}
int shipspeed(const ship * sh, const unit * u)
{
double k = sh->type->range;
static const curse_type *stormwind_ct, *nodrift_ct;
static bool init;
attrib *a;
curse *c;
if (!init) {
init = true;
stormwind_ct = ct_find("stormwind");
nodrift_ct = ct_find("nodrift");
}
assert(u->ship == sh);
assert(sh->type->construction->improvement == NULL); /* sonst ist construction::size nicht ship_type::maxsize */
if (sh->size != sh->type->construction->maxsize)
return 0;
if (curse_active(get_curse(sh->attribs, stormwind_ct)))
k *= 2;
if (curse_active(get_curse(sh->attribs, nodrift_ct)))
k += 1;
if (u->faction->race == u_race(u)) {
/* race bonus for this faction? */
if (fval(u_race(u), RCF_SHIPSPEED)) {
k += 1;
}
}
k += ShipSpeedBonus(u);
a = a_find(sh->attribs, &at_speedup);
while (a != NULL && a->type == &at_speedup) {
k += a->data.sa[0];
a = a->next;
}
c = get_curse(sh->attribs, ct_find("shipspeedup"));
while (c) {
k += curse_geteffect(c);
c = c->nexthash;
}
#ifdef SHIPSPEED
k *= SHIPSPEED;
#endif
if (sh->damage)
k =
(k * (sh->size * DAMAGE_SCALE - sh->damage) + sh->size * DAMAGE_SCALE -
1) / (sh->size * DAMAGE_SCALE);
return (int)k;
}
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
void verify_data(void)
{
#ifndef NDEBUG
int lf = -1;
faction *f;
unit *u;
int mage, alchemist;
if (verbosity >= 1)
puts(" - checking data for correctness...");
for (f = factions; f; f = f->next) {
mage = 0;
alchemist = 0;
for (u = f->units; u; u = u->nextF) {
if (eff_skill(u, SK_MAGIC, u->region)) {
mage += u->number;
}
if (eff_skill(u, SK_ALCHEMY, u->region))
alchemist += u->number;
if (u->number > UNIT_MAXSIZE) {
if (lf != f->no) {
lf = f->no;
log_printf(stdout, "Partei %s:\n", factionid(f));
}
log_warning("Einheit %s hat %d Personen\n", unitid(u), u->number);
}
}
if (f->no != 0 && ((mage > 3 && f->race != get_race(RC_ELF)) || mage > 4))
log_error("Partei %s hat %d Magier.\n", factionid(f), mage);
if (alchemist > 3)
log_error("Partei %s hat %d Alchemisten.\n", factionid(f), alchemist);
}
#endif
}
int distribute(int old, int new_value, int n) int distribute(int old, int new_value, int n)
{ {
int i; int i;
@ -570,23 +461,6 @@ int distribute(int old, int new_value, int n)
return t; return t;
} }
int change_hitpoints(unit * u, int value)
{
int hp = u->hp;
hp += value;
/* Jede Person benötigt mindestens 1 HP */
if (hp < u->number) {
if (hp < 0) { /* Einheit tot */
hp = 0;
}
scale_number(u, hp);
}
u->hp = hp;
return hp;
}
bool unit_has_cursed_item(const unit * u) bool unit_has_cursed_item(const unit * u)
{ {
item *itm = u->items; item *itm = u->items;
@ -1030,12 +904,6 @@ int newcontainerid(void)
return random_no; return random_no;
} }
unit *createunit(region * r, faction * f, int number, const struct race * rc)
{
assert(rc);
return create_unit(r, f, number, rc, 0, NULL, NULL);
}
bool idle(faction * f) bool idle(faction * f)
{ {
return (bool)(f ? false : true); return (bool)(f ? false : true);
@ -1048,36 +916,6 @@ int maxworkingpeasants(const struct region *r)
return _max(size-treespace, _min(size / 10 , 200)); return _max(size-treespace, _min(size / 10 , 200));
} }
void **blk_list[1024];
int list_index;
int blk_index;
static void gc_done(void)
{
int i, k;
for (i = 0; i != list_index; ++i) {
for (k = 0; k != 1024; ++k)
free(blk_list[i][k]);
free(blk_list[i]);
}
for (k = 0; k != blk_index; ++k)
free(blk_list[list_index][k]);
free(blk_list[list_index]);
}
void *gc_add(void *p)
{
if (blk_index == 0) {
blk_list[list_index] = (void **)malloc(1024 * sizeof(void *));
}
blk_list[list_index][blk_index] = p;
blk_index = (blk_index + 1) % 1024;
if (!blk_index)
++list_index;
return p;
}
static const char * parameter_key(int i) static const char * parameter_key(int i)
{ {
assert(i < MAXPARAMS && i >= 0); assert(i < MAXPARAMS && i >= 0);
@ -1305,7 +1143,6 @@ void kernel_done(void)
* calling it is optional, e.g. a release server will most likely not do it. * calling it is optional, e.g. a release server will most likely not do it.
*/ */
translation_done(); translation_done();
gc_done();
} }
attrib_type at_germs = { attrib_type at_germs = {
@ -1318,9 +1155,6 @@ attrib_type at_germs = {
ATF_UNIQUE ATF_UNIQUE
}; };
/*********************/
/* at_guard */
/*********************/
attrib_type at_guard = { attrib_type at_guard = {
"guard", "guard",
DEFAULT_INIT, DEFAULT_INIT,
@ -1392,38 +1226,6 @@ bool faction_id_is_unused(int id)
return findfaction(id) == NULL; return findfaction(id) == NULL;
} }
int weight(const unit * u)
{
int w = 0, n = 0, in_bag = 0;
const resource_type *rtype = get_resourcetype(R_BAG_OF_HOLDING);
item *itm;
for (itm = u->items; itm; itm = itm->next) {
w = itm->type->weight * itm->number;
n += w;
if (rtype && !fval(itm->type, ITF_BIG)) {
in_bag += w;
}
}
n += u->number * u_race(u)->weight;
if (rtype) {
w = i_get(u->items, rtype->itype) * BAGCAPACITY;
if (w > in_bag) w = in_bag;
n -= w;
}
return n;
}
void make_undead_unit(unit * u)
{
free_orders(&u->orders);
name_unit(u);
fset(u, UFL_ISNEW);
}
unsigned int guard_flags(const unit * u) unsigned int guard_flags(const unit * u)
{ {
unsigned int flags = unsigned int flags =
@ -1816,7 +1618,6 @@ static int read_ext(attrib * a, void *owner, struct storage *store)
void attrib_init(void) void attrib_init(void)
{ {
/* Alle speicherbaren Attribute müssen hier registriert werden */ /* Alle speicherbaren Attribute müssen hier registriert werden */
at_register(&at_speedup);
at_register(&at_shiptrail); at_register(&at_shiptrail);
at_register(&at_familiar); at_register(&at_familiar);
at_register(&at_familiarmage); at_register(&at_familiarmage);

View File

@ -40,6 +40,7 @@ extern "C" {
#ifndef MAXUNITS #ifndef MAXUNITS
# define MAXUNITS 1048573 /* must be prime for hashing. 524287 was >90% full */ # define MAXUNITS 1048573 /* must be prime for hashing. 524287 was >90% full */
#endif #endif
#define MAXLUXURIES 16 /* there must be no more than MAXLUXURIES kinds of luxury goods in any game */
#define TREESIZE (8) /* space used by trees (in #peasants) */ #define TREESIZE (8) /* space used by trees (in #peasants) */
@ -91,7 +92,6 @@ extern "C" {
#define want(option) (1<<option) #define want(option) (1<<option)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
int shipspeed(const struct ship *sh, const struct unit *u);
#define i2b(i) ((bool)((i)?(true):(false))) #define i2b(i) ((bool)((i)?(true):(false)))
@ -105,9 +105,6 @@ extern "C" {
int max_magicians(const struct faction * f); int max_magicians(const struct faction * f);
int findoption(const char *s, const struct locale *lang); int findoption(const char *s, const struct locale *lang);
/* special units */
void make_undead_unit(struct unit *);
param_t findparam(const char *s, const struct locale *lang); param_t findparam(const char *s, const struct locale *lang);
param_t findparam_ex(const char *s, const struct locale * lang); param_t findparam_ex(const char *s, const struct locale * lang);
bool isparam(const char *s, const struct locale * lang, param_t param); bool isparam(const char *s, const struct locale * lang, param_t param);
@ -132,9 +129,6 @@ extern "C" {
int forbiddenid(int id); int forbiddenid(int id);
int newcontainerid(void); int newcontainerid(void);
struct unit *createunit(struct region *r, struct faction *f,
int number, const struct race *rc);
void create_unitid(struct unit *u, int id);
int getunit(const struct region * r, const struct faction * f, struct unit **uresult); int getunit(const struct region * r, const struct faction * f, struct unit **uresult);
int read_unitid(const struct faction *f, const struct region *r); int read_unitid(const struct faction *f, const struct region *r);
@ -187,26 +181,9 @@ extern "C" {
bool has_limited_skills(const struct unit *u); bool has_limited_skills(const struct unit *u);
const struct race *findrace(const char *, const struct locale *); const struct race *findrace(const char *, const struct locale *);
int ispresent(const struct faction *f, const struct region *r);
int check_option(struct faction *f, int option);
/* Anzahl Personen in einer Einheit festlegen. NUR (!) mit dieser Routine,
* sonst großes Unglück. Durch asserts an ein paar Stellen abgesichert. */
void verify_data(void);
int change_hitpoints(struct unit *u, int value);
int weight(const struct unit *u);
void changeblockchaos(void);
bool idle(struct faction *f); bool idle(struct faction *f);
bool unit_has_cursed_item(const struct unit *u); bool unit_has_cursed_item(const struct unit *u);
/* simple garbage collection: */
void *gc_add(void *p);
/* grammatik-flags: */ /* grammatik-flags: */
#define GF_NONE 0 #define GF_NONE 0
/* singular, ohne was dran */ /* singular, ohne was dran */

View File

@ -258,7 +258,7 @@ unit *addplayer(region * r, faction * f)
assert(f->units == NULL); assert(f->units == NULL);
set_ursprung(f, 0, r->x, r->y); set_ursprung(f, 0, r->x, r->y);
u = createunit(r, f, 1, f->race); u = create_unit(r, f, 1, f->race, 0, NULL, NULL);
equip_items(&u->faction->items, get_equipment("new_faction")); equip_items(&u->faction->items, get_equipment("new_faction"));
equip_unit(u, get_equipment("first_unit")); equip_unit(u, get_equipment("first_unit"));
sprintf(buffer, "first_%s", u_race(u)->_name); sprintf(buffer, "first_%s", u_race(u)->_name);

View File

@ -1,7 +1,7 @@
/* /*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de> Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de> Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -118,7 +118,8 @@ const char *write_regionname(const region * r, const faction * f, char *buffer,
const struct locale *lang = f ? f->locale : 0; const struct locale *lang = f ? f->locale : 0;
if (r == NULL) { if (r == NULL) {
strlcpy(buf, "(null)", size); strlcpy(buf, "(null)", size);
} else { }
else {
plane *pl = rplane(r); plane *pl = rplane(r);
int nx = r->x, ny = r->y; int nx = r->x, ny = r->y;
pnormalize(&nx, &ny, pl); pnormalize(&nx, &ny, pl);
@ -132,7 +133,7 @@ const char *regionname(const region * r, const faction * f)
{ {
static int index = 0; static int index = 0;
static char buf[2][NAMESIZE]; static char buf[2][NAMESIZE];
index = 1-index; index = 1 - index;
return write_regionname(r, f, buf[index], sizeof(buf[index])); return write_regionname(r, f, buf[index], sizeof(buf[index]));
} }
@ -179,18 +180,18 @@ void a_initmoveblock(attrib * a)
int a_readmoveblock(attrib * a, void *owner, struct storage *store) int a_readmoveblock(attrib * a, void *owner, struct storage *store)
{ {
moveblock *m = (moveblock *) (a->data.v); moveblock *m = (moveblock *)(a->data.v);
int i; int i;
READ_INT(store, &i); READ_INT(store, &i);
m->dir = (direction_t) i; m->dir = (direction_t)i;
return AT_READ_OK; return AT_READ_OK;
} }
void void
a_writemoveblock(const attrib * a, const void *owner, struct storage *store) a_writemoveblock(const attrib * a, const void *owner, struct storage *store)
{ {
moveblock *m = (moveblock *) (a->data.v); moveblock *m = (moveblock *)(a->data.v);
WRITE_INT(store, (int)m->dir); WRITE_INT(store, (int)m->dir);
} }
@ -202,7 +203,7 @@ attrib_type at_moveblock = {
#define RMAXHASH MAXREGIONS #define RMAXHASH MAXREGIONS
static region *regionhash[RMAXHASH]; static region *regionhash[RMAXHASH];
static int dummy_data; static int dummy_data;
static region *dummy_ptr = (region *) & dummy_data; /* a funny hack */ static region *dummy_ptr = (region *)& dummy_data; /* a funny hack */
typedef struct uidhashentry { typedef struct uidhashentry {
int uid; int uid;
@ -214,7 +215,7 @@ struct region *findregionbyid(int uid)
{ {
int key = uid % MAXREGIONS; int key = uid % MAXREGIONS;
while (uidhash[key].uid != 0 && uidhash[key].uid != uid) { while (uidhash[key].uid != 0 && uidhash[key].uid != uid) {
if (++key==MAXREGIONS) key = 0; if (++key == MAXREGIONS) key = 0;
} }
return uidhash[key].r; return uidhash[key].r;
} }
@ -335,7 +336,7 @@ region *r_connect(const region * r, direction_t dir)
region *result; region *result;
int x, y; int x, y;
#ifdef FAST_CONNECT #ifdef FAST_CONNECT
region *rmodify = (region *) r; region *rmodify = (region *)r;
assert(dir >= 0 && dir < MAXDIRECTIONS); assert(dir >= 0 && dir < MAXDIRECTIONS);
if (r->connect[dir]) if (r->connect[dir])
return r->connect[dir]; return r->connect[dir];
@ -381,10 +382,12 @@ static int koor_distance_orig(int x1, int y1, int x2, int y2)
if (dx >= 0) { if (dx >= 0) {
int result = dx + dy; int result = dx + dy;
return result; return result;
} else if (-dx >= dy) { }
else if (-dx >= dy) {
int result = -dx; int result = -dx;
return result; return result;
} else { }
else {
return dy; return dy;
} }
} }
@ -441,7 +444,8 @@ int koor_distance(int x1, int y1, int x2, int y2)
int height = plane_height(p1); int height = plane_height(p1);
if (width && height) { if (width && height) {
return koor_distance_wrap_xy(x1, y1, x2, y2, width, height); return koor_distance_wrap_xy(x1, y1, x2, y2, width, height);
} else { }
else {
return koor_distance_orig(x1, y1, x2, y2); return koor_distance_orig(x1, y1, x2, y2);
} }
} }
@ -463,7 +467,7 @@ void free_regionlist(region_list * rl)
void add_regionlist(region_list ** rl, region * r) void add_regionlist(region_list ** rl, region * r)
{ {
region_list *rl2 = (region_list *) malloc(sizeof(region_list)); region_list *rl2 = (region_list *)malloc(sizeof(region_list));
rl2->data = r; rl2->data = r;
rl2->next = *rl; rl2->next = *rl;
@ -553,7 +557,8 @@ void rsetroad(region * r, direction_t d, short val)
} }
if (r == b->from) { if (r == b->from) {
b->data.sa[0] = val; b->data.sa[0] = val;
} else { }
else {
b->data.sa[1] = val; b->data.sa[1] = val;
} }
} }
@ -598,7 +603,7 @@ bool is_coastregion(region * r)
if (rn && fval(rn->terrain, SEA_REGION)) if (rn && fval(rn->terrain, SEA_REGION))
res++; res++;
} }
return res!=0; return res != 0;
} }
int rpeasants(const region * r) int rpeasants(const region * r)
@ -791,7 +796,7 @@ void region_setresource(region * r, const resource_type * rtype, int value)
int i; int i;
for (i = 0; r->terrain->production[i].type; ++i) { for (i = 0; r->terrain->production[i].type; ++i) {
const terrain_production *production = r->terrain->production + i; const terrain_production *production = r->terrain->production + i;
if (production->type==rtype) { if (production->type == rtype) {
add_resource(r, 1, value, dice_rand(production->divisor), rtype); add_resource(r, 1, value, dice_rand(production->divisor), rtype);
break; break;
} }
@ -923,7 +928,8 @@ static char *makename(void)
k = rng_int() % (int)nk; k = rng_int() % (int)nk;
name[p] = kons[k]; name[p] = kons[k];
p++; p++;
} else { }
else {
k = rng_int() % (int)ns; k = rng_int() % (int)ns;
name[p] = start[k]; name[p] = start[k];
p++; p++;
@ -936,7 +942,8 @@ static char *makename(void)
name[p] = end[e]; name[p] = end[e];
p++; p++;
x = 1; x = 1;
} else }
else
x = 0; x = 0;
} }
name[p] = '\0'; name[p] = '\0';
@ -989,7 +996,8 @@ void terraform_region(region * r, const terrain_type * terrain)
if (rtype == NULL) { if (rtype == NULL) {
*lrm = rm->next; *lrm = rm->next;
free(rm); free(rm);
} else { }
else {
lrm = &rm->next; lrm = &rm->next;
} }
} }
@ -1018,11 +1026,12 @@ void terraform_region(region * r, const terrain_type * terrain)
if (r->land) { if (r->land) {
int d; int d;
for (d=0;d!=MAXDIRECTIONS;++d) { for (d = 0; d != MAXDIRECTIONS; ++d) {
rsetroad(r, d, 0); rsetroad(r, d, 0);
} }
i_freeall(&r->land->items); i_freeall(&r->land->items);
} else { }
else {
static struct surround { static struct surround {
struct surround *next; struct surround *next;
const luxury_type *type; const luxury_type *type;
@ -1050,20 +1059,23 @@ void terraform_region(region * r, const terrain_type * terrain)
if (trash) { if (trash) {
sr = trash; sr = trash;
trash = trash->next; trash = trash->next;
} else { }
else {
sr = calloc(1, sizeof(struct surround)); sr = calloc(1, sizeof(struct surround));
} }
sr->next = nb; sr->next = nb;
sr->type = sale->type; sr->type = sale->type;
sr->value = 1; sr->value = 1;
nb = sr; nb = sr;
} else }
else
sr->value++; sr->value++;
++mnr; ++mnr;
} }
} }
} }
if (!nb) { if (!nb) {
// TODO: this is really lame
int i = get_maxluxuries(); int i = get_maxluxuries();
if (i > 0) { if (i > 0) {
i = rng_int() % i; i = rng_int() % i;
@ -1071,7 +1083,8 @@ void terraform_region(region * r, const terrain_type * terrain)
while (i--) while (i--)
ltype = ltype->next; ltype = ltype->next;
} }
} else { }
else {
int i = rng_int() % mnr; int i = rng_int() % mnr;
struct surround *srd = nb; struct surround *srd = nb;
while (i > srd->value) { while (i > srd->value) {
@ -1106,7 +1119,8 @@ void terraform_region(region * r, const terrain_type * terrain)
if (itype != NULL) { if (itype != NULL) {
rsetherbtype(r, itype); rsetherbtype(r, itype);
rsetherbs(r, (short)(50 + rng_int() % 31)); rsetherbs(r, (short)(50 + rng_int() % 31));
} else { }
else {
rsetherbtype(r, NULL); rsetherbtype(r, NULL);
} }
if (oldterrain == NULL || !fval(oldterrain, LAND_REGION)) { if (oldterrain == NULL || !fval(oldterrain, LAND_REGION)) {
@ -1126,9 +1140,11 @@ void terraform_region(region * r, const terrain_type * terrain)
if (rng_int() % 100 < 40) { if (rng_int() % 100 < 40) {
rsettrees(r, 2, terrain->size * (30 + rng_int() % 40) / 1000); rsettrees(r, 2, terrain->size * (30 + rng_int() % 40) / 1000);
} }
} else if (chance(0.2)) { }
else if (chance(0.2)) {
rsettrees(r, 2, terrain->size * (30 + rng_int() % 40) / 1000); rsettrees(r, 2, terrain->size * (30 + rng_int() % 40) / 1000);
} else { }
else {
rsettrees(r, 2, 0); rsettrees(r, 2, 0);
} }
rsettrees(r, 1, rtrees(r, 2) / 4); rsettrees(r, 1, rtrees(r, 2) / 4);
@ -1164,10 +1180,10 @@ int resolve_region_coor(variant id, void *address)
{ {
region *r = findregion(id.sa[0], id.sa[1]); region *r = findregion(id.sa[0], id.sa[1]);
if (r) { if (r) {
*(region **) address = r; *(region **)address = r;
return 0; return 0;
} }
*(region **) address = NULL; *(region **)address = NULL;
return -1; return -1;
} }
@ -1177,11 +1193,11 @@ int resolve_region_id(variant id, void *address)
if (id.i != 0) { if (id.i != 0) {
r = findregionbyid(id.i); r = findregionbyid(id.i);
if (r == NULL) { if (r == NULL) {
*(region **) address = NULL; *(region **)address = NULL;
return -1; return -1;
} }
} }
*(region **) address = r; *(region **)address = r;
return 0; return 0;
} }
@ -1194,7 +1210,8 @@ variant read_region_reference(struct storage * store)
result.sa[0] = (short)n; result.sa[0] = (short)n;
READ_INT(store, &n); READ_INT(store, &n);
result.sa[1] = (short)n; result.sa[1] = (short)n;
} else { }
else {
READ_INT(store, &result.i); READ_INT(store, &result.i);
} }
return result; return result;
@ -1204,7 +1221,8 @@ void write_region_reference(const region * r, struct storage *store)
{ {
if (r) { if (r) {
WRITE_INT(store, r->uid); WRITE_INT(store, r->uid);
} else { }
else {
WRITE_INT(store, 0); WRITE_INT(store, 0);
} }
} }
@ -1221,7 +1239,7 @@ struct message_list *r_getmessages(const struct region *r,
} }
struct message *r_addmessage(struct region *r, const struct faction *viewer, struct message *r_addmessage(struct region *r, const struct faction *viewer,
struct message *msg) struct message *msg)
{ {
assert(r); assert(r);
if (viewer) { if (viewer) {
@ -1299,16 +1317,19 @@ faction *update_owners(region * r)
r->land->ownership->flags |= OWNER_MOURNING; r->land->ownership->flags |= OWNER_MOURNING;
f = NULL; f = NULL;
} }
} else if (u->faction != f) { }
else if (u->faction != f) {
if (!r->land->ownership) { if (!r->land->ownership) {
/* there has never been a prior owner */ /* there has never been a prior owner */
region_set_morale(r, MORALE_DEFAULT, turn); region_set_morale(r, MORALE_DEFAULT, turn);
} else { }
else {
alliance *al = region_get_alliance(r); alliance *al = region_get_alliance(r);
if (al && u->faction->alliance == al) { if (al && u->faction->alliance == al) {
int morale = _max(0, r->land->morale - MORALE_TRANSFER); int morale = _max(0, r->land->morale - MORALE_TRANSFER);
region_set_morale(r, morale, turn); region_set_morale(r, morale, turn);
} else { }
else {
region_set_morale(r, MORALE_TAKEOVER, turn); region_set_morale(r, MORALE_TAKEOVER, turn);
if (f) { if (f) {
r->land->ownership->flags |= OWNER_MOURNING; r->land->ownership->flags |= OWNER_MOURNING;
@ -1319,7 +1340,8 @@ faction *update_owners(region * r)
f = u->faction; f = u->faction;
} }
} }
} else if (r->land->ownership && r->land->ownership->owner) { }
else if (r->land->ownership && r->land->ownership->owner) {
r->land->ownership->flags |= OWNER_MOURNING; r->land->ownership->flags |= OWNER_MOURNING;
region_set_owner(r, NULL, turn); region_set_owner(r, NULL, turn);
f = NULL; f = NULL;

View File

@ -274,20 +274,8 @@ int readorders(const char *filename)
const char *s; const char *s;
init_tokens_str(b); init_tokens_str(b);
s = gettoken(token, sizeof(token)); s = gettoken(token, sizeof(token));
p = s ? findparam(s, lang) : NOPARAM; p = (s && s[0] != '@') ? findparam(s, lang) : NOPARAM;
switch (p) { switch (p) {
#undef LOCALE_CHANGE
#ifdef LOCALE_CHANGE
case P_LOCALE:
{
const char *s = getstrtoken();
if (f && get_locale(s)) {
f->locale = get_locale(s);
}
}
b = getbuf(F, enc_gamedata);
break;
#endif
case P_GAMENAME: case P_GAMENAME:
case P_FACTION: case P_FACTION:
f = factionorders(); f = factionorders();
@ -311,8 +299,8 @@ int readorders(const char *filename)
break; break;
} }
init_tokens_str(b); init_tokens_str(b);
b = getstrtoken(); s = gettoken(token, sizeof(token));
p = (!b || b[0] == '@') ? NOPARAM : findparam(b, lang); p = (s && s[0] != '@') ? findparam(s, lang) : NOPARAM;
} while ((p != P_UNIT || !f) && p != P_FACTION && p != P_NEXT } while ((p != P_UNIT || !f) && p != P_FACTION && p != P_NEXT
&& p != P_GAMENAME); && p != P_GAMENAME);
break; break;
@ -1030,11 +1018,12 @@ void writeregion(struct gamedata *data, const region * r)
WRITE_INT(data->store, rherbs(r)); WRITE_INT(data->store, rherbs(r));
WRITE_INT(data->store, rpeasants(r)); WRITE_INT(data->store, rpeasants(r));
WRITE_INT(data->store, rmoney(r)); WRITE_INT(data->store, rmoney(r));
if (r->land) if (r->land) {
for (demand = r->land->demands; demand; demand = demand->next) { for (demand = r->land->demands; demand; demand = demand->next) {
WRITE_TOK(data->store, resourcename(demand->type->itype->rtype, 0)); WRITE_TOK(data->store, resourcename(demand->type->itype->rtype, 0));
WRITE_INT(data->store, demand->value); WRITE_INT(data->store, demand->value);
} }
}
WRITE_TOK(data->store, "end"); WRITE_TOK(data->store, "end");
write_items(data->store, r->land->items); write_items(data->store, r->land->items);
WRITE_SECTION(data->store); WRITE_SECTION(data->store);

View File

@ -1,7 +1,7 @@
/* /*
Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de> Copyright (c) 1998-2010, Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de> Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -22,6 +22,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* kernel includes */ /* kernel includes */
#include "build.h" #include "build.h"
#include "curse.h"
#include "faction.h"
#include "unit.h" #include "unit.h"
#include "item.h" #include "item.h"
#include "race.h" #include "race.h"
@ -39,6 +41,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <quicklist.h> #include <quicklist.h>
#include <util/xml.h> #include <util/xml.h>
#include <attributes/movement.h>
#include <storage.h> #include <storage.h>
/* libc includes */ /* libc includes */
@ -65,12 +69,12 @@ const ship_type *findshiptype(const char *name, const struct locale *lang)
quicklist *ql; quicklist *ql;
int qi; int qi;
sn = (local_names *) calloc(sizeof(local_names), 1); sn = (local_names *)calloc(sizeof(local_names), 1);
sn->next = snames; sn->next = snames;
sn->lang = lang; sn->lang = lang;
for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) { for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) {
ship_type *stype = (ship_type *) ql_get(ql, qi); ship_type *stype = (ship_type *)ql_get(ql, qi);
variant var2; variant var2;
const char *n = locale_string(lang, stype->_name); const char *n = locale_string(lang, stype->_name);
var2.v = (void *)stype; var2.v = (void *)stype;
@ -89,7 +93,7 @@ static ship_type *st_find_i(const char *name)
int qi; int qi;
for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) { for (qi = 0, ql = shiptypes; ql; ql_advance(&ql, &qi, 1)) {
ship_type *stype = (ship_type *) ql_get(ql, qi); ship_type *stype = (ship_type *)ql_get(ql, qi);
if (strcmp(stype->_name, name) == 0) { if (strcmp(stype->_name, name) == 0) {
return stype; return stype;
} }
@ -177,7 +181,7 @@ static ship *deleted_ships;
ship *new_ship(const ship_type * stype, region * r, const struct locale *lang) ship *new_ship(const ship_type * stype, region * r, const struct locale *lang)
{ {
static char buffer[32]; static char buffer[32];
ship *sh = (ship *) calloc(1, sizeof(ship)); ship *sh = (ship *)calloc(1, sizeof(ship));
const char *sname = 0; const char *sname = 0;
assert(stype); assert(stype);
@ -254,6 +258,79 @@ const char *write_shipname(const ship * sh, char *ibuf, size_t size)
return ibuf; return ibuf;
} }
static int ShipSpeedBonus(const unit * u)
{
static int level = -1;
if (level == -1) {
level =
get_param_int(global.parameters, "movement.shipspeed.skillbonus", 0);
}
if (level > 0) {
ship *sh = u->ship;
int skl = effskill(u, SK_SAILING);
int minsk = (sh->type->cptskill + 1) / 2;
return (skl - minsk) / level;
}
return 0;
}
int shipspeed(const ship * sh, const unit * u)
{
double k = sh->type->range;
static const struct curse_type *stormwind_ct, *nodrift_ct;
static bool init;
attrib *a;
struct curse *c;
if (!init) {
init = true;
stormwind_ct = ct_find("stormwind");
nodrift_ct = ct_find("nodrift");
}
assert(u->ship == sh);
assert(sh->type->construction->improvement == NULL); /* sonst ist construction::size nicht ship_type::maxsize */
if (sh->size != sh->type->construction->maxsize)
return 0;
if (curse_active(get_curse(sh->attribs, stormwind_ct)))
k *= 2;
if (curse_active(get_curse(sh->attribs, nodrift_ct)))
k += 1;
if (u->faction->race == u_race(u)) {
/* race bonus for this faction? */
if (fval(u_race(u), RCF_SHIPSPEED)) {
k += 1;
}
}
k += ShipSpeedBonus(u);
a = a_find(sh->attribs, &at_speedup);
while (a != NULL && a->type == &at_speedup) {
k += a->data.sa[0];
a = a->next;
}
c = get_curse(sh->attribs, ct_find("shipspeedup"));
while (c) {
k += curse_geteffect(c);
c = c->nexthash;
}
#ifdef SHIPSPEED
k *= SHIPSPEED;
#endif
if (sh->damage)
k =
(k * (sh->size * DAMAGE_SCALE - sh->damage) + sh->size * DAMAGE_SCALE -
1) / (sh->size * DAMAGE_SCALE);
return (int)k;
}
const char *shipname(const ship * sh) const char *shipname(const ship * sh)
{ {
typedef char name[OBJECTIDSIZE + 1]; typedef char name[OBJECTIDSIZE + 1];
@ -314,7 +391,7 @@ static unit * ship_owner_ex(const ship * sh, const struct faction * last_owner)
for (u = sh->region->units; u; u = u->next) { for (u = sh->region->units; u; u = u->next) {
if (u->ship == sh) { if (u->ship == sh) {
if (u->number > 0) { if (u->number > 0) {
if (heir && last_owner && heir->faction!=last_owner && u->faction==last_owner) { if (heir && last_owner && heir->faction != last_owner && u->faction == last_owner) {
heir = u; heir = u;
break; /* we found someone from the same faction who is not dead. let's take this guy */ break; /* we found someone from the same faction who is not dead. let's take this guy */
} }
@ -329,15 +406,15 @@ static unit * ship_owner_ex(const ship * sh, const struct faction * last_owner)
void ship_update_owner(ship * sh) { void ship_update_owner(ship * sh) {
unit * owner = sh->_owner; unit * owner = sh->_owner;
sh->_owner = ship_owner_ex(sh, owner?owner->faction:0); sh->_owner = ship_owner_ex(sh, owner ? owner->faction : 0);
} }
unit *ship_owner(const ship * sh) unit *ship_owner(const ship * sh)
{ {
unit *owner = sh->_owner; unit *owner = sh->_owner;
if (!owner || (owner->ship!=sh || owner->number<=0)) { if (!owner || (owner->ship != sh || owner->number <= 0)) {
unit * heir = ship_owner_ex(sh, owner?owner->faction:0); unit * heir = ship_owner_ex(sh, owner ? owner->faction : 0);
return (heir && heir->number>0) ? heir : 0; return (heir && heir->number > 0) ? heir : 0;
} }
return owner; return owner;
} }

View File

@ -124,6 +124,7 @@ extern "C" {
extern const char *ship_getname(const struct ship *self); extern const char *ship_getname(const struct ship *self);
extern void ship_setname(struct ship *self, const char *name); extern void ship_setname(struct ship *self, const char *name);
int shipspeed(const struct ship *sh, const struct unit *u);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -159,8 +159,8 @@ void spawn_braineaters(float chance)
/* Neues Monster ? */ /* Neues Monster ? */
if (next-- == 0) { if (next-- == 0) {
unit *u = unit *u =
createunit(r, f0, 1 + rng_int() % 10 + rng_int() % 10, create_unit(r, f0, 1 + rng_int() % 10 + rng_int() % 10,
get_race(RC_HIRNTOETER)); get_race(RC_HIRNTOETER), 0, NULL, NULL);
equip_unit(u, get_equipment("monster_braineater")); equip_unit(u, get_equipment("monster_braineater"));
next = rng_int() % (int)(chance * 100); next = rng_int() % (int)(chance * 100);

View File

@ -67,6 +67,31 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define FIND_FOREIGN_TEMP #define FIND_FOREIGN_TEMP
int weight(const unit * u)
{
int w = 0, n = 0, in_bag = 0;
const resource_type *rtype = get_resourcetype(R_BAG_OF_HOLDING);
item *itm;
for (itm = u->items; itm; itm = itm->next) {
w = itm->type->weight * itm->number;
n += w;
if (rtype && !fval(itm->type, ITF_BIG)) {
in_bag += w;
}
}
n += u->number * u_race(u)->weight;
if (rtype) {
w = i_get(u->items, rtype->itype) * BAGCAPACITY;
if (w > in_bag) w = in_bag;
n -= w;
}
return n;
}
attrib_type at_creator = { attrib_type at_creator = {
"creator" "creator"
/* Rest ist NULL; temporaeres, nicht alterndes Attribut */ /* Rest ist NULL; temporaeres, nicht alterndes Attribut */

View File

@ -125,6 +125,7 @@ extern "C" {
extern struct attrib_type at_showskchange; extern struct attrib_type at_showskchange;
int ualias(const struct unit *u); int ualias(const struct unit *u);
int weight(const struct unit *u);
const struct race *u_irace(const struct unit *u); const struct race *u_irace(const struct unit *u);
const struct race *u_race(const struct unit *u); const struct race *u_race(const struct unit *u);

View File

@ -644,7 +644,7 @@ static weapon_type *xml_readweapon(xmlXPathContextPtr xpath, item_type * itype)
xmlFree(propValue); xmlFree(propValue);
propValue = xmlGetProp(node, BAD_CAST "value"); propValue = xmlGetProp(node, BAD_CAST "value");
wtype->damage[pos] = gc_add(_strdup((const char *)propValue)); wtype->damage[pos] = _strdup((const char *)propValue); // TODO: this is a memory leak
if (k == 0) if (k == 0)
wtype->damage[1 - pos] = wtype->damage[pos]; wtype->damage[1 - pos] = wtype->damage[pos];
xmlFree(propValue); xmlFree(propValue);

View File

@ -367,7 +367,7 @@ static void guardian_faction(plane * pl, int id)
} }
if (u) if (u)
continue; continue;
u = createunit(r, f, 1, get_race(RC_GOBLIN)); u = create_unit(r, f, 1, get_race(RC_GOBLIN), 0, NULL, NULL);
set_string(&u->name, "Igjarjuks Auge"); set_string(&u->name, "Igjarjuks Auge");
i_change(&u->items, it_find("roi"), 1); i_change(&u->items, it_find("roi"), 1);
set_order(&u->thisorder, NULL); set_order(&u->thisorder, NULL);

View File

@ -8,7 +8,7 @@
This program may not be used, modified or distributed This program may not be used, modified or distributed
without prior permission by the authors of Eressea. without prior permission by the authors of Eressea.
*/ */
#include <platform.h> #include <platform.h>
#include <kernel/config.h> #include <kernel/config.h>
@ -70,7 +70,8 @@ const terrain_type *random_terrain(const terrain_type * terrains[],
} }
assert(i < size); assert(i < size);
terrain = terrains[i]; terrain = terrains[i];
} else { }
else {
terrain = terrains[n]; terrain = terrains[n];
} }
return terrain; return terrain;
@ -103,7 +104,7 @@ static int count_demand(const region * r)
static int static int
recurse_regions(region * r, region_list ** rlist, recurse_regions(region * r, region_list ** rlist,
bool(*fun) (const region * r)) bool(*fun) (const region * r))
{ {
if (!fun(r)) if (!fun(r))
return 0; return 0;
@ -134,30 +135,30 @@ static bool f_nolux(const region * r)
int fix_demand(region * rd) int fix_demand(region * rd)
{ {
region_list *rl, *rlist = NULL; region_list *rl, *rlist = NULL;
static const struct luxury_type **mlux = 0, **ltypes; static const luxury_type *mlux[MAXLUXURIES];
const luxury_type *ltypes[MAXLUXURIES];
const luxury_type *sale = NULL; const luxury_type *sale = NULL;
int maxlux = 0; int maxlux = 0;
int maxluxuries = get_maxluxuries(); static int maxluxuries = -1;
if (maxluxuries == 0) // TODO: this entire function is impossible to understand
return 0;
recurse_regions(rd, &rlist, f_nolux); recurse_regions(rd, &rlist, f_nolux);
if (mlux == 0) { if (maxluxuries < 0) {
int i = 0; int i = 0;
mlux =
(const luxury_type **)gc_add(calloc(maxluxuries,
sizeof(const luxury_type *)));
ltypes =
(const luxury_type **)gc_add(calloc(maxluxuries,
sizeof(const luxury_type *)));
for (sale = luxurytypes; sale; sale = sale->next) { for (sale = luxurytypes; sale; sale = sale->next) {
ltypes[i++] = sale; ltypes[i++] = sale;
} }
} else { maxluxuries = i;
}
if (maxluxuries == 0) {
return -1;
}
else {
int i; int i;
for (i = 0; i != maxluxuries; ++i) for (i = 0; i != maxluxuries; ++i) {
mlux[i] = 0; mlux[i] = 0;
} }
}
for (rl = rlist; rl; rl = rl->next) { for (rl = rlist; rl; rl = rl->next) {
region *r = rl->data; region *r = rl->data;
direction_t d; direction_t d;
@ -173,7 +174,8 @@ int fix_demand(region * rd)
maxlux = i; maxlux = i;
mlux[i] = dmd->type; mlux[i] = dmd->type;
break; break;
} else if (mlux[i] == dmd->type) { }
else if (mlux[i] == dmd->type) {
break; break;
} }
} }
@ -274,7 +276,8 @@ newfaction *read_newfactions(const char *filename)
al = makealliance(alliance, zText); al = makealliance(alliance, zText);
} }
nf->allies = al; nf->allies = al;
} else { }
else {
nf->allies = NULL; nf->allies = NULL;
} }
if (nf->race == NULL) { if (nf->race == NULL) {
@ -360,13 +363,13 @@ static bool virgin_region(const region * r)
static quicklist * get_island(region * root) static quicklist * get_island(region * root)
{ {
quicklist * ql, * result = 0; quicklist * ql, *result = 0;
int qi = 0; int qi = 0;
fset(root, RF_MARK); fset(root, RF_MARK);
ql_push(&result, root); ql_push(&result, root);
for (ql=result,qi=0; ql; ql_advance(&ql, &qi, 1)) { for (ql = result, qi = 0; ql; ql_advance(&ql, &qi, 1)) {
int dir; int dir;
region *r = (region *)ql_get(ql, qi); region *r = (region *)ql_get(ql, qi);
region * next[MAXDIRECTIONS]; region * next[MAXDIRECTIONS];
@ -382,7 +385,7 @@ static quicklist * get_island(region * root)
} }
} }
for (ql=result,qi=0; ql; ql_advance(&ql, &qi, 1)) { for (ql = result, qi = 0; ql; ql_advance(&ql, &qi, 1)) {
region *r = (region *)ql_get(ql, qi); region *r = (region *)ql_get(ql, qi);
freset(r, RF_MARK); freset(r, RF_MARK);
} }
@ -398,7 +401,7 @@ get_island_info(region * root, int *size_p, int *inhabited_p, int *maxage_p)
ql_push(&island, root); ql_push(&island, root);
fset(root, RF_MARK); fset(root, RF_MARK);
for (ql=island,qi=0; ql; ql_advance(&ql, &qi, 1)) { for (ql = island, qi = 0; ql; ql_advance(&ql, &qi, 1)) {
int d; int d;
region *r = (region *)ql_get(ql, qi); region *r = (region *)ql_get(ql, qi);
if (r->units) { if (r->units) {
@ -419,7 +422,7 @@ get_island_info(region * root, int *size_p, int *inhabited_p, int *maxage_p)
} }
} }
} }
for (ql=island,qi=0; ql; ql_advance(&ql, &qi, 1)) { for (ql = island, qi = 0; ql; ql_advance(&ql, &qi, 1)) {
region *r = (region *)ql_get(ql, qi); region *r = (region *)ql_get(ql, qi);
freset(r, RF_MARK); freset(r, RF_MARK);
} }
@ -568,7 +571,7 @@ int autoseed(newfaction ** players, int nsize, int max_agediff)
quicklist *ql, *rlist = get_island(rmin); quicklist *ql, *rlist = get_island(rmin);
int qi; int qi;
for (ql=rlist,qi=0;ql;ql_advance(&ql, &qi, 1)) { for (ql = rlist, qi = 0; ql; ql_advance(&ql, &qi, 1)) {
region *r = (region *)ql_get(ql, qi); region *r = (region *)ql_get(ql, qi);
unit *u; unit *u;
for (u = r->units; u; u = u->next) { for (u = r->units; u; u = u->next) {
@ -667,7 +670,8 @@ int autoseed(newfaction ** players, int nsize, int max_agediff)
} }
if (volcano_terrain != NULL && (rng_int() % VOLCANO_CHANCE == 0)) { if (volcano_terrain != NULL && (rng_int() % VOLCANO_CHANCE == 0)) {
terraform_region(r, volcano_terrain); terraform_region(r, volcano_terrain);
} else if (nsize && (rng_int() % isize == 0 || rsize == 0)) { }
else if (nsize && (rng_int() % isize == 0 || rsize == 0)) {
newfaction **nfp, *nextf = *players; newfaction **nfp, *nextf = *players;
faction *f; faction *f;
unit *u; unit *u;
@ -690,7 +694,8 @@ int autoseed(newfaction ** players, int nsize, int max_agediff)
if (strcmp(nextf->email, nf->email) == 0) { if (strcmp(nextf->email, nf->email) == 0) {
*nfp = nf->next; *nfp = nf->next;
free_newfaction(nf); free_newfaction(nf);
} else }
else
nfp = &nf->next; nfp = &nf->next;
} }
*players = nextf->next; *players = nextf->next;
@ -701,7 +706,8 @@ int autoseed(newfaction ** players, int nsize, int max_agediff)
--isize; --isize;
if (psize >= PLAYERS_PER_ISLAND) if (psize >= PLAYERS_PER_ISLAND)
break; break;
} else { }
else {
terraform_region(r, random_terrain(terrainarr, distribution, nterrains)); terraform_region(r, random_terrain(terrainarr, distribution, nterrains));
--isize; --isize;
} }
@ -740,7 +746,8 @@ int autoseed(newfaction ** players, int nsize, int max_agediff)
if (rng_int() % SPECIALCHANCE < special) { if (rng_int() % SPECIALCHANCE < special) {
terrain = random_terrain(terrainarr, distribution, nterrains); terrain = random_terrain(terrainarr, distribution, nterrains);
special = SPECIALCHANCE / 3; /* 33% chance auf noch eines */ special = SPECIALCHANCE / 3; /* 33% chance auf noch eines */
} else { }
else {
special = 1; special = 1;
} }
terraform_region(rn, terrain); terraform_region(rn, terrain);
@ -821,14 +828,14 @@ static struct geo {
terrain_t type; terrain_t type;
} geography_e3[GEOMAX] = { } geography_e3[GEOMAX] = {
{ {
8, T_OCEAN}, { 8, T_OCEAN }, {
3, T_SWAMP}, { 3, T_SWAMP }, {
1, T_VOLCANO}, { 1, T_VOLCANO }, {
3, T_DESERT}, { 3, T_DESERT }, {
4, T_HIGHLAND}, { 4, T_HIGHLAND }, {
3, T_MOUNTAIN}, { 3, T_MOUNTAIN }, {
2, T_GLACIER}, { 2, T_GLACIER }, {
1, T_PLAIN} 1, T_PLAIN }
}; };
const terrain_type *random_terrain_e3(direction_t dir) const terrain_type *random_terrain_e3(direction_t dir)
@ -851,7 +858,7 @@ const terrain_type *random_terrain_e3(direction_t dir)
int int
random_neighbours(region * r, region_list ** rlist, random_neighbours(region * r, region_list ** rlist,
const terrain_type * (*terraformer) (direction_t)) const terrain_type * (*terraformer) (direction_t))
{ {
int nsize = 0; int nsize = 0;
direction_t dir; direction_t dir;
@ -993,7 +1000,8 @@ int build_island_e3(int x, int y, int numfactions, int minsize)
if (r->land) { if (r->land) {
if (nsize < minsize) { if (nsize < minsize) {
nsize += random_neighbours(r, &rlist, &random_terrain_e3); nsize += random_neighbours(r, &rlist, &random_terrain_e3);
} else { }
else {
nsize += random_neighbours(r, &rlist, &get_ocean); nsize += random_neighbours(r, &rlist, &get_ocean);
} }
} }
@ -1047,7 +1055,8 @@ int build_island_e3(int x, int y, int numfactions, int minsize)
prepare_starting_region(r); prepare_starting_region(r);
} }
r->land->money = 50000; /* 2% = 1000 silver */ r->land->money = 50000; /* 2% = 1000 silver */
} else if (r->land) { }
else if (r->land) {
r->land->money *= 4; r->land->money *= 4;
} }
} }

View File

@ -630,7 +630,7 @@ static void recruit_dracoids(unit * dragon, int size)
region *r = dragon->region; region *r = dragon->region;
const struct item *weapon = NULL; const struct item *weapon = NULL;
order *new_order = NULL; order *new_order = NULL;
unit *un = createunit(r, f, size, get_race(RC_DRACOID)); unit *un = create_unit(r, f, size, get_race(RC_DRACOID), 0, NULL, NULL);
fset(un, UFL_ISNEW | UFL_MOVED); fset(un, UFL_ISNEW | UFL_MOVED);
@ -908,7 +908,7 @@ void spawn_dragons(void)
unit *u; unit *u;
if (fval(r->terrain, SEA_REGION) && rng_int() % 10000 < 1) { if (fval(r->terrain, SEA_REGION) && rng_int() % 10000 < 1) {
u = createunit(r, monsters, 1, get_race(RC_SEASERPENT)); u = create_unit(r, monsters, 1, get_race(RC_SEASERPENT), 0, NULL, NULL);
fset(u, UFL_ISNEW | UFL_MOVED); fset(u, UFL_ISNEW | UFL_MOVED);
equip_unit(u, get_equipment("monster_seaserpent")); equip_unit(u, get_equipment("monster_seaserpent"));
} }
@ -918,9 +918,9 @@ void spawn_dragons(void)
|| r->terrain == newterrain(T_DESERT)) || r->terrain == newterrain(T_DESERT))
&& rng_int() % 10000 < (5 + 100 * chaosfactor(r))) { && rng_int() % 10000 < (5 + 100 * chaosfactor(r))) {
if (chance(0.80)) { if (chance(0.80)) {
u = createunit(r, monsters, nrand(60, 20) + 1, get_race(RC_FIREDRAGON)); u = create_unit(r, monsters, nrand(60, 20) + 1, get_race(RC_FIREDRAGON), 0, NULL, NULL);
} else { } else {
u = createunit(r, monsters, nrand(30, 20) + 1, get_race(RC_DRAGON)); u = create_unit(r, monsters, nrand(30, 20) + 1, get_race(RC_DRAGON), 0, NULL, NULL);
} }
fset(u, UFL_ISNEW | UFL_MOVED); fset(u, UFL_ISNEW | UFL_MOVED);
equip_unit(u, get_equipment("monster_dragon")); equip_unit(u, get_equipment("monster_dragon"));
@ -983,7 +983,7 @@ void spawn_undead(void)
break; break;
} }
u = createunit(r, monsters, undead, rc); u = create_unit(r, monsters, undead, rc, 0, NULL, NULL);
fset(u, UFL_ISNEW | UFL_MOVED); fset(u, UFL_ISNEW | UFL_MOVED);
if ((rc == get_race(RC_SKELETON) || rc == get_race(RC_ZOMBIE)) if ((rc == get_race(RC_SKELETON) || rc == get_race(RC_ZOMBIE))
&& rng_int() % 10 < 4) { && rng_int() % 10 < 4) {

View File

@ -170,22 +170,6 @@ attrib_type at_shiptrail = {
shiptrail_read shiptrail_read
}; };
static int age_speedup(attrib * a)
{
if (a->data.sa[0] > 0) {
a->data.sa[0] = a->data.sa[0] - a->data.sa[1];
}
return (a->data.sa[0] > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE;
}
attrib_type at_speedup = {
"speedup",
NULL, NULL,
age_speedup,
a_writeint,
a_readint
};
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static attrib_type at_driveweight = { static attrib_type at_driveweight = {

View File

@ -31,7 +31,6 @@ extern "C" {
struct ship; struct ship;
struct building_type; struct building_type;
extern struct attrib_type at_speedup;
extern struct attrib_type at_shiptrail; extern struct attrib_type at_shiptrail;
/* die Zahlen sind genau äquivalent zu den race Flags */ /* die Zahlen sind genau äquivalent zu den race Flags */

View File

@ -15,7 +15,8 @@
extern "C" { extern "C" {
#endif #endif
extern void register_races(void); void register_races(void);
void make_undead_unit(struct unit *);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -17,6 +17,7 @@
/* kernel includes */ /* kernel includes */
#include <kernel/race.h> #include <kernel/race.h>
#include <kernel/order.h>
#include <kernel/unit.h> #include <kernel/unit.h>
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/region.h> #include <kernel/region.h>
@ -35,6 +36,13 @@
#define age_chance(a,b,p) (_max(0,a-b)*p) #define age_chance(a,b,p) (_max(0,a-b)*p)
void make_undead_unit(unit * u)
{
free_orders(&u->orders);
name_unit(u);
fset(u, UFL_ISNEW);
}
void age_undead(unit * u) void age_undead(unit * u)
{ {
region *r = u->region; region *r = u->region;

View File

@ -56,6 +56,8 @@
#include <kernel/xmlreader.h> #include <kernel/xmlreader.h>
#include <kernel/version.h> #include <kernel/version.h>
#include <races/races.h>
/* util includes */ /* util includes */
#include <util/attrib.h> #include <util/attrib.h>
#include <util/base36.h> #include <util/base36.h>
@ -2782,6 +2784,23 @@ static int sp_unholypower(castorder * co)
return cast_level; return cast_level;
} }
static int change_hitpoints(unit * u, int value)
{
int hp = u->hp;
hp += value;
/* Jede Person benötigt mindestens 1 HP */
if (hp < u->number) {
if (hp < 0) { /* Einheit tot */
hp = 0;
}
scale_number(u, hp);
}
u->hp = hp;
return hp;
}
static int dc_age(struct curse *c) static int dc_age(struct curse *c)
/* age returns 0 if the attribute needs to be removed, !=0 otherwise */ /* age returns 0 if the attribute needs to be removed, !=0 otherwise */
{ {