From b01d9fc685ba36fa6318a49d7766c4fd0156c942 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 19 Dec 2008 16:30:31 +0000 Subject: [PATCH] more tolua bindings started work on an alternate tolua code generator --- src/combined/gamecode.c | 3 + src/common/gamecode/creport.c | 2 +- src/common/gamecode/laws.c | 34 ++ src/common/gamecode/laws.h | 1 + src/common/gamecode/report.c | 4 +- src/common/kernel/build.h | 3 + src/common/kernel/eressea.c | 85 +-- src/common/kernel/eressea.h | 4 - src/common/kernel/faction.c | 38 ++ src/common/kernel/faction.h | 1 + src/common/kernel/message.h | 1 + src/common/kernel/order.c | 2 +- src/common/kernel/order.h | 2 +- src/common/kernel/race.c | 30 -- src/common/kernel/region.c | 33 ++ src/common/kernel/region.h | 64 +-- src/common/kernel/reports.c | 2 +- src/common/kernel/save.c | 6 +- src/common/kernel/unit.c | 134 +++++ src/common/kernel/unit.h | 20 +- src/common/spells/spells.h | 2 +- src/eressea.sln | 22 +- src/eressea/eressea-lua.vcproj | 20 + src/eressea/lua/eressea.cpp | 34 -- src/eressea/lua/message.cpp | 6 + src/eressea/lua/unit.cpp | 29 +- src/eressea/server.cpp | 7 + src/eressea/tolua/bind_faction.c | 256 +++++++++ src/eressea/tolua/bind_faction.h | 24 + src/eressea/tolua/bind_message.c | 307 +++++++++++ src/eressea/tolua/bind_message.h | 22 + src/eressea/tolua/bind_unit.c | 895 +++++++++++++++++++++++++++++++ src/eressea/tolua/bind_unit.h | 24 + src/eressea/tolua/bindings.c | 570 ++++++++++---------- src/eressea/tolua/message.xml | 61 +++ src/scripts/eressea/embassy.lua | 2 +- src/scripts/eressea/ents.lua | 2 +- src/scripts/eressea/xmas2005.lua | 2 +- src/scripts/eressea/xmas2006.lua | 4 +- src/scripts/spells.lua | 4 +- src/scripts/tests.lua | 84 +++ src/scripts/wdw/sphinx.lua | 2 +- src/tools/codegen/codegen.cpp | 114 ++++ src/tools/codegen/codegen.vcproj | 202 +++++++ 44 files changed, 2633 insertions(+), 531 deletions(-) create mode 100644 src/eressea/tolua/bind_faction.c create mode 100644 src/eressea/tolua/bind_faction.h create mode 100644 src/eressea/tolua/bind_message.c create mode 100644 src/eressea/tolua/bind_message.h create mode 100644 src/eressea/tolua/bind_unit.c create mode 100644 src/eressea/tolua/bind_unit.h create mode 100644 src/eressea/tolua/message.xml create mode 100644 src/scripts/tests.lua create mode 100644 src/tools/codegen/codegen.cpp create mode 100644 src/tools/codegen/codegen.vcproj diff --git a/src/combined/gamecode.c b/src/combined/gamecode.c index 487d8950d..0ace5a0f0 100644 --- a/src/combined/gamecode.c +++ b/src/combined/gamecode.c @@ -4,6 +4,9 @@ #ifdef BINDINGS_TOLUA #include "eressea/tolua/bindings.c" +#include "eressea/tolua/bind_unit.c" +#include "eressea/tolua/bind_faction.c" +#include "eressea/tolua/bind_message.c" #include "eressea/tolua/helpers.c" #endif diff --git a/src/common/gamecode/creport.c b/src/common/gamecode/creport.c index db10aac40..f87f96bc9 100644 --- a/src/common/gamecode/creport.c +++ b/src/common/gamecode/creport.c @@ -625,7 +625,7 @@ fwriteorder(FILE * F, const struct order * ord, const struct locale * lang) { char obuf[1024]; fputc('"', F); - write_order(ord, lang, obuf, sizeof(obuf)); + write_order(ord, obuf, sizeof(obuf)); if (obuf[0]) fputs(obuf, F); fputc('"', F); } diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 26f16bc59..2131141e1 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -3909,3 +3909,37 @@ writepasswd(void) } return 1; } + +void +update_subscriptions(void) +{ + FILE * F; + char zText[MAX_PATH]; + faction * f; + strcat(strcpy(zText, basepath()), "/subscriptions"); + F = fopen(zText, "r"); + if (F==NULL) { + log_info((0, "could not open %s.\n", zText)); + return; + } + for (;;) { + char zFaction[5]; + int subscription, fno; + if (fscanf(F, "%d %s", &subscription, zFaction)<=0) break; + fno = atoi36(zFaction); + f = findfaction(fno); + if (f!=NULL) { + f->subscription=subscription; + } + } + fclose(F); + + sprintf(zText, "subscriptions.%u", turn); + F = fopen(zText, "w"); + for (f=factions;f!=NULL;f=f->next) { + fprintf(F, "%s:%u:%s:%s:%s:%u:\n", + itoa36(f->no), f->subscription, f->email, f->override, + dbrace(f->race), f->lastorders); + } + fclose(F); +} diff --git a/src/common/gamecode/laws.h b/src/common/gamecode/laws.h index 499244cd4..2ddb63f0d 100644 --- a/src/common/gamecode/laws.h +++ b/src/common/gamecode/laws.h @@ -32,6 +32,7 @@ void demographics(void); void last_orders(void); void find_address(void); void update_guards(void); +void update_subscriptions(void); extern void deliverMail(struct faction * f, struct region * r, struct unit * u, const char *s, struct unit * receiver); /* eressea-specific. put somewhere else, please. */ diff --git a/src/common/gamecode/report.c b/src/common/gamecode/report.c index 36cab701b..5489e8afa 100644 --- a/src/common/gamecode/report.c +++ b/src/common/gamecode/report.c @@ -1444,7 +1444,7 @@ report_template(const char * filename, report_context * ctx, const char * charse for (ord = u->old_orders; ord; ord = ord->next) { /* this new order will replace the old defaults */ strcpy(buf, " "); - write_order(ord, u->faction->locale, buf+2, sizeof(buf)-2); + write_order(ord, buf+2, sizeof(buf)-2); rps_nowrap(F, buf); rnl(F); } @@ -1452,7 +1452,7 @@ report_template(const char * filename, report_context * ctx, const char * charse if (u->old_orders && is_repeated(ord)) continue; /* unit has defaults */ if (is_persistent(ord)) { strcpy(buf, " "); - write_order(ord, u->faction->locale, buf+2, sizeof(buf)-2); + write_order(ord, buf+2, sizeof(buf)-2); rps_nowrap(F, buf); rnl(F); } diff --git a/src/common/kernel/build.h b/src/common/kernel/build.h index ea39e7082..96dfe29ab 100644 --- a/src/common/kernel/build.h +++ b/src/common/kernel/build.h @@ -20,6 +20,9 @@ #ifndef H_KRNL_BUILD #define H_KRNL_BUILD + +#include "types.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index cc33d708d..78bd13f9b 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -665,41 +665,6 @@ ffindhash(int no) } /* ----------------------------------------------------------------------- */ -void -stripfaction (faction * f) -{ - /* TODO: inhalt auch löschen */ - if (f->msgs) free_messagelist(f->msgs); - while (f->battles) { - struct bmsg * bm = f->battles; - f->battles = bm->next; - if (bm->msgs) free_messagelist(bm->msgs); - free(bm); - } - - while (f->groups) { - group * g = f->groups; - f->groups = g->next; - free_group(g); - } - freelist(f->allies); - - free(f->email); - free(f->banner); - free(f->passw); - free(f->override); - free(f->name); - - while (f->attribs) { - a_remove (&f->attribs, f->attribs); - } - - i_freeall(&f->items); - - freelist(f->ursprung); - funhash(f); -} - void verify_data(void) { @@ -833,50 +798,6 @@ eff_stealth(const unit * u, const region * r) return e; } -void -scale_number (unit * u, int n) -{ - skill_t sk; - const attrib * a; - int remain; - - if (n == u->number) return; - if (n && u->number>0) { - int full; - remain = ((u->hp%u->number) * (n % u->number)) % u->number; - - full = u->hp/u->number; /* wieviel kriegt jede person mindestens */ - u->hp = full * n + (u->hp-full*u->number) * n / u->number; - assert(u->hp>=0); - if ((rng_int() % u->number) < remain) - ++u->hp; /* Nachkommastellen */ - } else { - remain = 0; - u->hp = 0; - } - if (u->number>0) { - for (a = a_find(u->attribs, &at_effect);a && a->type==&at_effect;a=a->next) { - effect_data * data = (effect_data *)a->data.v; - int snew = data->value / u->number * n; - if (n) { - remain = data->value - snew / n * u->number; - snew += remain * n / u->number; - remain = (remain * n) % u->number; - if ((rng_int() % u->number) < remain) - ++snew; /* Nachkommastellen */ - } - data->value = snew; - } - } - if (u->number==0 || n==0) { - for (sk = 0; sk < MAXSKILLS; sk++) { - remove_skill(u, sk); - } - } - - set_number(u, n); -} - boolean unit_has_cursed_item(unit *u) { @@ -2379,6 +2300,9 @@ remove_empty_factions(boolean writedropouts) } *fp = f->next; + funhash(f); + free_faction(f); + free(f); } else fp = &(*fp)->next; } @@ -3030,7 +2954,8 @@ free_gamedata(void) while (factions) { faction * f = factions; factions = f->next; - stripfaction(f); + funhash(f); + free_faction(f); free(f); } diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index 21a27bbe5..9839b6623 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -256,8 +256,6 @@ extern boolean has_limited_skills(const struct unit * u); extern const struct race * findrace(const char *, const struct locale *); int eff_stealth(const struct unit * u, const struct region * r); -void scale_number(struct unit * u, int n); -int unit_max_hp(const struct unit * u); int ispresent(const struct faction * f, const struct region * r); int check_option(struct faction * f, int option); @@ -267,7 +265,6 @@ extern void parse(keyword_t kword, int (*dofun)(struct unit *, struct order *), * sonst großes Unglück. Durch asserts an ein paar Stellen abgesichert. */ void verify_data(void); -void stripfaction(struct faction * f); void freestrlist(strlist * s); int change_hitpoints(struct unit *u, int value); @@ -287,7 +284,6 @@ boolean unit_has_cursed_item(struct unit *u); /* simple garbage collection: */ void * gc_add(void * p); -void addmessage(struct region * r, struct faction * f, const char *s, msg_t mtype, int level); /* grammatik-flags: */ #define GF_NONE 0 diff --git a/src/common/kernel/faction.c b/src/common/kernel/faction.c index 2911ec003..75db1ec34 100644 --- a/src/common/kernel/faction.c +++ b/src/common/kernel/faction.c @@ -47,6 +47,44 @@ #include #include +/** remove the faction from memory. + * this frees all memory that's only accessible through the faction, + * but you should still call funhash and remove the faction from the + * global list. + */ +void +free_faction (faction * f) +{ + if (f->msgs) free_messagelist(f->msgs); + while (f->battles) { + struct bmsg * bm = f->battles; + f->battles = bm->next; + if (bm->msgs) free_messagelist(bm->msgs); + free(bm); + } + + while (f->groups) { + group * g = f->groups; + f->groups = g->next; + free_group(g); + } + freelist(f->allies); + + free(f->email); + free(f->banner); + free(f->passw); + free(f->override); + free(f->name); + + while (f->attribs) { + a_remove (&f->attribs, f->attribs); + } + + i_freeall(&f->items); + + freelist(f->ursprung); +} + faction * get_monsters(void) { diff --git a/src/common/kernel/faction.h b/src/common/kernel/faction.h index ea60f47f9..bbbf4ed18 100644 --- a/src/common/kernel/faction.h +++ b/src/common/kernel/faction.h @@ -125,6 +125,7 @@ extern variant read_faction_reference(struct storage * store); extern int resolve_faction(variant data, void * addr); extern void renumber_faction(faction * f, int no); +void free_faction(struct faction * f); #ifdef SMART_INTERVALS extern void update_interval(struct faction * f, struct region * r); diff --git a/src/common/kernel/message.h b/src/common/kernel/message.h index fdafbe08a..39094bc81 100644 --- a/src/common/kernel/message.h +++ b/src/common/kernel/message.h @@ -46,6 +46,7 @@ extern struct message * msg_message(const char * name, const char* sig, ...); extern struct message * msg_feedback(const struct unit *, struct order *cmd, const char * name, const char* sig, ...); extern struct message * add_message(struct message_list** pm, struct message * m); +void addmessage(struct region * r, struct faction * f, const char *s, msg_t mtype, int level); #define ADDMSG(msgs, mcreate) { message * m = mcreate; if (m) { assert(m->refcount>=1); add_message(msgs, m); msg_release(m); } } diff --git a/src/common/kernel/order.c b/src/common/kernel/order.c index 630708770..2afad4695 100644 --- a/src/common/kernel/order.c +++ b/src/common/kernel/order.c @@ -500,7 +500,7 @@ is_persistent(const order * ord) } char * -write_order(const order * ord, const struct locale * lang, char * buffer, size_t size) +write_order(const order * ord, char * buffer, size_t size) { if (ord==0) { buffer[0]=0; diff --git a/src/common/kernel/order.h b/src/common/kernel/order.h index d03b34155..29f273863 100644 --- a/src/common/kernel/order.h +++ b/src/common/kernel/order.h @@ -52,7 +52,7 @@ extern boolean is_persistent(const order *ord); extern boolean is_exclusive(const order *ord); extern boolean is_repeated(const order * ord); -extern char * write_order(const order * ord, const struct locale * lang, char * buffer, size_t size); +extern char * write_order(const order * ord, char * buffer, size_t size); #ifdef __cplusplus diff --git a/src/common/kernel/race.c b/src/common/kernel/race.c index 66d6e3012..338fe92e5 100644 --- a/src/common/kernel/race.c +++ b/src/common/kernel/race.c @@ -192,36 +192,6 @@ set_show_item(faction *f, item_t i) a->data.v = (void*)olditemtype[i]; } -int -unit_max_hp(const unit * u) -{ - int h; - double p; - static const curse_type * heal_ct = NULL; - h = u->race->hitpoints; - if (heal_ct==NULL) heal_ct = ct_find("healingzone"); - - - p = pow(effskill(u, SK_STAMINA) / 2.0, 1.5) * 0.2; - h += (int) (h * p + 0.5); - -#if KARMA_MODULE - if (fspecial(u->faction, FS_UNDEAD)) { - h *= 2; - } -#endif /* KARMA_MODULE */ - - /* der healing curse verändert die maximalen hp */ - if (heal_ct) { - curse *c = get_curse(u->region->attribs, heal_ct); - if (c) { - h = (int) (h * (1.0+(curse_geteffect(c)/100))); - } - } - - return h; -} - boolean r_insectstalled(const region * r) { diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index 49169f7b4..8cd656b23 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -891,6 +891,39 @@ freeland(land_region * lr) free(lr); } +void +region_setresource(region * r, const resource_type * rtype, int value) +{ + rawmaterial * rm = r->resources; + while (rm) { + if (rm->type->rtype==rtype) { + rm->amount = value; + break; + } + rm=rm->next; + } + if (!rm) { + if (rtype==rt_find("money")) rsetmoney(r, value); + else if (rtype==rt_find("peasant")) rsetpeasants(r, value); + else if (rtype==rt_find("horse")) rsethorses(r, value); + } +} + +int +region_getresource(const region * r, const resource_type * rtype) +{ + const rawmaterial * rm; + for (rm=r->resources;rm;rm=rm->next) { + if (rm->type->rtype==rtype) { + return rm->amount; + } + } + if (rtype==rt_find("money")) return rmoney(r); + if (rtype==rt_find("horse")) return rhorses(r); + if (rtype==rt_find("peasant")) return rpeasants(r); + return 0; +} + void free_region(region * r) { diff --git a/src/common/kernel/region.h b/src/common/kernel/region.h index efb18d8ff..0e0bd4ed2 100644 --- a/src/common/kernel/region.h +++ b/src/common/kernel/region.h @@ -126,8 +126,8 @@ typedef struct region_list { struct region * data; } region_list; -extern struct message_list * r_getmessages(const struct region * r, const struct faction * viewer); -extern struct message * r_addmessage(struct region * r, const struct faction * viewer, struct message * msg); +struct message_list * r_getmessages(const struct region * r, const struct faction * viewer); +struct message * r_addmessage(struct region * r, const struct faction * viewer, struct message * msg); typedef struct spec_direction { short x, y; @@ -145,13 +145,12 @@ typedef struct { int distance(const struct region*, const struct region*); int koor_distance(int ax, int ay, int bx, int by) ; -extern direction_t reldirection(const struct region * from, const struct region * to); -extern struct region * findregion(short x, short y); -extern struct region * findregionbyid(unsigned int uid); +direction_t reldirection(const struct region * from, const struct region * to); +struct region * findregion(short x, short y); +struct region * findregionbyid(unsigned int uid); extern struct attrib_type at_direction; extern struct attrib_type at_moveblock; -/* new: */ extern struct attrib_type at_peasantluck; extern struct attrib_type at_horseluck; extern struct attrib_type at_chaoscount; @@ -166,10 +165,10 @@ void runhash(struct region * r); void free_regionlist(region_list *rl); void add_regionlist(region_list **rl, struct region *r); -extern struct region * find_special_direction(const struct region *r, const char *token, const struct locale * lang); -extern void register_special_direction(const char * name); -extern struct spec_direction * special_direction(const region * from, const region * to); -extern struct attrib *create_special_direction(struct region *r, struct region *rt, +struct region * find_special_direction(const struct region *r, const char *token, const struct locale * lang); +void register_special_direction(const char * name); +struct spec_direction * special_direction(const region * from, const region * to); +struct attrib *create_special_direction(struct region *r, struct region *rt, int duration, const char *desc, const char *keyword); @@ -180,7 +179,7 @@ void deathcounts(struct region * r, int delta); void chaoscounts(struct region * r, int delta); void setluxuries(struct region * r, const struct luxury_type * sale); -extern int get_maxluxuries(void); +int get_maxluxuries(void); short rroad(const struct region * r, direction_t d); void rsetroad(struct region * r, direction_t d, short value); @@ -205,52 +204,53 @@ void rsethorses(const struct region * r, int value); #define rherbs(r) ((r)->land?(r)->land->herbs:0) #define rsetherbs(r, value) if ((r)->land) ((r)->land->herbs=(short)(value)) -extern boolean r_isforest(const struct region * r); +boolean r_isforest(const struct region * r); #define rterrain(r) (oldterrain((r)->terrain)) #define rsetterrain(r, t) ((r)->terrain = newterrain(t)) -extern const char * rname(const struct region * r, const struct locale * lang); +const char * rname(const struct region * r, const struct locale * lang); #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); +void r_setdemand(struct region * r, const struct luxury_type * ltype, int value); +int r_demand(const struct region * r, const struct luxury_type * ltype); -extern const char * write_regionname(const struct region * r, const struct faction * f, char * buffer, size_t size); +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); -extern void remove_region(region ** rlist, region * r); -extern void terraform_region(struct region * r, const struct terrain_type * terrain); +struct region * new_region(short x, short y, unsigned int uid); +void remove_region(region ** rlist, region * r); +void terraform_region(struct region * r, const struct terrain_type * terrain); extern const short delta_x[MAXDIRECTIONS]; extern const short delta_y[MAXDIRECTIONS]; -extern direction_t dir_invert(direction_t dir); -extern int production(const struct region *r); +direction_t dir_invert(direction_t dir); +int production(const struct region *r); void region_setowner(struct region * r, struct faction * owner); -extern struct faction * region_owner(const struct region * r); +struct faction * region_owner(const struct region * r); -extern struct region * r_connect(const struct region *, direction_t dir); +struct region * r_connect(const struct region *, direction_t dir); #ifdef FAST_CONNECT # define rconnect(r, dir) ((r)->connect[dir]?(r)->connect[dir]:r_connect(r, dir)) #else # define rconnect(r, dir) r_connect(r, dir) #endif -extern void free_regions(void); +void free_regions(void); -extern void write_region_reference(const struct region * r, struct storage * store); -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); +void write_region_reference(const struct region * r, struct storage * store); +variant read_region_reference(struct storage * store); +int resolve_region_coor(variant id, void * address); +int resolve_region_id(variant id, void * address); #define RESOLVE_REGION(version) ((version string */ size_t len; variant var; - write_order(ord, report->locale, buf, sizeof(buf)); + write_order(ord, buf, sizeof(buf)); len = strlen(buf); var.v = strcpy(balloc(len+1), buf); opush(stack, var); diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index 0574d111a..07edf9268 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -607,7 +607,7 @@ static void writeorder(struct storage * store, const struct order * ord, const struct locale * lang) { char obuf[1024]; - write_order(ord, lang, obuf, sizeof(obuf)); + write_order(ord, obuf, sizeof(obuf)); if (obuf[0]) store->w_str(store, obuf); } @@ -837,8 +837,8 @@ writeunit(struct storage * store, const unit * u) write_items(store, u->items); store->w_brk(store); if (u->hp == 0) { - log_error(("Einheit %s hat 0 Trefferpunkte\n", itoa36(u->no))); - ((unit*)u)->hp = 1; + log_error(("unit %s has 0 hitpoints, adjusting.\n", itoa36(u->no))); + ((unit*)u)->hp = u->number; } store->w_int(store, u->hp); store->w_brk(store); diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index a9cdc0c93..f9f749ebb 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -1546,3 +1546,137 @@ unit_setinfo(unit * u, const char * info) else u->display = NULL; } +int +unit_getid(const unit * u) +{ + return u->no; +} + +void +unit_setid(unit * u, int id) +{ + unit * nu = findunit(id); + if (nu==NULL) { + uunhash(u); + u->no = id; + uhash(u); + } +} + +int +unit_gethp(const unit * u) +{ + return u->hp; +} + +void +unit_sethp(unit * u, int hp) +{ + u->hp = hp; +} + +status_t +unit_getstatus(const unit * u) +{ + return u->status; +} + +void +unit_setstatus(unit * u, status_t status) +{ + u->status = status; +} + +int +unit_getweight(const unit * u) +{ + return weight(u); +} + +int +unit_getcapacity(const unit * u) +{ + return walkingcapacity(u); +} + +void +unit_addorder(unit * u, order * ord) +{ + order ** ordp = &u->orders; + while (*ordp) ordp = &(*ordp)->next; + *ordp = ord; + u->faction->lastorders = turn; +} + +int +unit_max_hp(const unit * u) +{ + int h; + double p; + static const curse_type * heal_ct = NULL; + h = u->race->hitpoints; + if (heal_ct==NULL) heal_ct = ct_find("healingzone"); + + p = pow(effskill(u, SK_STAMINA) / 2.0, 1.5) * 0.2; + h += (int) (h * p + 0.5); + +#if KARMA_MODULE + if (fspecial(u->faction, FS_UNDEAD)) { + h *= 2; + } +#endif /* KARMA_MODULE */ + + /* der healing curse verändert die maximalen hp */ + if (heal_ct) { + curse *c = get_curse(u->region->attribs, heal_ct); + if (c) { + h = (int) (h * (1.0+(curse_geteffect(c)/100))); + } + } + + return h; +} + +void +scale_number (unit * u, int n) +{ + skill_t sk; + const attrib * a; + int remain; + + if (n == u->number) return; + if (n && u->number>0) { + int full; + remain = ((u->hp%u->number) * (n % u->number)) % u->number; + + full = u->hp/u->number; /* wieviel kriegt jede person mindestens */ + u->hp = full * n + (u->hp-full*u->number) * n / u->number; + assert(u->hp>=0); + if ((rng_int() % u->number) < remain) + ++u->hp; /* Nachkommastellen */ + } else { + remain = 0; + u->hp = 0; + } + if (u->number>0) { + for (a = a_find(u->attribs, &at_effect);a && a->type==&at_effect;a=a->next) { + effect_data * data = (effect_data *)a->data.v; + int snew = data->value / u->number * n; + if (n) { + remain = data->value - snew / n * u->number; + snew += remain * n / u->number; + remain = (remain * n) % u->number; + if ((rng_int() % u->number) < remain) + ++snew; /* Nachkommastellen */ + } + data->value = snew; + } + } + if (u->number==0 || n==0) { + for (sk = 0; sk < MAXSKILLS; sk++) { + remove_skill(u, sk); + } + } + + set_number(u, n); +} diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h index 257b1d940..7d613097d 100644 --- a/src/common/kernel/unit.h +++ b/src/common/kernel/unit.h @@ -213,11 +213,21 @@ 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); - +const char * unit_getname(const struct unit * u); +void unit_setname(struct unit * u, const char * name); +const char * unit_getinfo(const struct unit * u); +void unit_setinfo(struct unit * u, const char * name); +int unit_getid(const unit * u); +void unit_setid(unit * u, int id); +int unit_gethp(const unit * u); +void unit_sethp(unit * u, int id); +status_t unit_getstatus(const unit * u); +void unit_setstatus(unit * u, status_t status); +int unit_getweight(const unit * u); +int unit_getcapacity(const unit * u); +void unit_addorder(unit * u, struct order * ord); +int unit_max_hp(const struct unit * u); +void scale_number(struct unit * u, int n); extern struct attrib_type at_creator; #ifdef __cplusplus diff --git a/src/common/spells/spells.h b/src/common/spells/spells.h index 34b5b6570..44088cfd5 100644 --- a/src/common/spells/spells.h +++ b/src/common/spells/spells.h @@ -40,7 +40,7 @@ extern "C" { int countdown; } wall_data; - int levitate_ship(ship * sh, unit * mage, double power, int duration); + int levitate_ship(struct ship * sh, struct unit * mage, double power, int duration); #ifdef __cplusplus } diff --git a/src/eressea.sln b/src/eressea.sln index 7c8fccf2c..1016a7601 100644 --- a/src/eressea.sln +++ b/src/eressea.sln @@ -1,5 +1,5 @@ Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 +# Visual C++ Express 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "util", "common\util.vcproj", "{F70CFB27-8A2F-E447-B452-4E1C590EDA6D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kernel", "common\kernel.vcproj", "{6F104C0A-DDF5-A34B-A89C-0DC278DCEF6D}" @@ -12,20 +12,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "editor", "eressea\editor.vc EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eressea-lua", "eressea\eressea-lua.vcproj", "{75501170-51C2-E641-BA8B-EDC008184192}" ProjectSection(ProjectDependencies) = postProject - {F70CFB27-8A2F-E447-B452-4E1C590EDA6D} = {F70CFB27-8A2F-E447-B452-4E1C590EDA6D} {6F104C0A-DDF5-A34B-A89C-0DC278DCEF6D} = {6F104C0A-DDF5-A34B-A89C-0DC278DCEF6D} + {F70CFB27-8A2F-E447-B452-4E1C590EDA6D} = {F70CFB27-8A2F-E447-B452-4E1C590EDA6D} {1E8BFF9E-3044-0742-992F-C5765B80FE65} = {1E8BFF9E-3044-0742-992F-C5765B80FE65} - {74B1CBD4-3B6E-E544-9475-33FBB0BCE165} = {74B1CBD4-3B6E-E544-9475-33FBB0BCE165} {D893D6B3-805D-9848-8EA4-CDA1B79151F6} = {D893D6B3-805D-9848-8EA4-CDA1B79151F6} + {74B1CBD4-3B6E-E544-9475-33FBB0BCE165} = {74B1CBD4-3B6E-E544-9475-33FBB0BCE165} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "eressea", "eressea.vcproj", "{AD80EB0B-7CB4-42F2-9C95-8CCEF68DB387}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "codegen", "tools\codegen\codegen.vcproj", "{BEF9E49F-3E98-4CE7-B641-62456E656E34}" +EndProject Global - GlobalSection(SubversionScc) = preSolution - Svn-Managed = True - Manager = AnkhSVN - Subversion Support for Visual Studio - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Profile|Win32 = Profile|Win32 @@ -68,8 +66,18 @@ Global {AD80EB0B-7CB4-42F2-9C95-8CCEF68DB387}.Profile|Win32.Build.0 = Release|Win32 {AD80EB0B-7CB4-42F2-9C95-8CCEF68DB387}.Release|Win32.ActiveCfg = Release|Win32 {AD80EB0B-7CB4-42F2-9C95-8CCEF68DB387}.Release|Win32.Build.0 = Release|Win32 + {BEF9E49F-3E98-4CE7-B641-62456E656E34}.Debug|Win32.ActiveCfg = Debug|Win32 + {BEF9E49F-3E98-4CE7-B641-62456E656E34}.Debug|Win32.Build.0 = Debug|Win32 + {BEF9E49F-3E98-4CE7-B641-62456E656E34}.Profile|Win32.ActiveCfg = Release|Win32 + {BEF9E49F-3E98-4CE7-B641-62456E656E34}.Profile|Win32.Build.0 = Release|Win32 + {BEF9E49F-3E98-4CE7-B641-62456E656E34}.Release|Win32.ActiveCfg = Release|Win32 + {BEF9E49F-3E98-4CE7-B641-62456E656E34}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(SubversionScc) = preSolution + Svn-Managed = True + Manager = AnkhSVN - Subversion Support for Visual Studio + EndGlobalSection EndGlobal diff --git a/src/eressea/eressea-lua.vcproj b/src/eressea/eressea-lua.vcproj index a763a6b42..0e95b1d97 100644 --- a/src/eressea/eressea-lua.vcproj +++ b/src/eressea/eressea-lua.vcproj @@ -275,6 +275,26 @@ + + + + + + + + + + diff --git a/src/eressea/lua/eressea.cpp b/src/eressea/lua/eressea.cpp index 129806288..aa6ba848d 100644 --- a/src/eressea/lua/eressea.cpp +++ b/src/eressea/lua/eressea.cpp @@ -164,40 +164,6 @@ lua_equipunit(unit * u, const char * eqname) equip_unit(u, get_equipment(eqname)); } -static void -update_subscriptions(void) -{ - FILE * F; - char zText[MAX_PATH]; - faction * f; - strcat(strcpy(zText, basepath()), "/subscriptions"); - F = fopen(zText, "r"); - if (F==NULL) { - log_info((0, "could not open %s.\n", zText)); - return; - } - for (;;) { - char zFaction[5]; - int subscription, fno; - if (fscanf(F, "%d %s", &subscription, zFaction)<=0) break; - fno = atoi36(zFaction); - f = findfaction(fno); - if (f!=NULL) { - f->subscription=subscription; - } - } - fclose(F); - - sprintf(zText, "subscriptions.%u", turn); - F = fopen(zText, "w"); - for (f=factions;f!=NULL;f=f->next) { - fprintf(F, "%s:%u:%s:%s:%s:%u:\n", - itoa36(f->no), f->subscription, f->email, f->override, - dbrace(f->race), f->lastorders); - } - fclose(F); -} - static void lua_learnskill(unit * u, const char * skname, float chances) { diff --git a/src/eressea/lua/message.cpp b/src/eressea/lua/message.cpp index 906ea7329..139ca35a7 100644 --- a/src/eressea/lua/message.cpp +++ b/src/eressea/lua/message.cpp @@ -176,6 +176,11 @@ operator<<(std::ostream& stream, const lua_message& msg) return stream; } +lua_message * +create_lua_message(const char * str) +{ + return new lua_message(str); +} void bind_message(lua_State * L) @@ -185,6 +190,7 @@ bind_message(lua_State * L) .def(constructor()) .def(tostring(const_self)) + .def("create", create_lua_message) .def("set_unit", &lua_message::set_unit) .def("set_region", &lua_message::set_region) .def("set_resource", &lua_message::set_resource) diff --git a/src/eressea/lua/unit.cpp b/src/eressea/lua/unit.cpp index fe0294a1e..30749a8cd 100644 --- a/src/eressea/lua/unit.cpp +++ b/src/eressea/lua/unit.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -358,23 +359,6 @@ unit_getbuilding(const unit * u) return u->building; } -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 bool get_flag(const unit * u, const char * name) { @@ -456,15 +440,14 @@ unit_setmagic(unit * u, const char * type) } static void -unit_addorder(unit * u, const char * str) +unit_add_order(unit * u, const char * str) { order * ord = parse_order(str, u->faction->locale); - addlist(&u->orders, ord); - u->faction->lastorders = turn; + unit_addorder(u, ord); } static void -unit_clearorders(unit * u) +unit_clear_orders(unit * u) { free_orders(&u->orders); } @@ -574,8 +557,8 @@ bind_unit(lua_State * L) .property("familiar", &unit_getfamiliar, &unit_setfamiliar) // orders: - .def("add_order", &unit_addorder) - .def("clear_orders", &unit_clearorders) + .def("add_order", &unit_add_order) + .def("clear_orders", &unit_clear_orders) .property("orders", &unit_orders, return_stl_iterator) // key-attributes for named flags: diff --git a/src/eressea/server.cpp b/src/eressea/server.cpp index e68fa6691..8ed3a8097 100644 --- a/src/eressea/server.cpp +++ b/src/eressea/server.cpp @@ -100,6 +100,9 @@ #include #include "tolua/bindings.h" #include "tolua/helpers.h" +#include "tolua/bind_unit.h" +#include "tolua/bind_faction.h" +#include "tolua/bind_message.h" #endif // BINDINGS_TOLUA #ifdef BINDINGS_LUABIND @@ -286,6 +289,10 @@ lua_init(void) #ifdef BINDINGS_TOLUA register_tolua_helpers(); tolua_eressea_open(L); + tolua_unit_open(L); + tolua_faction_open(L); + tolua_unit_open(L); + tolua_message_open(L); #endif #ifdef BINDINGS_LUABIND diff --git a/src/eressea/tolua/bind_faction.c b/src/eressea/tolua/bind_faction.c new file mode 100644 index 000000000..3e8b67f63 --- /dev/null +++ b/src/eressea/tolua/bind_faction.c @@ -0,0 +1,256 @@ +/* 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 + +#include +#include + +#include +#include + +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 */ +} + +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_faction_get_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_faction_get_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_faction_get_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_faction_get_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_faction_get_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_faction_get_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_faction_get_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_faction_get_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_faction_get_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_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; +} + +void +tolua_faction_open(lua_State* tolua_S) +{ + /* register user types */ + tolua_usertype(tolua_S, "faction"); + 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_faction_get_name, tolua_faction_set_name); + tolua_variable(tolua_S, "units", tolua_faction_get_units, NULL); + tolua_variable(tolua_S, "heroes", tolua_faction_get_heroes, NULL); + tolua_variable(tolua_S, "maxheroes", tolua_faction_get_maxheroes, NULL); + tolua_variable(tolua_S, "password", tolua_faction_get_password, tolua_faction_set_password); + tolua_variable(tolua_S, "email", tolua_faction_get_email, tolua_faction_set_email); + tolua_variable(tolua_S, "locale", tolua_faction_get_locale, tolua_faction_set_locale); + tolua_variable(tolua_S, "race", tolua_faction_get_race, tolua_faction_set_race); + tolua_variable(tolua_S, "alliance", tolua_faction_get_alliance, tolua_faction_set_alliance); + tolua_variable(tolua_S, "score", tolua_faction_get_score, NULL); + tolua_variable(tolua_S, "id", tolua_faction_get_id, NULL); + tolua_variable(tolua_S, "age", tolua_faction_get_age, NULL); + tolua_variable(tolua_S, "options", tolua_faction_get_options, NULL); + tolua_variable(tolua_S, "flags", tolua_faction_get_flags, NULL); + tolua_variable(tolua_S, "lastturn", tolua_faction_get_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_endmodule(tolua_S); +} diff --git a/src/eressea/tolua/bind_faction.h b/src/eressea/tolua/bind_faction.h new file mode 100644 index 000000000..d504f0281 --- /dev/null +++ b/src/eressea/tolua/bind_faction.h @@ -0,0 +1,24 @@ +/* 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; + int tolua_factionlist_next(struct lua_State *tolua_S); + int tolua_factionlist_iter(struct lua_State *tolua_S); + void tolua_faction_open(struct lua_State *tolua_S); + +#ifdef __cplusplus +} +#endif diff --git a/src/eressea/tolua/bind_message.c b/src/eressea/tolua/bind_message.c new file mode 100644 index 000000000..9cc0879aa --- /dev/null +++ b/src/eressea/tolua/bind_message.c @@ -0,0 +1,307 @@ +#include +#include + +// kernel includes +#include +#include +#include +#include +#include + +// util includes +#include + +// lua includes +#include +#include + +#define E_OK 0 +#define E_INVALID_MESSAGE 1 +#define E_INVALID_PARAMETER_NAME 2 +#define E_INVALID_PARAMETER_TYPE 3 +#define E_INVALID_PARAMETER_VALUE 4 + +typedef struct lua_message { + const message_type * mtype; + message * msg; + variant * args; +} lua_message; + +int +mtype_get_param(const message_type * mtype, const char * param) +{ + int i; + for (i=0;i!=mtype->nparameters;++i) { + if (strcmp(mtype->pnames[i], param)==0) { + return i; + } + } + return mtype->nparameters; +} + +static lua_message * +msg_create_message(const char *type) +{ + lua_message * lmsg = malloc(sizeof(lua_message)); + lmsg->msg = 0; + lmsg->args = 0; + lmsg->mtype = mt_find(type); + if (lmsg->mtype) { + lmsg->args = (variant*)calloc(lmsg->mtype->nparameters, sizeof(variant)); + } + return lmsg; +} + +static void +msg_destroy_message(lua_message * msg) +{ + if (msg->msg) msg_release(msg->msg); + if (msg->mtype) { + int i; + for (i=0;i!=msg->mtype->nparameters;++i) { + if (msg->mtype->types[i]->release) { + msg->mtype->types[i]->release(msg->args[i]); + } + } + } +} + +int +msg_set_resource(lua_message * msg, const char * param, const char * resname) +{ + if (msg->mtype) { + int i = mtype_get_param(msg->mtype, param); + if (i==msg->mtype->nparameters) { + return E_INVALID_PARAMETER_NAME; + } + if (strcmp(msg->mtype->types[i]->name, "resource")!=0) { + return E_INVALID_PARAMETER_TYPE; + } + + msg->args[i].v = (void*)rt_find(resname); + + return E_OK; + } + return E_INVALID_MESSAGE; +} + +int +msg_set_unit(lua_message * msg, const char * param, const unit * u) +{ + int i = mtype_get_param(msg->mtype, param); + + if (msg->mtype) { + + if (i==msg->mtype->nparameters) { + return E_INVALID_PARAMETER_NAME; + } + if (strcmp(msg->mtype->types[i]->name, "unit")!=0) { + return E_INVALID_PARAMETER_TYPE; + } + + msg->args[i].v = (void*)u; + + return E_OK; + } + return E_INVALID_MESSAGE; +} + +int +msg_set_region(lua_message * msg, const char * param, const region * r) +{ + int i = mtype_get_param(msg->mtype, param); + if (msg->mtype) { + + if (i==msg->mtype->nparameters) { + return E_INVALID_PARAMETER_NAME; + } + if (strcmp(msg->mtype->types[i]->name, "region")!=0) { + return E_INVALID_PARAMETER_TYPE; + } + + msg->args[i].v = (void*)r; + + return E_OK; + } + return E_INVALID_MESSAGE; +} + +int +msg_set_string(lua_message * msg, const char * param, const char * value) +{ + int i = mtype_get_param(msg->mtype, param); + if (msg->mtype) { + variant var; + if (i==msg->mtype->nparameters) { + return E_INVALID_PARAMETER_NAME; + } + if (strcmp(msg->mtype->types[i]->name, "string")!=0) { + return E_INVALID_PARAMETER_TYPE; + } + + var.v = (void*)value; + msg->args[i] = msg->mtype->types[i]->copy(var); + + return E_OK; + } + return E_INVALID_MESSAGE; +} + +int +msg_set_int(lua_message * msg, const char * param, int value) +{ + if (msg->mtype) { + int i = mtype_get_param(msg->mtype, param); + if (i==msg->mtype->nparameters) { + return E_INVALID_PARAMETER_NAME; + } + if (strcmp(msg->mtype->types[i]->name, "int")!=0) { + return E_INVALID_PARAMETER_TYPE; + } + + msg->args[i].i = value; + + return E_OK; + } + return E_INVALID_MESSAGE; +} + +int +msg_send_faction(lua_message * msg, faction * f) +{ + if (msg->mtype) { + if (msg->msg==NULL) { + msg->msg = msg_create(msg->mtype, msg->args); + } + add_message(&f->msgs, msg->msg); + return E_OK; + } + return E_INVALID_MESSAGE; +} + +int +msg_send_region(lua_message * lmsg, region * r) +{ + if (lmsg->mtype) { + if (lmsg->msg==NULL) { + lmsg->msg = msg_create(lmsg->mtype, lmsg->args); + } + add_message(&r->msgs, lmsg->msg); + return E_OK; + } + return E_INVALID_MESSAGE; +} + + +static int +tolua_msg_create(lua_State * tolua_S) +{ + const char * type = tolua_tostring(tolua_S, 1, 0); + lua_message * lmsg = msg_create_message(type); + tolua_pushusertype(tolua_S, (void*)lmsg, "message"); + return 1; +} +static int +tolua_msg_set_string(lua_State * tolua_S) +{ + lua_message * lmsg = (lua_message *)tolua_tousertype(tolua_S, 1, 0); + const char * param = tolua_tostring(tolua_S, 2, 0); + const char * value = tolua_tostring(tolua_S, 3, 0); + int result = msg_set_string(lmsg, param, value); + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_msg_set_int(lua_State * tolua_S) +{ + lua_message * lmsg = (lua_message *)tolua_tousertype(tolua_S, 1, 0); + const char * param = tolua_tostring(tolua_S, 2, 0); + int value = (int)tolua_tonumber(tolua_S, 3, 0); + int result = msg_set_int(lmsg, param, value); + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_msg_set_resource(lua_State * tolua_S) +{ + lua_message * lmsg = (lua_message *)tolua_tousertype(tolua_S, 1, 0); + const char * param = tolua_tostring(tolua_S, 2, 0); + const char * value = tolua_tostring(tolua_S, 3, 0); + int result = msg_set_resource(lmsg, param, value); + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_msg_set_unit(lua_State * tolua_S) +{ + lua_message * lmsg = (lua_message *)tolua_tousertype(tolua_S, 1, 0); + const char * param = tolua_tostring(tolua_S, 2, 0); + unit * value = (unit *)tolua_tousertype(tolua_S, 3, 0); + int result = msg_set_unit(lmsg, param, value); + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_msg_set_region(lua_State * tolua_S) +{ + lua_message * lmsg = (lua_message *)tolua_tousertype(tolua_S, 1, 0); + const char * param = tolua_tostring(tolua_S, 2, 0); + region * value = (region *)tolua_tousertype(tolua_S, 3, 0); + int result = msg_set_region(lmsg, param, value); + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_msg_send_region(lua_State * tolua_S) +{ + lua_message * lmsg = (lua_message *)tolua_tousertype(tolua_S, 1, 0); + region * r = (region *)tolua_tousertype(tolua_S, 2, 0); + int result = msg_send_region(lmsg, r); + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_msg_send_faction(lua_State * tolua_S) +{ + lua_message * lmsg = (lua_message *)tolua_tousertype(tolua_S, 1, 0); + faction * f = (faction *)tolua_tousertype(tolua_S, 2, 0); + int result = msg_send_faction(lmsg, f); + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +void +tolua_message_open(lua_State* tolua_S) +{ + /* register user types */ + tolua_usertype(tolua_S, "message"); + + tolua_module(tolua_S, NULL, 0); + tolua_beginmodule(tolua_S, NULL); + { + tolua_function(tolua_S, "message", tolua_msg_create); + + tolua_cclass(tolua_S, "message", "message", "", NULL); + tolua_beginmodule(tolua_S, "message"); + { + tolua_function(tolua_S, "set_unit", tolua_msg_set_unit); + tolua_function(tolua_S, "set_region", tolua_msg_set_region); + tolua_function(tolua_S, "set_resource", tolua_msg_set_resource); + tolua_function(tolua_S, "set_int", tolua_msg_set_int); + tolua_function(tolua_S, "set_string", tolua_msg_set_string); + tolua_function(tolua_S, "send_faction", tolua_msg_send_faction); + tolua_function(tolua_S, "send_region", tolua_msg_send_region); + + tolua_function(tolua_S, "create", tolua_msg_create); + // tolua_function(tolua_S, "destroy", tolua_msg_destroy); + } + tolua_endmodule(tolua_S); + } + tolua_endmodule(tolua_S); +} diff --git a/src/eressea/tolua/bind_message.h b/src/eressea/tolua/bind_message.h new file mode 100644 index 000000000..d93d6d640 --- /dev/null +++ b/src/eressea/tolua/bind_message.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; + void tolua_message_open(struct lua_State *tolua_S); + +#ifdef __cplusplus +} +#endif diff --git a/src/eressea/tolua/bind_unit.c b/src/eressea/tolua/bind_unit.c new file mode 100644 index 000000000..ae01808bc --- /dev/null +++ b/src/eressea/tolua/bind_unit.c @@ -0,0 +1,895 @@ +/* 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 + +// Atributes includes +#include +#include + +// kernel includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// util includes +#include +#include +#include +#include +#include + +#include +#include + +int tolua_spelllist_next(lua_State *tolua_S) +{ + spell_list** spell_ptr = (spell_list **)lua_touserdata(tolua_S, lua_upvalueindex(1)); + spell_list* slist = *spell_ptr; + if (slist != NULL) { + tolua_pushusertype(tolua_S, slist->data, "spell"); + *spell_ptr = slist->next; + return 1; + } + else return 0; /* no more values to return */ +} + +int tolua_itemlist_next(lua_State *tolua_S) +{ + item** item_ptr = (item **)lua_touserdata(tolua_S, lua_upvalueindex(1)); + item* itm = *item_ptr; + if (itm != NULL) { + tolua_pushstring(tolua_S, itm->type->rtype->_name[0]); + *item_ptr = itm->next; + return 1; + } + else return 0; /* no more values to return */ +} + +int tolua_orderlist_next(lua_State *tolua_S) +{ + order** order_ptr = (order **)lua_touserdata(tolua_S, lua_upvalueindex(1)); + order* ord = *order_ptr; + if (ord != NULL) { + char cmd[8192]; + write_order(ord, cmd, sizeof(cmd)); + tolua_pushstring(tolua_S, cmd); + *order_ptr = ord->next; + return 1; + } + else return 0; /* no more values to return */ +} + +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 */ +} + +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_unit_get_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_unit_set_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_unit_get_info(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, unit_getinfo(self)); + return 1; +} + +static int tolua_unit_set_info(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + unit_setinfo(self, tolua_tostring(tolua_S, 2, 0)); + return 0; +} + +static int tolua_unit_get_id(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)unit_getid(self)); + return 1; +} + +static int tolua_unit_set_id(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + unit_setid(self, (int)tolua_tonumber(tolua_S, 2, 0)); + return 0; +} + +static int tolua_unit_get_hpmax(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)unit_max_hp(self)); + return 1; +} + +static int tolua_unit_get_hp(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)unit_gethp(self)); + return 1; +} + +static int tolua_unit_set_hp(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + unit_sethp(self, (int)tolua_tonumber(tolua_S, 2, 0)); + return 0; +} + +static int tolua_unit_get_number(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)self->number); + return 1; +} + +static int tolua_unit_set_number(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + int number = (int)tolua_tonumber(tolua_S, 2, 0); + if (self->number==0) { + set_number(self, number); + self->hp = unit_max_hp(self) * number; + } else { + scale_number(self, number); + } + return 0; +} + +static int tolua_unit_get_flags(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)self->flags); + return 1; +} + +static int tolua_unit_set_flags(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + self->flags = (int)tolua_tonumber(tolua_S, 2, 0); + return 0; +} + +static const char * +unit_getmagic(const unit * u) +{ + sc_mage * mage = get_mage(u); + return mage?magietypen[mage->magietyp]:NULL; +} + +static int tolua_unit_get_magic(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + lua_pushstring(tolua_S, unit_getmagic(self)); + return 1; +} + +static void +unit_setmagic(unit * u, const char * type) +{ + sc_mage * mage = get_mage(u); + magic_t mtype; + for (mtype=0;mtype!=MAXMAGIETYP;++mtype) { + if (strcmp(magietypen[mtype], type)==0) break; + } + if (mtype==MAXMAGIETYP) return; + if (mage==NULL) { + mage = create_mage(u, mtype); + } +} + +static int tolua_unit_set_magic(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * type = tolua_tostring(tolua_S, 2, 0); + unit_setmagic(self, type); + return 0; +} + +static int tolua_unit_get_aura(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)get_spellpoints(self)); + return 1; +} + +static int tolua_unit_set_aura(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + set_spellpoints(self, (int)tolua_tonumber(tolua_S, 2, 0)); + return 0; +} + +static int tolua_unit_get_age(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)self->age); + return 1; +} + +static int tolua_unit_set_age(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + self->age = (short)tolua_tonumber(tolua_S, 2, 0); + return 0; +} + +static int tolua_unit_get_status(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)unit_getstatus(self)); + return 1; +} + +static int tolua_unit_set_status(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + unit_setstatus(self, (status_t)tolua_tonumber(tolua_S, 2, 0)); + return 0; +} + +static int +tolua_unit_get_item(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * iname = tolua_tostring(tolua_S, 2, 0); + int result = -1; + + if (iname!=NULL) { + const item_type * itype = it_find(iname); + if (itype!=NULL) { + result = i_get(self->items, itype); + } + } + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_unit_add_item(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * iname = tolua_tostring(tolua_S, 2, 0); + int number = (int)tolua_tonumber(tolua_S, 3, 0); + int result = -1; + + if (iname!=NULL) { + const item_type * itype = it_find(iname); + if (itype!=NULL) { + item * i = i_change(&self->items, itype, number); + result = i?i->number:0; + } + } + lua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_unit_getskill(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * skname = tolua_tostring(tolua_S, 2, 0); + skill_t sk = sk_find(skname); + int value = -1; + if (sk!=NOSKILL) { + skill * sv = get_skill(self, sk); + if (sv) { + value = sv->level; + } + else value = 0; + } + lua_pushnumber(tolua_S, (lua_Number)value); + return 1; +} + +static int +tolua_unit_effskill(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * skname = tolua_tostring(tolua_S, 2, 0); + skill_t sk = sk_find(skname); + int value = (sk==NOSKILL)?-1:eff_skill(self, sk, self->region); + lua_pushnumber(tolua_S, (lua_Number)value); + return 1; +} + +typedef struct fctr_data { + unit * target; + int fhandle; +} fctr_data; + +typedef struct event { + struct event_arg * args; + char * msg; +} event; + +int +fctr_handle(struct trigger * tp, void * data) +{ + trigger * t = tp; + event evt = { 0 }; + fctr_data * fd = (fctr_data*)t->data.v; + lua_State * L = (lua_State *)global.vm_state; + unit * u = fd->target; + + evt.args = (event_arg*)data; + tolua_pushusertype(L, u, "unit"); + tolua_pushusertype(L, &evt, "event"); + if (lua_pcall(L, 2, 0, 0)!=0) { + const char* error = lua_tostring(L, -1); + log_error(("event (%s): %s", unitname(u), error)); + lua_pop(L, 1); + } + + return 0; +} + +static void +fctr_init(trigger * t) +{ + t->data.v = calloc(sizeof(fctr_data), 1); +} + +static void +fctr_done(trigger * t) +{ + fctr_data * fd = (fctr_data*)t->data.v; + lua_State * L = (lua_State *)global.vm_state; + luaL_unref(L, LUA_REGISTRYINDEX, fd->fhandle); + free(fd); +} + +static struct trigger_type tt_lua = { + "lua_event", + fctr_init, + fctr_done, + fctr_handle +}; + +static trigger * +trigger_lua(struct unit * u, int handle) +{ + trigger * t = t_new(&tt_lua); + fctr_data * td = (fctr_data*)t->data.v; + td->target = u; + td->fhandle = handle; + return t; +} + +static int +tolua_unit_addhandler(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * ename = tolua_tostring(tolua_S, 2, 0); + int handle; + + lua_pushvalue(tolua_S, 3); + handle = luaL_ref(tolua_S, LUA_REGISTRYINDEX); + add_trigger(&self->attribs, ename, trigger_lua(self, handle)); + + return 0; +} + +static int +tolua_unit_addnotice(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * str = tolua_tostring(tolua_S, 2, 0); + + addmessage(self->region, self->faction, str, MSG_MESSAGE, ML_IMPORTANT); + return 0; +} + +static void +unit_castspell(unit * u, const char * name) +{ + spell_list * slist = spells; + while (slist!=NULL) { + spell * sp = slist->data; + if (strcmp(name, sp->sname)==0) { + castorder * co = (castorder*)malloc(sizeof(castorder)); + co->distance = 0; + co->familiar = NULL; + co->force = sp->level; + co->level = sp->level; + co->magician.u = u; + co->order = NULL; + co->par = NULL; + co->rt = u->region; + co->sp = sp; + if (sp->sp_function==NULL) { + log_error(("spell '%s' has no function.\n", sp->sname)); + co->level = 0; + } else { + sp->sp_function(co); + } + free(co); + } + slist=slist->next; + } +} + +static int +tolua_unit_castspell(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * str = tolua_tostring(tolua_S, 2, 0); + unit_castspell(self, str); + return 0; +} + +static void +unit_addspell(unit * u, const char * name) +{ + int add = 0; + spell_list * slist = spells; + while (slist!=NULL) { + spell * sp = slist->data; + if (strcmp(name, sp->sname)==0) { + struct sc_mage * mage = get_mage(u); + if (add) log_error(("two spells are called %s.\n", name)); + add_spell(mage, sp); + add = 1; + } + slist=slist->next; + } + if (!add) log_error(("spell %s could not be found\n", name)); +} + +static int +tolua_unit_addspell(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * str = tolua_tostring(tolua_S, 2, 0); + unit_addspell(self, str); + return 0; +} + +static void +unit_removespell(unit * u, const spell * sp) +{ + sc_mage * mage = get_mage(u); + if (mage!=NULL) { + spell_list ** isptr = &mage->spells; + while (*isptr && (*isptr)->data != sp) { + isptr = &(*isptr)->next; + } + if (*isptr) { + spell_list * sptr = *isptr; + *isptr = sptr->next; + free(sptr); + } + } +} + +static int +tolua_unit_removespell(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + spell * sp = (spell*)tolua_tousertype(tolua_S, 2, 0); + unit_removespell(self, sp); + return 0; +} + +static int +tolua_unit_setracename(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * str = tolua_tostring(tolua_S, 2, 0); + + set_racename(&self->attribs, str); + return 0; +} + +static int +tolua_unit_setskill(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * skname = tolua_tostring(tolua_S, 2, 0); + int level = (int)tolua_tonumber(tolua_S, 3, 0); + skill_t sk = sk_find(skname); + if (sk!=NOSKILL) { + set_level(self, sk, level); + } else { + level = -1; + } + lua_pushnumber(tolua_S, (lua_Number)level); + return 1; +} + +static int +tolua_unit_use_pooled(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * iname = tolua_tostring(tolua_S, 2, 0); + int number = (int)tolua_tonumber(tolua_S, 3, 0); + const resource_type * rtype = rt_find(iname); + int result = -1; + if (rtype!=NULL) { + result = use_pooled(self, rtype, GET_DEFAULT, number); + } + lua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_unit_get_pooled(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * iname = tolua_tostring(tolua_S, 2, 0); + const resource_type * rtype = rt_find(iname); + int result = -1; + if (rtype!=NULL) { + result = get_pooled(self, rtype, GET_DEFAULT, INT_MAX); + } + lua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static unit * +unit_getfamiliar(const unit * u) +{ + attrib * a = a_find(u->attribs, &at_familiar); + if (a!=NULL) { + return (unit*)a->data.v; + } + return NULL; +} + +static int tolua_unit_get_familiar(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushusertype(tolua_S, unit_getfamiliar(self), "unit"); + return 1; +} + +static int tolua_unit_set_familiar(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + create_newfamiliar(self, (unit *)tolua_tousertype(tolua_S, 2, 0)); + return 0; +} + +static int tolua_unit_get_building(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushusertype(tolua_S, self->building, "building"); + return 1; +} + +static void +unit_setbuilding(unit * u, building * b) +{ + leave(u->region, u); + if (u->region!=b->region) { + move_unit(u, b->region, NULL); + } + u->building = b; +} + +static int tolua_unit_set_building(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + unit_setbuilding(self, (building *)tolua_tousertype(tolua_S, 2, 0)); + return 0; +} + +static int tolua_unit_get_ship(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushusertype(tolua_S, self->ship, "ship"); + return 1; +} + +static void +unit_setship(unit * u, ship * s) +{ + leave(u->region, u); + if (u->region!=s->region) { + move_unit(u, s->region, NULL); + } + u->ship = s; +} + +static int tolua_unit_set_ship(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + unit_setship(self, (ship *)tolua_tousertype(tolua_S, 2, 0)); + return 0; +} + +static int tolua_unit_get_region(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushusertype(tolua_S, self->region, "region"); + return 1; +} + +static void +unit_setregion(unit * u, region * r) +{ + move_unit(u, r, NULL); +} + +static int tolua_unit_set_region(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + unit_setregion(self, (region *)tolua_tousertype(tolua_S, 2, 0)); + return 0; +} + +static int tolua_unit_add_order(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * str = tolua_tostring(tolua_S, 2, 0); + order * ord = parse_order(str, self->faction->locale); + unit_addorder(self, ord); + return 0; +} + +static int tolua_unit_clear_orders(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + free_orders(&self->orders); + return 0; +} + +static int tolua_unit_get_items(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + + item ** item_ptr = (item **)lua_newuserdata(tolua_S, sizeof(item *)); + + luaL_getmetatable(tolua_S, "item"); + lua_setmetatable(tolua_S, -2); + + *item_ptr = self->items; + + lua_pushcclosure(tolua_S, tolua_itemlist_next, 1); + + return 1; +} + +static int tolua_unit_get_spells(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + sc_mage * mage; + spell_list ** spell_ptr = (spell_list **)lua_newuserdata(tolua_S, sizeof(spell_list *)); + + luaL_getmetatable(tolua_S, "spell_list"); + lua_setmetatable(tolua_S, -2); + + mage = get_mage(self); + + *spell_ptr = mage?mage->spells:0; + + lua_pushcclosure(tolua_S, tolua_spelllist_next, 1); + + return 1; +} + +static int tolua_unit_get_orders(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + + order ** order_ptr = (order **)lua_newuserdata(tolua_S, sizeof(order *)); + + luaL_getmetatable(tolua_S, "order"); + lua_setmetatable(tolua_S, -2); + + *order_ptr = self->orders; + + lua_pushcclosure(tolua_S, tolua_orderlist_next, 1); + + return 1; +} + +static int tolua_unit_get_flag(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * name = tolua_tostring(tolua_S, 2, 0); + int flag = atoi36(name); + attrib * a = find_key(self->attribs, flag); + lua_pushboolean(tolua_S, (a!=NULL)); + return 1; +} + +static int tolua_unit_set_flag(lua_State* tolua_S) +{ + unit* self = (unit*)tolua_tousertype(tolua_S, 1, 0); + const char * name = tolua_tostring(tolua_S, 2, 0); + int value = (int)tolua_tonumber(tolua_S, 3, 0); + int flag = atoi36(name); + attrib * a = find_key(self->attribs, flag); + if (a==NULL && value) { + add_key(&self->attribs, flag); + } else if (a!=NULL && !value) { + a_remove(&self->attribs, a); + } + return 0; +} + +static int tolua_unit_get_weight(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)unit_getweight(self)); + return 1; +} + +static int tolua_unit_get_capacity(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)unit_getcapacity(self)); + return 1; +} + +static int tolua_unit_get_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_unit_set_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_unit_get_race(lua_State* tolua_S) +{ + unit* self = (unit*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, self->race->_name[0]); + return 1; +} + +static int tolua_unit_set_race(lua_State* tolua_S) +{ + unit * self = (unit*) tolua_tousertype(tolua_S, 1, 0); + const char * rcname = tolua_tostring(tolua_S, 2, 0); + race * rc = rc_find(rcname); + if (rc!=NULL) { + if (self->irace==self->race) self->irace = rc; + self->race = rc; + } + return 0; +} + +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 = create_unit(r, f, 0, f->race, 0, NULL, NULL); + + tolua_pushusertype(tolua_S, u, "unit"); + return 1; +} + +void +tolua_unit_open(lua_State * tolua_S) +{ + /* register user types */ + tolua_usertype(tolua_S, "unit"); + tolua_usertype(tolua_S, "unit_list"); + + tolua_module(tolua_S, NULL, 0); + tolua_beginmodule(tolua_S, NULL); + { + tolua_cclass(tolua_S, "unit", "unit", "", NULL); + tolua_beginmodule(tolua_S, "unit"); + { + tolua_function(tolua_S, "create", tolua_unit_create); + + tolua_variable(tolua_S, "name", tolua_unit_get_name, tolua_unit_set_name); + tolua_variable(tolua_S, "faction", tolua_unit_get_faction, tolua_unit_set_faction); + tolua_variable(tolua_S, "id", tolua_unit_get_id, tolua_unit_set_id); + tolua_variable(tolua_S, "info", tolua_unit_get_info, tolua_unit_set_info); + tolua_variable(tolua_S, "hp", tolua_unit_get_hp, tolua_unit_set_hp); + tolua_variable(tolua_S, "status", tolua_unit_get_status, tolua_unit_set_status); + tolua_variable(tolua_S, "familiar", tolua_unit_get_familiar, tolua_unit_set_familiar); + + tolua_variable(tolua_S, "weight", tolua_unit_get_weight, 0); + tolua_variable(tolua_S, "capacity", tolua_unit_get_capacity, 0); + + tolua_function(tolua_S, "add_order", tolua_unit_add_order); + tolua_function(tolua_S, "clear_orders", tolua_unit_clear_orders); + tolua_variable(tolua_S, "orders", tolua_unit_get_orders, 0); + + // key-attributes for named flags: + tolua_function(tolua_S, "set_flag", tolua_unit_set_flag); + tolua_function(tolua_S, "get_flag", tolua_unit_get_flag); + tolua_variable(tolua_S, "flags", tolua_unit_get_flags, tolua_unit_set_flags); + tolua_variable(tolua_S, "age", tolua_unit_get_age, tolua_unit_set_age); + + // items: + tolua_function(tolua_S, "get_item", tolua_unit_get_item); + tolua_function(tolua_S, "add_item", tolua_unit_add_item); + tolua_variable(tolua_S, "items", tolua_unit_get_items, 0); + tolua_function(tolua_S, "get_pooled", tolua_unit_get_pooled); + tolua_function(tolua_S, "use_pooled", tolua_unit_use_pooled); + + // skills: + tolua_function(tolua_S, "get_skill", tolua_unit_getskill); + tolua_function(tolua_S, "eff_skill", tolua_unit_effskill); + tolua_function(tolua_S, "set_skill", tolua_unit_setskill); + + tolua_function(tolua_S, "add_notice", tolua_unit_addnotice); + + // npc logic: + tolua_function(tolua_S, "add_handler", tolua_unit_addhandler); + + tolua_function(tolua_S, "set_racename", tolua_unit_setracename); + tolua_function(tolua_S, "add_spell", tolua_unit_addspell); + tolua_function(tolua_S, "remove_spell", tolua_unit_removespell); + tolua_function(tolua_S, "cast_spell", tolua_unit_castspell); + + tolua_variable(tolua_S, "magic", tolua_unit_get_magic, tolua_unit_set_magic); + tolua_variable(tolua_S, "aura", tolua_unit_get_aura, tolua_unit_set_aura); + tolua_variable(tolua_S, "building", tolua_unit_get_building, tolua_unit_set_building); + tolua_variable(tolua_S, "ship", tolua_unit_get_ship, tolua_unit_set_ship); + tolua_variable(tolua_S, "region", tolua_unit_get_region, tolua_unit_set_region); + tolua_variable(tolua_S, "spells", tolua_unit_get_spells, 0); + tolua_variable(tolua_S, "number", tolua_unit_get_number, tolua_unit_set_number); + tolua_variable(tolua_S, "race", tolua_unit_get_race, tolua_unit_set_race); + tolua_variable(tolua_S, "hp_max", tolua_unit_get_hpmax, 0); + } + tolua_endmodule(tolua_S); + } + tolua_endmodule(tolua_S); +} diff --git a/src/eressea/tolua/bind_unit.h b/src/eressea/tolua/bind_unit.h new file mode 100644 index 000000000..8de703d25 --- /dev/null +++ b/src/eressea/tolua/bind_unit.h @@ -0,0 +1,24 @@ +/* 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; + int tolua_unitlist_nextf(struct lua_State *tolua_S); + int tolua_unitlist_next(struct lua_State *tolua_S); + void tolua_unit_open(struct lua_State *tolua_S); + +#ifdef __cplusplus +} +#endif diff --git a/src/eressea/tolua/bindings.c b/src/eressea/tolua/bindings.c index 127fe070d..0d47f49a4 100644 --- a/src/eressea/tolua/bindings.c +++ b/src/eressea/tolua/bindings.c @@ -10,14 +10,22 @@ This program may not be used, modified or distributed without prior permission by the authors of Eressea. */ -#include "bindings.h" #include +#include "bindings.h" +#include "bind_unit.h" +#include "bind_faction.h" + #include #include +#include #include +#include #include +#include +#include +#include #include #include #include @@ -25,6 +33,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include #include #include #include @@ -35,26 +44,13 @@ without prior permission by the authors of Eressea. #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); @@ -69,14 +65,22 @@ static int tolua_set_building_name(lua_State* tolua_S) return 0; } -static int tolua_get_region_name(lua_State* tolua_S) +static int +tolua_region_get_terrain(lua_State* tolua_S) +{ + region* self = (region*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, self->terrain->_name); + return 1; +} + +static int tolua_region_get_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) +static int tolua_region_set_units(lua_State* tolua_S) { region* self = (region*)tolua_tousertype(tolua_S, 1, 0); region_setname(self, tolua_tostring(tolua_S, 2, 0)); @@ -97,57 +101,6 @@ static int tolua_set_ship_name(lua_State* tolua_S) 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)); @@ -160,33 +113,7 @@ static int tolua_regionlist_next(lua_State *tolua_S) 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) +static int tolua_region_get_units(lua_State* tolua_S) { region * self = (region *)tolua_tousertype(tolua_S, 1, 0); unit ** unit_ptr = (unit**)lua_newuserdata(tolua_S, sizeof(unit *)); @@ -293,6 +220,131 @@ tolua_update_guards(lua_State * tolua_S) return 0; } +static int +tolua_get_turn(lua_State * tolua_S) +{ + tolua_pushnumber(tolua_S, (lua_Number)turn); + return 1; +} + +static int +tolua_atoi36(lua_State * tolua_S) +{ + const char * s = tolua_tostring(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)atoi36(s)); + return 1; +} + +static int +tolua_itoa36(lua_State * tolua_S) +{ + int i = (int)tolua_tonumber(tolua_S, 1, 0); + tolua_pushstring(tolua_S, itoa36(i)); + return 1; +} + +static int +tolua_dice_rand(lua_State * tolua_S) +{ + const char * s = tolua_tostring(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, dice_rand(s)); + return 1; +} + +static int +lua_addequipment(const char * eqname, const char * iname, const char * value) +{ + return 0; +} + +static int +tolua_get_season(lua_State * tolua_S) +{ + int turnno = (int)tolua_tonumber(tolua_S, 1, 0); + gamedate gd; + get_gamedate(turnno, &gd); + tolua_pushstring(tolua_S, seasonnames[gd.season]); + return 1; +} + +static int +tolua_learn_skill(lua_State * tolua_S) +{ + unit * u = (unit *)tolua_tousertype(tolua_S, 1, 0); + const char * skname = tolua_tostring(tolua_S, 2, 0); + float chances = (float)tolua_tonumber(tolua_S, 3, 0); + skill_t sk = sk_find(skname); + if (sk!=NOSKILL) { + learn_skill(u, sk, chances); + } + return 0; +} + +static int +tolua_update_scores(lua_State * tolua_S) +{ + score(); + return 0; +} + +static int +tolua_update_subscriptions(lua_State * tolua_S) +{ + update_subscriptions(); + return 0; +} + +static int +tolua_remove_empty_units(lua_State * tolua_S) +{ + remove_empty_units(); + return 0; +} + +static int +tolua_get_nmrs(lua_State * tolua_S) +{ + int result = -1; + int n = (int)tolua_tonumber(tolua_S, 1, 0); + if (n<=NMRTimeout()) { + if (nmrs==NULL) { + update_nmrs(); + result = nmrs[n]; + } + } + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + +static int +tolua_lua_equipunit(lua_State * tolua_S) +{ + unit * u = (unit *)tolua_tousertype(tolua_S, 1, 0); + const char * eqname = tolua_tostring(tolua_S, 2, 0); + + equip_unit(u, get_equipment(eqname)); + + return 0; +} + +static int +tolua_equipment_setitem(lua_State * tolua_S) +{ + int result = -1; + const char * eqname = tolua_tostring(tolua_S, 1, 0); + const char * iname = tolua_tostring(tolua_S, 2, 0); + const char * value = tolua_tostring(tolua_S, 3, 0); + if (iname!=NULL) { + const struct item_type * itype = it_find(iname); + if (itype!=NULL) { + equipment_setitem(create_equipment(eqname), itype, value); + result = 0; + } + } + tolua_pushnumber(tolua_S, (lua_Number)result); + return 1; +} + static int tolua_levitate_ship(lua_State * tolua_S) { @@ -481,6 +533,37 @@ tolua_get_faction(lua_State* tolua_S) return 1; } +static int +tolua_get_region(lua_State* tolua_S) +{ + short x = (short)tolua_tonumber(tolua_S, 1, 0); + short y = (short)tolua_tonumber(tolua_S, 2, 0); + region * r = findregion(x, y); + + tolua_pushusertype(tolua_S, r, "region"); + return 1; +} + +static int +tolua_get_building(lua_State* tolua_S) +{ + int no = (int)tolua_tonumber(tolua_S, 1, 0); + building * b = findbuilding(no); + + tolua_pushusertype(tolua_S, b, "building"); + return 1; +} + +static int +tolua_get_ship(lua_State* tolua_S) +{ + int no = (int)tolua_tonumber(tolua_S, 1, 0); + ship * sh = findship(no); + + tolua_pushusertype(tolua_S, sh, "ship"); + return 1; +} + static int tolua_get_alliance(lua_State* tolua_S) { @@ -501,158 +584,76 @@ tolua_get_unit(lua_State* tolua_S) return 1; } -static int -tolua_unit_create(lua_State* tolua_S) +static int tolua_region_get_flag(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); + region* self = (region*)tolua_tousertype(tolua_S, 1, 0); + int bit = (int)tolua_tonumber(tolua_S, 2, 0); - tolua_pushusertype(tolua_S, u, "unit"); + lua_pushboolean(tolua_S, (self->flags & (1<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); + if (set) self->flags |= (1<flags &= ~(1<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) { @@ -695,24 +696,6 @@ tolua_alliance_create(lua_State* tolua_S) 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) { @@ -756,42 +739,42 @@ tolua_get_alliance_factions(lua_State* tolua_S) return 1; } -static int tolua_get_faction_password(lua_State* tolua_S) +static int tolua_faction_get_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) +static int tolua_faction_set_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) +static int tolua_faction_get_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) +static int tolua_faction_set_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) +static int tolua_faction_get_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) +static int tolua_faction_set_locale(lua_State* tolua_S) { faction* self = (faction*)tolua_tousertype(tolua_S, 1, 0); const char * name = tolua_tostring(tolua_S, 2, 0); @@ -799,14 +782,14 @@ static int tolua_set_faction_locale(lua_State* tolua_S) return 0; } -static int tolua_get_faction_race(lua_State* tolua_S) +static int tolua_faction_get_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) +static int tolua_faction_set_race(lua_State* tolua_S) { faction* self = (faction*)tolua_tousertype(tolua_S, 1, 0); const char * name = tolua_tostring(tolua_S, 2, 0); @@ -818,14 +801,14 @@ static int tolua_set_faction_race(lua_State* tolua_S) return 0; } -static int tolua_get_faction_alliance(lua_State* tolua_S) +static int tolua_faction_get_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) +static int tolua_faction_set_alliance(lua_State* tolua_S) { faction* self = (faction*)tolua_tousertype(tolua_S, 1, 0); alliance* alli = (alliance*)tolua_tousertype(tolua_S, 2, 0); @@ -858,28 +841,28 @@ static int tolua_set_alliance_name(lua_State* tolua_S) return 0; } -static int tolua_get_faction_name(lua_State* tolua_S) +static int tolua_faction_get_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) +static int tolua_faction_set_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) +static int tolua_faction_get_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) +static int tolua_faction_set_info(lua_State* tolua_S) { faction* self = (faction*)tolua_tousertype(tolua_S, 1, 0); faction_setbanner(self, tolua_tostring(tolua_S, 2, 0)); @@ -887,50 +870,25 @@ static int tolua_set_faction_info(lua_State* tolua_S) } -int tolua_eressea_open(lua_State* tolua_S) +int +tolua_eressea_open(lua_State* tolua_S) { tolua_open(tolua_S); /* register user types */ - tolua_usertype(tolua_S, "unit"); + tolua_usertype(tolua_S, "spell"); + tolua_usertype(tolua_S, "spell_list"); + tolua_usertype(tolua_S, "order"); + tolua_usertype(tolua_S, "item"); tolua_usertype(tolua_S, "alliance"); - tolua_usertype(tolua_S, "faction"); + tolua_usertype(tolua_S, "event"); 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"); { @@ -944,8 +902,12 @@ int tolua_eressea_open(lua_State* 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_variable(tolua_S, "name", tolua_region_get_name, tolua_region_set_units); + tolua_variable(tolua_S, "units", tolua_region_get_units, NULL); + tolua_variable(tolua_S, "terrain", tolua_region_get_terrain, NULL); + tolua_function(tolua_S, "get_resource", tolua_region_get_resource); + tolua_function(tolua_S, "set_resource", tolua_region_set_resource); + tolua_function(tolua_S, "get_flag", tolua_region_get_flag); tolua_function(tolua_S, "create", tolua_region_create); } tolua_endmodule(tolua_S); @@ -964,14 +926,12 @@ int tolua_eressea_open(lua_State* tolua_S) } 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); + 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); + tolua_function(tolua_S, "get_ship", tolua_get_ship), + tolua_function(tolua_S, "get_building", tolua_get_building), + tolua_function(tolua_S, "get_region", tolua_get_region), // deprecated_function(tolua_S, "add_faction"); // deprecated_function(tolua_S, "faction_origin"); @@ -997,10 +957,6 @@ int tolua_eressea_open(lua_State* tolua_S) 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); @@ -1014,6 +970,24 @@ int tolua_eressea_open(lua_State* tolua_S) tolua_function(tolua_S, "levitate_ship", tolua_levitate_ship); tolua_function(tolua_S, "update_guards", tolua_update_guards); + + tolua_function(tolua_S, "get_turn", tolua_get_turn); + tolua_function(tolua_S, "get_season", tolua_get_season); + + tolua_function(tolua_S, "equipment_setitem", tolua_equipment_setitem); + tolua_function(tolua_S, "equip_unit", tolua_lua_equipunit); + + tolua_function(tolua_S, "atoi36", tolua_atoi36); + tolua_function(tolua_S, "itoa36", tolua_itoa36); + tolua_function(tolua_S, "dice_roll", tolua_dice_rand); + + tolua_function(tolua_S, "get_nmrs", tolua_get_nmrs); + tolua_function(tolua_S, "remove_empty_units", tolua_remove_empty_units); + + tolua_function(tolua_S, "update_subscriptions", tolua_update_subscriptions); + tolua_function(tolua_S, "update_scores", tolua_update_scores); + + tolua_function(tolua_S, "learn_skill", tolua_learn_skill); } tolua_endmodule(tolua_S); return 1; diff --git a/src/eressea/tolua/message.xml b/src/eressea/tolua/message.xml new file mode 100644 index 000000000..1dcf75484 --- /dev/null +++ b/src/eressea/tolua/message.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/scripts/eressea/embassy.lua b/src/scripts/eressea/embassy.lua index 86e0af466..8648d600e 100644 --- a/src/scripts/eressea/embassy.lua +++ b/src/scripts/eressea/embassy.lua @@ -4,7 +4,7 @@ function use_seashell(u, amount) local visit = u.faction.objects:get("embassy_muschel") if visit~=nil and u.region~= r then local turns = get_turn() - visit - local msg = message("msg_event") + local msg = message.create("msg_event") msg:set_string("string", u.name .. "(" .. itoa36(u.id) .. ") erzählt den Bewohnern von " .. u.region.name .. " von Muschelplateau, das die Partei " .. u.faction.name .. " vor " .. turns .. " Wochen besucht hat." ) msg:send_region(u.region) return 0 diff --git a/src/scripts/eressea/ents.lua b/src/scripts/eressea/ents.lua index c118705f9..60532442d 100644 --- a/src/scripts/eressea/ents.lua +++ b/src/scripts/eressea/ents.lua @@ -7,7 +7,7 @@ local function create_ents(r, number) u.name = "Wütende Ents" u:set_skill("perception", 2) - msg = message("entrise") + msg = message.create("entrise") msg:set_region("region", r) msg:send_region(r) return u diff --git a/src/scripts/eressea/xmas2005.lua b/src/scripts/eressea/xmas2005.lua index f64e4e8d0..cde00f65b 100644 --- a/src/scripts/eressea/xmas2005.lua +++ b/src/scripts/eressea/xmas2005.lua @@ -1,5 +1,5 @@ function usepotion_message(u, potion) - msg = message("usepotion") + msg = message.create("usepotion") msg:set_unit("unit", u) msg:set_resource("potion", potion) return msg diff --git a/src/scripts/eressea/xmas2006.lua b/src/scripts/eressea/xmas2006.lua index 3eb665f3c..fa3ec251b 100644 --- a/src/scripts/eressea/xmas2006.lua +++ b/src/scripts/eressea/xmas2006.lua @@ -1,7 +1,7 @@ function use_xmastree(u, amount) u.region:set_key("xm06", true) u:use_pooled("xmastree", amount) - local msg = message("usepotion") + local msg = message.create("usepotion") msg:set_unit("unit", u) msg:set_resource("potion", "xmastree") msg:send_region(u.region) @@ -13,7 +13,7 @@ function update_xmas2006() local season = get_season(turn) if season == "calendar::winter" then print("it is " .. season .. ", the christmas trees do their magic") - local msg = message("xmastree_effect") + local msg = message.create("xmastree_effect") for r in regions() do if r:get_key("xm06") then trees = r:get_resource("tree") diff --git a/src/scripts/spells.lua b/src/scripts/spells.lua index 230c78f65..e6db19a75 100644 --- a/src/scripts/spells.lua +++ b/src/scripts/spells.lua @@ -1,5 +1,5 @@ function creation_message(mage, type) - msg = message("item_create_spell") + msg = message.create("item_create_spell") msg:set_unit("mage", mage) msg:set_int("number", 1) msg:set_resource("item", type) @@ -100,7 +100,7 @@ function earn_silver(r, mage, level, force) r:set_resource("money", money - amount) mage:add_item("money", amount) - local msg = message("income") + local msg = message.create("income") msg:set_unit("unit", mage) msg:set_region("region", r) msg:set_int("mode", 6) diff --git a/src/scripts/tests.lua b/src/scripts/tests.lua new file mode 100644 index 000000000..6fbfeeaeb --- /dev/null +++ b/src/scripts/tests.lua @@ -0,0 +1,84 @@ +local function test_read_write() + free_game() + local r = region.create(0, 0, "plain") + local f = faction.create("enno@eressea.de", "human", "de") + local u = unit.create(f, r) + u.number = 2 + local fno = f.id + local uno = u.id + local result = 0 + assert(r.terrain=="plain") + result = write_game("test_read_write.dat", "binary") + assert(result==0) + assert(get_region(0, 0)~=nil) + assert(get_faction(fno)~=nil) + assert(get_unit(uno)~=nil) + r = nil + f = nil + u = nil + free_game() + assert(get_region(0, 0)==nil) + assert(get_faction(fno)==nil) + assert(get_unit(uno)==nil) + result = read_game("test_read_write.dat", "binary") + assert(result==0) + assert(get_region(0, 0)~=nil) + assert(get_faction(fno)~=nil) + assert(get_unit(uno)~=nil) + free_game() +end + +function test_unit() + free_game() + local r = region.create(0, 0, "plain") + local f = faction.create("enno@eressea.de", "human", "de") + local u = unit.create(f, r) + u.number = 20 + u.name = "Enno" + assert(u.name=="Enno") + u:add_item("sword", 4) + assert(u:get_item("sword")==4) + assert(u:get_pooled("sword")==4) + u:use_pooled("sword", 2) + assert(u:get_item("sword")==2) +end + +function test_region() + free_game() + local r = region.create(0, 0, "plain") + r:set_resource("horse", 42) + r:set_resource("money", 45) + r:set_resource("peasant", 200) + assert(r:get_resource("horse") == 42) + assert(r:get_resource("money") == 45) + assert(r:get_resource("peasant") == 200) +end + +function loadscript(name) + local script = scriptpath .. "/" .. name + print("- loading " .. script) + if pcall(dofile, script)==0 then + print("Could not load " .. script) + end +end + +function test_message() + free_game() + local r = region.create(0, 0, "plain") + local f = faction.create("enno@eressea.de", "human", "de") + local u = unit.create(f, r) + local msg = message.create("item_create_spell") + msg:set_unit("mage", u) + msg:set_int("number", 1) + msg:set_resource("item", "sword") + msg:send_region(r) + msg:send_faction(f) + + return msg +end + +loadscript("extensions.lua") +test_read_write() +test_region() +test_unit() +test_message() diff --git a/src/scripts/wdw/sphinx.lua b/src/scripts/wdw/sphinx.lua index fcaede652..87cd450f5 100644 --- a/src/scripts/wdw/sphinx.lua +++ b/src/scripts/wdw/sphinx.lua @@ -88,7 +88,7 @@ function sphinx_handler() if table.getn(tokens) == 2 and string.lower(tokens[1]) == "antwort" then if string.lower(tokens[2]) == "999999" then -- Botschaft in alle Regionen - local m = message("msg_event") + local m = message.create("msg_event") m:set_string("string", "Das Rätsel der Sphinx ist gelöst! Die Sphinx wird sich eine neue Heimat und ein neues Rätsel suchen.") for r in regions() do m:send_region(r) diff --git a/src/tools/codegen/codegen.cpp b/src/tools/codegen/codegen.cpp new file mode 100644 index 000000000..2552358ad --- /dev/null +++ b/src/tools/codegen/codegen.cpp @@ -0,0 +1,114 @@ +/* libxml includes */ +#include +#include + +/* libc includes */ +#include + +const char * tmp_includes = +"#include \n" +"#include \n" +; +void +read_templates() +{ +} + +xmlDocPtr +readfile(const char * filename) +{ + xmlDocPtr doc; +#ifdef XML_PARSE_XINCLUDE + doc = xmlReadFile(filename, NULL, XML_PARSE_XINCLUDE); +#else + doc = xmlParseFile(filename); +#endif + return doc; +} + +void +parse_module(xmlXPathContextPtr xpath, FILE * out) +{ + xmlChar * name = xmlGetProp(xpath->node, BAD_CAST "name"); + xmlXPathObjectPtr result = xmlXPathEvalExpression(BAD_CAST "module", xpath); + xmlNodePtr node; + + xmlXPathFreeObject(result); + if (name) { + fprintf(out, " tolua_module(tolua_S, \"%s\", 0);\n", name); + fprintf(out, " tolua_beginmodule(tolua_S, \"%s\");\n", name); + xmlFree(name); + } else { + fputs(" tolua_module(tolua_S, 0, 0);\n", out); + fputs(" tolua_beginmodule(tolua_S, 0);\n", out); + } + + for (node=xpath->node->children;node;node=node->next) { + if (strcmp((const char *)node->name, "class")==0) { + xmlChar * lname = xmlGetProp(node, BAD_CAST "name"); + xmlChar * name = xmlGetProp(node, BAD_CAST "ctype"); + xmlChar * base = xmlGetProp(node, BAD_CAST "base"); + const char * col = "NULL"; + fprintf(out, " tolua_cclass(tolua_S, \"%s\", \"%s\", \"%s\", %s);\n", + lname, name, base, col); + xmlFree(lname); + xmlFree(name); + xmlFree(base); + } else if (strcmp((const char *)node->name, "module")==0) { + xpath->node = node; + parse_module(xpath, out); + xpath->node = node->parent; + } + } + fputs(" tolua_endmodule(tolua_S);\n", out); +} + +int +writefile(xmlDocPtr doc, FILE * out) +{ + xmlXPathContextPtr xpath = xmlXPathNewContext(doc); + xmlXPathObjectPtr result = xmlXPathEvalExpression(BAD_CAST "/package", xpath); + xmlChar * pkg_name = xmlGetProp(doc->children, BAD_CAST "name"); + + fputs(tmp_includes, out); + fputc('\n', out); + fprintf(out, "int tolua_%s_open(struct lua_State * L) {\n", pkg_name); + xmlFree(pkg_name); + + fputs(" tolua_open(L);\n", out); + + result = xmlXPathEvalExpression(BAD_CAST "/package/type", xpath); + if (result->nodesetval!=NULL) { + int i; + xmlNodeSetPtr nodes = result->nodesetval; + for (i=0;i!=nodes->nodeNr;++i) { + xmlChar * name = xmlGetProp(nodes->nodeTab[i], BAD_CAST "name"); + fprintf(out, " tolua_usertype(tolua_S, \"%s\");\n", name); + } + } + xmlXPathFreeObject(result); + + xpath->node = doc->children; + parse_module(xpath, out); + + fputs("}\n", out); + + xmlXPathFreeContext(xpath); + + return 0; +} + +int +main(int argc, char* argv[]) +{ + xmlDocPtr doc; + if (argc>1) { + FILE * out = stdout; + read_templates(); + doc = readfile(argv[1]); + if (doc) { + return writefile(doc, stdout); + } + } + return 1; +} diff --git a/src/tools/codegen/codegen.vcproj b/src/tools/codegen/codegen.vcproj new file mode 100644 index 000000000..0fdf5fe54 --- /dev/null +++ b/src/tools/codegen/codegen.vcproj @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +