diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index 6b94bea4c..936e78756 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -1838,17 +1838,17 @@ deliverMail(faction * f, region * r, unit * u, const char *s, unit * receiver) static void mailunit(region * r, unit * u, int n, struct order * ord, const char * s) { - unit *u2; /* nur noch an eine Unit möglich */ - - u2=findunitr(r,n); + unit * u2 = findunitr(r,n); if (u2 && cansee(u->faction, r, u2, 0)) { deliverMail(u2->faction, r, u, s, u2); + handle_event_va(&u2->attribs, "message", "string unit", s, u); + } + else { + /* Immer eine Meldung - sonst könnte man so getarnte EHs enttarnen: + * keine Meldung -> EH hier. */ + cmistake(u, ord, 63, MSG_MESSAGE); } - else - cmistake(u, ord, 63, MSG_MESSAGE); - /* Immer eine Meldung - sonst könnte man so getarnte EHs enttarnen: - * keine Meldung -> EH hier. */ } static void @@ -1927,14 +1927,14 @@ mail_cmd(unit * u, struct order * ord) boolean see = false; n = getid(); - for(u2=r->units; u2; u2=u2->next) { - if(u2->no == n && cansee(u->faction, r, u2, 0)) { + for (u2=r->units; u2; u2=u2->next) { + if (u2->no == n && cansee(u->faction, r, u2, 0)) { see = true; break; } } - if(see == false) { + if (see == false) { cmistake(u, ord, 63, MSG_MESSAGE); break; } diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index dc55b4ede..0c26ffae3 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -3357,6 +3357,9 @@ freadstr(FILE * F, char * start, size_t size) } } +/** writes a quoted string to the file + * no trailing space, since this is used to make the creport. + */ int fwritestr(FILE * F, const char * str) { diff --git a/src/common/util/event.c b/src/common/util/event.c index b1761ae5a..f475b1b68 100644 --- a/src/common/util/event.c +++ b/src/common/util/event.c @@ -21,6 +21,7 @@ /* libc includes */ #include +#include #include #include @@ -200,7 +201,29 @@ add_trigger(struct attrib ** ap, const char * event, struct trigger * t) } void -handle_event(attrib ** attribs, const char * event, void * param) +handle_event_va(attrib ** attribs, const char * event, const char * format, ...) +{ + event_arg args[9]; + int argc = 0; + va_list marker; + char * toks = strdup(format); + char * tok = strtok(toks, " "); + + va_start(marker, format); + while (tok && argc!=8) { + args[argc].data = va_arg(marker, void *); + args[argc].type = tok; + ++argc; + tok = strtok(NULL, " "); + } + args[argc].type=NULL; + va_end(marker); + handle_event(attribs, event, args); + free (toks); +} + +void +handle_event(attrib ** attribs, const char * event, void * data) { while (*attribs) { if ((*attribs)->type==&at_eventhandler) break; @@ -213,7 +236,7 @@ handle_event(attrib ** attribs, const char * event, void * param) } if (*attribs) { handler_info * tl = (handler_info*)(*attribs)->data.v; - handle_triggers(&tl->triggers, param); + handle_triggers(&tl->triggers, data); } } diff --git a/src/common/util/event.h b/src/common/util/event.h index 1500fbda2..8e1a8bbe2 100644 --- a/src/common/util/event.h +++ b/src/common/util/event.h @@ -44,6 +44,11 @@ typedef struct trigger { variant data; } trigger; +typedef struct event_arg { + char * type; + void * data; +} event_arg; + extern trigger * t_new(trigger_type * ttype); extern void t_free(trigger * t); extern void t_add(trigger ** tlist, trigger * t); @@ -55,6 +60,7 @@ extern void remove_triggers(struct attrib ** ap, const char * event, const trigg extern struct trigger ** get_triggers(struct attrib * ap, const char * event); /* calls handle() for each of these. e.g. used in timeout */ extern void handle_event(struct attrib ** attribs, const char * event, void * data); +extern void handle_event_va(struct attrib ** attribs, const char * event, const char * format, ...); /* functions for making complex triggers: */ extern void free_triggers(trigger * triggers); /* release all these triggers */ diff --git a/src/eressea/Jamfile b/src/eressea/Jamfile index 6816bac73..877dc7a70 100644 --- a/src/eressea/Jamfile +++ b/src/eressea/Jamfile @@ -17,6 +17,7 @@ LUASERVER_SOURCES = alliance.cpp building.cpp eressea.cpp + event.cpp faction.cpp region.cpp script.cpp diff --git a/src/eressea/eressea-lua.vcproj b/src/eressea/eressea-lua.vcproj index b45bb33f9..ea19b28a8 100644 --- a/src/eressea/eressea-lua.vcproj +++ b/src/eressea/eressea-lua.vcproj @@ -251,6 +251,9 @@ + + +#include +#include "event.h" + +// util includes +#include +#include + +// lua includes +#include +#include + +using namespace luabind; + + +const char * +event::get_type(int i) const +{ + return args[i].type; +} + +struct unit * +event::get_unit(int i) const +{ + return (struct unit *)args[i].data; +} + +const char * +event::get_string(int i) const +{ + return (const char*)args[i].data; +} + +int +event::get_int(int i) const +{ + return (int)args[i].data; +} + +void +bind_event(lua_State * L) +{ + module(L)[ + class_("event") + .def("message", &event::get_message) + .def("get_type", &event::get_type) + .def("get_string", &event::get_string) + .def("get_unit", &event::get_unit) + .def("get_int", &event::get_int) + ]; +} diff --git a/src/eressea/lua/event.h b/src/eressea/lua/event.h new file mode 100644 index 000000000..929fd296e --- /dev/null +++ b/src/eressea/lua/event.h @@ -0,0 +1,15 @@ +class event { +public: + event(char * m, struct event_arg * a) : args(a), msg(m) {} + + const char * get_message(int i) const { return msg; } + const char * get_type(int i) const; + struct unit * get_unit(int i) const; + const char * get_string(int i) const; + int get_int(int i) const; + +private: + struct event_arg * args; + char * msg; +}; + diff --git a/src/eressea/lua/unit.cpp b/src/eressea/lua/unit.cpp index a972eac05..1965ed351 100644 --- a/src/eressea/lua/unit.cpp +++ b/src/eressea/lua/unit.cpp @@ -2,6 +2,7 @@ #include #include "list.h" #include "script.h" +#include "event.h" // Atributes includes #include @@ -22,6 +23,7 @@ // util includes #include +#include // lua includes #include @@ -405,6 +407,57 @@ unit_weight(const struct unit& u) return weight(&u); } +typedef struct fctr_data { + unit * target; + luabind::functor * fptr; +} fctr_data; + +static int +fctr_handle(trigger * t, void * data) +{ + event * evt = new event(NULL, (event_arg*)data); + fctr_data * fd = (fctr_data*)t->data.v; + fd->fptr->operator()(fd->target, evt); + delete evt; + return 0; +} + +static void +fctr_init(trigger * t) +{ + t->data.v = calloc(sizeof(fctr_data), 1); +} + +static void +fctr_done(trigger * t) +{ + free(t->data.v); +} + +static struct trigger_type tt_functor = { + "functor", + fctr_init, + fctr_done, + fctr_handle +}; + +static trigger * +trigger_functor(struct unit& u, const functor& f) +{ + luabind::functor * fptr = new luabind::functor(f); + trigger * t = t_new(&tt_functor); + fctr_data * td = (fctr_data*)t->data.v; + td->target = &u; + td->fptr = fptr; + return t; +} + +static void +unit_addhandler(struct unit& u, const char * event, const functor& f) +{ + add_trigger(&u.attribs, event, trigger_functor(u, f)); +} + static int unit_capacity(const struct unit& u) { @@ -449,6 +502,7 @@ bind_unit(lua_State * L) .def("eff_skill", &unit_effskill) .def("set_skill", &unit_setskill) + .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 6bd503e29..a4d83ee89 100644 --- a/src/eressea/server.cpp +++ b/src/eressea/server.cpp @@ -283,6 +283,7 @@ lua_init(void) bind_unit(luaState); bind_ship(luaState); bind_building(luaState); + bind_event(luaState); return luaState; } diff --git a/src/scripts/samples.lua b/src/scripts/samples.lua index 72197f4bd..b12f602d5 100644 --- a/src/scripts/samples.lua +++ b/src/scripts/samples.lua @@ -1,3 +1,41 @@ +function test_handler() + + local function msg_handler(u, evt) + str = evt:get_string(0) + u2 = evt:get_unit(1) + print(u) + print(u2) + print(str) + end + + plain = terraform(0, 0, "plain") + skill = 8 + + f = add_faction("enno@eressea.de", "orc", "de") + f.age = 20 + + u = add_unit(f, plain) + u.number = 1 + u:add_item("money", u.number*100) + u:clear_orders() + u:add_order("NUMMER PARTEI test") + u:add_handler("message", msg_handler) + msg = "BOTSCHAFT EINHEIT " .. itoa36(u.id) .. " Du~Elf~stinken" + + f = add_faction("enno@eressea.de", "elf", "de") + f.age = 20 + + u = add_unit(f, plain) + u.number = 1 + u:add_item("money", u.number*100) + u:clear_orders() + u:add_order("NUMMER PARTEI eviL") + u:add_order(msg) + + process_orders() + write_reports() +end + function test_combat() plain = terraform(0, 0, "plain") @@ -175,7 +213,8 @@ function test_parser() write_game("parser") end -test_parser() +test_handler() +-- test_parser() -- test_monsters() -- test_combat() -- test_rewards()