--- deliantra/server/plugins/cfperl/cfperl.xs 2006/02/08 05:22:41 1.17 +++ deliantra/server/plugins/cfperl/cfperl.xs 2006/03/06 22:59:26 1.28 @@ -31,7 +31,7 @@ #undef save_long // clashes with libproto.h #define PLUGIN_NAME "perl" -#define PLUGIN_VERSION "cfperl 0.0" +#define PLUGIN_VERSION "cfperl 0.2" #ifndef __CEXTRACT__ #include @@ -49,28 +49,32 @@ #include "perlxsi.c" +typedef object object_ornull; +typedef mapstruct mapstruct_ornull; + static f_plug_api gethook; static f_plug_api registerGlobalEvent; static f_plug_api unregisterGlobalEvent; static f_plug_api systemDirectory; static f_plug_api object_set_property; static f_plug_api map_get_map; +static f_plug_api object_insert; +/* this is a stupid way to do things, and awkward to use for plug-in authors */ typedef struct { object* who; object* activator; object* third; + mapstruct* map; char message[1024]; - int fix; + int fix; // seems to be python-only, and should not be part of the API int event_code; char extension[1024]; // name field, should invoke specific perl extension char options[1024]; // slaying field of event_connectors int returnvalue; } CFPContext; -//static int current_command = -999; - static HV *obj_cache; static PerlInterpreter *perl; @@ -82,8 +86,12 @@ void clean_obj_cache () { - return; //D // killing neko-san gives me an unreferenced scalar - int todo = 10; + static int count; + + if (++count & 7) + return; + + int todo = 1000; do { I32 klen; @@ -94,7 +102,7 @@ { SV *sv = hv_iterval (obj_cache, he); - // emopty and unreferened? nuke it + // empty and unreferenced? nuke it if (SvREFCNT (sv) == 1 && SvREFCNT (SvRV (sv)) == 1 && !HvFILL ((HV *)(SvRV (sv)))) { hv_delete (obj_cache, HeKEY (he), HeKLEN (he), G_DISCARD); @@ -110,30 +118,39 @@ static SV * newSVptr (void *ptr, const char *klass) { + SV *sv; + if (!ptr) return &PL_sv_undef; - HV *hv = newHV (); - sv_magic ((SV *)hv, 0, PERL_MAGIC_ext, (char *)ptr, 0); - return sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1)); + sv = newSV (0); + sv_magic (sv, 0, PERL_MAGIC_ext, (char *)ptr, 0); + return sv_bless (newRV_noinc (sv), gv_stashpv (klass, 1)); +} + +static SV * +SVptr_cached (void *ptr) +{ + SV **he = hv_fetch (obj_cache, (char *)&ptr, sizeof (ptr), 0); + + return he ? *he : 0; } static SV * newSVptr_cached (void *ptr, const char *klass) { - SV *sv, **he; + SV *sv; if (!ptr) return &PL_sv_undef; - he = hv_fetch (obj_cache, (char *)&ptr, sizeof (ptr), 0); + sv = SVptr_cached (ptr); - if (he) - sv = *he; - else + if (!sv) { - return sv; //D - sv = newSVptr (ptr, klass); + HV *hv = newHV (); + sv_magic ((SV *)hv, 0, PERL_MAGIC_ext, (char *)ptr, 0); + sv = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1)); hv_store (obj_cache, (char *)&ptr, sizeof (ptr), sv, 0); } @@ -164,6 +181,15 @@ return (long)mg->mg_ptr; } +static long +SvPTR_ornull (SV *sv, const char *klass) +{ + if (SvOK (sv)) + return SvPTR (sv, klass); + else + return 0; +} + SV * newSVcfapi (int type, ...) { @@ -174,6 +200,12 @@ switch (type) { +#if 0 + case CFAPI_INT16: + sv = newSViv (*va_arg (args, sint16_t *)); + break; +#endif + case CFAPI_INT: sv = newSViv (*va_arg (args, int *)); break; @@ -263,6 +295,7 @@ hv_context (CFAPI_POBJECT, ,who); hv_context (CFAPI_POBJECT, ,activator); hv_context (CFAPI_POBJECT, ,third); + hv_context (CFAPI_PMAP, ,map); hv_context (CFAPI_STRING , ,message); hv_context (CFAPI_INT ,&,fix); hv_context (CFAPI_INT ,&,event_code); @@ -393,6 +426,7 @@ systemDirectory = gethook (&rtype, hooktype, "cfapi_system_directory"); object_set_property = gethook (&rtype, hooktype, "cfapi_object_set_property"); map_get_map = gethook (&rtype, hooktype, "cfapi_map_get_map"); + object_insert = gethook (&rtype, hooktype, "cfapi_object_insert"); cf_init_plugin (gethook); @@ -407,6 +441,9 @@ registerGlobalEvent (NULL, EVENT_MAPENTER, PLUGIN_NAME, globalEventListener); registerGlobalEvent (NULL, EVENT_MAPLEAVE, PLUGIN_NAME, globalEventListener); registerGlobalEvent (NULL, EVENT_MAPRESET, PLUGIN_NAME, globalEventListener); + registerGlobalEvent (NULL, EVENT_MAPLOAD, PLUGIN_NAME, globalEventListener); + registerGlobalEvent (NULL, EVENT_MAPOUT, PLUGIN_NAME, globalEventListener); + registerGlobalEvent (NULL, EVENT_MAPIN, PLUGIN_NAME, globalEventListener); registerGlobalEvent (NULL, EVENT_REMOVE, PLUGIN_NAME, globalEventListener); registerGlobalEvent (NULL, EVENT_SHOUT, PLUGIN_NAME, globalEventListener); registerGlobalEvent (NULL, EVENT_TELL, PLUGIN_NAME, globalEventListener); @@ -468,6 +505,12 @@ printf ("Unimplemented for now\n"); break; + case EVENT_MAPLOAD: + case EVENT_MAPOUT: + case EVENT_MAPIN: + context.map = va_arg (args, mapstruct *); + break; + case EVENT_MAPENTER: case EVENT_MAPLEAVE: case EVENT_FREE_OB: @@ -511,6 +554,7 @@ 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)); @@ -521,13 +565,10 @@ if (context.event_code == EVENT_FREE_OB) { - SV *sv = hv_delete (obj_cache, (char *)&context.activator, sizeof (object *), 0); + SV *sv = hv_delete (obj_cache, (char *)&context.activator, sizeof (void *), 0); if (sv) - { - clearSVptr (sv); - SvREFCNT_dec (sv); - } + clearSVptr (sv); } else inject_event ("cf::inject_global_event", &context); @@ -734,6 +775,33 @@ const_iv (ST_MAT_WALL) const_iv (ST_MAT_ITEM) + const_iv (AT_PHYSICAL) + const_iv (AT_MAGIC) + const_iv (AT_FIRE) + const_iv (AT_ELECTRICITY) + const_iv (AT_COLD) + const_iv (AT_CONFUSION) + const_iv (AT_ACID) + const_iv (AT_DRAIN) + const_iv (AT_WEAPONMAGIC) + const_iv (AT_GHOSTHIT) + const_iv (AT_POISON) + const_iv (AT_SLOW) + const_iv (AT_PARALYZE) + const_iv (AT_TURN_UNDEAD) + const_iv (AT_FEAR) + const_iv (AT_CANCELLATION) + const_iv (AT_DEPLETE) + const_iv (AT_DEATH) + const_iv (AT_CHAOS) + const_iv (AT_COUNTERSPELL) + const_iv (AT_GODPOWER) + const_iv (AT_HOLYWORD) + const_iv (AT_BLIND) + const_iv (AT_INTERNAL) + const_iv (AT_LIFE_STEALING) + const_iv (AT_DISEASE) + const_iv (QUEST_IN_PROGRESS) const_iv (QUEST_DONE_QUEST) const_iv (QUEST_DONE_TASK) @@ -945,6 +1013,9 @@ const_event (MAPENTER) const_event (MAPLEAVE) const_event (MAPRESET) + const_event (MAPLOAD) + const_event (MAPOUT) + const_event (MAPIN) const_event (REMOVE) const_event (SHOUT) const_event (TELL) @@ -1154,12 +1225,46 @@ } break; case CFAPI_STRING: - cf_object_set_string_property (obj, idx, SvPV_nolen (newval)); + cf_object_set_string_property (obj, idx, SvOK (newval) ? SvPV_nolen (newval) : 0); + break; + case CFAPI_POBJECT: + { + int unused_type; + object_set_property (&unused_type, obj, idx, (object *)SvPTR_ornull (newval, "cf::object")); + } break; default: croak ("unhandled type '%d' in set_property '%d'", type, idx); } +# missing properties + +void +set_attacktype (object *obj, U32 attacktype) + CODE: + obj->attacktype = attacktype; + +U32 +get_attacktype (object *obj) + ALIAS: + attacktype = 0 + CODE: + RETVAL = obj->attacktype; + OUTPUT: RETVAL + +void +set_food (object *obj, int food) + CODE: + obj->stats.food = food; + +int +get_food (object *obj) + ALIAS: + food = 0 + CODE: + RETVAL = obj->stats.food; + OUTPUT: RETVAL + void inv (object *obj) PROTOTYPE: $ @@ -1178,7 +1283,7 @@ void cf_object_set_flag (object *op, int flag, int value) -void cf_object_move (object *op, int dir, object *originator) +void cf_object_move (object *op, int dir, object *originator = op) void cf_object_apply (object *op, object *author, int flags = 0) @@ -1194,15 +1299,15 @@ int cf_object_change_map (object *op, int x, int y, mapstruct *map) -object *cf_object_clone (object *op, int clonetype) +object *cf_object_clone (object *op, int clonetype = 0) int cf_object_pay_item (object *op, object *buyer) int cf_object_pay_amount (object *op, double amount) -int cf_object_cast_spell (object *caster, object *ctoo, int dir, object *sp_, char *flags) +int cf_object_cast_spell (object *caster, object *ctoo, int dir, object *spell_ob, char *stringarg = 0) -int cf_object_cast_ability (object *caster, object *ctoo, int dir, object *sp_, char *flags) +int cf_object_cast_ability (object *caster, object *ctoo, int dir, object *sp_, char *stringarg = 0) void cf_object_learn_spell (object *op, object *sp) @@ -1248,31 +1353,37 @@ void cf_object_set_key (object *op, char *keyname, char *value) -char * -base_name (object *ob, int plural) - CODE: - RETVAL = cf_query_base_name (ob, plural); - OUTPUT: RETVAL +object *cf_create_object_by_name (const char *name) -MODULE = cf PACKAGE = cf::object PREFIX = cf_object_ +MODULE = cf PACKAGE = cf::object PREFIX = cf_ + +void cf_fix_object (object *pl) + ALIAS: fix = 0 + +object *cf_insert_ob_in_ob (object *ob, object *where) + +# no clean way to get an object from an archetype - stupid idiotic +# dumb kludgy misdesigned plug-in api slowly gets on my nerves. -object *cf_create_object_by_name (const char *name = 0) +object *new (const char *archetype = 0) PROTOTYPE: ;$ - ALIAS: - create_object = 0 - new = 0 CODE: - RETVAL = name ? cf_create_object_by_name (name) : cf_create_object (); + RETVAL = archetype ? get_archetype (archetype) : cf_create_object (); OUTPUT: RETVAL -void cf_fix_object (object *pl) - ALIAS: fix = 0 - -object *cf_insert_ob_in_ob (object *ob, object *where) +object *insert_ob_in_map_at (object *ob, mapstruct *where, object_ornull *orig, int flag, int x, int y) + PROTOTYPE: $$$$$$ + CODE: +{ + int unused_type; + RETVAL = (object *)object_insert (&unused_type, ob, 0, where, orig, flag, x, y); +} object *get_nearest_player (object *ob) ALIAS: nearest_player = 0 + PREINIT: + extern object *get_nearest_player (object *); void rangevector (object *ob, object *other, int flags = 0) PROTOTYPE: $$;$ @@ -1293,6 +1404,12 @@ RETVAL = on_same_map (ob, other); OUTPUT: RETVAL +char * +base_name (object *ob, int plural) + CODE: + RETVAL = cf_query_base_name (ob, plural); + OUTPUT: RETVAL + MODULE = cf PACKAGE = cf::object::player PREFIX = cf_player_ @@ -1305,6 +1422,11 @@ object *cf_player_send_inventory (object *op) +player *contr (object *op) + CODE: + RETVAL = op->contr; + OUTPUT: RETVAL + char *cf_player_get_ip (object *op) ALIAS: ip = 0 @@ -1328,6 +1450,8 @@ void cf_player_move (player *pl, int dir) +void MapNewmapCmd (player *pl) + # nonstandard object *ob (player *pl) CODE: @@ -1409,6 +1533,7 @@ PPCODE: { object *o; + for (o = GET_MAP_OB (obj, x, y); o; o = o->above) XPUSHs (sv_2mortal (newSVcfapi (CFAPI_POBJECT, o))); } @@ -1441,6 +1566,43 @@ OUTPUT: RETVAL +void +_get_obs (mapstruct *map) + PPCODE: +{ + object *o; + int x, y; + AV *obs = newAV (); + int nonnull = 0; + + for (y = 0; y < MAP_HEIGHT (map); y++) + for (x = 0; x < MAP_WIDTH (map); x++) + { + AV *av = newAV (); + + for (o = GET_MAP_OB (map, x, y); o; o = o->above) + { + SV *sv = SVptr_cached (o); + + if (sv && HvFILL (SvRV (sv))) + { + nonnull = 1; + sv = newSVsv (sv); + } + else + sv = &PL_sv_undef; + + av_push (av, sv); + } + + av_store (obs, x + y * MAP_HEIGHT (map), newRV_noinc ((SV *)av)); + } + + if (nonnull) + XPUSHs (sv_2mortal (newRV_noinc ((SV *)obs))); + else + SvREFCNT_dec (obs); +} MODULE = cf PACKAGE = cf::arch PREFIX = cf_archetype_