- made startup regions more balanced

implementing free_gamedata():
- cleaning up some static variables
This commit is contained in:
Enno Rehling 2008-05-22 10:46:02 +00:00
parent a40e5a3711
commit 1052e46613
31 changed files with 227 additions and 180 deletions

View File

@ -439,11 +439,11 @@ expandrecruit(region * r, request * recruitorders)
static void static void
recruit(unit * u, struct order * ord, request ** recruitorders) recruit(unit * u, struct order * ord, request ** recruitorders)
{ {
int n; int n;
region * r = u->region; region * r = u->region;
plane * pl; plane * pl;
request *o; request *o;
int recruitcost; int recruitcost;
const faction * f = u->faction; const faction * f = u->faction;
const struct race * rc = f->race; const struct race * rc = f->race;
@ -457,45 +457,47 @@ recruit(unit * u, struct order * ord, request ** recruitorders)
if (rc==NULL) rc = f->race; if (rc==NULL) rc = f->race;
} }
#if GUARD_DISABLES_RECRUIT == 1 #if GUARD_DISABLES_RECRUIT
/* this is a very special case because the recruiting unit may be empty /* this is a very special case because the recruiting unit may be empty
* at this point and we have to look at the creating unit instead. This * at this point and we have to look at the creating unit instead. This
* is done in cansee, which is called indirectly by is_guarded(). */ * is done in cansee, which is called indirectly by is_guarded(). */
if (is_guarded(r, u, GUARD_RECRUIT)) { if (is_guarded(r, u, GUARD_RECRUIT)) {
cmistake(u, ord, 70, MSG_EVENT); cmistake(u, ord, 70, MSG_EVENT);
return; return;
} }
#endif #endif
if (rc == new_race[RC_INSECT]) { if (rc == new_race[RC_INSECT]) {
if (get_gamedate(turn, 0)->season == 0 && rterrain(r) != T_DESERT) { gamedate date;
get_gamedate(turn, &date);
if (date.season == 0 && rterrain(r) != T_DESERT) {
#ifdef INSECT_POTION #ifdef INSECT_POTION
boolean usepotion = false; boolean usepotion = false;
unit *u2; unit *u2;
for (u2 = r->units; u2; u2 = u2->next) for (u2 = r->units; u2; u2 = u2->next)
if (fval(u2, UFL_WARMTH)) { if (fval(u2, UFL_WARMTH)) {
usepotion = true; usepotion = true;
break; break;
} }
if (!usepotion) if (!usepotion)
#endif #endif
{ {
cmistake(u, ord, 98, MSG_EVENT); cmistake(u, ord, 98, MSG_EVENT);
return; return;
} }
} }
/* in Gletschern, Eisbergen gar nicht rekrutieren */ /* in Gletschern, Eisbergen gar nicht rekrutieren */
if (r_insectstalled(r)) { if (r_insectstalled(r)) {
cmistake(u, ord, 97, MSG_EVENT); cmistake(u, ord, 97, MSG_EVENT);
return; return;
} }
} }
if (is_cursed(r->attribs, C_RIOT, 0)) { if (is_cursed(r->attribs, C_RIOT, 0)) {
/* Die Region befindet sich in Aufruhr */ /* Die Region befindet sich in Aufruhr */
cmistake(u, ord, 237, MSG_EVENT); cmistake(u, ord, 237, MSG_EVENT);
return; return;
} }
if (!(rc->ec_flags & ECF_REC_HORSES) && fval(r, RF_ORCIFIED)) { if (!(rc->ec_flags & ECF_REC_HORSES) && fval(r, RF_ORCIFIED)) {
if (rc != new_race[RC_URUK]) if (rc != new_race[RC_URUK])
@ -504,16 +506,16 @@ recruit(unit * u, struct order * ord, request ** recruitorders)
return; return;
} }
} }
recruitcost = rc->recruitcost; recruitcost = rc->recruitcost;
if (recruitcost) { if (recruitcost) {
pl = getplane(r); pl = getplane(r);
if (pl && fval(pl, PFL_NORECRUITS)) { if (pl && fval(pl, PFL_NORECRUITS)) {
ADDMSG(&u->faction->msgs, ADDMSG(&u->faction->msgs,
msg_feedback(u, ord, "error_pflnorecruit", "")); msg_feedback(u, ord, "error_pflnorecruit", ""));
return; return;
} }
if (get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, recruitcost) < recruitcost) { if (get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, recruitcost) < recruitcost) {
cmistake(u, ord, 142, MSG_EVENT); cmistake(u, ord, 142, MSG_EVENT);
return; return;
@ -524,7 +526,7 @@ recruit(unit * u, struct order * ord, request ** recruitorders)
return; return;
} }
/* snotlinge sollten hiermit bereits abgefangen werden, die /* snotlinge sollten hiermit bereits abgefangen werden, die
* parteirasse ist uruk oder ork*/ * parteirasse ist uruk oder ork*/
if (u->race != rc) { if (u->race != rc) {
if (u->number != 0) { if (u->number != 0) {
cmistake(u, ord, 139, MSG_EVENT); cmistake(u, ord, 139, MSG_EVENT);
@ -532,16 +534,16 @@ recruit(unit * u, struct order * ord, request ** recruitorders)
} }
else u->race = rc; else u->race = rc;
} }
if (has_skill(u, SK_MAGIC)) { if (has_skill(u, SK_MAGIC)) {
/* error158;de;{unit} in {region}: '{command}' - Magier arbeiten /* error158;de;{unit} in {region}: '{command}' - Magier arbeiten
* grundsätzlich nur alleine! */ * grundsätzlich nur alleine! */
cmistake(u, ord, 158, MSG_EVENT); cmistake(u, ord, 158, MSG_EVENT);
return; return;
} }
if (has_skill(u, SK_ALCHEMY) if (has_skill(u, SK_ALCHEMY)
&& count_skill(u->faction, SK_ALCHEMY) + n > && count_skill(u->faction, SK_ALCHEMY) + n >
max_skill(u->faction, SK_ALCHEMY)) max_skill(u->faction, SK_ALCHEMY))
{ {
cmistake(u, ord, 156, MSG_EVENT); cmistake(u, ord, 156, MSG_EVENT);
return; return;
@ -550,9 +552,9 @@ recruit(unit * u, struct order * ord, request ** recruitorders)
int pooled = get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, recruitcost * n); int pooled = get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, recruitcost * n);
n = min(n, pooled / recruitcost); n = min(n, pooled / recruitcost);
} }
u->wants = n; u->wants = n;
if (!n) { if (!n) {
cmistake(u, ord, 142, MSG_EVENT); cmistake(u, ord, 142, MSG_EVENT);
return; return;
@ -2542,9 +2544,15 @@ breedtrees(region *r, unit *u, int raw)
{ {
int n, i, skill, planted = 0; int n, i, skill, planted = 0;
const resource_type * rtype; const resource_type * rtype;
static int current_season = -1; static int thisturn = -1;
static int current_season;
if (current_season<0) current_season = get_gamedate(turn, NULL)->season; if (thisturn!=turn) {
gamedate date;
get_gamedate(turn, &date);
current_season = date.season;
thisturn = turn;
}
/* Bäume züchten geht nur im Frühling */ /* Bäume züchten geht nur im Frühling */
if (current_season != SEASON_SPRING){ if (current_season != SEASON_SPRING){

View File

@ -780,8 +780,11 @@ demographics(void)
static int current_season = -1; static int current_season = -1;
if (current_season<0) { if (current_season<0) {
current_season = get_gamedate(turn, NULL)->season; gamedate date;
last_weeks_season = get_gamedate(turn-1, NULL)->season; get_gamedate(turn, &date);
current_season = date.season;
get_gamedate(turn-1, &date);
last_weeks_season = date.season;
} }
for (r = regions; r; r = r->next) { for (r = regions; r; r = r->next) {

View File

@ -450,9 +450,9 @@ set_new_dragon_target(unit * u, region * r, int range)
static order * static order *
make_movement_order(unit * u, const region * target, int moves, boolean (*allowed)(const region *, const region *)) make_movement_order(unit * u, const region * target, int moves, boolean (*allowed)(const region *, const region *))
{ {
region * r = u->region; region * r = u->region;
region ** plan; region ** plan;
int bytes, position = 0; int bytes, position = 0;
char zOrder[128], * bufp = zOrder; char zOrder[128], * bufp = zOrder;
size_t size = sizeof(zOrder) - 1; size_t size = sizeof(zOrder) - 1;

View File

@ -1918,6 +1918,19 @@ report_plaintext(const char * filename, report_context * ctx, const char * chars
int enc = xmlParseCharEncoding(charset); int enc = xmlParseCharEncoding(charset);
size_t size; size_t size;
/* static variables can cope with writing for different turns */
static int thisseason = -1;
static int nextseason = -1;
static int thisturn = -1;
if (thisturn!=turn) {
gamedate date;
get_gamedate(turn+1, &date);
thisseason = date.season;
get_gamedate(turn+2, &date);
nextseason = date.season;
thisturn = turn;
}
if (F==NULL) { if (F==NULL) {
perror(filename); perror(filename);
return -1; return -1;
@ -2033,14 +2046,10 @@ report_plaintext(const char * filename, report_context * ctx, const char * chars
/* Insekten-Winter-Warnung */ /* Insekten-Winter-Warnung */
if (f->race == new_race[RC_INSECT]) { if (f->race == new_race[RC_INSECT]) {
static int thisseason = -1;
if (thisseason<0) thisseason = get_gamedate(turn+1, 0)->season;
if (thisseason == 0) { if (thisseason == 0) {
centre(F, LOC(f->locale, "nr_insectwinter"), true); centre(F, LOC(f->locale, "nr_insectwinter"), true);
rnl(F); rnl(F);
} else { } else {
static int nextseason = -1;
if (nextseason<0) nextseason = get_gamedate(turn+2, 0)->season;
if (nextseason == 0) { if (nextseason == 0) {
centre(F, LOC(f->locale, "nr_insectfall"), true); centre(F, LOC(f->locale, "nr_insectfall"), true);
rnl(F); rnl(F);

View File

@ -57,7 +57,7 @@ extern "C" {
static char * strlwc(const char * s) static char * strlwc(const char * s)
{ {
static char l[ASCIILINESZ+1]; static char l[ASCIILINESZ+1]; /* STATIC_RETURN: used for return, not across calls */
int i ; int i ;
if (s==NULL) return NULL ; if (s==NULL) return NULL ;
@ -109,7 +109,7 @@ static char * strskp(char * s)
static char * strcrop(char * s) static char * strcrop(char * s)
{ {
static char l[ASCIILINESZ+1]; static char l[ASCIILINESZ+1]; /* STATIC_RETURN: used for return, not across calls */
char * last ; char * last ;
if (s==NULL) return NULL ; if (s==NULL) return NULL ;

View File

@ -157,8 +157,8 @@ static char *
sidename(side * s) sidename(side * s)
{ {
#define SIDENAMEBUFLEN 256 #define SIDENAMEBUFLEN 256
static int bufno; static int bufno; /* STATIC_XCALL: used across calls */
static char sidename_buf[4][SIDENAMEBUFLEN]; static char sidename_buf[4][SIDENAMEBUFLEN]; /* STATIC_RESULT: used for return, not across calls */
bufno = bufno % 4; bufno = bufno % 4;
if (s->stealthfaction) { if (s->stealthfaction) {
@ -174,7 +174,7 @@ sidename(side * s)
static const char * static const char *
sideabkz(side *s, boolean truename) sideabkz(side *s, boolean truename)
{ {
static char sideabkz_buf[8]; static char sideabkz_buf[8]; /* STATIC_RESULT: used for return, not across calls */
if (s->stealthfaction && truename == false) { if (s->stealthfaction && truename == false) {
abkz(s->stealthfaction->name, sideabkz_buf, sizeof(sideabkz_buf), 3); abkz(s->stealthfaction->name, sideabkz_buf, sizeof(sideabkz_buf), 3);

View File

@ -1,6 +1,8 @@
#include <config.h> #include <config.h>
#include "calendar.h" #include "calendar.h"
#include <assert.h>
int first_turn = 0; int first_turn = 0;
int first_month = 0; int first_month = 0;
int weeks_per_month = 0; int weeks_per_month = 0;
@ -16,11 +18,10 @@ int seasons = 0;
const gamedate * const gamedate *
get_gamedate(int turn, gamedate * gd) get_gamedate(int turn, gamedate * gd)
{ {
static gamedate staticdate;
int weeks_per_year = months_per_year * weeks_per_month; int weeks_per_year = months_per_year * weeks_per_month;
int t = turn - first_turn; int t = turn - first_turn;
if (gd==NULL) gd = &staticdate; assert(gd);
if (t<0) t = turn; if (t<0) t = turn;
gd->week = t%weeks_per_month; /* 0 - weeks_per_month-1 */ gd->week = t%weeks_per_month; /* 0 - weeks_per_month-1 */

View File

@ -2493,17 +2493,18 @@ besieged(const unit * u)
int int
lifestyle(const unit * u) lifestyle(const unit * u)
{ {
static plane * astralspace = NULL;
int need; int need;
static plane * astralspace;
static int thisturn = -1;
if (thisturn!=turn) {
astralspace = getplanebyname("Astralraum");
thisturn = turn;
}
if (is_monsters(u->faction)) return 0; if (is_monsters(u->faction)) return 0;
need = maintenance_cost(u); need = maintenance_cost(u);
if (!astralspace) {
astralspace = getplanebyname("Astralraum");
}
if(u->region->planep && fval(u->region->planep, PFL_NOFEED)) if(u->region->planep && fval(u->region->planep, PFL_NOFEED))
return 0; return 0;
@ -2994,3 +2995,28 @@ entertainmoney(const region *r)
return n; return n;
} }
/** releases all memory associated with the game state.
* call this function before calling read_game() to load a new game
* if you have a previously loaded state in memory.
*/
void
free_gamedata(void)
{
free_units();
free_regions();
while (factions) {
faction * f = factions;
factions = f->next;
stripfaction(f);
free(f);
}
while (planes) {
plane * pl = planes;
planes = planes->next;
free(pl->name);
free(pl);
}
}

View File

@ -410,7 +410,7 @@ extern int entertainmoney(const struct region * r);
extern void plagues(struct region * r, boolean ismagic); extern void plagues(struct region * r, boolean ismagic);
extern struct attrib_type at_guard; extern struct attrib_type at_guard;
extern void free_gamedata(void);
#if 1 /* disable to count all units */ #if 1 /* disable to count all units */
# define count_unit(u) playerrace(u->race) # define count_unit(u) playerrace(u->race)
#else #else

View File

@ -50,7 +50,12 @@
faction * faction *
get_monsters(void) get_monsters(void)
{ {
static faction * monsters = NULL; static faction * monsters;
static int thisturn = -1;
if (thisturn!=turn) {
monsters = NULL;
thisturn = turn;
}
if (!monsters) { if (!monsters) {
faction * f; faction * f;

View File

@ -879,7 +879,16 @@ is_guarded(region * r, unit * u, unsigned int mask)
{ {
unit *u2 = NULL; unit *u2 = NULL;
int i; int i;
static unit * guardcache[MAXGUARDCACHE], * lastguard; static unit * guardcache[MAXGUARDCACHE], * lastguard; /* STATIC_XCALL: used across calls */
static int thisturn = -1;
if (thisturn!=turn) {
if (thisturn>=0) {
/* clear the previous turn's cache */
memset(guardcache, 0, sizeof(guardcache));
lastguard = NULL;
}
thisturn = turn;
}
if (!fval(r, RF_GUARDED)) { if (!fval(r, RF_GUARDED)) {
return NULL; return NULL;
@ -1638,12 +1647,15 @@ sail(unit * u, order * ord, boolean move_on_land, region_list **routep)
} }
if (!flying_ship(sh)) { if (!flying_ship(sh)) {
static int stormyness = -1;
int stormchance; int stormchance;
static int stormyness;
static int thisturn = -1;
if (stormyness == -1) { if (thisturn != turn) {
int thismonth = get_gamedate(turn, 0)->month; gamedate date;
stormyness = storms[thismonth] * 5; get_gamedate(turn, &date);
stormyness = storms[date.month] * 5;
thisturn = turn;
} }
/* storms should be the first thing we do. */ /* storms should be the first thing we do. */

View File

@ -143,7 +143,7 @@ regions_in_range(struct region * start, int maxdist, boolean (*allowed)(const st
static region ** static region **
internal_path_find(region *start, const region *target, int maxlen, boolean (*allowed)(const region*, const region*)) internal_path_find(region *start, const region *target, int maxlen, boolean (*allowed)(const region*, const region*))
{ {
static region * path[MAXDEPTH+2]; static region * path[MAXDEPTH+2]; /* STATIC_RETURN: used for return, not across calls */
direction_t d; direction_t d;
node * root = new_node(start, 0, NULL); node * root = new_node(start, 0, NULL);
node ** end = &root->next; node ** end = &root->next;

View File

@ -388,9 +388,11 @@ 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 * delmarker = (region*)&dummy_data; /* a funny hack */ static region * dummy_ptr = (region*)&dummy_data; /* a funny hack */
static unsigned int uidhash[MAXREGIONS]; static unsigned int uidhash[MAXREGIONS];
#define DELMARKER dummy_ptr
unsigned int unsigned int
generate_region_id(void) generate_region_id(void)
{ {
@ -425,7 +427,7 @@ rfindhash(short x, short y)
#endif #endif
if (rid>=0) { if (rid>=0) {
int key = HASH1(rid, RMAXHASH), gk = HASH2(rid, RMAXHASH); int key = HASH1(rid, RMAXHASH), gk = HASH2(rid, RMAXHASH);
while (regionhash[key]!=NULL && (regionhash[key]==delmarker || regionhash[key]->x!=x || regionhash[key]->y!=y)) { while (regionhash[key]!=NULL && (regionhash[key]==DELMARKER || regionhash[key]->x!=x || regionhash[key]->y!=y)) {
key = (key + gk) % RMAXHASH; key = (key + gk) % RMAXHASH;
#if HASH_STATISTICS #if HASH_STATISTICS
++hash_misses; ++hash_misses;
@ -441,7 +443,7 @@ rhash(region * r)
{ {
unsigned int rid = coor_hashkey(r->x, r->y); unsigned int rid = coor_hashkey(r->x, r->y);
int key = HASH1(rid, RMAXHASH), gk = HASH2(rid, RMAXHASH); int key = HASH1(rid, RMAXHASH), gk = HASH2(rid, RMAXHASH);
while (regionhash[key]!=NULL && regionhash[key]!=delmarker && regionhash[key]!=r) { while (regionhash[key]!=NULL && regionhash[key]!=DELMARKER && regionhash[key]!=r) {
key = (key + gk) % RMAXHASH; key = (key + gk) % RMAXHASH;
} }
assert(regionhash[key]!=r || !"trying to add the same region twice"); assert(regionhash[key]!=r || !"trying to add the same region twice");
@ -469,37 +471,27 @@ runhash(region * r)
key = (key + gk) % RMAXHASH; key = (key + gk) % RMAXHASH;
} }
assert(regionhash[key]==r || !"trying to remove a unit that is not hashed"); assert(regionhash[key]==r || !"trying to remove a unit that is not hashed");
regionhash[key] = delmarker; regionhash[key] = DELMARKER;
} }
region * region *
r_connect(const region * r, direction_t dir) r_connect(const region * r, direction_t dir)
{ {
static int set = 0; region * result;
static region * buffer[MAXDIRECTIONS];
static const region * last = NULL;
#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]) return r->connect[dir]; if (r->connect[dir]) return r->connect[dir];
#endif #endif
assert(dir<MAXDIRECTIONS); assert(dir<MAXDIRECTIONS);
if (r != last) { result = rfindhash(r->x + delta_x[dir], r->y + delta_y[dir]);
set = 0;
last = r;
}
else
if (set & (1 << dir)) return buffer[dir];
buffer[dir] = rfindhash(r->x + delta_x[dir], r->y + delta_y[dir]);
set |= (1<<dir);
#ifdef FAST_CONNECT #ifdef FAST_CONNECT
if (buffer[dir]) { if (result) {
rmodify->connect[dir] = buffer[dir]; rmodify->connect[dir] = result;
buffer[dir]->connect[back[dir]] = rmodify; result->connect[back[dir]] = rmodify;
} }
#endif #endif
return buffer[dir]; return result;
} }
region * region *
@ -935,6 +927,7 @@ free_region(region * r)
while (r->buildings) { while (r->buildings) {
building * b = r->buildings; building * b = r->buildings;
r->buildings = b->next; r->buildings = b->next;
bunhash(b);
free(b->name); free(b->name);
free(b->display); free(b->display);
free(b); free(b);
@ -943,6 +936,7 @@ free_region(region * r)
while (r->ships) { while (r->ships) {
ship * s = r->ships; ship * s = r->ships;
r->ships = s->next; r->ships = s->next;
sunhash(s);
free(s->name); free(s->name);
free(s->display); free(s->display);
free(s); free(s);

View File

@ -116,7 +116,7 @@ typedef struct region {
struct faction * owner; struct faction * owner;
#endif #endif
#ifdef FAST_CONNECT #ifdef FAST_CONNECT
struct region * connect[MAXDIRECTIONS]; struct region * connect[MAXDIRECTIONS]; /* use rconnect(r, dir) to access */
#endif #endif
} region; } region;

View File

@ -163,16 +163,19 @@ get_normalplane(void)
plane * plane *
get_astralplane(void) get_astralplane(void)
{ {
static plane * astral_plane = NULL; static plane * astralspace;
if (astral_plane==NULL) { static int thisturn = -1;
astral_plane = getplanebyid(1); if (thisturn!=turn) {
astralspace = getplanebyname("Astralraum");
thisturn = turn;
} }
if (astral_plane==NULL) {
astral_plane = create_new_plane(1, "Astralraum", if (astralspace==NULL) {
astralspace = create_new_plane(1, "Astralraum",
TE_CENTER_X-500, TE_CENTER_X+500, TE_CENTER_X-500, TE_CENTER_X+500,
TE_CENTER_Y-500, TE_CENTER_Y+500, 0); TE_CENTER_Y-500, TE_CENTER_Y+500, 0);
} }
return astral_plane; return astralspace;
} }
void void

View File

@ -414,6 +414,37 @@ frame_regions(int age, terrain_t terrain)
} }
} }
} }
static void
prepare_starting_region(region * r)
{
int n, t;
double p;
assert(r->land);
/* population between 30% and 60% of max */
p = rng_double();
n = (int)(r->terrain->size * (0.3 + p*0.3));
rsetpeasants(r, n);
/* trees: don't squash the peasants, and at least 5% should be forrest */
t = (rtrees(r, 2) + rtrees(r, 1)/2) * TREESIZE;
if (t < r->terrain->size/20 || t+n > r->terrain->size) {
double p2 = 0.05 + rng_double()*(1.0-p-0.05);
int maxtrees = (int)(r->terrain->size/1.25/TREESIZE); /* 1.25 = each young tree will take 1/2 the space of old trees */
int trees = (int)(p2 * maxtrees);
rsettrees(r, 2, trees);
rsettrees(r, 1, trees/2);
rsettrees(r, 0, trees/4);
}
/* horses: between 1% and 2% */
p = rng_double();
rsethorses(r, (int)(r->terrain->size * (0.01 + p*0.01)));
fix_demand(r);
}
int int
autoseed(newfaction ** players, int nsize, int max_agediff) autoseed(newfaction ** players, int nsize, int max_agediff)
@ -545,28 +576,14 @@ autoseed(newfaction ** players, int nsize, int max_agediff)
newfaction ** nfp, * nextf = *players; newfaction ** nfp, * nextf = *players;
faction * f; faction * f;
unit * u; unit * u;
int n;
isize += REGIONS_PER_FACTION; isize += REGIONS_PER_FACTION;
terraform(r, preferred_terrain(nextf->race)); terraform(r, preferred_terrain(nextf->race));
n = rhorses(r); prepare_starting_region(r);
if (n<r->terrain->size/200) {
n = r->terrain->size/200;
rsethorses(r, n);
}
n = rtrees(r, 2);
if (n<r->terrain->size/100) {
n = r->terrain->size/100;
rsettrees(r, 2, n);
rsettrees(r, 2, n/4);
rsettrees(r, 2, n/2);
}
n = rhorses(r);
++tsize; ++tsize;
assert(r->land && r->units==0); assert(r->land && r->units==0);
u = addplayer(r, addfaction(nextf->email, nextf->password, nextf->race, u = addplayer(r, addfaction(nextf->email, nextf->password, nextf->race,
nextf->lang, nextf->subscription)); nextf->lang, nextf->subscription));
fix_demand(r);
f = u->faction; f = u->faction;
fset(f, FFL_ISNEW); fset(f, FFL_ISNEW);
f->alliance = nextf->allies; f->alliance = nextf->allies;

View File

@ -55,14 +55,14 @@ atoi36(const char * str)
const char* const char*
itoab(int i, int base) itoab(int i, int base)
{ {
static char **as = NULL; static char **as = NULL; /* STATIC_RETURN: used for return, not across calls */
char * s, * dst; char * s, * dst;
static int index = 0; static int index = 0; /* STATIC_XCALL: used across calls */
int neg = 0; int neg = 0;
if (!as) { if (!as) {
int j; int j;
char * x = (char*)calloc(sizeof(char), 8*4); char * x = (char*)calloc(sizeof(char), 8*4); /* STATIC_LEAK: malloc in static variable */
as = (char **)calloc(sizeof(char*), 4); as = (char **)calloc(sizeof(char*), 4);
for (j=0;j!=4;++j) as[j] = x+j*8; for (j=0;j!=4;++j) as[j] = x+j*8;
} }

View File

@ -80,7 +80,7 @@ spc_email_isvalid(const char *address)
{ {
int count = 0; int count = 0;
const char *c, *domain; const char *c, *domain;
static const char *rfc822_specials = "()<>@,;:\\\"[]"; static const char *rfc822_specials = "()<>@,;:\\\"[]"; /* STATIC_CONST: contains a constant value */
/* first we validate the name portion (name@domain) */ /* first we validate the name portion (name@domain) */
for (c = address; *c; c++) { for (c = address; *c; c++) {

View File

@ -215,7 +215,7 @@ mkname_buf(const char * space, const char * name, char * buffer)
const char * const char *
mkname(const char * space, const char * name) mkname(const char * space, const char * name)
{ {
static char zBuffer[128]; static char zBuffer[128]; /* STATIC_RESULT: used for return, not across calls */
return mkname_buf(space, name, zBuffer); return mkname_buf(space, name, zBuffer);
} }

View File

@ -140,9 +140,9 @@ log_close(void)
static int static int
check_dupe(const char * format, const char * type) check_dupe(const char * format, const char * type)
{ {
static const char * last_type; static const char * last_type; /* STATIC_XCALL: used across calls */
static char last_message[32]; static char last_message[32]; /* STATIC_XCALL: used across calls */
static int dupes = 0; static int dupes = 0; /* STATIC_XCALL: used across calls */
if (strncmp(last_message, format, sizeof(last_message))==0) { if (strncmp(last_message, format, sizeof(last_message))==0) {
++dupes; ++dupes;
return 1; return 1;

View File

@ -124,7 +124,7 @@ skip_token(void)
const char * const char *
parse_token(const char ** str) parse_token(const char ** str)
{ {
static char lbuf[MAXTOKENSIZE]; static char lbuf[MAXTOKENSIZE]; /* STATIC_RESULT: used for return, not across calls */
char * cursor = lbuf; char * cursor = lbuf;
char quotechar = 0; char quotechar = 0;
boolean escape = false; boolean escape = false;

View File

@ -36,7 +36,7 @@
double double
normalvariate(double mu, double sigma) normalvariate(double mu, double sigma)
{ {
static double NV_MAGICCONST = 1.7155277699214135; static const double NV_MAGICCONST = 1.7155277699214135; /* STATIC_CONST: a constant */
double z; double z;
for (;;) { for (;;) {
double u1 = rng_double(); double u1 = rng_double();

View File

@ -74,5 +74,6 @@ resolve(void)
ur->resolve(ur->data, ur->ptrptr); ur->resolve(ur->data, ur->ptrptr);
++ur; ++ur;
} }
ur_list = ur_begin = ur_current; free(ur_list);
ur_list = NULL;
} }

View File

@ -68,8 +68,8 @@ sqlquote(const char * str)
{ {
#define BUFFERS 4 #define BUFFERS 4
#define BUFSIZE 1024 #define BUFSIZE 1024
static char sqlstring[BUFSIZE*BUFFERS]; static char sqlstring[BUFSIZE*BUFFERS]; /* STATIC_RESULT: used for return, not across calls */
static int index = 0; static int index = 0; /* STATIC_XCALL: used across calls */
char * start = sqlstring+index*BUFSIZE; char * start = sqlstring+index*BUFSIZE;
char * o = start; char * o = start;
const char * i = str; const char * i = str;

View File

@ -37,7 +37,7 @@ hashstring(const char* s)
INLINE_FUNCTION const char * INLINE_FUNCTION const char *
escape_string(const char * str, char * buffer, unsigned int len) escape_string(const char * str, char * buffer, unsigned int len)
{ {
static char s_buffer[4096]; static char s_buffer[4096]; /* STATIC_RESULT: used for return, not across calls */
const char * p = str; const char * p = str;
char * o; char * o;
if (buffer==NULL) { if (buffer==NULL) {

View File

@ -77,7 +77,7 @@ static struct {
char * char *
balloc(size_t size) balloc(size_t size)
{ {
static int init = 0; static int init = 0; /* STATIC_XCALL: used across calls */
if (!init) { if (!init) {
init = 1; init = 1;
buffer.current = buffer.begin = malloc(BUFSIZE); buffer.current = buffer.begin = malloc(BUFSIZE);

View File

@ -42,7 +42,7 @@ typedef struct tref {
void void
addtoken(tnode * root, const char * str, variant id) addtoken(tnode * root, const char * str, variant id)
{ {
static struct replace { static const struct replace { /* STATIC_CONST: constant value */
ucs4_t ucs; ucs4_t ucs;
const char str[3]; const char str[3];
} replace[] = { } replace[] = {

View File

@ -22,7 +22,7 @@
DIR * DIR *
opendir(const char *name) opendir(const char *name)
{ {
static DIR direct; static DIR direct; /* STATIC_RESULT: used for return, not across calls */
direct.first = 1; direct.first = 1;
_searchenv(name, "ERESSEA_PATH", direct.name); _searchenv(name, "ERESSEA_PATH", direct.name);
@ -34,8 +34,8 @@ opendir(const char *name)
struct dirent * struct dirent *
readdir(DIR * thedir) readdir(DIR * thedir)
{ {
static struct _finddata_t ft; static struct _finddata_t ft; /* STATIC_RESULT: used for return, not across calls */
static struct dirent de; static struct dirent de; /* STATIC_RESULT: used for return, not across calls */
char where[_MAX_PATH]; char where[_MAX_PATH];
strcat(strcpy(where, thedir->name), "/*"); strcat(strcpy(where, thedir->name), "/*");

View File

@ -128,17 +128,6 @@ curse_emptiness(void)
return 0; return 0;
} }
void
french_testers(void)
{
faction * f = factions;
const struct locale * french = find_locale("fr");
while (f!=NULL) {
if (f->locale==french) fset(f, FFL_NOTIMEOUT);
f = f->next;
}
}
static void static void
verify_owners(boolean bOnce) verify_owners(boolean bOnce)
{ {
@ -928,18 +917,19 @@ fix_groups(void)
void void
korrektur(void) korrektur(void)
{ {
#if GLOBAL_WARMING
gamedate date;
get_gamedate(turn, &date);
if (date.season == SEASON_SUMMER) {
global_warming();
}
#endif
check_dissolve(); check_dissolve();
french_testers();
do_once("rdec", &road_decay); do_once("rdec", &road_decay);
do_once("unfi", &fix_undead); do_once("unfi", &fix_undead);
do_once("chgt", &fix_chaosgates); do_once("chgt", &fix_chaosgates);
do_once("atrx", &fix_attribflags); do_once("atrx", &fix_attribflags);
do_once("asfi", &fix_astral_firewalls); do_once("asfi", &fix_astral_firewalls);
#if GLOBAL_WARMING
if (get_gamedate(turn, NULL)->season == SEASON_SUMMER) {
global_warming();
}
#endif
fix_astralplane(); fix_astralplane();
fix_firewalls(); fix_firewalls();
fix_toads(); fix_toads();

View File

@ -233,6 +233,7 @@ bind_gamecode(lua_State * L)
module(L)[ module(L)[
def("read_game", &read_game), def("read_game", &read_game),
def("write_game", &write_game), def("write_game", &write_game),
def("free_game", &free_gamedata),
def("get_encoding", &get_encoding), def("get_encoding", &get_encoding),
def("set_encoding", &set_encoding), def("set_encoding", &set_encoding),

View File

@ -129,9 +129,6 @@
#if defined(_MSC_VER) #if defined(_MSC_VER)
# include <crtdbg.h> # include <crtdbg.h>
#endif #endif
#if defined(USE_DMALLOC)
# define CLEANUP_CODE
#endif
/** /**
** global variables we are importing from other modules ** global variables we are importing from other modules
@ -322,42 +319,24 @@ lua_done(lua_State * luaState)
lua_close(luaState); lua_close(luaState);
} }
#ifndef CLEANUP_CODE
# define CLEANUP_CODE
#endif
#ifdef CLEANUP_CODE
static void static void
game_done(void) game_done(void)
{ {
#ifdef CLEANUP_CODE
/* Diese Routine enfernt allen allokierten Speicher wieder. Das ist nur /* Diese Routine enfernt allen allokierten Speicher wieder. Das ist nur
* zum Debugging interessant, wenn man Leak Detection hat, und nach * zum Debugging interessant, wenn man Leak Detection hat, und nach
* nicht freigegebenem Speicher sucht, der nicht bis zum Ende benötigt * nicht freigegebenem Speicher sucht, der nicht bis zum Ende benötigt
* wird (temporäre Hilsstrukturen) */ * wird (temporäre Hilsstrukturen) */
free_units(); free_game();
free_regions();
while (factions) {
faction * f = factions;
factions = f->next;
stripfaction(f);
free(f);
}
while (planes) {
plane * pl = planes;
planes = planes->next;
free(pl->name);
free(pl);
}
creport_cleanup(); creport_cleanup();
#ifdef REPORT_FORMAT_NR #ifdef REPORT_FORMAT_NR
report_cleanup(); report_cleanup();
#endif #endif
calendar_cleanup(); calendar_cleanup();
}
#endif #endif
}
#define CRTDBG #define CRTDBG
#ifdef CRTDBG #ifdef CRTDBG
@ -657,9 +636,7 @@ main(int argc, char *argv[])
#ifdef MSPACES #ifdef MSPACES
malloc_stats(); malloc_stats();
#endif #endif
#ifdef CLEANUP_CODE
game_done(); game_done();
#endif
kernel_done(); kernel_done();
lua_done(luaState); lua_done(luaState);
log_close(); log_close();