- Ein Haufen kleiner Dinge, und ein crashfix in Bauernblut.

This commit is contained in:
Enno Rehling 2004-06-26 20:51:19 +00:00
parent e88fb30f0e
commit 612cb54ed9
25 changed files with 538 additions and 349 deletions

View File

@ -677,101 +677,108 @@ cr_output_unit(FILE * F, const region * r,
fprintf(F, "%d;belagert\n", b->no); fprintf(F, "%d;belagert\n", b->no);
/* additional information for own units */ /* additional information for own units */
if (u->faction == f || omniscient(f)) { if (u->faction == f || omniscient(f)) {
order * ord; order * ord;
const char *c; const char *c;
int i; char * cmd;
const attrib * a; int i;
const attrib * a;
a = a_find(u->attribs, &at_follow); a = a_find(u->attribs, &at_follow);
if (a) { if (a) {
unit * u = (unit*)a->data.v; unit * u = (unit*)a->data.v;
if (u) fprintf(F, "%d;folgt\n", u->no); if (u) fprintf(F, "%d;folgt\n", u->no);
} }
i = ualias(u); i = ualias(u);
if (i>0) if (i>0)
fprintf(F, "%d;temp\n", i); fprintf(F, "%d;temp\n", i);
else if (i<0) else if (i<0)
fprintf(F, "%d;alias\n", -i); fprintf(F, "%d;alias\n", -i);
i = get_money(u); i = get_money(u);
fprintf(F, "%d;Kampfstatus\n", u->status); fprintf(F, "%d;Kampfstatus\n", u->status);
if(fval(u, UFL_NOAID)) { if(fval(u, UFL_NOAID)) {
fputs("1;unaided\n", F); fputs("1;unaided\n", F);
} }
i = u_geteffstealth(u); i = u_geteffstealth(u);
if (i >= 0) if (i >= 0)
fprintf(F, "%d;Tarnung\n", i); fprintf(F, "%d;Tarnung\n", i);
c = uprivate(u); c = uprivate(u);
if (c) if (c)
fprintf(F, "\"%s\";privat\n", c); fprintf(F, "\"%s\";privat\n", c);
c = hp_status(u); c = hp_status(u);
if (c && *c && (u->faction == f || omniscient(f))) if (c && *c && (u->faction == f || omniscient(f)))
fprintf(F, "\"%s\";hp\n", add_translation(c, locale_string(u->faction->locale, c))); fprintf(F, "\"%s\";hp\n", add_translation(c, locale_string(u->faction->locale, c)));
if (fval(u, UFL_HUNGER) && (u->faction == f)) if (fval(u, UFL_HUNGER) && (u->faction == f))
fputs("1;hunger\n", F); fputs("1;hunger\n", F);
if (is_mage(u)) { if (is_mage(u)) {
fprintf(F, "%d;Aura\n", get_spellpoints(u)); fprintf(F, "%d;Aura\n", get_spellpoints(u));
fprintf(F, "%d;Auramax\n", max_spellpoints(u->region,u)); fprintf(F, "%d;Auramax\n", max_spellpoints(u->region,u));
} }
/* default commands */ /* default commands */
fprintf(F, "COMMANDS\n"); fprintf(F, "COMMANDS\n");
if (u->lastorder) fprintf(F, "\"%s\"\n", getcommand(u->lastorder)); if (u->lastorder) {
for (ord = u->orders; ord; ord = ord->next) { cmd = getcommand(u->lastorder);
if (is_persistent(ord) && ord!=u->lastorder) { fprintf(F, "\"%s\"\n", cmd);
fprintf(F, "\"%s\"\n", getcommand(ord)); free(cmd);
} }
} for (ord = u->orders; ord; ord = ord->next) {
if (is_persistent(ord) && ord!=u->lastorder) {
cmd = getcommand(ord);
fprintf(F, "\"%s\"\n", cmd);
free(cmd);
}
}
/* talents */ /* talents */
pr = 0; pr = 0;
for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
if (sv->level>0) { if (sv->level>0) {
skill_t sk = sv->id; skill_t sk = sv->id;
int esk = eff_skill(u, sk, r); int esk = eff_skill(u, sk, r);
if (!pr) { if (!pr) {
pr = 1; pr = 1;
fprintf(F, "TALENTE\n"); fprintf(F, "TALENTE\n");
} }
fprintf(F, "%d %d;%s\n", u->number*level_days(sv->level), esk, fprintf(F, "%d %d;%s\n", u->number*level_days(sv->level), esk,
add_translation(skillname(sk, NULL), skillname(sk, f->locale))); add_translation(skillname(sk, NULL), skillname(sk, f->locale)));
} }
} }
/* spells */ /* spells */
if (is_mage(u)) { if (is_mage(u)) {
sc_mage * mage = get_mage(u); sc_mage * mage = get_mage(u);
spell_ptr *spt = mage->spellptr; spell_ptr *spt = mage->spellptr;
if (spt) { if (spt) {
spell *sp; spell *sp;
int i; int i;
int t = effskill(u, SK_MAGIC); int t = effskill(u, SK_MAGIC);
fprintf(F, "SPRUECHE\n"); fprintf(F, "SPRUECHE\n");
for (;spt; spt = spt->next) { for (;spt; spt = spt->next) {
sp = find_spellbyid(spt->spellid); sp = find_spellbyid(spt->spellid);
if (sp) { if (sp) {
const char * name = sp->sname; const char * name = sp->sname;
if (sp->level > t) continue; if (sp->level > t) continue;
if (sp->info==NULL) { if (sp->info==NULL) {
name = add_translation(mkname("spell", name), spell_name(sp, f->locale)); name = add_translation(mkname("spell", name), spell_name(sp, f->locale));
} }
fprintf(F, "\"%s\"\n", name); fprintf(F, "\"%s\"\n", name);
} }
} }
for (i=0;i!=MAXCOMBATSPELLS;++i) { for (i=0;i!=MAXCOMBATSPELLS;++i) {
sp = find_spellbyid(mage->combatspell[i]); sp = find_spellbyid(mage->combatspell[i]);
if (sp) { if (sp) {
const char * name = sp->sname; const char * name = sp->sname;
if (sp->info==NULL) { if (sp->info==NULL) {
name = add_translation(mkname("spell", name), spell_name(sp, f->locale)); name = add_translation(mkname("spell", name), spell_name(sp, f->locale));
} }
fprintf(F, "KAMPFZAUBER %d\n", i); fprintf(F, "KAMPFZAUBER %d\n", i);
fprintf(F, "\"%s\";name\n", name); fprintf(F, "\"%s\";name\n", name);
fprintf(F, "%d;level\n", mage->combatspelllevel[i]); fprintf(F, "%d;level\n", mage->combatspelllevel[i]);
} }
} }
} }
} }
} }
/* items */ /* items */
pr = 0; pr = 0;
if (f == u->faction || omniscient(u->faction)) { if (f == u->faction || omniscient(u->faction)) {

View File

@ -740,72 +740,6 @@ random_growl(void)
extern attrib_type at_direction; extern attrib_type at_direction;
static void
make_ponnuki(void)
{
int ponn = atoi36("ponn");
unit * u = ufindhash(ponn);
region * r = findregion(-67,-5);
if (u || !r) return;
u = createunit(r, findfaction(MONSTER_FACTION), 1, new_race[RC_ILLUSION]);
u->irace = new_race[RC_GOBLIN];
set_string(&u->name, "Ponnuki");
set_string(&u->display, "Go, Ponnuki, Go.");
uunhash(u);
u->no = ponn;
uhash(u);
/* 'andere' ponnukis mit eigener nummer */
ponn = atoi36("255x");
do {
u = ufindhash(ponn);
if (!u) break;
uunhash(u);
u->no = newunitid();
uhash(u);
} while (u);
}
static void ponnuki(unit * u)
{
const char* joke[] = {
"Ein Bummerang ist, wenn man ihn wegwirft und er kommt nicht wieder, dann war's keiner.",
"Ein Riese und ein Zwerg sitzen an der Bar und trinken Bier. Der Zwerg spuckt - tftftf - dem Riesen ins Bier.\n"
"Riese: Hör auf, oder ich reiß Dir ein Ohr ab!\n"
"Zwerg: Mir egal, bei uns Zwergen wachsen die Ohren nach! - tftftf\n"
"Riese: Wenn Du nicht sofort aufhörst, reiße ich Dir ein Bein aus!\n"
"Zwerg: Na und, bei uns Zwergen wachsen Beine nach - tftftf\n"
"Riese: Jetzt reichts aber wirklich! Schluß, oder ich reiße Dir den\n"
"Schniedel aus.\n"
"Zwerg: Probier's doch, wir Zwerge haben gar keinen Schniedel - tftftf\n"
"Riese (verblüfft): So, und wie pinkelt Ihr dann???\n"
"Zwerg: tftftf",
"Ein Ingenieur und ein Mathematiker sitzen zusammen in einem Vortrag über Kulza-Klein Theorie, die sich mit\n"
"11, 12 und sogar höheren Dimensionen beschäftig. Der Mathematiker geniesst die Vorlesung, während der\n"
"Ingenieur immer mehr verwirrt aussieht. Als der Vortrag zu ende ist, hat der Ingenieur schreckliche\n"
"Kopfschmerzen davon.\n"
"\n"
"Ingenieur: Wie kannst du nur diesen schrecklichen, abgehobenen Vortrag verstehen?\n"
"Mathematiker: Ich stelle mir das ganze einfach vor.\n"
"Ingenieur: Wie kannst du dir einen 11-dimensionalen Raum vorstellen???\n"
"Mathematiker: Nun, ich stelle mir einen n-dimensionalen Raum vor und lasse dann n gegen 11 gehen..",
"Merke: Mit Schwabenwitzen soll man ganz sparsam sein.",
"F: Was bekommt man, wenn man Katzen und Elfen kreuzt?\nA: Elfen ohne Rheuma.",
"F: Was bekommt man, wenn man Insekten und Katzen kreuzt?\nA: Tiger, die Crisan benutzen.",
NULL };
int jokes = 0;
while(joke[jokes]) jokes++;
if (jokes) addmessage(u->region, 0, joke[rand() % jokes], MSG_MESSAGE, ML_IMPORTANT);
}
static void static void
learn_monster(unit *u) learn_monster(unit *u)
{ {
@ -981,13 +915,10 @@ void
plan_monsters(void) plan_monsters(void)
{ {
region *r; region *r;
faction *f;
unit *u; unit *u;
attrib *ta; attrib *ta;
u = findunitg(atoi36("ponn"), NULL); faction *f = findfaction(MONSTER_FACTION);
if (!u) make_ponnuki();
f = findfaction(MONSTER_FACTION);
if (!f) if (!f)
return; return;
@ -1065,10 +996,6 @@ plan_monsters(void)
/* Ab hier noch nicht generalisierte Spezialbehandlungen. */ /* Ab hier noch nicht generalisierte Spezialbehandlungen. */
switch (old_race(u->race)) { switch (old_race(u->race)) {
case RC_ILLUSION:
if (u->no==atoi36("ponn")) ponnuki(u);
break;
/* Alp */
case RC_ALP: case RC_ALP:
monster_seeks_target(r, u); monster_seeks_target(r, u);
break; break;

View File

@ -960,7 +960,7 @@ move_iceberg(region *r)
} }
} }
void static void
move_icebergs(void) move_icebergs(void)
{ {
region *r; region *r;
@ -987,6 +987,7 @@ create_icebergs(void)
region *rc; region *rc;
unit *u; unit *u;
freset(r, RF_DH);
for (dir=0; dir < MAXDIRECTIONS; dir++) { for (dir=0; dir < MAXDIRECTIONS; dir++) {
rc = rconnect(r, dir); rc = rconnect(r, dir);
if (rc && rterrain(rc) == T_OCEAN) { if (rc && rterrain(rc) == T_OCEAN) {
@ -1009,7 +1010,7 @@ create_icebergs(void)
} }
} }
void static void
godcurse(void) godcurse(void)
{ {
region *r; region *r;
@ -1076,6 +1077,88 @@ check_split(void)
} }
} }
/** handles the "orcish" curse that makes units grow like old orks
* This would probably be better handled in an age-function for the curse,
* but it's now being called by randomevents()
*/
static void
orc_growth(void)
{
region * r;
for (r = regions; r; r = r->next) {
unit *u;
for (u = r->units; u; u = u->next) {
curse *c = get_curse(u->attribs, ct_find("orcish"));
if (c && !has_skill(u, SK_MAGIC) && !has_skill(u, SK_ALCHEMY)) {
int n;
int increase = 0;
int num = get_cursedmen(u, c);
int prob = curse_geteffect(c);
for (n = (num - get_item(u, I_CHASTITY_BELT)); n > 0; n--) {
if (rand() % 100 < prob) {
++increase;
}
}
if (increase) {
set_number(u, u->number + increase);
u->hp += unit_max_hp(u) * increase;
ADDMSG(&u->faction->msgs, msg_message("orcgrowth",
"unit amount race", u, increase, u->race));
}
}
}
}
}
/** Talente von Dämonen verschieben sich.
*/
static void
demon_skillchanges(void)
{
region * r;
for (r = regions; r; r = r->next) {
unit * u;
for (u = r->units; u; u = u->next) {
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) {
reduce_skill(u, sv, weeks);
} else {
while (weeks--) learn_skill(u, sv->id, 1.0);
}
if (sv->old>sv->level) {
log_printf("%s dropped from %u to %u:%u in %s\n",
unitname(u), sv->old, sv->level,
sv->weeks, skillname(sv->id, NULL));
}
}
++sv;
}
}
}
}
}
/** Eisberge entstehen und bewegen sich.
* Einheiten die im Wasser landen, ertrinken.
*/
static void
icebergs(void)
{
region * r;
create_icebergs();
move_icebergs();
for (r=regions; r; r=r->next) {
drown(r);
}
}
void void
randomevents(void) randomevents(void)
{ {
@ -1084,67 +1167,10 @@ randomevents(void)
building *b, *b2; building *b, *b2;
unit *u; unit *u;
/* Eiseberge */ icebergs();
for (r=regions; r; r=r->next) freset(r, RF_DH); godcurse();
create_icebergs(); orc_growth();
move_icebergs(); demon_skillchanges();
godcurse();
for (r=regions; r; r=r->next) {
drown(r);
}
for (r = regions; r; r = r->next) {
for (u = r->units; u; u = u->next) {
curse *c = get_curse(u->attribs, ct_find("orcish"));
if (c && !has_skill(u, SK_MAGIC) && !has_skill(u, SK_ALCHEMY)) {
int n;
int increase = 0;
int num = get_cursedmen(u, c);
int prob = curse_geteffect(c);
for (n = (num - get_item(u, I_CHASTITY_BELT)); n > 0; n--) {
if (rand() % 100 < prob) {
++increase;
}
}
if (increase) {
set_number(u, u->number + increase);
u->hp += unit_max_hp(u) * increase;
ADDMSG(&u->faction->msgs, msg_message("orcgrowth",
"unit amount race", u, increase, u->race));
}
}
}
}
/* Talentverschiebung: Talente von Dämonen verschieben sich */
for (r = regions; r; r = r->next) {
for (u = r->units; u; u = u->next) {
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) {
reduce_skill(u, sv, weeks);
} else {
while (weeks--) learn_skill(u, sv->id, 1.0);
}
if (sv->old>sv->level) {
log_printf("%s dropped from %u to %u:%u in %s\n",
unitname(u), sv->old, sv->level,
sv->weeks, skillname(sv->id, NULL));
}
}
++sv;
}
}
}
}
#if RACE_ADJUSTMENTS == 0 #if RACE_ADJUSTMENTS == 0
/* Orks vermehren sich */ /* Orks vermehren sich */

View File

@ -1218,7 +1218,10 @@ init_tokens_str(const char * initstr)
void void
init_tokens(const struct order * ord) init_tokens(const struct order * ord)
{ {
init_tokens_str(getcommand(ord)); static char * cmd = NULL;
if (cmd!=NULL) free(cmd);
cmd = getcommand(ord);
init_tokens_str(cmd);
} }
void void

View File

@ -378,7 +378,7 @@ typedef struct ursprung {
/* ----------------- Befehle ----------------------------------- */ /* ----------------- Befehle ----------------------------------- */
typedef int keyword_t; typedef unsigned char keyword_t;
enum { enum {
K_KOMMENTAR, K_KOMMENTAR,
K_BANNER, K_BANNER,

View File

@ -233,9 +233,6 @@
<File <File
RelativePath=".\order.h"> RelativePath=".\order.h">
</File> </File>
<File
RelativePath=".\orders.h">
</File>
<File <File
RelativePath=".\pathfinder.h"> RelativePath=".\pathfinder.h">
</File> </File>
@ -354,9 +351,6 @@
<File <File
RelativePath=".\order.c"> RelativePath=".\order.c">
</File> </File>
<File
RelativePath=".\orders.c">
</File>
<File <File
RelativePath=".\pathfinder.c"> RelativePath=".\pathfinder.c">
</File> </File>

View File

@ -1859,7 +1859,7 @@ add_spellparameter(region *target_r, unit *u, const char *syntax, struct order *
par = calloc(1, sizeof(spellparameter)); par = calloc(1, sizeof(spellparameter));
/* Temporären Puffer initialisieren */ /* Temporären Puffer initialisieren */
tbuf = strdup(getcommand(ord)); tbuf = getcommand(ord);
/* Tokens zählen */ /* Tokens zählen */
token = strtok(tbuf, " "); token = strtok(tbuf, " ");
@ -1867,6 +1867,7 @@ add_spellparameter(region *target_r, unit *u, const char *syntax, struct order *
par->length++; par->length++;
token = strtok(NULL, " "); token = strtok(NULL, " ");
} }
free(tbuf);
/* length sollte nun nur noch die Anzahl der für den Zauber relevanten /* length sollte nun nur noch die Anzahl der für den Zauber relevanten
* Elemente enthalten */ * Elemente enthalten */
par->length -= skip; /* Anzahl der Elemente ('temp 123' sind zwei!) */ par->length -= skip; /* Anzahl der Elemente ('temp 123' sind zwei!) */
@ -1877,7 +1878,6 @@ add_spellparameter(region *target_r, unit *u, const char *syntax, struct order *
/* Fehler: Ziel vergessen */ /* Fehler: Ziel vergessen */
cmistake(u, ord, 203, MSG_MAGIC); cmistake(u, ord, 203, MSG_MAGIC);
/* Aufräumen */ /* Aufräumen */
free(tbuf);
free(par); free(par);
return 0; return 0;
} }
@ -1886,7 +1886,7 @@ add_spellparameter(region *target_r, unit *u, const char *syntax, struct order *
par->param = calloc(par->length, sizeof(spllprm *)); par->param = calloc(par->length, sizeof(spllprm *));
/* Tokens zuweisen */ /* Tokens zuweisen */
strcpy(tbuf, getcommand(ord)); tbuf = getcommand(ord);
token = strtok (tbuf, " "); token = strtok (tbuf, " ");
while(token && syntax[c] != 0) { while(token && syntax[c] != 0) {
if (i > skip) { if (i > skip) {
@ -2216,6 +2216,7 @@ add_spellparameter(region *target_r, unit *u, const char *syntax, struct order *
i++; i++;
token = strtok(NULL, " "); token = strtok(NULL, " ");
} }
free(tbuf);
/* im Endeffekt waren es nur l parameter */ /* im Endeffekt waren es nur l parameter */
par->length = l; par->length = l;
@ -2226,14 +2227,10 @@ add_spellparameter(region *target_r, unit *u, const char *syntax, struct order *
/* Syntax Error. */ /* Syntax Error. */
cmistake(u, ord, 209, MSG_MAGIC); cmistake(u, ord, 209, MSG_MAGIC);
/* Aufräumen */ /* Aufräumen */
free(tbuf);
free_spellparameter(par); free_spellparameter(par);
return 0; return 0;
} }
/* Aufräumen */
free(tbuf);
return par; return par;
} }

View File

@ -21,6 +21,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static const struct locale * locale_array[16];
static int nlocales = 0;
#undef SHORT_STRINGS
keyword_t keyword_t
get_keyword(const order * ord) get_keyword(const order * ord)
{ {
@ -30,17 +35,35 @@ get_keyword(const order * ord)
return ord->_keyword; return ord->_keyword;
} }
const char * char *
getcommand(const order * ord) getcommand(const order * ord)
{ {
return ord->_str; char sbuffer[DISPLAYSIZE*2];
char * str = sbuffer;
assert(ord->_lindex<nlocales);
if (ord->_persistent) *str++ = '@';
#ifdef SHORT_STRINGS
if (ord->_keyword!=NOKEYWORD) {
const struct locale * lang = locale_array[ord->_lindex];
strcpy(str, LOC(lang, keywords[ord->_keyword]));
str += strlen(str);
if (ord->_str) {
*str++ = ' ';
*str = 0;
}
}
#endif
strcpy(str, ord->_str);
return strdup(sbuffer);
} }
void void
free_order(order * ord) free_order(order * ord)
{ {
if (ord!=NULL && --ord->_refcount==0) { if (ord!=NULL && --ord->_refcount==0) {
free(ord->_str); if (ord->_str!=NULL) free(ord->_str);
free(ord); free(ord);
} }
} }
@ -73,37 +96,69 @@ free_orders(order ** olist)
order * order *
parse_order(const char * s, const struct locale * lang) parse_order(const char * s, const struct locale * lang)
{ {
while (isspace(*s)) ++s; while (isspace(*(unsigned char*)s)) ++s;
if (*s==0) return NULL; if (*s==0) return NULL;
else { else {
order * ord = (order*)malloc(sizeof(order)); const char * sptr;
ord->_str = strdup(s); order * ord = (order*)malloc(sizeof(order));
ord->_keyword = findkeyword(parse_token(&s), lang); int i;
ord->_refcount = 1;
ord->next = NULL; for (i=0;i!=nlocales;++i) {
return ord; if (locale_array[i]==lang) break;
}
if (i==nlocales) locale_array[nlocales++] = lang;
ord->_lindex = (unsigned char)i;
ord->_str = NULL;
ord->_persistent = 0;
ord->_refcount = 1;
ord->next = NULL;
#ifdef AT_PERSISTENT
if (*s=='@') {
ord->_persistent = 1;
#ifdef SHORT_STRINGS
++s;
#endif
}
#endif
sptr = s;
ord->_keyword = findkeyword(parse_token(&sptr), lang);
#ifdef SHORT_STRINGS
if (ord->_keyword==NOKEYWORD) {
ord->_str = strdup(s);
} else {
while (isspace(*(unsigned char*)sptr)) ++sptr;
if (*sptr) {
ord->_str = strdup(sptr);
}
}
#else
ord->_str = strdup(s);
#endif
return ord;
} }
} }
boolean boolean
is_persistent(const order * cmd) is_persistent(const order * cmd)
{ {
#ifdef AT_PERSISTENT
if (cmd->_str[0] == '@') return true;
#endif /* Nur kurze Befehle! */
switch (cmd->_keyword) { switch (cmd->_keyword) {
case K_KOMMENTAR: case NOKEYWORD:
case K_LIEFERE: return false;
return true; case K_KOMMENTAR:
break; case K_LIEFERE:
return true;
} }
#ifdef AT_PERSISTENT
if (cmd->_persistent) return true;
#endif /* Nur kurze Befehle! */
return false; return false;
} }
char * char *
write_order(const order * cmd, const struct locale * lang, char * buffer, size_t size) write_order(const order * ord, const struct locale * lang, char * buffer, size_t size)
{ {
if (cmd==0) { if (ord==0 || ord->_keyword==NOKEYWORD) {
buffer[0]=0; buffer[0]=0;
} else { } else {
#ifndef NDEBUG #ifndef NDEBUG

View File

@ -30,7 +30,9 @@ typedef struct order {
/* do not access this data: */ /* do not access this data: */
char * _str; char * _str;
keyword_t _keyword; keyword_t _keyword;
int _refcount; int _lindex : 7;
int _persistent : 1;
int _refcount : 16;
} order; } order;
/* constructor */ /* constructor */
@ -44,7 +46,7 @@ extern void free_orders(struct order ** olist);
/* access functions for orders */ /* access functions for orders */
extern keyword_t get_keyword(const struct order * ord); extern keyword_t get_keyword(const struct order * ord);
extern void set_order(struct order ** destp, struct order * src); extern void set_order(struct order ** destp, struct order * src);
extern const char * getcommand(const struct order * ord); extern char * getcommand(const struct order * ord);
extern boolean is_persistent(const struct order *ord); extern boolean is_persistent(const struct order *ord);
extern char * write_order(const struct order * ord, const struct locale * lang, char * buffer, size_t size); extern char * write_order(const struct order * ord, const struct locale * lang, char * buffer, size_t size);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1,18 +0,0 @@
/* vi: set ts=2:
*
*
* Eressea PB(E)M host Copyright (C) 1998-2003
* Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de)
* Henning Peters (faroul@beyond.kn-bremen.de)
* Enno Rehling (enno@eressea-pbem.de)
* Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
*
* This program may not be used, modified or distributed without
* prior permission by the authors of Eressea.
*/
#include <config.h>
#include "eressea.h"
#include "orders.h"

View File

@ -1,18 +0,0 @@
/* vi: set ts=2:
*
*
* Eressea PB(E)M host Copyright (C) 1998-2003
* Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de)
* Henning Peters (faroul@beyond.kn-bremen.de)
* Enno Rehling (enno@eressea-pbem.de)
* Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
*
* This program may not be used, modified or distributed without
* prior permission by the authors of Eressea.
*/
#ifndef ORDERS_H
#define ORDERS_H
#endif

View File

@ -407,9 +407,11 @@ bufunit(const faction * f, const unit * u, int indent, int mode)
} }
} }
if (!isbattle && u->lastorder) { if (!isbattle && u->lastorder) {
char * cmd = getcommand(u->lastorder);
scat(", \""); scat(", \"");
scat(getcommand(u->lastorder)); scat(cmd);
scat("\""); scat("\"");
free(cmd);
} }
} }
i = 0; i = 0;

View File

@ -1095,12 +1095,13 @@ readunit(FILE * F)
free_orders(&u->orders); free_orders(&u->orders);
rs(F, buf); rs(F, buf);
while(*buf != 0) { while(*buf != 0) {
addlist(&u->orders, parse_order(buf, u->faction->locale)); order * ord = parse_order(buf, u->faction->locale);
if (ord!=NULL) addlist(&u->orders, ord);
rs(F, buf); rs(F, buf);
} }
rs(F, buf); rs(F, buf);
u->lastorder = parse_order(buf, u->faction->locale); u->lastorder = parse_order(buf, u->faction->locale);
set_order(&u->thisorder, NULL); set_order(&u->thisorder, NULL);
assert(u->number >= 0); assert(u->number >= 0);
assert(u->race); assert(u->race);
@ -1200,7 +1201,8 @@ writeunit(FILE * F, const unit * u)
wi(F, u->flags & UFL_SAVEMASK); wi(F, u->flags & UFL_SAVEMASK);
wnl(F); wnl(F);
for (ord = u->orders; ord; ord=ord->next) { for (ord = u->orders; ord; ord=ord->next) {
if (is_persistent(ord)) writeorder(ord, u->faction->locale, F); if (is_persistent(ord) && get_keyword(ord)!=NOKEYWORD) {
writeorder(ord, u->faction->locale, F);
} }
ws(F, ""); /* Abschluß der persistenten Befehle */ ws(F, ""); /* Abschluß der persistenten Befehle */
writeorder(u->lastorder, u->faction->locale, F); writeorder(u->lastorder, u->faction->locale, F);

View File

@ -807,15 +807,15 @@ u_setfaction(unit * u, faction * f)
{ {
int cnt = u->number; int cnt = u->number;
if (u->faction==f) return; if (u->faction==f) return;
if (u->faction) { if (u->faction) {
set_number(u, 0); set_number(u, 0);
--u->faction->no_units; --u->faction->no_units;
join_group(u, NULL); join_group(u, NULL);
free_orders(&u->orders); free_orders(&u->orders);
set_order(&u->thisorder, NULL); set_order(&u->thisorder, NULL);
set_order(&u->lastorder, NULL); set_order(&u->lastorder, NULL);
} }
if (u->prevF) u->prevF->nextF = u->nextF; if (u->prevF) u->prevF->nextF = u->nextF;
else if (u->faction) { else if (u->faction) {
assert(u->faction->units==u); assert(u->faction->units==u);
u->faction->units = u->nextF; u->faction->units = u->nextF;

View File

@ -87,10 +87,12 @@ do_command_i(const struct tnode * keys, void * u, const char * str, struct order
} }
} }
extern const char * getcommand(struct order * ord); extern char * getcommand(struct order * ord);
void void
do_command(const struct tnode * keys, void * u, struct order * ord) do_command(const struct tnode * keys, void * u, struct order * ord)
{ {
do_command_i(keys, u, getcommand(ord), ord); char * cmd = getcommand(ord);
do_command_i(keys, u, cmd, ord);
free(cmd);
} }

View File

@ -22,10 +22,10 @@ public:
static faction * value(faction_list * node) { return node->data; } static faction * value(faction_list * node) { return node->data; }
}; };
static eressea::list<faction, faction_list, factionlist_iterator> static eressea::list<faction *, faction_list *, factionlist_iterator>
alliance_factions(const alliance& al) alliance_factions(const alliance& al)
{ {
return eressea::list<faction, faction_list, factionlist_iterator>(al.members); return eressea::list<faction *, faction_list *, factionlist_iterator>(al.members);
} }
static alliance * static alliance *
@ -34,9 +34,9 @@ add_alliance(int id, const char * name)
return makealliance(id, name); return makealliance(id, name);
} }
static eressea::list<alliance> static eressea::list<alliance *>
get_alliances(void) { get_alliances(void) {
return eressea::list<alliance>(alliances); return eressea::list<alliance *>(alliances);
} }
void void

View File

@ -146,6 +146,13 @@ race_setscript(const char * rcname, const functor<void>& f)
} }
} }
#ifdef LUABIND_NO_EXCEPTIONS
static void
error_callback(lua_State * L)
{
}
#endif
void void
bind_eressea(lua_State * L) bind_eressea(lua_State * L)
{ {
@ -177,4 +184,7 @@ bind_eressea(lua_State * L)
/* planes not really implemented */ /* planes not really implemented */
def("get_plane_id", &find_plane_id) def("get_plane_id", &find_plane_id)
]; ];
#ifdef LUABIND_NO_EXCEPTIONS
luabind::set_error_callback(error_callback);
#endif
} }

View File

@ -32,9 +32,9 @@ add_faction(const char * email, const char * racename, const char * lang)
return f; return f;
} }
static eressea::list<faction> static eressea::list<faction *>
get_factions(void) { get_factions(void) {
return eressea::list<faction>(factions); return eressea::list<faction *>(factions);
} }
class factionunit { class factionunit {
@ -43,10 +43,10 @@ public:
static unit * value(unit * node) { return node; } static unit * value(unit * node) { return node; }
}; };
static eressea::list<unit, unit, factionunit> static eressea::list<unit *, unit *, factionunit>
faction_units(const faction& f) faction_units(const faction& f)
{ {
return eressea::list<unit, unit, factionunit>(f.units); return eressea::list<unit *, unit *, factionunit>(f.units);
} }
#ifdef ALLIANCES #ifdef ALLIANCES

View File

@ -6,8 +6,8 @@ namespace eressea {
template<class T, class N = T> template<class T, class N = T>
class listnode { class listnode {
public: public:
static N * next(N * node) { return node->next; } static N next(N& node) { return node->next; }
static T * value(N * node) { return node; } static T value(N& node) { return node; }
}; };
template<class T, class N = T, class nodetype = listnode<T, N> > template<class T, class N = T, class nodetype = listnode<T, N> >
@ -15,8 +15,8 @@ namespace eressea {
public: public:
class iterator { class iterator {
public: public:
iterator(N * index) : m_index(index) {} iterator(const N& index) : m_index(index) {}
T * operator*() { return nodetype::value(m_index); } T operator*() { return nodetype::value(m_index); }
bool operator==(const iterator& iter) { bool operator==(const iterator& iter) {
return iter.m_index==m_index; return iter.m_index==m_index;
} }
@ -25,15 +25,15 @@ namespace eressea {
return *this; return *this;
} }
private: private:
N * m_index; N m_index;
}; };
typedef iterator const_iterator; typedef iterator const_iterator;
list<T, N, nodetype>(N * clist) : m_clist(clist) {} list<T, N, nodetype>(const N& clist) : m_clist(clist) {}
iterator begin() const { return iterator(m_clist); } iterator begin() const { return iterator(m_clist); }
iterator end() const { return iterator(NULL); } iterator end() const { return iterator(NULL); }
public: public:
N * m_clist; N m_clist;
}; };
}; };

View File

@ -17,24 +17,24 @@
#include <ostream> #include <ostream>
using namespace luabind; using namespace luabind;
static eressea::list<region> static eressea::list<region *>
get_regions(void) { get_regions(void) {
return eressea::list<region>(regions); return eressea::list<region *>(regions);
} }
static eressea::list<unit> static eressea::list<unit *>
region_units(const region& r) { region_units(const region& r) {
return eressea::list<unit>(r.units); return eressea::list<unit *>(r.units);
} }
static eressea::list<building> static eressea::list<building *>
region_buildings(const region& r) { region_buildings(const region& r) {
return eressea::list<building>(r.buildings); return eressea::list<building *>(r.buildings);
} }
static eressea::list<ship> static eressea::list<ship *>
region_ships(const region& r) { region_ships(const region& r) {
return eressea::list<ship>(r.ships); return eressea::list<ship *>(r.ships);
} }
static void static void

View File

@ -26,6 +26,7 @@
#include <luabind/iterator_policy.hpp> #include <luabind/iterator_policy.hpp>
#include <ostream> #include <ostream>
#include <string>
using namespace luabind; using namespace luabind;
class bind_spell_ptr { class bind_spell_ptr {
@ -34,12 +35,12 @@ public:
static spell * value(spell_ptr * node) { return find_spellbyid(node->spellid); } static spell * value(spell_ptr * node) { return find_spellbyid(node->spellid); }
}; };
static eressea::list<spell, spell_ptr, bind_spell_ptr> static eressea::list<spell *, spell_ptr *, bind_spell_ptr>
unit_spells(const unit& u) { unit_spells(const unit& u) {
sc_mage * mage = get_mage(&u); sc_mage * mage = get_mage(&u);
if (mage==NULL) return eressea::list<spell, spell_ptr, bind_spell_ptr>(NULL); if (mage==NULL) return eressea::list<spell *, spell_ptr *, bind_spell_ptr>(NULL);
spell_ptr * splist = mage->spellptr; spell_ptr * splist = mage->spellptr;
return eressea::list<spell, spell_ptr, bind_spell_ptr>(splist); return eressea::list<spell *, spell_ptr *, bind_spell_ptr>(splist);
} }
class bind_spell_list { class bind_spell_list {
@ -48,10 +49,26 @@ public:
static spell * value(spell_list * node) { return node->data; } static spell * value(spell_list * node) { return node->data; }
}; };
static eressea::list<spell, spell_list, bind_spell_list> static eressea::list<spell *, spell_list *, bind_spell_list>
unit_familiarspells(const unit& u) { unit_familiarspells(const unit& u) {
spell_list * spells = familiarspells(u.race); spell_list * spells = familiarspells(u.race);
return eressea::list<spell, spell_list, bind_spell_list>(spells); return eressea::list<spell *, spell_list *, bind_spell_list>(spells);
}
class bind_orders {
public:
static order * next(order * node) { return node->next; }
static std::string value(order * node) {
char * cmd = getcommand(node);
std::string s(cmd);
free(cmd);
return s;
}
};
static eressea::list<std::string, order *, bind_orders>
unit_orders(const unit& u) {
return eressea::list<std::string, order *, bind_orders>(u.orders);
} }
static unit * static unit *
@ -211,6 +228,23 @@ unit_getregion(const unit& u)
return u.region; return u.region;
} }
static int
unit_getid(const unit& u)
{
return u.no;
}
static void
unit_setid(unit& u, int id)
{
unit * nu = findunit(id);
if (nu==NULL) {
uunhash(&u);
u.no = id;
uhash(&u);
}
}
static const char * static const char *
unit_getname(const unit& u) unit_getname(const unit& u)
{ {
@ -223,6 +257,18 @@ unit_setname(unit& u, const char * name)
set_string(&u.name, name); set_string(&u.name, name);
} }
static const char *
unit_getinfo(const unit& u)
{
return u.display;
}
static void
unit_setinfo(unit& u, const char * info)
{
set_string(&u.display, info);
}
static std::ostream& static std::ostream&
operator<<(std::ostream& stream, unit& u) operator<<(std::ostream& stream, unit& u)
{ {
@ -319,15 +365,21 @@ bind_unit(lua_State * L)
def("add_unit", &add_unit), def("add_unit", &add_unit),
class_<struct unit>("unit") class_<struct unit>("unit")
.property("name", &unit_getname, &unit_setname)
.def(tostring(self)) .def(tostring(self))
.def(self == unit()) .def(self == unit())
.property("name", &unit_getname, &unit_setname)
.property("info", &unit_getinfo, &unit_setinfo)
.property("id", &unit_getid, &unit_setid)
.def_readonly("faction", &unit::faction) .def_readonly("faction", &unit::faction)
.def_readonly("id", &unit::no)
.def_readwrite("hp", &unit::hp) .def_readwrite("hp", &unit::hp)
.def_readwrite("status", &unit::status) .def_readwrite("status", &unit::status)
// orders:
.def("add_order", &unit_addorder) .def("add_order", &unit_addorder)
.def("clear_orders", &unit_clearorders) .def("clear_orders", &unit_clearorders)
.property("orders", &unit_orders, return_stl_iterator)
// items:
.def("get_item", &unit_getitem) .def("get_item", &unit_getitem)
.def("add_item", &unit_additem) .def("add_item", &unit_additem)
.def("get_skill", &unit_getskill) .def("get_skill", &unit_getskill)

View File

@ -142,6 +142,7 @@ static int nowrite = 0;
static boolean g_writemap = false; static boolean g_writemap = false;
static boolean opt_reportonly = false; static boolean opt_reportonly = false;
static const char * luafile = "default.lua"; static const char * luafile = "default.lua";
static const char * script_path = NULL;
struct settings global = { struct settings global = {
"Eressea", /* gamename */ "Eressea", /* gamename */
@ -272,6 +273,7 @@ lua_init(void)
luaopen_math(luaState); luaopen_math(luaState);
luaopen_string(luaState); luaopen_string(luaState);
luaopen_io(luaState); luaopen_io(luaState);
luaopen_table(luaState);
luabind::open(luaState); luabind::open(luaState);
bind_eressea(luaState); bind_eressea(luaState);
bind_spell(luaState); bind_spell(luaState);
@ -590,7 +592,7 @@ read_args(int argc, char **argv, lua_State * luaState)
} }
break; break;
case 'l': case 'l':
log_open(argv[++i]); script_path = argv[++i];
break; break;
case 'w': case 'w':
g_writemap = true; g_writemap = true;
@ -605,6 +607,7 @@ read_args(int argc, char **argv, lua_State * luaState)
/* add some more variables to the lua globals */ /* add some more variables to the lua globals */
setLuaString(luaState, "datapath", datapath()); setLuaString(luaState, "datapath", datapath());
setLuaString(luaState, "scriptpath", script_path);
setLuaString(luaState, "basepath", basepath()); setLuaString(luaState, "basepath", basepath());
setLuaString(luaState, "reportpath", reportpath()); setLuaString(luaState, "reportpath", reportpath());
setLuaString(luaState, "resourcepath", resourcepath()); setLuaString(luaState, "resourcepath", resourcepath());
@ -663,8 +666,25 @@ main(int argc, char *argv[])
// run the main script // run the main script
if (luafile==NULL) lua_console(luaState); if (luafile==NULL) lua_console(luaState);
else lua_dofile(luaState, luafile); else {
try {
if (script_path) {
sprintf(buf, "%s/%s", script_path, luafile);
lua_dofile(luaState, buf);
}
else lua_dofile(luaState, luafile);
}
catch (luabind::error& e) {
lua_State* L = e.state();
const char* error = lua_tostring(L, -1);
log_error((error));
lua_pop(L, 1);
std::terminate();
// L will now point to the destructed
// lua state and be invalid
/* ... */
}
}
#ifdef CLEANUP_CODE #ifdef CLEANUP_CODE
game_done(); game_done();
#endif #endif

78
src/scripts/eressea.lua Normal file
View File

@ -0,0 +1,78 @@
function write_emails()
local locales = { "de", "en" }
local files = {}
local key
for key in locales do
local locale = locales[key]
files[locale] = io.open(basepath .. "/emails." .. locale, "w")
end
local faction
for faction in factions() do
-- print(faction.id .. " - " .. faction.locale)
files[faction.locale]:write(faction.email .. "\n")
end
for key in files do
files[key]:close()
end
end
function process(orders)
file = "" .. get_turn()
if read_game(file)~=0 then
print("could not read game")
return -1
end
-- initialize starting equipment for new players
-- probably not necessary, since mapper sets new players, not server
add_equipment("conquesttoken", 1);
add_equipment("wood", 30);
add_equipment("stone", 30);
add_equipment("money", 2000 + get_turn() * 10);
-- initialize other scripts
local magrathea = get_region(-67, -5)
if magrathea~=nil and init_ponnuki~=nil then
init_ponnuki(magrathea)
return
end
-- run the turn:
read_orders(orders)
plan_monsters()
process_orders()
write_passwords()
write_reports()
write_emails()
file = "" .. get_turn()
if write_game(file)~=0 then
print("could not write game")
return -1
end
end
--
-- main body of script
--
scripts= { "ponnuki.lua" }
-- orderfile: contains the name of the orders.
if orderfile==nil then
print "you must specify an orderfile"
else
for index in scripts do
local script = scriptpath .. scripts[index]
if pcall(dofile, script)==0 then
print("Could not load " .. script)
end
end
process(orderfile)
end

34
src/scripts/ponnuki.lua Normal file
View File

@ -0,0 +1,34 @@
function ponnuki_brain(u)
jokes = {
"Ein Bummerang ist, wenn man ihn wegwirft und er kommt nicht wieder, dann war's keiner.",
"Merke: Mit Schwabenwitzen soll man ganz sparsam sein.",
"Was bekommt man, wenn man Katzen und Elfen kreuzt? Elfen ohne Rheuma.",
"Was bekommt man, wenn man Insekten und Katzen kreuzt? Tiger, die Crisan benutzen."
}
local i = math.random(table.getn(jokes))
u.region:add_notice(jokes[i])
local d = math.random(6)
r = u.region:next(d-1)
u:clear_orders()
directions = { "NW", "NO", "O", "SO", "SW", "W" }
u:add_order("NACH " .. directions[d])
end
function init_ponnuki(home)
local f = get_faction(0)
local u = get_unit(atoi36("ponn"))
if u == nil then
u = add_unit(f, home)
u.id = atoi36("ponn")
u.name = "Ponnuki"
u.info = "Go, Ponnuki, Go!"
u.race = "illusion"
u:set_racename("Ritter von Go")
end
if u.faction==f then
u:set_brain(ponnuki_brain)
end
end

View File

@ -130,12 +130,26 @@ function test_write()
end end
function move_north(u) function move_north(u)
for order in u.orders do
print(order)
end
u:clear_orders() u:clear_orders()
u:add_order("NACH NORDEN") u:add_order("NACH NORDEN")
end end
function test_monsters() function test_monsters()
read_game("23") read_game("23")
-- magrathea = get_region(-67, -5)
local magrathea = get_region(0, 0)
if magrathea ~= nil then
if pcall(dofile, scriptpath .. "/ponnuki.lua") then
init_ponnuki(magrathea)
else
print("could not open ponnuki")
end
end
set_brain("braineater", move_north) set_brain("braineater", move_north)
plan_monsters() plan_monsters()
process_orders() process_orders()