lua bindings:

- moved gamecode-related ones to a new object file
- added bindings to the gmtool
- fixed scripts that used set_brain()
This commit is contained in:
Enno Rehling 2006-04-16 14:18:09 +00:00
parent ec1f6c9963
commit 288961e38a
15 changed files with 410 additions and 217 deletions

View File

@ -21,7 +21,8 @@ SERVER = eressea ;
GMTOOL = gmtool ;
SERVER_SOURCES = main.c korrektur.c ;
LUASERVER_SOURCES =
SHARED_BINDINGS =
<lua>alliance.cpp
<lua>building.cpp
<lua>eressea.cpp
@ -30,17 +31,23 @@ LUASERVER_SOURCES =
<lua>message.cpp
<lua>objects.cpp
<lua>region.cpp
<lua>script.cpp
<lua>ship.cpp
<lua>spell.cpp
<lua>unit.cpp
<lua>item.cpp
;
LUASERVER_SOURCES =
$(SHARED_BINDINGS)
<lua>script.cpp
<lua>gamecode.cpp
server.cpp
korrektur.c
console.c
;
GMTOOL_SOURCES =
$(SHARED_BINDINGS)
<curses>listbox.c
console.c
editing.c

View File

@ -427,6 +427,9 @@
DisableLanguageExtensions="FALSE"/>
</FileConfiguration>
</File>
<File
RelativePath=".\lua\gamecode.cpp">
</File>
<File
RelativePath=".\lua\item.cpp">
</File>

View File

@ -17,7 +17,6 @@
/* lua includes */
#include "lua/bindings.h"
#include "lua/script.h"
#include <boost/version.hpp>
#include <lua.hpp>
#include <luabind/luabind.hpp>
@ -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;
}

View File

@ -107,7 +107,7 @@
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="lua50.lib curses.lib libxml2.lib"
AdditionalDependencies="luabind.lib lua50.lib curses.lib libxml2.lib"
OutputFile=".\Debug/gmtool.exe"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
@ -222,6 +222,48 @@
RelativePath=".\curses\listbox.h">
</File>
</Filter>
<Filter
Name="bindings">
<File
RelativePath=".\lua\alliance.cpp">
</File>
<File
RelativePath=".\lua\bindings.h">
</File>
<File
RelativePath=".\lua\building.cpp">
</File>
<File
RelativePath=".\lua\eressea.cpp">
</File>
<File
RelativePath=".\lua\faction.cpp">
</File>
<File
RelativePath=".\lua\item.cpp">
</File>
<File
RelativePath=".\lua\list.h">
</File>
<File
RelativePath=".\lua\objects.cpp">
</File>
<File
RelativePath=".\lua\objects.h">
</File>
<File
RelativePath=".\lua\region.cpp">
</File>
<File
RelativePath=".\lua\ship.cpp">
</File>
<File
RelativePath=".\lua\spell.cpp">
</File>
<File
RelativePath=".\lua\unit.cpp">
</File>
</Filter>
<File
RelativePath=".\console.c">
</File>

View File

@ -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

View File

@ -3,7 +3,7 @@
#include <eressea.h>
#include "list.h"
#include "objects.h"
#include "script.h"
#include "bindings.h"
// kernel includes
#include <building.h>

View File

@ -1,18 +1,12 @@
#include <config.h>
#include <eressea.h>
#include "script.h"
#include "../korrektur.h"
#include "bindings.h"
#include <attributes/key.h>
#include <modules/autoseed.h>
#include <modules/score.h>
// gamecode includes
#include <gamecode/laws.h>
#include <gamecode/monster.h>
#include <gamecode/creport.h>
// kernel includes
#include <kernel/alliance.h>
#include <kernel/equipment.h>
@ -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),

View File

@ -0,0 +1,278 @@
#include <config.h>
#include <eressea.h>
#include "script.h"
#include "../korrektur.h"
#include <attributes/key.h>
#include <modules/autoseed.h>
#include <modules/score.h>
// gamecode includes
#include <gamecode/laws.h>
#include <gamecode/monster.h>
#include <gamecode/creport.h>
// kernel includes
#include <kernel/alliance.h>
#include <kernel/equipment.h>
#include <kernel/faction.h>
#include <kernel/item.h>
#include <kernel/plane.h>
#include <kernel/race.h>
#include <kernel/reports.h>
#include <kernel/save.h>
#include <kernel/skill.h>
#include <kernel/teleport.h>
#include <kernel/unit.h>
// lua includes
#include <lua.hpp>
#include <luabind/luabind.hpp>
#include <luabind/iterator_policy.hpp>
// util includes
#include <util/language.h>
#include <util/base36.h>
#include <util/rand.h>
#include <util/rng.h>
#include <cstring>
#include <ctime>
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
}

View File

@ -1,7 +1,7 @@
#include <config.h>
#include <eressea.h>
#include "script.h"
#include "bindings.h"
// kernel includes
#include <kernel/item.h>

View File

@ -1,10 +1,10 @@
/* vi: set ts=2:
+-------------------+
+-------------------+
| | Christian Schlittchen <corwin@amber.kn-bremen.de>
| Eressea PBEM host | Enno Rehling <enno@eressea-pbem.de>
| (c) 1998 - 2004 | Katja Zedel <katze@felidae.kn-bremen.de>
| |
+-------------------+
+-------------------+
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
@ -15,6 +15,7 @@
#include <lua.hpp>
#include "eressea.h"
#include "script.h"
#include "bindings.h"
// kernel includes
#include <kernel/equipment.h>
@ -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)
];
}

View File

@ -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

View File

@ -2,7 +2,7 @@
#include <eressea.h>
#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)

View File

@ -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

View File

@ -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

View File

@ -332,7 +332,7 @@ function test_monsters()
end
end
set_brain("braineater", move_north)
set_race_brain("braineater", move_north)
plan_monsters()
end