From b7552f0d06ef5e9cdf9a754f8d0e062eb855b322 Mon Sep 17 00:00:00 2001 From: Enno Rehling <enno@eressea.de> Date: Sun, 19 Feb 2006 22:43:56 +0000 Subject: [PATCH] - New random number generator - Faster get_pooled/use_pooled - faster peasants() - faster plagues() - faster horses() --- src/Jamrules | 33 +- src/common/attributes/key.c | 1 + src/common/attributes/orcification.c | 1 + src/common/gamecode/creport.c | 428 ++++++++-------- src/common/gamecode/economy.c | 728 ++++++++++++++------------- src/common/gamecode/laws.c | 128 +++-- src/common/gamecode/luck.c | 22 +- src/common/gamecode/monster.c | 68 +-- src/common/gamecode/randenc.c | 87 ++-- src/common/gamecode/report.c | 213 ++++---- src/common/gamecode/spy.c | 5 +- src/common/gamecode/study.c | 7 +- src/common/items/phoenixcompass.c | 4 +- src/common/items/weapons.c | 11 +- src/common/kernel/battle.c | 34 +- src/common/kernel/border.c | 5 +- src/common/kernel/build.c | 33 +- src/common/kernel/curse.c | 4 +- src/common/kernel/equipment.c | 5 +- src/common/kernel/eressea.c | 76 ++- src/common/kernel/eressea.h | 19 +- src/common/kernel/faction.c | 11 +- src/common/kernel/faction.h | 3 +- src/common/kernel/give.c | 2 +- src/common/kernel/item.c | 124 ++--- src/common/kernel/item.h | 38 +- src/common/kernel/karma.c | 7 +- src/common/kernel/magic.c | 83 ++- src/common/kernel/movement.c | 18 +- src/common/kernel/names.c | 47 +- src/common/kernel/player.c | 6 +- src/common/kernel/pool.c | 8 +- src/common/kernel/pool.h | 2 +- src/common/kernel/race.c | 9 +- src/common/kernel/region.c | 40 +- src/common/kernel/reports.c | 122 +++-- src/common/kernel/reports.h | 24 +- src/common/kernel/resources.c | 7 +- src/common/kernel/save.c | 17 +- src/common/kernel/skill.c | 3 +- src/common/kernel/teleport.c | 10 +- src/common/kernel/unit.c | 6 +- src/common/kernel/unit.h | 2 +- src/common/modules/arena.c | 69 +-- src/common/modules/autoseed.c | 24 +- src/common/modules/dungeon.c | 8 +- src/common/modules/gmcmd.c | 21 +- src/common/modules/weather.c | 8 +- src/common/modules/wormhole.c | 3 +- src/common/races/dragons.c | 8 +- src/common/races/zombies.c | 25 +- src/common/spells/combatspells.c | 16 +- src/common/spells/spells.c | 70 +-- src/common/util/Jamfile | 2 + src/common/util/cvector.c | 9 +- src/common/util/dice.c | 7 +- src/common/util/mt19937ar.c | 172 +++++++ src/common/util/rand.c | 11 +- src/common/util/rng.h | 45 ++ src/eressea/lua/eressea.cpp | 5 +- src/eressea/main.c | 22 +- src/eressea/server.cpp | 6 +- src/mapper/map_modify.c | 36 +- src/mapper/mapper.c | 14 +- src/tools/namegen.c | 2 +- 65 files changed, 1698 insertions(+), 1386 deletions(-) create mode 100644 src/common/util/mt19937ar.c create mode 100644 src/common/util/rng.h diff --git a/src/Jamrules b/src/Jamrules index df9c50026..83e7ad7b8 100644 --- a/src/Jamrules +++ b/src/Jamrules @@ -18,6 +18,10 @@ if ! $(HAVE_LUA) { HAVE_LUA = 1 ; } +if ! $(CPU) { + CPU = pentium2 ; +} + if $(DISTCC_HOSTS) { DISTCC = 1 ; } @@ -42,6 +46,13 @@ if $(DMALLOC) { LINKFLAGS += -ldmalloc ; } +if $(COVERAGE) = 1 { + Echo Compiling with gcov info ; + CCFLAGS += -fprofile-arcs -ftest-coverage ; + C++FLAGS += -fprofile-arcs -ftest-coverage ; + LINKFLAGS += -fprofile-arcs -ftest-coverage ; +} + if $(PROFILE) = 1 { Echo Compiling with profiler ; CCFLAGS += -pg -ggdb ; @@ -125,8 +136,8 @@ rule TargetDirectory SubDirC++Flags -ggdb -O0 ; } else { - SubDirCcFlags -DNDEBUG -O2 ; - SubDirC++Flags -DNDEBUG -O2 ; + SubDirCcFlags -DNDEBUG -O3 -mtune=$(CPU) ; + SubDirC++Flags -DNDEBUG -O3 -mtune=$(CPU) ; } } @@ -136,19 +147,21 @@ if ! $(DEBUG) { } if $(WITHOUT_LUA) { - ECHO Compiling without LUA ; + ECHO Compiling without LUA ; } +if $(DEBUG) = 0 { + TARGET_PREFIX = Release ; +} +else { + TARGET_PREFIX = Debug ; +} if $(PROFILE) = 1 { TARGET_PREFIX = Profile ; } -else { - if $(DEBUG) = 0 { - TARGET_PREFIX = Release ; - } - else { - TARGET_PREFIX = Debug ; - } +if $(COVERAGE) = 1 { + TARGET_PREFIX = Coverage ; } + diff --git a/src/common/attributes/key.c b/src/common/attributes/key.c index 2f8c12871..27f6b0013 100644 --- a/src/common/attributes/key.c +++ b/src/common/attributes/key.c @@ -13,6 +13,7 @@ */ #include <config.h> +#include <eressea.h> #include "key.h" #include <kernel/save.h> diff --git a/src/common/attributes/orcification.c b/src/common/attributes/orcification.c index f6bc70d44..c2719c717 100644 --- a/src/common/attributes/orcification.c +++ b/src/common/attributes/orcification.c @@ -13,6 +13,7 @@ */ #include <config.h> +#include <eressea.h> #include "orcification.h" #include <kernel/save.h> diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index f0636ce57..42f369870 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -1089,6 +1089,7 @@ report_computer(const char * filename, report_context * ctx) unit *u; const char * mailto = locale_string(f->locale, "mailto"); const attrib * a; + seen_region * sr = NULL; #ifdef SCORE_MODULE int score = 0, avgscore = 0; #endif @@ -1224,7 +1225,7 @@ report_computer(const char * filename, report_context * ctx) description = LOC(f->locale, potiontext); } - fprintf(F, "\"%s\";Beschr\n", description); + fprintf(F, "\"%s\";Beschr\n", description); fprintf(F, "ZUTATEN\n"); while (m->number) { @@ -1235,237 +1236,238 @@ report_computer(const char * filename, report_context * ctx) } /* traverse all regions */ - for (r=ctx->first;r!=ctx->last;r=r->next) { + for (r=ctx->first;sr==NULL && r!=ctx->last;r=r->next) { + sr = find_seen(ctx->seen, r); + } + for (;sr!=NULL;sr=sr->next) { + region * r = sr->r; int modifier = 0; const char * tname; - const seen_region * sd = find_seen(ctx->seen, r); - - if (sd==NULL) continue; - if (!rplane(r)) { - if (opt_cr_absolute_coords) { - fprintf(F, "REGION %d %d\n", r->x, r->x); - } else { - fprintf(F, "REGION %d %d\n", region_x(r, f), region_y(r, f)); - } - } else { + if (!rplane(r)) { + if (opt_cr_absolute_coords) { + fprintf(F, "REGION %d %d\n", r->x, r->x); + } else { + fprintf(F, "REGION %d %d\n", region_x(r, f), region_y(r, f)); + } + } else { #if ENCODE_SPECIAL - if (rplane(r)->flags & PFL_NOCOORDS) fprintf(F, "SPEZIALREGION %d %d\n", encode_region(f, r), rplane(r)->id); + if (rplane(r)->flags & PFL_NOCOORDS) fprintf(F, "SPEZIALREGION %d %d\n", encode_region(f, r), rplane(r)->id); #else - if (rplane(r)->flags & PFL_NOCOORDS) continue; + if (rplane(r)->flags & PFL_NOCOORDS) continue; #endif - else fprintf(F, "REGION %d %d %d\n", region_x(r, f), region_y(r, f), rplane(r)->id); - } - if (r->land && strlen(rname(r, f->locale))) fprintf(F, "\"%s\";Name\n", rname(r, f->locale)); - if (is_cursed(r->attribs,C_MAELSTROM, 0)) - tname = "maelstrom"; - else { - tname = terrain_name(r); - } - - fprintf(F, "\"%s\";Terrain\n", add_translation(tname, locale_string(f->locale, tname))); - if (sd->mode!=see_unit) fprintf(F, "\"%s\";visibility\n", visibility[sd->mode]); - + else fprintf(F, "REGION %d %d %d\n", region_x(r, f), region_y(r, f), rplane(r)->id); + } + if (r->land && strlen(rname(r, f->locale))) fprintf(F, "\"%s\";Name\n", rname(r, f->locale)); + if (is_cursed(r->attribs,C_MAELSTROM, 0)) + tname = "maelstrom"; + else { + tname = terrain_name(r); + } + + fprintf(F, "\"%s\";Terrain\n", add_translation(tname, locale_string(f->locale, tname))); + if (sr->mode!=see_unit) fprintf(F, "\"%s\";visibility\n", visibility[sr->mode]); + { faction * owner = region_owner(r); if (owner) { fprintf(F, "%d;owner\n", owner->no); } } - if (sd->mode == see_neighbour) { - cr_borders(ctx->seen, r, f, sd->mode, F); - } else { + if (sr->mode == see_neighbour) { + cr_borders(ctx->seen, r, f, sr->mode, F); + } else { #define RESOURCECOMPAT - char cbuf[8192], *pos = cbuf; + char cbuf[8192], *pos = cbuf; #ifdef RESOURCECOMPAT - if (r->display && strlen(r->display)) - fprintf(F, "\"%s\";Beschr\n", r->display); + if (r->display && strlen(r->display)) + fprintf(F, "\"%s\";Beschr\n", r->display); #endif - if (fval(r->terrain, LAND_REGION)) { - int trees = rtrees(r, 2); - int saplings = rtrees(r, 1); -# ifdef RESOURCECOMPAT - if (trees > 0) fprintf(F, "%d;Baeume\n", trees); - if (saplings > 0) fprintf(F, "%d;Schoesslinge\n", saplings); - if (fval(r, RF_MALLORN) && (trees > 0 || saplings > 0)) - fprintf(F, "1;Mallorn\n"); -# endif - if (!fval(r, RF_MALLORN)) { - if (saplings) pos = report_resource(pos, "rm_sapling", f->locale, saplings, -1); - if (trees) pos = report_resource(pos, "rm_trees", f->locale, trees, -1); - } else { - if (saplings) pos = report_resource(pos, "rm_mallornsapling", f->locale, saplings, -1); - if (trees) pos = report_resource(pos, "rm_mallorn", f->locale, trees, -1); - } - fprintf(F, "%d;Bauern\n", rpeasants(r)); - if(fval(r, RF_ORCIFIED)) { - fprintf(F, "1;Verorkt\n"); - } - fprintf(F, "%d;Pferde\n", rhorses(r)); - - if (sd->mode>=see_unit) { - struct demand * dmd = r->land->demands; - struct rawmaterial * res = r->resources; - fprintf(F, "%d;Silber\n", rmoney(r)); - fprintf(F, "%d;Unterh\n", entertainmoney(r)); - - if (is_cursed(r->attribs, C_RIOT, 0)){ - fprintf(F, "0;Rekruten\n"); - } else { - fprintf(F, "%d;Rekruten\n", rpeasants(r) / RECRUITFRACTION); - } - if (production(r)) { - fprintf(F, "%d;Lohn\n", wage(r, f, f->race)); - } - - while (res) { - int maxskill = 0; - int level = -1; - int visible = -1; - const item_type * itype = resource2item(res->type->rtype); - if (res->type->visible==NULL) { - visible = res->amount; - level = res->level + itype->construction->minskill - 1; - } else { - const unit * u; - for (u=r->units; visible!=res->amount && u!=NULL; u=u->next) { - if (u->faction == f) { - int s = eff_skill(u, itype->construction->skill, r); - if (s>maxskill) { - if (s>=itype->construction->minskill) { - assert(itype->construction->minskill>0); - level = res->level + itype->construction->minskill - 1; - } - maxskill = s; - visible = res->type->visible(res, maxskill); - } - } - } - } - if (level>=0 && visible >=0) { - pos = report_resource(pos, res->type->name, f->locale, visible, level); -# ifdef RESOURCECOMPAT - if (visible>=0) fprintf(F, "%d;%s\n", visible, crtag(res->type->name)); + if (fval(r->terrain, LAND_REGION)) { + int trees = rtrees(r, 2); + int saplings = rtrees(r, 1); +#ifdef RESOURCECOMPAT + if (trees > 0) fprintf(F, "%d;Baeume\n", trees); + if (saplings > 0) fprintf(F, "%d;Schoesslinge\n", saplings); + if (fval(r, RF_MALLORN) && (trees > 0 || saplings > 0)) + fprintf(F, "1;Mallorn\n"); #endif - } - res = res->next; - } - /* trade */ - if (!TradeDisabled() && rpeasants(r)/TRADE_FRACTION > 0) { - fputs("PREISE\n", F); - while (dmd) { - const char * ch = resourcename(dmd->type->itype->rtype, 0); - fprintf(F, "%d;%s\n", (dmd->value - ? dmd->value*dmd->type->price - : -dmd->type->price), - add_translation(ch, locale_string(f->locale, ch))); - dmd=dmd->next; - } - } - } - if (pos!=cbuf) fputs(cbuf, F); - } + if (!fval(r, RF_MALLORN)) { + if (saplings) pos = report_resource(pos, "rm_sapling", f->locale, saplings, -1); + if (trees) pos = report_resource(pos, "rm_trees", f->locale, trees, -1); + } else { + if (saplings) pos = report_resource(pos, "rm_mallornsapling", f->locale, saplings, -1); + if (trees) pos = report_resource(pos, "rm_mallorn", f->locale, trees, -1); + } + fprintf(F, "%d;Bauern\n", rpeasants(r)); + if(fval(r, RF_ORCIFIED)) { + fprintf(F, "1;Verorkt\n"); + } + fprintf(F, "%d;Pferde\n", rhorses(r)); + + if (sr->mode>=see_unit) { + struct demand * dmd = r->land->demands; + struct rawmaterial * res = r->resources; + fprintf(F, "%d;Silber\n", rmoney(r)); + fprintf(F, "%d;Unterh\n", entertainmoney(r)); + + if (is_cursed(r->attribs, C_RIOT, 0)){ + fprintf(F, "0;Rekruten\n"); + } else { + fprintf(F, "%d;Rekruten\n", rpeasants(r) / RECRUITFRACTION); + } + if (production(r)) { + fprintf(F, "%d;Lohn\n", wage(r, f, f->race)); + } + + while (res) { + int maxskill = 0; + int level = -1; + int visible = -1; + const item_type * itype = resource2item(res->type->rtype); + if (res->type->visible==NULL) { + visible = res->amount; + level = res->level + itype->construction->minskill - 1; + } else { + const unit * u; + for (u=r->units; visible!=res->amount && u!=NULL; u=u->next) { + if (u->faction == f) { + int s = eff_skill(u, itype->construction->skill, r); + if (s>maxskill) { + if (s>=itype->construction->minskill) { + assert(itype->construction->minskill>0); + level = res->level + itype->construction->minskill - 1; + } + maxskill = s; + visible = res->type->visible(res, maxskill); + } + } + } + } + if (level>=0 && visible >=0) { + pos = report_resource(pos, res->type->name, f->locale, visible, level); +#ifdef RESOURCECOMPAT + if (visible>=0) fprintf(F, "%d;%s\n", visible, crtag(res->type->name)); +#endif + } + res = res->next; + } + /* trade */ + if (!TradeDisabled() && rpeasants(r)/TRADE_FRACTION > 0) { + fputs("PREISE\n", F); + while (dmd) { + const char * ch = resourcename(dmd->type->itype->rtype, 0); + fprintf(F, "%d;%s\n", (dmd->value + ? dmd->value*dmd->type->price + : -dmd->type->price), + add_translation(ch, locale_string(f->locale, ch))); + dmd=dmd->next; + } + } + } + if (pos!=cbuf) fputs(cbuf, F); + } if (r->land) { print_items(F, r->land->items, f->locale); } - print_curses(F, f, r, TYP_REGION); - cr_borders(ctx->seen, r, f, sd->mode, F); - if (sd->mode==see_unit && rplane(r)==get_astralplane() && !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) - { - /* Sonderbehandlung Teleport-Ebene */ - region_list *rl = astralregions(r, inhabitable); - - if (rl) { - region_list *rl2 = rl; - while(rl2) { - region * r = rl2->data; - fprintf(F, "SCHEMEN %d %d\n", region_x(r, f), region_y(r, f)); - fprintf(F, "\"%s\";Name\n", rname(r, f->locale)); - rl2 = rl2->next; - if(rl2) scat(", "); - } - free_regionlist(rl); - } - } - - /* describe both passed and inhabited regions */ - show_active_spells(r); - if (fval(r, RF_TRAVELUNIT)) { - boolean seeunits = false, seeships = false; - const attrib * ru; - /* show units pulled through region */ - for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) { - unit * u = (unit*)ru->data.v; - if (cansee_durchgezogen(f, r, u, 0) && r!=u->region) { - if (!u->ship || !fval(u, UFL_OWNER)) continue; - if (!seeships) fprintf(F, "DURCHSCHIFFUNG\n"); - seeships = true; - fprintf(F, "\"%s\"\n", shipname(u->ship)); - } - } - for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) { - unit * u = (unit*)ru->data.v; - if (cansee_durchgezogen(f, r, u, 0) && r!=u->region) { - if (u->ship) continue; - if (!seeunits) fprintf(F, "DURCHREISE\n"); - seeunits = true; - fprintf(F, "\"%s\"\n", unitname(u)); - } - } - } - cr_output_messages(F, r->msgs, f); - { - message_list * mlist = r_getmessages(r, f); - if (mlist) cr_output_messages(F, mlist, f); - } - /* buildings */ - for (b = rbuildings(r); b; b = b->next) { - int fno = -1; - u = buildingowner(r, b); - if (u && !fval(u, UFL_PARTEITARNUNG)) { - const faction * sf = visible_faction(f,u); - fno = sf->no; - } - cr_output_buildings(F, b, u, fno, f); - } - - /* ships */ - for (sh = r->ships; sh; sh = sh->next) { - int fno = -1; - u = shipowner(sh); - if (u && !fval(u, UFL_PARTEITARNUNG)) { - const faction * sf = visible_faction(f,u); - fno = sf->no; - } - - cr_output_ship(F, sh, u, fno, f, r); - } - - /* visible units */ - for (u = r->units; u; u = u->next) { - boolean visible = true; - switch (sd->mode) { - case see_unit: - modifier=0; - break; - case see_far: - case see_lighthouse: - modifier = -2; - break; - case see_travel: - modifier = -1; - break; - default: - visible=false; - } - if (u->building || u->ship || (visible && cansee(f, r, u, modifier))) - cr_output_unit(F, r, f, u, sd->mode); - } - } /* region traversal */ - } - report_crtypes(F, f->locale); - write_translations(F); - reset_translations(); + print_curses(F, f, r, TYP_REGION); + cr_borders(ctx->seen, r, f, sr->mode, F); + if (sr->mode==see_unit && rplane(r)==get_astralplane() && !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) + { + /* Sonderbehandlung Teleport-Ebene */ + region_list *rl = astralregions(r, inhabitable); + + if (rl) { + region_list *rl2 = rl; + while(rl2) { + region * r = rl2->data; + fprintf(F, "SCHEMEN %d %d\n", region_x(r, f), region_y(r, f)); + fprintf(F, "\"%s\";Name\n", rname(r, f->locale)); + rl2 = rl2->next; + if(rl2) scat(", "); + } + free_regionlist(rl); + } + } + + /* describe both passed and inhabited regions */ + show_active_spells(r); + if (fval(r, RF_TRAVELUNIT)) { + boolean seeunits = false, seeships = false; + const attrib * ru; + /* show units pulled through region */ + for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) { + unit * u = (unit*)ru->data.v; + if (cansee_durchgezogen(f, r, u, 0) && r!=u->region) { + if (!u->ship || !fval(u, UFL_OWNER)) continue; + if (!seeships) fprintf(F, "DURCHSCHIFFUNG\n"); + seeships = true; + fprintf(F, "\"%s\"\n", shipname(u->ship)); + } + } + for (ru = a_find(r->attribs, &at_travelunit); ru; ru = ru->nexttype) { + unit * u = (unit*)ru->data.v; + if (cansee_durchgezogen(f, r, u, 0) && r!=u->region) { + if (u->ship) continue; + if (!seeunits) fprintf(F, "DURCHREISE\n"); + seeunits = true; + fprintf(F, "\"%s\"\n", unitname(u)); + } + } + } + cr_output_messages(F, r->msgs, f); + { + message_list * mlist = r_getmessages(r, f); + if (mlist) cr_output_messages(F, mlist, f); + } + /* buildings */ + for (b = rbuildings(r); b; b = b->next) { + int fno = -1; + u = buildingowner(r, b); + if (u && !fval(u, UFL_PARTEITARNUNG)) { + const faction * sf = visible_faction(f,u); + fno = sf->no; + } + cr_output_buildings(F, b, u, fno, f); + } + + /* ships */ + for (sh = r->ships; sh; sh = sh->next) { + int fno = -1; + u = shipowner(sh); + if (u && !fval(u, UFL_PARTEITARNUNG)) { + const faction * sf = visible_faction(f,u); + fno = sf->no; + } + + cr_output_ship(F, sh, u, fno, f, r); + } + + /* visible units */ + for (u = r->units; u; u = u->next) { + boolean visible = true; + switch (sr->mode) { + case see_unit: + modifier=0; + break; + case see_far: + case see_lighthouse: + modifier = -2; + break; + case see_travel: + modifier = -1; + break; + default: + visible=false; + } + if (u->building || u->ship || (visible && cansee(f, r, u, modifier))) + cr_output_unit(F, r, f, u, sr->mode); + } + } /* region traversal */ + } + report_crtypes(F, f->locale); + write_translations(F); + reset_translations(); if (errno) { log_error(("%s\n", strerror(errno))); errno = 0; diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index 48c694176..6e0d25267 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -58,11 +58,11 @@ #include <util/event.h> #include <util/goodies.h> #include <util/message.h> +#include <util/rng.h> /* libs includes */ #include <math.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> #include <assert.h> #include <limits.h> @@ -116,7 +116,7 @@ scramble(void *data, int n, size_t width) char temp[64]; assert(width<=sizeof(temp)); for (j=0;j!=n;++j) { - int k = rand() % n; + int k = rng_int() % n; if (k==j) continue; memcpy(temp, (char*)data+j*width, width); memcpy((char*)data+j*width, (char*)data+k*width, width); @@ -325,7 +325,7 @@ do_recruiting(recruitment * recruits, int available) if (want>0) { int get = mintotal; - if (want>mintotal && rest<n && (rand() % n) < rest) { + if (want>mintotal && rest<n && (rng_int() % n) < rest) { --rest; ++get; } @@ -349,7 +349,7 @@ do_recruiting(recruitment * recruits, int available) number = min(req->qty, get / multi); if (rc->recruitcost) { - int afford = get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT) / rc->recruitcost; + int afford = get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, number*rc->recruitcost) / rc->recruitcost; number = min(number, afford); use_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, rc->recruitcost*number); } @@ -494,60 +494,63 @@ recruit(unit * u, struct order * ord, request ** recruitorders) return; } } - - recruitcost = rc->recruitcost; - if (recruitcost) { - pl = getplane(r); - if (pl && fval(pl, PFL_NORECRUITS)) { - ADDMSG(&u->faction->msgs, - msg_feedback(u, ord, "error_pflnorecruit", "")); - return; - } - - if (get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT) < recruitcost) { + + recruitcost = rc->recruitcost; + if (recruitcost) { + pl = getplane(r); + if (pl && fval(pl, PFL_NORECRUITS)) { + ADDMSG(&u->faction->msgs, + msg_feedback(u, ord, "error_pflnorecruit", "")); + return; + } + + if (get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, recruitcost) < recruitcost) { cmistake(u, ord, 142, MSG_EVENT); - return; - } - } - if (!playerrace(u->race) || idle(u->faction)) { - cmistake(u, ord, 139, MSG_EVENT); - return; - } - /* snotlinge sollten hiermit bereits abgefangen werden, die - * parteirasse ist uruk oder ork*/ - if (u->race != rc) { - if (u->number != 0) { - cmistake(u, ord, 139, MSG_EVENT); - return; - } - else u->race = rc; - } - - if (has_skill(u, SK_MAGIC)) { - /* error158;de;{unit} in {region}: '{command}' - Magier arbeiten - * grunds�tzlich nur alleine! */ - cmistake(u, ord, 158, MSG_EVENT); - return; - } - if (has_skill(u, SK_ALCHEMY) - && count_skill(u->faction, SK_ALCHEMY) + n > - max_skill(u->faction, SK_ALCHEMY)) - { - cmistake(u, ord, 156, MSG_EVENT); - return; - } - if (recruitcost) n = min(n, get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT) / recruitcost); - - u->wants = n; - - if (!n) { - cmistake(u, ord, 142, MSG_EVENT); - return; - } - o = (request *) calloc(1, sizeof(request)); - o->qty = n; - o->unit = u; - addlist(recruitorders, o); + return; + } + } + if (!playerrace(u->race) || idle(u->faction)) { + cmistake(u, ord, 139, MSG_EVENT); + return; + } + /* snotlinge sollten hiermit bereits abgefangen werden, die + * parteirasse ist uruk oder ork*/ + if (u->race != rc) { + if (u->number != 0) { + cmistake(u, ord, 139, MSG_EVENT); + return; + } + else u->race = rc; + } + + if (has_skill(u, SK_MAGIC)) { + /* error158;de;{unit} in {region}: '{command}' - Magier arbeiten + * grunds�tzlich nur alleine! */ + cmistake(u, ord, 158, MSG_EVENT); + return; + } + if (has_skill(u, SK_ALCHEMY) + && count_skill(u->faction, SK_ALCHEMY) + n > + max_skill(u->faction, SK_ALCHEMY)) + { + cmistake(u, ord, 156, MSG_EVENT); + return; + } + if (recruitcost>0) { + int pooled = get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, recruitcost * n); + n = min(n, pooled / recruitcost); + } + + u->wants = n; + + if (!n) { + cmistake(u, ord, 142, MSG_EVENT); + return; + } + o = (request *) calloc(1, sizeof(request)); + o->qty = n; + o->unit = u; + addlist(recruitorders, o); } /* ------------------------------------------------------------- */ @@ -871,43 +874,43 @@ maintain(building * b, boolean first) fset(b, BLD_WORKING); return true; } - u = buildingowner(r, b); - if (u==NULL) return false; - for (c=0;b->type->maintenance[c].number;++c) { - const maintenance * m = b->type->maintenance+c; - int need = m->number; - - if (fval(m, MTF_VARIABLE)) need = need * b->size; - if (u) { - /* first ist im ersten versuch true, im zweiten aber false! Das - * bedeutet, das in der Runde in die Region geschafften Resourcen - * nicht genutzt werden k�nnen, weil die reserviert sind! */ - if (!first) need -= get_pooled(u, m->rtype, GET_ALL); - else need -= get_pooled(u, m->rtype, GET_DEFAULT); - if (!first && need > 0) { - unit * ua; - for (ua=r->units;ua;ua=ua->next) freset(ua->faction, FL_DH); - fset(u->faction, FL_DH); /* hat schon */ - for (ua=r->units;ua;ua=ua->next) { - if (!fval(ua->faction, FL_DH) && (ua->faction == u->faction || alliedunit(ua, u->faction, HELP_MONEY))) { - need -= get_pooled(ua, m->rtype, GET_ALL); - fset(ua->faction, FL_DH); - if (need<=0) break; - } - } - } - if (need > 0) { - if (!fval(m, MTF_VITAL)) work = false; - else { - paid = false; - break; - } - } - } - } - if (paid && c>0) { - /* TODO: wieviel von was wurde bezahlt */ - if (first) { + u = buildingowner(r, b); + if (u==NULL) return false; + for (c=0;b->type->maintenance[c].number;++c) { + const maintenance * m = b->type->maintenance+c; + int need = m->number; + + if (fval(m, MTF_VARIABLE)) need = need * b->size; + if (u) { + /* first ist im ersten versuch true, im zweiten aber false! Das + * bedeutet, das in der Runde in die Region geschafften Resourcen + * nicht genutzt werden k�nnen, weil die reserviert sind! */ + if (!first) need -= get_pooled(u, m->rtype, GET_ALL, need); + else need -= get_pooled(u, m->rtype, GET_DEFAULT, need); + if (!first && need > 0) { + unit * ua; + for (ua=r->units;ua;ua=ua->next) freset(ua->faction, FL_DH); + fset(u->faction, FL_DH); /* hat schon */ + for (ua=r->units;ua;ua=ua->next) { + if (!fval(ua->faction, FL_DH) && (ua->faction == u->faction || alliedunit(ua, u->faction, HELP_MONEY))) { + need -= get_pooled(ua, m->rtype, GET_ALL, need); + fset(ua->faction, FL_DH); + if (need<=0) break; + } + } + } + if (need > 0) { + if (!fval(m, MTF_VITAL)) work = false; + else { + paid = false; + break; + } + } + } + } + if (paid && c>0) { + /* TODO: wieviel von was wurde bezahlt */ + if (first) { ADDMSG(&u->faction->msgs, msg_message("maintenance", "unit building", u, b)); } else { ADDMSG(&u->faction->msgs, msg_message("maintenance_late", "building", b)); @@ -968,7 +971,7 @@ gebaeude_stuerzt_ein(region * r, building * b) leave(r,u); n = u->number; for (i = 0; i < n; i++) { - if (rand() % 100 >= EINSTURZUEBERLEBEN) { + if (rng_int() % 100 >= EINSTURZUEBERLEBEN) { ++loss; } } @@ -1002,7 +1005,7 @@ maintain_buildings(boolean crash) /* the second time, send a message */ if (crash) { - if (!maintained && (rand() % 100 < EINSTURZCHANCE)) { + if (!maintained && (rng_int() % 100 < EINSTURZCHANCE)) { gebaeude_stuerzt_ein(r, b); continue; } else if (!fval(b, BLD_WORKING)) { @@ -1409,7 +1412,7 @@ leveled_allocation(const resource_type * rtype, region * r, allocation * alist) int want = required(al->want-al->get, al->save); int x = avail*want/norders; /* Wenn Rest, dann w�rfeln, ob ich was bekomme: */ - if (rand() % norders < (avail*want) % norders) + if (rng_int() % norders < (avail*want) % norders) ++x; avail -= x; use += x; @@ -1453,7 +1456,7 @@ attrib_allocation(const resource_type * rtype, region * r, allocation * alist) int want = required(al->want, al->save); int x = avail*want/norders; /* Wenn Rest, dann w�rfeln, ob ich was bekomme: */ - if (rand() % norders < (avail*want) % norders) + if (rng_int() % norders < (avail*want) % norders) ++x; avail -= x; norders -= want; @@ -1757,32 +1760,32 @@ expandbuying(region * r, request * buyorders) max_products = rpeasants(r) / TRADE_FRACTION; - /* Kauf - auch so programmiert, da� er leicht erweiterbar auf mehrere - * G�ter pro Monat ist. j sind die Befehle, i der Index des - * gehandelten Produktes. */ + /* Kauf - auch so programmiert, da� er leicht erweiterbar auf mehrere + * G�ter pro Monat ist. j sind die Befehle, i der Index des + * gehandelten Produktes. */ if (max_products>0) { - expandorders(r, buyorders); - if (!norders) return; - - for (j = 0; j != norders; j++) { - int price, multi; - ltype = oa[j].type.ltype; - trade = trades; - while (trade->type!=ltype) ++trade; - multi = trade->multi; - if (trade->number + 1 > max_products) ++multi; - price = ltype->price * multi; - - if (get_pooled(oa[j].unit, oldresourcetype[R_SILVER], GET_DEFAULT) >= price) { - unit * u = oa[j].unit; - - /* litems z�hlt die G�ter, die verkauft wurden, u->n das Geld, das - * verdient wurde. Dies mu� gemacht werden, weil der Preis st�ndig sinkt, - * man sich also das verdiente Geld und die verkauften Produkte separat - * merken mu�. */ - attrib * a = a_find(u->attribs, &at_luxuries); - if (a==NULL) a = a_add(&u->attribs, a_new(&at_luxuries)); - i_change((item**)&a->data.v, ltype->itype, 1); + expandorders(r, buyorders); + if (!norders) return; + + for (j = 0; j != norders; j++) { + int price, multi; + ltype = oa[j].type.ltype; + trade = trades; + while (trade->type!=ltype) ++trade; + multi = trade->multi; + if (trade->number + 1 > max_products) ++multi; + price = ltype->price * multi; + + if (get_pooled(oa[j].unit, oldresourcetype[R_SILVER], GET_DEFAULT, price) >= price) { + unit * u = oa[j].unit; + + /* litems z�hlt die G�ter, die verkauft wurden, u->n das Geld, das + * verdient wurde. Dies mu� gemacht werden, weil der Preis st�ndig sinkt, + * man sich also das verdiente Geld und die verkauften Produkte separat + * merken mu�. */ + attrib * a = a_find(u->attribs, &at_luxuries); + if (a==NULL) a = a_add(&u->attribs, a_new(&at_luxuries)); + i_change((item**)&a->data.v, ltype->itype, 1); i_change(&oa[j].unit->items, ltype->itype, 1); use_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, price); if (u->n < 0) @@ -2113,13 +2116,13 @@ static boolean sell(unit * u, request ** sellorders, struct order * ord) { boolean unlimited = true; - const item_type * itype; - const luxury_type * ltype=NULL; - int n; + const item_type * itype; + const luxury_type * ltype=NULL; + int n; region * r = u->region; - const char *s; - - if (u->ship && is_guarded(r, u, GUARD_CREWS)) { + const char *s; + + if (u->ship && is_guarded(r, u, GUARD_CREWS)) { cmistake(u, ord, 69, MSG_INCOME); return false; } @@ -2165,13 +2168,13 @@ sell(unit * u, request ** sellorders, struct order * ord) building * b; static const struct building_type * bt_castle; if (!bt_castle) bt_castle = bt_find("castle"); - for (b=r->buildings;b;b=b->next) { - if (b->type==bt_castle && b->size>=2) break; + for (b=r->buildings;b;b=b->next) { + if (b->type==bt_castle && b->size>=2) break; } - if (b==NULL) { - cmistake(u, ord, 119, MSG_COMMERCE); - return false; - } + if (b==NULL) { + cmistake(u, ord, 119, MSG_COMMERCE); + return false; + } } /* Ein H�ndler kann nur 10 G�ter pro Talentpunkt verkaufen. */ @@ -2189,27 +2192,27 @@ sell(unit * u, request ** sellorders, struct order * ord) cmistake(u, ord, 126, MSG_COMMERCE); return false; } - else { - attrib * a; + else { + attrib * a; request *o; - int k, available; + int k, available; + + if (!r_demand(r, ltype)) { + cmistake(u, ord, 263, MSG_COMMERCE); + return false; + } + available = get_pooled(u, itype->rtype, GET_DEFAULT, INT_MAX); - if (!r_demand(r, ltype)) { - cmistake(u, ord, 263, MSG_COMMERCE); - return false; - } - available = get_pooled(u, itype->rtype, GET_DEFAULT); - - /* Wenn andere Einheiten das selbe verkaufen, mu� ihr Zeug abgezogen - * werden damit es nicht zweimal verkauft wird: */ - for (o=*sellorders;o;o=o->next) { - if (o->type.ltype==ltype && o->unit->faction == u->faction) { - int fpool = o->qty - get_pooled(o->unit, itype->rtype, GET_RESERVE); - available -= max(0, fpool); - } - } - - n = min(n, available); + /* Wenn andere Einheiten das selbe verkaufen, mu� ihr Zeug abgezogen + * werden damit es nicht zweimal verkauft wird: */ + for (o=*sellorders;o;o=o->next) { + if (o->type.ltype==ltype && o->unit->faction == u->faction) { + int fpool = o->qty - get_pooled(o->unit, itype->rtype, GET_RESERVE, INT_MAX); + available -= max(0, fpool); + } + } + + n = min(n, available); if (n <= 0) { cmistake(u, ord, 264, MSG_COMMERCE); @@ -2262,212 +2265,212 @@ expandstealing(region * r, request * stealorders) * u ist die beklaute unit. oa.unit ist die klauende unit. */ - for (i = 0; i != norders && oa[i].unit->n <= oa[i].unit->wants; i++) { - unit *u = findunitg(oa[i].no, r); - int n = 0; - if (u && u->region==r) n = get_pooled(u, r_silver, GET_ALL); + for (i = 0; i != norders && oa[i].unit->n <= oa[i].unit->wants; i++) { + unit *u = findunitg(oa[i].no, r); + int n = 0; + if (u && u->region==r) { + n = get_pooled(u, r_silver, GET_ALL, INT_MAX); + } #ifndef GOBLINKILL - if (oa[i].type.goblin) { /* Goblin-Spezialklau */ - int uct = 0; - unit *u2; - assert(effskill(oa[i].unit, SK_STEALTH)>=4 || !"this goblin\'s talent is too low"); + if (oa[i].type.goblin) { /* Goblin-Spezialklau */ + int uct = 0; + unit *u2; + assert(effskill(oa[i].unit, SK_STEALTH)>=4 || !"this goblin\'s talent is too low"); for (u2 = r->units; u2; u2 = u2->next) { if (u2->faction == u->faction) { uct += maintenance_cost(u2); } } - n -= uct * 2; - } + n -= uct * 2; + } #endif - if (n>10 && rplane(r) && (rplane(r)->flags & PFL_NOALLIANCES)) { - /* In Questen nur reduziertes Klauen */ - n = 10; - } - if (n > 0) { - n = min(n, oa[i].unit->wants); - use_pooled(u, r_silver, GET_ALL, n); - oa[i].unit->n = n; - change_money(oa[i].unit, n); - ADDMSG(&u->faction->msgs, msg_message("stealeffect", "unit region amount", u, u->region, n)); - } - add_income(oa[i].unit, IC_STEAL, oa[i].unit->wants, oa[i].unit->n); + if (n>10 && rplane(r) && (rplane(r)->flags & PFL_NOALLIANCES)) { + /* In Questen nur reduziertes Klauen */ + n = 10; + } + if (n > 0) { + n = min(n, oa[i].unit->wants); + use_pooled(u, r_silver, GET_ALL, n); + oa[i].unit->n = n; + change_money(oa[i].unit, n); + ADDMSG(&u->faction->msgs, msg_message("stealeffect", "unit region amount", u, u->region, n)); + } + add_income(oa[i].unit, IC_STEAL, oa[i].unit->wants, oa[i].unit->n); fset(oa[i].unit, UFL_LONGACTION); - } - free(oa); + } + free(oa); } /* ------------------------------------------------------------- */ static void plant(region *r, unit *u, int raw) { - int n, i, skill, planted = 0; + int n, i, skill, planted = 0; const item_type * itype; static const resource_type * rt_water = NULL; if (rt_water==NULL) rt_water = rt_find("p2"); - + assert(rt_water!=NULL); - if (!fval(r->terrain, LAND_REGION)) { - return; - } - if (rherbtype(r) == NULL) { - cmistake(u, u->thisorder, 108, MSG_PRODUCE); - return; - } - - /* Skill pr�fen */ - skill = eff_skill(u, SK_HERBALISM, r); - itype = rherbtype(r); - if (skill < 6) { - ADDMSG(&u->faction->msgs, - msg_feedback(u, u->thisorder, "plant_skills", + if (!fval(r->terrain, LAND_REGION)) { + return; + } + if (rherbtype(r) == NULL) { + cmistake(u, u->thisorder, 108, MSG_PRODUCE); + return; + } + + /* Skill pr�fen */ + skill = eff_skill(u, SK_HERBALISM, r); + itype = rherbtype(r); + if (skill < 6) { + ADDMSG(&u->faction->msgs, + msg_feedback(u, u->thisorder, "plant_skills", "skill minskill product", SK_HERBALISM, 6, itype->rtype, 1)); - return; - } - /* Wasser des Lebens pr�fen */ - if (get_pooled(u, rt_water, GET_DEFAULT) == 0) { - ADDMSG(&u->faction->msgs, - msg_feedback(u, u->thisorder, "resource_missing", "missing", rt_water)); - return; - } - n = get_pooled(u, itype->rtype, GET_DEFAULT); - /* Kr�uter pr�fen */ - if (n==0) { - ADDMSG(&u->faction->msgs, - msg_feedback(u, u->thisorder, "resource_missing", "missing", + return; + } + /* Wasser des Lebens pr�fen */ + if (get_pooled(u, rt_water, GET_DEFAULT, 1) == 0) { + ADDMSG(&u->faction->msgs, + msg_feedback(u, u->thisorder, "resource_missing", "missing", rt_water)); + return; + } + n = get_pooled(u, itype->rtype, GET_DEFAULT, skill*u->number); + /* Kr�uter pr�fen */ + if (n==0) { + ADDMSG(&u->faction->msgs, + msg_feedback(u, u->thisorder, "resource_missing", "missing", itype->rtype)); - return; - } + return; + } - n = min(skill*u->number, n); - n = min(raw, n); - /* F�r jedes Kraut Talent*10% Erfolgschance. */ - for(i = n; i>0; i--) { - if (rand()%10 < skill) planted++; - } - produceexp(u, SK_HERBALISM, u->number); - - /* Alles ok. Abziehen. */ - use_pooled(u, rt_water, GET_DEFAULT, 1); - use_pooled(u, itype->rtype, GET_DEFAULT, n); - rsetherbs(r, rherbs(r)+planted); - ADDMSG(&u->faction->msgs, msg_message("plant", "unit region amount herb", - u, r, planted, itype->rtype)); + n = min(skill*u->number, n); + n = min(raw, n); + /* F�r jedes Kraut Talent*10% Erfolgschance. */ + for(i = n; i>0; i--) { + if (rng_int()%10 < skill) planted++; + } + produceexp(u, SK_HERBALISM, u->number); + + /* Alles ok. Abziehen. */ + use_pooled(u, rt_water, GET_DEFAULT, 1); + use_pooled(u, itype->rtype, GET_DEFAULT, n); + rsetherbs(r, rherbs(r)+planted); + ADDMSG(&u->faction->msgs, msg_message("plant", "unit region amount herb", + u, r, planted, itype->rtype)); } static void planttrees(region *r, unit *u, int raw) { - int n, i, skill, planted = 0; - const resource_type * rtype; - - if (!fval(r->terrain, LAND_REGION)) { - return; - } - - /* Mallornb�ume kann man nur in Mallornregionen z�chten */ - if (fval(r, RF_MALLORN)) { - rtype = rt_mallornseed; - } else { - rtype = rt_seed; - } - - /* Skill pr�fen */ - skill = eff_skill(u, SK_HERBALISM, r); - if (skill < 6) { - ADDMSG(&u->faction->msgs, - msg_feedback(u, u->thisorder, "plant_skills", + int n, i, skill, planted = 0; + const resource_type * rtype; + + if (!fval(r->terrain, LAND_REGION)) { + return; + } + + /* Mallornb�ume kann man nur in Mallornregionen z�chten */ + if (fval(r, RF_MALLORN)) { + rtype = rt_mallornseed; + } else { + rtype = rt_seed; + } + + /* Skill pr�fen */ + skill = eff_skill(u, SK_HERBALISM, r); + if (skill < 6) { + ADDMSG(&u->faction->msgs, + msg_feedback(u, u->thisorder, "plant_skills", "skill minskill product", SK_HERBALISM, 6, rtype, 1)); - return; - } - if (fval(r, RF_MALLORN) && skill < 7 ) { - ADDMSG(&u->faction->msgs, - msg_feedback(u, u->thisorder, "plant_skills", + return; + } + if (fval(r, RF_MALLORN) && skill < 7 ) { + ADDMSG(&u->faction->msgs, + msg_feedback(u, u->thisorder, "plant_skills", "skill minskill product", SK_HERBALISM, 7, rtype, 1)); - return; - } - - n = get_pooled(u, rtype, GET_DEFAULT); - /* Samen pr�fen */ - if (n==0) { - ADDMSG(&u->faction->msgs, - msg_feedback(u, u->thisorder, "resource_missing", "missing", rtype)); - return; - } - - /* wenn eine Anzahl angegeben wurde, nur soviel verbrauchen */ - n = min(raw, n); - n = min(skill*u->number, n); - - /* F�r jeden Samen Talent*10% Erfolgschance. */ - for(i = n; i>0; i--) { - if (rand()%10 < skill) planted++; - } - rsettrees(r, 0, rtrees(r, 0)+planted); - - /* Alles ok. Abziehen. */ - produceexp(u, SK_HERBALISM, u->number); - use_pooled(u, rtype, GET_DEFAULT, n); - - ADDMSG(&u->faction->msgs, msg_message("plant", - "unit region amount herb", u, r, planted, rtype)); + return; + } + + /* wenn eine Anzahl angegeben wurde, nur soviel verbrauchen */ + raw = min(raw, skill*u->number); + n = get_pooled(u, rtype, GET_DEFAULT, raw); + if (n==0) { + ADDMSG(&u->faction->msgs, + msg_feedback(u, u->thisorder, "resource_missing", "missing", rtype)); + return; + } + n = min(raw, n); + + /* F�r jeden Samen Talent*10% Erfolgschance. */ + for(i = n; i>0; i--) { + if (rng_int()%10 < skill) planted++; + } + rsettrees(r, 0, rtrees(r, 0)+planted); + + /* Alles ok. Abziehen. */ + produceexp(u, SK_HERBALISM, u->number); + use_pooled(u, rtype, GET_DEFAULT, n); + + ADDMSG(&u->faction->msgs, msg_message("plant", + "unit region amount herb", u, r, planted, rtype)); } /* z�chte b�ume */ static void breedtrees(region *r, unit *u, int raw) { - int n, i, skill, planted = 0; - const resource_type * rtype; - static int current_season = -1; + int n, i, skill, planted = 0; + const resource_type * rtype; + static int current_season = -1; if (current_season<0) current_season = get_gamedate(turn, NULL)->season; - - /* B�ume z�chten geht nur im Fr�hling */ - if (current_season != SEASON_SPRING){ - planttrees(r, u, raw); - return; - } - - if (!fval(r->terrain, LAND_REGION)) { - return; - } - - /* Mallornb�ume kann man nur in Mallornregionen z�chten */ - if (fval(r, RF_MALLORN)) { - rtype = rt_mallornseed; - } else { - rtype = rt_seed; - } - - /* Skill pr�fen */ - skill = eff_skill(u, SK_HERBALISM, r); - if (skill < 12) { - planttrees(r, u, raw); - return; - } - n = get_pooled(u, rtype, GET_DEFAULT); - /* Samen pr�fen */ - if (n==0) { - ADDMSG(&u->faction->msgs, - msg_feedback(u, u->thisorder, "resource_missing", "missing", rtype)); - return; - } - - /* wenn eine Anzahl angegeben wurde, nur soviel verbrauchen */ - n = min(raw, n); - n = min(skill*u->number, n); - - /* F�r jeden Samen Talent*5% Erfolgschance. */ - for(i = n; i>0; i--) { - if (rand()%100 < skill*5) planted++; - } - rsettrees(r, 1, rtrees(r, 1)+planted); - - /* Alles ok. Abziehen. */ - produceexp(u, SK_HERBALISM, u->number); - use_pooled(u, rtype, GET_DEFAULT, n); - - ADDMSG(&u->faction->msgs, msg_message("plant", + + /* B�ume z�chten geht nur im Fr�hling */ + if (current_season != SEASON_SPRING){ + planttrees(r, u, raw); + return; + } + + if (!fval(r->terrain, LAND_REGION)) { + return; + } + + /* Mallornb�ume kann man nur in Mallornregionen z�chten */ + if (fval(r, RF_MALLORN)) { + rtype = rt_mallornseed; + } else { + rtype = rt_seed; + } + + /* Skill pr�fen */ + skill = eff_skill(u, SK_HERBALISM, r); + if (skill < 12) { + planttrees(r, u, raw); + return; + } + + /* wenn eine Anzahl angegeben wurde, nur soviel verbrauchen */ + raw = min(skill*u->number, raw); + n = get_pooled(u, rtype, GET_DEFAULT, raw); + /* Samen pr�fen */ + if (n==0) { + ADDMSG(&u->faction->msgs, + msg_feedback(u, u->thisorder, "resource_missing", "missing", rtype)); + return; + } + n = min(raw, n); + + /* F�r jeden Samen Talent*5% Erfolgschance. */ + for(i = n; i>0; i--) { + if (rng_int()%100 < skill*5) planted++; + } + rsettrees(r, 1, rtrees(r, 1)+planted); + + /* Alles ok. Abziehen. */ + produceexp(u, SK_HERBALISM, u->number); + use_pooled(u, rtype, GET_DEFAULT, n); + + ADDMSG(&u->faction->msgs, msg_message("plant", "unit region amount herb", u, r, planted, rtype)); } @@ -2475,11 +2478,11 @@ static void plant_cmd(unit *u, struct order * ord) { region * r = u->region; - int m; - const char *s; - param_t p; - const resource_type * rtype = NULL; - + int m; + const char *s; + param_t p; + const resource_type * rtype = NULL; + if (r->land==NULL) { /* TODO: error message here */ return; @@ -2488,40 +2491,39 @@ plant_cmd(unit *u, struct order * ord) /* pflanze [<anzahl>] <parameter> */ init_tokens(ord); skip_token(); - s = getstrtoken(); - m = atoi(s); - sprintf(buf, "%d", m); - if (!strcmp(buf, s)) { - /* first came a want-paramter */ - s = getstrtoken(); - } else { - m = INT_MAX; - } - - if (!s[0]) { - p = P_ANY; - } else { - p = findparam(s, u->faction->locale); - rtype = findresourcetype(s, u->faction->locale); - } - - if (p==P_HERBS){ - plant(r, u, m); - return; - } - else if (p==P_TREES){ - breedtrees(r, u, m); - return; - } - else if (rtype!=NULL){ - if (rtype==rt_mallornseed || rtype==rt_seed) { - breedtrees(r, u, m); - return; - } - } + s = getstrtoken(); + m = atoi(s); + sprintf(buf, "%d", m); + if (!strcmp(buf, s)) { + /* first came a want-paramter */ + s = getstrtoken(); + } else { + m = INT_MAX; + } + + if (!s[0]) { + p = P_ANY; + } else { + p = findparam(s, u->faction->locale); + rtype = findresourcetype(s, u->faction->locale); + } + + if (p==P_HERBS){ + plant(r, u, m); + return; + } + else if (p==P_TREES){ + breedtrees(r, u, m); + return; + } + else if (rtype!=NULL){ + if (rtype==rt_mallornseed || rtype==rt_seed) { + breedtrees(r, u, m); + return; + } + } } - /* z�chte pferde */ static void breedhorses(region *r, unit *u) @@ -2542,7 +2544,7 @@ breedhorses(region *r, unit *u) n = min(u->number * eff_skill(u, SK_HORSE_TRAINING, r), get_item(u, I_HORSE)); for (c = 0; c < n; c++) { - if (rand() % 100 < eff_skill(u, SK_HORSE_TRAINING, r)) { + if (rng_int() % 100 < eff_skill(u, SK_HORSE_TRAINING, r)) { i_change(&u->items, olditemtype[I_HORSE], 1); gezuechtet++; } @@ -2882,7 +2884,7 @@ expandwork(region * r) if (m>=working) workers = u->number; else { workers = u->number * m / working; - if (rand() % working < (u->number * m) % working) workers++; + if (rng_int() % working < (u->number * m) % working) workers++; } assert(workers>=0); diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 78ebed40c..b244ac2d6 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -77,8 +77,10 @@ #include <util/goodies.h> #include <util/log.h> #include <util/rand.h> +#include <util/rng.h> #include <util/sql.h> #include <util/message.h> +#include <util/rng.h> #include <modules/xecmd.h> @@ -91,7 +93,6 @@ #include <stdio.h> #include <math.h> #include <time.h> -#include <stdlib.h> #include <string.h> #include <assert.h> #include <ctype.h> @@ -99,6 +100,21 @@ #include <attributes/otherfaction.h> +/* chance that a peasant dies of starvation: */ +#define PEASANT_STARVATION_CHANCE 0.9F +/* Pferdevermehrung */ +#define HORSEGROWTH 4 +/* Wanderungschance pro Pferd */ +#define HORSEMOVE 3 +/* Vermehrungschance pro Baum */ +#define FORESTGROWTH 10000 /* In Millionstel */ + +/** Ausbreitung und Vermehrung */ +#define MAXDEMAND 25 +#define DMRISE 0.1F /* weekly chance that demand goes up */ +#define DMRISEHAFEN 0.2F /* weekly chance that demand goes up with harbor */ + + /* - external symbols ------------------------------------------ */ extern int dropouts[2]; extern int * age; @@ -526,38 +542,43 @@ calculate_emigration(region *r) static void peasants(region * r) { - int glueck = 0; int peasants = rpeasants(r); int money = rmoney(r); int maxp = production(r) * MAXPEASANTS_PER_AREA; int n, satiated; int dead = 0; - attrib * a = a_find(r->attribs, &at_peasantluck); /* Bis zu 1000 Bauern k�nnen Zwillinge bekommen oder 1000 Bauern * wollen nicht! */ - if (a!=NULL) { - glueck = a->data.i * 1000; - } + if (peasants>0) { + int glueck = 0; + int births = (int)(0.5F + peasants * 0.0001F * PEASANTGROWTH); + attrib * a = a_find(r->attribs, &at_peasantluck); - for (n = peasants; n; n--) { - int chances = 1; - - if (glueck>0) { - --glueck; - chances += PEASANTLUCK; + if (a!=NULL) { + glueck = a->data.i * 1000; } - while (chances--) { - if (rand() % 10000 < PEASANTGROWTH) { - /* First chance always goes through. Next ones only with 75% chance if - * peasants have reached 90% of maxpopulation */ - if (chances==0 || peasants/(float)maxp < 0.9 || chance(PEASANTFORCE)) { - ++peasants; + for (n = peasants; n; --n) { + int chances = 0; + + if (glueck>0) { + --glueck; + chances += PEASANTLUCK; + } + + while (chances--) { + if (rng_int() % 10000 < PEASANTGROWTH) { + /* Only raise with 75% chance if peasants have + * reached 90% of maxpopulation */ + if (peasants/(float)maxp < 0.9 || chance(PEASANTFORCE)) { + ++births; + } } } } + peasants += births; } /* Alle werden satt, oder halt soviele f�r die es auch Geld gibt */ @@ -571,9 +592,8 @@ peasants(region * r) /* Es verhungert maximal die unterern�hrten Bev�lkerung. */ - for (n = min((peasants - satiated), rpeasants(r)); n; n--) { - if (rand() % 100 > STARVATION_SURVIVAL) ++dead; - } + n = min(peasants - satiated, rpeasants(r)); + dead += (int)(n * PEASANT_STARVATION_CHANCE); if (dead > 0) { message * msg = add_message(&r->msgs, msg_message("phunger", "dead", dead)); @@ -656,19 +676,21 @@ horses(region * r) maxhorses = maxworkingpeasants(r)/10; maxhorses = max(0, maxhorses); horses = rhorses(r); - if(is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) { - rsethorses(r, (int)(horses*0.9)); - } else if (maxhorses > 0) { - int i; - int growth = (int)((RESOURCE_QUANTITY * HORSEGROWTH * 200 * (maxhorses-horses))/maxhorses); + if (horses > 0) { + if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) { + rsethorses(r, (int)(horses*0.9F)); + } else if (maxhorses) { + int i; + double growth = (RESOURCE_QUANTITY * HORSEGROWTH * 200 * (maxhorses-horses))/maxhorses; - if(a_find(r->attribs, &at_horseluck)) growth *= 2; - /* printf("Horses: <%d> %d -> ", growth, horses); */ - for(i = 0; i < horses; i++) { - if(rand()%10000 < growth) horses++; + if (growth>0) { + if (a_find(r->attribs, &at_horseluck)) growth *= 2; + /* printf("Horses: <%d> %d -> ", growth, horses); */ + i = (int)(0.5F + (horses * 0.0001F) * growth); + /* printf("%d\n", horses); */ + rsethorses(r, horses + i); + } } - /* printf("%d\n", horses); */ - rsethorses(r, horses); } /* Pferde wandern in Nachbarregionen. @@ -743,7 +765,7 @@ trees(region * r, const int current_season, const int last_weeks_season) return; } - if(production(r) <= 0) return; + if (production(r) <= 0) return; /* Grundchance 1.0% */ seedchance = (int)(FORESTGROWTH * RESOURCE_QUANTITY); @@ -752,8 +774,8 @@ trees(region * r, const int current_season, const int last_weeks_season) grownup_trees = rtrees(r, 2); seeds = 0; - for(i=0;i<grownup_trees;i++) { - if(rand()%1000000 < seedchance) seeds++; + if (grownup_trees>0) { + seeds += (int)(seedchance*0.000001F*grownup_trees); } rsettrees(r, 0, rtrees(r, 0) + seeds); @@ -773,7 +795,7 @@ trees(region * r, const int current_season, const int last_weeks_season) sprout = 0; seedchance = (1000 * maxworkingpeasants(r2)) / r2->terrain->size; for(i=0; i<seeds/MAXDIRECTIONS; i++) { - if(rand()%10000 < seedchance) sprout++; + if(rng_int()%10000 < seedchance) sprout++; } rsettrees(r2, 0, rtrees(r2, 0) + sprout); } @@ -804,7 +826,7 @@ trees(region * r, const int current_season, const int last_weeks_season) sprout = 0; for(i=0;i<seeds;i++) { - if(rand()%10000 < growth) sprout++; + if(rng_int()%10000 < growth) sprout++; } /* aus dem Samenpool dieses Jahres abziehen */ a->data.sa[0] = (short)(seeds - sprout); @@ -823,7 +845,7 @@ trees(region * r, const int current_season, const int last_weeks_season) grownup_trees = 0; for(i=0;i<sprout;i++) { - if(rand()%10000 < growth) grownup_trees++; + if(rng_int()%10000 < growth) grownup_trees++; } /* aus dem Spr��lingepool dieses Jahres abziehen */ a->data.sa[1] = (short)(sprout - grownup_trees); @@ -841,7 +863,7 @@ trees(region * r, const int current_season, const int last_weeks_season) || current_season == SEASON_AUTUMN) { for(i = rherbs(r); i > 0; i--) { - if (rand()%100 < (100-rherbs(r))) rsetherbs(r, (short)(rherbs(r)+1)); + if (rng_int()%100 < (100-rherbs(r))) rsetherbs(r, (short)(rherbs(r)+1)); } } } @@ -868,9 +890,9 @@ demographics(void) struct demand * dmd; if (r->land) for (dmd=r->land->demands;dmd;dmd=dmd->next) { if (dmd->value>0 && dmd->value < MAXDEMAND) { - int rise = DMRISE; + float rise = DMRISE; if (buildingtype_exists(r, bt_find("harbour"))) rise = DMRISEHAFEN; - if (rand() % 100 < rise) dmd->value++; + if (rng_double()<rise) ++dmd->value; } } /* Seuchen erst nachdem die Bauern sich vermehrt haben @@ -921,7 +943,7 @@ modify(int i) c = i * 2 / 3; if (c >= 1) { - return (c + rand() % c); + return (c + rng_int() % c); } else { return (i); } @@ -1118,7 +1140,7 @@ parse_restart(void) } if (fval(f, FFL_OVERRIDE)) { free(f->override); - f->override = strdup(itoa36(rand())); + f->override = strdup(itoa36(rng_int())); freset(f, FFL_OVERRIDE); } if (turn!=f->lastorders) { @@ -2075,7 +2097,7 @@ password_cmd(unit * u, struct order * ord) s = getstrtoken(); if (!s || !*s) { - for(i=0; i<6; i++) pbuf[i] = (char)(97 + rand() % 26); + for(i=0; i<6; i++) pbuf[i] = (char)(97 + rng_int() % 26); pbuf[6] = 0; } else { boolean pwok = true; @@ -2090,7 +2112,7 @@ password_cmd(unit * u, struct order * ord) } if (pwok == false) { cmistake(u, ord, 283, MSG_EVENT); - for(i=0; i<6; i++) pbuf[i] = (char)(97 + rand() % 26); + for(i=0; i<6; i++) pbuf[i] = (char)(97 + rng_int() % 26); pbuf[6] = 0; } } @@ -2485,8 +2507,8 @@ promotion_cmd(unit * u, struct order * ord) u->race)); return 0; } - money = get_pooled(u, i_silver->rtype, GET_ALL); people = count_all(u->faction) * u->number; + money = get_pooled(u, i_silver->rtype, GET_ALL, people); if (people>money) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "heroes_cost", "cost have", @@ -3589,7 +3611,7 @@ use_item(unit * u, const item_type * itype, int amount, struct order * ord) int i; int target = read_unitid(u->faction, u->region); - i = get_pooled(u, itype->rtype, GET_DEFAULT); + i = get_pooled(u, itype->rtype, GET_DEFAULT, amount); if (amount>i) { amount = i; @@ -3921,8 +3943,8 @@ processorders (void) puts(" - Attackieren"); if (nobattle == false) do_battle(); - if (turn == 0) srand((int)time(0)); - else srand(turn); + if (turn == 0) rng_init((int)time(0)); + else rng_init(turn); puts(" - Belagern"); do_siege(); @@ -3936,8 +3958,8 @@ processorders (void) puts(" - Folge auf Einheiten ersetzen"); follow_unit(); - if (turn == 0) srand((int)time(0)); - else srand(turn); + if (turn == 0) rng_init((int)time(0)); + else rng_init(turn); puts(" - Zerst�ren, Geben, Rekrutieren, Vergessen"); economics(); @@ -3980,8 +4002,8 @@ processorders (void) puts(" - Zufallsbegegnungen"); encounters(); - if (turn == 0) srand((int)time(0)); - else srand(turn); + if (turn == 0) rng_init((int)time(0)); + else rng_init(turn); puts(" - Monster fressen und vertreiben Bauern"); monsters_kill_peasants(); diff --git a/src/common/gamecode/luck.c b/src/common/gamecode/luck.c index fb15fbf78..53a0cfb4f 100644 --- a/src/common/gamecode/luck.c +++ b/src/common/gamecode/luck.c @@ -43,7 +43,8 @@ #include <karma.h> /* util includes */ -#include <rand.h> +#include <util/rand.h> +#include <util/rng.h> #include <util/message.h> /* libc includes */ @@ -51,7 +52,6 @@ #include <string.h> #include <assert.h> #include <math.h> -#include <stdlib.h> #ifdef KARMA_MODULE @@ -64,7 +64,7 @@ lucky_silver(const unit *u) int luck = fspecial(u->faction, FS_LUCKY); do { - r = 1 + rand()%(10000*(luck+STANDARD_LUCK)); + r = 1 + rng_int()%(10000*(luck+STANDARD_LUCK)); if(r > max) max = r; i++; } while(i <= luck); @@ -101,10 +101,10 @@ lucky_item(const unit *u) } } /* weight is unused */ - r = rand()%nitems; + r = rng_int()%nitems; do { - r = rand()%nitems; + r = rng_int()%nitems; if(r > max) max = r; i++; } while(i <= luck); @@ -112,9 +112,9 @@ lucky_item(const unit *u) itype = it_find(it_list[r].name); if(luck) - amount = 10 + rand()%(luck*40) + rand()%(luck*40); + amount = 10 + rng_int()%(luck*40) + rng_int()%(luck*40); else - amount = 5 + rand()%10 +rand()%10; + amount = 5 + rng_int()%10 +rng_int()%10; i_change(&((unit *)u)->items, itype, amount); ADDMSG(&u->faction->msgs, msg_message("lucky_item", @@ -144,8 +144,8 @@ lucky_magic_item(const unit *u) olditemtype[I_SACK_OF_CONSERVATION], }; - itype = it_list[rand()%n_items]; - amount = 1 + rand()%luck; + itype = it_list[rng_int()%n_items]; + amount = 1 + rng_int()%luck; i_change(&((unit *)u)->items, itype, amount); ADDMSG(&u->faction->msgs, msg_message("lucky_item", @@ -161,7 +161,7 @@ lucky_event(const faction *f) if(!u) return; - switch(rand()%3) { + switch(rng_int()%3) { case 0: lucky_silver(u); break; @@ -180,7 +180,7 @@ check_luck(void) faction *f; for(f=factions; f; f=f->next) { - if(rand()%100 < STANDARD_LUCK+fspecial(f, FS_LUCKY)*8) + if(rng_int()%100 < STANDARD_LUCK+fspecial(f, FS_LUCKY)*8) lucky_event(f); } } diff --git a/src/common/gamecode/monster.c b/src/common/gamecode/monster.c index bf06d75a2..eb1866e82 100644 --- a/src/common/gamecode/monster.c +++ b/src/common/gamecode/monster.c @@ -57,14 +57,14 @@ #include <kernel/unit.h> /* util includes */ -#include <attrib.h> -#include <base36.h> -#include <event.h> -#include <rand.h> +#include <util/attrib.h> +#include <util/base36.h> +#include <util/event.h> +#include <util/rand.h> +#include <util/rng.h> /* libc includes */ #include <stdio.h> -#include <stdlib.h> #include <string.h> #include <assert.h> @@ -283,7 +283,7 @@ random_neighbour(region * r, unit *u) /* Zuf�llig eine ausw�hlen */ - rr = rand() % c; + rr = rng_int() % c; /* Durchz�hlen */ @@ -327,7 +327,7 @@ treeman_neighbour(region * r) } /* Zuf�llig eine ausw�hlen */ - rr = rand() % c; + rr = rng_int() % c; /* Durchz�hlen */ @@ -382,7 +382,7 @@ monster_move(region * r, unit * u) /* Wir machen das mal autoconf-style: */ #ifndef HAVE_DRAND48 -#define drand48() (((double)rand()) / RAND_MAX) +#define drand48() (((double)rng_int()) / RAND_MAX) #endif static int @@ -552,7 +552,7 @@ random_unit(const region * r) if (c == 0) { return NULL; } - n = rand() % c; + n = rng_int() % c; c = 0; u = r->units; @@ -588,19 +588,19 @@ eaten_by_monster(unit * u) switch (old_race(u->race)) { case RC_FIREDRAGON: - n = rand()%80 * u->number; + n = rng_int()%80 * u->number; horse = get_item(u, I_HORSE); break; case RC_DRAGON: - n = rand()%200 * u->number; + n = rng_int()%200 * u->number; horse = get_item(u, I_HORSE); break; case RC_WYRM: - n = rand()%500 * u->number; + n = rng_int()%500 * u->number; horse = get_item(u, I_HORSE); break; default: - n = rand()%(u->number/20+1); + n = rng_int()%(u->number/20+1); } if (n > 0) { @@ -626,7 +626,7 @@ absorbed_by_monster(unit * u) switch (old_race(u->race)) { default: - n = rand()%(u->number/20+1); + n = rng_int()%(u->number/20+1); } if(n > 0) { @@ -660,7 +660,7 @@ scareaway(region * r, int anzahl) p = rpeasants(r); assert(p >= 0 && anzahl >= 0); for (n = min(p, anzahl); n; n--) { - direction_t dir = (direction_t)(rand() % MAXDIRECTIONS); + direction_t dir = (direction_t)(rng_int() % MAXDIRECTIONS); region * rc = rconnect(r, dir); if (rc && fval(rc->terrain, LAND_REGION)) { @@ -681,16 +681,16 @@ scared_by_monster(unit * u) switch (old_race(u->race)) { case RC_FIREDRAGON: - n = rand()%160 * u->number; + n = rng_int()%160 * u->number; break; case RC_DRAGON: - n = rand()%400 * u->number; + n = rng_int()%400 * u->number; break; case RC_WYRM: - n = rand()%1000 * u->number; + n = rng_int()%1000 * u->number; break; default: - n = rand()%(u->number/4+1); + n = rng_int()%(u->number/4+1); } if(n > 0) { @@ -709,7 +709,7 @@ scared_by_monster(unit * u) static const char * random_growl(void) { - switch(rand()%5) { + switch(rng_int()%5) { case 0: return "Groammm"; case 1: @@ -743,7 +743,7 @@ monster_learn(unit *u) if(c == 0) return NULL; - n = rand()%c + 1; + n = rng_int()%c + 1; c = 0; for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { @@ -884,7 +884,7 @@ plan_dragon(unit * u) long_order = make_movement_order(u, tr, 1, allowed_dragon); break; } - if (rand()%100 < 15) { + if (rng_int()%100 < 15) { /* do a growl */ if (rname(tr, u->faction->locale)) { sprintf(buf, @@ -904,8 +904,8 @@ plan_dragon(unit * u) else if (u->race != new_race[RC_FIREDRAGON]) { /* neue dracoiden! */ if (r->land && !fval(r->terrain, FORBIDDEN_REGION)) { - int ra = 20 + rand() % 100; - if (get_money(u) > ra * 50 + 100 && rand() % 100 < 50) { + int ra = 20 + rng_int() % 100; + if (get_money(u) > ra * 50 + 100 && rng_int() % 100 < 50) { recruit_dracoids(u, ra); } } @@ -985,7 +985,7 @@ plan_monsters(void) a_remove(&u->attribs, ta); } } else if (u->race->flags & RCF_MOVERANDOM) { - if (rand()%100<MOVECHANCE || check_overpopulated(u)) { + if (rng_int()%100<MOVECHANCE || check_overpopulated(u)) { long_order = monster_move(r, u); } } @@ -1053,7 +1053,7 @@ nrand(int start, int sub) int res = 0; do { - if (rand() % 100 < start) + if (rng_int() % 100 < start) res++; start -= sub; } while (start > 0); @@ -1071,7 +1071,7 @@ spawn_dragons(void) unit * u; message * msg; - if (fval(r->terrain, SEA_REGION) && rand()%10000 < 1) { + if (fval(r->terrain, SEA_REGION) && rng_int()%10000 < 1) { u = createunit(r, findfaction(MONSTER_FACTION), 1, new_race[RC_SEASERPENT]); fset(u, UFL_ISNEW|UFL_MOVED); set_level(u, SK_MAGIC, 4); @@ -1081,7 +1081,7 @@ spawn_dragons(void) set_string(&u->name, "Seeschlange"); } - if ((rterrain(r) == T_GLACIER || r->terrain == newterrain(T_SWAMP) || rterrain(r) == T_DESERT) && rand() % 10000 < (5 + 100 * chaosfactor(r))) + if ((rterrain(r) == T_GLACIER || r->terrain == newterrain(T_SWAMP) || rterrain(r) == T_DESERT) && rng_int() % 10000 < (5 + 100 * chaosfactor(r))) { if (chance(0.80)) { u = createunit(r, findfaction(MONSTER_FACTION), nrand(60, 20) + 1, new_race[RC_FIREDRAGON]); @@ -1090,9 +1090,9 @@ spawn_dragons(void) } fset(u, UFL_ISNEW|UFL_MOVED); - set_money(u, u->number * (rand() % 500 + 100)); + set_money(u, u->number * (rng_int() % 500 + 100)); set_level(u, SK_MAGIC, 4); - set_level(u, SK_OBSERVATION, 1+rand()%3); + set_level(u, SK_OBSERVATION, 1+rng_int()%3); set_level(u, SK_STEALTH, 1); set_level(u, SK_AUSDAUER, 1); log_printf("%d %s in %s.\n", u->number, @@ -1132,19 +1132,19 @@ spawn_undead(void) if(is_cursed(r->attribs, C_HOLYGROUND, 0)) continue; /* Chance 0.1% * chaosfactor */ - if (r->land && unburied > r->land->peasants / 20 && rand() % 10000 < (100 + 100 * chaosfactor(r))) { + if (r->land && unburied > r->land->peasants / 20 && rng_int() % 10000 < (100 + 100 * chaosfactor(r))) { unit * u; /* es ist sinnfrei, wenn irgendwo im Wald 3er-Einheiten Untote entstehen. * Lieber sammeln lassen, bis sie mindestens 5% der Bev�lkerung sind, und * dann erst auferstehen. */ - int undead = unburied / (rand() % 2 + 1); + int undead = unburied / (rng_int() % 2 + 1); const race * rc = NULL; int i; if (r->age<100) undead = undead * r->age / 100; /* newbie-regionen kriegen weniger ab */ if (!undead || r->age < 20) continue; - switch(rand()%3) { + switch(rng_int()%3) { case 0: rc = new_race[RC_SKELETON]; break; case 1: @@ -1155,7 +1155,7 @@ spawn_undead(void) u = createunit(r, findfaction(MONSTER_FACTION), undead, rc); fset(u, UFL_ISNEW|UFL_MOVED); - if ((rc == new_race[RC_SKELETON] || rc == new_race[RC_ZOMBIE]) && rand()%10 < 4) { + if ((rc == new_race[RC_SKELETON] || rc == new_race[RC_ZOMBIE]) && rng_int()%10 < 4) { equip_unit(u, get_equipment("rising_undead")); } diff --git a/src/common/gamecode/randenc.c b/src/common/gamecode/randenc.c index 10a757881..670838713 100644 --- a/src/common/gamecode/randenc.c +++ b/src/common/gamecode/randenc.c @@ -55,8 +55,9 @@ #include <attributes/racename.h> /* util includes */ -#include <rand.h> +#include <util/rand.h> #include <util/message.h> +#include <util/rng.h> /* libc includes */ #include <stdio.h> @@ -93,7 +94,7 @@ dissolve_units(void) } else { n = 0; for (i=0;i<u->number;i++) { - if (rand()%100 < a->data.ca[1]) n++; + if (rng_int()%100 < a->data.ca[1]) n++; } } @@ -180,7 +181,7 @@ find_manual(region * r, unit * u) sprintf(buf, "%s stolper%c bei der Erforschung der Region �ber ", unitname(u), "nt"[u->number == 1]); - switch (rand() % 4) { + switch (rng_int() % 4) { case 0: scat("die Ruine eines alten Tempels"); break; @@ -203,7 +204,7 @@ find_manual(region * r, unit * u) } scat(" sie auf das zerfledderte Exemplar eines alten Buches, betitelt "); - switch (rand() % 36) { + switch (rng_int() % 36) { case 0: scat("\'Magie der Elemente\'"); skill = SK_MAGIC; @@ -295,7 +296,7 @@ get_unit(region * r, unit * u) addmessage(r, u->faction, buf, MSG_EVENT, ML_IMPORTANT); - newunit = createunit(r, u->faction, rand() % 20 + 3, u->faction->race); + newunit = createunit(r, u->faction, rng_int() % 20 + 3, u->faction->race); fset(newunit, UFL_ISNEW|UFL_MOVED); set_string(&newunit->name, "Dorfbewohner"); if (fval(u, UFL_PARTEITARNUNG)) { @@ -313,9 +314,9 @@ get_allies(region * r, unit * u) case T_PLAIN: if (!r_isforest(r)) { - if (get_money(u) / u->number < 100 + rand() % 200) + if (get_money(u) / u->number < 100 + rng_int() % 200) return; - newunit = createunit(r, u->faction, rand() % 8 + 2, u->faction->race); + newunit = createunit(r, u->faction, rng_int() % 8 + 2, u->faction->race); set_string(&newunit->name, "S�ldner"); equip_unit(newunit, get_equipment("random_plain")); break; @@ -325,7 +326,7 @@ get_allies(region * r, unit * u) && eff_skill(u, SK_MAGIC, r) < 2) { return; } - newunit = createunit(r, u->faction, rand() % 6 + 2, u->faction->race); + newunit = createunit(r, u->faction, rng_int() % 6 + 2, u->faction->race); set_string(&newunit->name, "Waldbewohner"); equip_unit(newunit, get_equipment("random_forest")); } @@ -335,7 +336,7 @@ get_allies(region * r, unit * u) if (eff_skill(u, SK_OBSERVATION, r) <= 3) { return; } - newunit = createunit(r, u->faction, rand() % 6 + 2, u->faction->race); + newunit = createunit(r, u->faction, rng_int() % 6 + 2, u->faction->race); set_string(&newunit->name, "Sumpfbewohner"); equip_unit(newunit, get_equipment("random_swamp")); break; @@ -344,7 +345,7 @@ get_allies(region * r, unit * u) if (eff_skill(u, SK_RIDING, r) <= 2) { return; } - newunit = createunit(r, u->faction, rand() % 12 + 2, u->faction->race); + newunit = createunit(r, u->faction, rng_int() % 12 + 2, u->faction->race); set_string(&newunit->name, "Berber"); equip_unit(newunit, get_equipment("random_desert")); break; @@ -353,7 +354,7 @@ get_allies(region * r, unit * u) if (eff_skill(u, SK_MELEE, r) <= 1) { return; } - newunit = createunit(r, u->faction, rand() % 8 + 2, u->faction->race); + newunit = createunit(r, u->faction, rng_int() % 8 + 2, u->faction->race); set_string(&newunit->name, "Hochlandbarbaren"); equip_unit(newunit, get_equipment("random_highland")); break; @@ -363,7 +364,7 @@ get_allies(region * r, unit * u) || eff_skill(u, SK_TRADE, r) <= 2) { return; } - newunit = createunit(r, u->faction, rand() % 6 + 2, u->faction->race); + newunit = createunit(r, u->faction, rng_int() % 6 + 2, u->faction->race); set_string(&newunit->name, "Bergbewohner"); equip_unit(newunit, get_equipment("random_mountain")); @@ -374,7 +375,7 @@ get_allies(region * r, unit * u) || eff_skill(u, SK_TRADE, r) <= 1) { return; } - newunit = createunit(r, u->faction, rand() % 4 + 2, u->faction->race); + newunit = createunit(r, u->faction, rng_int() % 4 + 2, u->faction->race); set_string(&newunit->name, "Eisleute"); equip_unit(newunit, get_equipment("random_glacier")); @@ -403,8 +404,8 @@ encounter(region * r, unit * u) { if (!fval(r, RF_ENCOUNTER)) return; freset(r, RF_ENCOUNTER); - if (rand() % 100>=ENCCHANCE) return; - switch (rand() % 3) { + if (rng_int() % 100>=ENCCHANCE) return; + switch (rng_int() % 3) { case 0: find_manual(r, u); break; @@ -434,7 +435,7 @@ encounters(void) } if (c > 0) { - n = rand() % c; + n = rng_int() % c; u = r->units; for (i = u->number; i < n; i += u->number) { @@ -468,7 +469,7 @@ chaosterrain(void) } } } - return types[rand() % numtypes]; + return types[rng_int() % numtypes]; } void @@ -477,8 +478,8 @@ chaos(region * r) unit *u = NULL, *u2; building *b, *b2; - if (rand() % 100 < 8) { - switch (rand() % 3) { + if (rng_int() % 100 < 8) { + switch (rng_int() % 3) { case 0: /* Untote */ if (!fval(r->terrain, SEA_REGION)) { u = random_unit(r); @@ -494,10 +495,10 @@ chaos(region * r) case 1: /* Drachen */ if (random_unit(r)) { int mfac = 0; - switch (rand() % 3) { + switch (rng_int() % 3) { case 0: mfac = 100; - u = createunit(r, findfaction(MONSTER_FACTION), rand() % 8 + 1, new_race[RC_FIREDRAGON]); + u = createunit(r, findfaction(MONSTER_FACTION), rng_int() % 8 + 1, new_race[RC_FIREDRAGON]); if (u->number == 1) { set_string(&u->name, "Feuerdrache"); } else { @@ -506,7 +507,7 @@ chaos(region * r) break; case 1: mfac = 500; - u = createunit(r, findfaction(MONSTER_FACTION), rand() % 4 + 1, new_race[RC_DRAGON]); + u = createunit(r, findfaction(MONSTER_FACTION), rng_int() % 4 + 1, new_race[RC_DRAGON]); if (u->number == 1) { set_string(&u->name, "Drache"); } else { @@ -515,7 +516,7 @@ chaos(region * r) break; case 2: mfac = 1000; - u = createunit(r, findfaction(MONSTER_FACTION), rand() % 2 + 1, new_race[RC_WYRM]); + u = createunit(r, findfaction(MONSTER_FACTION), rng_int() % 2 + 1, new_race[RC_WYRM]); if (u->number == 1) { set_string(&u->name, "Wyrm"); } else { @@ -523,7 +524,7 @@ chaos(region * r) } break; } - if (mfac) set_money(u, u->number * (rand() % mfac)); + if (mfac) set_money(u, u->number * (rng_int() % mfac)); fset(u, UFL_ISNEW|UFL_MOVED); } case 2: /* Terrainver�nderung */ @@ -719,7 +720,7 @@ rrandneighbour(region *r) } /* Zuf�llig eine ausw�hlen */ - rr = rand() % c; + rr = rng_int() % c; /* Durchz�hlen */ @@ -759,7 +760,7 @@ volcano_outbreak(region *r) /* Produktion vierteln ... */ a->data.sa[0] = 25; /* F�r 6-17 Runden */ - a->data.sa[1] = (short)(a->data.sa[1] + 6 + rand()%12); + a->data.sa[1] = (short)(a->data.sa[1] + 6 + rng_int()%12); /* Personen bekommen 4W10 Punkte Schaden. */ @@ -799,7 +800,7 @@ volcano_outbreak(region *r) /* Produktion vierteln ... */ a->data.sa[0] = 25; /* F�r 6-17 Runden */ - a->data.sa[1] = (short)(a->data.sa[1] + 6 + rand()%12); + a->data.sa[1] = (short)(a->data.sa[1] + 6 + rng_int()%12); /* Personen bekommen 3W10 Punkte Schaden. */ for (up=&rn->units; *up;) { @@ -860,11 +861,11 @@ move_iceberg(region *r) a = a_find(r->attribs, &at_iceberg); if (!a) { - dir = (direction_t)(rand()%MAXDIRECTIONS); + dir = (direction_t)(rng_int()%MAXDIRECTIONS); a = a_add(&r->attribs, make_iceberg(dir)); } else { - if (rand()%100 < 20) { - dir = (direction_t)(rand()%MAXDIRECTIONS); + if (rng_int()%100 < 20) { + dir = (direction_t)(rng_int()%MAXDIRECTIONS); a->data.i = dir; } else { dir = (direction_t)a->data.i; @@ -949,7 +950,7 @@ move_iceberg(region *r) sh = shn; } - } else if (rand()%100 < 20) { /* Eisberg bleibt als Gletscher liegen */ + } else if (rng_int()%100 < 20) { /* Eisberg bleibt als Gletscher liegen */ unit *u; rsetterrain(r, T_GLACIER); @@ -971,7 +972,7 @@ move_icebergs(void) for (r=regions; r; r=r->next) { if (rterrain(r) == T_ICEBERG && !fval(r, RF_DH)) { - int select = rand() % 10; + int select = rng_int() % 10; if (select < 4) { /* 4% chance */ fset(r, RF_DH); @@ -1036,7 +1037,7 @@ godcurse(void) for(u=r->units; u; u=u->next) { skill * sv = u->skills; while (sv!=u->skills+u->skill_size) { - int weeks = 1+rand()%3; + int weeks = 1+rng_int()%3; reduce_skill(u, sv, weeks); ++sv; } @@ -1117,7 +1118,7 @@ orc_growth(void) int prob = curse_geteffect(c); for (n = (num - get_item(u, I_CHASTITY_BELT)); n > 0; n--) { - if (rand() % 100 < prob) { + if (rng_int() % 100 < prob) { ++increase; } } @@ -1146,9 +1147,9 @@ demon_skillchanges(void) if (u->race == new_race[RC_DAEMON]) { skill * sv = u->skills; while (sv!=u->skills+u->skill_size) { - if (sv->level>0 && rand() % 100 < 25) { - int weeks = 1+rand()%3; - if (rand() % 100 < 40) { + if (sv->level>0 && rng_int() % 100 < 25) { + int weeks = 1+rng_int()%3; + if (rng_int() % 100 < 40) { reduce_skill(u, sv, weeks); } else { while (weeks--) learn_skill(u, sv->id, 1.0); @@ -1234,16 +1235,16 @@ randomevents(void) rsetterrain(r, T_VOLCANO); } else switch(rterrain(r)) { case T_VOLCANO: - if (rand()%100 < 4) { + if (rng_int()%100 < 4) { ADDMSG(&r->msgs, msg_message("volcanostartsmoke", "region", r)); rsetterrain(r, T_VOLCANO_SMOKING); } break; case T_VOLCANO_SMOKING: - if (rand()%100 < 12) { + if (rng_int()%100 < 12) { ADDMSG(&r->msgs, msg_message("volcanostopsmoke", "region", r)); rsetterrain(r, T_VOLCANO); - } else if (rand()%100 < 8) { + } else if (rng_int()%100 < 8) { volcano_outbreak(r); } break; @@ -1270,7 +1271,7 @@ randomevents(void) if (u->faction->no != MONSTER_FACTION && (u->race->flags & RCF_DESERT)) { if (fval(u, UFL_ISNEW)) continue; - if (rand()%100 < 5) { + if (rng_int()%100 < 5) { ADDMSG(&u->faction->msgs, msg_message("desertion", "unit region", u, r)); u_setfaction(u, findfaction(MONSTER_FACTION)); @@ -1285,7 +1286,7 @@ randomevents(void) int level = fspecial(f, FS_LYCANTROPE); if (level > 0) { for(u = f->units; u; u=u->nextF) { - if(rand()%100 < 2*level) { + if(rng_int()%100 < 2*level) { ADDMSG(&u->faction->msgs, msg_message("becomewere", "unit region", u, u->region)); fset(u, UFL_WERE); @@ -1303,7 +1304,7 @@ randomevents(void) } i = chaoscount(r); if (!i) continue; - chaoscounts(r, -(int) (i * ((double) (rand() % 10)) / 100.0)); + chaoscounts(r, -(int) (i * ((double) (rng_int() % 10)) / 100.0)); } #ifdef HERBS_ROT diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index aa8ee9b3a..bdc30a32b 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -68,12 +68,13 @@ /* util includes */ #include <util/bsdstring.h> -#include <goodies.h> -#include <base36.h> -#include <nrmessage.h> -#include <translation.h> +#include <util/goodies.h> +#include <util/base36.h> +#include <util/nrmessage.h> +#include <util/translation.h> #include <util/message.h> -#include <log.h> +#include <util/rng.h> +#include <util/log.h> /* libc includes */ #include <assert.h> @@ -1234,8 +1235,9 @@ report_template(const char * filename, report_context * ctx) faction * f = ctx->f; region *r; plane *pl; - region *last = lastregion(f); FILE * F = fopen(filename, "wt"); + seen_region * sr = NULL; + if (F==NULL) { perror(filename); return -1; @@ -1260,11 +1262,18 @@ report_template(const char * filename, report_context * ctx) rps_nowrap(F, buf); rnl(F); - for (r = firstregion(f); r != last; r = r->next) { + for (r=ctx->first; sr==NULL && r!=ctx->last; r=r->next) { + sr = find_seen(ctx->seen, r); + } + + for (;sr!=NULL;sr=sr->next) { + region * r = sr->r; unit *u; - int dh = 0; - for (u = r->units; u; u = u->next) + + if (sr->mode<see_unit) continue; + + for (u = r->units; u; u = u->next) { if (u->faction == f && u->race != new_race[RC_SPELL]) { order * ord; if (!dh) { @@ -1349,6 +1358,7 @@ report_template(const char * filename, report_context * ctx) } #endif } + } } rps_nowrap(F, ""); rnl(F); @@ -1721,22 +1731,24 @@ report_building(FILE *F, const region * r, const building * b, const faction * f int report_plaintext(const char * filename, report_context * ctx) { - int flag = 0; - char ch; - int dh; - int anyunits; - const struct region *r; + int flag = 0; + char ch; + int dh; + int anyunits; + const struct region *r; faction * f = ctx->f; - building *b; - ship *sh; - unit *u; + building *b; + ship *sh; + unit *u; char pzTime[64]; - attrib *a; - message * m; - unsigned char op; + attrib *a; + message * m; + unsigned char op; int ix = Pow(O_STATISTICS); - int wants_stats = (f->options & ix); + int wants_stats = (f->options & ix); FILE * F = fopen(filename, "wt"); + seen_region * sr = NULL; + if (F==NULL) { perror(filename); return -1; @@ -1952,30 +1964,32 @@ report_plaintext(const char * filename, report_context * ctx) const char * potiontext = mkname("potion", pname); description = LOC(f->locale, potiontext); } - centre(F, description, true); + centre(F, description, true); } } - rnl(F); - centre(F, LOC(f->locale, "nr_alliances"), false); - rnl(F); - + rnl(F); + centre(F, LOC(f->locale, "nr_alliances"), false); + rnl(F); + #ifdef ENEMIES enemies(F, f); #endif - allies(F, f); + allies(F, f); + + rpline(F); + + anyunits = 0; - rpline(F); - - anyunits = 0; - - for (r=ctx->first;r!=ctx->last;r=r->next) { + for (r=ctx->first;sr==NULL && r!=ctx->last;r=r->next) { + sr = find_seen(ctx->seen, r); + } + for (;sr!=NULL;sr=sr->next) { + region * r = sr->r; boolean unit_in_region = false; boolean durchgezogen_in_region = false; int turm_sieht_region = false; - seen_region * sd = find_seen(ctx->seen, r); - if (sd==NULL) continue; - switch (sd->mode) { + switch (sr->mode) { case see_lighthouse: turm_sieht_region = true; break; @@ -1991,7 +2005,6 @@ report_plaintext(const char * filename, report_context * ctx) default: continue; } - r = sd->r; /* Beschreibung */ if (unit_in_region) { @@ -2004,68 +2017,68 @@ report_plaintext(const char * filename, report_context * ctx) durchreisende(F, r, f); } else { - if (sd->mode==see_far) { - describe(F, r, 3, f); - guards(F, r, f); - durchreisende(F, r, f); - } - else if (turm_sieht_region) { - describe(F, r, 2, f); - durchreisende(F, r, f); - } else { - describe(F, r, 1, f); - durchreisende(F, r, f); - } + if (sr->mode==see_far) { + describe(F, r, 3, f); + guards(F, r, f); + durchreisende(F, r, f); + } + else if (turm_sieht_region) { + describe(F, r, 2, f); + durchreisende(F, r, f); + } else { + describe(F, r, 1, f); + durchreisende(F, r, f); + } } - /* Statistik */ - - if (wants_stats && unit_in_region == 1) - statistics(F, r, f); - - /* Nachrichten an REGION in der Region */ - - if (unit_in_region || durchgezogen_in_region) { - message_list * mlist = r_getmessages(r, f); - rp_messages(F, r->msgs, f, 0, true); - if (mlist) rp_messages(F, mlist, f, 0, true); - } - /* Burgen und ihre Einheiten */ - - for (b = rbuildings(r); b; b = b->next) { - rnl(F); - report_building(F, r, b, f, sd->mode); - } - - /* Restliche Einheiten */ - - if (sd->mode>=see_lighthouse) { - for (u = r->units; u; u = u->next) { - if (!u->building && !u->ship) { - if ((u->faction == f) || - (unit_in_region && cansee(f, r, u, 0)) || - (durchgezogen_in_region && cansee(f, r, u, -1)) || - (sd->mode==see_far && cansee(f, r, u, -2)) || - (turm_sieht_region && cansee(f, r, u, -2))) - { - if (dh == 0 && !(rbuildings(r) || r->ships)) { - dh = 1; - /* rnl(F); */ - } - rpunit(F, f, u, 4, sd->mode); - } - } - } - } - - /* Schiffe und ihre Einheiten */ - - for (sh = r->ships; sh; sh = sh->next) { - faction *of = NULL; - - rnl(F); - - /* Gewicht feststellen */ + /* Statistik */ + + if (wants_stats && unit_in_region == 1) + statistics(F, r, f); + + /* Nachrichten an REGION in der Region */ + + if (unit_in_region || durchgezogen_in_region) { + message_list * mlist = r_getmessages(r, f); + rp_messages(F, r->msgs, f, 0, true); + if (mlist) rp_messages(F, mlist, f, 0, true); + } + /* Burgen und ihre Einheiten */ + + for (b = rbuildings(r); b; b = b->next) { + rnl(F); + report_building(F, r, b, f, sr->mode); + } + + /* Restliche Einheiten */ + + if (sr->mode>=see_lighthouse) { + for (u = r->units; u; u = u->next) { + if (!u->building && !u->ship) { + if ((u->faction == f) || + (unit_in_region && cansee(f, r, u, 0)) || + (durchgezogen_in_region && cansee(f, r, u, -1)) || + (sr->mode==see_far && cansee(f, r, u, -2)) || + (turm_sieht_region && cansee(f, r, u, -2))) + { + if (dh == 0 && !(rbuildings(r) || r->ships)) { + dh = 1; + /* rnl(F); */ + } + rpunit(F, f, u, 4, sr->mode); + } + } + } + } + + /* Schiffe und ihre Einheiten */ + for (sh = r->ships; sh; sh = sh->next) { + faction *of = NULL; + + rnl(F); + + /* Gewicht feststellen */ + for (u = r->units; u; u = u->next) { if (u->ship == sh && fval(u, UFL_OWNER)) { of = u->faction; @@ -2076,7 +2089,7 @@ report_plaintext(const char * filename, report_context * ctx) int n = 0, p = 0; getshipweight(sh, &n, &p); n = (n+99) / 100; /* 1 Silber = 1 GE */ - + sprintf(buf, "%s, %s, (%d/%d)", shipname(sh), LOC(f->locale, sh->type->name[0]), n, shipcapacity(sh) / 100); } else { @@ -2116,13 +2129,13 @@ report_plaintext(const char * filename, report_context * ctx) for (u = r->units; u; u = u->next) { if (u->ship == sh && fval(u, UFL_OWNER)) { - rpunit(F, f, u, 6, sd->mode); + rpunit(F, f, u, 6, sr->mode); break; } } for (u = r->units; u; u = u->next) { if (u->ship == sh && !fval(u, UFL_OWNER)) { - rpunit(F, f, u, 6, sd->mode); + rpunit(F, f, u, 6, sr->mode); } } } @@ -2490,7 +2503,7 @@ writemonument(void) fprintf(F, "\n--- newcomer ---\n\n"); if(count > 7) { - ra = rand()%(count-7); + ra = rng_int()%(count-7); j = 0; for (r = regions; r; r = r->next) { for (b = r->buildings; b; b = b->next) { diff --git a/src/common/gamecode/spy.c b/src/common/gamecode/spy.c index ef65b99c2..125fb1058 100644 --- a/src/common/gamecode/spy.c +++ b/src/common/gamecode/spy.c @@ -47,6 +47,7 @@ /* util includes */ #include <util/vset.h> #include <util/rand.h> +#include <util/rng.h> /* libc includes */ #include <assert.h> @@ -134,7 +135,7 @@ setwere_cmd(unit *u, struct order * ord) if (s == NULL || *s == '\0') { if(fval(u, UFL_WERE)) { cmistake(u, ord, 309, MSG_EVENT); - } else if(rand()%100 < 35+(level-1)*20) { /* 35, 55, 75, 95% */ + } else if(rng_int()%100 < 35+(level-1)*20) { /* 35, 55, 75, 95% */ fset(u, UFL_WERE); } else { cmistake(u, ord, 311, MSG_EVENT); @@ -142,7 +143,7 @@ setwere_cmd(unit *u, struct order * ord) } else if (findparam(s, u->faction->locale) == P_NOT) { if(fval(u, UFL_WERE)) { cmistake(u, ord, 310, MSG_EVENT); - } else if(rand()%100 < 90-level*20) { /* 70, 50, 30, 10% */ + } else if(rng_int()%100 < 90-level*20) { /* 70, 50, 30, 10% */ freset(u, UFL_WERE); } else { cmistake(u, ord, 311, MSG_EVENT); diff --git a/src/common/gamecode/study.c b/src/common/gamecode/study.c index 1b2bbde98..58d352a0d 100644 --- a/src/common/gamecode/study.c +++ b/src/common/gamecode/study.c @@ -194,7 +194,7 @@ teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk, int j = study_cost(student, sk); j = max(50, j * 2); /* kann Einheit das zahlen? */ - if (get_pooled(student, oldresourcetype[R_SILVER], GET_DEFAULT) >= j) { + if (get_pooled(student, oldresourcetype[R_SILVER], GET_DEFAULT, j) >= j) { /* Jeder Sch�ler zus�tzlich +10 Tage wenn in Uni. */ teach->value += (n / 30) * 10; /* learning erh�hen */ /* Lehrer zus�tzlich +1 Tag pro Sch�ler. */ @@ -605,8 +605,9 @@ learn(void) } } if (studycost) { - money = get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT); - money = min(money, studycost * u->number); + int cost = studycost * u->number; + money = get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, cost); + money = min(money, cost); } if (money < studycost * u->number) { studycost = p; /* Ohne Univertreurung */ diff --git a/src/common/items/phoenixcompass.c b/src/common/items/phoenixcompass.c index 37d896a37..600cc5044 100644 --- a/src/common/items/phoenixcompass.c +++ b/src/common/items/phoenixcompass.c @@ -26,11 +26,11 @@ /* util includes */ #include <util/functions.h> #include <util/rand.h> +#include <util/rng.h> /* libc includes */ #include <assert.h> #include <string.h> -#include <stdlib.h> #include <limits.h> static int @@ -98,7 +98,7 @@ use_phoenixcompass(struct unit * u, const struct item_type * itype, if(dist < closest_neighbour_distance) { closest_neighbour_direction = direction; closest_neighbour_distance = dist; - } else if(dist == closest_neighbour_distance && rand()%100 < 50) { + } else if(dist == closest_neighbour_distance && rng_int()%100 < 50) { /* there can never be more than two neighbours with the same * distance (except when you are standing in the same region * as the phoenix, but that case has already been handled). diff --git a/src/common/items/weapons.c b/src/common/items/weapons.c index f5c857c7c..94d18982a 100644 --- a/src/common/items/weapons.c +++ b/src/common/items/weapons.c @@ -24,7 +24,8 @@ #include <pool.h> /* util includes */ -#include <functions.h> +#include <util/functions.h> +#include <util/rng.h> /* libc includes */ #include <assert.h> @@ -82,7 +83,7 @@ attack_firesword(const troop * at, const struct weapon_type * wtype, int *casual int enemies = 0; int killed = 0; const char *damage = "2d8"; - int force = 1+rand()%10; + int force = 1+rng_int()%10; if (row==FIGHT_ROW) { enemies = count_enemies(fi->side->battle, fi->side, minrow, maxrow, true); @@ -140,7 +141,7 @@ attack_catapult(const troop * at, const struct weapon_type * wtype, int * casual assert(af->person[at->index].reload==0); if (it_catapultammo!=NULL) { - if (get_pooled(au, it_catapultammo->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK) <= 0) { + if (get_pooled(au, it_catapultammo->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, 1) <= 0) { /* No ammo. Use other weapon if available. */ return true; } @@ -174,9 +175,9 @@ attack_catapult(const troop * at, const struct weapon_type * wtype, int * casual if (hits(*at, dt, wp)) { d += terminate(dt, *at, AT_STANDARD, wp->type->damage[0], true); #ifdef CATAPULT_STRUCTURAL_DAMAGE - if (dt.fighter->unit->building && rand()%100 < 5) { + if (dt.fighter->unit->building && rng_int()%100 < 5) { damage_building(b, dt.fighter->unit->building, 1); - } else if (dt.fighter->unit->ship && rand()%100 < 5) { + } else if (dt.fighter->unit->ship && rng_int()%100 < 5) { dt.fighter->unit->ship->damage+=DAMAGE_SCALE; } #endif diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index 0db147d1a..3ea8c4fc2 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -56,6 +56,7 @@ #include <util/bsdstring.h> #include <util/cvector.h> #include <util/rand.h> +#include <util/rng.h> #include <util/log.h> /* libc includes */ @@ -63,7 +64,6 @@ #include <ctype.h> #include <limits.h> #include <math.h> -#include <stdlib.h> #include <string.h> #include <sys/stat.h> @@ -73,7 +73,7 @@ static FILE *bdebug; #undef DELAYED_OFFENSE /* non-guarding factions cannot attack after moving */ #define TACTICS_RANDOM 5 /* define this as 1 to deactivate */ -#define CATAPULT_INITIAL_RELOAD 4 /* erster schuss in runde 1 + rand() % INITIAL */ +#define CATAPULT_INITIAL_RELOAD 4 /* erster schuss in runde 1 + rng_int() % INITIAL */ #define CATAPULT_STRUCTURAL_DAMAGE #define BASE_CHANCE 70 /* 70% Basis-�berlebenschance */ @@ -143,7 +143,7 @@ fleeregion(const unit * u) if (!c) return NULL; - return neighbours[rand() % c]; + return neighbours[rng_int() % c]; } static char * @@ -331,7 +331,7 @@ select_corpse(battle * b, fighter * af) } cv_next(side); - di = rand() % maxcasualties; + di = rng_int() % maxcasualties; cv_foreach(df, b->fighters) { /* Geflohene haben auch 0 hp, d�rfen hier aber nicht ausgew�hlt * werden! */ @@ -522,7 +522,7 @@ contest(int skilldiff, const armor_type * ar, const armor_type * sh) vw = (int)(100 - ((100 - vw) * mod)); do { - p = rand() % 100; + p = rng_int() % 100; vw -= p; } while (vw >= 0 && p >= 90); @@ -849,7 +849,7 @@ remove_troop(troop dt) void drain_exp(struct unit *u, int n) { - skill_t sk = (skill_t)(rand() % MAXSKILLS); + skill_t sk = (skill_t)(rng_int() % MAXSKILLS); skill_t ssk; ssk = sk; @@ -870,7 +870,7 @@ drain_exp(struct unit *u, int n) reduce_skill(u, sv, 1); n-=30; } else { - if (rand()%(30*u->number)<n) reduce_skill(u, sv, 1); + if (rng_int()%(30*u->number)<n) reduce_skill(u, sv, 1); n = 0; } } @@ -1192,7 +1192,7 @@ terminate(troop dt, troop at, int type, const char *damage, boolean missile) const item_type * itype = (*pitm)->type; if (!itype->flags & ITF_CURSED && dt.index < (*pitm)->number) { /* 25% Grundchance, das ein Item kaputtgeht. */ - if (rand() % 4 < 1) i_change(pitm, itype, -1); + if (rng_int() % 4 < 1) i_change(pitm, itype, -1); } } remove_troop(dt); @@ -1269,7 +1269,7 @@ select_enemy(battle * b, fighter * af, int minrow, int maxrow, boolean advance) /* Niemand ist in der angegebenen Entfernung? */ if (enemies<=0) return no_troop; - enemies = rand() % enemies; + enemies = rng_int() % enemies; for (si=0;as->enemies[si];++si) { side *ds = as->enemies[si]; void ** fi; @@ -1556,7 +1556,7 @@ do_combatspell(troop at, int row) } /* Antimagie die Fehlschlag erh�ht */ - if (rand()%100 < fumblechance) { + if (rng_int()%100 < fumblechance) { report_failed_spell(b, mage, sp); pay_spell(mage, sp, level, 1); free_order(ord); @@ -1735,7 +1735,7 @@ attack_message(const troop at, const troop dt, const weapon * wp, int dist) if (wp == NULL) { sprintf(smallbuf, "%s %s %s", - a_unit, noweap_string[rand()%4], d_unit); + a_unit, noweap_string[rng_int()%4], d_unit); return smallbuf; } @@ -1779,12 +1779,12 @@ hits(troop at, troop dt, weapon * awp) af->person[at.index].flags &= ~FL_STUNNED; return 0; } - if ((af->person[at.index].flags & FL_TIRED && rand()%100 < 50) + if ((af->person[at.index].flags & FL_TIRED && rng_int()%100 < 50) || (af->person[at.index].flags & FL_SLEEPING)) return 0; if (awp && fval(awp->type, WTF_MISSILE) && af->side->battle->reelarrow == true - && rand()%100 < 50) + && rng_int()%100 < 50) { return 0; } @@ -2053,7 +2053,7 @@ attack(battle *b, troop ta, const att *a, int numattack) if (hits(ta, td, NULL)) { int c = dice_rand(a->data.dice); while(c > 0) { - if (rand()%2) { + if (rng_int()%2) { td.fighter->person[td.index].attack -= 1; } else { td.fighter->person[td.index].defence -= 1; @@ -2263,7 +2263,7 @@ loot_items(fighter * corpse) if (itm->type->flags & (ITF_CURSED|ITF_NOTLOST)) maxrow = LAST_ROW; itm->number -= loot; - if (maxrow == LAST_ROW || rand() % 100 < lootchance) { + if (maxrow == LAST_ROW || rng_int() % 100 < lootchance) { fighter *fig = select_enemy(b, corpse, FIGHT_ROW, maxrow, false).fighter; if (fig) { item * l = fig->loot; @@ -2382,7 +2382,7 @@ aftermath(battle * b) /* Regeneration durch PR_MERCY */ if (dead>0 && pr_mercy) { for (i = 0; i != dead; ++i) { - if (rand()%100 < pr_mercy) { + if (rng_int()%100 < pr_mercy) { ++df->alive; ++df->side->alive; ++df->side->battle->alive; @@ -3089,7 +3089,7 @@ make_fighter(battle * b, unit * u, side * s1, boolean attack) int rnd; do { - rnd = rand()%100; + rnd = rng_int()%100; if (rnd >= 40 && rnd <= 69) p_bonus += 1; else if (rnd <= 89) diff --git a/src/common/kernel/border.c b/src/common/kernel/border.c index c8b6a040c..0c220b12f 100644 --- a/src/common/kernel/border.c +++ b/src/common/kernel/border.c @@ -21,10 +21,11 @@ #include "terrain.h" #include "unit.h" +#include <util/rng.h> + /* libc includes */ #include <assert.h> #include <limits.h> -#include <stdlib.h> #include <string.h> extern boolean incomplete_data; @@ -549,7 +550,7 @@ read_borders(FILE * f) } if (to==from) { - direction_t dir = (direction_t) (rand() % MAXDIRECTIONS); + direction_t dir = (direction_t) (rng_int() % MAXDIRECTIONS); region * r = rconnect(from, dir); log_error(("[read_borders] invalid %s in %s\n", type->__name, regionname(from, NULL))); diff --git a/src/common/kernel/build.c b/src/common/kernel/build.c index 774f66857..bc2f13a66 100644 --- a/src/common/kernel/build.c +++ b/src/common/kernel/build.c @@ -192,7 +192,7 @@ siege_cmd(unit * u, order * ord) region * r = u->region; unit *u2; building *b; - int d; + int d, pooled; int bewaffnete, katapultiere = 0; static boolean init = false; static const curse_type * magicwalls_ct; @@ -222,8 +222,10 @@ siege_cmd(unit * u, order * ord) } /* schaden durch katapulte */ - d = min(u->number, i_get(u->items, it_catapult)); - d = min(get_pooled(u, it_catapultammo->rtype, GET_DEFAULT), d); + d = i_get(u->items, it_catapult); + d = min(u->number, d); + pooled = get_pooled(u, it_catapultammo->rtype, GET_DEFAULT, d); + d = min(pooled, d); if (eff_skill(u, SK_CATAPULT, r) >= 1) { katapultiere = d; d *= eff_skill(u, SK_CATAPULT, r); @@ -501,13 +503,10 @@ build_road(region * r, unit * u, int size, direction_t d) return; } } - if (!get_pooled(u, oldresourcetype[R_STONE], GET_DEFAULT) && u->race != new_race[RC_STONEGOLEM]) { - cmistake(u, u->thisorder, 151, MSG_PRODUCE); - return; - } - + /* left kann man noch bauen */ left = r->terrain->max_road - rroad(r, d); + /* hoffentlich ist r->road <= r->terrain->max_road, n also >= 0 */ if (left <= 0) { sprintf(buf, "In %s gibt es keine Br�cken und Stra�en " @@ -516,14 +515,18 @@ build_road(region * r, unit * u, int size, direction_t d) return; } + if (size>0) left = min(size, left); /* baumaximum anhand der rohstoffe */ if (u->race == new_race[RC_STONEGOLEM]){ n = u->number * GOLEM_STONE; } else { - n = get_pooled(u, oldresourcetype[R_STONE], GET_DEFAULT); + n = get_pooled(u, oldresourcetype[R_STONE], GET_DEFAULT, left); + if (n==0) { + cmistake(u, u->thisorder, 151, MSG_PRODUCE); + return; + } } left = min(n, left); - if (size>0) left = min(size, left); /* n = maximum by skill. try to maximize it */ n = u->number * eff_skill(u, SK_ROAD_BUILDING, r); @@ -710,13 +713,13 @@ build(unit * u, const construction * ctype, int completed, int want) if (type->materials) for (c=0;n>0 && type->materials[c].number;c++) { const struct resource_type * rtype = type->materials[c].rtype; - int need; - int have = get_pooled(u, rtype, GET_DEFAULT); - int prebuilt; - int canuse = have; + int need, prebuilt; + int canuse = get_pooled(u, rtype, GET_DEFAULT, INT_MAX); + if (inside_building(u)) { canuse = matmod(u->building->type->attribs, u, rtype, canuse); } + if (canuse<0) return canuse; /* pass errors to caller */ canuse = matmod(type->attribs, u, rtype, canuse); if (type->reqsize>1) { @@ -771,7 +774,7 @@ maxbuild(const unit * u, const construction * cons) int maximum = INT_MAX; for (c=0;cons->materials[c].number;c++) { const resource_type * rtype = cons->materials[c].rtype; - int have = get_pooled(u, rtype, GET_DEFAULT); + int have = get_pooled(u, rtype, GET_DEFAULT, INT_MAX); int need = required(1, cons->reqsize, cons->materials[c].number); if (have<need) { cmistake(u, u->thisorder, 88, MSG_PRODUCE); diff --git a/src/common/kernel/curse.c b/src/common/kernel/curse.c index 7efcd8a5f..5cf6d85b5 100644 --- a/src/common/kernel/curse.c +++ b/src/common/kernel/curse.c @@ -38,13 +38,13 @@ #include <util/resolve.h> #include <util/base36.h> #include <util/rand.h> +#include <util/rng.h> #include <util/goodies.h> #include <util/variant.h> /* libc includes */ #include <stdio.h> #include <string.h> -#include <stdlib.h> #include <limits.h> #include <assert.h> #include <math.h> @@ -584,7 +584,7 @@ do_transfer_curse(curse *c, unit * u, unit * u2, int n) int i; int u_number = u->number; for (i=0;i<n+1 && u_number>0;i++){ - if (rand()%u_number < cursedmen){ + if (rng_int()%u_number < cursedmen){ ++men; --cursedmen; dogive = true; diff --git a/src/common/kernel/equipment.c b/src/common/kernel/equipment.c index ba057b5d0..afa07fa51 100644 --- a/src/common/kernel/equipment.c +++ b/src/common/kernel/equipment.c @@ -28,6 +28,7 @@ /* util includes */ #include <util/rand.h> +#include <util/rng.h> /* libc includes */ #include <string.h> @@ -141,7 +142,7 @@ equip_unit(struct unit * u, const struct equipment * eq) int i; for (i=0;eq->subsets[i].sets;++i) { if (chance(eq->subsets[i].chance)) { - float rnd = (1+rand() % 1000) / 1000.0f; + float rnd = (1+rng_int() % 1000) / 1000.0f; int k; for (k=0;eq->subsets[i].sets[k].set;++k) { if (rnd<=eq->subsets[i].sets[k].chance) { @@ -172,7 +173,7 @@ equip_items(struct item ** items, const struct equipment * eq) int i; for (i=0;eq->subsets[i].sets;++i) { if (chance(eq->subsets[i].chance)) { - float rnd = (1+rand() % 1000) / 1000.0f; + float rnd = (1+rng_int() % 1000) / 1000.0f; int k; for (k=0;eq->subsets[i].sets[k].set;++k) { if (rnd<=eq->subsets[i].sets[k].chance) { diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index b5d6d84e4..a36b15bab 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -64,6 +64,7 @@ #include <util/event.h> #include <util/functions.h> #include <util/log.h> +#include <util/rng.h> #include <util/sql.h> #include <util/translation.h> #include <util/umlaut.h> @@ -75,7 +76,6 @@ /* libc includes */ #include <stdio.h> -#include <stdlib.h> #include <message.h> #include <string.h> #include <ctype.h> @@ -766,7 +766,7 @@ distribute(int old, int new_value, int n) t = (n / old) * new_value; for (i = (n % old); i; i--) - if (rand() % old < new_value) + if (rng_int() % old < new_value) t++; return t; @@ -881,7 +881,7 @@ scale_number (unit * u, int n) full = u->hp/u->number; /* wieviel kriegt jede person mindestens */ u->hp = full * n + (u->hp-full*u->number) * n / u->number; assert(u->hp>=0); - if ((rand() % u->number) < remain) + if ((rng_int() % u->number) < remain) ++u->hp; /* Nachkommastellen */ } else { remain = 0; @@ -894,7 +894,7 @@ scale_number (unit * u, int n) remain = data->value - snew / n * u->number; snew += remain * n / u->number; remain = (remain * n) % u->number; - if ((rand() % u->number) < remain) + if ((rng_int() % u->number) < remain) ++snew; /* Nachkommastellen */ } data->value = snew; @@ -1850,7 +1850,7 @@ newunitid(void) { int random_unit_no; int start_random_no; - random_unit_no = 1 + (rand() % MAX_UNIT_NR); + random_unit_no = 1 + (rng_int() % MAX_UNIT_NR); start_random_no = random_unit_no; while (ufindhash(random_unit_no) || dfindhash(random_unit_no) @@ -1874,7 +1874,7 @@ newcontainerid(void) int random_no; int start_random_no; - random_no = 1 + (rand() % MAX_CONTAINER_NR); + random_no = 1 + (rng_int() % MAX_CONTAINER_NR); start_random_no = random_no; while (findship(random_no) || findbuilding(random_no)) { @@ -2678,7 +2678,7 @@ hunger(int number, unit * u) int hp = u->hp / u->number; while (number--) { - int dam = u->race==new_race[RC_HALFLING]?15+rand()%14:(13+rand()%12); + int dam = u->race==new_race[RC_HALFLING]?15+rng_int()%14:(13+rng_int()%12); if (dam >= hp) { ++dead; } else { @@ -2711,40 +2711,36 @@ hunger(int number, unit * u) void plagues(region * r, boolean ismagic) { - double prob; - int peasants; - int i; - int gestorben; - /* Vermeidung von DivByZero */ - double mwp = max(maxworkingpeasants(r), 1); + int peasants; + int i; + int dead = 0; - /* Seuchenwahrscheinlichkeit in % */ + /* Seuchenwahrscheinlichkeit in % */ - prob = pow((double) rpeasants(r) / - (mwp * (((double)wage(r, NULL, NULL)) / 10.0) * 1.3), 4.0) - * (double) SEUCHE; + if (!ismagic) { + double mwp = max(maxworkingpeasants(r), 1); + double prob = pow(rpeasants(r) / (mwp * wage(r, NULL, NULL) * 0.13), 4.0) + * SEUCHE; + + if (rng_double() >= prob) return; + } - if (rand() % 100 >= (int)prob && !ismagic) return; + peasants = rpeasants(r); + dead = (int)(0.5F + SEUCHENOPFER * peasants); + for (i = dead; i != 0; i--) { + if (rng_int() % 100 < HEILCHANCE && rmoney(r) >= HEILKOSTEN) { + rsetmoney(r, rmoney(r) - HEILKOSTEN); + } else { + --dead; + } + } - peasants = rpeasants(r); - for (i = peasants; i != 0; i--) { - if (rand() % 100 < SEUCHENOPFER) { - if (rand() % 100 < HEILCHANCE && rmoney(r) >= HEILKOSTEN) { - rsetmoney(r, rmoney(r) - HEILKOSTEN); - } else { - peasants--; - } - } - } - - gestorben = rpeasants(r) - peasants; - - if (gestorben > 0) { - message * msg = add_message(&r->msgs, msg_message("pest", "dead", gestorben)); - msg_release(msg); - deathcounts(r, gestorben); - } - rsetpeasants(r, peasants); + if (dead > 0) { + message * msg = add_message(&r->msgs, msg_message("pest", "dead", dead)); + msg_release(msg); + deathcounts(r, dead); + rsetpeasants(r, peasants - dead); + } } /* Lohn bei den einzelnen Burgstufen f�r Normale Typen, Orks, Bauern, @@ -3053,7 +3049,7 @@ lovar(double xpct_x2) { int n = (int)(xpct_x2 * 500)+1; if (n==0) return 0; - return (rand() % n + rand() % n)/1000; + return (rng_int() % n + rng_int() % n)/1000; } boolean @@ -3139,9 +3135,9 @@ kernel_init(void) if (!turn) turn = lastturn(); if (turn == 0) - srand((int)time(0)); + rng_init((int)time(0)); else - srand(turn); + rng_init(turn); if (sqlpatch) { sprintf(zBuffer, "%s/patch-%d.sql", datapath(), turn); sql_init(zBuffer); diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index 1fd57cee8..419c2af89 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -223,27 +223,12 @@ extern void read_laen(struct region * r, int laen); #define DISALLOW_ATTACK_AND_WORK -/** Ausbreitung und Vermehrung */ - -#define MAXDEMAND 25 -#define DMRISE 10 -#define DMRISEHAFEN 20 - /* Vermehrung trotz 90% Auslastung */ #define PEASANTFORCE 0.75 #define PEASANTSWANDER_WEIGHT 5 #define PEASANTSGREED_WEIGHT 5 -#define STARVATION_SURVIVAL 10 - -/* Pferdevermehrung */ -#define HORSEGROWTH 4 -/* Wanderungschance pro Pferd */ -#define HORSEMOVE 3 - -/* Vermehrungschance pro Baum */ -#define FORESTGROWTH 10000 /* In Millionstel */ #define TREESIZE (MAXPEASANTS_PER_AREA-2) /* Eisen in Bergregionen bei Erschaffung */ @@ -273,9 +258,9 @@ extern void read_laen(struct region * r, int laen); /** Plagues **/ /* Seuchenwahrscheinlichkeit (siehe plagues()) */ -#define SEUCHE 10 +#define SEUCHE 0.1F /* % Betroffene */ -#define SEUCHENOPFER 20 +#define SEUCHENOPFER 0.2F extern void plagues(struct region * r, boolean ismagic); /** Healing **/ diff --git a/src/common/kernel/faction.c b/src/common/kernel/faction.c index a1260e6f4..e3fdbaf01 100644 --- a/src/common/kernel/faction.c +++ b/src/common/kernel/faction.c @@ -31,6 +31,7 @@ #include <util/event.h> #include <util/goodies.h> #include <util/resolve.h> +#include <util/rng.h> #include <util/variant.h> #include <attributes/otherfaction.h> @@ -48,7 +49,7 @@ random_unit_in_faction(const faction *f) for(u = f->units; u; u=u->next) c++; - u_nr = rand()%c; + u_nr = rng_int()%c; c = 0; for(u = f->units; u; u=u->next) @@ -85,7 +86,7 @@ resolve_faction(variant id) { static int unused_faction_id(void) { - int id = rand()%MAX_FACTION_ID; + int id = rng_int()%MAX_FACTION_ID; while (!faction_id_is_unused(id)) { id++; if(id == MAX_FACTION_ID) id = 0; @@ -111,10 +112,10 @@ addfaction(const char *email, const char * password, if (password) { set_string(&f->passw, password); } else { - for (i = 0; i < 6; i++) buf[i] = (char) (97 + rand() % 26); buf[i] = 0; + for (i = 0; i < 6; i++) buf[i] = (char) (97 + rng_int() % 26); buf[i] = 0; set_string(&f->passw, buf); } - for (i = 0; i < 6; i++) buf[i] = (char) (97 + rand() % 26); buf[i] = 0; + for (i = 0; i < 6; i++) buf[i] = (char) (97 + rng_int() % 26); buf[i] = 0; set_string(&f->override, buf); f->lastorders = turn; @@ -152,7 +153,7 @@ addplayer(region *r, faction * f) if (f->race == new_race[RC_DAEMON]) { race_t urc; do { - urc = (race_t)(rand() % MAXRACES); + urc = (race_t)(rng_int() % MAXRACES); } while (new_race[urc]==NULL || urc == RC_DAEMON || !playerrace(new_race[urc])); u->irace = new_race[urc]; } diff --git a/src/common/kernel/faction.h b/src/common/kernel/faction.h index db761a8e8..56d4476ec 100644 --- a/src/common/kernel/faction.h +++ b/src/common/kernel/faction.h @@ -18,7 +18,8 @@ extern "C" { struct player; struct alliance; - +struct item; + /* SMART_INTERVALS: define to speed up finding the interval of regions that a faction is in. defining this speeds up the turn by 30-40% */ #define SMART_INTERVALS diff --git a/src/common/kernel/give.c b/src/common/kernel/give.c index e43f86766..26541349c 100644 --- a/src/common/kernel/give.c +++ b/src/common/kernel/give.c @@ -96,7 +96,7 @@ give_item(int want, const item_type * itype, unit * src, unit * dest, struct ord int n; assert(itype!=NULL); - n = get_pooled(src, item2resource(itype), GET_DEFAULT); + n = get_pooled(src, item2resource(itype), GET_DEFAULT, want); n = min(want, n); if (dest && src->faction != dest->faction && src->faction->age < GiveRestriction()) { if (ord!=NULL) { diff --git a/src/common/kernel/item.c b/src/common/kernel/item.c index 4832fe0bd..c0014ebc6 100644 --- a/src/common/kernel/item.c +++ b/src/common/kernel/item.c @@ -40,6 +40,7 @@ #include <util/goodies.h> #include <util/message.h> #include <util/umlaut.h> +#include <util/rng.h> /* libc includes */ #include <assert.h> @@ -315,20 +316,21 @@ new_potiontype(item_type * itype, void rt_register(resource_type * rtype) { - resource_type ** prtype = &resourcetypes; - - if (!rtype->hashkey) - rtype->hashkey = hashstring(rtype->_name[0]); - while (*prtype && *prtype!=rtype) prtype=&(*prtype)->next; - if (*prtype == NULL) { - *prtype = rtype; - } + resource_type ** prtype = &resourcetypes; + + if (!rtype->hashkey) { + rtype->hashkey = hashstring(rtype->_name[0]); + } + while (*prtype && *prtype!=rtype) prtype=&(*prtype)->next; + if (*prtype == NULL) { + *prtype = rtype; + } } const resource_type * item2resource(const item_type * itype) { - return itype->rtype; + return itype->rtype; } const item_type * @@ -339,18 +341,18 @@ resource2item(const resource_type * rtype) const weapon_type * resource2weapon(const resource_type * rtype) { - return rtype->wtype; + return rtype->wtype; } const luxury_type * resource2luxury(const resource_type * rtype) { #ifdef AT_LTYPE - attrib * a = a_find(rtype->attribs, &at_ltype); - if (a) return (const luxury_type *)a->data.v; - return NULL; + attrib * a = a_find(rtype->attribs, &at_ltype); + if (a) return (const luxury_type *)a->data.v; + return NULL; #else - return rtype->ltype; + return rtype->ltype; #endif } @@ -358,25 +360,25 @@ const potion_type * resource2potion(const resource_type * rtype) { #ifdef AT_PTYPE - attrib * a = a_find(rtype->attribs, &at_ptype); - if (a) return (const potion_type *)a->data.v; - return NULL; + attrib * a = a_find(rtype->attribs, &at_ptype); + if (a) return (const potion_type *)a->data.v; + return NULL; #else - return rtype->ptype; + return rtype->ptype; #endif } resource_type * rt_find(const char * name) { - unsigned int hash = hashstring(name); - resource_type * rtype; + unsigned int hash = hashstring(name); + resource_type * rtype; for (rtype=resourcetypes; rtype; rtype=rtype->next) { if (rtype->hashkey==hash && !strcmp(rtype->_name[0], name)) break; } - return rtype; + return rtype; } static const char * it_aliases[][2] = { @@ -401,57 +403,57 @@ it_alias(const char * zname) item_type * it_find(const char * zname) { - const char * name = it_alias(zname); - unsigned int hash = hashstring(name); - item_type * itype; + const char * name = it_alias(zname); + unsigned int hash = hashstring(name); + item_type * itype; unsigned int key = hash % IMAXHASH; - + for (itype=itemtypes[key]; itype; itype=itype->next) { if (itype->rtype->hashkey==hash && strcmp(itype->rtype->_name[0], name) == 0) { break; } - } + } if (itype==NULL) { for (itype=itemtypes[key]; itype; itype=itype->next) { if (strcmp(itype->rtype->_name[1], name) == 0) break; } } - return itype; + return itype; } item ** i_find(item ** i, const item_type * it) { - while (*i && (*i)->type!=it) i = &(*i)->next; - return i; + while (*i && (*i)->type!=it) i = &(*i)->next; + return i; } int i_get(const item * i, const item_type * it) { - i = *i_find((item**)&i, it); - if (i) return i->number; - return 0; + i = *i_find((item**)&i, it); + if (i) return i->number; + return 0; } item * i_add(item ** pi, item * i) { - assert(i && i->type && !i->next); - while (*pi) { - int d = strcmp((*pi)->type->rtype->_name[0], i->type->rtype->_name[0]); - if (d>=0) break; - pi = &(*pi)->next; - } - if (*pi && (*pi)->type==i->type) { - (*pi)->number += i->number; - i_free(i); - } else { - i->next = *pi; - *pi = i; - } - return *pi; + assert(i && i->type && !i->next); + while (*pi) { + int d = strcmp((*pi)->type->rtype->_name[0], i->type->rtype->_name[0]); + if (d>=0) break; + pi = &(*pi)->next; + } + if (*pi && (*pi)->type==i->type) { + (*pi)->number += i->number; + i_free(i); + } else { + i->next = *pi; + *pi = i; + } + return *pi; } void @@ -629,7 +631,7 @@ use_tacticcrystal(region * r, unit * u, int amount, struct order * ord) curse * c; variant effect; - effect.i = rand()%6 - 1; + effect.i = rng_int()%6 - 1; c = create_curse(u, &u->attribs, ct_find("skillmod"), power, duration, effect, u->number); c->data.i = SK_TACTICS; @@ -1125,7 +1127,7 @@ use_bloodpotion(struct unit *u, const struct item_type *itype, int amount, struc change_effect(u, itype->rtype->ptype, 100*amount); } else { trigger * trestore = trigger_changerace(u, u->race, u->irace); - int duration = 2 + rand() % 8; + int duration = 2 + rng_int() % 8; add_trigger(&u->attribs, "timer", trigger_timeout(duration, trestore)); u->irace = u->race = new_race[RC_TOAD]; @@ -1142,25 +1144,25 @@ use_bloodpotion(struct unit *u, const struct item_type *itype, int amount, struc static int use_mistletoe(struct unit * user, const struct item_type * itype, int amount, struct order * ord) { - int mtoes = get_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK); + int mtoes = get_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, user->number); - if (user->number>mtoes) { - ADDMSG(&user->faction->msgs, msg_message("use_singleperson", - "unit item region command", user, itype->rtype, user->region, ord)); - return -1; - } - use_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, user->number); - a_add(&user->attribs, make_fleechance((float)1.0)); - ADDMSG(&user->faction->msgs, msg_message("use_item", - "unit item", user, itype->rtype)); - - return 0; + if (user->number>mtoes) { + ADDMSG(&user->faction->msgs, msg_message("use_singleperson", + "unit item region command", user, itype->rtype, user->region, ord)); + return -1; + } + use_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, user->number); + a_add(&user->attribs, make_fleechance((float)1.0)); + ADDMSG(&user->faction->msgs, + msg_message("use_item", "unit item", user, itype->rtype)); + + return 0; } static int use_magicboost(struct unit * user, const struct item_type * itype, int amount, struct order * ord) { - int mtoes = get_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK); + int mtoes = get_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, user->number); faction * f = user->faction; if (user->number>mtoes) { ADDMSG(&user->faction->msgs, msg_message("use_singleperson", diff --git a/src/common/kernel/item.h b/src/common/kernel/item.h index b67b792b5..82caba55f 100644 --- a/src/common/kernel/item.h +++ b/src/common/kernel/item.h @@ -53,22 +53,22 @@ typedef int (*rtype_uchange)(struct unit * user, const struct resource_type * rt typedef int (*rtype_uget)(const struct unit * user, const struct resource_type * rtype); typedef char * (*rtype_name)(const struct resource_type * rtype, int flags); typedef struct resource_type { - /* --- constants --- */ - char * _name[2]; /* wie es hei�t */ - char * _appearance[2]; /* wie es f�r andere aussieht */ - unsigned int flags; - /* --- functions --- */ - rtype_uchange uchange; - rtype_uget uget; - rtype_name name; - /* --- pointers --- */ - struct attrib * attribs; - struct resource_type * next; - unsigned int hashkey; - struct item_type * itype; - struct potion_type * ptype; - struct luxury_type * ltype; - struct weapon_type * wtype; + /* --- constants --- */ + char * _name[2]; /* wie es hei�t */ + char * _appearance[2]; /* wie es f�r andere aussieht */ + unsigned int flags; + /* --- functions --- */ + rtype_uchange uchange; + rtype_uget uget; + rtype_name name; + /* --- pointers --- */ + struct attrib * attribs; + struct resource_type * next; + unsigned int hashkey; + struct item_type * itype; + struct potion_type * ptype; + struct luxury_type * ltype; + struct weapon_type * wtype; struct armor_type * atype; } resource_type; extern resource_type * resourcetypes; @@ -90,10 +90,10 @@ extern struct attrib_type at_resourcelimit; typedef int (*rlimit_limit)(const struct region * r, const struct resource_type * rtype); typedef void (*rlimit_produce)(struct region * r, const struct resource_type * rtype, int n); typedef struct resource_limit { - rlimit_limit limit; - rlimit_produce produce; + rlimit_limit limit; + rlimit_produce produce; unsigned int guard; /* how to guard against theft */ - int value; + int value; resource_mod * modifiers; } resource_limit; diff --git a/src/common/kernel/karma.c b/src/common/kernel/karma.c index 23a8142f6..adaf50d6c 100644 --- a/src/common/kernel/karma.c +++ b/src/common/kernel/karma.c @@ -32,8 +32,9 @@ #include "message.h" /* util includes */ -#include <attrib.h> -#include <base36.h> +#include <util/attrib.h> +#include <util/base36.h> +#include <util/rng.h> /* libc includes */ #include <math.h> @@ -561,7 +562,7 @@ jihad_attacks(void) for(f=factions; f; f=f->next) if(fspecial(f, FS_JIHAD)) { region * last = lastregion(f); - for (r=firstregion(f); r != last; r = r->next) if (rand()%1000 <= 1) { + for (r=firstregion(f); r != last; r = r->next) if (rng_int()%1000 <= 1) { boolean doit = false; for(u=r->units; u; u=u->next) if(jihad(f, u->race)) { diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index 2c6f7ce33..7fd579887 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -54,6 +54,7 @@ #include <util/attrib.h> #include <util/resolve.h> #include <util/rand.h> +#include <util/rng.h> #include <util/base36.h> #include <util/event.h> @@ -803,42 +804,40 @@ spl_costtyp(const spell * sp) int eff_spelllevel(unit *u, const spell * sp, int cast_level, int range) { - int k; - int maxlevel; - int needplevel; - int costtyp = SPC_FIX; - - for (k = 0; sp->components[k].type; k++) { - if (cast_level == 0) - return 0; - - if (sp->components[k].amount > 0) { - /* Die Kosten f�r Aura sind auch von der Zahl der bereits - * gezauberten Spr�che abh�ngig */ - if (sp->components[k].type == r_aura) { - needplevel = spellcost(u, sp) * range; - } else { - needplevel = sp->components[k].amount * range; - } - maxlevel = get_pooled(u, sp->components[k].type, GET_DEFAULT)/needplevel; - - /* sind die Kosten fix, so muss die Komponente nur einmal vorhanden - * sein und der cast_level �ndert sich nicht */ - if (sp->components[k].cost == SPC_FIX) { - if (maxlevel < 1) cast_level = 0; - /* ansonsten wird das Minimum aus maximal m�glicher Stufe und der - * gew�nschten gebildet */ - } else if (sp->components[k].cost == SPC_LEVEL) { - costtyp = SPC_LEVEL; - cast_level = min(cast_level, maxlevel); - /* bei Typ Linear m�ssen die Kosten in H�he der Stufe vorhanden - * sein, ansonsten schl�gt der Spruch fehl */ - } else if (sp->components[k].cost == SPC_LINEAR) { - costtyp = SPC_LINEAR; - if (maxlevel < cast_level) cast_level = 0; - } - } - } + int k, maxlevel, needplevel; + int costtyp = SPC_FIX; + + for (k = 0; sp->components[k].type; k++) { + if (cast_level == 0) + return 0; + + if (sp->components[k].amount > 0) { + /* Die Kosten f�r Aura sind auch von der Zahl der bereits + * gezauberten Spr�che abh�ngig */ + if (sp->components[k].type == r_aura) { + needplevel = spellcost(u, sp) * range; + } else { + needplevel = sp->components[k].amount * range; + } + maxlevel = get_pooled(u, sp->components[k].type, GET_DEFAULT, needplevel*cast_level)/needplevel; + + /* sind die Kosten fix, so muss die Komponente nur einmal vorhanden + * sein und der cast_level �ndert sich nicht */ + if (sp->components[k].cost == SPC_FIX) { + if (maxlevel < 1) cast_level = 0; + /* ansonsten wird das Minimum aus maximal m�glicher Stufe und der + * gew�nschten gebildet */ + } else if (sp->components[k].cost == SPC_LEVEL) { + costtyp = SPC_LEVEL; + cast_level = min(cast_level, maxlevel); + /* bei Typ Linear m�ssen die Kosten in H�he der Stufe vorhanden + * sein, ansonsten schl�gt der Spruch fehl */ + } else if (sp->components[k].cost == SPC_LINEAR) { + costtyp = SPC_LINEAR; + if (maxlevel < cast_level) cast_level = 0; + } + } + } /* Ein Spruch mit Fixkosten wird immer mit der Stufe des Spruchs und * nicht auf der Stufe des Magiers gezaubert */ if (costtyp == SPC_FIX) { @@ -965,7 +964,7 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord) break; } - if (get_pooled(u, rtype, GET_DEFAULT) < itemanz) { + if (get_pooled(u, rtype, GET_DEFAULT, itemanz) < itemanz) { resource * res = malloc(sizeof(resource)); res->number = itemanz; res->type = rtype; @@ -1263,7 +1262,7 @@ fumble(region * r, unit * u, const spell * sp, int cast_grade) #endif return false; } - rnd = rand()%100; + rnd = rng_int()%100; #ifdef PATZERDEBUG printf("%s: Zauber Stufe %d, Talent %d, Patzerchance %d, rand: %d\n", @@ -1306,7 +1305,7 @@ do_fumble(castorder *co) ADDMSG(&u->faction->msgs, msg_message("patzer", "unit region spell", u, r, sp)); - switch (rand() % 10) { + switch (rng_int() % 10) { case 0: /* wenn vorhanden spezieller Patzer, ansonsten nix */ if (sp->patzer) sp->patzer(co); @@ -1315,7 +1314,7 @@ do_fumble(castorder *co) case 1: /* Kr�te */ - duration = rand()%level/2; + duration = rng_int()%level/2; if (duration<2) duration = 2; { /* one or two things will happen: the toad changes her race back, @@ -1340,7 +1339,7 @@ do_fumble(castorder *co) case 2: /* tempor�rer Stufenverlust */ - duration = max(rand()%level/2, 2); + duration = max(rng_int()%level/2, 2); effect.i = -(level/2); c = create_curse(u, &u->attribs, ct_find("skil"), level, duration, effect, 1); @@ -1413,7 +1412,7 @@ regeneration(unit * u) /* TODO (noch gibs keine)*/ /* W�rfeln */ - aura = (rand() % d + rand() % d)/2 + 1; + aura = (rng_int() % d + rng_int() % d)/2 + 1; aura = (int)(aura * MagicRegeneration()); diff --git a/src/common/kernel/movement.c b/src/common/kernel/movement.c index 6570892d4..8ed53c550 100644 --- a/src/common/kernel/movement.c +++ b/src/common/kernel/movement.c @@ -51,12 +51,12 @@ #include <util/goodies.h> #include <util/language.h> #include <util/rand.h> +#include <util/rng.h> /* libc includes */ #include <assert.h> #include <math.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> /* attributes includes */ @@ -479,7 +479,7 @@ do_maelstrom(region *r, unit *u) { int damage; - damage = rand()%150 - eff_skill(u, SK_SAILING, r)*5; + damage = rng_int()%150 - eff_skill(u, SK_SAILING, r)*5; if(damage <= 0) { ADDMSG(&u->faction->msgs, msg_message("entermaelstrom", @@ -721,7 +721,7 @@ drifting_ships(region * r) /* Auswahl einer Richtung: Zuerst auf Land, dann * zuf�llig. Falls unm�gliches Resultat: vergi� es. */ - d_offset = rand() % MAXDIRECTIONS; + d_offset = rng_int() % MAXDIRECTIONS; for (d = 0; d != MAXDIRECTIONS; ++d) { region * rn = rconnect(r, (direction_t)((d + d_offset) % MAXDIRECTIONS)); if (rn!=NULL && fval(rn->terrain, SAIL_INTO) && ship_allowed(sh, rn)) { @@ -1107,7 +1107,7 @@ regain_orientation(region * r) cap = shipowner(sh); if (cap==NULL) continue; - if (!fval(r->terrain, SEA_REGION) || rand() % 10 >= storms[thismonth]) { + if (!fval(r->terrain, SEA_REGION) || rng_int() % 10 >= storms[thismonth]) { remove_curse(&sh->attribs, c); ADDMSG(&cap->faction->msgs, msg_message("shipnoconf", "ship", sh)); continue; @@ -1132,7 +1132,7 @@ next_region(unit * u, region * current, region * next) if (is_disoriented(u)) { direction_t d = reldirection(current, next); if (d<MAXDIRECTIONS) { - d = (direction_t)(((d+MAXDIRECTIONS-1)+rand()%3)%MAXDIRECTIONS); + d = (direction_t)(((d+MAXDIRECTIONS-1)+rng_int()%3)%MAXDIRECTIONS); next = rconnect(current, d); } } @@ -1634,11 +1634,11 @@ sail(unit * u, order * ord, boolean move_on_land, region_list **routep) stormchance = stormyness / shipspeed(sh, u); if (check_leuchtturm(next_point, NULL)) stormchance /= 3; - if (rand()%10000 < stormchance && fval(current_point->terrain, SEA_REGION)) { + if (rng_int()%10000 < stormchance && fval(current_point->terrain, SEA_REGION)) { if (!is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) { region * rnext = NULL; boolean storm = true; - int d_offset = rand() % MAXDIRECTIONS; + int d_offset = rng_int() % MAXDIRECTIONS; direction_t d; /* Sturm nur, wenn n�chste Region Hochsee ist. */ for (d=0;d!=MAXDIRECTIONS;++d) { @@ -2144,7 +2144,7 @@ piracy_cmd(unit *u, struct order * ord) if (alliedunit(u, f, HELP_FIGHT)) continue; if (il == 0 || intlist_find(il, cap->faction->no)) { ++aff[dir].value; - if (rand() % aff[dir].value == 0) { + if (rng_int() % aff[dir].value == 0) { aff[dir].target = f; } } @@ -2157,7 +2157,7 @@ piracy_cmd(unit *u, struct order * ord) } if (saff != 0) { - saff = rand() % saff; + saff = rng_int() % saff; for (dir=0; dir!=MAXDIRECTIONS; ++dir) { if (saff!=aff[dir].value) break; saff -= aff[dir].value; diff --git a/src/common/kernel/names.c b/src/common/kernel/names.c index 829fd803a..c0983c665 100644 --- a/src/common/kernel/names.c +++ b/src/common/kernel/names.c @@ -40,6 +40,7 @@ /* util includes */ #include <util/base36.h> #include <util/bsdstring.h> +#include <util/rng.h> /* Untote */ @@ -119,10 +120,10 @@ untoten_name(const unit * u) /* nur 50% aller Namen haben "Vor-Teil" */ u=u; - uv = rand() % (UNTOT_VOR * 2); + uv = rng_int() % (UNTOT_VOR * 2); - uu = rand() % UNTOT; - un = rand() % (UNTOT_NACH * (uv >= UNTOT_VOR ? 1 : 2)); + uu = rng_int() % UNTOT; + un = rng_int() % (UNTOT_NACH * (uv >= UNTOT_VOR ? 1 : 2)); /* nur 50% aller Namen haben "Nach-Teil", wenn kein Vor-Teil */ if (uv < UNTOT_VOR) { @@ -206,9 +207,9 @@ skeleton_name(const unit * u) u=u; /* nur 20% aller Namen haben "Vor-Teil" */ - uv = rand() % (SKEL_VOR * 5); - uu = rand() % SKEL; - un = rand() % (SKEL_NACH * (uv >= SKEL_VOR ? 1 : 2)); + uv = rng_int() % (SKEL_VOR * 5); + uu = rng_int() % SKEL; + un = rng_int() % (SKEL_NACH * (uv >= SKEL_VOR ? 1 : 2)); /* nur 50% aller Namen haben "Nach-Teil", wenn kein Vor-Teil */ @@ -289,9 +290,9 @@ zombie_name(const unit * u) u=u; /* nur 20% aller Namen haben "Vor-Teil" */ - uv = rand() % (ZOM_VOR * 5); - uu = rand() % ZOM; - un = rand() % (ZOM_NACH * (uv >= ZOM_VOR ? 1 : 2)); + uv = rng_int() % (ZOM_VOR * 5); + uu = rng_int() % ZOM; + un = rng_int() % (ZOM_NACH * (uv >= ZOM_VOR ? 1 : 2)); /* nur 50% aller Namen haben "Nach-Teil", wenn kein Vor-Teil */ @@ -374,9 +375,9 @@ ghoul_name(const unit * u) u=u; /* nur 20% aller Namen haben "Vor-Teil" */ - uv = rand() % (GHOUL_VOR * 5); - uu = rand() % GHOUL; - un = rand() % (GHOUL_NACH * (uv >= GHOUL_VOR ? 1 : 4)); + uv = rng_int() % (GHOUL_VOR * 5); + uu = rng_int() % GHOUL; + un = rng_int() % (GHOUL_NACH * (uv >= GHOUL_VOR ? 1 : 4)); /* nur 25% aller Namen haben "Nach-Teil", wenn kein Vor-Teil */ @@ -521,7 +522,7 @@ const char * drachen_name(const unit *u) { static char name[NAMESIZE + 1]; - int rnd = rand() % DTITEL; + int rnd = rng_int() % DTITEL; const char *t = dtitel[0][rnd]; int anzahl = 1; @@ -552,10 +553,10 @@ drachen_name(const unit *u) } else { char n[32]; - strcpy(n, silbe1[rand() % SIL1]); - strcat(n, silbe2[rand() % SIL2]); - strcat(n, silbe3[rand() % SIL3]); - if (rand() % 5 > 2) { + strcpy(n, silbe1[rng_int() % SIL1]); + strcat(n, silbe2[rng_int() % SIL2]); + strcat(n, silbe3[rng_int() % SIL3]); + if (rng_int() % 5 > 2) { sprintf(name, "%s, %s", n, t); /* "Name, der Titel" */ } else { strcpy(name, t); /* "Der Titel Name" */ @@ -563,7 +564,7 @@ drachen_name(const unit *u) strcat(name, " "); strcat(name, n); } - if (u && (rand() % 3 == 0)) { + if (u && (rng_int() % 3 == 0)) { strcat(name, " von "); strcat(name, rname(u->region, NULL)); } @@ -630,15 +631,15 @@ dracoid_name(const unit *u) u=u; /* Wieviele Mittelteile? */ - mid_syllabels = rand()%4; + mid_syllabels = rng_int()%4; - strcpy(name, drac_pre[rand()%DRAC_PRE]); + strcpy(name, drac_pre[rng_int()%DRAC_PRE]); while(mid_syllabels > 0) { mid_syllabels--; - if(rand()%10 < 4) strcat(name,"'"); - strcat(name, drac_mid[rand()%DRAC_MID]); + if(rng_int()%10 < 4) strcat(name,"'"); + strcat(name, drac_mid[rng_int()%DRAC_MID]); } - strcat(name, drac_suf[rand()%DRAC_SUF]); + strcat(name, drac_suf[rng_int()%DRAC_SUF]); return name; } diff --git a/src/common/kernel/player.c b/src/common/kernel/player.c index 5103031de..bce2704a3 100644 --- a/src/common/kernel/player.c +++ b/src/common/kernel/player.c @@ -13,10 +13,10 @@ #include <config.h> #include "player.h" -#include <goodies.h> +#include <util/goodies.h> +#include <util/rng.h> #include <string.h> -#include <stdlib.h> #include <limits.h> #define PMAXHASH 1021 @@ -33,7 +33,7 @@ make_player(const struct faction * f) player * p = calloc(sizeof(player), 1); unsigned int hash; - for (p->id = rand();;p->id++) { + for (p->id = rng_int();;p->id++) { /* if there is a hashing conflict, resolve it */ player * pi = get_player(p->id); if (pi) p->id++; diff --git a/src/common/kernel/pool.c b/src/common/kernel/pool.c index 5d84b2920..69210b311 100644 --- a/src/common/kernel/pool.c +++ b/src/common/kernel/pool.c @@ -166,7 +166,7 @@ new_set_resvalue(unit * u, const resource_type * rtype, int value) } int -get_pooled(const unit * u, const resource_type * rtype, unsigned int mode) +get_pooled(const unit * u, const resource_type * rtype, unsigned int mode, int count) { const faction * f = u->faction; unit *v; @@ -186,7 +186,7 @@ get_pooled(const unit * u, const resource_type * rtype, unsigned int mode) else if (mode & GET_SLACK) use = slack; } if (rtype->flags & RTF_POOLED && mode & ~(GET_SLACK|GET_RESERVE)) { - for (v = r->units; v; v = v->next) if (u!=v) { + for (v = r->units; v && use<count; v = v->next) if (u!=v) { int mask; if (u==v) continue; @@ -202,7 +202,7 @@ get_pooled(const unit * u, const resource_type * rtype, unsigned int mode) } else if (alliedunit(v, f, HELP_MONEY)) mask = (mode >> 6) & (GET_SLACK|GET_RESERVE); else continue; - use += get_pooled(v, rtype, mask); + use += get_pooled(v, rtype, mask, count-use); } } return use; @@ -241,7 +241,7 @@ use_pooled(unit * u, const resource_type * rtype, unsigned int mode, int count) } if (rtype->flags & RTF_POOLED && mode & ~(GET_SLACK|GET_RESERVE)) { - for (v = r->units; v; v = v->next) if (u!=v) { + for (v = r->units; use>0 && v!=NULL; v = v->next) if (u!=v) { int mask; if (urace(v)->ec_flags & NOGIVE) continue; if (v->faction == f) { diff --git a/src/common/kernel/pool.h b/src/common/kernel/pool.h index 74ae04ca1..b9bbac38f 100644 --- a/src/common/kernel/pool.h +++ b/src/common/kernel/pool.h @@ -32,7 +32,7 @@ extern "C" { #define GET_DEFAULT (GET_RESERVE|GET_SLACK|GET_POOLED_SLACK) #define GET_ALL (GET_SLACK|GET_RESERVE|GET_POOLED_SLACK|GET_POOLED_RESERVE|GET_POOLED_FORCE) -int get_pooled(const struct unit * u, const struct resource_type * res, unsigned int mode); +int get_pooled(const struct unit * u, const struct resource_type * res, unsigned int mode, int count); int use_pooled(struct unit * u, const struct resource_type * res, unsigned int mode, int count); /** use_pooled * verbraucht 'count' Objekte der resource 'itm' diff --git a/src/common/kernel/race.c b/src/common/kernel/race.c index 1ac7a7607..75f73b87c 100644 --- a/src/common/kernel/race.c +++ b/src/common/kernel/race.c @@ -43,8 +43,9 @@ #include "unit.h" /* util includes */ -#include <attrib.h> -#include <functions.h> +#include <util/attrib.h> +#include <util/functions.h> +#include <util/rng.h> /* attrib includes */ #include <attributes/raceprefix.h> @@ -260,7 +261,7 @@ give_starting_equipment(struct unit *u) } break; case RC_CENTAUR: - rsethorses(r, 250+rand()%51+rand()%51); + rsethorses(r, 250+rng_int()%51+rng_int()%51); break; } u->hp = unit_max_hp(u); @@ -331,7 +332,7 @@ default_spoil(const struct race * rc, int size) { item * itm = NULL; - if (rand()%100 < RACESPOILCHANCE) { + if (rng_int()%100 < RACESPOILCHANCE) { char spoilname[32]; const item_type * itype; diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index 2f548a137..3de2be0ca 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -40,7 +40,8 @@ #include "unit.h" /* util includes */ -#include <resolve.h> +#include <util/resolve.h> +#include <util/rng.h> /* libc includes */ #include <assert.h> @@ -48,7 +49,6 @@ #include <limits.h> #include <rand.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> extern int dice_rand(const char *s); @@ -777,21 +777,21 @@ makename(void) nv = strlen(vokal); ns = strlen(start); - for (s = rand() % 3 + 2; s > 0; s--) { + for (s = rng_int() % 3 + 2; s > 0; s--) { if (x > 0) { - k = rand() % (int)nk; + k = rng_int() % (int)nk; name[p] = kons[k]; p++; } else { - k = rand() % (int)ns; + k = rng_int() % (int)ns; name[p] = start[k]; p++; } - v = rand() % (int)nv; + v = rng_int() % (int)nv; name[p] = vokal[v]; p++; - if (rand() % 3 == 2 || s == 1) { - e = rand() % (int)ne; + if (rng_int() % 3 == 2 || s == 1) { + e = rng_int() % (int)ne; name[p] = end[e]; p++; x = 1; @@ -815,7 +815,7 @@ setluxuries(region * r, const luxury_type * sale) for (ltype=luxurytypes; ltype; ltype=ltype->next) { struct demand * dmd = calloc(sizeof(struct demand), 1); dmd->type = ltype; - if (ltype!=sale) dmd->value = 1 + rand() % 5; + if (ltype!=sale) dmd->value = 1 + rng_int() % 5; dmd->next = r->land->demands; r->land->demands = dmd; } @@ -917,12 +917,12 @@ terraform_region(region * r, const terrain_type * terrain) if (!nb) { int i = get_maxluxuries(); if (i>0) { - i = rand() % i; + i = rng_int() % i; ltype = luxurytypes; while (i--) ltype=ltype->next; } } else { - int i = rand() % mnr; + int i = rng_int() % mnr; struct surround * srd = nb; while (i>srd->value) { i-=srd->value; @@ -947,19 +947,19 @@ terraform_region(region * r, const terrain_type * terrain) if (r->terrain->herbs) { int len=0; while (r->terrain->herbs[len]) ++len; - if (len) itype = r->terrain->herbs[rand()%len]; + if (len) itype = r->terrain->herbs[rng_int()%len]; } if (itype!=NULL) { rsetherbtype(r, itype); - rsetherbs(r, (short)(50+rand()%31)); + rsetherbs(r, (short)(50+rng_int()%31)); } else { rsetherbtype(r, NULL); } if (oldterrain==NULL || !fval(oldterrain, LAND_REGION)) { - if (rand() % 100 < 3) fset(r, RF_MALLORN); + if (rng_int() % 100 < 3) fset(r, RF_MALLORN); else freset(r, RF_MALLORN); - if (rand() % 100 < ENCCHANCE) { + if (rng_int() % 100 < ENCCHANCE) { fset(r, RF_ENCOUNTER); } } @@ -967,14 +967,14 @@ terraform_region(region * r, const terrain_type * terrain) if (oldterrain==NULL || terrain->size!=oldterrain->size) { if (terrain==newterrain(T_PLAIN)) { - rsethorses(r, rand() % (terrain->size / 50)); - if(rand()%100 < 40) { - rsettrees(r, 2, terrain->size * (30+rand()%40)/1000); + rsethorses(r, rng_int() % (terrain->size / 50)); + if(rng_int()%100 < 40) { + rsettrees(r, 2, terrain->size * (30+rng_int()%40)/1000); rsettrees(r, 1, rtrees(r, 2)/4); rsettrees(r, 0, rtrees(r, 2)/2); } } else if (chance(0.2)) { - rsettrees(r, 2, terrain->size * (30 + rand() % 40) / 1000); + rsettrees(r, 2, terrain->size * (30 + rng_int() % 40) / 1000); rsettrees(r, 1, rtrees(r, 2)/4); rsettrees(r, 0, rtrees(r, 2)/2); } @@ -983,7 +983,7 @@ terraform_region(region * r, const terrain_type * terrain) int peasants; peasants = (maxworkingpeasants(r) * (20+dice_rand("6d10")))/100; rsetpeasants(r, max(100, peasants)); - rsetmoney(r, rpeasants(r) * ((wage(r, NULL, NULL)+1) + rand() % 5)); + rsetmoney(r, rpeasants(r) * ((wage(r, NULL, NULL)+1) + rng_int() % 5)); } } } diff --git a/src/common/kernel/reports.c b/src/common/kernel/reports.c index 3742b9544..9e56c7889 100644 --- a/src/common/kernel/reports.c +++ b/src/common/kernel/reports.c @@ -913,62 +913,67 @@ spy_message(int spy, unit *u, unit *target) const struct unit * ucansee(const struct faction *f, const struct unit *u, const struct unit *x) { - if (cansee(f, u->region, u, 0)) return u; - return x; + if (cansee(f, u->region, u, 0)) return u; + return x; } static void get_addresses(report_context * ctx) { /* "TODO: travelthru" */ + seen_region * sr = NULL; region *r; const faction * lastf = NULL; faction_list * flist = calloc(1, sizeof(faction_list)); + flist->data = ctx->f; - for (r=ctx->first;r!=ctx->last;r=r->next) { + for (r=ctx->first;sr==NULL && r!=ctx->last;r=r->next) { + sr = find_seen(ctx->seen, r); + } + + for (;sr!=NULL;sr=sr->next) { + const region * r = sr->r; const unit * u = r->units; - const seen_region * sr = find_seen(ctx->seen, r); - - if (sr==NULL) continue; + while (u!=NULL) { - faction * sf = visible_faction(ctx->f, u); - boolean ballied = sf && sf!=ctx->f && sf!=lastf - && !fval(u, UFL_PARTEITARNUNG) && cansee(ctx->f, r, u, 0); - if (ballied || ALLIED(ctx->f, sf)) { - faction_list ** fnew = &flist; - while (*fnew && (*fnew)->data->no < sf->no) { - fnew =&(*fnew)->next; - } - if ((*fnew==NULL) || (*fnew)->data!=sf) { - faction_list * finsert = malloc(sizeof(faction_list)); - finsert->next = *fnew; - *fnew = finsert; - finsert->data = sf; - } - lastf = sf; - } - u = u->next; - } - } - + faction * sf = visible_faction(ctx->f, u); + boolean ballied = sf && sf!=ctx->f && sf!=lastf + && !fval(u, UFL_PARTEITARNUNG) && cansee(ctx->f, r, u, 0); + if (ballied || ALLIED(ctx->f, sf)) { + faction_list ** fnew = &flist; + while (*fnew && (*fnew)->data->no < sf->no) { + fnew =&(*fnew)->next; + } + if ((*fnew==NULL) || (*fnew)->data!=sf) { + faction_list * finsert = malloc(sizeof(faction_list)); + finsert->next = *fnew; + *fnew = finsert; + finsert->data = sf; + } + lastf = sf; + } + u = u->next; + } + } + if (ctx->f->alliance != NULL) { - faction *f2; - for(f2 = factions; f2; f2 = f2->next) { - if(f2->alliance != NULL && f2->alliance == ctx->f->alliance) { - faction_list ** fnew = &flist; - while (*fnew && (*fnew)->data->no < f2->no) { - fnew =&(*fnew)->next; - } - if ((*fnew==NULL) || (*fnew)->data!=f2) { - faction_list * finsert = malloc(sizeof(faction_list)); - finsert->next = *fnew; - *fnew = finsert; - finsert->data = f2; - } - } - } - } + faction *f2; + for(f2 = factions; f2; f2 = f2->next) { + if(f2->alliance != NULL && f2->alliance == ctx->f->alliance) { + faction_list ** fnew = &flist; + while (*fnew && (*fnew)->data->no < f2->no) { + fnew =&(*fnew)->next; + } + if ((*fnew==NULL) || (*fnew)->data!=f2) { + faction_list * finsert = malloc(sizeof(faction_list)); + finsert->next = *fnew; + *fnew = finsert; + finsert->data = f2; + } + } + } + } ctx->addresses = flist; } @@ -1006,6 +1011,30 @@ free_seen(void) } } +void +link_seen(seen_region * seehash[], const region * first, const region * last) +{ + const region * r = first; + seen_region * sr = NULL; + + if (first==last) return; + + do { + sr = find_seen(seehash, r); + r = r->next; + } while (sr==NULL && r!=last); + + while (r!=last) { + seen_region * sn = find_seen(seehash, r); + if (sn!=NULL) { + sr->next = sn; + sr = sn; + } + r = r->next; + } + sr->next = 0; +} + seen_region * find_seen(struct seen_region * seehash[], const region * r) { @@ -1036,6 +1065,7 @@ get_seen_interval(report_context * ctx) sr = sr->nextHash; } } + link_seen(ctx->seen, ctx->first, ctx->last); } boolean @@ -1059,10 +1089,10 @@ add_seen(struct seen_region * seehash[], struct region * r, unsigned char mode, } typedef struct report_type { - struct report_type * next; - report_fun write; - const char * extension; - int flag; + struct report_type * next; + report_fun write; + const char * extension; + int flag; } report_type; static report_type * report_types; diff --git a/src/common/kernel/reports.h b/src/common/kernel/reports.h index a36df2c87..63caade55 100644 --- a/src/common/kernel/reports.h +++ b/src/common/kernel/reports.h @@ -59,17 +59,18 @@ int hat_in_region(item_t itm, struct region * r, struct faction * f); /* f�r fast_region und neuen CR: */ enum { - see_none, - see_neighbour, - see_lighthouse, - see_travel, - see_far, - see_unit, - see_battle + see_none, + see_neighbour, + see_lighthouse, + see_travel, + see_far, + see_unit, + see_battle }; typedef struct seen_region { struct seen_region * nextHash; + struct seen_region * next; struct region *r; unsigned char mode; boolean disbelieves; @@ -80,14 +81,15 @@ extern boolean add_seen(struct seen_region * seehash[], struct region * r, unsig extern struct seen_region ** seen_init(void); extern void seen_done(struct seen_region * seehash[]); extern void free_seen(void); +extern void link_seen(seen_region * seehash[], const struct region * first, const struct region * last); extern const char * visibility[]; typedef struct report_context { - struct faction * f; - struct faction_list * addresses; - struct seen_region ** seen; + struct faction * f; + struct faction_list * addresses; + struct seen_region ** seen; struct region * first, * last; - void * userdata; + void * userdata; time_t report_time; } report_context; diff --git a/src/common/kernel/resources.c b/src/common/kernel/resources.c index 2dca79513..b06a91d97 100644 --- a/src/common/kernel/resources.c +++ b/src/common/kernel/resources.c @@ -21,6 +21,7 @@ #include "terrain.h" #include <util/rand.h> +#include <util/rng.h> #include <stdlib.h> #include <assert.h> @@ -97,7 +98,7 @@ static void terraform_default(struct rawmaterial * res, const region * r) { #define SHIFT 70 - double modifier = 1.0 + ((rand() % (SHIFT*2+1)) - SHIFT) * ((rand() % (SHIFT*2+1)) - SHIFT) / 10000.0; + double modifier = 1.0 + ((rng_int() % (SHIFT*2+1)) - SHIFT) * ((rng_int() % (SHIFT*2+1)) - SHIFT) / 10000.0; res->amount = (int)(res->amount*modifier); /* random adjustment, +/- 91% */ if (res->amount<1) res->amount=1; unused(r); @@ -108,7 +109,7 @@ static void resource_random_change(int *pvalue, boolean used) { int split = 5; - int rnd = rand()%100; + int rnd = rng_int()%100; if (pvalue==0 || rnd %10 >= 10) return; if (used) split = 4; @@ -147,7 +148,7 @@ use_default(rawmaterial *res, const region * r, int amount) assert(res->amount>0 && amount>=0 && amount <= res->amount); res->amount-=amount; while (res->amount==0) { - double modifier = 1.0 + ((rand() % (SHIFT*2+1)) - SHIFT) * ((rand() % (SHIFT*2+1)) - SHIFT) / 10000.0; + double modifier = 1.0 + ((rng_int() % (SHIFT*2+1)) - SHIFT) * ((rng_int() % (SHIFT*2+1)) - SHIFT) / 10000.0; int i; for (i=0;r->terrain->production[i].type;++i) { diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index 9b781fb05..3c9555ef4 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -52,14 +52,15 @@ #include <attributes/key.h> /* util includes */ -#include <attrib.h> -#include <base36.h> -#include <event.h> +#include <util/attrib.h> +#include <util/base36.h> +#include <util/event.h> #include <util/goodies.h> -#include <resolve.h> -#include <sql.h> -#include <rand.h> -#include <umlaut.h> +#include <util/resolve.h> +#include <util/sql.h> +#include <util/rand.h> +#include <util/rng.h> +#include <util/umlaut.h> /* libc includes */ #include <string.h> @@ -1505,7 +1506,7 @@ readfaction(FILE * F) if (global.data_version >= OVERRIDE_VERSION) { rds(F, &f->override); } else { - f->override = strdup(itoa36(rand())); + f->override = strdup(itoa36(rng_int())); } if (global.data_version < LOCALE_VERSION) { diff --git a/src/common/kernel/skill.c b/src/common/kernel/skill.c index c0346aad1..e70f5129c 100644 --- a/src/common/kernel/skill.c +++ b/src/common/kernel/skill.c @@ -35,6 +35,7 @@ #include <util/attrib.h> #include <util/goodies.h> +#include <util/rng.h> /* libc includes */ #include <assert.h> @@ -302,7 +303,7 @@ skill_weeks(int level) int coins = 2*level; int heads = 1; while (coins--) { - heads += rand() % 2; + heads += rng_int() % 2; } return heads; } diff --git a/src/common/kernel/teleport.c b/src/common/kernel/teleport.c index e1f7f482a..f1dccdd2d 100644 --- a/src/common/kernel/teleport.c +++ b/src/common/kernel/teleport.c @@ -33,11 +33,11 @@ #include "plane.h" /* util includes */ -#include <log.h> +#include <util/log.h> +#include <util/rng.h> /* libc includes */ #include <assert.h> -#include <stdlib.h> #define TE_CENTER_X 1000 #define TE_CENTER_Y 1000 @@ -142,7 +142,7 @@ spawn_braineaters(float chance) { region *r; faction *f0 = findfaction(MONSTER_FACTION); - int next = rand() % (int)(chance*100); + int next = rng_int() % (int)(chance*100); if (f0==NULL) return; @@ -151,13 +151,13 @@ spawn_braineaters(float chance) /* Neues Monster ? */ if (next-- == 0) { - unit *u = createunit(r, f0, 1+rand()%10+rand()%10, new_race[RC_HIRNTOETER]); + unit *u = createunit(r, f0, 1+rng_int()%10+rng_int()%10, new_race[RC_HIRNTOETER]); set_string(&u->name, "Hirnt�ter"); set_string(&u->display, "Wabernde gr�ne Schwaden treiben durch den Nebel und verdichten sich zu einer unheimlichen Kreatur, die nur aus einem langen Ruderschwanz und einem riesigen runden Maul zu bestehen scheint."); set_level(u, SK_STEALTH, 1); set_level(u, SK_OBSERVATION, 1); - next = rand() % (int)(chance*100); + next = rng_int() % (int)(chance*100); } } } diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index 539e93c94..8a826f51e 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -46,12 +46,12 @@ #include <util/event.h> #include <util/goodies.h> #include <util/resolve.h> +#include <util/rng.h> #include <util/variant.h> /* libc includes */ #include <assert.h> #include <limits.h> -#include <stdlib.h> #include <string.h> #include <math.h> @@ -227,7 +227,7 @@ destroy_unit(unit * u) * Items haben, sonst Memory-Leak. */ clone = has_clone(u); - if (clone && rand()%100 < 90) { + if (clone && rng_int()%100 < 90) { attrib *a; int i; @@ -955,7 +955,7 @@ boolean learn_skill(unit * u, skill_t sk, double chance) { skill * sv = u->skills; - if (chance < 1.0 && rand()%10000>=chance*10000) return false; + if (chance < 1.0 && rng_int()%10000>=chance*10000) return false; while (sv != u->skills + u->skill_size) { assert (sv->weeks>0); if (sv->id == sk) { diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h index fb1bfc215..879f3cf47 100644 --- a/src/common/kernel/unit.h +++ b/src/common/kernel/unit.h @@ -29,7 +29,7 @@ extern "C" { #endif struct skill; - +struct item; #define UFL_DEBUG (1<<0) #define UFL_ISNEW (1<<1) /* 2 */ #define UFL_LONGACTION (1<<2) /* 4 */ diff --git a/src/common/modules/arena.c b/src/common/modules/arena.c index eca6abc6b..898bb75d4 100644 --- a/src/common/modules/arena.c +++ b/src/common/modules/arena.c @@ -46,11 +46,12 @@ #include <kernel/unit.h> /* util include */ -#include <base36.h> -#include <resolve.h> -#include <functions.h> -#include <event.h> -#include <goodies.h> +#include <util/base36.h> +#include <util/event.h> +#include <util/functions.h> +#include <util/goodies.h> +#include <util/resolve.h> +#include <util/rng.h> /* libc include */ #include <assert.h> @@ -110,22 +111,22 @@ enter_fail(unit * u) { static int enter_arena(unit * u, const item_type * itype, int amount, order * ord) { - skill_t sk; - region * r = u->region; - unit * u2; - int fee = u->faction->score / 5; - unused(ord); - unused(amount); - unused(itype); - if (fee>2000) fee = 2000; - if (getplane(r)==arena) return -1; - if (u->number!=1 && enter_fail(u)) return -1; - if (get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT) < fee && enter_fail(u)) return -1; - for (sk=0;sk!=MAXSKILLS;++sk) { - if (get_level(u, sk)>1 && enter_fail(u)) return -1; - } - for (u2=r->units;u2;u2=u2->next) if (u2->faction==u->faction) break; - + skill_t sk; + region * r = u->region; + unit * u2; + int fee = u->faction->score / 5; + unused(ord); + unused(amount); + unused(itype); + if (fee>2000) fee = 2000; + if (getplane(r)==arena) return -1; + if (u->number!=1 && enter_fail(u)) return -1; + if (get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, fee) < fee && enter_fail(u)) return -1; + for (sk=0;sk!=MAXSKILLS;++sk) { + if (get_level(u, sk)>1 && enter_fail(u)) return -1; + } + for (u2=r->units;u2;u2=u2->next) if (u2->faction==u->faction) break; + assert(!"not implemented"); /* for (res=0;res!=MAXRESOURCES;++res) if (res!=R_SILVER && res!=R_ARENA_GATE && (is_item(res) || is_herb(res) || is_potion(res))) { @@ -139,18 +140,18 @@ enter_arena(unit * u, const item_type * itype, int amount, order * ord) } } */ - if (get_money(u) > fee) { - if (u2) change_money(u2, get_money(u) - fee); - else if (enter_fail(u)) return -1; - } - sprintf(buf, "In %s �ffnet sich ein Portal. Eine Stimme ert�nt, und spricht: 'Willkommen in der Ebene der Herausforderung'. %s durchschreitet das Tor zu einer anderen Welt.", regionname(u->region, u->faction), unitname(u)); - addmessage(NULL, u->faction, buf, MSG_MESSAGE, ML_IMPORTANT); - use_pooled(u, itype->rtype, GET_SLACK|GET_RESERVE, 1); + if (get_money(u) > fee) { + if (u2) change_money(u2, get_money(u) - fee); + else if (enter_fail(u)) return -1; + } + sprintf(buf, "In %s �ffnet sich ein Portal. Eine Stimme ert�nt, und spricht: 'Willkommen in der Ebene der Herausforderung'. %s durchschreitet das Tor zu einer anderen Welt.", regionname(u->region, u->faction), unitname(u)); + addmessage(NULL, u->faction, buf, MSG_MESSAGE, ML_IMPORTANT); + use_pooled(u, itype->rtype, GET_SLACK|GET_RESERVE, 1); use_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, fee); set_money(u, 109); - fset(u, UFL_PARTEITARNUNG); - move_unit(u, start_region[rand() % 6], NULL); - return 0; + fset(u, UFL_PARTEITARNUNG); + move_unit(u, start_region[rng_int() % 6], NULL); + return 0; } /*** @@ -169,7 +170,7 @@ use_wand_of_tears(unit * user, const struct item_type * itype, int amount, order int i; for (i=0;i!=u->skill_size;++i) { - if (rand()%3) reduce_skill(u, u->skills+i, 1); + if (rng_int()%3) reduce_skill(u, u->skills+i, 1); } ADDMSG(&u->faction->msgs, msg_message("wand_of_tears_effect", "unit", u)); @@ -301,8 +302,8 @@ guardian_faction(plane * pl, int id) if (!f) { f = calloc(1, sizeof(faction)); f->banner = strdup("Sie dienen dem gro�en Wyrm"); - f->passw = strdup(itoa36(rand())); - f->override = strdup(itoa36(rand())); + f->passw = strdup(itoa36(rng_int())); + f->override = strdup(itoa36(rng_int())); set_email(&f->email, "igjarjuk@eressea.de"); f->name = strdup("Igjarjuks Kundschafter"); f->race = new_race[RC_ILLUSION]; diff --git a/src/common/modules/autoseed.c b/src/common/modules/autoseed.c index 47d2a32cd..8bf848883 100644 --- a/src/common/modules/autoseed.c +++ b/src/common/modules/autoseed.c @@ -27,8 +27,8 @@ /* util includes */ #include <util/base36.h> -#include <util/sql.h> #include <util/goodies.h> +#include <util/rng.h> #include <util/sql.h> /* libc includes */ @@ -51,7 +51,7 @@ random_terrain(boolean distribution) } } - n = rand() % (distribution?ndistribution:nterrains); + n = rng_int() % (distribution?ndistribution:nterrains); for (terrain=terrains();terrain;terrain=terrain->next) { n -= distribution?terrain->distribution:1; if (n<0) break; @@ -152,7 +152,7 @@ fix_demand(region *r) for (i=maxlux;i!=2;++i) { int j; do { - int k = rand() % maxluxuries; + int k = rng_int() % maxluxuries; mlux[i] = ltypes[k]; for (j=0;j!=i;++j) { if (mlux[j]==mlux[i]) break; @@ -166,7 +166,7 @@ fix_demand(region *r) if (!fval(r, RF_CHAOTIC)) { log_warning(("fixing demand in %s\n", regionname(r, NULL))); } - sale = mlux[rand() % maxlux]; + sale = mlux[rng_int() % maxlux]; if (sale) setluxuries(r, sale); } while (rlist) { @@ -200,8 +200,8 @@ read_newfactions(const char * filename) sscanf(buf, "%s %s %s %d %d %s %d", email, race, lang, &bonus, &subscription, password, &alliance); if (email[0]=='\0') break; if (password[0]=='\0') { - strcpy(password, itoa36(rand())); - strcat(password, itoa36(rand())); + strcpy(password, itoa36(rng_int())); + strcat(password, itoa36(rng_int())); } for (f=factions;f;f=f->next) { if (strcmp(f->email, email)==0 && f->subscription && f->age<MINAGE_MULTI) break; @@ -578,7 +578,7 @@ autoseed(newfaction ** players, int nsize, boolean new_island) } while (rsize && (nsize || isize>=REGIONS_PER_FACTION)) { - int i = rand() % rsize; + int i = rng_int() % rsize; region_list ** rnext = &rlist; region_list * rfind; direction_t d; @@ -602,9 +602,9 @@ autoseed(newfaction ** players, int nsize, boolean new_island) ++rsize; } } - if (volcano_terrain!=NULL && (rand() % VOLCANO_CHANCE == 0)) { + if (volcano_terrain!=NULL && (rng_int() % VOLCANO_CHANCE == 0)) { terraform_region(r, volcano_terrain); - } else if (nsize && (rand() % isize == 0 || rsize==0)) { + } else if (nsize && (rng_int() % isize == 0 || rsize==0)) { newfaction ** nfp, * nextf = *players; faction * f; unit * u; @@ -692,7 +692,7 @@ autoseed(newfaction ** players, int nsize, boolean new_island) if (rn==NULL) { const struct terrain_type * terrain = newterrain(T_OCEAN); rn = new_region(r->x + delta_x[d], r->y + delta_y[d]); - if (rand() % SPECIALCHANCE < special) { + if (rng_int() % SPECIALCHANCE < special) { terrain = random_terrain(true); special = SPECIALCHANCE / 3; /* 33% chance auf noch eines */ } else { @@ -700,9 +700,9 @@ autoseed(newfaction ** players, int nsize, boolean new_island) } terraform_region(rn, terrain); /* the new region has an extra 15% chance to have laen */ - if (rand() % 100 < 15) rsetlaen(r, 5 + rand() % 5); + if (rng_int() % 100 < 15) rsetlaen(r, 5 + rng_int() % 5); /* the new region has an extra 20% chance to have mallorn */ - if (rand() % 100 < 20) fset(r, RF_MALLORN); + if (rng_int() % 100 < 20) fset(r, RF_MALLORN); add_regionlist(rend, rn); } } diff --git a/src/common/modules/dungeon.c b/src/common/modules/dungeon.c index d53901b15..9039ee6ac 100644 --- a/src/common/modules/dungeon.c +++ b/src/common/modules/dungeon.c @@ -106,7 +106,7 @@ make_dungeon(const dungeon * data) add_regionlist(&rlist, center); rnext = r = center; while (size>0 && iterations--) { - int d, o = rand() % 3; + int d, o = rng_int() % 3; for (d=0;d!=3;++d) { int index = (d+o) % 3; region * rn = findregion(r->x+nb[n][index][0], r->y+nb[n][index][1]); @@ -115,7 +115,7 @@ make_dungeon(const dungeon * data) if (rn->terrain==terrain_hell) { rnext = rn; } else if (fval(rn->terrain, SEA_REGION)) { - if (rand() % 100 < data->connect*100) { + if (rng_int() % 100 < data->connect*100) { terraform_region(rn, terrain_hell); --size; rnext = rn; @@ -143,11 +143,11 @@ make_dungeon(const dungeon * data) monster * m = data->monsters; region * r = iregion->data; while (m) { - if ((rand() % 100) < (m->chance * 100)) { + if ((rng_int() % 100) < (m->chance * 100)) { /* TODO: check maxunits. */ treasure * loot = m->treasures; struct itemtype_list * weapon = m->weapons; - int size = 1 + (rand() % m->avgsize) + (rand() % m->avgsize); + int size = 1 + (rng_int() % m->avgsize) + (rng_int() % m->avgsize); unit * u = createunit(r, fmonsters, size, m->race); while (weapon) { i_change(&u->items, weapon->type, size); diff --git a/src/common/modules/gmcmd.c b/src/common/modules/gmcmd.c index 41d0759df..11b544561 100644 --- a/src/common/modules/gmcmd.c +++ b/src/common/modules/gmcmd.c @@ -40,6 +40,7 @@ #include <util/event.h> #include <util/goodies.h> #include <util/umlaut.h> +#include <util/rng.h> /* libc includes */ #include <stdlib.h> @@ -628,9 +629,9 @@ gm_addquest(const char * email, const char * name, short radius, unsigned int fl /* GM faction */ a_add(&f->attribs, make_key(atoi36("quest"))); f->banner = strdup("Questenpartei"); - f->passw = strdup(itoa36(rand())); - f->override = strdup(itoa36(rand())); - f->override = strdup(itoa36(rand())); + f->passw = strdup(itoa36(rng_int())); + f->override = strdup(itoa36(rng_int())); + f->override = strdup(itoa36(rng_int())); if (set_email(&f->email, email)!=0) { log_error(("Invalid email address for faction %s: %s\n", itoa36(f->no), email)); } @@ -655,8 +656,8 @@ gm_addquest(const char * email, const char * name, short radius, unsigned int fl /* GM playfield */ do { - minx = (short)((rand() % (2*EXTENSION)) - EXTENSION); - miny = (short)((rand() % (2*EXTENSION)) - EXTENSION); + minx = (short)((rng_int() % (2*EXTENSION)) - EXTENSION); + miny = (short)((rng_int() % (2*EXTENSION)) - EXTENSION); for (x=0;!invalid && x<=radius*2;++x) { short y; for (y=0;!invalid && y<=radius*2;++y) { @@ -667,7 +668,7 @@ gm_addquest(const char * email, const char * name, short radius, unsigned int fl } while (invalid); maxx = minx+2*radius; cx = minx+radius; maxy = miny+2*radius; cy = miny+radius; - p = create_new_plane(rand(), name, minx, maxx, miny, maxy, flags); + p = create_new_plane(rng_int(), name, minx, maxx, miny, maxy, flags); center = new_region(cx, cy); for (x=0;x<=2*radius;++x) { short y; @@ -735,7 +736,7 @@ gm_addfaction(const char * email, plane * p, region * r) /* GM faction */ add_key(&f->attribs, atoi36("quest")); f->banner = strdup("Questenpartei"); - f->passw = strdup(itoa36(rand())); + f->passw = strdup(itoa36(rng_int())); if (set_email(&f->email, email)!=0) { log_error(("Invalid email address for faction %s: %s\n", itoa36(f->no), email)); } @@ -798,8 +799,8 @@ gm_addplane(short radius, unsigned int flags, const char * name) /* GM playfield */ do { - minx = (short)(rand() % (2*EXTENSION)) - EXTENSION; - miny = (short)(rand() % (2*EXTENSION)) - EXTENSION; + minx = (short)(rng_int() % (2*EXTENSION)) - EXTENSION; + miny = (short)(rng_int() % (2*EXTENSION)) - EXTENSION; for (x=0;!invalid && x<=radius*2;++x) { short y; for (y=0;!invalid && y<=radius*2;++y) { @@ -810,7 +811,7 @@ gm_addplane(short radius, unsigned int flags, const char * name) } while (invalid); maxx = minx+2*radius; cx = minx+radius; maxy = miny+2*radius; cy = miny+radius; - p = create_new_plane(rand(), name, minx, maxx, miny, maxy, flags); + p = create_new_plane(rng_int(), name, minx, maxx, miny, maxy, flags); center = new_region(cx, cy); for (x=0;x<=2*radius;++x) { short y; diff --git a/src/common/modules/weather.c b/src/common/modules/weather.c index 902f45de1..426354138 100644 --- a/src/common/modules/weather.c +++ b/src/common/modules/weather.c @@ -42,12 +42,12 @@ create_weather(region *r, weather_t type) w->center[0] = r->x; w->center[1] = r->y; w->type = type; - w->move[0] = (rand()%3) - 1; - w->move[1] = (rand()%3) - 1; + w->move[0] = (rng_int()%3) - 1; + w->move[1] = (rng_int()%3) - 1; switch(type) { case WEATHER_STORM: - w->radius = rand()%2+1; + w->radius = rng_int()%2+1; break; case WEATHER_HURRICANE: w->radius = 1; @@ -128,7 +128,7 @@ move_weather(void) w->center[0] = w->center[0] + w->move[0]; w->center[1] = w->center[1] + w->move[1]; r = findregion(w->center[0], w->center[1]); - if(!r || rand()%100 < 5) { + if(!r || rng_int()%100 < 5) { removelist(&weathers, w); } w = wnext; diff --git a/src/common/modules/wormhole.c b/src/common/modules/wormhole.c index 16cb37448..b272e1790 100644 --- a/src/common/modules/wormhole.c +++ b/src/common/modules/wormhole.c @@ -26,6 +26,7 @@ /* util includes */ #include <util/attrib.h> +#include <util/rng.h> /* libc includes */ #include <assert.h> @@ -159,7 +160,7 @@ create_wormholes(void) * select a list of regions. we'll sort them by age later. */ while (r!=NULL) { - int next = rand() % (2*WORMHOLE_CHANCE); + int next = rng_int() % (2*WORMHOLE_CHANCE); while (r!=NULL && (next!=0 || !good_region(r))) { if (good_region(r)) { --next; diff --git a/src/common/races/dragons.c b/src/common/races/dragons.c index a27692c56..ad3a9a39d 100644 --- a/src/common/races/dragons.c +++ b/src/common/races/dragons.c @@ -20,8 +20,8 @@ #include <region.h> #include <unit.h> -/* libc includes */ -#include <stdlib.h> +/* util includes */ +#include <util/rng.h> #define age_chance(a,b,p) (max(0,a-b)*p) @@ -31,7 +31,7 @@ void age_firedragon(unit *u) { - if (rand()%100 < age_chance(u->age, DRAGONAGE, 1)) { + if (rng_int()%100 < age_chance(u->age, DRAGONAGE, 1)) { double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); u->race = new_race[RC_DRAGON]; u->irace = new_race[RC_DRAGON]; @@ -43,7 +43,7 @@ age_firedragon(unit *u) void age_dragon(unit *u) { - if (rand()%100 < age_chance(u->age, WYRMAGE, 1)) { + if (rng_int()%100 < age_chance(u->age, WYRMAGE, 1)) { double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); u->race = new_race[RC_WYRM]; u->irace = new_race[RC_WYRM]; diff --git a/src/common/races/zombies.c b/src/common/races/zombies.c index 956554650..c14f02837 100644 --- a/src/common/races/zombies.c +++ b/src/common/races/zombies.c @@ -17,16 +17,19 @@ #include "zombies.h" /* kernel includes */ -#include <unit.h> -#include <faction.h> -#include <region.h> +#include <kernel/unit.h> +#include <kernel/faction.h> +#include <kernel/region.h> + +/* util iclude */ +#include <util/rng.h> /* libc includes */ #include <stdlib.h> #define UNDEAD_MIN 90 /* mind. zahl vor weg gehen */ #define UNDEAD_BREAKUP 25 /* chance dafuer */ -#define UNDEAD_BREAKUP_FRACTION (25+rand()%70) /* anteil der weg geht */ +#define UNDEAD_BREAKUP_FRACTION (25+rng_int()%70) /* anteil der weg geht */ #define age_chance(a,b,p) (max(0,a-b)*p) @@ -45,14 +48,14 @@ age_undead(unit *u) for (m=0;m!=100;++m) { int d = k/(100-m); k-=d; - if (rand() % 100 < UNDEAD_REPRODUCTION) + if (rng_int() % 100 < UNDEAD_REPRODUCTION) n+=d; } assert(k==0); } else #endif for (m = u->number; m; m--) - if (rand() % 100 < UNDEAD_REPRODUCTION) + if (rng_int() % 100 < UNDEAD_REPRODUCTION) n++; set_number(u, u->number + n); u->hp += n * unit_max_hp(u); @@ -65,13 +68,13 @@ age_undead(unit *u) * absplitten, anstatt sich zu vermehren. monster * untote vermehren sich nur noch */ - if (u->number > UNDEAD_MIN && u->faction->no != MONSTER_FACTION && rand() % 100 < UNDEAD_BREAKUP) { + if (u->number > UNDEAD_MIN && u->faction->no != MONSTER_FACTION && rng_int() % 100 < UNDEAD_BREAKUP) { int m; unit *u2; n = 0; for (m = u->number; m; m--) - if (rand() % 100 < UNDEAD_BREAKUP_FRACTION) + if (rng_int() % 100 < UNDEAD_BREAKUP_FRACTION) n++; u2 = create_unit(r, findfaction(MONSTER_FACTION), 0, new_race[RC_UNDEAD], 0, NULL, u); make_undead_unit(u2); @@ -82,7 +85,7 @@ age_undead(unit *u) void age_skeleton(unit *u) { - if (u->faction->no == 0 && rand()%100 < age_chance(u->age, 27, 1)) { + if (u->faction->no == 0 && rng_int()%100 < age_chance(u->age, 27, 1)) { int n = max(1,u->number/2); double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); u->race = new_race[RC_SKELETON_LORD]; @@ -95,7 +98,7 @@ age_skeleton(unit *u) void age_zombie(unit *u) { - if (u->faction->no == 0 && rand()%100 < age_chance(u->age, 27, 1)) { + if (u->faction->no == 0 && rng_int()%100 < age_chance(u->age, 27, 1)) { int n = max(1,u->number/2); double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); u->race = new_race[RC_ZOMBIE_LORD]; @@ -108,7 +111,7 @@ age_zombie(unit *u) void age_ghoul(unit *u) { - if (u->faction->no == 0 && rand()%100 < age_chance(u->age, 27, 1)) { + if (u->faction->no == 0 && rng_int()%100 < age_chance(u->age, 27, 1)) { int n = max(1,u->number/2); double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); u->race = new_race[RC_GHOUL_LORD]; diff --git a/src/common/spells/combatspells.c b/src/common/spells/combatspells.c index 4c5dcbde6..c8655b2a1 100644 --- a/src/common/spells/combatspells.c +++ b/src/common/spells/combatspells.c @@ -31,12 +31,12 @@ #include <kernel/skill.h> /* util includes */ -#include <rand.h> -#include <base36.h> +#include <util/base36.h> +#include <util/rand.h> +#include <util/rng.h> /* libc includes */ #include <assert.h> -#include <stdlib.h> #define EFFECT_HEALING_SPELL 5 @@ -426,7 +426,7 @@ select_ally_in_row(fighter * af, int minrow, int maxrow) if (!allies) return dt; - allies = rand() % allies; + allies = rng_int() % allies; cv_foreach(df, b->fighters) { side *ds = df->side; @@ -501,7 +501,7 @@ random_skill(unit *u) if(n == 0) return NOSKILL; - n = rand()%n; + n = rng_int()%n; for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { if (sv->level>0) { @@ -548,7 +548,7 @@ sp_mindblast(fighter * fi, int level, double power, spell * sp) sk = random_skill(du); if (sk != NOSKILL) { skill * sv = get_skill(du, sk); - int n = 1 + rand() % 3; + int n = 1 + rng_int() % 3; /* Skill abziehen */ reduce_skill(du, sv, n); } else { @@ -755,7 +755,7 @@ sp_shadowcall(fighter * fi, int level, double power, spell * sp) int force = (int)(get_force(power, 3)/2); unit *u; const char * races[3] = { "shadowbat", "nightmare", "vampunicorn" }; - const race *rc = rc_find(races[rand()%3]); + const race *rc = rc_find(races[rng_int()%3]); unused(sp); @@ -928,7 +928,7 @@ sp_chaosrow(fighter * fi, int level, double power, spell * sp) if (df->unit->race->battle_flags & BF_NOBLOCK) { df->side->nonblockers[row] -= df->alive; } - row = FIRST_ROW + (rand()%(LAST_ROW-FIRST_ROW)); + row = FIRST_ROW + (rng_int()%(LAST_ROW-FIRST_ROW)); switch (row) { case FIGHT_ROW: df->status = ST_FIGHT; diff --git a/src/common/spells/spells.c b/src/common/spells/spells.c index 177c17775..37560096b 100644 --- a/src/common/spells/spells.c +++ b/src/common/spells/spells.c @@ -65,13 +65,13 @@ extern void ct_register(const struct curse_type * ct); #include <util/variant.h> #include <util/goodies.h> #include <util/resolve.h> +#include <util/rng.h> /* libc includes */ #include <assert.h> #include <ctype.h> #include <math.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> #include <limits.h> @@ -134,7 +134,7 @@ magicanalyse_region(region *r, unit *mage, double force) /* ist der curse schw�cher als der Analysezauber, so ergibt sich * mehr als 100% probability und damit immer ein Erfolg. */ probability = curse_chance(c, force); - mon = c->duration + (rand()%10) - 5; + mon = c->duration + (rng_int()%10) - 5; mon = max(1, mon); found = true; @@ -176,7 +176,7 @@ magicanalyse_unit(unit *u, unit *mage, double force) /* ist der curse schw�cher als der Analysezauber, so ergibt sich * mehr als 100% probability und damit immer ein Erfolg. */ probability = curse_chance(c, force); - mon = c->duration + (rand()%10) - 5; + mon = c->duration + (rng_int()%10) - 5; mon = max(1,mon); if (chance(probability)) { /* Analyse gegl�ckt */ @@ -218,7 +218,7 @@ magicanalyse_building(building *b, unit *mage, double force) /* ist der curse schw�cher als der Analysezauber, so ergibt sich * mehr als 100% probability und damit immer ein Erfolg. */ probability = curse_chance(c, force); - mon = c->duration + (rand()%10) - 5; + mon = c->duration + (rng_int()%10) - 5; mon = max(1,mon); if (chance(probability)) { /* Analyse gegl�ckt */ @@ -260,7 +260,7 @@ magicanalyse_ship(ship *sh, unit *mage, double force) /* ist der curse schw�cher als der Analysezauber, so ergibt sich * mehr als 100% probability und damit immer ein Erfolg. */ probability = curse_chance(c, force); - mon = c->duration + (rand()%10) - 5; + mon = c->duration + (rng_int()%10) - 5; mon = max(1,mon); if (chance(probability)) { /* Analyse gegl�ckt */ @@ -478,7 +478,7 @@ static const race * select_familiar(const race * magerace, magic_t magiegebiet) { const race * retval = NULL; - int rnd = rand()%100; + int rnd = rng_int()%100; assert(magerace->familiars[0]); if (rnd < 3) { @@ -486,7 +486,7 @@ select_familiar(const race * magerace, magic_t magiegebiet) unsigned int maxlen = listlen(familiarraces); if (maxlen>0) { race_list * rclist = familiarraces; - int index = rand()%maxlen; + int index = rng_int()%maxlen; while (index-->0) { rclist = rclist->next; } @@ -562,7 +562,7 @@ sp_summon_familiar(castorder *co) } /* In welcher benachbarten Ozeanregion soll der Familiar erscheinen? */ - coasts = rand()%coasts; + coasts = rng_int()%coasts; dh = -1; for(d=0; d<MAXDIRECTIONS; d++) { region * rn = rconnect(r,d); @@ -1294,7 +1294,7 @@ sp_rosthauch(castorder *co) #endif } - force = rand()%((int)(force * 10)) + force; + force = rng_int()%((int)(force * 10)) + force; /* fuer jede Einheit */ for (n = 0; n < pa->length; n++) { @@ -1448,7 +1448,7 @@ sp_sparkle(castorder *co) if(pa->param[0]->flag == TARGET_RESISTS) return cast_level; u = pa->param[0]->data.u; - effect.i = rand(); + effect.i = rng_int(); create_curse(mage, &u->attribs, ct_find("sparkle"), cast_level, duration, effect, u->number); @@ -1645,7 +1645,7 @@ sp_great_drought(castorder *co) create_curse(mage, &r->attribs, ct_find("drought"), force, duration, effect, 0); /* terraforming */ - if (rand() % 100 < 25){ + if (rng_int() % 100 < 25){ terraform = true; switch(rterrain(r)) { @@ -1665,7 +1665,7 @@ sp_great_drought(castorder *co) break; */ case T_GLACIER: - if (rand() % 100 < 50){ + if (rng_int() % 100 < 50){ rsetterrain(r, T_SWAMP); destroy_all_roads(r); } else { /* Ozean */ @@ -2414,7 +2414,7 @@ patzer_peasantmob(castorder *co) faction * f = findfaction(MONSTER_FACTION); const struct locale * lang = f->locale; - anteil += rand() % 4; + anteil += rng_int() % 4; n = rpeasants(r) * anteil / 10; rsetpeasants(r, rpeasants(r) - n); assert(rpeasants(r) >= 0); @@ -2474,7 +2474,7 @@ sp_forest_fire(castorder *co) unit *mage = co->magician.u; int cast_level = co->level; double probability; - double percentage = (rand() % 8 + 1) * 0.1; /* 10 - 80% */ + double percentage = (rng_int() % 8 + 1) * 0.1; /* 10 - 80% */ int vernichtet_schoesslinge = (int)(rtrees(r, 1) * percentage); int destroyed = (int)(rtrees(r, 2) * percentage); @@ -2578,7 +2578,7 @@ sp_fumblecurse(castorder *co) target = pa->param[0]->data.u; - rx = rand()%3; + rx = rng_int()%3; sx = cast_level - effskill(target, SK_MAGIC); duration = max(sx, rx) + 1; @@ -2660,8 +2660,8 @@ sp_summondragon(castorder *co) } for(time = 1; time < 7; time++){ - if (rand()%100 < 25){ - switch(rand()%3){ + if (rng_int()%100 < 25){ + switch(rng_int()%3){ case 0: race = new_race[RC_WYRM]; number = 1; @@ -3007,7 +3007,7 @@ wisps_move(const border * b, struct unit * u, struct region * from, struct regio /* pick left and right region: */ region * rl = rconnect(from, (direction_t)((reldir+MAXDIRECTIONS-1)%MAXDIRECTIONS)); region * rr = rconnect(from, (direction_t)((reldir+1)%MAXDIRECTIONS)); - int j = rand() % 3; + int j = rng_int() % 3; if (j==1 && rl && fval(rl->terrain, LAND_REGION)==fval(next, LAND_REGION)) return rl; if (j==2 && rr && fval(rr->terrain, LAND_REGION)==fval(next, LAND_REGION)) return rr; } @@ -3318,7 +3318,7 @@ patzer_deathcloud(castorder *co) unit *mage = co->magician.u; int hp = (mage->hp - 2); - change_hitpoints(mage, -rand()%hp); + change_hitpoints(mage, -rng_int()%hp); ADDMSG(&mage->faction->msgs, msg_message( "magic_fumble", "unit region command", @@ -3953,7 +3953,7 @@ sp_charmingsong(castorder *co) return 0; } - duration = 3 + rand()%(int)force; + duration = 3 + rng_int()%(int)force; { trigger * trestore = trigger_changefaction(target, target->faction); /* l�uft die Dauer ab, setze Partei zur�ck */ @@ -4137,7 +4137,7 @@ sp_raisepeasantmob(castorder *co) double force = co->force; int duration = (int)force+1; - anteil.i = 6 + (rand()%4); + anteil.i = 6 + (rng_int()%4); n = rpeasants(r) * anteil.i / 10; n = max(0, n); @@ -4609,7 +4609,7 @@ sp_seduce(castorder *co) item * itm = *itmp; loot = itm->number/2; if (itm->number % 2) { - loot += rand() % 2; + loot += rng_int() % 2; } if (loot > 0) { loot = (int)min(loot, force * 5); @@ -4730,7 +4730,7 @@ sp_headache(castorder *co) } if (smax!=NULL) { /* wirkt auf maximal 10 Personen */ - int change = min(10, target->number) * (rand()%2+1) / target->number; + int change = min(10, target->number) * (rng_int()%2+1) / target->number; reduce_skill(target, smax, change); } set_order(&target->thisorder, NULL); @@ -4991,9 +4991,9 @@ sp_icastle(castorder *co) /* Gr��e festlegen. */ if (type == bt_find("illusion")) { - b->size = (rand()%(int)((power*power)+1)*10); + b->size = (rng_int()%(int)((power*power)+1)*10); } else if (type->maxsize == -1) { - b->size = ((rand()%(int)(power))+1)*5; + b->size = ((rng_int()%(int)(power))+1)*5; } else { b->size = type->maxsize; } @@ -5005,7 +5005,7 @@ sp_icastle(castorder *co) data = (icastle_data*)a->data.v; data->type = type; data->building = b; - data->time = 2+(rand()%(int)(power)+1)*(rand()%(int)(power)+1); + data->time = 2+(rng_int()%(int)(power)+1)*(rng_int()%(int)(power)+1); if(mage->region == r) { leave(r, mage); @@ -5211,7 +5211,7 @@ sp_baddreams(castorder *co) /* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken, * also duration+2 */ duration = (int)max(1, power/2); /* Stufe 1 macht sonst mist */ - duration = 2 + rand()%duration; + duration = 2 + rng_int()%duration; /* Nichts machen als ein entsprechendes Attribut in die Region legen. */ effect.i = -1; @@ -5252,7 +5252,7 @@ sp_gooddreams(castorder *co) /* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken, * also duration+2 */ duration = (int)max(1, power/2); /* Stufe 1 macht sonst mist */ - duration = 2 + rand()%duration; + duration = 2 + rng_int()%duration; effect.i = 1; c = create_curse(mage, &r->attribs, ct_find("gbdream"), power, duration, effect, 0); curse_setflag(c, CURSE_ISNEW); @@ -6304,7 +6304,7 @@ sp_disruptastral(castorder *co) if (u->race != new_race[RC_SPELL]) { region_list *trl2 = trl; region *tr; - int c = rand() % inhab_regions; + int c = rng_int() % inhab_regions; /* Zuf�llige Zielregion suchen */ while (c--!=0) trl2 = trl2->next; @@ -6507,7 +6507,7 @@ sp_movecastle(castorder *co) bunhash(b); translist(&r->buildings, &target_region->buildings, b); b->region = target_region; - b->size -= b->size/(10-rand()%6); + b->size -= b->size/(10-rng_int()%6); bhash(b); for(u=r->units;u;) { @@ -6642,7 +6642,7 @@ sp_stealaura(castorder *co) return 0; } - taura = (get_mage(u)->spellpoints*(rand()%(int)(3*power)+1))/100; + taura = (get_mage(u)->spellpoints*(rng_int()%(int)(3*power)+1))/100; if(taura > 0) { get_mage(u)->spellpoints -= taura; @@ -6725,7 +6725,7 @@ sp_antimagiczone(castorder *co) * * Wirkung: * Gibt Geb�uden einen Bonus auf Magieresistenz von +20%. Der Zauber - * dauert 3+rand()%Level Wochen an, also im Extremfall bis zu 2 Jahre + * dauert 3+rng_int()%Level Wochen an, also im Extremfall bis zu 2 Jahre * bei Stufe 20 * * Es k�nnen mehrere Zauber �bereinander gelegt werden, der Effekt @@ -6734,7 +6734,7 @@ sp_antimagiczone(castorder *co) * oder: * * Gibt Schiffen einen Bonus auf Magieresistenz von +20%. Der Zauber - * dauert 3+rand()%Level Wochen an, also im Extremfall bis zu 2 Jahre + * dauert 3+rng_int()%Level Wochen an, also im Extremfall bis zu 2 Jahre * bei Stufe 20 * * Es k�nnen mehrere Zauber �bereinander gelegt werden, der Effekt @@ -6759,7 +6759,7 @@ sp_magicrunes(castorder *co) spellparameter *pa = co->par; variant effect; - duration = 3 + rand()%cast_level; + duration = 3 + rng_int()%cast_level; effect.i = 20; switch(pa->param[0]->typ){ @@ -7116,7 +7116,7 @@ sp_wdwpyramid(castorder *co) assert(mindist >= 1); - minshowdist = mindist - rand()%5; + minshowdist = mindist - rng_int()%5; maxshowdist = minshowdist + 4; ADDMSG(&mage->faction->msgs, msg_message("wdw_pyramidspell_notfound", diff --git a/src/common/util/Jamfile b/src/common/util/Jamfile index 6d30d656f..26cc6f234 100644 --- a/src/common/util/Jamfile +++ b/src/common/util/Jamfile @@ -37,6 +37,8 @@ SOURCES = xml.c ; +SOURCES += mt19937ar.c ; + if $(MSPACES) { SOURCES += <dl>malloc.c ; } diff --git a/src/common/util/cvector.c b/src/common/util/cvector.c index 500f8d0de..bbf037883 100644 --- a/src/common/util/cvector.c +++ b/src/common/util/cvector.c @@ -19,12 +19,13 @@ * permission from the authors. */ +#include <config.h> +#include "cvector.h" +#include "rng.h" + #include <stdlib.h> #include <assert.h> #include <limits.h> -#include <config.h> -#include "cvector.h" -#include "memory.h" void cv_init(cvector * cv) @@ -114,7 +115,7 @@ __cv_scramble(void *v1, size_t n, size_t width) v = (void *) realloc(v, s); } for (i = 0; i != n; i++) { - *(long *) addptr(v, i * (width + 4)) = rand(); + *(long *) addptr(v, i * (width + 4)) = rng_int(); memcpy(addptr(v, i * (width + 4) + 4), addptr(v1, i * width), width); } diff --git a/src/common/util/dice.c b/src/common/util/dice.c index b1d82396c..4050f3aba 100644 --- a/src/common/util/dice.c +++ b/src/common/util/dice.c @@ -18,6 +18,7 @@ */ #include <config.h> +#include "rng.h" #include <assert.h> #include <stdlib.h> @@ -33,10 +34,10 @@ dice(int count, int value) if (value<=0) return 0; /* (enno) %0 geht nicht. echt wahr. */ if (count >= 0) for (c = count; c > 0; c--) - d += rand() % value + 1; + d += rng_int() % value + 1; else for (c = count; c < 0; c++) - d -= rand() % value + 1; + d -= rng_int() % value + 1; return d; } @@ -58,7 +59,7 @@ term_eval(const char **sptr) else if (state==2) { /* dDk */ int i; if (k == 0) k = 6; /* 3d == 3d6 */ - for (i=0;i!=d;++i) m += (1 + rand() % k)*multi; + for (i=0;i!=d;++i) m += (1 + rng_int() % k)*multi; } else assert(!"dice_rand: illegal token"); if (*c=='*') { diff --git a/src/common/util/mt19937ar.c b/src/common/util/mt19937ar.c new file mode 100644 index 000000000..4fbd3f70d --- /dev/null +++ b/src/common/util/mt19937ar.c @@ -0,0 +1,172 @@ +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using init_genrand(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) +*/ + +#include <stdio.h> + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializes mt[N] with a seed */ +void init_genrand(unsigned long s) +{ + mt[0]= s & 0xffffffffUL; + for (mti=1; mti<N; mti++) { + mt[mti] = + (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +/* slight change for C++, 2004/2/26 */ +void init_by_array(unsigned long init_key[], int key_length) +{ + int i, j, k; + init_genrand(19650218UL); + i=1; j=0; + k = (N>key_length ? N : key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + + init_key[j] + j; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=N-1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) + - i; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + } + + mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long genrand_int32(void) +{ + unsigned long y; + static unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + if (mti == N+1) /* if init_genrand() has not been called, */ + init_genrand(5489UL); /* a default initial seed is used */ + + for (kk=0;kk<N-M;kk++) { + y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); + mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL]; + } + for (;kk<N-1;kk++) { + y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); + mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +/* generates a random number on [0,0x7fffffff]-interval */ +long genrand_int31(void) +{ + return (long)(genrand_int32()>>1); +} + +/* generates a random number on [0,1]-real-interval */ +double genrand_real1(void) +{ + return genrand_int32()*(1.0/4294967295.0); + /* divided by 2^32-1 */ +} + +/* generates a random number on [0,1)-real-interval */ +double genrand_real2(void) +{ + return genrand_int32()*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on (0,1)-real-interval */ +double genrand_real3(void) +{ + return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/* generates a random number on [0,1) with 53-bit resolution*/ +double genrand_res53(void) +{ + unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; + return(a*67108864.0+b)*(1.0/9007199254740992.0); +} +/* These real versions are due to Isaku Wada, 2002/01/09 added */ diff --git a/src/common/util/rand.c b/src/common/util/rand.c index eec3b3372..4ef75e534 100644 --- a/src/common/util/rand.c +++ b/src/common/util/rand.c @@ -21,15 +21,14 @@ #include <config.h> #include "rand.h" +#include "rng.h" -#include <stdlib.h> #include <assert.h> #include <string.h> #include <math.h> #include <float.h> #include <ctype.h> -#define drand() ((rand()%RAND_MAX)/(double)RAND_MAX) #define M_PIl 3.1415926535897932384626433832795029L /* pi */ /* NormalRand aus python, random.py geklaut, dort ist Referenz auf @@ -40,8 +39,8 @@ normalvariate(double mu, double sigma) static double NV_MAGICCONST = 1.7155277699214135; double z; for (;;) { - double u1 = drand(); - double u2 = 1.0 - drand(); + double u1 = rng_double(); + double u2 = 1.0 - rng_double(); z = NV_MAGICCONST*(u1-0.5)/u2; if (z*z/4.0 <= -log(u2)) { break; @@ -57,7 +56,7 @@ ntimespprob(int n, double p, double mod) int i; for(i=0; i<n && p>0; i++) { - if(drand() < p) { + if(rng_double() < p) { count++; p += mod; } @@ -69,6 +68,6 @@ boolean chance(double x) { if (x>=1.0) return true; - return (boolean) (rand() % RAND_MAX < RAND_MAX * x); + return rng_double() < x; } diff --git a/src/common/util/rng.h b/src/common/util/rng.h new file mode 100644 index 000000000..7dbc81039 --- /dev/null +++ b/src/common/util/rng.h @@ -0,0 +1,45 @@ +/* vi: set ts=2: + * +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de> + * | | Enno Rehling <enno@eressea.de> + * | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de> + * | (c) 1998 - 2005 | + * | | This program may not be used, modified or distributed + * +-------------------+ without prior permission by the authors of Eressea. + * + */ +#ifndef UTIL_RNG_H +#define UTIL_RNG_H +#ifdef __cplusplus +extern "C" { +#endif + +#define RNG_MT + +#ifdef RNG_MT + /* initializes mt[N] with a seed */ + extern void init_genrand(unsigned long s); + + /* generates a random number on [0,0xffffffff]-interval */ + extern unsigned long genrand_int32(void); + + /* generates a random number on [0,1]-real-interval */ + extern double genrand_real1(void); + + /* generates a random number on [0,0x7fffffff]-interval */ + long genrand_int31(void); + +# define rng_init(seed) init_genrand(seed) +# define rng_int() genrand_int31() +# define rng_double() genrand_real1() +# define RNG_RAND_MAX 0x7fffffff +#else +# include <stdlib.h> +# define rng_init(seed) srand(seed) +# define rng_int() rand() +# define rng_double() ((rand()%RAND_MAX)/(double)RAND_MAX) +# define RNG_RAND_MAX RAND_MAX +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/eressea/lua/eressea.cpp b/src/eressea/lua/eressea.cpp index 37b9695a4..e21cf5c22 100644 --- a/src/eressea/lua/eressea.cpp +++ b/src/eressea/lua/eressea.cpp @@ -35,6 +35,7 @@ #include <util/language.h> #include <util/base36.h> #include <util/rand.h> +#include <util/rng.h> #include <cstring> #include <ctime> @@ -154,8 +155,8 @@ lua_planmonsters(void) faction * f = findfaction(MONSTER_FACTION); if (f==NULL) return; - if (turn == 0) srand((int)time(0)); - else srand(turn); + if (turn == 0) rng_init((int)time(0)); + else rng_init(turn); plan_monsters(); for (u=f->units;u;u=u->nextF) { call_script(u); diff --git a/src/eressea/main.c b/src/eressea/main.c index ed38261f9..67c2192fd 100644 --- a/src/eressea/main.c +++ b/src/eressea/main.c @@ -83,16 +83,16 @@ #include <kernel/item.h> /* util includes */ -#include <rand.h> +#include <util/rand.h> +#include <util/rng.h> #include <util/xml.h> #include <util/goodies.h> -#include <log.h> -#include <sql.h> -#include <base36.h> +#include <util/log.h> +#include <util/sql.h> +#include <util/base36.h> /* libc includes */ #include <stdio.h> -#include <stdlib.h> #include <ctype.h> #include <string.h> #include <time.h> @@ -244,8 +244,8 @@ processturn(char *filename) newfaction * players; int i; - if (turn == 0) srand((int)time(0)); - else srand(turn); + if (turn == 0) rng_init((int)time(0)); + else rng_init(turn); #ifdef SHORTPWDS readshortpwds("passwords"); @@ -254,8 +254,8 @@ processturn(char *filename) turn++; if ((i=readorders(filename))!=0) return i; if (!nomonsters) { - if (turn == 0) srand((int)time(0)); - else srand(turn); + if (turn == 0) rng_init((int)time(0)); + else rng_init(turn); puts(" - Monster KI..."); plan_monsters(); } @@ -604,8 +604,8 @@ main(int argc, char *argv[]) return crwritemap("world.cr"); } - if (turn == 0) srand((int)time(0)); - else srand(turn); + if (turn == 0) rng_init((int)time(0)); + else rng_init(turn); if ((i = processturn(orders))!=0) { diff --git a/src/eressea/server.cpp b/src/eressea/server.cpp index cdb11ed9d..e3810c628 100644 --- a/src/eressea/server.cpp +++ b/src/eressea/server.cpp @@ -87,6 +87,7 @@ #include <util/goodies.h> #include <util/log.h> #include <util/rand.h> +#include <util/rng.h> #include <util/sql.h> #ifdef MSPACES # include <util/dl/malloc.h> @@ -106,7 +107,6 @@ /* libc includes */ #include <cstdio> -#include <cstdlib> #include <cctype> #include <cstring> #include <ctime> @@ -332,8 +332,8 @@ lua_done(lua_State * luaState) int process_orders() { - if (turn == 0) srand((int)time(0)); - else srand(turn); + if (turn == 0) rng_init((int)time(0)); + else rng_init(turn); #ifdef SHORTPWDS readshortpwds("passwords"); diff --git a/src/mapper/map_modify.c b/src/mapper/map_modify.c index 150913a4a..e2143fded 100644 --- a/src/mapper/map_modify.c +++ b/src/mapper/map_modify.c @@ -33,10 +33,10 @@ #include <resources.h> /* util includes */ -#include <base36.h> +#include <util/base36.h> +#include <util/rng.h> /* libc includes */ -#include <stdlib.h> #include <string.h> typedef struct menulist { @@ -77,7 +77,7 @@ static char maxseeds[MAXCLIMATES][8] = static terrain_t terrain_create(int climate) { - int i = rand() % MAXSEEDSIZE; + int i = rng_int() % MAXSEEDSIZE; terrain_t terrain = T_OCEAN; while (i > maxseeds[climate][terrain]) @@ -151,7 +151,7 @@ block_create(short x1, short y1, int size, char chaotisch, int special, const te } } for (k = 0; k != size; ++k) { - int c = (int) fringe.data[rand() % fringe.size]; + int c = (int) fringe.data[rng_int() % fringe.size]; direction_t d; x = (short)(c >> 16); @@ -176,9 +176,9 @@ block_create(short x1, short y1, int size, char chaotisch, int special, const te const luxury_type *ltype, *p1 = NULL, *p2=NULL; int maxlux = get_maxluxuries(); if (maxlux>0) { - i1 = (item_t)(rand() % maxlux); + i1 = (item_t)(rng_int() % maxlux); do { - i2 = (item_t)(rand() % maxlux); + i2 = (item_t)(rng_int() % maxlux); } while (i2 == i1); } @@ -190,7 +190,7 @@ block_create(short x1, short y1, int size, char chaotisch, int special, const te } for (x = 0; x != BLOCKSIZE; x++) { for (y = 0; y != BLOCKSIZE; y++) { - const luxury_type * sale = (rand()%2)?p1:p2; + const luxury_type * sale = (rng_int()%2)?p1:p2; r = findregion(x1 + x - BLOCKSIZE/2, y1 + y - BLOCKSIZE/2); if (r && !fval(r->terrain, SEA_REGION)) continue; if (r==NULL) r = new_region(x1 + x - BLOCKSIZE/2, y1 + y - BLOCKSIZE/2); @@ -1026,15 +1026,15 @@ static terrain_t choose_terrain(terrain_t t) { int q; - if (rand()%100 < 50) return t; - if (rand()%100 < 10) return T_OCEAN; + if (rng_int()%100 < 50) return t; + if (rng_int()%100 < 10) return T_OCEAN; - q = rand()%100; + q = rng_int()%100; switch (t) { case T_OCEAN: - if(rand()%100 < 60) return T_OCEAN; - switch(rand()%6) { + if(rng_int()%100 < 60) return T_OCEAN; + switch(rng_int()%6) { case 0: return T_SWAMP; case 1: @@ -1142,7 +1142,7 @@ shift(void) if(t_queue_len == 0) return NULL; - p = rand()%t_queue_len; + p = rng_int()%t_queue_len; r = t_queue[p]; memmove(&t_queue[p], &t_queue[p+1], (10000-p)*sizeof(region *)); @@ -1160,11 +1160,11 @@ settg(region *r) if (tradegood==NULL) tradegood = luxurytypes; for (ltype=luxurytypes; ltype; ltype=ltype->next) { - if (ltype!=tradegood) r_setdemand(r, ltype, 1 + rand() % 5); + if (ltype!=tradegood) r_setdemand(r, ltype, 1 + rng_int() % 5); } r_setdemand(r, tradegood, 0); - if (g>0 && (rand()%10)<2) { - int t = rand() % g; + if (g>0 && (rng_int()%10)<2) { + int t = rng_int() % g; for (tradegood = luxurytypes;t;--t) { tradegood = tradegood->next; @@ -1178,7 +1178,7 @@ Create_Island(region *r, int * n, const terrain_type * terrain, int x, int y) { if (!r) return false; if (*n == 0) return true; - if((t == T_MOUNTAIN || t == T_GLACIER) && rand()%100 < 5) { + if((t == T_MOUNTAIN || t == T_GLACIER) && rng_int()%100 < 5) { terraform(r,T_VOLCANO); } else { terraform_region(r, terrain); @@ -1203,7 +1203,7 @@ create_island(region *r, int n, const struct terrain_type * terrain) tradegood = NULL; terraform_region(r, terrain); if(r->land) settg(r); - r->msgs = (void *)(rand()%6); + r->msgs = (void *)(rng_int()%6); push(r); for(d=0; d<MAXDIRECTIONS; d++) { diff --git a/src/mapper/mapper.c b/src/mapper/mapper.c index 6b472c2f9..9aa9537d6 100644 --- a/src/mapper/mapper.c +++ b/src/mapper/mapper.c @@ -60,13 +60,13 @@ /* util includes */ #include <util/base36.h> #include <util/goodies.h> +#include <util/rng.h> /* libc includes */ #include <ctype.h> #include <limits.h> #include <locale.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> #include <time.h> @@ -693,14 +693,14 @@ modify_block(void) rsetname(r, name); break; case 'p': - rsetpeasants(r, (production(r)*3+rand()%(production(r)*3))/div); - rsetmoney(r, (production(r)*10+rand()%(production(r)*10))/div); + rsetpeasants(r, (production(r)*3+rng_int()%(production(r)*3))/div); + rsetmoney(r, (production(r)*10+rng_int()%(production(r)*10))/div); break; case 'h': - rsethorses(r, rand()%(production(r) / 10)); + rsethorses(r, rng_int()%(production(r) / 10)); break; case 's': - rsetmoney(r, production(r)*10+rand()%(production(r)*10)); + rsetmoney(r, production(r)*10+rng_int()%(production(r)*10)); break; case 'r': for (res=r->resources;res;res=res->next) { @@ -1528,7 +1528,7 @@ makemonsters(void) f->subscription = 0; f->name=strdup("Monster"); f->passw=strdup("abc123"); - f->override = strdup(itoa36(rand())); + f->override = strdup(itoa36(rng_int())); return f; } @@ -1701,7 +1701,7 @@ main(int argc, char *argv[]) make_xref(); #endif setminmax(); - srand(time((time_t *) NULL)); + rng_init(time((time_t *) NULL)); if (autoseeding) { runautoseed(); diff --git a/src/tools/namegen.c b/src/tools/namegen.c index ef4366dff..564d73743 100644 --- a/src/tools/namegen.c +++ b/src/tools/namegen.c @@ -143,7 +143,7 @@ create_random_name(race_t race) switch (race) { case RC_DWARF: - strcpy(name, dwarf_syllable1[rand()%(sizeof(dwarf_syllable1) / sizeof(char*))]); + strcpy(name, dwarf_syllable1[rng_int()%(sizeof(dwarf_syllable1) / sizeof(char*))]); strcat(name, dwarf_syllable2[rand()%(sizeof(dwarf_syllable2) / sizeof(char*))]); strcat(name, dwarf_syllable3[rand()%(sizeof(dwarf_syllable3) / sizeof(char*))]); break;