ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
(Generate patch)

Comparing deliantra/server/server/cfperl.xs (file contents):
Revision 1.6 by root, Thu Aug 24 17:29:30 2006 UTC vs.
Revision 1.10 by root, Fri Aug 25 17:11:53 2006 UTC

87} CFPContext; 87} CFPContext;
88 88
89static HV *obj_cache; 89static HV *obj_cache;
90static PerlInterpreter *perl; 90static PerlInterpreter *perl;
91 91
92static AV *cb_global, *cb_object, *cb_player, *cb_type, *cb_map;
93
92#define PUSHcfapi(type,value) PUSHs (sv_2mortal (newSVcfapi (CFAPI_ ## type, (value)))) 94#define PUSHcfapi(type,value) PUSHs (sv_2mortal (newSVcfapi (CFAPI_ ## type, (value))))
93#define PUSHcfapi_va(type,ctype) PUSHcfapi (type, va_arg (args, ctype)) 95#define PUSHcfapi_va(type,ctype) PUSHcfapi (type, va_arg (args, ctype))
94#define PUSH_OB PUSHcfapi_va(POBJECT, object *) 96#define PUSH_OB PUSHcfapi_va(POBJECT, object *)
95#define PUSH_PL PUSHcfapi_va(PPLAYER, player *) 97#define PUSH_PL PUSHcfapi_va(PPLAYER, player *)
96#define PUSH_MAP PUSHcfapi_va(PMAP, mapstruct *) 98#define PUSH_MAP PUSHcfapi_va(PMAP, mapstruct *)
140 SV *sv; 142 SV *sv;
141 143
142 if (!ptr) 144 if (!ptr)
143 return &PL_sv_undef; 145 return &PL_sv_undef;
144 146
145 sv = newSV (0); 147 sv = (SV *)newHV ();
146 sv_magic (sv, 0, PERL_MAGIC_ext, (char *)ptr, 0); 148 sv_magic (sv, 0, PERL_MAGIC_ext, (char *)ptr, 0);
147 return sv_bless (newRV_noinc (sv), gv_stashpv (klass, 1)); 149 return sv_bless (newRV_noinc (sv), gv_stashpv (klass, 1));
148} 150}
149 151
150static void 152static void
221{ 223{
222 SV *sv; 224 SV *sv;
223 225
224 switch (type) 226 switch (type)
225 { 227 {
228 // first three exist only for cfapi-compatibility
226 case DT_INT: 229 case DT_INT_PTR:
227 sv = newSViv (*va_arg (ap, int *)); 230 sv = newSViv (*va_arg (ap, int *));
228 break; 231 break;
229 232
230 case DT_LONG: 233 case DT_INT64_PTR:
231 sv = newSVval64 ((val64)*va_arg (ap, sint64 *)); 234 sv = newSVval64 ((val64)*va_arg (ap, sint64 *));
232 break; 235 break;
233 236
234 case DT_DOUBLE: 237 case DT_DOUBLE_PTR:
235 sv = newSVnv (*va_arg (ap, double *)); 238 sv = newSVnv (*va_arg (ap, double *));
236 break; 239 break;
237 240
241 case DT_INT:
242 sv = newSViv (va_arg (ap, int));
243 break;
244
245 case DT_INT64:
246 sv = newSVval64 ((val64)va_arg (ap, sint64));
247 break;
248
249 case DT_DOUBLE:
250 sv = newSVnv (va_arg (ap, double));
251 break;
252
238 case DT_STRING: 253 case DT_STRING:
239 { 254 {
240 char *str = va_arg (ap, char *); 255 char *str = (char *)va_arg (ap, const char *);
241 sv = str ? newSVpv (str, 0) : &PL_sv_undef; 256 sv = str ? newSVpv (str, 0) : &PL_sv_undef;
242 } 257 }
243 break; 258 break;
244 259
245 case DT_DATA: 260 case DT_DATA:
246 { 261 {
247 char *str = (char *)va_arg (ap, void *); 262 char *str = (char *)va_arg (ap, const void *);
248 int len = va_arg (ap, int); 263 int len = va_arg (ap, int);
249 sv = str ? newSVpv (str, len) : &PL_sv_undef; 264 sv = str ? newSVpv (str, len) : &PL_sv_undef;
250 } 265 }
251 break; 266 break;
252 267
255 object *obj = va_arg (ap, object *); 270 object *obj = va_arg (ap, object *);
256 271
257 if (!obj) 272 if (!obj)
258 sv = &PL_sv_undef; 273 sv = &PL_sv_undef;
259 else 274 else
275 {
276 if (!obj->self)
260 switch (obj->type) 277 switch (obj->type)
261 { 278 {
262 case MAP: 279 case MAP:
263 sv = newSVptr_cached (obj, "cf::object::map::wrap"); 280 obj->self = static_cast<void *>(newSVptr (obj, "cf::object::map::wrap"));
264 break; 281 break;
265 282
266 case PLAYER: 283 case PLAYER:
267 sv = newSVptr_cached (obj, "cf::object::player::wrap"); 284 obj->self = static_cast<void *>(newSVptr (obj, "cf::object::player::wrap"));
268 break; 285 break;
269 286
270 default: 287 default:
271 sv = newSVptr_cached (obj, "cf::object::wrap"); 288 obj->self = static_cast<void *>(newSVptr (obj, "cf::object::wrap"));
272 break; 289 break;
290 }
291
292 sv = newSVsv (static_cast<SV *>(obj->self));
273 } 293 }
274 } 294 }
275 break; 295 break;
276 296
277 case DT_MAP: 297 case DT_MAP:
278 sv = newSVptr (va_arg (ap, mapstruct *), "cf::map::wrap"); 298 sv = newSVptr (va_arg (ap, mapstruct *), "cf::map::wrap");
321 va_list ap; 341 va_list ap;
322 va_start (ap, type); 342 va_start (ap, type);
323 343
324 switch (type) 344 switch (type)
325 { 345 {
326 case CFAPI_INT: sv = newSVdt_va (ap, DT_INT ); break; 346 case CFAPI_INT: sv = newSVdt_va (ap, DT_INT_PTR ); break;
327 case CFAPI_LONG: sv = newSVdt_va (ap, DT_LONG ); break; 347 case CFAPI_LONG: sv = newSVdt_va (ap, DT_INT64_PTR ); break;
328 case CFAPI_DOUBLE: sv = newSVdt_va (ap, DT_DOUBLE); break; 348 case CFAPI_DOUBLE: sv = newSVdt_va (ap, DT_DOUBLE_PTR); break;
329 case CFAPI_STRING: sv = newSVdt_va (ap, DT_STRING); break; 349 case CFAPI_STRING: sv = newSVdt_va (ap, DT_STRING); break;
330 case CFAPI_POBJECT: sv = newSVdt_va (ap, DT_OBJECT); break; 350 case CFAPI_POBJECT: sv = newSVdt_va (ap, DT_OBJECT); break;
331 case CFAPI_PMAP: sv = newSVdt_va (ap, DT_MAP ); break; 351 case CFAPI_PMAP: sv = newSVdt_va (ap, DT_MAP ); break;
332 case CFAPI_PPLAYER: sv = newSVdt_va (ap, DT_PLAYER); break; 352 case CFAPI_PPLAYER: sv = newSVdt_va (ap, DT_PLAYER); break;
333 case CFAPI_PARCH: sv = newSVdt_va (ap, DT_ARCH ); break; 353 case CFAPI_PARCH: sv = newSVdt_va (ap, DT_ARCH ); break;
449 object_insert = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_object_insert"); 469 object_insert = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_object_insert");
450 470
451 cf_init_plugin (gethook); 471 cf_init_plugin (gethook);
452 472
453 /* Pick the global events you want to monitor from this plugin */ 473 /* Pick the global events you want to monitor from this plugin */
454 registerGlobalEvent (NULL, EVENT_BORN, PLUGIN_NAME, globalEventListener);
455 registerGlobalEvent (NULL, EVENT_CLOCK, PLUGIN_NAME, globalEventListener); 474 registerGlobalEvent (NULL, EVENT_CLOCK, PLUGIN_NAME, globalEventListener);
456 //registerGlobalEvent (NULL, EVENT_CRASH, PLUGIN_NAME, globalEventListener); 475 //registerGlobalEvent (NULL, EVENT_CRASH, PLUGIN_NAME, globalEventListener);
457 registerGlobalEvent (NULL, EVENT_FIND_UNARMED_SKILL, PLUGIN_NAME, globalEventListener); 476 registerGlobalEvent (NULL, EVENT_FIND_UNARMED_SKILL, PLUGIN_NAME, globalEventListener);
458 registerGlobalEvent (NULL, EVENT_PLAYER_USE_SKILL, PLUGIN_NAME, globalEventListener);
459 registerGlobalEvent (NULL, EVENT_CAST_SPELL, PLUGIN_NAME, globalEventListener);
460 registerGlobalEvent (NULL, EVENT_MONSTER_USE_SKILL, PLUGIN_NAME, globalEventListener);
461 registerGlobalEvent (NULL, EVENT_PLAYER_DEATH, PLUGIN_NAME, globalEventListener);
462 registerGlobalEvent (NULL, EVENT_GKILL, PLUGIN_NAME, globalEventListener);
463 registerGlobalEvent (NULL, EVENT_LOGIN, PLUGIN_NAME, globalEventListener);
464 registerGlobalEvent (NULL, EVENT_LOGOUT, PLUGIN_NAME, globalEventListener);
465 registerGlobalEvent (NULL, EVENT_MAPENTER, PLUGIN_NAME, globalEventListener);
466 registerGlobalEvent (NULL, EVENT_MAPLEAVE, PLUGIN_NAME, globalEventListener);
467 registerGlobalEvent (NULL, EVENT_MAPRESET, PLUGIN_NAME, globalEventListener);
468 registerGlobalEvent (NULL, EVENT_MAPLOAD, PLUGIN_NAME, globalEventListener);
469 registerGlobalEvent (NULL, EVENT_MAPOUT, PLUGIN_NAME, globalEventListener);
470 registerGlobalEvent (NULL, EVENT_MAPIN, PLUGIN_NAME, globalEventListener);
471 registerGlobalEvent (NULL, EVENT_MAPCLEAN, PLUGIN_NAME, globalEventListener);
472 registerGlobalEvent (NULL, EVENT_REMOVE, PLUGIN_NAME, globalEventListener);
473 registerGlobalEvent (NULL, EVENT_SHOUT, PLUGIN_NAME, globalEventListener); 477 registerGlobalEvent (NULL, EVENT_SHOUT, PLUGIN_NAME, globalEventListener);
474 registerGlobalEvent (NULL, EVENT_TELL, PLUGIN_NAME, globalEventListener); 478 registerGlobalEvent (NULL, EVENT_TELL, PLUGIN_NAME, globalEventListener);
475 registerGlobalEvent (NULL, EVENT_MUZZLE, PLUGIN_NAME, globalEventListener); 479 registerGlobalEvent (NULL, EVENT_MUZZLE, PLUGIN_NAME, globalEventListener);
476 registerGlobalEvent (NULL, EVENT_KICK, PLUGIN_NAME, globalEventListener); 480 registerGlobalEvent (NULL, EVENT_KICK, PLUGIN_NAME, globalEventListener);
477 registerGlobalEvent (NULL, EVENT_FREE_OB, PLUGIN_NAME, globalEventListener);
478 registerGlobalEvent (NULL, EVENT_PLAYER_LOAD, PLUGIN_NAME, globalEventListener);
479 registerGlobalEvent (NULL, EVENT_PLAYER_SAVE, PLUGIN_NAME, globalEventListener);
480 registerGlobalEvent (NULL, EVENT_EXTCMD, PLUGIN_NAME, globalEventListener);
481
482 char *argv[] = {
483 "",
484 "-e"
485 "BEGIN {"
486 " cf->bootstrap;"
487 " unshift @INC, cf::datadir ();"
488 "}"
489 ""
490 "use cf;"
491 };
492
493 perl = perl_alloc ();
494 perl_construct (perl);
495
496 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
497
498 if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl))
499 {
500 printf ("unable to initialize perl-interpreter, aborting.\n");
501
502 exit (EXIT_FAILURE);
503 //perl_destruct (perl);
504 //perl_free (perl);
505 //perl = 0;
506 }
507 else
508 {
509 obj_cache = newHV ();
510 }
511 481
512 return 0; 482 return 0;
513} 483}
514 484
515static void * 485static void *
523 return NULL; 493 return NULL;
524 494
525 va_start (args, type); 495 va_start (args, type);
526 event_code = va_arg (args, int); 496 event_code = va_arg (args, int);
527 497
528 if (event_code == EVENT_FREE_OB)
529 {
530 player *pl;
531 object *op;
532 SV *sv;
533
534 op = va_arg (args, object *);
535 sv = hv_delete (obj_cache, (char *)&op, sizeof (void *), 0);
536
537 if (sv)
538 clearSVptr (sv);
539
540 rv = 0;
541 }
542 else if (event_code == EVENT_CLOCK) 498 if (event_code == EVENT_CLOCK)
543 { 499 {
544 clean_obj_cache (); 500 clean_obj_cache ();
545 } 501 }
546 else 502 else
547 { 503 {
558 switch (event_code) 514 switch (event_code)
559 { 515 {
560 case EVENT_CRASH: 516 case EVENT_CRASH:
561 break; 517 break;
562 518
563 case EVENT_PLAYER_LOAD:
564 case EVENT_PLAYER_SAVE:
565 PUSH_OB;
566 PUSH_PV;
567 break;
568
569 case EVENT_MAPLOAD:
570 case EVENT_MAPOUT:
571 case EVENT_MAPIN:
572 case EVENT_MAPCLEAN:
573 case EVENT_MAPRESET:
574 PUSH_MAP;
575 break;
576
577 case EVENT_MAPENTER:
578 case EVENT_MAPLEAVE:
579 case EVENT_BORN:
580 case EVENT_REMOVE:
581 case EVENT_PLAYER_DEATH:
582 PUSH_OB;
583 break;
584
585 case EVENT_GKILL:
586 PUSH_OB;
587 PUSH_OB;
588 break;
589
590 case EVENT_LOGIN:
591 case EVENT_LOGOUT:
592 PUSH_PL;
593 PUSH_PV;
594 break;
595
596 case EVENT_SHOUT: 519 case EVENT_SHOUT:
597 case EVENT_MUZZLE: 520 case EVENT_MUZZLE:
598 case EVENT_KICK: 521 case EVENT_KICK:
599 PUSH_OB; 522 PUSH_OB;
600 PUSH_PV; 523 PUSH_PV;
601 break; 524 break;
602 525
603 case EVENT_FIND_UNARMED_SKILL: 526 case EVENT_FIND_UNARMED_SKILL:
604 PUSH_OB; 527 PUSH_OB;
605 break;
606
607 case EVENT_PLAYER_USE_SKILL:
608 case EVENT_MONSTER_USE_SKILL:
609 case EVENT_CAST_SPELL:
610 PUSH_OB;
611 PUSH_OB;
612 PUSH_OB;
613 PUSH_IV;
614 PUSH_PV;
615 break;
616
617 case EVENT_EXTCMD:
618 PUSH_PL;
619 {
620 char *buf = va_arg (args, char *);
621 int len = va_arg (args, int);
622 PUSHs (sv_2mortal (newSVpvn (buf, len)));
623 }
624 break; 528 break;
625 529
626 case EVENT_TELL: 530 case EVENT_TELL:
627 break; 531 break;
628 } 532 }
692 break; 596 break;
693 597
694 case EVENT_APPLY: // $ob, $who 598 case EVENT_APPLY: // $ob, $who
695 case EVENT_DROP: // $ob, $who 599 case EVENT_DROP: // $ob, $who
696 case EVENT_CLOSE: // $ob, $who 600 case EVENT_CLOSE: // $ob, $who
697 case EVENT_DEATH: // $ob[, $killer]
698 case EVENT_MOVE: // $ob, $enemy 601 case EVENT_MOVE: // $ob, $enemy
699 case EVENT_THROW: // $ob, $thrower 602 case EVENT_THROW: // $ob, $thrower
700 PUSHcfapi (POBJECT, activator); 603 PUSHcfapi (POBJECT, activator);
701 break; 604 break;
702 605
742extern "C" int cfperl_closePlugin () 645extern "C" int cfperl_closePlugin ()
743{ 646{
744 return 0; 647 return 0;
745} 648}
746 649
650void
651cfperl_init ()
652{
653 char *argv[] = {
654 "",
655 "-e"
656 "BEGIN {"
657 " cf->bootstrap;"
658 " unshift @INC, cf::datadir ();"
659 "}"
660 ""
661 "use cf;"
662 };
663
664 perl = perl_alloc ();
665 perl_construct (perl);
666
667 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
668
669 if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl))
670 {
671 printf ("unable to initialize perl-interpreter, aborting.\n");
672
673 exit (EXIT_FAILURE);
674 //perl_destruct (perl);
675 //perl_free (perl);
676 //perl = 0;
677 //return;
678 }
679
680 obj_cache = newHV ();
681}
682
747void cfperl_main () 683void cfperl_main ()
748{ 684{
749 dSP; 685 dSP;
750 686
751 PUSHMARK (SP); 687 PUSHMARK (SP);
752 PUTBACK; 688 PUTBACK;
753 call_pv ("cf::run", G_DISCARD | G_VOID); 689 call_pv ("cf::main", G_DISCARD | G_VOID);
754} 690}
755 691
756int cfperl_invoke (const char *klass, event_type event, ...) 692void cfperl_free_ob (object *op)
757{ 693{
694 if (op->self) fprintf (stderr, "free_ob_self %p %s\n", op, op->name);//D
695 if (op->self) SvREFCNT_dec (op->self), op->self = 0;
696 if (op->cb) SvREFCNT_dec (op->cb), op->cb = 0;
697}
698
699static event_klass klass_of[NUM_EVENT_TYPES] = {
700# define def(type,name) KLASS_ ## type,
701# include "eventinc.h"
702# undef def
703};
704
705static void
706gather_callbacks (AV *&callbacks, AV *registry, event_type event)
707{
708 // event must be in array
709 if (event >= 0 && event <= AvFILLp (registry))
710 {
711 SV *cbs_ = AvARRAY (registry)[event];
712
713 // element must be list of callback entries
714 if (cbs_ && SvROK (cbs_) && SvTYPE (SvRV (cbs_)) == SVt_PVAV)
715 {
716 AV *cbs = (AV *)SvRV (cbs_);
717
718 // no callback entries, no callbacks to call
719 if (AvFILLp (cbs) >= 0)
720 {
721 if (!callbacks)
722 {
723 callbacks = newAV ();
724 av_extend (callbacks, 16);
725 }
726
727 // never use SvREFCNT_inc to copy values, but its ok here :)
728 for (int i = 0; i <= AvFILLp (cbs); ++i)
729 av_push (callbacks, SvREFCNT_inc (AvARRAY (cbs)[i]));
730 }
731 }
732 }
733}
734
735bool cfperl_invoke (event_type event, ...)
736{
737 data_type dt;
738 va_list ap;
739
740 va_start (ap, event);
741
742 AV *callbacks = 0;
743
744 object *op;
745 player *pl;
746 mapstruct *map;
747
748 // callback call ordering is:
749 // 1. per-object callback (NYI)
750 // 2. per-class object
751 // 2a. per-type callback
752 // 4. global callbacks
753
754 gather_callbacks (callbacks, cb_global, event);
755
756 switch (klass_of [event])
757 {
758 case KLASS_GLOBAL:
759 break;
760
761 case KLASS_OBJECT:
762 dt = (data_type) va_arg (ap, int);
763 assert (("first argument must be of type object", dt == DT_OBJECT));
764
765 op = va_arg (ap, object *);
766
767 gather_callbacks (callbacks, cb_object, event);
768 //TODO: per-object
769
770 if (op->type > 0 && op->type <= AvFILLp (cb_type))
771 {
772 SV *registry = AvARRAY (cb_type)[op->type];
773
774 if (registry && SvROK (registry) && SvTYPE (SvRV (registry)) == SVt_PVAV)
775 gather_callbacks (callbacks, (AV *)SvRV (registry), event);
776 }
777
778 break;
779
780 case KLASS_PLAYER:
781 dt = (data_type) va_arg (ap, int);
782 assert (("first argument must be of type player", dt == DT_PLAYER));
783
784 pl = va_arg (ap, player *);
785 gather_callbacks (callbacks, cb_player, event);
786 break;
787
788 case KLASS_MAP:
789 dt = (data_type) va_arg (ap, int);
790 assert (("first argument must be of type object", dt == DT_MAP));
791
792 map = va_arg (ap, mapstruct *);
793 gather_callbacks (callbacks, cb_map, event);
794 break;
795
796 default:
797 assert (("unsupported event klass in cfperl_invoke", 0));
798 }
799
800 // short-circuit processing if no callbacks found/defined
801 if (!callbacks)
802 return 0;
803
758 dSP; 804 dSP;
759 va_list ap;
760
761 ENTER; 805 ENTER;
762 SAVETMPS; 806 SAVETMPS;
763 807
764 va_start (ap, event);
765 PUSHMARK (SP); 808 PUSHMARK (SP);
766 EXTEND (SP, 2); 809 EXTEND (SP, 3);
767 PUSHs (sv_2mortal (newSViv (event))); 810
811 PUSHs (sv_2mortal (newSViv (event))); // only used for debugging nowadays
812 PUSHs (sv_2mortal (newRV_noinc ((SV *)callbacks)));
813
814 switch (klass_of [event])
815 {
816 case KLASS_OBJECT: PUSHs (sv_2mortal (newSVdt (DT_OBJECT, op))); break;
817 case KLASS_PLAYER: PUSHs (sv_2mortal (newSVdt (DT_PLAYER, pl))); break;
818 case KLASS_MAP: PUSHs (sv_2mortal (newSVdt (DT_MAP, map))); break;
819 }
768 820
769 for (;;) 821 for (;;)
770 { 822 {
771 data_type dt = (data_type) va_arg (ap, int); 823 dt = (data_type) va_arg (ap, int);
772 824
773 if (dt == DT_END) 825 if (dt == DT_END)
774 break; 826 break;
775 827
776 PUSHs (sv_2mortal (newSVdt_va (ap, dt))); 828 XPUSHs (sv_2mortal (newSVdt_va (ap, dt)));
777 } 829 }
778 830
779 va_end (ap); 831 va_end (ap);
780 832
781 PUTBACK; 833 PUTBACK;
782 int count = call_pv (klass, G_SCALAR | G_EVAL); 834 int count = call_pv ("cf::invoke", G_SCALAR | G_EVAL);
783 SPAGAIN; 835 SPAGAIN;
784 836
785 count = count > 0 ? POPi : 0; 837 count = count > 0 ? POPi : 0;
786 838
787 FREETMPS; 839 FREETMPS;
1274 1326
1275 const_iv (MAP_IN_MEMORY) 1327 const_iv (MAP_IN_MEMORY)
1276 const_iv (MAP_SWAPPED) 1328 const_iv (MAP_SWAPPED)
1277 const_iv (MAP_LOADING) 1329 const_iv (MAP_LOADING)
1278 const_iv (MAP_SAVING) 1330 const_iv (MAP_SAVING)
1331
1332 const_iv (KLASS_GLOBAL)
1333 const_iv (KLASS_OBJECT)
1334 const_iv (KLASS_PLAYER)
1335 const_iv (KLASS_MAP)
1279 }; 1336 };
1280 1337
1281 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 1338 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
1282 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 1339 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
1283 1340
1284 static const struct { 1341 static const struct {
1285 const char *name; 1342 const char *name;
1343 IV klass;
1286 IV iv; 1344 IV iv;
1287 } *eiv, event_iv[] = { 1345 } *eiv, event_iv[] = {
1288# define def(name) { # name, (IV)EV_ ## name }, 1346# define def(klass,name) { # name, (IV)KLASS_ ## klass, (IV)EV_ ## klass ## _ ## name },
1289# include "eventinc.h" 1347# include "eventinc.h"
1290# undef def 1348# undef def
1291 }; 1349 };
1292 1350
1293 AV *av = get_av ("cf::EVENT", 1); 1351 AV *av = get_av ("cf::EVENT", 1);
1294 1352
1295 for (eiv = event_iv + sizeof (event_iv) / sizeof (event_iv [0]); eiv-- > event_iv; ) 1353 for (eiv = event_iv + sizeof (event_iv) / sizeof (event_iv [0]); eiv-- > event_iv; )
1354 {
1355 AV *event = newAV ();
1296 av_store (av, eiv->iv, newSVpv ((char *)eiv->name, 0)); 1356 av_push (event, newSVpv ((char *)eiv->name, 0));
1357 av_push (event, newSViv (eiv->klass));
1358 av_store (av, eiv->iv, newRV_noinc ((SV *)event));
1359 }
1297 1360
1298 static const struct { 1361 static const struct {
1299 const char *name; 1362 const char *name;
1300 IV iv; 1363 IV iv;
1301 } *event, event_list[] = { 1364 } *event, event_list[] = {
1302# define const_event(name) { # name, (IV)EVENT_ ## name }, 1365# define const_event(name) { # name, (IV)EVENT_ ## name },
1303 const_event (NONE) 1366 const_event (NONE)
1304 const_event (APPLY) 1367 const_event (APPLY)
1305 const_event (ATTACK) 1368 const_event (ATTACK)
1306 const_event (DEATH)
1307 const_event (DROP) 1369 const_event (DROP)
1308 const_event (DROP_ON) 1370 const_event (DROP_ON)
1309 const_event (PICKUP) 1371 const_event (PICKUP)
1310 const_event (SAY) 1372 const_event (SAY)
1311 const_event (STOP) 1373 const_event (STOP)
1314 const_event (TRIGGER) 1376 const_event (TRIGGER)
1315 const_event (CLOSE) 1377 const_event (CLOSE)
1316 const_event (TIMER) 1378 const_event (TIMER)
1317 const_event (MOVE) 1379 const_event (MOVE)
1318 1380
1319 const_event (BORN)
1320 //const_event (CLOCK) 1381 //const_event (CLOCK)
1321 const_event (CRASH) 1382 const_event (CRASH)
1322 const_event (PLAYER_DEATH)
1323 const_event (PLAYER_LOAD)
1324 const_event (PLAYER_SAVE)
1325 const_event (GKILL)
1326 const_event (LOGIN)
1327 const_event (LOGOUT)
1328 const_event (MAPENTER)
1329 const_event (MAPLEAVE)
1330 const_event (MAPRESET)
1331 const_event (MAPLOAD)
1332 const_event (MAPOUT)
1333 const_event (MAPIN)
1334 const_event (MAPCLEAN)
1335 const_event (REMOVE)
1336 const_event (SHOUT) 1383 const_event (SHOUT)
1337 const_event (TELL) 1384 const_event (TELL)
1338 const_event (MUZZLE) 1385 const_event (MUZZLE)
1339 const_event (KICK) 1386 const_event (KICK)
1340 const_event (PLAYER_USE_SKILL)
1341 const_event (MONSTER_USE_SKILL)
1342 const_event (CAST_SPELL)
1343 const_event (FIND_UNARMED_SKILL) 1387 const_event (FIND_UNARMED_SKILL)
1344 const_event (EXTCMD)
1345 //const_event (FREE_OB) 1388 //const_event (FREE_OB)
1346 }; 1389 };
1347 1390
1348 av = get_av ("cf::PLUGIN_EVENT", 1); 1391 av = get_av ("cf::PLUGIN_EVENT", 1);
1349 1392
1484 { 1527 {
1485 hv_store (prop_type, cprop->name, strlen (cprop->name), newSViv (cprop->dtype), 0); 1528 hv_store (prop_type, cprop->name, strlen (cprop->name), newSViv (cprop->dtype), 0);
1486 hv_store (prop_idx, cprop->name, strlen (cprop->name), newSViv (cprop->idx ), 0); 1529 hv_store (prop_idx, cprop->name, strlen (cprop->name), newSViv (cprop->idx ), 0);
1487 } 1530 }
1488 1531
1532 cb_global = get_av ("cf::CB_GLOBAL", 1);
1533 cb_object = get_av ("cf::CB_OBJECT", 1);
1534 cb_player = get_av ("cf::CB_PLAYER", 1);
1535 cb_type = get_av ("cf::CB_TYPE" , 1);
1536 cb_map = get_av ("cf::CB_MAP" , 1);
1537
1489 //I_EVENT_API (PACKAGE); 1538 //I_EVENT_API (PACKAGE);
1490} 1539}
1491 1540
1492NV floor (NV x) 1541NV floor (NV x)
1493 1542
1905 1954
1906char * 1955char *
1907client (player *pl) 1956client (player *pl)
1908 CODE: 1957 CODE:
1909 RETVAL = pl->socket.client; 1958 RETVAL = pl->socket.client;
1959 OUTPUT:
1960 RETVAL
1961
1962char *
1963host (player *pl)
1964 CODE:
1965 RETVAL = pl->socket.host;
1966 OUTPUT:
1967 RETVAL
1968
1969char *
1970killer (player *pl, char *killer = 0)
1971 CODE:
1972 if (killer)
1973 snprintf (pl->killer, sizeof (pl->killer), "%s", killer);
1974 RETVAL = pl->killer;
1910 OUTPUT: 1975 OUTPUT:
1911 RETVAL 1976 RETVAL
1912 1977
1913void 1978void
1914buggy_mapscroll (player *pl, int value = 1) 1979buggy_mapscroll (player *pl, int value = 1)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines