--- deliantra/server/plugins/cfperl/cfperl.xs 2006/06/26 15:40:15 1.55 +++ deliantra/server/plugins/cfperl/cfperl.xs 2006/07/15 21:10:04 1.60 @@ -47,11 +47,18 @@ #include +//#include "EventAPI.h" #include "perlxsi.c" +extern sint64 *levels; // the experience table + typedef object object_ornull; typedef mapstruct mapstruct_ornull; +typedef double val64; +#define newSVval64 newSVnv +#define SvVAL64 SvNV + static f_plug_api gethook; static f_plug_api registerGlobalEvent; static f_plug_api unregisterGlobalEvent; @@ -87,6 +94,9 @@ #define PUSH_PV PUSHcfapi_va(STRING, const char *) #define PUSH_IV PUSHs (sv_2mortal (newSViv (va_arg (args, int)))) +extern void pay_player(object *op, uint64 amount); +extern uint64 pay_player_arch(object *op, const char *arch, uint64 amount); + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // garbage collect some perl objects, if possible @@ -227,7 +237,7 @@ break; case CFAPI_LONG: - sv = newSVnv ((double)*va_arg (args, sint64 *)); /* oh, the humanity! */ + sv = newSVval64 ((val64)*va_arg (args, sint64 *)); break; case CFAPI_DOUBLE: @@ -410,6 +420,9 @@ registerGlobalEvent (NULL, EVENT_BORN, PLUGIN_NAME, globalEventListener); registerGlobalEvent (NULL, EVENT_CLOCK, PLUGIN_NAME, globalEventListener); //registerGlobalEvent (NULL, EVENT_CRASH, PLUGIN_NAME, globalEventListener); + registerGlobalEvent (NULL, EVENT_FIND_UNARMED_SKILL, PLUGIN_NAME, globalEventListener); + registerGlobalEvent (NULL, EVENT_PLAYER_USE_SKILL, PLUGIN_NAME, globalEventListener); + registerGlobalEvent (NULL, EVENT_MONSTER_USE_SKILL, PLUGIN_NAME, globalEventListener); registerGlobalEvent (NULL, EVENT_PLAYER_DEATH, PLUGIN_NAME, globalEventListener); registerGlobalEvent (NULL, EVENT_GKILL, PLUGIN_NAME, globalEventListener); registerGlobalEvent (NULL, EVENT_LOGIN, PLUGIN_NAME, globalEventListener); @@ -490,6 +503,34 @@ rv = 0; } + else if (event_code == EVENT_CLOCK) + { + dSP; + int i, count; + + clean_obj_cache (); + + ENTER; + SAVETMPS; + + // service up to 8 events per tick better would be + // to check for elapsed time and stop processing after + // 0.25 * server_tick or so + for (i = 9; --i; ) + { + PUSHMARK (SP); + XPUSHs (sv_2mortal (newSViv (0))); + PUTBACK; + count = call_pv ("Event::one_event", G_SCALAR | G_EVAL); + SPAGAIN; + + if (!count || !POPi) + break; + } + + FREETMPS; + LEAVE; + } else { dSP; @@ -547,6 +588,19 @@ PUSH_PV; break; + case EVENT_FIND_UNARMED_SKILL: + PUSH_OB; + break; + + case EVENT_PLAYER_USE_SKILL: + case EVENT_MONSTER_USE_SKILL: + PUSH_OB; + PUSH_OB; + PUSH_OB; + PUSH_IV; + PUSH_PV; + break; + case EVENT_EXTCMD: PUSH_PL; { @@ -556,10 +610,6 @@ } break; - case EVENT_CLOCK: - clean_obj_cache (); - break; - case EVENT_TELL: break; } @@ -1132,6 +1182,36 @@ const_iv (SOUND_DRINK_POISON) const_iv (SOUND_CAST_SPELL_0) + const_iv (PREFER_LOW) + const_iv (PREFER_HIGH) + + const_iv (ATNR_PHYSICAL) + const_iv (ATNR_MAGIC) + const_iv (ATNR_FIRE) + const_iv (ATNR_ELECTRICITY) + const_iv (ATNR_COLD) + const_iv (ATNR_CONFUSION) + const_iv (ATNR_ACID) + const_iv (ATNR_DRAIN) + const_iv (ATNR_WEAPONMAGIC) + const_iv (ATNR_GHOSTHIT) + const_iv (ATNR_POISON) + const_iv (ATNR_SLOW) + const_iv (ATNR_PARALYZE) + const_iv (ATNR_TURN_UNDEAD) + const_iv (ATNR_FEAR) + const_iv (ATNR_CANCELLATION) + const_iv (ATNR_DEPLETE) + const_iv (ATNR_DEATH) + const_iv (ATNR_CHAOS) + const_iv (ATNR_COUNTERSPELL) + const_iv (ATNR_GODPOWER) + const_iv (ATNR_HOLYWORD) + const_iv (ATNR_BLIND) + const_iv (ATNR_INTERNAL) + const_iv (ATNR_LIFE_STEALING) + const_iv (ATNR_DISEASE) + const_iv (MAP_FLUSH) const_iv (MAP_PLAYER_UNIQUE) const_iv (MAP_BLOCK) @@ -1168,7 +1248,7 @@ const_event (MOVE) const_event (BORN) - const_event (CLOCK) + //const_event (CLOCK) const_event (CRASH) const_event (PLAYER_DEATH) const_event (PLAYER_LOAD) @@ -1188,6 +1268,9 @@ const_event (TELL) const_event (MUZZLE) const_event (KICK) + const_event (PLAYER_USE_SKILL) + const_event (MONSTER_USE_SKILL) + const_event (FIND_UNARMED_SKILL) const_event (EXTCMD) //const_event (FREE_OB) }; @@ -1332,6 +1415,8 @@ hv_store (prop_type, cprop->name, strlen (cprop->name), newSViv (cprop->dtype), 0); hv_store (prop_idx, cprop->name, strlen (cprop->name), newSViv (cprop->idx ), 0); } + + //I_EVENT_API (PACKAGE); } void @@ -1372,6 +1457,47 @@ cf_find_animation (char *text) PROTOTYPE: $ +int random_roll(int min, int max, object *op, int goodbad); + +int +exp_to_level (val64 exp) + CODE: +{ + int i = 0; + + RETVAL = settings.max_level; + + for (i = 1; i <= settings.max_level; i++) + { + if (levels[i] > exp) + { + RETVAL = i - 1; + break; + } + } +} + OUTPUT: RETVAL + +val64 +level_to_min_exp (int level) + CODE: + if (level > settings.max_level) + RETVAL = levels[settings.max_level]; + else if (level < 1) + RETVAL = 0; + else + RETVAL = levels[level]; + OUTPUT: RETVAL + +SV * +resistance_to_string (int atnr) + CODE: + if (atnr >= 0 && atnr < NROFATTACKS) + RETVAL = newSVpv (resist_plus[atnr], 0); + else + XSRETURN_UNDEF; + OUTPUT: RETVAL + MODULE = cf PACKAGE = cf::object PREFIX = cf_object_ SV * @@ -1389,7 +1515,7 @@ cf_object_set_int_property (obj, idx, SvIV (newval)); break; case CFAPI_LONG: - cf_object_set_long_property (obj, idx, SvNV (newval)); + cf_object_set_long_property (obj, idx, SvVAL64 (newval)); break; case CFAPI_DOUBLE: { @@ -1477,7 +1603,7 @@ int cf_object_pay_item (object *op, object *buyer) -int cf_object_pay_amount (object *op, double amount) +int cf_object_pay_amount (object *op, val64 amount) int cf_object_cast_spell (object *caster, object *ctoo, int dir, object *spell_ob, char *stringarg = 0) @@ -1524,12 +1650,25 @@ object *cf_create_object_by_name (const char *name) -void change_exp (object *op, double exp, const char *skill_name = 0, int flag = 0) +void change_exp (object *op, val64 exp, const char *skill_name = 0, int flag = 0) + +void pay_player (object *op, val64 amount) + +val64 pay_player_arch (object *op, const char *arch, val64 amount) void player_lvl_adj (object *who, object *skill = 0) int kill_object (object *op, int dam = 0, object *hitter = 0, int type = AT_PHYSICAL) +int calc_skill_exp (object *who, object *op, object *skill); + +void +cf_object_set_resistance (object *op, int rtype, int val) + CODE: + if (rtype >= 0 && rtype < NROFATTACKS) + op->resist[rtype] = val; + + MODULE = cf PACKAGE = cf::object PREFIX = cf_ void cf_fix_object (object *pl) @@ -1632,7 +1771,7 @@ void cf_player_set_party (object *op, partylist *party) -void change_skill (object *op, double exp, char *skill_name = 0, int flag = 0) +void change_skill (object *op, val64 exp, char *skill_name = 0, int flag = 0) void kill_player (object *op) @@ -1775,6 +1914,20 @@ void play_sound_map (mapstruct *map, int x, int y, int sound_num) +mapstruct *tile_map (mapstruct *map, unsigned int dir) + CODE: + RETVAL = dir < 4 ? map->tile_map [dir] : 0; + OUTPUT: + RETVAL + +char *tile_path (mapstruct *map, unsigned int dir) + CODE: + if (dir >= 4) + XSRETURN_UNDEF; + RETVAL = map->tile_path [dir]; + OUTPUT: + RETVAL + mapstruct *cf_map_get_map (char *name) PROTOTYPE: $ ALIAS: map = 0 @@ -2015,8 +2168,8 @@ MODULE = cf PACKAGE = cf::living PREFIX = cf_living_ -double -exp (living *liv, double new_val = 0.) +val64 +exp (living *liv, val64 new_val = 0) PROTOTYPE: $;$ ALIAS: Str = 1