--- deliantra/server/plugins/cfperl/cfperl.xs 2006/03/21 02:08:02 1.39 +++ deliantra/server/plugins/cfperl/cfperl.xs 2006/03/31 19:47:55 1.43 @@ -79,6 +79,13 @@ static HV *obj_cache; static PerlInterpreter *perl; +#define PUSHcfapi(type,ctype) PUSHs (sv_2mortal (newSVcfapi ((type), va_arg (args, ctype)))) +#define PUSH_OB PUSHcfapi(CFAPI_POBJECT, object *) +#define PUSH_PL PUSHcfapi(CFAPI_PPLAYER, player *) +#define PUSH_MAP PUSHcfapi(CFAPI_PMAP, mapstruct *) +#define PUSH_PV PUSHcfapi(CFAPI_STRING, const char *) +#define PUSH_IV PUSHcfapi(CFAPI_INT, int) + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // garbage collect some perl objects, if possible @@ -298,6 +305,8 @@ PUSHMARK (SP); + EXTEND (SP, 10); + HV *hv = newHV (); #define hv_context(type,addr,expr) hv_store (hv, #expr, sizeof (#expr) - 1, newSVcfapi (type, addr context->expr), 0) hv_context (CFAPI_POBJECT, ,who); @@ -310,7 +319,7 @@ hv_context (CFAPI_STRING , ,options); hv_context (CFAPI_STRING , ,extension); - XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); + PUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); PUTBACK; int count = call_pv (func, G_SCALAR | G_EVAL); @@ -496,104 +505,109 @@ globalEventListener (int *type, ...) { va_list args; - static int rv = 0; - CFPContext context; - char *buf; - player *pl; - object *op; + static int rv; + int event_code; if (!perl) return; - memset (&context, 0, sizeof (context)); - va_start (args, type); - context.event_code = va_arg (args, int); + event_code = va_arg (args, int); - switch (context.event_code) + if (event_code == EVENT_FREE_OB) { - case EVENT_CRASH: - printf ("Unimplemented for now\n"); - break; + player *pl; + object *op; + SV *sv; - case EVENT_PLAYER_LOAD: - case EVENT_PLAYER_SAVE: - context.who = va_arg (args, object *); - buf = va_arg (args, char *); - if (buf != 0) - strncpy (context.message, buf, sizeof (context.message)); - break; + op = va_arg (args, object *); + sv = hv_delete (obj_cache, (char *)&op, sizeof (void *), 0); - case EVENT_MAPLOAD: - case EVENT_MAPOUT: - case EVENT_MAPIN: - case EVENT_MAPCLEAN: - context.map = va_arg (args, mapstruct *); - break; - - case EVENT_MAPENTER: - case EVENT_MAPLEAVE: - case EVENT_FREE_OB: - case EVENT_BORN: - case EVENT_REMOVE: - context.activator = va_arg (args, object *); - break; - - case EVENT_PLAYER_DEATH: - context.who = va_arg (args, object *); - break; + if (sv) + clearSVptr (sv); - case EVENT_GKILL: - context.who = va_arg (args, object *); - context.activator = va_arg (args, object *); - break; + rv = 0; + } + else + { + dSP; - case EVENT_LOGIN: - case EVENT_LOGOUT: - pl = va_arg (args, player *); - context.activator = pl->ob; - buf = va_arg (args, char *); - if (buf != 0) - strncpy (context.message, buf, sizeof (context.message)); - break; + ENTER; + SAVETMPS; - case EVENT_SHOUT: - case EVENT_MUZZLE: - case EVENT_KICK: - context.activator = va_arg (args, object *); - buf = va_arg (args, char *); - if (buf != 0) - strncpy (context.message, buf, sizeof (context.message)); - break; + PUSHMARK (SP); - case EVENT_CLOCK: - clean_obj_cache (); - break; + EXTEND (SP, 10); + PUSHs (sv_2mortal (newSViv (event_code))); - case EVENT_TELL: - break; + switch (event_code) + { + case EVENT_CRASH: + break; - case EVENT_MAPRESET: - /* stupid, should be the map itself, not "message"??? */ - buf = va_arg (args, char *); - if (buf != 0) - strncpy (context.message, buf, sizeof (context.message)); - break; - } + case EVENT_PLAYER_LOAD: + case EVENT_PLAYER_SAVE: + PUSH_OB; + PUSH_PV; + break; + + case EVENT_MAPLOAD: + case EVENT_MAPOUT: + case EVENT_MAPIN: + case EVENT_MAPCLEAN: + case EVENT_MAPRESET: + PUSH_MAP; + break; + + case EVENT_MAPENTER: + case EVENT_MAPLEAVE: + case EVENT_BORN: + case EVENT_REMOVE: + case EVENT_PLAYER_DEATH: + PUSH_OB; + break; + + case EVENT_GKILL: + PUSH_OB; + PUSH_OB; + break; + + case EVENT_LOGIN: + case EVENT_LOGOUT: + PUSH_PL; + PUSH_PV; + break; + + case EVENT_SHOUT: + case EVENT_MUZZLE: + case EVENT_KICK: + PUSH_OB; + PUSH_PV; + break; + + case EVENT_CLOCK: + clean_obj_cache (); + break; - va_end (args); + case EVENT_TELL: + break; + } - if (context.event_code == EVENT_FREE_OB) - { - SV *sv = hv_delete (obj_cache, (char *)&context.activator, sizeof (void *), 0); + va_end (args); - if (sv) - clearSVptr (sv); + PUTBACK; + int count = call_pv ("cf::inject_global_event", G_SCALAR | G_EVAL); + SPAGAIN; + + if (SvTRUE (ERRSV)) + LOG (llevError, "event '%d' callback evaluation error: %s", event_code, SvPV_nolen (ERRSV)); + + rv = count > 0 ? POPi : 0; + + PUTBACK; + FREETMPS; + LEAVE; } - else - inject_event ("cf::inject_global_event", &context); - - rv = context.returnvalue; return &rv; } @@ -605,6 +619,7 @@ va_list args; char *buf; CFPContext context; + object *eob; if (!perl) return; @@ -625,6 +640,7 @@ context.fix = va_arg (args, int); strncpy (context.extension, va_arg (args, char *), sizeof (context.extension)); strncpy (context.options, va_arg (args, char *), sizeof (context.options)); + eob = va_arg (args, object *); context.returnvalue = 0; va_end (args); @@ -1495,6 +1511,10 @@ RETVAL = (object *)object_insert (&unused_type, ob, 0, where, orig, flag, x, y); } +const char *get_ob_key_value (object *op, const char *key) + +bool set_ob_key_value (object *op, const char *key, const char *value = 0, int add_key = 1) + object *get_nearest_player (object *ob) ALIAS: nearest_player = 0 PREINIT: @@ -1616,6 +1636,16 @@ XPUSHs (newSVcfapi (CFAPI_PPLAYER, pl)); } +bool +peaceful (player *pl, bool new_setting = 0) + PROTOTYPE: $;$ + CODE: + RETVAL = pl->peaceful; + if (items > 1) + pl->peaceful = new_setting; + OUTPUT: + RETVAL + living * orig_stats (player *pl) CODE: