Bugfix leave_trail. Aufsplitten von move_ship

- Änderung von get_param (liefert NULL für undeklarierte params) in Vorbereitung auf "mehr config, weniger define"

Diverse indenting-anpassungen (space statt tabs)
This commit is contained in:
Enno Rehling 2004-04-10 10:43:46 +00:00
parent 77a00514ae
commit e319698a43
9 changed files with 423 additions and 398 deletions

View File

@ -110,11 +110,12 @@ static request *oa;
static int static int
giverestriction(void) { giverestriction(void) {
static int value = -1; static int value = -1;
if (value<0) { if (value<0) {
value = atoi(get_param(global.parameters, "GiveRestriction")); const char * str = get_param(global.parameters, "GiveRestriction");
} value = str?atoi(str):0;
return value; }
return value;
} }
int int
@ -2990,43 +2991,48 @@ expandentertainment(region * r)
void void
entertain(region * r, unit * u) entertain(region * r, unit * u)
{ {
int max_e; int max_e;
request *o; request *o;
static int entertainbase = 0; static int entertainbase = 0;
static int entertainperlevel = 0; static int entertainperlevel = 0;
if (!entertainbase) entertainbase = atoi(get_param(global.parameters, "entertain.base")); if (!entertainbase) {
if (!entertainperlevel) entertainperlevel = atoi(get_param(global.parameters, "entertain.perlevel")); const char * str = get_param(global.parameters, "entertain.base");
entertainbase = str?atoi(str):0;
}
if (!entertainperlevel) {
const char * str = get_param(global.parameters, "entertain.perlevel");
entertainperlevel = str?atoi(str):0;
}
if (fval(u, UFL_WERE)) {
cmistake(u, findorder(u, u->thisorder), 58, MSG_INCOME);
return;
}
if (fval(u, UFL_WERE)) { if (!effskill(u, SK_ENTERTAINMENT)) {
cmistake(u, findorder(u, u->thisorder), 58, MSG_INCOME); cmistake(u, findorder(u, u->thisorder), 58, MSG_INCOME);
return; return;
} }
if (besieged(u)) {
cmistake(u, findorder(u, u->thisorder), 60, MSG_INCOME);
return;
}
if (u->ship && is_guarded(r, u, GUARD_CREWS)) {
cmistake(u, findorder(u, u->thisorder), 69, MSG_INCOME);
return;
}
if (is_cursed(r->attribs, C_DEPRESSION, 0)) {
cmistake(u, findorder(u, u->thisorder), 28, MSG_INCOME);
return;
}
if (!effskill(u, SK_ENTERTAINMENT)) { u->wants = u->number * (entertainbase + effskill(u, SK_ENTERTAINMENT) * entertainperlevel);
cmistake(u, findorder(u, u->thisorder), 58, MSG_INCOME); if ((max_e = geti()) != 0)
return; u->wants = min(u->wants,max_e);
}
if (besieged(u)) {
cmistake(u, findorder(u, u->thisorder), 60, MSG_INCOME);
return;
}
if (u->ship && is_guarded(r, u, GUARD_CREWS)) {
cmistake(u, findorder(u, u->thisorder), 69, MSG_INCOME);
return;
}
if (is_cursed(r->attribs, C_DEPRESSION, 0)) {
cmistake(u, findorder(u, u->thisorder), 28, MSG_INCOME);
return;
}
u->wants = u->number * (entertainbase + effskill(u, SK_ENTERTAINMENT) * entertainperlevel); o = nextentertainer++;
if ((max_e = geti()) != 0) o->unit = u;
u->wants = min(u->wants,max_e); o->qty = u->wants;
entertaining += o->qty;
o = nextentertainer++;
o->unit = u;
o->qty = u->wants;
entertaining += o->qty;
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */

View File

@ -106,39 +106,40 @@ boolean nomonsters = false;
static int static int
RemoveNMRNewbie(void) { RemoveNMRNewbie(void) {
static int value = -1; static int value = -1;
if (value<0) { if (value<0) {
value = atoi(get_param(global.parameters, "nmr.removenewbie")); const char * str = get_param(global.parameters, "nmr.removenewbie");
} value = str?atoi(str):0;
return value; }
return value;
} }
static void static void
restart(unit *u, const race * rc) restart(unit *u, const race * rc)
{ {
faction *f = addfaction(u->faction->email, u->faction->passw, rc, u->faction->locale, u->faction->subscription); faction *f = addfaction(u->faction->email, u->faction->passw, rc, u->faction->locale, u->faction->subscription);
unit * nu = addplayer(u->region, f); unit * nu = addplayer(u->region, f);
strlist ** o=&u->orders; strlist ** o=&u->orders;
f->subscription = u->faction->subscription; f->subscription = u->faction->subscription;
fset(f, FFL_RESTART); fset(f, FFL_RESTART);
if (f->subscription) fprintf(sqlstream, "UPDATE subscriptions set faction='%s', race='%s' where id=%u;\n", if (f->subscription) fprintf(sqlstream, "UPDATE subscriptions set faction='%s', race='%s' where id=%u;\n",
itoa36(f->no), dbrace(rc), f->subscription); itoa36(f->no), dbrace(rc), f->subscription);
f->magiegebiet = u->faction->magiegebiet; f->magiegebiet = u->faction->magiegebiet;
f->options = u->faction->options; f->options = u->faction->options;
freestrlist(nu->orders); freestrlist(nu->orders);
nu->orders = u->orders; nu->orders = u->orders;
u->orders = NULL; u->orders = NULL;
while (*o) { while (*o) {
strlist * S = *o; strlist * S = *o;
if (igetkeyword(S->s, u->faction->locale) == K_RESTART) { if (igetkeyword(S->s, u->faction->locale) == K_RESTART) {
*o = S->next; *o = S->next;
S->next = NULL; S->next = NULL;
freestrlist(S); freestrlist(S);
} else { } else {
o = &S->next; o = &S->next;
} }
} }
destroyfaction(u->faction); destroyfaction(u->faction);
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */

View File

@ -57,59 +57,58 @@
void void
spy(region * r, unit * u) spy(region * r, unit * u)
{ {
unit *target; unit *target;
int spy, observe; int spy, observe;
double spychance, observechance; double spychance, observechance;
target = getunit(r, u->faction); target = getunit(r, u->faction);
if (!target) { if (!target) {
cmistake(u, findorder(u, u->thisorder), 63, MSG_EVENT); cmistake(u, findorder(u, u->thisorder), 63, MSG_EVENT);
return; return;
} }
if (!can_contact(r, u, target)) { if (!can_contact(r, u, target)) {
cmistake(u, findorder(u, u->thisorder), 24, MSG_EVENT); cmistake(u, findorder(u, u->thisorder), 24, MSG_EVENT);
return; return;
} }
if (eff_skill(u, SK_SPY, r) < 1) { if (eff_skill(u, SK_SPY, r) < 1) {
cmistake(u, findorder(u, u->thisorder), 39, MSG_EVENT); cmistake(u, findorder(u, u->thisorder), 39, MSG_EVENT);
return; return;
} }
/* Die Grundchance für einen erfolgreichen Spionage-Versuch ist 10%. /* Die Grundchance für einen erfolgreichen Spionage-Versuch ist 10%.
* Für jeden Talentpunkt, den das Spionagetalent das Tarnungstalent * Für jeden Talentpunkt, den das Spionagetalent das Tarnungstalent
* des Opfers übersteigt, erhöht sich dieses um 5%*/ * des Opfers übersteigt, erhöht sich dieses um 5%*/
spy = eff_skill(u, SK_SPY, r) - eff_skill(target, SK_STEALTH, r); spy = eff_skill(u, SK_SPY, r) - eff_skill(target, SK_STEALTH, r);
spychance = 0.1 + max(spy*0.05, 0.0); spychance = 0.1 + max(spy*0.05, 0.0);
if (chance(spychance)) { if (chance(spychance)) {
spy_message(spy, u, target); spy_message(spy, u, target);
} else { } else {
add_message(&u->faction->msgs, new_message(u->faction, ADDMSG(&u->faction->msgs, msg_message("spyfail", "spy target", u, target));
"spyfail%u:spy%u:target", u, target)); }
}
/* der Spion kann identifiziert werden, wenn das Opfer bessere /* der Spion kann identifiziert werden, wenn das Opfer bessere
* Wahrnehmung als das Ziel Tarnung + Spionage/2 hat */ * Wahrnehmung als das Ziel Tarnung + Spionage/2 hat */
observe = eff_skill(target, SK_OBSERVATION, r) observe = eff_skill(target, SK_OBSERVATION, r)
- (effskill(u, SK_STEALTH) + eff_skill(u, SK_SPY, r)/2); - (effskill(u, SK_STEALTH) + eff_skill(u, SK_SPY, r)/2);
#if NEWATSROI == 0 #if NEWATSROI == 0
if (invisible(u) >= u->number && if (invisible(u) >= u->number &&
get_item(target, I_AMULET_OF_TRUE_SEEING) == 0) { get_item(target, I_AMULET_OF_TRUE_SEEING) == 0) {
observe = min(observe, 0); observe = min(observe, 0);
} }
#endif #endif
/* Anschließend wird - unabhängig vom Erfolg - gewürfelt, ob der /* Anschließend wird - unabhängig vom Erfolg - gewürfelt, ob der
* Spionageversuch bemerkt wurde. Die Wahrscheinlich dafür ist (100 - * Spionageversuch bemerkt wurde. Die Wahrscheinlich dafür ist (100 -
* SpionageSpion*5 + WahrnehmungOpfer*2)%. */ * SpionageSpion*5 + WahrnehmungOpfer*2)%. */
observechance = 1.0 - (eff_skill(u, SK_SPY, r) * 0.05) observechance = 1.0 - (eff_skill(u, SK_SPY, r) * 0.05)
+ (eff_skill(target, SK_OBSERVATION, r) * 0.02); + (eff_skill(target, SK_OBSERVATION, r) * 0.02);
if (chance(observechance)){ if (chance(observechance)){
add_message(&target->faction->msgs, new_message(target->faction, add_message(&target->faction->msgs, new_message(target->faction,
"spydetect%u:spy%u:target", observe>0?u:NULL, target)); "spydetect%u:spy%u:target", observe>0?u:NULL, target));
} }
} }
void void

View File

@ -109,58 +109,63 @@ static attrib_type at_creator = {
}; };
static int static int
MaxAge(void) { MaxAge(void) {
static int value = -1; static int value = -1;
if (value<0) { if (value<0) {
value = atoi(get_param(global.parameters, "MaxAge")); const char * str = get_param(global.parameters, "MaxAge");
} value = str?atoi(str):0;
return value; }
return value;
} }
int int
LongHunger(void) { LongHunger(void) {
static int value = -1; static int value = -1;
if (value<0) { if (value<0) {
value = atoi(get_param(global.parameters, "hunger.long")); const char * str = get_param(global.parameters, "hunger.long");
} value = str?atoi(str):0;
return value; }
return value;
} }
int int
SkillCap(skill_t sk) { SkillCap(skill_t sk) {
static int value = -1; static int value = -1;
if (sk==SK_MAGIC) return 0; /* no caps on magic */ if (sk==SK_MAGIC) return 0; /* no caps on magic */
if (value<0) { if (value<0) {
value = atoi(get_param(global.parameters, "skill.maxlevel")); const char * str = get_param(global.parameters, "skill.maxlevel");
} value = str?atoi(str):0;
return value; }
return value;
} }
boolean boolean
TradeDisabled(void) { TradeDisabled(void) {
static int value = -1; static int value = -1;
if (value<0) { if (value<0) {
value = (boolean)atoi(get_param(global.parameters, "trade.disabled")); const char * str = get_param(global.parameters, "trade.disabled");
} value = str?atoi(str):0;
return value; }
return value;
} }
int int
NMRTimeout(void) { NMRTimeout(void) {
static int value = -1; static int value = -1;
if (value<0) { if (value<0) {
value = atoi(get_param(global.parameters, "nmr.timeout")); const char * str = get_param(global.parameters, "nmr.timeout");
} value = str?atoi(str):0;
return value; }
return value;
} }
race_t race_t
old_race(const struct race * rc) old_race(const struct race * rc)
{ {
race_t i; race_t i;
for (i=0;i!=MAXRACES;++i) { for (i=0;i!=MAXRACES;++i) {
if (new_race[i]==rc) return i; if (new_race[i]==rc) return i;
} }
return NORACE; return NORACE;
} }
const char *directions[MAXDIRECTIONS+2] = const char *directions[MAXDIRECTIONS+2] =
@ -378,7 +383,8 @@ allied_skillcount(const faction * f, skill_t sk)
int int
allied_skilllimit(const faction * f, skill_t sk) allied_skilllimit(const faction * f, skill_t sk)
{ {
return atoi(get_param(global.parameters, "allied.skilllimit")); const char * str = get_param(global.parameters, "allied.skilllimit");
return str?atoi(str):0;
} }
#endif #endif
@ -2174,37 +2180,37 @@ init_tokens(const struct locale * lang)
} }
typedef struct param { typedef struct param {
struct param * next; struct param * next;
char * name; char * name;
char * data; char * data;
} param; } param;
const char * const char *
get_param(const struct param * p, const char * key) get_param(const struct param * p, const char * key)
{ {
while (p!=NULL) { while (p!=NULL) {
if (strcmp(p->name, key)==0) return p->data; if (strcmp(p->name, key)==0) return p->data;
p = p->next; p = p->next;
} }
return "0"; return NULL;
} }
void void
set_param(struct param ** p, const char * key, const char * data) set_param(struct param ** p, const char * key, const char * data)
{ {
while (*p!=NULL) { while (*p!=NULL) {
if (strcmp((*p)->name, key)==0) { if (strcmp((*p)->name, key)==0) {
free((*p)->data); free((*p)->data);
(*p)->data = strdup(data); (*p)->data = strdup(data);
return; return;
} }
p=&(*p)->next; p=&(*p)->next;
} }
*p = malloc(sizeof(param)); *p = malloc(sizeof(param));
(*p)->name = strdup(key); (*p)->name = strdup(key);
(*p)->data = strdup(data); (*p)->data = strdup(data);
(*p)->next = NULL; (*p)->next = NULL;
} }
void void

View File

@ -435,74 +435,83 @@ do_maelstrom(region *r, unit *u)
void void
travelthru(unit * u, region * r) travelthru(unit * u, region * r)
{ {
attrib *ru = a_add(&r->attribs, a_new(&at_travelunit)); attrib *ru = a_add(&r->attribs, a_new(&at_travelunit));
ru->data.v = u; ru->data.v = u;
u->faction->first = 0;
u->faction->last = 0; /* the first and last region of the faction gets reset, because travelthrough
* could be in regions that are located before the [first, last] interval,
* and recalculation is needed */
u->faction->first = 0;
u->faction->last = 0;
}
static void
leave_trail(ship * sh, region **route)
{
region **ri = route;
while (*ri) {
region *r = *ri;
direction_t dir = reldirection(*ri, *rn);
attrib * a = a_find((*ri)->attribs, &at_traveldir_new);
traveldir * td = NULL;
while (a!=NULL) {
td = (traveldir *)a->data.v;
if (td->no == sh->no) break;
a = a->nexttype;
}
if (a!=NULL) {
a = a_add(&((*ri)->attribs), a_new(&at_traveldir_new));
td = (traveldir *)a->data.v;
td->no = sh->no;
}
td->dir = dir;
td->age = 2;
travelthru(u, r);
++ri;
}
} }
ship * ship *
move_ship(ship * sh, region * from, region * to, region ** route) move_ship(ship * sh, region * from, region * to, region ** route)
{ {
unit *u = from->units; unit **iunit = &from->units;
unit **ulist = &to->units; unit **ulist = &to->units;
direction_t dir; direction_t dir;
attrib *a; attrib *a;
boolean trail = (route==NULL);
if (from!=to) { if (from!=to) {
translist(&from->ships, &to->ships, sh); translist(&from->ships, &to->ships, sh);
sh->region = to; sh->region = to;
} }
while (u) { while (*iunit!=NULL) {
unit *nu = u->next; unit *u = *iunit;
assert(u->region==from);
if (u->ship == sh) if (u->ship == sh) {
{ if (!trail) {
if (route) { leave_trail(sh, from, to, route);
region **ri = route; trail=true;
region **rn; }
if (from!=to) {
while (*ri) { u->ship = NULL; /* damit move_unit() kein leave() macht */
rn = ri+1; move_unit(u, to, ulist);
if(*rn) { ulist = &u->next;
dir = reldirection(*ri, *rn); u->ship = sh;
a = a_find((*ri)->attribs, &at_traveldir_new); }
while (a) { if (route && eff_skill(u, SK_SAILING, from) >= 1) {
if(((traveldir *)(a->data.v))->no == sh->no) break; produceexp(u, SK_SAILING, u->number);
a = a->nexttype; }
} }
if(!a) { if (*iunit==u) iunit=&u->next;
a = a_add(&((*ri)->attribs), a_new(&at_traveldir_new)); }
{ return sh;
traveldir *t = (traveldir *)(a->data.v);
t->no = sh->no;
t->dir = dir;
t->age = 2;
}
} else {
traveldir *t = (traveldir *)(a->data.v);
t->dir = dir;
t->age = 2;
}
}
travelthru(u, *ri++);
}
}
if (from!=to) {
u->ship = NULL; /* damit move_unit() kein leave() macht */
move_unit(u, to, ulist);
ulist = &u->next;
u->ship = sh;
}
if (route && eff_skill(u, SK_SAILING, from) >= 1) {
produceexp(u, SK_SAILING, u->number);
}
}
u = nu;
}
return sh;
} }
static void static void
@ -1941,15 +1950,15 @@ age_traveldir(region *r)
static direction_t static direction_t
hunted_dir(attrib *at, int id) hunted_dir(attrib *at, int id)
{ {
attrib *a = a_find(at, &at_traveldir_new); attrib *a = a_find(at, &at_traveldir_new);
while(a) { while (a!=NULL) {
traveldir *t = (traveldir *)(a->data.v); traveldir *t = (traveldir *)(a->data.v);
if(t->no == id) return t->dir; if (t->no == id) return t->dir;
a = a->nexttype; a = a->nexttype;
} }
return NODIRECTION; return NODIRECTION;
} }
static boolean static boolean
@ -1963,67 +1972,66 @@ can_move(const unit * u)
static int static int
hunt(unit *u) hunt(unit *u)
{ {
region *rc = u->region; region *rc = u->region;
int moves, id; int moves, id;
char command[256]; char command[256];
direction_t dir; direction_t dir;
if(!u->ship) { if(!u->ship) {
cmistake(u, findorder(u, u->thisorder), 144, MSG_MOVE); cmistake(u, findorder(u, u->thisorder), 144, MSG_MOVE);
return 0; return 0;
} else if(!fval(u, UFL_OWNER)) { } else if(!fval(u, UFL_OWNER)) {
cmistake(u, findorder(u, u->thisorder), 146, MSG_MOVE); cmistake(u, findorder(u, u->thisorder), 146, MSG_MOVE);
return 0; return 0;
} else if(attacked(u)) { } else if(attacked(u)) {
cmistake(u, findorder(u, u->thisorder), 52, MSG_MOVE); cmistake(u, findorder(u, u->thisorder), 52, MSG_MOVE);
return 0; return 0;
} else if (!can_move(u)) { } else if (!can_move(u)) {
cmistake(u, findorder(u, u->thisorder), 55, MSG_MOVE); cmistake(u, findorder(u, u->thisorder), 55, MSG_MOVE);
return 0; return 0;
} }
id = getshipid(); id = getshipid();
if (id <= 0) { if (id <= 0) {
cmistake(u, findorder(u, u->thisorder), 20, MSG_MOVE); cmistake(u, findorder(u, u->thisorder), 20, MSG_MOVE);
return 0; return 0;
} }
dir = hunted_dir(rc->attribs, id); dir = hunted_dir(rc->attribs, id);
if(dir == NODIRECTION) { if (dir == NODIRECTION) {
ship * sh = findship(id); ship * sh = findship(id);
if (sh->region!=rc) { if (sh->region!=rc) {
cmistake(u, findorder(u, u->thisorder), 20, MSG_MOVE); cmistake(u, findorder(u, u->thisorder), 20, MSG_MOVE);
} }
return 0; return 0;
} }
sprintf(command, "%s %s", locale_string(u->faction->locale, keywords[K_MOVE]), sprintf(command, "%s %s", locale_string(u->faction->locale, keywords[K_MOVE]),
locale_string(u->faction->locale, directions[dir])); locale_string(u->faction->locale, directions[dir]));
moves = 1; moves = 1;
rc = rconnect(rc, dir); rc = rconnect(rc, dir);
while(moves < shipspeed(u->ship, u) while (moves < shipspeed(u->ship, u) && (dir = hunted_dir(rc->attribs, id)) != NODIRECTION)
&& (dir = hunted_dir(rc->attribs, id)) != NODIRECTION) { {
strcat(command, " "); strcat(command, " ");
strcat(command, locale_string(u->faction->locale, directions[dir])); strcat(command, locale_string(u->faction->locale, directions[dir]));
moves++; moves++;
rc = rconnect(rc, dir); rc = rconnect(rc, dir);
} }
/* In command steht jetzt das NACH-Kommando. */ /* In command steht jetzt das NACH-Kommando. */
igetkeyword(command, u->faction->locale); /* NACH ignorieren und Parsing initialisieren. */
igetkeyword(command, u->faction->locale); /* NACH ignorieren und Parsing initialisieren. */
/* NACH ausführen */ /* NACH ausführen */
if (move(u->region, u, false)!=0) { if (move(u->region, u, false)!=0) {
/* niemand sollte auf einen kapitän direkt ein folge haben, oder? */ /* niemand sollte auf einen kapitän direkt ein folge haben, oder? */
assert(1==0); assert(1==0);
} }
fset(u, UFL_LONGACTION); /* Von Hand setzen, um Endlosschleife zu vermeiden, fset(u, UFL_LONGACTION); /* Von Hand setzen, um Endlosschleife zu vermeiden, wenn Verfolgung nicht erfolgreich */
wenn Verfolgung nicht erfolgreich */ return 1; /* true -> Einheitenliste von vorne durchgehen */
return 1; /* true -> Einheitenliste von vorne durchgehen */
} }
void void

View File

@ -23,53 +23,59 @@
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
/** rolls a number of n-sided dice.
* Usage: 3d6-3d4+5 = dice(3,6)-dice(3,4)+5 */
int int
dice(int count, int value) dice(int count, int value)
{ /* Usage: 3d6-3d4+5 = dice(3,6)-dice(3,4)+5 */ {
int d = 0, c; int d = 0, c;
if (value<=0) return 0; /* (enno) %0 geht nicht. echt wahr. */ if (value<=0) return 0; /* (enno) %0 geht nicht. echt wahr. */
if (count >= 0) if (count >= 0)
for (c = count; c > 0; c--) for (c = count; c > 0; c--)
d += rand() % value + 1; d += rand() % value + 1;
else else
for (c = count; c < 0; c++) for (c = count; c < 0; c++)
d -= rand() % value + 1; d -= rand() % value + 1;
return d; return d;
} }
/** Parses a string of the form "2d6+8"
* Kann nur simple Strings der Form "xdy[+-]z" parsen!
* Schöner wäre eine flexibele Routine, die z.B. auch Sachen wie 2d6+3d4-1
* parsen kann. */
int int
dice_rand(const char *s) dice_rand(const char *s)
{ {
const char *c = s; const char *c = s;
int m = 0, d = 0, k = 0, multi = 1; int m = 0, d = 0, k = 0, multi = 1;
int state = 1; int state = 1;
for (;;) { for (;;) {
if (isdigit((int)*c)) { if (isdigit((int)*c)) {
k = k*10+(*c-'0'); k = k*10+(*c-'0');
} else if (*c=='+' || *c=='-' || *c==0) { } else if (*c=='+' || *c=='-' || *c==0) {
if (state==1) /* konstante k addieren */ if (state==1) /* konstante k addieren */
m+=k*multi; m+=k*multi;
else if (state==2) { /* dDk */ else if (state==2) { /* dDk */
int i; int i;
if (k == 0) k = 6; /* 3d == 3d6 */ 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 + rand() % k)*multi;
} }
else assert(!"dice_rand: illegal token"); else assert(!"dice_rand: illegal token");
k = d = 0; k = d = 0;
state = 1; state = 1;
multi = (*c=='-')?-1:1; multi = (*c=='-')?-1:1;
} else if (*c=='d' || *c=='D') { } else if (*c=='d' || *c=='D') {
if (k==0) k = 1; /* d9 == 1d9 */ if (k==0) k = 1; /* d9 == 1d9 */
assert(state==1 || !"dice_rand: illegal token"); assert(state==1 || !"dice_rand: illegal token");
d = k; d = k;
k = 0; k = 0;
state=2; state=2;
} else assert(!"dice_rand: illegal token"); } else assert(!"dice_rand: illegal token");
if (*c==0) break; if (*c==0) break;
c++; c++;
} }
return m; return m;
} }

View File

@ -19,10 +19,6 @@
* permission from the authors. * permission from the authors.
*/ */
/* Kann nur simple Strings der Form "xdy[+-]z" parsen!
* Schöner wäre eine flexibele Routine, die z.B. auch Sachen wie 2d6+3d4-1
* parsen kann. */
#include <config.h> #include <config.h>
#include "rand.h" #include "rand.h"
@ -35,67 +31,65 @@
#define drand() (((double)rand())/(double)RAND_MAX) #define drand() (((double)rand())/(double)RAND_MAX)
#define M_PIl 3.1415926535897932384626433832795029L /* pi */ #define M_PIl 3.1415926535897932384626433832795029L /* pi */
static double nv_next;
static char valid_next = 0;
/* NormalRand aus python, random.py geklaut, dort ist Referenz auf /* NormalRand aus python, random.py geklaut, dort ist Referenz auf
* den Algorithmus. mu = Mittelwert, sigma = Standardabweichung. */ * den Algorithmus. mu = Mittelwert, sigma = Standardabweichung. */
double nv_next;
char valid_next = 0;
double double
normalvariate(double mu, double sigma) normalvariate(double mu, double sigma)
{ {
double x2pi, g2rad, z; double x2pi, g2rad, z;
double t1, t2; double t1, t2;
double fac=1; double fac=1;
static double mu_alt, sigma_alt; static double mu_alt, sigma_alt;
if(mu < 10) { if(mu < 10) {
fac=0.01; fac=0.01;
mu*=100; mu*=100;
sigma*=100; sigma*=100;
} }
if(mu_alt!=mu || sigma_alt!= sigma) if(mu_alt!=mu || sigma_alt!= sigma)
valid_next=0; valid_next=0;
mu_alt=mu; mu_alt=mu;
sigma_alt=sigma; sigma_alt=sigma;
if (valid_next == 0) { if (valid_next == 0) {
x2pi = drand() * 2.0L * M_PIl; x2pi = drand() * 2.0L * M_PIl;
t1 = drand(); t1 = drand();
t1 = 1.0 - t1; t1 = 1.0 - t1;
t2 = log(t1); t2 = log(t1);
g2rad = sqrt(-2.0 * t2); g2rad = sqrt(-2.0 * t2);
z = cos(x2pi) * g2rad; z = cos(x2pi) * g2rad;
nv_next = sin(x2pi) * g2rad; nv_next = sin(x2pi) * g2rad;
valid_next = 1; valid_next = 1;
} else { } else {
z = nv_next; z = nv_next;
valid_next = 0; valid_next = 0;
} }
return (fac*(mu + z*sigma)); /* mu thorin */ return (fac*(mu + z*sigma)); /* mu thorin */
} }
int int
ntimespprob(int n, double p, double mod) ntimespprob(int n, double p, double mod)
{ {
int count = 0; int count = 0;
int i; int i;
for(i=0; i<n && p>0; i++) for(i=0; i<n && p>0; i++) {
if(drand() < p) { if(drand() < p) {
count++; count++;
p += mod; p += mod;
} }
}
return count; return count;
} }
boolean boolean
chance(double x) chance(double x)
{ {
if (x>=1.0) return true; if (x>=1.0) return true;
return (boolean) (rand() % RAND_MAX < RAND_MAX * x); return (boolean) (rand() % RAND_MAX < RAND_MAX * x);
} }

View File

@ -18,11 +18,14 @@
extern "C" { extern "C" {
#endif #endif
extern int dice_rand(const char *str); /* in dice.c: */
extern int dice(int count, int value); extern int dice_rand(const char *str);
extern double normalvariate(double mu, double sigma); extern int dice(int count, int value);
extern int ntimespprob(int n, double p, double mod);
extern boolean chance(double x); /* in rand.c: */
extern double normalvariate(double mu, double sigma);
extern int ntimespprob(int n, double p, double mod);
extern boolean chance(double x);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,44 +1,46 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<eressea xmlns:xi="http://www.w3.org/2001/XInclude"> <eressea xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="messages.xml"/> <xi:include href="messages.xml"/>
<comment>Localization</comment> <comment>Localization</comment>
<comment>Strings MUST always be read first</comment> <comment>Strings MUST always be read first</comment>
<xi:include href="de/strings.xml"/> <xi:include href="de/strings.xml"/>
<xi:include href="en/strings.xml"/> <xi:include href="en/strings.xml"/>
<xi:include href="races.xml"/> <xi:include href="races.xml"/>
<xi:include href="resources.xml"/> <xi:include href="resources.xml"/>
<xi:include href="ships.xml"/> <xi:include href="ships.xml"/>
<xi:include href="buildings.xml"/> <xi:include href="buildings.xml"/>
<game name="Wettstreit der Weisen" units="250" welcome="vinyambar"> <game name="Wettstreit der Weisen" units="250" welcome="vinyambar">
<comment>Game specific</comment> <comment>Game specific</comment>
<order name="ARBEITEN" disable="yes"/> <order name="ARBEITEN" disable="yes"/>
<order name="MEINUNG" disable="yes"/> <order name="MEINUNG" disable="yes"/>
<order name="MAGIEGEBIET" disable="yes"/> <order name="MAGIEGEBIET" disable="yes"/>
<param name="entertain.base" value="15"/> <param name="entertain.base" value="15"/>
<param name="entertain.perlevel" value="5"/> <param name="entertain.perlevel" value="5"/>
<param name="nmr.timeout" value="5"/> <param name="nmr.timeout" value="5"/>
<param name="nmr.removenewbie" value="0"/> <param name="nmr.removenewbie" value="0"/>
<param name="GiveRestriction" value="0"/> <param name="GiveRestriction" value="0"/>
<param name="database.gameid" value="3"/> <param name="database.gameid" value="3"/>
<param name="hunger.long" value="0"/> <param name="hunger.long" value="0"/>
<param name="allied.skilllimit" value="15"/> <param name="allied.skilllimit" value="15"/>
</game> <param name="atsroi.ats" value="2"/>
<param name="atsroi.roi" value="4"/>
</game>
<xi:include href="vinyambar/wdw-strings.xml"/> <xi:include href="vinyambar/wdw-strings.xml"/>
<xi:include href="vinyambar/wdw-resources.xml" /> <xi:include href="vinyambar/wdw-resources.xml" />
<xi:include href="vinyambar/wdw-races.xml"/> <xi:include href="vinyambar/wdw-races.xml"/>
<xi:include href="vinyambar/de/strings.xml"/> <xi:include href="vinyambar/de/strings.xml"/>
<strings> <strings>
<string name="mailto"> <string name="mailto">
<text locale="de">vinyambar@eressea.amber.kn-bremen.de</text> <text locale="de">vinyambar@eressea.amber.kn-bremen.de</text>
</string> </string>
<string name="mailcmd"> <string name="mailcmd">
<text locale="de">WDW BEFEHLE</text> <text locale="de">WDW BEFEHLE</text>
</string> </string>
</strings> </strings>
</eressea> </eressea>