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.4 by root, Mon Aug 21 07:13:32 2006 UTC vs.
Revision 1.10 by root, Fri Aug 25 17:11:53 2006 UTC

42#define MODULEAPI 42#define MODULEAPI
43#endif 43#endif
44 44
45#include <plugin_common.h> 45#include <plugin_common.h>
46#include <sounds.h> 46#include <sounds.h>
47
48#include <stdarg.h> 47#include <cstdarg>
49
50#include <sproto.h> 48#include <sproto.h>
51 49
52//#include "EventAPI.h" 50#include "cfperl.h"
51
53#include "perlxsi.c" 52#include "perlxsi.c"
54 53
55static void *globalEventListener (int *type, ...); 54static void *globalEventListener (int *type, ...);
56 55
57extern sint64 *levels; // the experience table 56extern sint64 *levels; // the experience table
88} CFPContext; 87} CFPContext;
89 88
90static HV *obj_cache; 89static HV *obj_cache;
91static PerlInterpreter *perl; 90static PerlInterpreter *perl;
92 91
92static AV *cb_global, *cb_object, *cb_player, *cb_type, *cb_map;
93
93#define PUSHcfapi(type,value) PUSHs (sv_2mortal (newSVcfapi (CFAPI_ ## type, (value)))) 94#define PUSHcfapi(type,value) PUSHs (sv_2mortal (newSVcfapi (CFAPI_ ## type, (value))))
94#define PUSHcfapi_va(type,ctype) PUSHcfapi (type, va_arg (args, ctype)) 95#define PUSHcfapi_va(type,ctype) PUSHcfapi (type, va_arg (args, ctype))
95#define PUSH_OB PUSHcfapi_va(POBJECT, object *) 96#define PUSH_OB PUSHcfapi_va(POBJECT, object *)
96#define PUSH_PL PUSHcfapi_va(PPLAYER, player *) 97#define PUSH_PL PUSHcfapi_va(PPLAYER, player *)
97#define PUSH_MAP PUSHcfapi_va(PMAP, mapstruct *) 98#define PUSH_MAP PUSHcfapi_va(PMAP, mapstruct *)
141 SV *sv; 142 SV *sv;
142 143
143 if (!ptr) 144 if (!ptr)
144 return &PL_sv_undef; 145 return &PL_sv_undef;
145 146
146 sv = newSV (0); 147 sv = (SV *)newHV ();
147 sv_magic (sv, 0, PERL_MAGIC_ext, (char *)ptr, 0); 148 sv_magic (sv, 0, PERL_MAGIC_ext, (char *)ptr, 0);
148 return sv_bless (newRV_noinc (sv), gv_stashpv (klass, 1)); 149 return sv_bless (newRV_noinc (sv), gv_stashpv (klass, 1));
149} 150}
150 151
151static void 152static void
216 else 217 else
217 return 0; 218 return 0;
218} 219}
219 220
220static SV * 221static SV *
221newSVcfapi (int type, ...) 222newSVdt_va (va_list &ap, data_type type)
222{ 223{
223 SV *sv; 224 SV *sv;
224
225 va_list args;
226 va_start (args, type);
227 225
228 switch (type) 226 switch (type)
229 { 227 {
230#if 0 228 // first three exist only for cfapi-compatibility
231 case CFAPI_INT16: 229 case DT_INT_PTR:
232 sv = newSViv (*va_arg (args, sint16_t *)); 230 sv = newSViv (*va_arg (ap, int *));
233 break; 231 break;
234#endif
235 232
236 case CFAPI_INT: 233 case DT_INT64_PTR:
237 sv = newSViv (*va_arg (args, int *)); 234 sv = newSVval64 ((val64)*va_arg (ap, sint64 *));
238 break; 235 break;
239 236
240 case CFAPI_LONG: 237 case DT_DOUBLE_PTR:
241 sv = newSVval64 ((val64)*va_arg (args, sint64 *)); 238 sv = newSVnv (*va_arg (ap, double *));
242 break; 239 break;
243 240
244 case CFAPI_DOUBLE: 241 case DT_INT:
245 sv = newSVnv (*va_arg (args, double *)); 242 sv = newSViv (va_arg (ap, int));
246 break; 243 break;
247 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
248 case CFAPI_STRING: 253 case DT_STRING:
249 { 254 {
250 char *str = va_arg (args, char *); 255 char *str = (char *)va_arg (ap, const char *);
251 sv = str ? newSVpv (str, 0) : &PL_sv_undef; 256 sv = str ? newSVpv (str, 0) : &PL_sv_undef;
252 } 257 }
253 break; 258 break;
254 259
255 case CFAPI_POBJECT: 260 case DT_DATA:
256 { 261 {
262 char *str = (char *)va_arg (ap, const void *);
263 int len = va_arg (ap, int);
264 sv = str ? newSVpv (str, len) : &PL_sv_undef;
265 }
266 break;
267
268 case DT_OBJECT:
269 {
257 object *obj = va_arg (args, object *); 270 object *obj = va_arg (ap, object *);
258 271
259 if (!obj) 272 if (!obj)
260 sv = &PL_sv_undef; 273 sv = &PL_sv_undef;
261 else 274 else
275 {
276 if (!obj->self)
262 switch (obj->type) 277 switch (obj->type)
263 { 278 {
264 case MAP: 279 case MAP:
265 sv = newSVptr_cached (obj, "cf::object::map::wrap"); 280 obj->self = static_cast<void *>(newSVptr (obj, "cf::object::map::wrap"));
266 break; 281 break;
267 282
268 case PLAYER: 283 case PLAYER:
269 sv = newSVptr_cached (obj, "cf::object::player::wrap"); 284 obj->self = static_cast<void *>(newSVptr (obj, "cf::object::player::wrap"));
270 break; 285 break;
271 286
272 default: 287 default:
273 sv = newSVptr_cached (obj, "cf::object::wrap"); 288 obj->self = static_cast<void *>(newSVptr (obj, "cf::object::wrap"));
274 break; 289 break;
290 }
291
292 sv = newSVsv (static_cast<SV *>(obj->self));
275 } 293 }
276 } 294 }
277 break; 295 break;
278 296
279 case CFAPI_PMAP: 297 case DT_MAP:
280 sv = newSVptr (va_arg (args, mapstruct *), "cf::map::wrap"); 298 sv = newSVptr (va_arg (ap, mapstruct *), "cf::map::wrap");
281 break; 299 break;
282 300
283 case CFAPI_PPLAYER: 301 case DT_PLAYER:
284 sv = newSVptr (va_arg (args, player *), "cf::player::wrap"); 302 sv = newSVptr (va_arg (ap, player *), "cf::player::wrap");
285 break; 303 break;
286 304
287 case CFAPI_PARCH: 305 case DT_ARCH:
288 sv = newSVptr (va_arg (args, archetype *), "cf::arch::wrap"); 306 sv = newSVptr (va_arg (ap, archetype *), "cf::arch::wrap");
289 break; 307 break;
290 308
291 case CFAPI_PPARTY: 309 case DT_PARTY:
292 sv = newSVptr (va_arg (args, partylist *), "cf::party::wrap"); 310 sv = newSVptr (va_arg (ap, partylist *), "cf::party::wrap");
293 break; 311 break;
294 312
295 case CFAPI_PREGION: 313 case DT_REGION:
296 sv = newSVptr (va_arg (args, region *), "cf::region::wrap"); 314 sv = newSVptr (va_arg (ap, region *), "cf::region::wrap");
297 break; 315 break;
316
317 default:
318 assert (("unhandled type in newSVdt_va", 0));
319 }
320
321 return sv;
322}
323
324static SV *
325newSVdt (data_type type, ...)
326{
327 va_list ap;
328
329 va_start (ap, type);
330 SV *sv = newSVdt_va (ap, type);
331 va_end (ap);
332
333 return sv;
334}
335
336static SV *
337newSVcfapi (int type, ...)
338{
339 SV *sv;
340
341 va_list ap;
342 va_start (ap, type);
343
344 switch (type)
345 {
346 case CFAPI_INT: sv = newSVdt_va (ap, DT_INT_PTR ); break;
347 case CFAPI_LONG: sv = newSVdt_va (ap, DT_INT64_PTR ); break;
348 case CFAPI_DOUBLE: sv = newSVdt_va (ap, DT_DOUBLE_PTR); break;
349 case CFAPI_STRING: sv = newSVdt_va (ap, DT_STRING); break;
350 case CFAPI_POBJECT: sv = newSVdt_va (ap, DT_OBJECT); break;
351 case CFAPI_PMAP: sv = newSVdt_va (ap, DT_MAP ); break;
352 case CFAPI_PPLAYER: sv = newSVdt_va (ap, DT_PLAYER); break;
353 case CFAPI_PARCH: sv = newSVdt_va (ap, DT_ARCH ); break;
354 case CFAPI_PPARTY: sv = newSVdt_va (ap, DT_PARTY ); break;
355 case CFAPI_PREGION: sv = newSVdt_va (ap, DT_REGION); break;
298 356
299 default: 357 default:
300 assert (("unhandled type in newSVcfapi", 0)); 358 assert (("unhandled type in newSVcfapi", 0));
301 } 359 }
302 360
303 va_end (args); 361 va_end (ap);
304 362
305 return sv; 363 return sv;
306} 364}
307 365
308///////////////////////////////////////////////////////////////////////////// 366/////////////////////////////////////////////////////////////////////////////
411 object_insert = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_object_insert"); 469 object_insert = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_object_insert");
412 470
413 cf_init_plugin (gethook); 471 cf_init_plugin (gethook);
414 472
415 /* Pick the global events you want to monitor from this plugin */ 473 /* Pick the global events you want to monitor from this plugin */
416 registerGlobalEvent (NULL, EVENT_BORN, PLUGIN_NAME, globalEventListener);
417 registerGlobalEvent (NULL, EVENT_CLOCK, PLUGIN_NAME, globalEventListener); 474 registerGlobalEvent (NULL, EVENT_CLOCK, PLUGIN_NAME, globalEventListener);
418 //registerGlobalEvent (NULL, EVENT_CRASH, PLUGIN_NAME, globalEventListener); 475 //registerGlobalEvent (NULL, EVENT_CRASH, PLUGIN_NAME, globalEventListener);
419 registerGlobalEvent (NULL, EVENT_FIND_UNARMED_SKILL, PLUGIN_NAME, globalEventListener); 476 registerGlobalEvent (NULL, EVENT_FIND_UNARMED_SKILL, PLUGIN_NAME, globalEventListener);
420 registerGlobalEvent (NULL, EVENT_PLAYER_USE_SKILL, PLUGIN_NAME, globalEventListener);
421 registerGlobalEvent (NULL, EVENT_CAST_SPELL, PLUGIN_NAME, globalEventListener);
422 registerGlobalEvent (NULL, EVENT_MONSTER_USE_SKILL, PLUGIN_NAME, globalEventListener);
423 registerGlobalEvent (NULL, EVENT_PLAYER_DEATH, PLUGIN_NAME, globalEventListener);
424 registerGlobalEvent (NULL, EVENT_GKILL, PLUGIN_NAME, globalEventListener);
425 registerGlobalEvent (NULL, EVENT_LOGIN, PLUGIN_NAME, globalEventListener);
426 registerGlobalEvent (NULL, EVENT_LOGOUT, PLUGIN_NAME, globalEventListener);
427 registerGlobalEvent (NULL, EVENT_MAPENTER, PLUGIN_NAME, globalEventListener);
428 registerGlobalEvent (NULL, EVENT_MAPLEAVE, PLUGIN_NAME, globalEventListener);
429 registerGlobalEvent (NULL, EVENT_MAPRESET, PLUGIN_NAME, globalEventListener);
430 registerGlobalEvent (NULL, EVENT_MAPLOAD, PLUGIN_NAME, globalEventListener);
431 registerGlobalEvent (NULL, EVENT_MAPOUT, PLUGIN_NAME, globalEventListener);
432 registerGlobalEvent (NULL, EVENT_MAPIN, PLUGIN_NAME, globalEventListener);
433 registerGlobalEvent (NULL, EVENT_MAPCLEAN, PLUGIN_NAME, globalEventListener);
434 registerGlobalEvent (NULL, EVENT_REMOVE, PLUGIN_NAME, globalEventListener);
435 registerGlobalEvent (NULL, EVENT_SHOUT, PLUGIN_NAME, globalEventListener); 477 registerGlobalEvent (NULL, EVENT_SHOUT, PLUGIN_NAME, globalEventListener);
436 registerGlobalEvent (NULL, EVENT_TELL, PLUGIN_NAME, globalEventListener); 478 registerGlobalEvent (NULL, EVENT_TELL, PLUGIN_NAME, globalEventListener);
437 registerGlobalEvent (NULL, EVENT_MUZZLE, PLUGIN_NAME, globalEventListener); 479 registerGlobalEvent (NULL, EVENT_MUZZLE, PLUGIN_NAME, globalEventListener);
438 registerGlobalEvent (NULL, EVENT_KICK, PLUGIN_NAME, globalEventListener); 480 registerGlobalEvent (NULL, EVENT_KICK, PLUGIN_NAME, globalEventListener);
439 registerGlobalEvent (NULL, EVENT_FREE_OB, PLUGIN_NAME, globalEventListener);
440 registerGlobalEvent (NULL, EVENT_PLAYER_LOAD, PLUGIN_NAME, globalEventListener);
441 registerGlobalEvent (NULL, EVENT_PLAYER_SAVE, PLUGIN_NAME, globalEventListener);
442 registerGlobalEvent (NULL, EVENT_EXTCMD, PLUGIN_NAME, globalEventListener);
443
444 char *argv[] = {
445 "",
446 "-e"
447 "BEGIN {"
448 " cf->bootstrap;"
449 " unshift @INC, cf::datadir ();"
450 "}"
451 ""
452 "use cf;"
453 };
454
455 perl = perl_alloc ();
456 perl_construct (perl);
457
458 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
459
460 if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl))
461 {
462 printf ("unable to initialize perl-interpreter, continuing without.\n");
463
464 perl_destruct (perl);
465 perl_free (perl);
466 perl = 0;
467 }
468 else
469 {
470 obj_cache = newHV ();
471 }
472 481
473 return 0; 482 return 0;
474} 483}
475 484
476static void * 485static void *
484 return NULL; 493 return NULL;
485 494
486 va_start (args, type); 495 va_start (args, type);
487 event_code = va_arg (args, int); 496 event_code = va_arg (args, int);
488 497
489 if (event_code == EVENT_FREE_OB)
490 {
491 player *pl;
492 object *op;
493 SV *sv;
494
495 op = va_arg (args, object *);
496 sv = hv_delete (obj_cache, (char *)&op, sizeof (void *), 0);
497
498 if (sv)
499 clearSVptr (sv);
500
501 rv = 0;
502 }
503 else if (event_code == EVENT_CLOCK) 498 if (event_code == EVENT_CLOCK)
504 { 499 {
505 clean_obj_cache (); 500 clean_obj_cache ();
506 } 501 }
507 else 502 else
508 { 503 {
519 switch (event_code) 514 switch (event_code)
520 { 515 {
521 case EVENT_CRASH: 516 case EVENT_CRASH:
522 break; 517 break;
523 518
524 case EVENT_PLAYER_LOAD:
525 case EVENT_PLAYER_SAVE:
526 PUSH_OB;
527 PUSH_PV;
528 break;
529
530 case EVENT_MAPLOAD:
531 case EVENT_MAPOUT:
532 case EVENT_MAPIN:
533 case EVENT_MAPCLEAN:
534 case EVENT_MAPRESET:
535 PUSH_MAP;
536 break;
537
538 case EVENT_MAPENTER:
539 case EVENT_MAPLEAVE:
540 case EVENT_BORN:
541 case EVENT_REMOVE:
542 case EVENT_PLAYER_DEATH:
543 PUSH_OB;
544 break;
545
546 case EVENT_GKILL:
547 PUSH_OB;
548 PUSH_OB;
549 break;
550
551 case EVENT_LOGIN:
552 case EVENT_LOGOUT:
553 PUSH_PL;
554 PUSH_PV;
555 break;
556
557 case EVENT_SHOUT: 519 case EVENT_SHOUT:
558 case EVENT_MUZZLE: 520 case EVENT_MUZZLE:
559 case EVENT_KICK: 521 case EVENT_KICK:
560 PUSH_OB; 522 PUSH_OB;
561 PUSH_PV; 523 PUSH_PV;
562 break; 524 break;
563 525
564 case EVENT_FIND_UNARMED_SKILL: 526 case EVENT_FIND_UNARMED_SKILL:
565 PUSH_OB; 527 PUSH_OB;
566 break;
567
568 case EVENT_PLAYER_USE_SKILL:
569 case EVENT_MONSTER_USE_SKILL:
570 case EVENT_CAST_SPELL:
571 PUSH_OB;
572 PUSH_OB;
573 PUSH_OB;
574 PUSH_IV;
575 PUSH_PV;
576 break;
577
578 case EVENT_EXTCMD:
579 PUSH_PL;
580 {
581 char *buf = va_arg (args, char *);
582 int len = va_arg (args, int);
583 PUSHs (sv_2mortal (newSVpvn (buf, len)));
584 }
585 break; 528 break;
586 529
587 case EVENT_TELL: 530 case EVENT_TELL:
588 break; 531 break;
589 } 532 }
653 break; 596 break;
654 597
655 case EVENT_APPLY: // $ob, $who 598 case EVENT_APPLY: // $ob, $who
656 case EVENT_DROP: // $ob, $who 599 case EVENT_DROP: // $ob, $who
657 case EVENT_CLOSE: // $ob, $who 600 case EVENT_CLOSE: // $ob, $who
658 case EVENT_DEATH: // $ob[, $killer]
659 case EVENT_MOVE: // $ob, $enemy 601 case EVENT_MOVE: // $ob, $enemy
660 case EVENT_THROW: // $ob, $thrower 602 case EVENT_THROW: // $ob, $thrower
661 PUSHcfapi (POBJECT, activator); 603 PUSHcfapi (POBJECT, activator);
662 break; 604 break;
663 605
700 return &rv; 642 return &rv;
701} 643}
702 644
703extern "C" int cfperl_closePlugin () 645extern "C" int cfperl_closePlugin ()
704{ 646{
705 printf (PLUGIN_VERSION " closing\n"); 647 return 0;
648}
706 649
707 if (perl) 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))
708 { 670 {
671 printf ("unable to initialize perl-interpreter, aborting.\n");
672
673 exit (EXIT_FAILURE);
709 perl_destruct (perl); 674 //perl_destruct (perl);
710 perl_free (perl); 675 //perl_free (perl);
711 perl = 0; 676 //perl = 0;
677 //return;
712 } 678 }
713 679
680 obj_cache = newHV ();
681}
682
683void cfperl_main ()
684{
685 dSP;
686
687 PUSHMARK (SP);
688 PUTBACK;
689 call_pv ("cf::main", G_DISCARD | G_VOID);
690}
691
692void cfperl_free_ob (object *op)
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)
714 return 0; 802 return 0;
715}
716 803
717void cfperl_sleep (double delta)
718{
719 dSP; 804 dSP;
720 ENTER; 805 ENTER;
721 SAVETMPS; 806 SAVETMPS;
722 807
723 PUSHMARK (SP); 808 PUSHMARK (SP);
809 EXTEND (SP, 3);
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 }
820
821 for (;;)
822 {
823 dt = (data_type) va_arg (ap, int);
824
825 if (dt == DT_END)
826 break;
827
724 XPUSHs (sv_2mortal (newSVnv (delta))); 828 XPUSHs (sv_2mortal (newSVdt_va (ap, dt)));
829 }
830
831 va_end (ap);
832
725 PUTBACK; 833 PUTBACK;
726 call_pv ("cf::sleep_delta", G_DISCARD | G_VOID | G_EVAL); 834 int count = call_pv ("cf::invoke", G_SCALAR | G_EVAL);
727 SPAGAIN; 835 SPAGAIN;
836
837 count = count > 0 ? POPi : 0;
728 838
729 FREETMPS; 839 FREETMPS;
730 LEAVE; 840 LEAVE;
841
842 return count;
731} 843}
732 844
733MODULE = cf PACKAGE = cf PREFIX = cf_ 845MODULE = cf PACKAGE = cf PREFIX = cf_
734 846
735BOOT: 847BOOT:
744 const_iv (llevError) 856 const_iv (llevError)
745 const_iv (llevInfo) 857 const_iv (llevInfo)
746 const_iv (llevDebug) 858 const_iv (llevDebug)
747 const_iv (llevMonster) 859 const_iv (llevMonster)
748 860
861 const_iv (MAX_TIME)
749 const_iv (PLAYER) 862 const_iv (PLAYER)
750 const_iv (TRANSPORT) 863 const_iv (TRANSPORT)
751 const_iv (ROD) 864 const_iv (ROD)
752 const_iv (TREASURE) 865 const_iv (TREASURE)
753 const_iv (POTION) 866 const_iv (POTION)
1213 1326
1214 const_iv (MAP_IN_MEMORY) 1327 const_iv (MAP_IN_MEMORY)
1215 const_iv (MAP_SWAPPED) 1328 const_iv (MAP_SWAPPED)
1216 const_iv (MAP_LOADING) 1329 const_iv (MAP_LOADING)
1217 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)
1218 }; 1336 };
1219 1337
1220 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; )
1221 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); 1339 newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv));
1340
1341 static const struct {
1342 const char *name;
1343 IV klass;
1344 IV iv;
1345 } *eiv, event_iv[] = {
1346# define def(klass,name) { # name, (IV)KLASS_ ## klass, (IV)EV_ ## klass ## _ ## name },
1347# include "eventinc.h"
1348# undef def
1349 };
1350
1351 AV *av = get_av ("cf::EVENT", 1);
1352
1353 for (eiv = event_iv + sizeof (event_iv) / sizeof (event_iv [0]); eiv-- > event_iv; )
1354 {
1355 AV *event = newAV ();
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 }
1222 1360
1223 static const struct { 1361 static const struct {
1224 const char *name; 1362 const char *name;
1225 IV iv; 1363 IV iv;
1226 } *event, event_list[] = { 1364 } *event, event_list[] = {
1227# define const_event(name) { # name, (IV)EVENT_ ## name }, 1365# define const_event(name) { # name, (IV)EVENT_ ## name },
1228 const_event (NONE) 1366 const_event (NONE)
1229 const_event (APPLY) 1367 const_event (APPLY)
1230 const_event (ATTACK) 1368 const_event (ATTACK)
1231 const_event (DEATH)
1232 const_event (DROP) 1369 const_event (DROP)
1233 const_event (DROP_ON) 1370 const_event (DROP_ON)
1234 const_event (PICKUP) 1371 const_event (PICKUP)
1235 const_event (SAY) 1372 const_event (SAY)
1236 const_event (STOP) 1373 const_event (STOP)
1239 const_event (TRIGGER) 1376 const_event (TRIGGER)
1240 const_event (CLOSE) 1377 const_event (CLOSE)
1241 const_event (TIMER) 1378 const_event (TIMER)
1242 const_event (MOVE) 1379 const_event (MOVE)
1243 1380
1244 const_event (BORN)
1245 //const_event (CLOCK) 1381 //const_event (CLOCK)
1246 const_event (CRASH) 1382 const_event (CRASH)
1247 const_event (PLAYER_DEATH)
1248 const_event (PLAYER_LOAD)
1249 const_event (PLAYER_SAVE)
1250 const_event (GKILL)
1251 const_event (LOGIN)
1252 const_event (LOGOUT)
1253 const_event (MAPENTER)
1254 const_event (MAPLEAVE)
1255 const_event (MAPRESET)
1256 const_event (MAPLOAD)
1257 const_event (MAPOUT)
1258 const_event (MAPIN)
1259 const_event (MAPCLEAN)
1260 const_event (REMOVE)
1261 const_event (SHOUT) 1383 const_event (SHOUT)
1262 const_event (TELL) 1384 const_event (TELL)
1263 const_event (MUZZLE) 1385 const_event (MUZZLE)
1264 const_event (KICK) 1386 const_event (KICK)
1265 const_event (PLAYER_USE_SKILL)
1266 const_event (MONSTER_USE_SKILL)
1267 const_event (CAST_SPELL)
1268 const_event (FIND_UNARMED_SKILL) 1387 const_event (FIND_UNARMED_SKILL)
1269 const_event (EXTCMD)
1270 //const_event (FREE_OB) 1388 //const_event (FREE_OB)
1271 }; 1389 };
1272 1390
1273 AV *av = get_av ("cf::EVENT", 1); 1391 av = get_av ("cf::PLUGIN_EVENT", 1);
1274 1392
1275 for (event = event_list + sizeof (event_list) / sizeof (event_list [0]); event-- > event_list; ) 1393 for (event = event_list + sizeof (event_list) / sizeof (event_list [0]); event-- > event_list; )
1276 av_store (av, event->iv, newSVpv ((char *)event->name, 0)); 1394 av_store (av, event->iv, newSVpv ((char *)event->name, 0));
1277 1395
1278 static const struct { 1396 static const struct {
1409 { 1527 {
1410 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);
1411 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);
1412 } 1530 }
1413 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
1414 //I_EVENT_API (PACKAGE); 1538 //I_EVENT_API (PACKAGE);
1415} 1539}
1416 1540
1417NV floor (NV x) 1541NV floor (NV x)
1418 1542
1419NV ceil (NV x) 1543NV ceil (NV x)
1544
1545void server_tick ()
1420 1546
1421void 1547void
1422LOG (int level, char *msg) 1548LOG (int level, char *msg)
1423 PROTOTYPE: $$ 1549 PROTOTYPE: $$
1424 C_ARGS: (LogLevel)level, "%s", msg 1550 C_ARGS: (LogLevel)level, "%s", msg
1828 1954
1829char * 1955char *
1830client (player *pl) 1956client (player *pl)
1831 CODE: 1957 CODE:
1832 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;
1833 OUTPUT: 1975 OUTPUT:
1834 RETVAL 1976 RETVAL
1835 1977
1836void 1978void
1837buggy_mapscroll (player *pl, int value = 1) 1979buggy_mapscroll (player *pl, int value = 1)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines