diff --git a/src/eressea/Jamfile b/src/eressea/Jamfile index 465ce028b..fb8713f11 100644 --- a/src/eressea/Jamfile +++ b/src/eressea/Jamfile @@ -21,7 +21,8 @@ SERVER = eressea ; GMTOOL = gmtool ; SERVER_SOURCES = main.c korrektur.c ; -LUASERVER_SOURCES = + +SHARED_BINDINGS = alliance.cpp building.cpp eressea.cpp @@ -30,17 +31,23 @@ LUASERVER_SOURCES = message.cpp objects.cpp region.cpp - script.cpp ship.cpp spell.cpp unit.cpp item.cpp +; + +LUASERVER_SOURCES = + $(SHARED_BINDINGS) + script.cpp + gamecode.cpp server.cpp korrektur.c console.c ; GMTOOL_SOURCES = + $(SHARED_BINDINGS) listbox.c console.c editing.c diff --git a/src/eressea/eressea-lua.vcproj b/src/eressea/eressea-lua.vcproj index 674170901..b4fbaafb0 100644 --- a/src/eressea/eressea-lua.vcproj +++ b/src/eressea/eressea-lua.vcproj @@ -427,6 +427,9 @@ DisableLanguageExtensions="FALSE"/> + + diff --git a/src/eressea/gmmain.cpp b/src/eressea/gmmain.cpp index 3d38549dd..3dbc1e8a9 100644 --- a/src/eressea/gmmain.cpp +++ b/src/eressea/gmmain.cpp @@ -17,7 +17,6 @@ /* lua includes */ #include "lua/bindings.h" -#include "lua/script.h" #include #include #include @@ -31,11 +30,13 @@ lua_init(void) luaopen_string(L); luaopen_io(L); luaopen_table(L); -#if 0 + luabind::open(L); bind_objects(L); bind_eressea(L); - bind_script(L); + // bind_script(L); + // bind_message(L); + // bind_event(L); bind_spell(L); bind_alliance(L); bind_region(L); @@ -44,9 +45,7 @@ lua_init(void) bind_unit(L); bind_ship(L); bind_building(L); - bind_event(L); - bind_message(L); -#endif + lua_readline = curses_readline; return L; } diff --git a/src/eressea/gmtool.vcproj b/src/eressea/gmtool.vcproj index 097246e2f..6000af092 100644 --- a/src/eressea/gmtool.vcproj +++ b/src/eressea/gmtool.vcproj @@ -107,7 +107,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/eressea/lua/bindings.h b/src/eressea/lua/bindings.h index 6257cbab4..18102b057 100644 --- a/src/eressea/lua/bindings.h +++ b/src/eressea/lua/bindings.h @@ -12,7 +12,10 @@ extern void bind_spell(struct lua_State * L) ; extern void bind_item(struct lua_State * L); extern void bind_event(struct lua_State * L); extern void bind_message(struct lua_State * L); -extern void bind_script(struct lua_State * L); extern void bind_objects(struct lua_State * L); +extern void bind_script(struct lua_State * L); +extern void bind_gamecode(struct lua_State * L); + +extern bool is_function(struct lua_State * L, const char * fname); #endif diff --git a/src/eressea/lua/building.cpp b/src/eressea/lua/building.cpp index 30e74ee9a..497a08777 100644 --- a/src/eressea/lua/building.cpp +++ b/src/eressea/lua/building.cpp @@ -3,7 +3,7 @@ #include #include "list.h" #include "objects.h" -#include "script.h" +#include "bindings.h" // kernel includes #include diff --git a/src/eressea/lua/eressea.cpp b/src/eressea/lua/eressea.cpp index 441eb2ff0..16123327b 100644 --- a/src/eressea/lua/eressea.cpp +++ b/src/eressea/lua/eressea.cpp @@ -1,18 +1,12 @@ #include #include -#include "script.h" -#include "../korrektur.h" +#include "bindings.h" #include #include #include -// gamecode includes -#include -#include -#include - // kernel includes #include #include @@ -57,50 +51,6 @@ get_turn(void) return turn; } -static int -read_game(const char * filename) -{ - int rv = readgame(filename, false); - printf(" - Korrekturen Runde %d\n", turn); - korrektur(); - return rv; -} - -static int -write_game(const char *filename) -{ - free_units(); - remove_empty_factions(true); - - return writegame(filename, 0); -} - -static summary * sum_begin = 0; - -static int -init_summary() -{ - sum_begin = make_summary(); - return 0; -} - -static int -write_summary() -{ - assert(sum_begin - || !"init_summary must be called before before write_summary"); - if (sum_begin) { - summary * sum_end = make_summary(); - report_summary(sum_end, sum_begin, false); - report_summary(sum_end, sum_begin, true); - return 0; - } - return -1; -} - - -extern int process_orders(void); - static int find_plane_id(const char * name) { @@ -148,31 +98,6 @@ lua_getstring(const char * lname, const char * key) return locale_getstring(lang, key); } -static void -lua_planmonsters(void) -{ - unit * u; - faction * f = findfaction(MONSTER_FACTION); - - if (f==NULL) return; - if (turn == 0) rng_init((int)time(0)); - else rng_init(turn); - plan_monsters(); - for (u=f->units;u;u=u->nextF) { - call_script(u); - } -} - -static void -race_setscript(const char * rcname, const luabind::object& f) -{ - race * rc = rc_find(rcname); - if (rc!=NULL) { - luabind::object * fptr = new luabind::object(f); - setscript(&rc->attribs, fptr); - } -} - #define ISLANDSIZE 20 #define TURNS_PER_ISLAND 4 static void @@ -216,13 +141,6 @@ lua_writereport(faction * f) return write_reports(f, ltime); } -int -lua_writereports(void) -{ - init_reports(); - return reports(); -} - static void lua_equipunit(unit& u, const char * eqname) { @@ -272,42 +190,53 @@ lua_learnskill(unit& u, const char * skname, float chances) } } +bool +is_function(struct lua_State * luaState, const char * fname) +{ +#if LUABIND_BETA>7 || (LUABIND_BETA==7 && LUABIND_DEVEL>=2) + object g = globals(luaState); + object fun = g[fname]; + if (fun.is_valid()) { + if (type(fun)==LUA_TFUNCTION) { + return true; + } + log_warning(("Lua global object %s is not a function, type is %u\n", fname, type(fun))); + if (type(fun)!=LUA_TNIL) { + log_warning(("Lua global object %s is not a function, type is %u\n", fname, type(fun))); + } + } +#else + object g = get_globals(luaState); + object fun = g[fname]; + if (fun.is_valid()) { + if (fun.type()==LUA_TFUNCTION) { + return true; + } + if (fun.type()!=LUA_TNIL) { + log_warning(("Lua global object %s is not a function, type is %u\n", fname, fun.type())); + } + } +#endif + return false; +} + void bind_eressea(lua_State * L) { module(L)[ def("atoi36", &atoi36), def("itoa36", &itoa36), - def("read_game", &read_game), - def("write_map", &crwritemap), - def("write_game", &write_game), - def("write_passwords", &writepasswd), - def("init_reports", &init_reports), def("dice_roll", &dice_rand), - def("write_reports", &lua_writereports), - def("write_report", &lua_writereport), - def("init_summary", &init_summary), - def("write_summary", &write_summary), - def("read_orders", &readorders), - def("process_orders", &process_orders), def("equipment_setitem", &lua_addequipment), def("get_turn", &get_turn), def("remove_empty_units", &remove_empty_units), def("update_subscriptions", &update_subscriptions), - def("update_guards", &update_guards), def("update_scores", &score), def("equip_unit", &lua_equipunit), def("learn_skill", &lua_learnskill), - /* scripted monsters */ - def("plan_monsters", &lua_planmonsters), - def("set_brain", &race_setscript), - def("spawn_braineaters", &spawn_braineaters), - def("spawn_undead", &spawn_undead), - def("spawn_dragons", &spawn_dragons), - /* map making */ def("autoseed", lua_autoseed), diff --git a/src/eressea/lua/gamecode.cpp b/src/eressea/lua/gamecode.cpp new file mode 100644 index 000000000..cd0ccb469 --- /dev/null +++ b/src/eressea/lua/gamecode.cpp @@ -0,0 +1,278 @@ +#include +#include + +#include "script.h" +#include "../korrektur.h" + +#include +#include +#include + +// gamecode includes +#include +#include +#include + +// kernel includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// lua includes +#include +#include +#include + +// util includes +#include +#include +#include +#include + +#include +#include + +using namespace luabind; + +static void +lua_planmonsters(void) +{ + unit * u; + faction * f = findfaction(MONSTER_FACTION); + + if (f==NULL) return; + if (turn == 0) rng_init((int)time(0)); + else rng_init(turn); + plan_monsters(); + for (u=f->units;u;u=u->nextF) { + call_script(u); + } +} + +#define ISLANDSIZE 20 +#define TURNS_PER_ISLAND 4 +static void +lua_autoseed(const char * filename, bool new_island) +{ + newfaction * players = read_newfactions(filename); + if (players!=NULL) { + rng_init(players->subscription); + while (players) { + int n = listlen(players); + int k = (n+ISLANDSIZE-1)/ISLANDSIZE; + k = n / k; + n = autoseed(&players, k, new_island || (turn % TURNS_PER_ISLAND)==0); + if (n==0) { + break; + } + } + } +} + +#ifdef LUABIND_NO_EXCEPTIONS +static void +error_callback(lua_State * L) +{ +} +#endif + +static int +get_direction(const char * name) +{ + for (int i=0;i!=MAXDIRECTIONS;++i) { + if (strcasecmp(directions[i], name)==0) return i; + } + return NODIRECTION; +} + +static int +lua_writereport(faction * f) +{ + time_t ltime = time(0); + return write_reports(f, ltime); +} + +static int +lua_writereports(void) +{ + init_reports(); + return reports(); +} + +static void +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) +{ + skill_t sk = sk_find(skname); + if (sk!=NOSKILL) { + learn_skill(&u, sk, chances); + } +} + +static int +read_game(const char * filename) +{ + int rv = readgame(filename, false); + printf(" - Korrekturen Runde %d\n", turn); + korrektur(); + return rv; +} + +static int +write_game(const char *filename) +{ + free_units(); + remove_empty_factions(true); + + return writegame(filename, 0); +} + +static summary * sum_begin = 0; + +static int +init_summary() +{ + sum_begin = make_summary(); + return 0; +} + +static int +write_summary() +{ + assert(sum_begin + || !"init_summary must be called before before write_summary"); + if (sum_begin) { + summary * sum_end = make_summary(); + report_summary(sum_end, sum_begin, false); + report_summary(sum_end, sum_begin, true); + return 0; + } + return -1; +} + +#ifdef SHORTPWDS +static void +readshortpwds() +{ + FILE * F; + char zText[MAX_PATH]; + sprintf(zText, "%s/%s.%u", basepath(), "shortpwds", turn); + + F = fopen(zText, "r"); + if (F==NULL) { + log_error(("could not open password file %s", zText)); + } else { + while (!feof(F)) { + faction * f; + char passwd[16], faction[5], email[64]; + fscanf(F, "%s %s %s\n", faction, passwd, email); + f = findfaction(atoi36(faction)); + if (f!=NULL) { + shortpwd * pwd = (shortpwd*)malloc(sizeof(shortpwd)); + if (set_email(&pwd->email, email)!=0) { + log_error(("Invalid email address: %s\n", email)); + } + pwd->pwd = strdup(passwd); + pwd->used = false; + pwd->next = f->shortpwds; + f->shortpwds = pwd; + } + } + fclose(F); + } +} +#endif + +static int +process_orders(void) +{ + if (turn == 0) rng_init((int)time(0)); + else rng_init(turn); + +#ifdef SHORTPWDS + readshortpwds("passwords"); +#endif + turn++; + processorders(); + + return 0; +} + + +void +bind_gamecode(lua_State * L) +{ + module(L)[ + def("read_game", &read_game), + def("write_game", &write_game), + + def("init_summary", &init_summary), + def("write_summary", &write_summary), + + def("read_orders", &readorders), + def("process_orders", &process_orders), + + def("write_map", &crwritemap), + def("write_passwords", &writepasswd), + def("init_reports", &init_reports), + def("write_reports", &lua_writereports), + def("write_report", &lua_writereport), + def("update_guards", &update_guards), + + /* scripted monsters */ + def("spawn_braineaters", &spawn_braineaters), + def("spawn_undead", &spawn_undead), + def("spawn_dragons", &spawn_dragons), + def("plan_monsters", &lua_planmonsters) + ]; +#ifdef LUABIND_NO_EXCEPTIONS + luabind::set_error_callback(error_callback); +#endif +} diff --git a/src/eressea/lua/item.cpp b/src/eressea/lua/item.cpp index 13ab01648..e622d4c90 100644 --- a/src/eressea/lua/item.cpp +++ b/src/eressea/lua/item.cpp @@ -1,7 +1,7 @@ #include #include -#include "script.h" +#include "bindings.h" // kernel includes #include diff --git a/src/eressea/lua/script.cpp b/src/eressea/lua/script.cpp index eba962be2..cd487b6f1 100644 --- a/src/eressea/lua/script.cpp +++ b/src/eressea/lua/script.cpp @@ -1,10 +1,10 @@ /* vi: set ts=2: - +-------------------+ + +-------------------+ | | Christian Schlittchen | Eressea PBEM host | Enno Rehling | (c) 1998 - 2004 | Katja Zedel | | - +-------------------+ + +-------------------+ This program may not be used, modified or distributed without prior permission by the authors of Eressea. @@ -15,6 +15,7 @@ #include #include "eressea.h" #include "script.h" +#include "bindings.h" // kernel includes #include @@ -37,7 +38,7 @@ using namespace luabind; -static void +static void free_script(attrib * a) { if (a->data.v!=NULL) { object * f = (object *)a->data.v; @@ -46,19 +47,19 @@ free_script(attrib * a) { } attrib_type at_script = { - "script", - NULL, free_script, NULL, - NULL, NULL, ATF_UNIQUE + "script", + NULL, free_script, NULL, + NULL, NULL, ATF_UNIQUE }; -int +int call_script(struct unit * u) { const attrib * a = a_findc(u->attribs, &at_script); if (a==NULL) a = a_findc(u->race->attribs, &at_script); if (a!=NULL && a->data.v!=NULL) { object * func = (object *)a->data.v; - try { + try { func->operator()(u); } catch (error& e) { @@ -72,7 +73,7 @@ call_script(struct unit * u) return -1; } -void +void setscript(struct attrib ** ap, void * fptr) { attrib * a = a_find(*ap, &at_script); @@ -86,7 +87,7 @@ setscript(struct attrib ** ap, void * fptr) } /** callback to use lua for spell functions */ -static int +static int lua_callspell(castorder *co) { const char * fname = co->sp->sname; @@ -196,36 +197,6 @@ lua_changeresource(unit * u, const struct resource_type * rtype, int delta) return retval; } -bool -is_function(struct lua_State * luaState, const char * fname) -{ -#if LUABIND_BETA>7 || (LUABIND_BETA==7 && LUABIND_DEVEL>=2) - object g = globals(luaState); - object fun = g[fname]; - if (fun.is_valid()) { - if (type(fun)==LUA_TFUNCTION) { - return true; - } - log_warning(("Lua global object %s is not a function, type is %u\n", fname, type(fun))); - if (type(fun)!=LUA_TNIL) { - log_warning(("Lua global object %s is not a function, type is %u\n", fname, type(fun))); - } - } -#else - object g = get_globals(luaState); - object fun = g[fname]; - if (fun.is_valid()) { - if (fun.type()==LUA_TFUNCTION) { - return true; - } - if (fun.type()!=LUA_TNIL) { - log_warning(("Lua global object %s is not a function, type is %u\n", fname, fun.type())); - } - } -#endif - return false; -} - static int lua_getresource(unit * u, const struct resource_type * rtype) { @@ -315,8 +286,25 @@ overload(const char * name, const object& f) } } +static void +unit_setscript(struct unit& u, const luabind::object& f) +{ + luabind::object * fptr = new luabind::object(f); + setscript(&u.attribs, fptr); +} + +static void +race_setscript(const char * rcname, const luabind::object& f) +{ + race * rc = rc_find(rcname); + if (rc!=NULL) { + luabind::object * fptr = new luabind::object(f); + setscript(&rc->attribs, fptr); + } +} + void -bind_script(lua_State * L) +bind_script(lua_State * L) { register_function((pf_generic)&lua_callspell, "lua_castspell"); register_function((pf_generic)&lua_initfamiliar, "lua_initfamiliar"); @@ -325,7 +313,9 @@ bind_script(lua_State * L) register_function((pf_generic)&lua_changeresource, "lua_changeresource"); module(L)[ - def("overload", &overload) + def("overload", &overload), + def("set_race_brain", &race_setscript), + def("set_unit_brain", &unit_setscript) ]; } diff --git a/src/eressea/lua/script.h b/src/eressea/lua/script.h index 6f30f465c..689eb67e9 100644 --- a/src/eressea/lua/script.h +++ b/src/eressea/lua/script.h @@ -15,7 +15,6 @@ extern int call_script(struct unit * u); extern void setscript(struct attrib ** ap, void * fptr); -extern bool is_function(struct lua_State * luaState, const char * fname); extern void reset_scripts(); #endif diff --git a/src/eressea/lua/unit.cpp b/src/eressea/lua/unit.cpp index be23b748f..5e004a462 100644 --- a/src/eressea/lua/unit.cpp +++ b/src/eressea/lua/unit.cpp @@ -2,7 +2,7 @@ #include #include "list.h" #include "objects.h" -#include "script.h" +#include "bindings.h" #include "event.h" // Atributes includes @@ -435,13 +435,6 @@ unit_clearorders(unit& u) free_orders(&u.orders); } -static void -unit_setscript(struct unit& u, const luabind::object& f) -{ - luabind::object * fptr = new luabind::object(f); - setscript(&u.attribs, fptr); -} - static int unit_weight(const struct unit& u) { @@ -568,8 +561,6 @@ bind_unit(lua_State * L) // npc logic: .def("add_handler", &unit_addhandler) - .def("set_brain", &unit_setscript) - .def("set_racename", &unit_setracename) .def("add_spell", &unit_addspell) diff --git a/src/eressea/server.cpp b/src/eressea/server.cpp index 6e8da46cb..5596777f2 100644 --- a/src/eressea/server.cpp +++ b/src/eressea/server.cpp @@ -253,39 +253,6 @@ game_init(void) #endif } -#ifdef SHORTPWDS -static void -readshortpwds() -{ - FILE * F; - char zText[MAX_PATH]; - sprintf(zText, "%s/%s.%u", basepath(), "shortpwds", turn); - - F = fopen(zText, "r"); - if (F==NULL) { - log_error(("could not open password file %s", zText)); - } else { - while (!feof(F)) { - faction * f; - char passwd[16], faction[5], email[64]; - fscanf(F, "%s %s %s\n", faction, passwd, email); - f = findfaction(atoi36(faction)); - if (f!=NULL) { - shortpwd * pwd = (shortpwd*)malloc(sizeof(shortpwd)); - if (set_email(&pwd->email, email)!=0) { - log_error(("Invalid email address: %s\n", email)); - } - pwd->pwd = strdup(passwd); - pwd->used = false; - pwd->next = f->shortpwds; - f->shortpwds = pwd; - } - } - fclose(F); - } -} -#endif - static lua_State * lua_init(void) { @@ -319,21 +286,6 @@ lua_done(lua_State * luaState) lua_close(luaState); } -int -process_orders() -{ - if (turn == 0) rng_init((int)time(0)); - else rng_init(turn); - -#ifdef SHORTPWDS - readshortpwds("passwords"); -#endif - turn++; - processorders(); - - return 0; -} - #ifndef CLEANUP_CODE # define CLEANUP_CODE #endif diff --git a/src/scripts/eressea/ponnuki.lua b/src/scripts/eressea/ponnuki.lua index 7b4faa494..95d121cc5 100644 --- a/src/scripts/eressea/ponnuki.lua +++ b/src/scripts/eressea/ponnuki.lua @@ -29,7 +29,7 @@ local function init_ponnuki(home) u:set_racename("Ritter von Go") end if u.faction==f then - u:set_brain(ponnuki_brain) + set_unit_brain(u, ponnuki_brain) end end diff --git a/src/scripts/samples.lua b/src/scripts/samples.lua index e48569536..00e4e4a63 100644 --- a/src/scripts/samples.lua +++ b/src/scripts/samples.lua @@ -332,7 +332,7 @@ function test_monsters() end end - set_brain("braineater", move_north) + set_race_brain("braineater", move_north) plan_monsters() end