From 9dbee6954413d65fe7832a53f27be62f71713522 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 16 Dec 2008 09:17:59 +0000 Subject: [PATCH] alternative bindings for tolua --- src/combined/bindings.cpp | 3 + src/combined/gamecode.c | 5 + src/common/gamecode/creport.c | 16 - src/common/gamecode/laws.c | 64 -- src/common/gamecode/report.c | 25 - src/common/kernel/alliance.c | 43 +- src/common/kernel/alliance.h | 1 + src/common/kernel/building.c | 12 + src/common/kernel/building.h | 6 +- src/common/kernel/faction.c | 83 ++- src/common/kernel/faction.h | 21 +- src/common/kernel/move.c | 3 - src/common/kernel/region.c | 26 +- src/common/kernel/region.h | 9 +- src/common/kernel/save.c | 36 -- src/common/kernel/ship.c | 10 +- src/common/kernel/ship.h | 5 +- src/common/kernel/unit.c | 35 +- src/common/kernel/unit.h | 7 + src/common/modules/xecmd.c | 3 +- src/common/settings-eressea.h | 8 + src/common/spells/combatspells.c | 6 +- src/common/spells/spells.c | 22 +- src/common/spells/spells.h | 2 + src/eressea.vcproj | 2 +- src/eressea/eressea-lua.vcproj | 24 + src/eressea/lua/building.cpp | 4 +- src/eressea/lua/gamecode.cpp | 10 - src/eressea/lua/region.cpp | 11 - src/eressea/lua/script.cpp | 5 - src/eressea/lua/script.h | 1 - src/eressea/lua/unit.cpp | 26 - src/eressea/server.cpp | 49 +- src/eressea/tolua/bindings.c | 1020 ++++++++++++++++++++++++++++++ src/eressea/tolua/bindings.h | 22 + src/eressea/tolua/helpers.c | 455 +++++++++++++ src/eressea/tolua/helpers.h | 21 + src/scripts/asgard.lua | 1 - src/scripts/eressea.lua | 1 - src/scripts/hse4-run.lua | 1 - src/scripts/samples.lua | 2 - 41 files changed, 1785 insertions(+), 321 deletions(-) create mode 100644 src/eressea/tolua/bindings.c create mode 100644 src/eressea/tolua/bindings.h create mode 100644 src/eressea/tolua/helpers.c create mode 100644 src/eressea/tolua/helpers.h diff --git a/src/combined/bindings.cpp b/src/combined/bindings.cpp index 17ece108f..0447bbb31 100644 --- a/src/combined/bindings.cpp +++ b/src/combined/bindings.cpp @@ -3,6 +3,8 @@ #include "stdafx.hpp" #include "eressea/server.cpp" + +#ifndef BINDINGS_TOLUA #include "eressea/lua/alliance.cpp" #include "eressea/lua/building.cpp" #include "eressea/lua/eressea.cpp" @@ -19,3 +21,4 @@ #include "eressea/lua/spell.cpp" #include "eressea/lua/test.cpp" #include "eressea/lua/unit.cpp" +#endif diff --git a/src/combined/gamecode.c b/src/combined/gamecode.c index 1d863872b..487d8950d 100644 --- a/src/combined/gamecode.c +++ b/src/combined/gamecode.c @@ -2,6 +2,11 @@ #include "common/config.h" #include "stdafx.h" +#ifdef BINDINGS_TOLUA +#include "eressea/tolua/bindings.c" +#include "eressea/tolua/helpers.c" +#endif + #include "eressea/console.c" #include "eressea/editing.c" #include "eressea/korrektur.c" diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index 92e0f2cf1..db10aac40 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -915,19 +915,6 @@ show_allies_cr(FILE * F, const faction * f, const ally * sf) } } -#ifdef ENEMIES -static void -show_enemies(FILE * F, const faction_list* flist) -{ - for (;flist!=NULL;flist=flist->next) { - if (flist->data) { - int fno = flist->data->no; - fprintf(F, "ENEMY %u\n%u;partei\n", fno, fno); - } - } -} -#endif - /* prints all visible spells in a region */ static void show_active_spells(const region * r) @@ -1360,9 +1347,6 @@ report_computer(const char * filename, report_context * ctx, const char * charse f->options &= (~flag); } } -#ifdef ENEMIES - show_enemies(F, f->enemies); -#endif show_allies_cr(F, f, f->allies); { group * g; diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 32eddde35..26f16bc59 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -2698,66 +2698,6 @@ evict(void) } #endif -#ifdef ENEMIES -static void -declare_war(void) -{ - region *r; - for (r=regions;r;r=r->next) { - unit * u; - for (u=r->units;u;u=u->next) { - strlist *S; - faction * f = u->faction; - for (S = u->orders; S; S = S->next) { - switch (get_keyword(ord)) { - case K_WAR: - init_tokens(ord); - skip_token(); - for (;;) { - const char * s = getstrtoken(); - if (s[0]==0) break; - else { - faction * enemy = findfaction(atoi36(s)); - if (enemy) { - if (!is_enemy(f, enemy)) { - add_enemy(f, enemy); - ADDMSG(&enemy->msgs, msg_message("war_notify", "enemy", f)); - ADDMSG(&f->msgs, msg_message("war_confirm", "enemy", enemy)); - } - } else { - ADDMSG(&f->msgs, msg_message("error66", "unit region command", u, r, ord)); - } - } - } - break; - case K_PEACE: - init_tokens(ord); - skip_token(); - for (;;) { - const char * s = getstrtoken(); - if (s[0]==0) break; - else { - faction * enemy = findfaction(atoi36(s)); - if (enemy) { - if (is_enemy(f, enemy)) { - remove_enemy(f, enemy); - ADDMSG(&enemy->msgs, msg_message("peace_notify", "enemy", f)); - ADDMSG(&f->msgs, msg_message("peace_confirm", "enemy", enemy)); - } - } else { - ADDMSG(&f->msgs, msg_message("error66", "unit region command", u, r, ord)); - } - } - } - break; - default: - break; - } - } - } - } -} -#endif static int renumber_cmd(unit * u, order * ord) @@ -3911,10 +3851,6 @@ init_processor(void) #ifdef ALLIANCEJOIN p+=10; add_proc_global(p, &alliancejoin, "Allianzen"); -#endif -#ifdef ENEMIES - p+=10; - add_proc_global(p, &declare_war, "Krieg & Frieden"); #endif add_proc_order(p, K_PROMOTION, &promotion_cmd, 0, "Heldenbefoerderung"); if (!global.disabled[K_NUMBER]) { diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index f6631a08f..36cab701b 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -1591,28 +1591,6 @@ allies(FILE * F, const faction * f) } } -#ifdef ENEMIES -static void -enemies(FILE * F, const faction * f) -{ - faction_list * flist = f->enemies; - if (flist!=NULL) { - strcpy(buf, "Wir liegen im Krieg mit "); - for (;flist!=NULL;flist = flist->next) { - const faction * enemy = flist->data; - scat(factionname(enemy)); - if (flist->next) { - scat(", "); - } else { - scat("."); - } - } - rparagraph(F, buf, 0, 0, 0); - rnl(F); - } -} -#endif - static void guards(FILE * F, const region * r, const faction * see) { @@ -2169,9 +2147,6 @@ report_plaintext(const char * filename, report_context * ctx, const char * chars centre(F, LOC(f->locale, "nr_alliances"), false); rnl(F); -#ifdef ENEMIES - enemies(F, f); -#endif allies(F, f); rpline(F); diff --git a/src/common/kernel/alliance.c b/src/common/kernel/alliance.c index c848c6b54..f80a8a802 100644 --- a/src/common/kernel/alliance.c +++ b/src/common/kernel/alliance.c @@ -206,24 +206,24 @@ alliancejoin(void) void setalliance(struct faction * f, alliance * al) { - if (f->alliance==al) return; - if (f->alliance!=NULL) { - faction_list ** flistp = &f->alliance->members; - while (*flistp) { - if ((*flistp)->data==f) { - *flistp = (*flistp)->next; - break; - } - flistp = &(*flistp)->next; - } - } - f->alliance = al; - if (al!=NULL) { - faction_list * flist = calloc(sizeof(faction_list), 1); - flist->next = al->members; - flist->data = f; - al->members = flist; - } + if (f->alliance==al) return; + if (f->alliance!=NULL) { + faction_list ** flistp = &f->alliance->members; + while (*flistp) { + if ((*flistp)->data==f) { + *flistp = (*flistp)->next; + break; + } + flistp = &(*flistp)->next; + } + } + f->alliance = al; + if (al!=NULL) { + faction_list * flist = calloc(sizeof(faction_list), 1); + flist->next = al->members; + flist->data = f; + al->members = flist; + } } const char * @@ -348,3 +348,10 @@ victorycondition(const alliance * al, const char * name) } return -1; } + +void alliance_setname(alliance * self, const char * name) +{ + free(self->name); + if (name) self->name = strdup(name); + else self->name = NULL; +} \ No newline at end of file diff --git a/src/common/kernel/alliance.h b/src/common/kernel/alliance.h index bcb7c7352..84e34db3e 100644 --- a/src/common/kernel/alliance.h +++ b/src/common/kernel/alliance.h @@ -42,6 +42,7 @@ extern void alliancejoin(void); extern void alliancekick(void); extern void alliancevictory(void); +void alliance_setname(alliance * self, const char * name); extern int victorycondition(const alliance * al, const char * name); /* execute commands */ diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c index d53d59cf8..f5495e7bd 100644 --- a/src/common/kernel/building.c +++ b/src/common/kernel/building.c @@ -598,3 +598,15 @@ buildingowner(const region * r, const building * b) fset(first, UFL_OWNER); return first; } + +const char * building_getname(const building * self) +{ + return self->name; +} + +void building_setname(building * self, const char * name) +{ + free(self->name); + if (name) self->name = strdup(name); + else self->name = NULL; +} diff --git a/src/common/kernel/building.h b/src/common/kernel/building.h index 1d45a35af..358f349fe 100644 --- a/src/common/kernel/building.h +++ b/src/common/kernel/building.h @@ -110,7 +110,6 @@ extern void add_buildinglist(building_list **bl, struct building *b); extern struct attrib_type at_building_generic_type; extern const char * buildingtype(const building_type * btype, const struct building * b, int bsize); -extern const char * buildingname(const struct building * b); extern const char * write_buildingname(const building * b, char * ibuf, size_t size); extern int buildingcapacity(const struct building * b); extern struct building *new_building(const struct building_type * typ, struct region * r, const struct locale * lang); @@ -153,6 +152,11 @@ typedef struct building_action { char * param; } building_action; +extern const char * buildingname(const struct building * b); + +extern const char * building_getname(const struct building * b); +extern void building_setname(struct building * self, const char * name); + #ifdef __cplusplus } #endif diff --git a/src/common/kernel/faction.c b/src/common/kernel/faction.c index 7f9ad0077..2911ec003 100644 --- a/src/common/kernel/faction.c +++ b/src/common/kernel/faction.c @@ -137,7 +137,6 @@ addfaction(const char *email, const char * password, int subscription) { faction * f = calloc(sizeof(faction), 1); - const char * pass = itoa36(rng_int()); char buf[128]; assert(frace && frace != new_race[RC_ORC]); @@ -146,13 +145,8 @@ addfaction(const char *email, const char * password, log_error(("Invalid email address for faction %s: %s\n", itoa36(f->no), email)); } - f->override = strdup(pass); - if (password) { - f->passw = strdup(password); - } else { - pass = itoa36(rng_int()); - f->passw = strdup(pass); - } + f->override = strdup(itoa36(rng_int())); + faction_setpassword(f, password); f->lastorders = turn; f->alive = 1; @@ -374,55 +368,50 @@ update_interval(struct faction * f, struct region * r) } #endif -#ifdef ENEMIES -boolean -is_enemy(const struct faction * f, const struct faction * enemy) +const char * faction_getname(const faction * self) { - struct faction_list * flist = f->enemies; - for (;flist!=NULL;flist=flist->next) { - if (flist->data==enemy) return true; - } - return false; + return self->name; } -static void -add_enemy_i(struct faction * f, struct faction * enemy) +void faction_setname(faction * self, const char * name) { - if (!is_enemy(f, enemy)) { - struct faction_list * flist = malloc(sizeof(faction_list)); - flist->next = f->enemies; - flist->data = enemy; - f->enemies = flist; - } + free(self->name); + if (name) self->name = strdup(name); +} + +const char * faction_getemail(const faction * self) +{ + return self->email; +} + +void faction_setemail(faction * self, const char * email) +{ + free(self->email); + if (email) self->email = strdup(email); +} + +const char * faction_getbanner(const faction * self) +{ + return self->banner; +} + +void faction_setbanner(faction * self, const char * banner) +{ + free(self->banner); + if (banner) self->banner = strdup(banner); } void -add_enemy(struct faction * f, struct faction * enemy) +faction_setpassword(faction * f, const char * passw) { - add_enemy_i(f, enemy); -/* add_enemy_i(enemy, f); */ + free(f->passw); + if (passw) f->passw = strdup(passw); + else f->passw = strdup(itoa36(rng_int())); } -static void -remove_enemy_i(struct faction * f, const struct faction * enemy) +const char * +faction_getpassword(const faction * f) { - struct faction_list **pflist = &f->enemies; - while (*pflist!=NULL) { - struct faction_list * flist = *pflist; - if (flist->data==enemy) { - *pflist = flist->next; - free(flist); - } else { - pflist = &flist->next; - } - } + return f->passw; } -void -remove_enemy(struct faction * f, struct faction * enemy) -{ - remove_enemy_i(f, enemy); -/* remove_enemy_i(enemy, f); */ -} - -#endif diff --git a/src/common/kernel/faction.h b/src/common/kernel/faction.h index 4ee87361e..ea60f47f9 100644 --- a/src/common/kernel/faction.h +++ b/src/common/kernel/faction.h @@ -94,9 +94,6 @@ typedef struct faction { struct unit * units; struct attrib *attribs; struct message_list * msgs; -#ifdef ENEMIES - struct faction_list * enemies; -#endif struct bmsg { struct bmsg * next; struct region * r; @@ -123,12 +120,6 @@ extern void destroyfaction(faction * f); extern void set_alliance(struct faction * a, struct faction * b, int status); extern int get_alliance(const struct faction * a, const struct faction * b); -#ifdef ENEMIES -extern boolean is_enemy(const struct faction * f, const struct faction * enemy); -extern void add_enemy(struct faction * f, struct faction * enemy); -extern void remove_enemy(struct faction * f, struct faction * enemy); -#endif - extern void write_faction_reference(const struct faction * f, struct storage * store); extern variant read_faction_reference(struct storage * store); extern int resolve_faction(variant data, void * addr); @@ -139,6 +130,18 @@ extern void renumber_faction(faction * f, int no); extern void update_interval(struct faction * f, struct region * r); #endif +const char * faction_getbanner(const struct faction * self); +void faction_setbanner(struct faction * self, const char * name); + +const char * faction_getname(const struct faction * self); +void faction_setname(struct faction * self, const char * name); + +const char * faction_getemail(const struct faction * self); +void faction_setemail(struct faction * self, const char * email); + +const char * faction_getpassword(const struct faction * self); +void faction_setpassword(struct faction * self, const char * password); + #ifdef __cplusplus } #endif diff --git a/src/common/kernel/move.c b/src/common/kernel/move.c index 01240cc70..a08469649 100644 --- a/src/common/kernel/move.c +++ b/src/common/kernel/move.c @@ -201,9 +201,6 @@ entrance_allowed(const struct unit * u, const struct region * r) faction * owner = region_owner(r); if (owner == NULL || u->faction == owner) return true; if (alliedfaction(r->planep, owner, u->faction, HELP_TRAVEL)) return true; -#ifdef ENEMIES - if (is_enemy(u->faction, owner)) return true; -#endif return false; #else return true; diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index 8c0eef483..49169f7b4 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -800,15 +800,6 @@ r_demand(const region * r, const luxury_type * ltype) return d->value; } -void -rsetname(struct region * r, const char * name) -{ - if (r->land) { - free(r->land->name); - r->land->name = strdup(name); - } -} - const char * rname(const region * r, const struct locale * lang) { if (r->land) { @@ -1109,7 +1100,7 @@ terraform_region(region * r, const terrain_type * terrain) int mnr = 0; r->land = calloc(1, sizeof(land_region)); - rsetname(r, makename()); + region_setname(r, makename()); for (d=0;d!=MAXDIRECTIONS;++d) { region * nr = rconnect(r, d); if (nr && nr->land) { @@ -1320,3 +1311,18 @@ region_setowner(struct region * r, struct faction * owner) unused(owner); #endif } + +void +region_setname(struct region * r, const char * name) +{ + if (r->land) { + free(r->land->name); + r->land->name = strdup(name); + } +} + +const char * +region_getname(const region * r) { + if (r->land) return (const char *)r->land->name; + return NULL; +} diff --git a/src/common/kernel/region.h b/src/common/kernel/region.h index f22de63d7..efb18d8ff 100644 --- a/src/common/kernel/region.h +++ b/src/common/kernel/region.h @@ -211,14 +211,12 @@ extern boolean r_isforest(const struct region * r); #define rsetterrain(r, t) ((r)->terrain = newterrain(t)) extern const char * rname(const struct region * r, const struct locale * lang); -extern void rsetname(struct region * r, const char * name); #define rplane(r) getplane(r) extern void r_setdemand(struct region * r, const struct luxury_type * ltype, int value); extern int r_demand(const struct region * r, const struct luxury_type * ltype); -extern const char * regionname(const struct region * r, const struct faction * f); extern const char * write_regionname(const struct region * r, const struct faction * f, char * buffer, size_t size); extern struct region * new_region(short x, short y, unsigned int uid); @@ -247,6 +245,13 @@ extern variant read_region_reference(struct storage * store); extern int resolve_region_coor(variant id, void * address); extern int resolve_region_id(variant id, void * address); #define RESOLVE_REGION(version) ((versionversionenemies = NULL; - for (;;) { - int fno = store->r_id(store); - if (fno<=0) break; - else { - variant id; - faction_list * flist = malloc(sizeof(faction_list)); - flist->next = f->enemies; - f->enemies = flist; - id.i = fno; - ur_add(id, &flist->data, resolve_faction); - } - } -} - -static void -write_enemies(struct storage * store, const faction_list * flist) -{ - while (flist) { - write_faction_reference(flist->data, store); - } - store->w_id(store, 0); -} -#endif - static unit * unitorders(FILE * F, int enc, struct faction * f) { @@ -1233,9 +1203,6 @@ readfaction(struct storage * store) } } read_groups(store, f); -#ifdef ENEMIES - read_enemies(store, f); -#endif return f; } @@ -1299,9 +1266,6 @@ writefaction(struct storage * store, const faction * f) store->w_id(store, 0); store->w_brk(store); write_groups(store, f->groups); -#ifdef ENEMIES - write_enemies(store, f->enemies); -#endif } int diff --git a/src/common/kernel/ship.c b/src/common/kernel/ship.c index 31991d461..1c60e5ff6 100644 --- a/src/common/kernel/ship.c +++ b/src/common/kernel/ship.c @@ -311,7 +311,15 @@ write_ship_reference(const struct ship * sh, struct storage * store) } void -register_ships(void) +ship_setname(ship * self, const char * name) { + free(self->name); + if (name) self->name = strdup(name); + else self->name = NULL; } +const char * +ship_getname(const ship * self) +{ + return self->name; +} diff --git a/src/common/kernel/ship.h b/src/common/kernel/ship.h index af8bc6e72..1baf3a2db 100644 --- a/src/common/kernel/ship.h +++ b/src/common/kernel/ship.h @@ -83,24 +83,25 @@ typedef struct ship { extern void damage_ship(ship *sh, double percent); extern struct unit *captain(ship *sh, struct region *r); extern struct unit *shipowner(const struct ship * sh); +extern const char * shipname(const struct ship * self); extern int shipcapacity(const struct ship * sh); extern void getshipweight(const struct ship * sh, int *weight, int *cabins); extern ship *new_ship(const struct ship_type * stype, const struct locale * lang, struct region * r); -extern const char *shipname(const struct ship * sh); extern const char *write_shipname(const struct ship * sh, char * buffer, size_t size); extern struct ship *findship(int n); extern struct ship *findshipr(const struct region *r, int n); extern const struct ship_type * findshiptype(const char *s, const struct locale * lang); -extern void register_ships(void); extern void write_ship_reference(const struct ship * sh, struct storage * store); extern void remove_ship(struct ship ** slist, struct ship * s); extern void free_ship(struct ship * s); extern void free_ships(void); +extern const char * ship_getname(const struct ship * self); +extern void ship_setname(struct ship * self, const char * name); #ifdef __cplusplus } diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index 82078d61b..a9cdc0c93 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -1376,18 +1376,17 @@ createunitid(unit *u, int id) void name_unit(unit *u) { - free(u->name); if (u->race->generate_name) { const char * gen_name = u->race->generate_name(u); if (gen_name) { - u->name = strdup(gen_name); + unit_setname(u, gen_name); } else { - u->name = strdup(racename(u->faction->locale, u, u->race)); + unit_setname(u, racename(u->faction->locale, u, u->race)); } } else { char name[16]; sprintf(name, "%s %s", LOC(u->faction->locale, "unitdefault"), itoa36(u->no)); - u->name = strdup(name); + unit_setname(u, name); } } @@ -1519,3 +1518,31 @@ countheroes(const struct faction * f) return n; } +const char * +unit_getname(const unit * u) +{ + return (const char *)u->name; +} + +void +unit_setname(unit * u, const char * name) +{ + free(u->name); + if (name) u->name = strdup(name); + else u->name = NULL; +} + +const char * +unit_getinfo(const unit * u) +{ + return (const char *)u->display; +} + +void +unit_setinfo(unit * u, const char * info) +{ + free(u->display); + if (info) u->display = strdup(info); + else u->display = NULL; +} + diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h index 4bc1eaca5..257b1d940 100644 --- a/src/common/kernel/unit.h +++ b/src/common/kernel/unit.h @@ -23,6 +23,7 @@ #define H_KRNL_UNIT_H #include +#include "types.h" #ifdef __cplusplus extern "C" { @@ -212,6 +213,12 @@ extern void uhash(struct unit * u); extern void uunhash(struct unit * u); extern struct unit *ufindhash(int i); +extern const char * unit_getname(const struct unit * u); +extern void unit_setname(struct unit * u, const char * name); +extern const char * unit_getinfo(const struct unit * u); +extern void unit_setinfo(struct unit * u, const char * name); + + extern struct attrib_type at_creator; #ifdef __cplusplus } diff --git a/src/common/modules/xecmd.c b/src/common/modules/xecmd.c index 171c1050e..2a6178e6a 100644 --- a/src/common/modules/xecmd.c +++ b/src/common/modules/xecmd.c @@ -76,8 +76,7 @@ xe_giveballon(unit *u, struct order *ord) sh = new_ship(st_find("balloon"), u2->faction->locale, u2->region); sh->size = 5; - free(sh->name); - sh->name = strdup("Xontormia-Ballon"); + ship_setname(sh, "Xontormia-Ballon"); leave(u2->region, u2); u2->ship = sh; fset(u2, UFL_OWNER); diff --git a/src/common/settings-eressea.h b/src/common/settings-eressea.h index 2b90eabe9..231dc3581 100644 --- a/src/common/settings-eressea.h +++ b/src/common/settings-eressea.h @@ -53,3 +53,11 @@ #define SIMPLE_COMBAT #define SIMPLE_ESCAPE + +#if defined(BINDINGS_LUABIND) +# undef BINDINGS_TOLUA +#elif defined(BINDINGS_TOLUA) +# undef BINDINGS_LUABIND +#else +# define BINDINGS_LUABIND /* fallback */ +#endif diff --git a/src/common/spells/combatspells.c b/src/common/spells/combatspells.c index 5f8f75cb4..5d5cec4ef 100644 --- a/src/common/spells/combatspells.c +++ b/src/common/spells/combatspells.c @@ -1649,11 +1649,11 @@ sp_undeadhero(fighter * fi, int level, double power, spell * sp) unit * u = create_unit(r, mage->faction, 0, new_race[RC_UNDEAD], 0, du->name, du); /* new units gets some stats from old unit */ - free(u->display); + if (du->display) { - u->display = strdup(du->display); + unit_setinfo(u, du->display); } else { - u->display = NULL; + unit_setinfo(u, NULL); } setstatus(u, du->status); setguard(u, GUARD_NONE); diff --git a/src/common/spells/spells.c b/src/common/spells/spells.c index d427d99bc..c58623c96 100644 --- a/src/common/spells/spells.c +++ b/src/common/spells/spells.c @@ -4776,8 +4776,7 @@ sp_icastle(castorder *co) } else { bname = LOC(mage->faction->locale, buildingtype(type, b, 0)); } - free(b->name); - b->name = strdup(bname); + building_setname(b, bname); /* TODO: Auf timeout und action_destroy umstellen */ a = a_add(&b->attribs, a_new(&at_icastle)); @@ -6201,6 +6200,18 @@ shipcurse_flyingship(ship* sh, unit * mage, double power, int duration) return create_curse(mage, &sh->attribs, ct_flyingship, power, duration, zero_effect, 0); } } + +int +levitate_ship(ship * sh, unit * mage, double power, int duration) +{ + curse * c = shipcurse_flyingship(sh, mage, power, duration); + if (c) { + return c->no; + } + return 0; +} + + /* ------------------------------------------------------------- */ /* Name: Luftschiff * Stufe: 6 @@ -6224,7 +6235,7 @@ sp_flying_ship(castorder *co) double power = co->force; spellparameter *pa = co->par; message * m = NULL; - curse * c; + int cno; /* wenn kein Ziel gefunden, Zauber abbrechen */ if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; @@ -6235,8 +6246,9 @@ sp_flying_ship(castorder *co) } /* Duration = 1, nur diese Runde */ - c = shipcurse_flyingship(sh, mage, power, 1); - if (c==NULL) { + + cno = levitate_ship(sh, mage, power, 1); + if (cno==0) { if (is_cursed(sh->attribs, C_SHIP_FLYING, 0) ) { /* Auf dem Schiff befindet liegt bereits so ein Zauber. */ cmistake(mage, co->order, 211, MSG_MAGIC); diff --git a/src/common/spells/spells.h b/src/common/spells/spells.h index 8939a6032..34b5b6570 100644 --- a/src/common/spells/spells.h +++ b/src/common/spells/spells.h @@ -40,6 +40,8 @@ extern "C" { int countdown; } wall_data; + int levitate_ship(ship * sh, unit * mage, double power, int duration); + #ifdef __cplusplus } #endif diff --git a/src/eressea.vcproj b/src/eressea.vcproj index c8cdb8ed9..d0f350b5c 100644 --- a/src/eressea.vcproj +++ b/src/eressea.vcproj @@ -66,7 +66,7 @@ /> + + + + + + + + + + @@ -288,6 +308,10 @@ RelativePath="..\scripts\eressea.lua" > + + diff --git a/src/eressea/lua/building.cpp b/src/eressea/lua/building.cpp index 95d627ac4..717f20f14 100644 --- a/src/eressea/lua/building.cpp +++ b/src/eressea/lua/building.cpp @@ -98,7 +98,7 @@ building_setinfo(building * b, const char * info) } static const char * -building_getname(const building * b) +buildingname(const building * b) { return (const char *)b->name; } @@ -187,7 +187,7 @@ bind_building(lua_State * L) class_("building") .def(self == building()) .def(tostring(self)) - .property("name", &building_getname, &building_setname) + .property("name", &buildingname, &building_setname) .property("info", &building_getinfo, &building_setinfo) .property("units", &building_units, return_stl_iterator) .property("region", &building_getregion, &building_setregion) diff --git a/src/eressea/lua/gamecode.cpp b/src/eressea/lua/gamecode.cpp index 45ecff141..ef4bf462f 100644 --- a/src/eressea/lua/gamecode.cpp +++ b/src/eressea/lua/gamecode.cpp @@ -180,16 +180,6 @@ process_orders(void) return 0; } -static int -levitate_ship(ship * sh, unit * mage, double power, int duration) -{ - curse * c = shipcurse_flyingship(sh, mage, power, duration); - if (c) { - return c->no; - } - return 0; -} - void bind_gamecode(lua_State * L) { diff --git a/src/eressea/lua/region.cpp b/src/eressea/lua/region.cpp index df67f4da9..cc7444c09 100644 --- a/src/eressea/lua/region.cpp +++ b/src/eressea/lua/region.cpp @@ -55,22 +55,11 @@ region_ships(const region * r) { return eressea::list(r->ships); } -static void -region_setname(region * r, const char * name) { - if (r->land) rsetname(r, name); -} - static const char * region_getterrain(const region * r) { return (const char *)r->terrain->_name; } -static const char * -region_getname(const region * r) { - if (r->land) return (const char *)r->land->name; - return NULL; -} - static void lua_region_setowner(region * r, faction * f) { region_setowner(r, f); diff --git a/src/eressea/lua/script.cpp b/src/eressea/lua/script.cpp index 3d99a8e47..ba171ce3f 100644 --- a/src/eressea/lua/script.cpp +++ b/src/eressea/lua/script.cpp @@ -328,8 +328,3 @@ bind_script(lua_State * L) def("set_unit_brain", &unit_setscript) ]; } - -void -reset_scripts() -{ -} diff --git a/src/eressea/lua/script.h b/src/eressea/lua/script.h index fbdf68741..046ca63d0 100644 --- a/src/eressea/lua/script.h +++ b/src/eressea/lua/script.h @@ -15,7 +15,6 @@ extern int call_script(struct unit * u); extern void setscript(struct attrib ** ap, void * fptr); -extern void reset_scripts(); extern int lua_useitem(struct unit * u, const struct item_type * itype, int amount, struct order * ord); #endif diff --git a/src/eressea/lua/unit.cpp b/src/eressea/lua/unit.cpp index 88393a399..fe0294a1e 100644 --- a/src/eressea/lua/unit.cpp +++ b/src/eressea/lua/unit.cpp @@ -375,32 +375,6 @@ unit_setid(unit * u, int id) } } -static const char * -unit_getname(const unit * u) -{ - return (const char *)u->name; -} - -static void -unit_setname(unit * u, const char * name) -{ - free(u->name); - u->name = strdup(name); -} - -static const char * -unit_getinfo(const unit * u) -{ - return (const char *)u->display; -} - -static void -unit_setinfo(unit * u, const char * info) -{ - free(u->display); - u->display = strdup(info); -} - static bool get_flag(const unit * u, const char * name) { diff --git a/src/eressea/server.cpp b/src/eressea/server.cpp index ac6fbce43..e68fa6691 100644 --- a/src/eressea/server.cpp +++ b/src/eressea/server.cpp @@ -96,18 +96,27 @@ #include /* lua includes */ +#ifdef BINDINGS_TOLUA +#include +#include "tolua/bindings.h" +#include "tolua/helpers.h" +#endif // BINDINGS_TOLUA + +#ifdef BINDINGS_LUABIND #include "lua/bindings.h" -#include "lua/script.h" -#include #ifdef _MSC_VER #pragma warning (push) #pragma warning (disable: 4127) -#endif +#endif // _MSC_VER #include #include #ifdef _MSC_VER #pragma warning (pop) -#endif +#endif // _MSC_VER +#endif // BINDINGS_LUABIND + +#include "lua/script.h" +#include #include @@ -210,7 +219,6 @@ game_init(void) register_names(); register_resources(); register_buildings(); - register_ships(); register_itemfunctions(); register_spells(); register_gcspells(); @@ -275,6 +283,12 @@ lua_init(void) lua_State * L = lua_open(); openlibs(L); +#ifdef BINDINGS_TOLUA + register_tolua_helpers(); + tolua_eressea_open(L); +#endif + +#ifdef BINDINGS_LUABIND luabind::open(L); bind_objects(L); @@ -294,13 +308,13 @@ lua_init(void) bind_gmtool(L); bind_test(L); +#endif return L; } static void lua_done(lua_State * luaState) { - reset_scripts(); lua_close(luaState); } @@ -380,15 +394,25 @@ usage(const char * prog, const char * arg) static void setLuaString(lua_State * luaState, const char * name, const char * value) { +#if defined(BINDINGS_LUABIND) luabind::object g = luabind::globals(luaState); g[name] = value; +#elif defined(BINDINGS_TOLUA) + lua_pushstring(luaState, value); + lua_setglobal(luaState, name); +#endif // BINDINGS_LUABIND } static void setLuaNumber(lua_State * luaState, const char * name, double value) { +#if defined(BINDINGS_LUABIND) luabind::object g = luabind::globals(luaState); g[name] = value; +#elif defined(BINDINGS_TOLUA) + lua_pushnumber(luaState, (lua_Number)value); + lua_setglobal(luaState, name); +#endif // BINDINGS_LUABIND } static int @@ -593,14 +617,9 @@ main(int argc, char *argv[]) char buf[MAX_PATH]; if (script_path) sprintf(buf, "%s/%s", script_path, luafile); else strcpy(buf, luafile); -#ifdef LUABIND_NO_EXCEPTIONS - luabind::set_error_callback(my_lua_error); - luabind::set_pcall_callback(my_lua_error); -#else +#ifdef BINDINGS_LUABIND try { -#endif luabind::call_function(luaState, "dofile", buf); -#ifndef LUABIND_NO_EXCEPTIONS } catch (std::runtime_error& rte) { log_error(("%s.\n", rte.what())); @@ -609,6 +628,12 @@ main(int argc, char *argv[]) lua_State* L = e.state(); my_lua_error(L); } +#elif defined(BINDINGS_TOLUA) + lua_getglobal(luaState, "dofile"); + lua_pushstring(luaState, buf); + if (lua_pcall(luaState, 1, 0, 0) != 0) { + my_lua_error(luaState); + } #endif } #ifdef MSPACES diff --git a/src/eressea/tolua/bindings.c b/src/eressea/tolua/bindings.c new file mode 100644 index 000000000..127fe070d --- /dev/null +++ b/src/eressea/tolua/bindings.c @@ -0,0 +1,1020 @@ +/* vi: set ts=2: ++-------------------+ +| | Enno Rehling +| Eressea PBEM host | Christian Schlittchen +| (c) 1998 - 2008 | Katja Zedel +| | Henning Peters ++-------------------+ + +This program may not be used, modified or distributed +without prior permission by the authors of Eressea. +*/ + +#include "bindings.h" +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include + +static int tolua_get_unit_name(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, self->name); + return 1; +} + +static int tolua_set_unit_name(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + unit_setname(self, tolua_tostring(tolua_S, 2, 0)); + return 0; +} + +static int tolua_get_building_name(lua_State* tolua_S) +{ + building* self = (building*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, building_getname(self)); + return 1; +} + +static int tolua_set_building_name(lua_State* tolua_S) +{ + building* self = (building*)tolua_tousertype(tolua_S, 1, 0); + building_setname(self, tolua_tostring(tolua_S, 2, 0)); + return 0; +} + +static int tolua_get_region_name(lua_State* tolua_S) +{ + region* self = (region*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, region_getname(self)); + return 1; +} + +static int tolua_set_region_name(lua_State* tolua_S) +{ + region* self = (region*)tolua_tousertype(tolua_S, 1, 0); + region_setname(self, tolua_tostring(tolua_S, 2, 0)); + return 0; +} + +static int tolua_get_ship_name(lua_State* tolua_S) +{ + ship* self = (ship*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, ship_getname(self)); + return 1; +} + +static int tolua_set_ship_name(lua_State* tolua_S) +{ + ship* self = (ship*)tolua_tousertype(tolua_S, 1, 0); + ship_setname(self, tolua_tostring(tolua_S, 2, 0)); + return 0; +} + +static int tolua_get_unit_faction(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushusertype(tolua_S, (void*)self->faction, "faction"); + return 1; +} + +static int tolua_set_unit_faction(lua_State* tolua_S) +{ + unit * self = (unit*) tolua_tousertype(tolua_S, 1, 0); + faction * f = (faction *)tolua_tousertype(tolua_S, 2, 0); + u_setfaction(self, f); + return 0; +} + +static int tolua_unitlist_next(lua_State *tolua_S) +{ + unit** unit_ptr = (unit **)lua_touserdata(tolua_S, lua_upvalueindex(1)); + unit * u = *unit_ptr; + if (u != NULL) { + tolua_pushusertype(tolua_S, (void*)u, "unit"); + *unit_ptr = u->next; + return 1; + } + else return 0; /* no more values to return */ +} + +static int tolua_factionlist_next(lua_State *tolua_S) +{ + faction** faction_ptr = (faction **)lua_touserdata(tolua_S, lua_upvalueindex(1)); + faction * f = *faction_ptr; + if (f != NULL) { + tolua_pushusertype(tolua_S, (void*)f, "faction"); + *faction_ptr = f->next; + return 1; + } + else return 0; /* no more values to return */ +} + +static int tolua_factionlist_iter(lua_State *tolua_S) +{ + faction_list** faction_ptr = (faction_list **)lua_touserdata(tolua_S, lua_upvalueindex(1)); + faction_list* flist = *faction_ptr; + if (flist != NULL) { + tolua_pushusertype(tolua_S, (void*)flist->data, "faction"); + *faction_ptr = flist->next; + return 1; + } + else return 0; /* no more values to return */ +} + +static int tolua_regionlist_next(lua_State *tolua_S) +{ + region** region_ptr = (region **)lua_touserdata(tolua_S, lua_upvalueindex(1)); + region * u = *region_ptr; + if (u != NULL) { + tolua_pushusertype(tolua_S, (void*)u, "region"); + *region_ptr = u->next; + return 1; + } + else return 0; /* no more values to return */ +} + +static int tolua_unitlist_nextf(lua_State *tolua_S) +{ + unit** unit_ptr = (unit **)lua_touserdata(tolua_S, lua_upvalueindex(1)); + unit * u = *unit_ptr; + if (u != NULL) { + tolua_pushusertype(tolua_S, (void*)u, "unit"); + *unit_ptr = u->nextF; + return 1; + } + else return 0; /* no more values to return */ +} + +static int tolua_get_faction_units(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + unit ** unit_ptr = (unit**)lua_newuserdata(tolua_S, sizeof(unit *)); + + luaL_getmetatable(tolua_S, "unit"); + lua_setmetatable(tolua_S, -2); + + *unit_ptr = self->units; + + lua_pushcclosure(tolua_S, tolua_unitlist_nextf, 1); + return 1; +} + +static int tolua_get_region_units(lua_State* tolua_S) +{ + region * self = (region *)tolua_tousertype(tolua_S, 1, 0); + unit ** unit_ptr = (unit**)lua_newuserdata(tolua_S, sizeof(unit *)); + + luaL_getmetatable(tolua_S, "unit"); + lua_setmetatable(tolua_S, -2); + + *unit_ptr = self->units; + + lua_pushcclosure(tolua_S, tolua_unitlist_next, 1); + return 1; +} + +static int +tolua_read_orders(lua_State* tolua_S) +{ + const char * filename = tolua_tostring(tolua_S, 1, 0); + int result; + ++turn; + result = readorders(filename); + lua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_message_unit(lua_State* tolua_S) +{ + unit * sender = (unit *)tolua_tousertype(tolua_S, 1, 0); + unit * target = (unit *)tolua_tousertype(tolua_S, 2, 0); + const char * str = tolua_tostring(tolua_S, 3, 0); + + deliverMail(target->faction, sender->region, sender, str, target); + return 0; +} + +static int +tolua_message_faction(lua_State * tolua_S) +{ + unit * sender = (unit *)tolua_tousertype(tolua_S, 1, 0); + faction * target = (faction *)tolua_tousertype(tolua_S, 2, 0); + const char * str = tolua_tostring(tolua_S, 3, 0); + + deliverMail(target, sender->region, sender, str, NULL); + return 0; +} + +static int +tolua_message_region(lua_State * tolua_S) +{ + unit * sender = (unit *)tolua_tousertype(tolua_S, 1, 0); + const char * str = tolua_tostring(tolua_S, 2, 0); + + ADDMSG(&sender->region->msgs, msg_message("mail_result", "unit message", sender, str)); + + return 0; +} + +static void +free_script(attrib * a) +{ + lua_State * L = (lua_State *)global.vm_state; + if (a->data.i>0) { + luaL_unref(L, LUA_REGISTRYINDEX, a->data.i); + } +} + +attrib_type at_script = { + "script", + NULL, free_script, NULL, + NULL, NULL, ATF_UNIQUE +}; + +static int +call_script(lua_State * L, struct unit * u) +{ + const attrib * a = a_findc(u->attribs, &at_script); + if (a==NULL) a = a_findc(u->race->attribs, &at_script); + if (a!=NULL && a->data.i>0) { + if (lua_pcall(L, 1, 0, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("call_script (%s): %s", unitname(u), error)); + lua_pop(L, 1); + } + } + return -1; +} + +static void +setscript(lua_State * tolua_S, struct attrib ** ap) +{ + attrib * a = a_find(*ap, &at_script); + if (a == NULL) { + a = a_add(ap, a_new(&at_script)); + } else if (a->data.i>0) { + luaL_unref(tolua_S, LUA_REGISTRYINDEX, a->data.i); + } + a->data.i = luaL_ref(tolua_S, LUA_REGISTRYINDEX); +} + +static int +tolua_update_guards(lua_State * tolua_S) +{ + update_guards(); + return 0; +} + +static int +tolua_levitate_ship(lua_State * tolua_S) +{ + ship * sh = (ship *)tolua_tousertype(tolua_S, 1, 0); + unit * mage = (unit *)tolua_tousertype(tolua_S, 2, 0); + double power = (double)tolua_tonumber(tolua_S, 3, 0); + int duration = (int)tolua_tonumber(tolua_S, 4, 0); + int cno = levitate_ship(sh, mage, power, duration); + tolua_pushnumber(tolua_S, (lua_Number)cno); + return 1; +} + +static int +tolua_set_unitscript(lua_State * tolua_S) +{ + struct unit * u = (struct unit *)tolua_tousertype(tolua_S, 1, 0); + if (u) { + lua_pushvalue(tolua_S, 2); + setscript(tolua_S, &u->attribs); + lua_pop(tolua_S, 1); + } + return 0; +} + +static int +tolua_set_racescript(lua_State * tolua_S) +{ + const char * rcname = tolua_tostring(tolua_S, 1, 0); + race * rc = rc_find(rcname); + + if (rc!=NULL) { + lua_pushvalue(tolua_S, 2); + setscript(tolua_S, &rc->attribs); + lua_pop(tolua_S, 1); + } + return 0; +} + +static int +tolua_spawn_dragons(lua_State * tolua_S) +{ + spawn_dragons(); + return 0; +} + +static int +tolua_spawn_undead(lua_State * tolua_S) +{ + spawn_undead(); + return 0; +} + +static int +tolua_spawn_braineaters(lua_State * tolua_S) +{ + float chance = (float)tolua_tonumber(tolua_S, 1, 0); + spawn_braineaters(chance); + return 0; +} + +static int +tolua_planmonsters(lua_State * tolua_S) +{ + faction * f = get_monsters(); + + if (f!=NULL) { + unit * u; + plan_monsters(); + for (u=f->units;u;u=u->nextF) { + call_script(tolua_S, u); + } + } + + return 0; +} + +static int +tolua_init_reports(lua_State* tolua_S) +{ + int result = init_reports(); + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_write_report(lua_State* tolua_S) +{ + faction * f = (faction * )tolua_tousertype(tolua_S, 1, 0); + time_t ltime = time(0); + int result = write_reports(f, ltime); + + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_write_reports(lua_State* tolua_S) +{ + int result; + + init_reports(); + result = reports(); + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_process_orders(lua_State* tolua_S) +{ + ++turn; + processorders(); + return 0; +} +static int +tolua_write_passwords(lua_State* tolua_S) +{ + int result = writepasswd(); + lua_pushnumber(tolua_S, (lua_Number)result); + return 0; +} + +static struct summary * sum_begin = 0; + +static int +tolua_init_summary(lua_State* tolua_S) +{ + sum_begin = make_summary(); + return 0; +} + +static int +tolua_write_summary(lua_State* tolua_S) +{ + if (sum_begin) { + struct summary * sum_end = make_summary(); + report_summary(sum_end, sum_begin, false); + report_summary(sum_end, sum_begin, true); + return 0; + } + return 0; +} + +static int +tolua_free_game(lua_State* tolua_S) +{ + free_gamedata(); + return 0; +} + +static int +tolua_write_game(lua_State* tolua_S) +{ + const char * filename = tolua_tostring(tolua_S, 1, 0); + const char * mode = tolua_tostring(tolua_S, 2, 0); + + int result, m = IO_TEXT; + if (strcmp(mode, "text")!=0) m = IO_BINARY; + remove_empty_factions(true); + result = writegame(filename, m); + + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_read_game(lua_State* tolua_S) +{ + const char * filename = tolua_tostring(tolua_S, 1, 0); + const char * mode = tolua_tostring(tolua_S, 2, 0); + + int rv, m = IO_TEXT; + if (strcmp(mode, "text")!=0) m = IO_BINARY; + rv = readgame(filename, m, false); + + tolua_pushnumber(tolua_S, (lua_Number)rv); + return 1; +} + +static int +tolua_get_faction(lua_State* tolua_S) +{ + int no = (int)tolua_tonumber(tolua_S, 1, 0); + faction * f = findfaction(no); + + tolua_pushusertype(tolua_S, f, "faction"); + return 1; +} + +static int +tolua_get_alliance(lua_State* tolua_S) +{ + int no = (int)tolua_tonumber(tolua_S, 1, 0); + alliance * f = findalliance(no); + + tolua_pushusertype(tolua_S, f, "alliance"); + return 1; +} + +static int +tolua_get_unit(lua_State* tolua_S) +{ + int no = (int)tolua_tonumber(tolua_S, 1, 0); + unit * u = findunit(no); + + tolua_pushusertype(tolua_S, u, "unit"); + return 1; +} + +static int +tolua_unit_create(lua_State* tolua_S) +{ + faction * f = (faction *)tolua_tousertype(tolua_S, 1, 0); + region * r = (region *)tolua_tousertype(tolua_S, 2, 0); + unit * u = createunit(r, f, 0, f->race); + + tolua_pushusertype(tolua_S, u, "unit"); + return 1; +} + +static int +tolua_get_faction_maxheroes(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)maxheroes(self)); + return 1; +} + +static int +tolua_get_faction_heroes(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)countheroes(self)); + return 1; +} + +static int +tolua_get_faction_score(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)self->score); + return 1; +} + +static int +tolua_get_faction_id(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)self->no); + return 1; +} + +static int +tolua_get_faction_age(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)self->age); + return 1; +} + +static int +tolua_get_faction_flags(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)self->flags); + return 1; +} + +static int +tolua_get_faction_options(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)self->options); + return 1; +} + +static int +tolua_get_faction_lastturn(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)self->lastorders); + return 1; +} + + +static int +tolua_faction_renumber(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + int no = (int)tolua_tonumber(tolua_S, 2, 0); + + renumber_faction(self, no); + return 0; +} + +static int +tolua_faction_get_policy(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + faction * other = (faction *)tolua_tousertype(tolua_S, 2, 0); + const char * policy = tolua_tostring(tolua_S, 3, 0); + + int result = 0, mode; + for (mode=0;helpmodes[mode].name!=NULL;++mode) { + if (strcmp(policy, helpmodes[mode].name)==0) { + result = get_alliance(self, other) & mode; + break; + } + } + + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + + +static int +tolua_faction_set_policy(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + faction * other = (faction *)tolua_tousertype(tolua_S, 2, 0); + const char * policy = tolua_tostring(tolua_S, 3, 0); + int value = tolua_toboolean(tolua_S, 4, 0); + + int mode; + for (mode=0;helpmodes[mode].name!=NULL;++mode) { + if (strcmp(policy, helpmodes[mode].name)==0) { + if (value) { + set_alliance(self, other, get_alliance(self, other) | helpmodes[mode].status); + } else { + set_alliance(self, other, get_alliance(self, other) & ~helpmodes[mode].status); + } + break; + } + } + + return 0; +} + +static int +tolua_faction_get_origin(lua_State* tolua_S) +{ + faction * self = (faction *)tolua_tousertype(tolua_S, 1, 0); + + ursprung * origin = self->ursprung; + int x, y; + while (origin!=NULL && origin->id!=0) { + origin = origin->next; + } + if (origin) { + x = origin->x; + y = origin->y; + } else { + x = 0; + y = 0; + } + + tolua_pushnumber(tolua_S, (lua_Number)x); + tolua_pushnumber(tolua_S, (lua_Number)y); + return 2; +} + +static int +tolua_region_create(lua_State* tolua_S) +{ + short x = (short)tolua_tonumber(tolua_S, 1, 0); + short y = (short)tolua_tonumber(tolua_S, 2, 0); + const char * tname = tolua_tostring(tolua_S, 3, 0); + + const terrain_type * terrain = get_terrain(tname); + region * r = findregion(x, y); + region * result = r; + + if (terrain==NULL) { + if (r!=NULL) { + if (r->units!=NULL) { + /* TODO: error message */ + result = NULL; + } + } + } + if (r==NULL) { + result = new_region(x, y, 0); + } + if (result) { + terraform_region(result, terrain); + } + + tolua_pushusertype(tolua_S, result, "region"); + return 1; +} + +static int +tolua_alliance_create(lua_State* tolua_S) +{ + int id = (int)tolua_tonumber(tolua_S, 1, 0); + const char * name = tolua_tostring(tolua_S, 2, 0); + + alliance * alli = makealliance(id, name); + + tolua_pushusertype(tolua_S, alli, "alliance"); + return 1; +} + +static int +tolua_faction_create(lua_State* tolua_S) +{ + const char * email = tolua_tostring(tolua_S, 1, 0); + const char * racename = tolua_tostring(tolua_S, 2, 0); + const char * lang = tolua_tostring(tolua_S, 3, 0); + struct locale * loc = find_locale(lang); + faction * f = NULL; + const struct race * frace = findrace(racename, default_locale); + if (frace==NULL) frace = findrace(racename, find_locale("de")); + if (frace==NULL) frace = findrace(racename, find_locale("en")); + if (frace!=NULL) { + f = addfaction(email, NULL, frace, loc, 0); + } + tolua_pushusertype(tolua_S, f, "faction"); + return 1; +} + +static int +tolua_get_regions(lua_State* tolua_S) +{ + region ** region_ptr = (region**)lua_newuserdata(tolua_S, sizeof(region *)); + + luaL_getmetatable(tolua_S, "region"); + lua_setmetatable(tolua_S, -2); + + *region_ptr = regions; + + lua_pushcclosure(tolua_S, tolua_regionlist_next, 1); + return 1; +} + +static int +tolua_get_factions(lua_State* tolua_S) +{ + faction ** faction_ptr = (faction**)lua_newuserdata(tolua_S, sizeof(faction *)); + + luaL_getmetatable(tolua_S, "faction"); + lua_setmetatable(tolua_S, -2); + + *faction_ptr = factions; + + lua_pushcclosure(tolua_S, tolua_factionlist_next, 1); + return 1; +} + +static int +tolua_get_alliance_factions(lua_State* tolua_S) +{ + alliance * self = (alliance *)tolua_tousertype(tolua_S, 1, 0); + faction_list ** faction_ptr = (faction_list**)lua_newuserdata(tolua_S, sizeof(faction_list *)); + + luaL_getmetatable(tolua_S, "faction_list"); + lua_setmetatable(tolua_S, -2); + + *faction_ptr = self->members; + + lua_pushcclosure(tolua_S, tolua_factionlist_iter, 1); + return 1; +} + +static int tolua_get_faction_password(lua_State* tolua_S) +{ + faction* self = (faction*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, faction_getpassword(self)); + return 1; +} + +static int tolua_set_faction_password(lua_State* tolua_S) +{ + faction* self = (faction*)tolua_tousertype(tolua_S, 1, 0); + faction_setpassword(self, tolua_tostring(tolua_S, 2, 0)); + return 0; +} + +static int tolua_get_faction_email(lua_State* tolua_S) +{ + faction* self = (faction*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, faction_getemail(self)); + return 1; +} + +static int tolua_set_faction_email(lua_State* tolua_S) +{ + faction* self = (faction*)tolua_tousertype(tolua_S, 1, 0); + faction_setemail(self, tolua_tostring(tolua_S, 2, 0)); + return 0; +} + +static int tolua_get_faction_locale(lua_State* tolua_S) +{ + faction* self = (faction*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, locale_name(self->locale)); + return 1; +} + +static int tolua_set_faction_locale(lua_State* tolua_S) +{ + faction* self = (faction*)tolua_tousertype(tolua_S, 1, 0); + const char * name = tolua_tostring(tolua_S, 2, 0); + self->locale = find_locale(name); + return 0; +} + +static int tolua_get_faction_race(lua_State* tolua_S) +{ + faction* self = (faction*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, self->race->_name[0]); + return 1; +} + +static int tolua_set_faction_race(lua_State* tolua_S) +{ + faction* self = (faction*)tolua_tousertype(tolua_S, 1, 0); + const char * name = tolua_tostring(tolua_S, 2, 0); + race * rc = rc_find(name); + if (rc!=NULL) { + self->race = rc; + } + + return 0; +} + +static int tolua_get_faction_alliance(lua_State* tolua_S) +{ + faction* self = (faction*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushusertype(tolua_S, self->alliance, "alliance"); + return 1; +} + +static int tolua_set_faction_alliance(lua_State* tolua_S) +{ + faction* self = (faction*)tolua_tousertype(tolua_S, 1, 0); + alliance* alli = (alliance*)tolua_tousertype(tolua_S, 2, 0); + + if (!self->alliance) { + setalliance(self, alli); + } + + return 0; +} + +static int tolua_get_alliance_id(lua_State* tolua_S) +{ + alliance* self = (alliance*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)self->id); + return 1; +} + +static int tolua_get_alliance_name(lua_State* tolua_S) +{ + alliance* self = (alliance*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, self->name); + return 1; +} + +static int tolua_set_alliance_name(lua_State* tolua_S) +{ + alliance* self = (alliance*)tolua_tousertype(tolua_S, 1, 0); + alliance_setname(self, tolua_tostring(tolua_S, 2, 0)); + return 0; +} + +static int tolua_get_faction_name(lua_State* tolua_S) +{ + faction* self = (faction*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, faction_getname(self)); + return 1; +} + +static int tolua_set_faction_name(lua_State* tolua_S) +{ + faction* self = (faction*)tolua_tousertype(tolua_S, 1, 0); + faction_setname(self, tolua_tostring(tolua_S, 2, 0)); + return 0; +} + +static int tolua_get_faction_info(lua_State* tolua_S) +{ + faction* self = (faction*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, faction_getbanner(self)); + return 1; +} + +static int tolua_set_faction_info(lua_State* tolua_S) +{ + faction* self = (faction*)tolua_tousertype(tolua_S, 1, 0); + faction_setbanner(self, tolua_tostring(tolua_S, 2, 0)); + return 0; +} + + +int tolua_eressea_open(lua_State* tolua_S) +{ + tolua_open(tolua_S); + + /* register user types */ + tolua_usertype(tolua_S, "unit"); + tolua_usertype(tolua_S, "alliance"); + tolua_usertype(tolua_S, "faction"); + tolua_usertype(tolua_S, "region"); + tolua_usertype(tolua_S, "ship"); + tolua_usertype(tolua_S, "building"); + tolua_usertype(tolua_S, "faction_list"); + + tolua_module(tolua_S, NULL, 0); + tolua_beginmodule(tolua_S, NULL); + { + tolua_cclass(tolua_S, "faction", "faction", "", NULL); + tolua_beginmodule(tolua_S, "faction"); + { + tolua_variable(tolua_S, "name", tolua_get_faction_name, tolua_set_faction_name); + tolua_variable(tolua_S, "units", tolua_get_faction_units, NULL); + tolua_variable(tolua_S, "heroes", tolua_get_faction_heroes, NULL); + tolua_variable(tolua_S, "maxheroes", tolua_get_faction_maxheroes, NULL); + tolua_variable(tolua_S, "password", tolua_get_faction_password, tolua_set_faction_password); + tolua_variable(tolua_S, "email", tolua_get_faction_email, tolua_set_faction_email); + tolua_variable(tolua_S, "locale", tolua_get_faction_locale, tolua_set_faction_locale); + tolua_variable(tolua_S, "race", tolua_get_faction_race, tolua_set_faction_race); + tolua_variable(tolua_S, "alliance", tolua_get_faction_alliance, tolua_set_faction_alliance); + tolua_variable(tolua_S, "score", tolua_get_faction_score, NULL); + tolua_variable(tolua_S, "id", tolua_get_faction_id, NULL); + tolua_variable(tolua_S, "age", tolua_get_faction_age, NULL); + tolua_variable(tolua_S, "options", tolua_get_faction_options, NULL); + tolua_variable(tolua_S, "flags", tolua_get_faction_flags, NULL); + tolua_variable(tolua_S, "lastturn", tolua_get_faction_lastturn, NULL); + + tolua_function(tolua_S, "set_policy", tolua_faction_set_policy); + tolua_function(tolua_S, "get_policy", tolua_faction_get_policy); + tolua_function(tolua_S, "get_origin", tolua_faction_get_origin); + + tolua_function(tolua_S, "renumber", tolua_faction_renumber); + tolua_function(tolua_S, "create", tolua_faction_create); + } + tolua_endmodule(tolua_S); + + tolua_cclass(tolua_S, "alliance", "alliance", "", NULL); + tolua_beginmodule(tolua_S, "alliance"); + { + tolua_variable(tolua_S, "name", tolua_get_alliance_name, tolua_set_alliance_name); + tolua_variable(tolua_S, "id", tolua_get_alliance_id, NULL); + tolua_variable(tolua_S, "factions", tolua_get_alliance_factions, NULL); + tolua_function(tolua_S, "create", tolua_alliance_create); + } + tolua_endmodule(tolua_S); + + tolua_cclass(tolua_S, "region", "region", "", NULL); + tolua_beginmodule(tolua_S, "region"); + { + tolua_variable(tolua_S, "name", tolua_get_region_name, tolua_set_region_name); + tolua_variable(tolua_S, "units", tolua_get_region_units, NULL); + tolua_function(tolua_S, "create", tolua_region_create); + } + tolua_endmodule(tolua_S); + + tolua_cclass(tolua_S, "building", "building", "", NULL); + tolua_beginmodule(tolua_S, "building"); + { + tolua_variable(tolua_S, "name", tolua_get_building_name, tolua_set_building_name); + } + tolua_endmodule(tolua_S); + + tolua_cclass(tolua_S, "ship", "ship", "", NULL); + tolua_beginmodule(tolua_S, "ship"); + { + tolua_variable(tolua_S, "name", tolua_get_ship_name, tolua_set_ship_name); + } + tolua_endmodule(tolua_S); + + tolua_cclass(tolua_S, "unit", "unit", "", NULL); + tolua_beginmodule(tolua_S, "unit"); + { + tolua_variable(tolua_S, "name", tolua_get_unit_name, tolua_set_unit_name); + tolua_variable(tolua_S, "faction", tolua_get_unit_faction, tolua_set_unit_faction); + tolua_function(tolua_S, "create", tolua_unit_create); + } + tolua_endmodule(tolua_S); + + // deprecated_function(tolua_S, "add_faction"); + // deprecated_function(tolua_S, "faction_origin"); + tolua_function(tolua_S, "factions", tolua_get_factions); + tolua_function(tolua_S, "regions", tolua_get_regions); + + tolua_function(tolua_S, "read_game", tolua_read_game); + tolua_function(tolua_S, "write_game", tolua_write_game); + tolua_function(tolua_S, "free_game", tolua_free_game); + + tolua_function(tolua_S, "read_orders", tolua_read_orders); + tolua_function(tolua_S, "process_orders", tolua_process_orders); + + tolua_function(tolua_S, "init_reports", tolua_init_reports); + tolua_function(tolua_S, "write_reports", tolua_write_reports); + tolua_function(tolua_S, "write_report", tolua_write_report); + + tolua_function(tolua_S, "init_summary", tolua_init_summary); + tolua_function(tolua_S, "write_summary", tolua_write_summary); + tolua_function(tolua_S, "write_passwords", tolua_write_passwords), + + tolua_function(tolua_S, "message_unit", tolua_message_unit); + tolua_function(tolua_S, "message_faction", tolua_message_faction); + tolua_function(tolua_S, "message_region", tolua_message_region); + + tolua_function(tolua_S, "get_faction", tolua_get_faction); + tolua_function(tolua_S, "get_unit", tolua_get_unit); + tolua_function(tolua_S, "get_alliance", tolua_get_alliance); + + /* scripted monsters */ + tolua_function(tolua_S, "plan_monsters", tolua_planmonsters); + tolua_function(tolua_S, "spawn_braineaters", tolua_spawn_braineaters); + tolua_function(tolua_S, "spawn_undead", tolua_spawn_undead); + tolua_function(tolua_S, "spawn_dragons", tolua_spawn_dragons); + + tolua_function(tolua_S, "set_race_brain", tolua_set_racescript); + tolua_function(tolua_S, "set_unit_brain", tolua_set_unitscript); + + /* spells and stuff */ + tolua_function(tolua_S, "levitate_ship", tolua_levitate_ship); + + tolua_function(tolua_S, "update_guards", tolua_update_guards); + } + tolua_endmodule(tolua_S); + return 1; +} diff --git a/src/eressea/tolua/bindings.h b/src/eressea/tolua/bindings.h new file mode 100644 index 000000000..8495a4b48 --- /dev/null +++ b/src/eressea/tolua/bindings.h @@ -0,0 +1,22 @@ +/* vi: set ts=2: ++-------------------+ +| | Enno Rehling +| Eressea PBEM host | Christian Schlittchen +| (c) 1998 - 2008 | Katja Zedel +| | Henning Peters ++-------------------+ + +This program may not be used, modified or distributed +without prior permission by the authors of Eressea. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + + struct lua_State; + extern int tolua_eressea_open(struct lua_State* tolua_S); + +#ifdef __cplusplus +} +#endif diff --git a/src/eressea/tolua/helpers.c b/src/eressea/tolua/helpers.c new file mode 100644 index 000000000..4e6a0f2e8 --- /dev/null +++ b/src/eressea/tolua/helpers.c @@ -0,0 +1,455 @@ +/* vi: set ts=2: ++-------------------+ +| | Enno Rehling +| Eressea PBEM host | Christian Schlittchen +| (c) 1998 - 2008 | Katja Zedel +| | Henning Peters ++-------------------+ + +This program may not be used, modified or distributed +without prior permission by the authors of Eressea. +*/ + +#include "helpers.h" +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static int +lua_giveitem(unit * s, unit * d, const item_type * itype, int n, struct order * ord) +{ + lua_State * L = (lua_State *)global.vm_state; + char fname[64]; + int result = -1; + const char * iname = itype->rtype->_name[0]; + + assert(s!=NULL); + strcat(strcpy(fname, iname), "_give"); + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, s, "unit"); + tolua_pushusertype(L, d, "unit"); + tolua_pushstring(L, iname); + tolua_pushnumber(L, (lua_Number)n); + + if (lua_pcall(L, 4, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("unit %s calling '%s': %s.\n", + unitname(s), fname, error)); + lua_pop(L, 1); + } else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } + } else { + log_error(("unit %s trying to call '%s' : not a function.\n", + unitname(s), fname)); + lua_pop(L, 1); + } + + return result; +} + +static int +limit_resource(const region * r, const resource_type * rtype) +{ + char fname[64]; + int result = -1; + lua_State * L = (lua_State *)global.vm_state; + + snprintf(fname, sizeof(fname), "%s_limit", rtype->_name[0]); + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, (void *)r, "region"); + + if (lua_pcall(L, 1, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("limit(%s) calling '%s': %s.\n", + regionname(r, NULL), fname, error)); + lua_pop(L, 1); + } else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } + } else { + log_error(("limit(%s) calling '%s': not a function.\n", + regionname(r, NULL), fname)); + lua_pop(L, 1); + } + + return result; +} + +static void +produce_resource(region * r, const resource_type * rtype, int norders) +{ + lua_State * L = (lua_State *)global.vm_state; + char fname[64]; + snprintf(fname, sizeof(fname), "%s_produce", rtype->_name[0]); + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, (void *)r, "region"); + tolua_pushnumber(L, (lua_Number)norders); + + if (lua_pcall(L, 2, 0, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("produce(%s) calling '%s': %s.\n", + regionname(r, NULL), fname, error)); + lua_pop(L, 1); + } + } else { + log_error(("produce(%s) calling '%s': not a function.\n", + regionname(r, NULL), fname)); + lua_pop(L, 1); + } +} + + +static int +lc_age(struct attrib * a) +{ + building_action * data = (building_action*)a->data.v; + const char * fname = data->fname; + const char * fparam = data->param; + building * b = data->b; + int result = -1; + + assert(b!=NULL); + if (fname!=NULL) { + lua_State * L = (lua_State *)global.vm_state; + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, (void *)b, "building"); + if (fparam) { + tolua_pushstring(L, fparam); + } + + if (lua_pcall(L, fparam?2:1, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("lc_age(%s) calling '%s': %s.\n", + buildingname(b), fname, error)); + lua_pop(L, 1); + } else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } + } else { + log_error(("lc_age(%s) calling '%s': not a function.\n", + buildingname(b), fname)); + lua_pop(L, 1); + } + } + return (result!=0)?AT_AGE_KEEP:AT_AGE_REMOVE; +} + + +/** callback to use lua for spell functions */ +static int +lua_callspell(castorder *co) +{ + lua_State * L = (lua_State *)global.vm_state; + const char * fname = co->sp->sname; + unit * mage = co->familiar?co->familiar:co->magician.u; + int result = -1; + const char * hashpos = strchr(fname, '#'); + char fbuf[64]; + + if (hashpos!=NULL) { + ptrdiff_t len = hashpos - fname; + assert(len<(ptrdiff_t)sizeof(fbuf)); + strncpy(fbuf, fname, len); + fbuf[len] = '\0'; + fname = fbuf; + } + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, co->rt, "region"); + tolua_pushusertype(L, mage, "unit"); + tolua_pushnumber(L, (lua_Number)co->level); + tolua_pushnumber(L, (lua_Number)co->force); + + if (lua_pcall(L, 4, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("spell(%s) calling '%s': %s.\n", + unitname(mage), fname, error)); + lua_pop(L, 1); + } else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } + } else { + log_error(("spell(%s) calling '%s': not a function.\n", + unitname(mage), fname)); + lua_pop(L, 1); + } + + return result; +} + +/** callback to initialize a familiar from lua. */ +static void +lua_initfamiliar(unit * u) +{ + lua_State * L = (lua_State *)global.vm_state; + char fname[64]; + int result = -1; + snprintf(fname, sizeof(fname), "initfamiliar_%s", u->race->_name[0]); + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, u, "unit"); + + if (lua_pcall(L, 1, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("familiar(%s) calling '%s': %s.\n", + unitname(u), fname, error)); + lua_pop(L, 1); + } else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } + } else { + log_error(("familiar(%s) calling '%s': not a function.\n", + unitname(u), fname)); + lua_pop(L, 1); + } + + create_mage(u, M_GRAU); + + snprintf(fname, sizeof(fname), "%s_familiar", u->race->_name[0]); + equip_unit(u, get_equipment(fname)); +} + +static int +lua_changeresource(unit * u, const struct resource_type * rtype, int delta) +{ + lua_State * L = (lua_State *)global.vm_state; + int result = -1; + char fname[64]; + snprintf(fname, sizeof(fname), "%s_changeresource", rtype->_name[0]); + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, u, "unit"); + tolua_pushnumber(L, (lua_Number)delta); + + if (lua_pcall(L, 2, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("change(%s) calling '%s': %s.\n", + unitname(u), fname, error)); + lua_pop(L, 1); + } else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } + } else { + log_error(("change(%s) calling '%s': not a function.\n", + unitname(u), fname)); + lua_pop(L, 1); + } + + return result; +} + +static int +lua_getresource(unit * u, const struct resource_type * rtype) +{ + lua_State * L = (lua_State *)global.vm_state; + int result = -1; + char fname[64]; + snprintf(fname, sizeof(fname), "%s_getresource", rtype->_name[0]); + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, u, "unit"); + + if (lua_pcall(L, 1, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("get(%s) calling '%s': %s.\n", + unitname(u), fname, error)); + lua_pop(L, 1); + } else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } + } else { + log_error(("get(%s) calling '%s': not a function.\n", + unitname(u), fname)); + lua_pop(L, 1); + } + + return result; +} + +static int +lua_wage(const region * r, const faction * f, const race * rc) +{ + lua_State * L = (lua_State *)global.vm_state; + const char * fname = "wage"; + int result = -1; + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, (void *)r, "region"); + tolua_pushusertype(L, (void *)f, "faction"); + tolua_pushstring(L, rc?rc->_name[0]:0); + + if (lua_pcall(L, 3, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("wage(%s) calling '%s': %s.\n", + regionname(r, NULL), fname, error)); + lua_pop(L, 1); + } else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } + } else { + log_error(("wage(%s) calling '%s': not a function.\n", + regionname(r, NULL), fname)); + lua_pop(L, 1); + } + + return result; +} + +static int +lua_maintenance(const unit * u) +{ + lua_State * L = (lua_State *)global.vm_state; + const char * fname = "maintenance"; + int result = -1; + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, (void *)u, "unit"); + + if (lua_pcall(L, 1, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("maintenance(%s) calling '%s': %s.\n", + unitname(u), fname, error)); + lua_pop(L, 1); + } else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } + } else { + log_error(("maintenance(%s) calling '%s': not a function.\n", + unitname(u), fname)); + lua_pop(L, 1); + } + + return result; +} + +static void +lua_equipmentcallback(const struct equipment * eq, unit * u) +{ + lua_State * L = (lua_State *)global.vm_state; + char fname[64]; + int result = -1; + snprintf(fname, sizeof(fname), "equip_%s", eq->name); + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, (void *)u, "unit"); + + if (lua_pcall(L, 1, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("equip(%s) calling '%s': %s.\n", + unitname(u), fname, error)); + lua_pop(L, 1); + } else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } + } else { + log_error(("equip(%s) calling '%s': not a function.\n", + unitname(u), fname)); + lua_pop(L, 1); + } +} + +/** callback for an item-use function written in lua. */ +int +lua_useitem(struct unit * u, const struct item_type * itype, int amount, struct order * ord) +{ + lua_State * L = (lua_State *)global.vm_state; + int result = 0; + char fname[64]; + snprintf(fname, sizeof(fname), "use_%s", itype->rtype->_name[0]); + + lua_pushstring(L, fname); + lua_rawget(L, LUA_GLOBALSINDEX); + if (lua_isfunction(L, 1)) { + tolua_pushusertype(L, (void *)u, "unit"); + tolua_pushnumber(L, (lua_Number)amount); + + if (lua_pcall(L, 2, 1, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("use(%s) calling '%s': %s.\n", + unitname(u), fname, error)); + lua_pop(L, 1); + } else { + result = (int)lua_tonumber(L, -1); + lua_pop(L, 1); + } + } else { + log_error(("use(%s) calling '%s': not a function.\n", + unitname(u), fname)); + lua_pop(L, 1); + } + + return result; +} + +void +register_tolua_helpers(void) +{ + at_building_action.age = lc_age; + + register_function((pf_generic)&lua_callspell, "lua_castspell"); + register_function((pf_generic)&lua_initfamiliar, "lua_initfamiliar"); + register_item_use(&lua_useitem, "lua_useitem"); + register_function((pf_generic)&lua_getresource, "lua_getresource"); + register_function((pf_generic)&lua_changeresource, "lua_changeresource"); + register_function((pf_generic)&lua_equipmentcallback, "lua_equip"); + + register_function((pf_generic)&lua_wage, "lua_wage"); + register_function((pf_generic)&lua_maintenance, "lua_maintenance"); + + + register_function((pf_generic)produce_resource, "lua_produceresource"); + register_function((pf_generic)limit_resource, "lua_limitresource"); + register_item_give(lua_giveitem, "lua_giveitem"); +} diff --git a/src/eressea/tolua/helpers.h b/src/eressea/tolua/helpers.h new file mode 100644 index 000000000..c28588699 --- /dev/null +++ b/src/eressea/tolua/helpers.h @@ -0,0 +1,21 @@ +/* vi: set ts=2: ++-------------------+ +| | Enno Rehling +| Eressea PBEM host | Christian Schlittchen +| (c) 1998 - 2008 | Katja Zedel +| | Henning Peters ++-------------------+ + +This program may not be used, modified or distributed +without prior permission by the authors of Eressea. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + + void register_tolua_helpers(void); + +#ifdef __cplusplus +} +#endif diff --git a/src/scripts/asgard.lua b/src/scripts/asgard.lua index 538fb8227..f26f22943 100644 --- a/src/scripts/asgard.lua +++ b/src/scripts/asgard.lua @@ -33,7 +33,6 @@ function process(orders) -- loadscript("eressea/multis.lua") -- run the turn: - -- set_encoding("utf8") if read_orders(orders) ~= 0 then print("could not read " .. orders) return -1 diff --git a/src/scripts/eressea.lua b/src/scripts/eressea.lua index 0b7d1685c..f3a338676 100644 --- a/src/scripts/eressea.lua +++ b/src/scripts/eressea.lua @@ -61,7 +61,6 @@ function process(orders) -- loadscript("eressea/multis.lua") -- run the turn: - -- set_encoding("utf8") if read_orders(orders) ~= 0 then print("could not read " .. orders) return -1 diff --git a/src/scripts/hse4-run.lua b/src/scripts/hse4-run.lua index ec311dd5c..566801df6 100644 --- a/src/scripts/hse4-run.lua +++ b/src/scripts/hse4-run.lua @@ -42,7 +42,6 @@ function process(orders) -- loadscript("eressea/multis.lua") -- run the turn: - set_encoding("utf8") if read_orders(orders) ~= 0 then print("could not read " .. orders) return -1 diff --git a/src/scripts/samples.lua b/src/scripts/samples.lua index c4e8a7c41..42025980f 100644 --- a/src/scripts/samples.lua +++ b/src/scripts/samples.lua @@ -433,14 +433,12 @@ end -- test_moving() if 0==1 then - set_encoding("ISO-8859-1") read_game("530") -- read_orders("../game/orders.530") plan_monsters() process_orders() write_game("531") else - set_encoding("UTF-8") read_game("531") plan_monsters() process_orders()