ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
Revision: 1.151
Committed: Tue Jan 23 01:29:51 2007 UTC (17 years, 4 months ago) by root
Branch: MAIN
Changes since 1.150: +2 -1 lines
Log Message:
re-enabled memleka, server crashes without it

File Contents

# User Rev Content
1 root 1.1 /*****************************************************************************/
2     /* CrossFire, A Multiplayer game for the X Window System */
3     /*****************************************************************************/
4    
5     /*
6     * This code is placed under the GNU General Public Licence (GPL)
7     *
8     * Copyright (C) 2001-2005 by Chachkoff Yann
9 root 1.49 * Copyright (C) 2006 by Marc Lehmann <cf@schmorp.de>
10 root 1.1 *
11     * This program is free software; you can redistribute it and/or modify
12     * it under the terms of the GNU General Public License as published by
13     * the Free Software Foundation; either version 2 of the License, or
14     * (at your option) any later version.
15     *
16     * This program is distributed in the hope that it will be useful,
17     * but WITHOUT ANY WARRANTY; without even the implied warranty of
18     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19     * GNU General Public License for more details.
20     *
21     * You should have received a copy of the GNU General Public License
22     * along with this program; if not, write to the Free Software
23     * Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 root 1.106 */
25 root 1.1
26     #define PLUGIN_NAME "perl"
27 root 1.13 #define PLUGIN_VERSION "cfperl 0.5"
28 root 1.1
29     #include <plugin_common.h>
30     #include <sounds.h>
31 root 1.6 #include <cstdarg>
32     #include <sproto.h>
33 root 1.1
34 root 1.6 #include "cfperl.h"
35 root 1.12 #include "shstr.h"
36 root 1.1
37 root 1.125 #include <unistd.h>
38     #if _POSIX_MEMLOCK
39     # include <sys/mman.h>
40     #endif
41    
42 root 1.32 #include <EXTERN.h>
43     #include <perl.h>
44     #include <XSUB.h>
45    
46 root 1.107 #include "CoroAPI.h"
47 root 1.1 #include "perlxsi.c"
48    
49     extern sint64 *levels; // the experience table
50    
51 root 1.61 typedef object object_ornull;
52     typedef maptile maptile_ornull;
53 root 1.1
54 root 1.71 #if IVSIZE >= 8
55     typedef IV val64;
56     # define newSVval64 newSViv
57     # define SvVAL64 SvIV
58     #else
59     typedef double val64;
60     # define newSVval64 newSVnv
61     # define SvVAL64 SvNV
62     #endif
63 root 1.1
64 root 1.19 static f_plug_api gethook = cfapi_get_hooks;
65     static f_plug_api object_set_property = cfapi_object_set_property;
66     static f_plug_api object_insert = cfapi_object_insert;
67 root 1.1
68     static PerlInterpreter *perl;
69    
70 root 1.116 double runtime;
71    
72 root 1.109 global gbl_ev;
73     static AV *cb_global, *cb_attachable, *cb_object, *cb_player, *cb_client, *cb_type, *cb_map;
74 root 1.116 static SV *sv_runtime;
75 root 1.109
76     static HV
77     *stash_cf,
78     *stash_cf_object_wrap,
79     *stash_cf_object_player_wrap,
80     *stash_cf_player_wrap,
81     *stash_cf_map_wrap,
82     *stash_cf_client_wrap,
83     *stash_cf_arch_wrap,
84     *stash_cf_party_wrap,
85     *stash_cf_region_wrap,
86     *stash_cf_living_wrap;
87    
88     // helper cast function, returns super class * or 0
89     template<class super>
90     static super *
91     is_a (attachable *at)
92     {
93     //return dynamic_cast<super *>(at); // slower, safer
94     if (typeid (*at) == typeid (super))
95     return static_cast<super *>(at);
96     else
97     return 0;
98     }
99    
100     //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
101    
102     unordered_vector<attachable *> attachable::mortals;
103    
104 root 1.129 attachable::~attachable ()
105 root 1.109 {
106 root 1.133 assert (!self);
107 root 1.109 }
108    
109 root 1.130 int
110     attachable::refcnt_cnt () const
111     {
112     return refcnt + (self ? SvREFCNT (self) : 0);
113     }
114    
115     void
116     attachable::optimise ()
117 root 1.109 {
118 root 1.129 if (self
119     && SvREFCNT (self) == 1
120     && !HvTOTALKEYS (self))
121     {
122     refcnt_inc ();
123     SvREFCNT_dec ((SV *)self);
124     }
125 root 1.109 }
126    
127     // check wether the object really is dead
128     void
129     attachable::do_check ()
130     {
131 root 1.133 if (refcnt > 0 || refcnt_cnt () > 0)
132 root 1.109 return;
133    
134 root 1.133 destroy ();
135 root 1.129
136     if (self)
137 root 1.109 {
138 root 1.133 hv_clear (self);
139     sv_unmagic ((SV *)self, PERL_MAGIC_ext);
140     SvREFCNT_dec (self);
141     self = 0;
142 root 1.109 }
143     }
144    
145     void
146     attachable::do_destroy ()
147     {
148     invoke (EVENT_ATTACHABLE_DESTROY, DT_END);
149    
150 root 1.127 if (self)
151     hv_clear (self);
152    
153 root 1.109 mortals.push_back (this);
154     }
155    
156     void
157     attachable::destroy ()
158     {
159     if (destroyed ())
160     return;
161    
162     flags |= F_DESTROYED;
163     do_destroy ();
164     }
165    
166 root 1.130 void
167     attachable::check_mortals ()
168 root 1.109 {
169 root 1.150 static int i = 0;
170    
171     for (;;)
172 root 1.109 {
173 root 1.150 if (i >= mortals.size ())
174     {
175     i = 0;
176    
177     if (mortals.size () > 1000)
178     fprintf (stderr, "mortal queue size (%d) exceeds 1000.\n", mortals.size ());
179    
180     break;
181     }
182    
183 root 1.109 attachable *obj = mortals [i];
184    
185     obj->refcnt_chk (); // unborrow from perl, if necessary
186    
187 root 1.151 //if (obj->refcnt > 0 || obj->self)
188     if (obj->refcnt || obj->self)
189 root 1.109 {
190 root 1.150 //printf ("%p rc %d\n", obj, obj->refcnt_cnt ());//D
191     ++i; // further delay freeing
192 root 1.109
193 root 1.150 if (!(i & 0x3ff))
194     break;
195     }
196 root 1.109 else
197     {
198 root 1.112 mortals.erase (i);
199 root 1.109 delete obj;
200     }
201     }
202     }
203    
204     attachable &
205     attachable::operator =(const attachable &src)
206     {
207     //if (self || cb)
208     //INVOKE_OBJECT (CLONE, this, ARG_OBJECT (dst));
209    
210     attach = src.attach;
211     return *this;
212     }
213 root 1.8
214 root 1.1 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
215    
216     static SV *
217 root 1.109 newSVptr (void *ptr, HV *stash, HV *hv = newHV ())
218 root 1.1 {
219     SV *sv;
220    
221     if (!ptr)
222     return &PL_sv_undef;
223    
224 root 1.109 sv_magicext ((SV *)hv, 0, PERL_MAGIC_ext, 0, (char *)ptr, 0);
225     return sv_bless (newRV_noinc ((SV *)hv), stash);
226     }
227    
228     static int
229     attachable_free (pTHX_ SV *sv, MAGIC *mg)
230     {
231     attachable *at = (attachable *)mg->mg_ptr;
232     at->self = 0;
233 root 1.111 // next line makes sense, but most objects still have refcnt 0 by default
234     //at->refcnt_chk ();
235 root 1.109 return 0;
236 root 1.1 }
237    
238 root 1.116 MGVTBL attachable::vtbl = {0, 0, 0, 0, attachable_free};
239 root 1.109
240 root 1.116 static SV *
241 root 1.109 newSVattachable (attachable *obj, HV *stash)
242 root 1.11 {
243     if (!obj)
244     return &PL_sv_undef;
245    
246     if (!obj->self)
247 root 1.109 {
248     obj->self = newHV ();
249 root 1.116 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0);
250 root 1.11
251 root 1.109 // borrow the refcnt from the object
252 root 1.133 // it is important thta no refcnt_chk is being executed here
253 root 1.109 obj->refcnt_dec ();
254 root 1.129
255     // now bless the object _once_
256     return sv_bless (newRV_inc ((SV *)obj->self), stash);
257 root 1.109 }
258 root 1.129 else
259 root 1.140 {
260     SV *sv = newRV_inc ((SV *)obj->self);
261    
262     if (Gv_AMG (stash)) // handle overload correctly, as the perl core does not
263     SvAMAGIC_on (sv);
264    
265     return sv;
266     }
267 root 1.11 }
268    
269 root 1.1 static void
270     clearSVptr (SV *sv)
271     {
272     if (SvROK (sv))
273     sv = SvRV (sv);
274    
275     hv_clear ((HV *)sv);
276     sv_unmagic (sv, PERL_MAGIC_ext);
277     }
278    
279     static long
280     SvPTR (SV *sv, const char *klass)
281     {
282     if (!sv_derived_from (sv, klass))
283     croak ("object of type %s expected", klass);
284    
285     MAGIC *mg = mg_find (SvRV (sv), PERL_MAGIC_ext);
286    
287     if (!mg)
288     croak ("perl code used %s object, but C object is already destroyed, caught", klass);
289    
290     return (long)mg->mg_ptr;
291     }
292    
293     static long
294     SvPTR_ornull (SV *sv, const char *klass)
295     {
296     if (SvOK (sv))
297     return SvPTR (sv, klass);
298     else
299     return 0;
300     }
301    
302 root 1.45 inline SV *to_sv (const shstr & v) { return v ? newSVpvn ((const char *)v, v.length ()) : &PL_sv_undef; }
303     inline SV *to_sv (const char * v) { return newSVpv (v, 0); }
304     inline SV *to_sv (bool v) { return newSViv (v); }
305     inline SV *to_sv ( signed char v) { return newSViv (v); }
306     inline SV *to_sv (unsigned char v) { return newSViv (v); }
307     inline SV *to_sv ( signed short v) { return newSViv (v); }
308     inline SV *to_sv (unsigned short v) { return newSVuv (v); }
309     inline SV *to_sv ( signed int v) { return newSViv (v); }
310     inline SV *to_sv (unsigned int v) { return newSVuv (v); }
311     inline SV *to_sv ( signed long v) { return newSViv (v); }
312     inline SV *to_sv (unsigned long v) { return newSVuv (v); }
313 root 1.48 inline SV *to_sv ( signed long long v) { return newSVval64 (v); }
314     inline SV *to_sv (unsigned long long v) { return newSVval64 (v); }
315 root 1.45 inline SV *to_sv (float v) { return newSVnv (v); }
316     inline SV *to_sv (double v) { return newSVnv (v); }
317 root 1.109 inline SV *to_sv (client * v) { return newSVattachable (v, stash_cf_client_wrap); }
318     inline SV *to_sv (player * v) { return newSVattachable (v, stash_cf_player_wrap); }
319     inline SV *to_sv (object * v) { return newSVattachable (v, v && v->type == PLAYER ? stash_cf_object_player_wrap : stash_cf_object_wrap); }
320     inline SV *to_sv (maptile * v) { return newSVattachable (v, stash_cf_map_wrap); }
321     inline SV *to_sv (archetype * v) { return newSVattachable (v, stash_cf_arch_wrap); }
322     inline SV *to_sv (partylist * v) { return newSVptr (v, stash_cf_party_wrap); }
323     inline SV *to_sv (region * v) { return newSVptr (v, stash_cf_region_wrap); }
324     inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); }
325 root 1.45
326     inline SV *to_sv (object & v) { return to_sv (&v); }
327     inline SV *to_sv (living & v) { return to_sv (&v); }
328    
329 root 1.145 inline SV *to_sv (facetile * v) { return to_sv (v->name); }
330 root 1.45 inline SV *to_sv (treasurelist * v) { return to_sv (v->name); }
331    
332 root 1.69 inline SV *to_sv (UUID v)
333     {
334 elmex 1.68 char buf[128];
335 root 1.71 snprintf (buf, 128, "<1,%" PRIx64 ">", v.seq);
336 elmex 1.68 return newSVpv (buf, 0);
337     }
338    
339 root 1.58 inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; }
340 root 1.72 inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; }
341 root 1.45 inline void sv_to (SV *sv, bool &v) { v = SvIV (sv); }
342     inline void sv_to (SV *sv, signed char &v) { v = SvIV (sv); }
343     inline void sv_to (SV *sv, unsigned char &v) { v = SvIV (sv); }
344     inline void sv_to (SV *sv, signed short &v) { v = SvIV (sv); }
345     inline void sv_to (SV *sv, unsigned short &v) { v = SvIV (sv); }
346     inline void sv_to (SV *sv, signed int &v) { v = SvIV (sv); }
347     inline void sv_to (SV *sv, unsigned int &v) { v = SvUV (sv); }
348     inline void sv_to (SV *sv, signed long &v) { v = SvIV (sv); }
349     inline void sv_to (SV *sv, unsigned long &v) { v = SvUV (sv); }
350 root 1.53 inline void sv_to (SV *sv, signed long long &v) { v = ( signed long long)SvVAL64 (sv); }
351     inline void sv_to (SV *sv, unsigned long long &v) { v = (unsigned long long)SvVAL64 (sv); }
352 root 1.45 inline void sv_to (SV *sv, float &v) { v = SvNV (sv); }
353     inline void sv_to (SV *sv, double &v) { v = SvNV (sv); }
354 root 1.115 inline void sv_to (SV *sv, client * &v) { v = (client *)(attachable *)SvPTR_ornull (sv, "cf::client"); }
355     inline void sv_to (SV *sv, player * &v) { v = (player *)(attachable *)SvPTR_ornull (sv, "cf::player"); }
356     inline void sv_to (SV *sv, object * &v) { v = (object *)(attachable *)SvPTR_ornull (sv, "cf::object"); }
357     inline void sv_to (SV *sv, archetype * &v) { v = (archetype *)(attachable *)SvPTR_ornull (sv, "cf::arch"); }
358     inline void sv_to (SV *sv, maptile * &v) { v = (maptile *)(attachable *)SvPTR_ornull (sv, "cf::map"); }
359 root 1.128 inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); }
360 root 1.45 inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); }
361     inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); }
362     inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); }
363    
364 root 1.145 inline void sv_to (SV *sv, facetile * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; }
365 root 1.136 inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); }
366 root 1.45
367 root 1.52 template<class T>
368     inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; }
369    
370 root 1.45 template<int N>
371 root 1.55 inline void sv_to (SV *sv, char (&v)[N]) { assign (v, SvPV_nolen (sv)); }
372 root 1.45
373 root 1.106 inline void sv_to (SV *sv, rangetype &v) { v = (rangetype) SvIV (sv); }
374     inline void sv_to (SV *sv, bowtype_t &v) { v = (bowtype_t) SvIV (sv); }
375     inline void sv_to (SV *sv, petmode_t &v) { v = (petmode_t) SvIV (sv); }
376     inline void sv_to (SV *sv, usekeytype &v) { v = (usekeytype) SvIV (sv); }
377     inline void sv_to (SV *sv, unapplymode &v) { v = (unapplymode) SvIV (sv); }
378    
379 root 1.69 inline void sv_to (SV *sv, UUID &v)
380     {
381     unsigned int version;
382 elmex 1.68
383 root 1.71 if (2 != sscanf (SvPV_nolen (sv), "<%d.%" SCNx64 ">", &version, &v.seq) || 1 != version)
384 root 1.69 croak ("unparsable uuid: %s", SvPV_nolen (sv));
385 elmex 1.68 }
386    
387 root 1.109 inline void sv_to (SV *sv, object::flags_t::reference v) { v = SvTRUE (sv); }
388 root 1.106
389 root 1.1 static SV *
390 root 1.6 newSVdt_va (va_list &ap, data_type type)
391 root 1.1 {
392     SV *sv;
393    
394     switch (type)
395     {
396 root 1.10 case DT_INT:
397     sv = newSViv (va_arg (ap, int));
398     break;
399    
400     case DT_INT64:
401     sv = newSVval64 ((val64)va_arg (ap, sint64));
402     break;
403    
404 root 1.6 case DT_DOUBLE:
405 root 1.10 sv = newSVnv (va_arg (ap, double));
406 root 1.1 break;
407    
408 root 1.6 case DT_STRING:
409     {
410 root 1.10 char *str = (char *)va_arg (ap, const char *);
411 root 1.6 sv = str ? newSVpv (str, 0) : &PL_sv_undef;
412     }
413 root 1.1 break;
414    
415 root 1.6 case DT_DATA:
416 root 1.1 {
417 root 1.10 char *str = (char *)va_arg (ap, const void *);
418 root 1.6 int len = va_arg (ap, int);
419     sv = str ? newSVpv (str, len) : &PL_sv_undef;
420 root 1.1 }
421     break;
422    
423 root 1.6 case DT_OBJECT:
424 root 1.45 sv = to_sv (va_arg (ap, object *));
425 root 1.1 break;
426    
427 root 1.6 case DT_MAP:
428 root 1.11 // va_arg (object *) when void * is passed is an XSI extension
429 root 1.61 sv = to_sv (va_arg (ap, maptile *));
430 root 1.1 break;
431    
432 root 1.88 case DT_CLIENT:
433 root 1.84 sv = to_sv (va_arg (ap, client *));
434 root 1.79 break;
435    
436 root 1.6 case DT_PLAYER:
437 root 1.45 sv = to_sv (va_arg (ap, player *));
438 root 1.1 break;
439    
440 root 1.6 case DT_ARCH:
441 root 1.45 sv = to_sv (va_arg (ap, archetype *));
442 root 1.1 break;
443    
444 root 1.6 case DT_PARTY:
445 root 1.45 sv = to_sv (va_arg (ap, partylist *));
446 root 1.1 break;
447    
448 root 1.6 case DT_REGION:
449 root 1.45 sv = to_sv (va_arg (ap, region *));
450 root 1.1 break;
451    
452     default:
453 root 1.6 assert (("unhandled type in newSVdt_va", 0));
454     }
455    
456     return sv;
457     }
458    
459     static SV *
460     newSVdt (data_type type, ...)
461     {
462     va_list ap;
463    
464     va_start (ap, type);
465     SV *sv = newSVdt_va (ap, type);
466     va_end (ap);
467    
468     return sv;
469     }
470    
471     static SV *
472     newSVcfapi (int type, ...)
473     {
474     SV *sv;
475    
476     va_list ap;
477     va_start (ap, type);
478    
479     switch (type)
480     {
481 root 1.12 case CFAPI_INT: sv = newSViv (*va_arg (ap, int * )); break;
482     case CFAPI_LONG: sv = newSVval64 (*va_arg (ap, sint64 *)); break;
483     case CFAPI_DOUBLE: sv = newSVnv (*va_arg (ap, double *)); break;
484 root 1.6 case CFAPI_STRING: sv = newSVdt_va (ap, DT_STRING); break;
485     case CFAPI_POBJECT: sv = newSVdt_va (ap, DT_OBJECT); break;
486     case CFAPI_PMAP: sv = newSVdt_va (ap, DT_MAP ); break;
487     case CFAPI_PPLAYER: sv = newSVdt_va (ap, DT_PLAYER); break;
488     case CFAPI_PARCH: sv = newSVdt_va (ap, DT_ARCH ); break;
489     case CFAPI_PPARTY: sv = newSVdt_va (ap, DT_PARTY ); break;
490     case CFAPI_PREGION: sv = newSVdt_va (ap, DT_REGION); break;
491    
492     default:
493 root 1.1 assert (("unhandled type in newSVcfapi", 0));
494     }
495    
496 root 1.6 va_end (ap);
497 root 1.1
498     return sv;
499     }
500    
501 root 1.11 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
502    
503 root 1.12 SV *
504 root 1.109 registry (attachable *ext)
505 root 1.12 {
506 root 1.13 if (!ext->cb)
507     ext->cb = newAV ();
508 root 1.12
509 root 1.13 return newRV_inc ((SV *)ext->cb);
510 root 1.12 }
511    
512 root 1.13 /////////////////////////////////////////////////////////////////////////////
513    
514 root 1.1 extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr)
515     {
516     return 0;
517     }
518    
519     static CommArray_s rtn_cmd;
520    
521     static int
522     runPluginCommand (object *obj, char *params)
523     {
524 root 1.73 return -1;
525 root 1.1 }
526    
527     extern "C" void *cfperl_getPluginProperty (int *type, ...)
528     {
529     va_list args;
530     char *propname;
531     int i;
532     va_start (args, type);
533     propname = va_arg (args, char *);
534     //printf ("Property name: %s\n", propname);
535    
536     if (!strcmp (propname, "command?"))
537 root 1.73 return NULL;
538 root 1.1 else if (!strcmp (propname, "Identification"))
539     {
540     va_end (args);
541 root 1.73 return (void *)PLUGIN_NAME;
542 root 1.1 }
543     else if (!strcmp (propname, "FullName"))
544     {
545     va_end (args);
546 root 1.73 return (void *)PLUGIN_VERSION;
547 root 1.1 }
548     else
549     va_end (args);
550    
551     return NULL;
552     }
553    
554     extern "C" int cfperl_postInitPlugin ()
555     {
556     int hooktype = 1;
557     int rtype = 0;
558    
559     cf_init_plugin (gethook);
560    
561     return 0;
562     }
563    
564     extern "C" int cfperl_closePlugin ()
565     {
566     return 0;
567     }
568    
569 root 1.7 void
570     cfperl_init ()
571     {
572 root 1.32 PERL_SYS_INIT3 (&settings.argc, &settings.argv, 0);
573     perl = perl_alloc ();
574     perl_construct (perl);
575    
576     PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
577    
578 root 1.7 char *argv[] = {
579     "",
580     "-e"
581 root 1.107 "use Event; use Coro;" // required for bootstrap
582     "cf->bootstrap;" // required for datadir :*>
583 root 1.32 "unshift @INC, cf::datadir ();"
584 root 1.41 "require cf;"
585 root 1.7 };
586    
587     if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl))
588     {
589     printf ("unable to initialize perl-interpreter, aborting.\n");
590     exit (EXIT_FAILURE);
591     }
592     }
593    
594 root 1.5 void cfperl_main ()
595 root 1.2 {
596     dSP;
597    
598     PUSHMARK (SP);
599     PUTBACK;
600 root 1.7 call_pv ("cf::main", G_DISCARD | G_VOID);
601     }
602    
603 root 1.109 void
604     attachable::instantiate ()
605     {
606     if (attach)
607     {
608     invoke (EVENT_ATTACHABLE_INSTANTIATE, ARG_STRING (attach), DT_END);
609     attach = 0;
610     }
611     }
612    
613     void
614     attachable::reattach ()
615     {
616     optimise ();
617     //TODO: check for _attachment's, very important for restarts
618     invoke (EVENT_ATTACHABLE_REATTACH, DT_END);
619     }
620    
621 root 1.8 static event_klass klass_of[NUM_EVENT_TYPES] = {
622     # define def(type,name) KLASS_ ## type,
623     # include "eventinc.h"
624     # undef def
625     };
626    
627 root 1.18 #define KLASS_OF(event) (((unsigned int)event) < NUM_EVENT_TYPES ? klass_of [event] : KLASS_NONE)
628    
629 root 1.8 static void
630     gather_callbacks (AV *&callbacks, AV *registry, event_type event)
631     {
632     // event must be in array
633     if (event >= 0 && event <= AvFILLp (registry))
634     {
635     SV *cbs_ = AvARRAY (registry)[event];
636    
637     // element must be list of callback entries
638     if (cbs_ && SvROK (cbs_) && SvTYPE (SvRV (cbs_)) == SVt_PVAV)
639     {
640     AV *cbs = (AV *)SvRV (cbs_);
641    
642     // no callback entries, no callbacks to call
643     if (AvFILLp (cbs) >= 0)
644     {
645     if (!callbacks)
646     {
647     callbacks = newAV ();
648     av_extend (callbacks, 16);
649     }
650    
651     // never use SvREFCNT_inc to copy values, but its ok here :)
652     for (int i = 0; i <= AvFILLp (cbs); ++i)
653     av_push (callbacks, SvREFCNT_inc (AvARRAY (cbs)[i]));
654     }
655     }
656     }
657     }
658    
659 root 1.109 void
660     attachable::gather_callbacks (AV *&callbacks, event_type event) const
661 root 1.6 {
662 root 1.109 ::gather_callbacks (callbacks, cb_attachable, event);
663 root 1.6
664 root 1.109 if (cb)
665     ::gather_callbacks (callbacks, cb, event);
666     }
667 root 1.8
668 root 1.109 void
669     global::gather_callbacks (AV *&callbacks, event_type event) const
670     {
671     ::gather_callbacks (callbacks, cb_object, event);
672     }
673 root 1.8
674 root 1.109 void
675     object::gather_callbacks (AV *&callbacks, event_type event) const
676     {
677     if (subtype && type + subtype * NUM_SUBTYPES <= AvFILLp (cb_type))
678     {
679     SV *registry = AvARRAY (cb_type)[type + subtype * NUM_SUBTYPES];
680 root 1.8
681 root 1.109 if (registry && SvROK (registry) && SvTYPE (SvRV (registry)) == SVt_PVAV)
682     ::gather_callbacks (callbacks, (AV *)SvRV (registry), event);
683     }
684 root 1.8
685 root 1.109 if (type <= AvFILLp (cb_type))
686 root 1.8 {
687 root 1.109 SV *registry = AvARRAY (cb_type)[type];
688 root 1.8
689 root 1.109 if (registry && SvROK (registry) && SvTYPE (SvRV (registry)) == SVt_PVAV)
690     ::gather_callbacks (callbacks, (AV *)SvRV (registry), event);
691     }
692 root 1.8
693 root 1.109 attachable::gather_callbacks (callbacks, event);
694     ::gather_callbacks (callbacks, cb_object, event);
695     }
696 root 1.8
697 root 1.109 void
698     archetype::gather_callbacks (AV *&callbacks, event_type event) const
699     {
700     attachable::gather_callbacks (callbacks, event);
701     //TODO//::gather_callbacks (callbacks, cb_archetype, event);
702     }
703 root 1.14
704 root 1.109 void
705     client::gather_callbacks (AV *&callbacks, event_type event) const
706     {
707     attachable::gather_callbacks (callbacks, event);
708     ::gather_callbacks (callbacks, cb_client, event);
709     }
710 root 1.8
711 root 1.109 void
712     player::gather_callbacks (AV *&callbacks, event_type event) const
713     {
714     attachable::gather_callbacks (callbacks, event);
715     ::gather_callbacks (callbacks, cb_player, event);
716     }
717 root 1.8
718 root 1.109 void
719     maptile::gather_callbacks (AV *&callbacks, event_type event) const
720     {
721     attachable::gather_callbacks (callbacks, event);
722     ::gather_callbacks (callbacks, cb_map, event);
723     }
724 root 1.8
725 root 1.109 bool
726     attachable::invoke (event_type event, ...)
727     {
728     data_type dt;
729     va_list ap;
730 root 1.14
731 root 1.109 va_start (ap, event);
732 root 1.8
733 root 1.109 // callback call ordering should be:
734     // 1. per-object callback
735     // 2. per-class object
736     // 3. per-type callback
737     // 4. global callbacks
738 root 1.12
739 root 1.109 AV *callbacks = 0;
740     gather_callbacks (callbacks, event);
741 root 1.8
742     // short-circuit processing if no callbacks found/defined
743     if (!callbacks)
744     return 0;
745    
746 root 1.116 CALL_BEGIN (3);
747     CALL_ARG_SV (newSViv (event)); // only used for debugging nowadays
748     CALL_ARG_SV (newRV_noinc ((SV *)callbacks));
749 root 1.8
750 root 1.109 //TODO: unhack
751 root 1.116 if (object *op = is_a<object>(this)) CALL_ARG_SV (newSVdt (DT_OBJECT, op));
752     else if (player *pl = is_a<player>(this)) CALL_ARG_SV (newSVdt (DT_PLAYER, pl));
753     else if (client *ns = is_a<client>(this)) CALL_ARG_SV (newSVdt (DT_CLIENT, ns));
754     else if (maptile *m = is_a<maptile>(this)) CALL_ARG_SV (newSVdt (DT_MAP, m));
755 root 1.109 else if (global *gl = is_a<global>(this)) /*nop*/;
756     else
757     abort (); //TODO
758 root 1.7
759 root 1.6 for (;;)
760     {
761 root 1.8 dt = (data_type) va_arg (ap, int);
762 root 1.6
763     if (dt == DT_END)
764     break;
765 root 1.109 else if (dt == DT_AV)
766 root 1.12 {
767     AV *av = va_arg (ap, AV *);
768    
769     for (int i = 0; i <= av_len (av); ++i)
770     XPUSHs (*av_fetch (av, i, 1));
771     }
772     else
773     XPUSHs (sv_2mortal (newSVdt_va (ap, dt)));
774 root 1.6 }
775    
776     va_end (ap);
777    
778 root 1.116 CALL_CALL ("cf::do_invoke", G_SCALAR);
779 root 1.6 count = count > 0 ? POPi : 0;
780    
781 root 1.116 CALL_END;
782 root 1.6
783     return count;
784 root 1.2 }
785    
786 root 1.12 SV *
787     cfperl_result (int idx)
788     {
789     AV *av = get_av ("cfperl::invoke_results", 0);
790     if (!av)
791     return &PL_sv_undef;
792    
793     SV **sv = av_fetch (av, idx, 0);
794     if (!sv)
795     return &PL_sv_undef;
796    
797     return *sv;
798     }
799    
800     int
801     cfperl_result_INT (int idx)
802     {
803     return SvIV (cfperl_result (idx));
804     }
805    
806 root 1.74 double
807 root 1.73 cfperl_result_DOUBLE (int idx)
808     {
809     return SvNV (cfperl_result (idx));
810     }
811    
812 root 1.80 /////////////////////////////////////////////////////////////////////////////
813    
814 root 1.116 void
815 root 1.134 cfperl_emergency_save ()
816 root 1.116 {
817     CALL_BEGIN (0);
818 root 1.134 CALL_CALL ("cf::emergency_save", G_VOID);
819 root 1.116 CALL_END;
820     }
821    
822     maptile *
823 root 1.126 maptile::find_sync (const char *path, maptile *origin)
824 root 1.116 {
825     CALL_BEGIN (2);
826     CALL_ARG (path);
827     CALL_ARG (origin);
828 root 1.126 CALL_CALL ("cf::map::find_sync", G_SCALAR);
829 root 1.116
830     maptile *retval;
831    
832     if (count)
833     sv_to (POPs, retval);
834     else
835     retval = 0;
836    
837     CALL_END;
838    
839     return retval;
840     }
841    
842 root 1.135 maptile *
843     maptile::find_async (const char *path, maptile *origin)
844     {
845     CALL_BEGIN (2);
846     CALL_ARG (path);
847     CALL_ARG (origin);
848     CALL_CALL ("cf::map::find_async", G_SCALAR);
849    
850     maptile *retval;
851    
852     if (count)
853     sv_to (POPs, retval);
854     else
855     retval = 0;
856    
857     CALL_END;
858    
859     return retval;
860     }
861    
862 root 1.116 void
863 root 1.126 maptile::do_load_sync ()
864     {
865     CALL_BEGIN (1);
866     CALL_ARG (this);
867     CALL_CALL ("cf::map::do_load_sync", G_SCALAR);
868     CALL_END;
869     }
870    
871     void
872 root 1.116 maptile::change_all_map_light (int change)
873     {
874     CALL_BEGIN (1);
875     CALL_ARG (change);
876     CALL_CALL ("cf::map::change_all_map_light", G_VOID);
877     CALL_END;
878     }
879    
880     void
881     object::enter_exit (object *exit)
882     {
883     if (type != PLAYER)
884     return;
885    
886     CALL_BEGIN (2);
887     CALL_ARG (this);
888     CALL_ARG (exit);
889     CALL_CALL ("cf::object::player::enter_exit", G_VOID);
890     CALL_END;
891     }
892    
893     /////////////////////////////////////////////////////////////////////////////
894    
895 root 1.80 struct EventAPI *watcher_base::GEventAPI;
896 root 1.116 struct CoroAPI *coroapi::GCoroAPI;
897 root 1.80
898 root 1.124 int coroapi::cede_counter;
899    
900 root 1.85 static void iw_dispatch (pe_event *ev)
901     {
902     iw *w = (iw *)ev->ext_data;
903     w->call (*w);
904     }
905    
906     void
907     iw::alloc ()
908     {
909     pe = GEventAPI->new_idle (0, 0);
910    
911 root 1.150 WaREENTRANT_off (pe);
912 root 1.85 pe->base.callback = (void *)iw_dispatch;
913     pe->base.ext_data = (void *)this;
914     }
915    
916 root 1.80 static void iow_dispatch (pe_event *ev)
917     {
918     iow *w = (iow *)ev->ext_data;
919     w->call (*w, ((pe_ioevent *)ev)->got);
920     }
921    
922     void
923     iow::alloc ()
924     {
925     pe = GEventAPI->new_io (0, 0);
926    
927 root 1.150 WaREENTRANT_off (pe);
928 root 1.80 pe->base.callback = (void *)iow_dispatch;
929     pe->base.ext_data = (void *)this;
930    
931 root 1.81 pe->fd = -1;
932     pe->poll = 0;
933 root 1.80 }
934    
935 root 1.85 void
936 root 1.80 iow::fd (int fd)
937     {
938     pe->fd = fd;
939     }
940    
941     int
942     iow::poll ()
943     {
944     return pe->poll;
945     }
946    
947 root 1.85 void
948 root 1.80 iow::poll (int events)
949     {
950 root 1.81 if (pe->poll != events)
951     {
952     if (pe->poll) stop ();
953     pe->poll = events;
954     if (pe->poll) start ();
955     }
956 root 1.80 }
957    
958 root 1.109 void
959     _connect_to_perl ()
960     {
961     stash_cf = gv_stashpv ("cf" , 1);
962    
963     stash_cf_object_wrap = gv_stashpv ("cf::object::wrap", 1);
964     stash_cf_object_player_wrap = gv_stashpv ("cf::object::player::wrap", 1);
965     stash_cf_player_wrap = gv_stashpv ("cf::player::wrap", 1);
966     stash_cf_map_wrap = gv_stashpv ("cf::map::wrap" , 1);
967     stash_cf_client_wrap = gv_stashpv ("cf::client::wrap", 1);
968     stash_cf_arch_wrap = gv_stashpv ("cf::arch::wrap" , 1);
969     stash_cf_party_wrap = gv_stashpv ("cf::party::wrap" , 1);
970     stash_cf_region_wrap = gv_stashpv ("cf::region::wrap", 1);
971     stash_cf_living_wrap = gv_stashpv ("cf::living::wrap", 1);
972    
973 root 1.116 sv_runtime = get_sv ("cf::RUNTIME", 1);
974     sv_upgrade (sv_runtime, SVt_NV);
975    
976 root 1.109 cb_global = get_av ("cf::CB_GLOBAL", 1);
977     cb_attachable = get_av ("cf::CB_ATTACHABLE", 1);
978     cb_object = get_av ("cf::CB_OBJECT", 1);
979     cb_player = get_av ("cf::CB_PLAYER", 1);
980     cb_client = get_av ("cf::CB_CLIENT", 1);
981     cb_type = get_av ("cf::CB_TYPE" , 1);
982     cb_map = get_av ("cf::CB_MAP" , 1);
983     }
984    
985 root 1.1 MODULE = cf PACKAGE = cf PREFIX = cf_
986    
987     BOOT:
988     {
989 root 1.109 _connect_to_perl ();
990 root 1.1
991 root 1.116 I_EVENT_API (PACKAGE); watcher_base::GEventAPI = GEventAPI;
992     I_CORO_API (PACKAGE); coroapi::GCoroAPI = GCoroAPI;
993 root 1.80
994 root 1.109 newCONSTSUB (stash_cf, "VERSION", newSVpv (VERSION, sizeof (VERSION) - 1));
995 root 1.63
996 root 1.1 static const struct {
997     const char *name;
998     IV iv;
999     } *civ, const_iv[] = {
1000     # define const_iv(name) { # name, (IV)name },
1001     const_iv (llevError)
1002     const_iv (llevInfo)
1003     const_iv (llevDebug)
1004     const_iv (llevMonster)
1005    
1006 root 1.5 const_iv (MAX_TIME)
1007 root 1.1 const_iv (PLAYER)
1008     const_iv (TRANSPORT)
1009     const_iv (ROD)
1010     const_iv (TREASURE)
1011     const_iv (POTION)
1012     const_iv (FOOD)
1013     const_iv (POISON)
1014     const_iv (BOOK)
1015     const_iv (CLOCK)
1016     const_iv (ARROW)
1017     const_iv (BOW)
1018     const_iv (WEAPON)
1019     const_iv (ARMOUR)
1020     const_iv (PEDESTAL)
1021     const_iv (ALTAR)
1022     const_iv (LOCKED_DOOR)
1023     const_iv (SPECIAL_KEY)
1024     const_iv (MAP)
1025     const_iv (DOOR)
1026     const_iv (KEY)
1027     const_iv (TIMED_GATE)
1028     const_iv (TRIGGER)
1029     const_iv (GRIMREAPER)
1030     const_iv (MAGIC_EAR)
1031     const_iv (TRIGGER_BUTTON)
1032     const_iv (TRIGGER_ALTAR)
1033     const_iv (TRIGGER_PEDESTAL)
1034     const_iv (SHIELD)
1035     const_iv (HELMET)
1036     const_iv (HORN)
1037     const_iv (MONEY)
1038     const_iv (CLASS)
1039     const_iv (GRAVESTONE)
1040     const_iv (AMULET)
1041     const_iv (PLAYERMOVER)
1042     const_iv (TELEPORTER)
1043     const_iv (CREATOR)
1044     const_iv (SKILL)
1045     const_iv (EARTHWALL)
1046     const_iv (GOLEM)
1047     const_iv (THROWN_OBJ)
1048     const_iv (BLINDNESS)
1049     const_iv (GOD)
1050     const_iv (DETECTOR)
1051     const_iv (TRIGGER_MARKER)
1052     const_iv (DEAD_OBJECT)
1053     const_iv (DRINK)
1054     const_iv (MARKER)
1055     const_iv (HOLY_ALTAR)
1056     const_iv (PLAYER_CHANGER)
1057     const_iv (BATTLEGROUND)
1058     const_iv (PEACEMAKER)
1059     const_iv (GEM)
1060     const_iv (FIREWALL)
1061     const_iv (ANVIL)
1062     const_iv (CHECK_INV)
1063     const_iv (MOOD_FLOOR)
1064     const_iv (EXIT)
1065     const_iv (ENCOUNTER)
1066     const_iv (SHOP_FLOOR)
1067     const_iv (SHOP_MAT)
1068     const_iv (RING)
1069     const_iv (FLOOR)
1070     const_iv (FLESH)
1071     const_iv (INORGANIC)
1072     const_iv (SKILL_TOOL)
1073     const_iv (LIGHTER)
1074 elmex 1.92 const_iv (BUILDABLE_WALL)
1075 root 1.1 const_iv (MISC_OBJECT)
1076     const_iv (LAMP)
1077     const_iv (DUPLICATOR)
1078     const_iv (SPELLBOOK)
1079     const_iv (CLOAK)
1080     const_iv (SPINNER)
1081     const_iv (GATE)
1082     const_iv (BUTTON)
1083     const_iv (CF_HANDLE)
1084     const_iv (HOLE)
1085     const_iv (TRAPDOOR)
1086     const_iv (SIGN)
1087     const_iv (BOOTS)
1088     const_iv (GLOVES)
1089     const_iv (SPELL)
1090     const_iv (SPELL_EFFECT)
1091     const_iv (CONVERTER)
1092     const_iv (BRACERS)
1093     const_iv (POISONING)
1094     const_iv (SAVEBED)
1095     const_iv (WAND)
1096     const_iv (SCROLL)
1097     const_iv (DIRECTOR)
1098     const_iv (GIRDLE)
1099     const_iv (FORCE)
1100     const_iv (POTION_EFFECT)
1101     const_iv (EVENT_CONNECTOR)
1102     const_iv (CLOSE_CON)
1103     const_iv (CONTAINER)
1104     const_iv (ARMOUR_IMPROVER)
1105     const_iv (WEAPON_IMPROVER)
1106     const_iv (SKILLSCROLL)
1107     const_iv (DEEP_SWAMP)
1108     const_iv (IDENTIFY_ALTAR)
1109     const_iv (MENU)
1110     const_iv (RUNE)
1111     const_iv (TRAP)
1112     const_iv (POWER_CRYSTAL)
1113     const_iv (CORPSE)
1114     const_iv (DISEASE)
1115     const_iv (SYMPTOM)
1116     const_iv (BUILDER)
1117     const_iv (MATERIAL)
1118     const_iv (ITEM_TRANSFORMER)
1119    
1120 root 1.14 const_iv (NUM_SUBTYPES)
1121    
1122 root 1.1 const_iv (ST_BD_BUILD)
1123     const_iv (ST_BD_REMOVE)
1124    
1125     const_iv (ST_MAT_FLOOR)
1126     const_iv (ST_MAT_WALL)
1127     const_iv (ST_MAT_ITEM)
1128    
1129     const_iv (AT_PHYSICAL)
1130     const_iv (AT_MAGIC)
1131     const_iv (AT_FIRE)
1132     const_iv (AT_ELECTRICITY)
1133     const_iv (AT_COLD)
1134     const_iv (AT_CONFUSION)
1135     const_iv (AT_ACID)
1136     const_iv (AT_DRAIN)
1137     const_iv (AT_WEAPONMAGIC)
1138     const_iv (AT_GHOSTHIT)
1139     const_iv (AT_POISON)
1140     const_iv (AT_SLOW)
1141     const_iv (AT_PARALYZE)
1142     const_iv (AT_TURN_UNDEAD)
1143     const_iv (AT_FEAR)
1144     const_iv (AT_CANCELLATION)
1145     const_iv (AT_DEPLETE)
1146     const_iv (AT_DEATH)
1147     const_iv (AT_CHAOS)
1148     const_iv (AT_COUNTERSPELL)
1149     const_iv (AT_GODPOWER)
1150     const_iv (AT_HOLYWORD)
1151     const_iv (AT_BLIND)
1152     const_iv (AT_INTERNAL)
1153     const_iv (AT_LIFE_STEALING)
1154     const_iv (AT_DISEASE)
1155    
1156     const_iv (WEAP_HIT)
1157     const_iv (WEAP_SLASH)
1158     const_iv (WEAP_PIERCE)
1159     const_iv (WEAP_CLEAVE)
1160     const_iv (WEAP_SLICE)
1161     const_iv (WEAP_STAB)
1162     const_iv (WEAP_WHIP)
1163     const_iv (WEAP_CRUSH)
1164     const_iv (WEAP_BLUD)
1165    
1166     const_iv (FLAG_ALIVE)
1167     const_iv (FLAG_WIZ)
1168     const_iv (FLAG_REMOVED)
1169     const_iv (FLAG_FREED)
1170     const_iv (FLAG_WAS_WIZ)
1171     const_iv (FLAG_APPLIED)
1172     const_iv (FLAG_UNPAID)
1173     const_iv (FLAG_USE_SHIELD)
1174     const_iv (FLAG_NO_PICK)
1175     const_iv (FLAG_ANIMATE)
1176     const_iv (FLAG_MONSTER)
1177     const_iv (FLAG_FRIENDLY)
1178     const_iv (FLAG_GENERATOR)
1179     const_iv (FLAG_IS_THROWN)
1180     const_iv (FLAG_AUTO_APPLY)
1181     const_iv (FLAG_PLAYER_SOLD)
1182     const_iv (FLAG_SEE_INVISIBLE)
1183     const_iv (FLAG_CAN_ROLL)
1184     const_iv (FLAG_OVERLAY_FLOOR)
1185     const_iv (FLAG_IS_TURNABLE)
1186     const_iv (FLAG_IS_USED_UP)
1187     const_iv (FLAG_IDENTIFIED)
1188     const_iv (FLAG_REFLECTING)
1189     const_iv (FLAG_CHANGING)
1190     const_iv (FLAG_SPLITTING)
1191     const_iv (FLAG_HITBACK)
1192     const_iv (FLAG_STARTEQUIP)
1193     const_iv (FLAG_BLOCKSVIEW)
1194     const_iv (FLAG_UNDEAD)
1195     const_iv (FLAG_SCARED)
1196     const_iv (FLAG_UNAGGRESSIVE)
1197     const_iv (FLAG_REFL_MISSILE)
1198     const_iv (FLAG_REFL_SPELL)
1199     const_iv (FLAG_NO_MAGIC)
1200     const_iv (FLAG_NO_FIX_PLAYER)
1201     const_iv (FLAG_IS_LIGHTABLE)
1202     const_iv (FLAG_TEAR_DOWN)
1203     const_iv (FLAG_RUN_AWAY)
1204     const_iv (FLAG_PICK_UP)
1205     const_iv (FLAG_UNIQUE)
1206     const_iv (FLAG_NO_DROP)
1207     const_iv (FLAG_WIZCAST)
1208     const_iv (FLAG_CAST_SPELL)
1209     const_iv (FLAG_USE_SCROLL)
1210     const_iv (FLAG_USE_RANGE)
1211     const_iv (FLAG_USE_BOW)
1212     const_iv (FLAG_USE_ARMOUR)
1213     const_iv (FLAG_USE_WEAPON)
1214     const_iv (FLAG_USE_RING)
1215     const_iv (FLAG_READY_RANGE)
1216     const_iv (FLAG_READY_BOW)
1217     const_iv (FLAG_XRAYS)
1218     const_iv (FLAG_NO_APPLY)
1219     const_iv (FLAG_IS_FLOOR)
1220     const_iv (FLAG_LIFESAVE)
1221     const_iv (FLAG_NO_STRENGTH)
1222     const_iv (FLAG_SLEEP)
1223     const_iv (FLAG_STAND_STILL)
1224     const_iv (FLAG_RANDOM_MOVE)
1225     const_iv (FLAG_ONLY_ATTACK)
1226     const_iv (FLAG_CONFUSED)
1227     const_iv (FLAG_STEALTH)
1228     const_iv (FLAG_WIZPASS)
1229     const_iv (FLAG_IS_LINKED)
1230     const_iv (FLAG_CURSED)
1231     const_iv (FLAG_DAMNED)
1232     const_iv (FLAG_SEE_ANYWHERE)
1233     const_iv (FLAG_KNOWN_MAGICAL)
1234     const_iv (FLAG_KNOWN_CURSED)
1235     const_iv (FLAG_CAN_USE_SKILL)
1236     const_iv (FLAG_BEEN_APPLIED)
1237     const_iv (FLAG_READY_SCROLL)
1238     const_iv (FLAG_USE_ROD)
1239     const_iv (FLAG_USE_HORN)
1240     const_iv (FLAG_MAKE_INVIS)
1241     const_iv (FLAG_INV_LOCKED)
1242     const_iv (FLAG_IS_WOODED)
1243     const_iv (FLAG_IS_HILLY)
1244     const_iv (FLAG_READY_SKILL)
1245     const_iv (FLAG_READY_WEAPON)
1246     const_iv (FLAG_NO_SKILL_IDENT)
1247     const_iv (FLAG_BLIND)
1248     const_iv (FLAG_SEE_IN_DARK)
1249     const_iv (FLAG_IS_CAULDRON)
1250     const_iv (FLAG_NO_STEAL)
1251     const_iv (FLAG_ONE_HIT)
1252     const_iv (FLAG_CLIENT_SENT)
1253     const_iv (FLAG_BERSERK)
1254     const_iv (FLAG_NEUTRAL)
1255     const_iv (FLAG_NO_ATTACK)
1256     const_iv (FLAG_NO_DAMAGE)
1257     const_iv (FLAG_OBJ_ORIGINAL)
1258     const_iv (FLAG_OBJ_SAVE_ON_OVL)
1259     const_iv (FLAG_ACTIVATE_ON_PUSH)
1260     const_iv (FLAG_ACTIVATE_ON_RELEASE)
1261     const_iv (FLAG_IS_WATER)
1262     const_iv (FLAG_CONTENT_ON_GEN)
1263     const_iv (FLAG_IS_A_TEMPLATE)
1264     const_iv (FLAG_IS_BUILDABLE)
1265 root 1.138 const_iv (FLAG_DESTROY_ON_DEATH)
1266 root 1.147 const_iv (FLAG_NO_MAP_SAVE)
1267 root 1.1
1268     const_iv (NDI_BLACK)
1269     const_iv (NDI_WHITE)
1270     const_iv (NDI_NAVY)
1271     const_iv (NDI_RED)
1272     const_iv (NDI_ORANGE)
1273     const_iv (NDI_BLUE)
1274     const_iv (NDI_DK_ORANGE)
1275     const_iv (NDI_GREEN)
1276     const_iv (NDI_LT_GREEN)
1277     const_iv (NDI_GREY)
1278     const_iv (NDI_BROWN)
1279     const_iv (NDI_GOLD)
1280     const_iv (NDI_TAN)
1281     const_iv (NDI_MAX_COLOR)
1282     const_iv (NDI_COLOR_MASK)
1283     const_iv (NDI_UNIQUE)
1284     const_iv (NDI_ALL)
1285    
1286 root 1.58 const_iv (UPD_LOCATION)
1287     const_iv (UPD_FLAGS)
1288     const_iv (UPD_WEIGHT)
1289     const_iv (UPD_FACE)
1290     const_iv (UPD_NAME)
1291     const_iv (UPD_ANIM)
1292     const_iv (UPD_ANIMSPEED)
1293     const_iv (UPD_NROF)
1294    
1295     const_iv (UPD_SP_MANA)
1296     const_iv (UPD_SP_GRACE)
1297     const_iv (UPD_SP_DAMAGE)
1298    
1299 root 1.1 const_iv (F_APPLIED)
1300     const_iv (F_LOCATION)
1301     const_iv (F_UNPAID)
1302     const_iv (F_MAGIC)
1303     const_iv (F_CURSED)
1304     const_iv (F_DAMNED)
1305     const_iv (F_OPEN)
1306     const_iv (F_NOPICK)
1307     const_iv (F_LOCKED)
1308    
1309     const_iv (F_BUY)
1310     const_iv (F_SHOP)
1311     const_iv (F_SELL)
1312    
1313     const_iv (P_BLOCKSVIEW)
1314 root 1.91 const_iv (P_PLAYER)
1315 root 1.1 const_iv (P_NO_MAGIC)
1316     const_iv (P_IS_ALIVE)
1317     const_iv (P_NO_CLERIC)
1318     const_iv (P_OUT_OF_MAP)
1319     const_iv (P_NEW_MAP)
1320 root 1.121 const_iv (P_UPTODATE)
1321 root 1.1
1322     const_iv (UP_OBJ_INSERT)
1323     const_iv (UP_OBJ_REMOVE)
1324     const_iv (UP_OBJ_CHANGE)
1325     const_iv (UP_OBJ_FACE)
1326    
1327     const_iv (INS_NO_MERGE)
1328     const_iv (INS_ABOVE_FLOOR_ONLY)
1329     const_iv (INS_NO_WALK_ON)
1330     const_iv (INS_ON_TOP)
1331     const_iv (INS_BELOW_ORIGINATOR)
1332     const_iv (INS_MAP_LOAD)
1333    
1334     const_iv (WILL_APPLY_HANDLE)
1335     const_iv (WILL_APPLY_TREASURE)
1336     const_iv (WILL_APPLY_EARTHWALL)
1337     const_iv (WILL_APPLY_DOOR)
1338     const_iv (WILL_APPLY_FOOD)
1339    
1340     const_iv (SAVE_MODE)
1341     const_iv (SAVE_DIR_MODE)
1342    
1343     const_iv (M_PAPER)
1344     const_iv (M_IRON)
1345     const_iv (M_GLASS)
1346     const_iv (M_LEATHER)
1347     const_iv (M_WOOD)
1348     const_iv (M_ORGANIC)
1349     const_iv (M_STONE)
1350     const_iv (M_CLOTH)
1351     const_iv (M_ADAMANT)
1352     const_iv (M_LIQUID)
1353     const_iv (M_SOFT_METAL)
1354     const_iv (M_BONE)
1355     const_iv (M_ICE)
1356     const_iv (M_SPECIAL)
1357    
1358     const_iv (SK_EXP_ADD_SKILL)
1359     const_iv (SK_EXP_TOTAL)
1360     const_iv (SK_EXP_NONE)
1361     const_iv (SK_SUBTRACT_SKILL_EXP)
1362 elmex 1.39 const_iv (SK_EXP_SKILL_ONLY)
1363 root 1.1
1364     const_iv (SK_LOCKPICKING)
1365     const_iv (SK_HIDING)
1366     const_iv (SK_SMITHERY)
1367     const_iv (SK_BOWYER)
1368     const_iv (SK_JEWELER)
1369     const_iv (SK_ALCHEMY)
1370     const_iv (SK_STEALING)
1371     const_iv (SK_LITERACY)
1372     const_iv (SK_BARGAINING)
1373     const_iv (SK_JUMPING)
1374     const_iv (SK_DET_MAGIC)
1375     const_iv (SK_ORATORY)
1376     const_iv (SK_SINGING)
1377     const_iv (SK_DET_CURSE)
1378     const_iv (SK_FIND_TRAPS)
1379     const_iv (SK_MEDITATION)
1380     const_iv (SK_PUNCHING)
1381     const_iv (SK_FLAME_TOUCH)
1382     const_iv (SK_KARATE)
1383     const_iv (SK_CLIMBING)
1384     const_iv (SK_WOODSMAN)
1385     const_iv (SK_INSCRIPTION)
1386     const_iv (SK_ONE_HANDED_WEAPON)
1387     const_iv (SK_MISSILE_WEAPON)
1388     const_iv (SK_THROWING)
1389     const_iv (SK_USE_MAGIC_ITEM)
1390     const_iv (SK_DISARM_TRAPS)
1391     const_iv (SK_SET_TRAP)
1392     const_iv (SK_THAUMATURGY)
1393     const_iv (SK_PRAYING)
1394     const_iv (SK_CLAWING)
1395     const_iv (SK_LEVITATION)
1396     const_iv (SK_SUMMONING)
1397     const_iv (SK_PYROMANCY)
1398     const_iv (SK_EVOCATION)
1399     const_iv (SK_SORCERY)
1400     const_iv (SK_TWO_HANDED_WEAPON)
1401     const_iv (SK_SPARK_TOUCH)
1402     const_iv (SK_SHIVER)
1403     const_iv (SK_ACID_SPLASH)
1404     const_iv (SK_POISON_NAIL)
1405    
1406     const_iv (SOUND_NEW_PLAYER)
1407     const_iv (SOUND_FIRE_ARROW)
1408     const_iv (SOUND_LEARN_SPELL)
1409     const_iv (SOUND_FUMBLE_SPELL)
1410     const_iv (SOUND_WAND_POOF)
1411     const_iv (SOUND_OPEN_DOOR)
1412     const_iv (SOUND_PUSH_PLAYER)
1413     const_iv (SOUND_PLAYER_HITS1)
1414     const_iv (SOUND_PLAYER_HITS2)
1415     const_iv (SOUND_PLAYER_HITS3)
1416     const_iv (SOUND_PLAYER_HITS4)
1417     const_iv (SOUND_PLAYER_IS_HIT1)
1418     const_iv (SOUND_PLAYER_IS_HIT2)
1419     const_iv (SOUND_PLAYER_IS_HIT3)
1420     const_iv (SOUND_PLAYER_KILLS)
1421     const_iv (SOUND_PET_IS_KILLED)
1422     const_iv (SOUND_PLAYER_DIES)
1423     const_iv (SOUND_OB_EVAPORATE)
1424     const_iv (SOUND_OB_EXPLODE)
1425     const_iv (SOUND_CLOCK)
1426     const_iv (SOUND_TURN_HANDLE)
1427     const_iv (SOUND_FALL_HOLE)
1428     const_iv (SOUND_DRINK_POISON)
1429     const_iv (SOUND_CAST_SPELL_0)
1430    
1431     const_iv (PREFER_LOW)
1432     const_iv (PREFER_HIGH)
1433    
1434     const_iv (ATNR_PHYSICAL)
1435     const_iv (ATNR_MAGIC)
1436     const_iv (ATNR_FIRE)
1437     const_iv (ATNR_ELECTRICITY)
1438     const_iv (ATNR_COLD)
1439     const_iv (ATNR_CONFUSION)
1440     const_iv (ATNR_ACID)
1441     const_iv (ATNR_DRAIN)
1442     const_iv (ATNR_WEAPONMAGIC)
1443     const_iv (ATNR_GHOSTHIT)
1444     const_iv (ATNR_POISON)
1445     const_iv (ATNR_SLOW)
1446     const_iv (ATNR_PARALYZE)
1447     const_iv (ATNR_TURN_UNDEAD)
1448     const_iv (ATNR_FEAR)
1449     const_iv (ATNR_CANCELLATION)
1450     const_iv (ATNR_DEPLETE)
1451     const_iv (ATNR_DEATH)
1452     const_iv (ATNR_CHAOS)
1453     const_iv (ATNR_COUNTERSPELL)
1454     const_iv (ATNR_GODPOWER)
1455     const_iv (ATNR_HOLYWORD)
1456     const_iv (ATNR_BLIND)
1457     const_iv (ATNR_INTERNAL)
1458     const_iv (ATNR_LIFE_STEALING)
1459     const_iv (ATNR_DISEASE)
1460    
1461     const_iv (MAP_IN_MEMORY)
1462     const_iv (MAP_SWAPPED)
1463     const_iv (MAP_LOADING)
1464     const_iv (MAP_SAVING)
1465 root 1.7
1466 root 1.109 const_iv (KLASS_ATTACHABLE)
1467 root 1.7 const_iv (KLASS_GLOBAL)
1468     const_iv (KLASS_OBJECT)
1469 root 1.96 const_iv (KLASS_CLIENT)
1470 root 1.7 const_iv (KLASS_PLAYER)
1471     const_iv (KLASS_MAP)
1472 root 1.99
1473 root 1.100 const_iv (CS_QUERY_YESNO)
1474     const_iv (CS_QUERY_SINGLECHAR)
1475     const_iv (CS_QUERY_HIDEINPUT)
1476    
1477 root 1.99 const_iv (ST_DEAD)
1478     const_iv (ST_SETUP)
1479     const_iv (ST_PLAYING)
1480     const_iv (ST_CUSTOM)
1481    
1482     const_iv (ST_CHANGE_CLASS)
1483 root 1.116
1484     const_iv (IO_HEADER)
1485     const_iv (IO_OBJECTS)
1486     const_iv (IO_UNIQUES)
1487 root 1.117
1488     // random map generator
1489     const_iv (LAYOUT_NONE)
1490     const_iv (LAYOUT_ONION)
1491     const_iv (LAYOUT_MAZE)
1492     const_iv (LAYOUT_SPIRAL)
1493     const_iv (LAYOUT_ROGUELIKE)
1494     const_iv (LAYOUT_SNAKE)
1495     const_iv (LAYOUT_SQUARE_SPIRAL)
1496    
1497     const_iv (RMOPT_RANDOM)
1498     const_iv (RMOPT_CENTERED)
1499     const_iv (RMOPT_LINEAR)
1500     const_iv (RMOPT_BOTTOM_C)
1501     const_iv (RMOPT_BOTTOM_R)
1502     const_iv (RMOPT_IRR_SPACE)
1503     const_iv (RMOPT_WALL_OFF)
1504     const_iv (RMOPT_WALLS_ONLY)
1505     const_iv (RMOPT_NO_DOORS)
1506    
1507     const_iv (SYMMETRY_RANDOM)
1508     const_iv (SYMMETRY_NONE)
1509     const_iv (SYMMETRY_X)
1510     const_iv (SYMMETRY_Y)
1511     const_iv (SYMMETRY_XY)
1512 root 1.1 };
1513    
1514     for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
1515 root 1.109 newCONSTSUB (stash_cf, (char *)civ->name, newSViv (civ->iv));
1516 root 1.1
1517     static const struct {
1518     const char *name;
1519 root 1.14 int skip;
1520 root 1.7 IV klass;
1521 root 1.1 IV iv;
1522 root 1.6 } *eiv, event_iv[] = {
1523 root 1.14 # define def(klass,name) { "EVENT_" # klass "_" # name, sizeof ("EVENT_" # klass), (IV)KLASS_ ## klass, (IV)EVENT_ ## klass ## _ ## name },
1524 root 1.6 # include "eventinc.h"
1525     # undef def
1526     };
1527    
1528     AV *av = get_av ("cf::EVENT", 1);
1529    
1530     for (eiv = event_iv + sizeof (event_iv) / sizeof (event_iv [0]); eiv-- > event_iv; )
1531 root 1.7 {
1532     AV *event = newAV ();
1533 root 1.14 av_push (event, newSVpv ((char *)eiv->name + eiv->skip, 0));
1534 root 1.7 av_push (event, newSViv (eiv->klass));
1535     av_store (av, eiv->iv, newRV_noinc ((SV *)event));
1536 root 1.109 newCONSTSUB (stash_cf, (char *)eiv->name, newSViv (eiv->iv));
1537 root 1.7 }
1538 root 1.14 }
1539    
1540 root 1.109 void _connect_to_perl ()
1541 root 1.14
1542 root 1.47 void _global_reattach ()
1543 root 1.14 CODE:
1544     {
1545     // reattach to all attachable objects in the game.
1546 root 1.128 for_all_clients (ns)
1547     ns->reattach ();
1548 root 1.96
1549 root 1.114 for_all_players (pl)
1550 root 1.109 pl->reattach ();
1551 root 1.14
1552 root 1.116 //TODO
1553     //for (map_container::iterator i = maps.begin (); i != maps.end (); ++i)
1554     // i->second->reattach ();
1555 root 1.8
1556 root 1.128 for_all_objects (op)
1557 root 1.109 op->reattach ();
1558 root 1.1 }
1559    
1560     NV floor (NV x)
1561    
1562     NV ceil (NV x)
1563    
1564 root 1.143 NV rndm (...)
1565     CODE:
1566     switch (items)
1567     {
1568     case 0: RETVAL = rndm (); break;
1569     case 1: RETVAL = rndm (SvUV (ST (0))); break;
1570     case 2: RETVAL = rndm (SvIV (ST (0)), SvIV (ST (1))); break;
1571     default: croak ("cf::rndm requires none, one or two parameters."); break;
1572     }
1573     OUTPUT:
1574     RETVAL
1575    
1576 root 1.5 void server_tick ()
1577 root 1.116 CODE:
1578     runtime = SvNVx (sv_runtime);
1579     server_tick ();
1580 root 1.5
1581 root 1.1 void
1582     LOG (int level, char *msg)
1583     PROTOTYPE: $$
1584     C_ARGS: (LogLevel)level, "%s", msg
1585    
1586     char *path_combine (char *base, char *path)
1587     PROTOTYPE: $$
1588    
1589     char *path_combine_and_normalize (char *base, char *path)
1590     PROTOTYPE: $$
1591    
1592 root 1.19 const char *
1593     get_maps_directory (char *path)
1594 root 1.1 PROTOTYPE: $
1595     ALIAS: maps_directory = 0
1596 root 1.19 CODE:
1597     RETVAL = create_pathname (path);
1598     OUTPUT: RETVAL
1599 root 1.1
1600     void
1601     sub_generation_inc ()
1602     CODE:
1603     PL_sub_generation++;
1604    
1605     char *
1606     mapdir ()
1607     PROTOTYPE:
1608     ALIAS:
1609     mapdir = 0
1610     uniquedir = 1
1611     tmpdir = 2
1612     confdir = 3
1613     localdir = 4
1614     playerdir = 5
1615     datadir = 6
1616     CODE:
1617 root 1.19 switch (ix)
1618     {
1619     case 0: RETVAL = settings.mapdir ; break;
1620     case 1: RETVAL = settings.uniquedir; break;
1621     case 2: RETVAL = settings.tmpdir ; break;
1622     case 3: RETVAL = settings.confdir ; break;
1623     case 4: RETVAL = settings.localdir ; break;
1624     case 5: RETVAL = settings.playerdir; break;
1625     case 6: RETVAL = settings.datadir ; break;
1626     }
1627 root 1.1 OUTPUT: RETVAL
1628    
1629 root 1.120 void abort ()
1630    
1631 root 1.144 void fork_abort (char *cause = "cf::fork_abort")
1632    
1633 root 1.134 void cleanup (const char *cause, bool make_core = false)
1634    
1635 root 1.116 void emergency_save ()
1636    
1637 root 1.149 UV sv_2watcher (SV *w)
1638     CODE:
1639     RETVAL = (UV)GEventAPI->sv_2watcher (w);
1640     OUTPUT:
1641     RETVAL
1642    
1643 root 1.56 void _exit (int status = 0)
1644    
1645 root 1.125 #if _POSIX_MEMLOCK
1646    
1647     int mlockall (int flags = MCL_CURRENT | MCL_FUTURE)
1648    
1649     int munlockall ()
1650    
1651     #endif
1652    
1653 root 1.74 int find_animation (char *text)
1654 root 1.1 PROTOTYPE: $
1655    
1656 root 1.74 int random_roll (int min, int max, object *op, int goodbad);
1657 root 1.1
1658     const char *cost_string_from_value(uint64 cost, int approx = 0)
1659    
1660     int
1661     exp_to_level (val64 exp)
1662     CODE:
1663     {
1664     int i = 0;
1665    
1666     RETVAL = settings.max_level;
1667    
1668     for (i = 1; i <= settings.max_level; i++)
1669     {
1670     if (levels[i] > exp)
1671     {
1672     RETVAL = i - 1;
1673     break;
1674     }
1675     }
1676     }
1677     OUTPUT: RETVAL
1678    
1679     val64
1680     level_to_min_exp (int level)
1681     CODE:
1682     if (level > settings.max_level)
1683     RETVAL = levels[settings.max_level];
1684     else if (level < 1)
1685     RETVAL = 0;
1686     else
1687     RETVAL = levels[level];
1688     OUTPUT: RETVAL
1689    
1690     SV *
1691     resistance_to_string (int atnr)
1692     CODE:
1693     if (atnr >= 0 && atnr < NROFATTACKS)
1694     RETVAL = newSVpv (resist_plus[atnr], 0);
1695     else
1696     XSRETURN_UNDEF;
1697     OUTPUT: RETVAL
1698    
1699 root 1.97 MODULE = cf PACKAGE = cf::attachable
1700    
1701 root 1.27 int
1702 root 1.97 valid (SV *obj)
1703 root 1.27 CODE:
1704     RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext);
1705     OUTPUT:
1706     RETVAL
1707    
1708 root 1.128 INCLUDE: $PERL genacc attachable ../include/cfperl.h |
1709 root 1.115
1710 root 1.101 MODULE = cf PACKAGE = cf::global
1711    
1712     int invoke (SV *klass, int event, ...)
1713     CODE:
1714     if (KLASS_OF (event) != KLASS_GLOBAL) croak ("event class must be GLOBAL");
1715     AV *av = (AV *)sv_2mortal ((SV *)newAV ());
1716     for (int i = 1; i < items; i++) av_push (av, SvREFCNT_inc (ST (i)));
1717 root 1.109 RETVAL = gbl_ev.invoke ((event_type)event, ARG_AV (av), DT_END);
1718 root 1.101 OUTPUT: RETVAL
1719    
1720 root 1.1 MODULE = cf PACKAGE = cf::object PREFIX = cf_object_
1721    
1722 root 1.62 INCLUDE: $PERL genacc object ../include/object.h |
1723    
1724 root 1.18 int invoke (object *op, int event, ...)
1725     CODE:
1726     if (KLASS_OF (event) != KLASS_OBJECT) croak ("event class must be OBJECT");
1727 root 1.24 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
1728     for (int i = 2; i < items; i++) av_push (av, SvREFCNT_inc (ST (i)));
1729 root 1.109 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END);
1730 root 1.18 OUTPUT: RETVAL
1731    
1732     SV *registry (object *op)
1733    
1734 root 1.57 void mortals ()
1735 root 1.59 PPCODE:
1736 root 1.57 EXTEND (SP, object::mortals.size ());
1737     for (AUTODECL (i, object::mortals.begin ()); i != object::mortals.end (); ++i)
1738     PUSHs (to_sv (*i));
1739    
1740 root 1.134 int objects_size ()
1741     CODE:
1742     RETVAL = objects.size ();
1743     OUTPUT: RETVAL
1744    
1745     object *objects (U32 index)
1746     CODE:
1747     RETVAL = index < objects.size () ? objects [index] : 0;
1748     OUTPUT: RETVAL
1749    
1750     int actives_size ()
1751     CODE:
1752     RETVAL = actives.size ();
1753     OUTPUT: RETVAL
1754    
1755     object *actives (U32 index)
1756 root 1.57 CODE:
1757 root 1.134 RETVAL = index < actives.size () ? actives [index] : 0;
1758 root 1.57 OUTPUT: RETVAL
1759    
1760 root 1.1 # missing properties
1761    
1762 root 1.54 object *head (object *op)
1763     PROTOTYPE: $
1764     CODE:
1765 root 1.134 RETVAL = op->head_ ();
1766 root 1.54 OUTPUT: RETVAL
1767    
1768     int is_head (object *op)
1769     PROTOTYPE: $
1770     CODE:
1771 root 1.134 RETVAL = op->head_ () == op;
1772 root 1.54 OUTPUT: RETVAL
1773    
1774 root 1.1 void
1775     inv (object *obj)
1776     PROTOTYPE: $
1777     PPCODE:
1778     {
1779     object *o;
1780     for (o = obj->inv; o; o = o->below)
1781 root 1.100 XPUSHs (sv_2mortal (to_sv (o)));
1782 root 1.1 }
1783    
1784 root 1.102 void
1785     set_animation (object *op, int idx)
1786     CODE:
1787     SET_ANIMATION (op, idx);
1788    
1789 root 1.58 object *find_best_object_match (object *op, const char *match)
1790    
1791     object *find_marked_object (object *op)
1792    
1793 root 1.109 int need_identify (object *obj);
1794 root 1.1
1795     int apply_shop_mat (object *shop_mat, object *op);
1796    
1797 root 1.27 int move (object *op, int dir, object *originator = op)
1798     CODE:
1799     RETVAL = move_ob (op, dir, originator);
1800     OUTPUT:
1801     RETVAL
1802 root 1.1
1803 root 1.74 void apply (object *applier, object *applied, int flags = 0)
1804     CODE:
1805     manual_apply (applied, applier, flags);
1806 root 1.1
1807 root 1.74 void apply_below (object *op)
1808     CODE:
1809     player_apply_below (op);
1810 root 1.1
1811     object *cf_object_present_archname_inside (object *op, char *whatstr)
1812    
1813     int cf_object_transfer (object *op, int x, int y, int r = 0, object_ornull *orig = 0)
1814    
1815 root 1.61 int cf_object_change_map (object *op, int x, int y, maptile *map)
1816 root 1.1
1817 root 1.116 #//TODO
1818     object *clone_ (object *op, int recursive = 0)
1819 root 1.74 CODE:
1820     if (recursive)
1821     RETVAL = object_create_clone (op);
1822     else
1823     {
1824     RETVAL = object::create ();
1825 root 1.75 op->copy_to (RETVAL);
1826 root 1.74 }
1827     OUTPUT: RETVAL
1828 root 1.1
1829 root 1.74 int pay_item (object *op, object *buyer)
1830     CODE:
1831     RETVAL = pay_for_item (op, buyer);
1832     OUTPUT: RETVAL
1833 root 1.1
1834 root 1.74 int pay_amount (object *op, uint64 amount)
1835     CODE:
1836     RETVAL = pay_for_amount (amount, op);
1837     OUTPUT: RETVAL
1838 root 1.1
1839     void pay_player (object *op, uint64 amount)
1840    
1841     val64 pay_player_arch (object *op, const char *arch, uint64 amount)
1842    
1843 root 1.74 int cast_spell (object *op, object *caster, int dir, object *spell_ob, char *stringarg = 0)
1844 root 1.1
1845 root 1.74 void learn_spell (object *op, object *sp, int special_prayer = 0)
1846     CODE:
1847     do_learn_spell (op, sp, special_prayer);
1848 root 1.1
1849 root 1.74 void forget_spell (object *op, object *sp)
1850     CODE:
1851     do_forget_spell (op, query_name (sp));
1852 root 1.1
1853 root 1.74 object *check_for_spell (object *op, char *spellname)
1854     CODE:
1855     RETVAL = check_spell_known (op, spellname);
1856     OUTPUT: RETVAL
1857 root 1.1
1858 root 1.74 int query_money (object *op)
1859 root 1.1 ALIAS: money = 0
1860    
1861 elmex 1.108 val64 query_cost (object *op, object *who, int flags)
1862 root 1.1 ALIAS: cost = 0
1863    
1864 root 1.74 void spring_trap (object *op, object *victim)
1865 root 1.1
1866 root 1.74 int check_trigger (object *op, object *cause)
1867 root 1.1
1868 root 1.74 void drop (object *who, object *op)
1869 root 1.1
1870 root 1.74 void pick_up (object *who, object *op)
1871 root 1.1
1872 root 1.61 int cf_object_teleport (object *op, maptile *map, int x, int y)
1873 root 1.1
1874 root 1.102 void update_object (object *op, int action)
1875 root 1.1
1876     object *cf_create_object_by_name (const char *name)
1877    
1878     void change_exp (object *op, uint64 exp, const char *skill_name = 0, int flag = 0)
1879    
1880     void player_lvl_adj (object *who, object *skill = 0)
1881    
1882     int kill_object (object *op, int dam = 0, object *hitter = 0, int type = AT_PHYSICAL)
1883    
1884     int calc_skill_exp (object *who, object *op, object *skill);
1885    
1886     void push_button (object *op);
1887    
1888     void use_trigger (object *op);
1889    
1890 root 1.61 void add_button_link (object *button, maptile *map, int connected);
1891 root 1.1
1892     void remove_button_link (object *op);
1893    
1894    
1895     MODULE = cf PACKAGE = cf::object PREFIX = cf_
1896    
1897     object *cf_insert_ob_in_ob (object *ob, object *where)
1898    
1899     # no clean way to get an object from an archetype - stupid idiotic
1900     # dumb kludgy misdesigned plug-in api slowly gets on my nerves.
1901    
1902     object *new (const char *archetype = 0)
1903     PROTOTYPE: ;$
1904     CODE:
1905     RETVAL = archetype ? get_archetype (archetype) : cf_create_object ();
1906     OUTPUT:
1907     RETVAL
1908    
1909 root 1.61 object *insert_ob_in_map_at (object *ob, maptile *where, object_ornull *orig, int flag, int x, int y)
1910 root 1.1 PROTOTYPE: $$$$$$
1911     CODE:
1912     {
1913     int unused_type;
1914     RETVAL = (object *)object_insert (&unused_type, ob, 0, where, orig, flag, x, y);
1915     }
1916    
1917     # syntatic sugar for easier use in event callbacks.
1918     const char *options (object *op)
1919     CODE:
1920     RETVAL = op->name;
1921     OUTPUT:
1922     RETVAL
1923    
1924     player *contr (object *op)
1925     CODE:
1926     RETVAL = op->contr;
1927     OUTPUT: RETVAL
1928    
1929     const char *get_ob_key_value (object *op, const char *key)
1930    
1931     bool set_ob_key_value (object *op, const char *key, const char *value = 0, int add_key = 1)
1932    
1933     object *get_nearest_player (object *ob)
1934     ALIAS: nearest_player = 0
1935     PREINIT:
1936     extern object *get_nearest_player (object *);
1937    
1938     void rangevector (object *ob, object *other, int flags = 0)
1939     PROTOTYPE: $$;$
1940     PPCODE:
1941     {
1942     rv_vector rv;
1943     get_rangevector (ob, other, &rv, flags);
1944     EXTEND (SP, 5);
1945     PUSHs (newSVuv (rv.distance));
1946     PUSHs (newSViv (rv.distance_x));
1947     PUSHs (newSViv (rv.distance_y));
1948     PUSHs (newSViv (rv.direction));
1949     PUSHs (newSVcfapi (CFAPI_POBJECT, rv.part));
1950     }
1951    
1952     bool on_same_map_as (object *ob, object *other)
1953     CODE:
1954     RETVAL = on_same_map (ob, other);
1955     OUTPUT: RETVAL
1956    
1957 root 1.58 const char *
1958     base_name (object *op, int plural = op->nrof > 1)
1959 root 1.1 CODE:
1960 root 1.58 RETVAL = query_base_name (op, plural);
1961 root 1.1 OUTPUT: RETVAL
1962    
1963 elmex 1.86 object *decrease_ob_nr (object *op, unsigned long i)
1964    
1965 root 1.1 MODULE = cf PACKAGE = cf::object::player PREFIX = cf_player_
1966    
1967     player *player (object *op)
1968     CODE:
1969     RETVAL = op->contr;
1970     OUTPUT: RETVAL
1971    
1972 root 1.105 void check_score (object *op)
1973    
1974 root 1.120 void message (object *op, char *txt, int flags = NDI_ORANGE | NDI_UNIQUE)
1975     CODE:
1976     new_draw_info (flags, 0, op, txt);
1977 root 1.1
1978     object *cf_player_send_inventory (object *op)
1979    
1980     char *cf_player_get_ip (object *op)
1981     ALIAS: ip = 0
1982    
1983     object *cf_player_get_marked_item (object *op)
1984     ALIAS: marked_item = 0
1985    
1986     void cf_player_set_marked_item (object *op, object *ob)
1987    
1988     partylist *cf_player_get_party (object *op)
1989     ALIAS: party = 0
1990    
1991     void cf_player_set_party (object *op, partylist *party)
1992    
1993     void kill_player (object *op)
1994    
1995 root 1.58 void esrv_update_item (object *op, int what, object *item)
1996     C_ARGS: what, op, item
1997    
1998 root 1.66 void clear_los (object *op)
1999    
2000 root 1.67 int command_summon (object *op, char *params)
2001    
2002     int command_arrest (object *op, char *params)
2003    
2004     int command_kick (object *op, char *params)
2005    
2006     int command_banish (object *op, char *params)
2007    
2008 root 1.66
2009 root 1.12 MODULE = cf PACKAGE = cf::player PREFIX = cf_player_
2010 root 1.1
2011 root 1.79 INCLUDE: $PERL genacc player ../include/player.h |
2012 root 1.62
2013 root 1.18 int invoke (player *pl, int event, ...)
2014     CODE:
2015     if (KLASS_OF (event) != KLASS_PLAYER) croak ("event class must be PLAYER");
2016 root 1.24 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
2017     for (int i = 2; i < items; i++) av_push (av, SvREFCNT_inc (ST (i)));
2018 root 1.109 RETVAL = pl->invoke ((event_type)event, ARG_AV (av), DT_END);
2019 root 1.18 OUTPUT: RETVAL
2020    
2021 root 1.12 SV *registry (player *pl)
2022 root 1.1
2023 root 1.102 void
2024     save_stats (player *pl)
2025     CODE:
2026     pl->ob->stats.hp = pl->ob->stats.maxhp;
2027     pl->ob->stats.sp = pl->ob->stats.maxsp;
2028     pl->ob->stats.grace = pl->ob->stats.maxgrace;
2029     pl->orig_stats = pl->ob->stats;
2030    
2031 root 1.1 void cf_player_move (player *pl, int dir)
2032    
2033     void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0);
2034    
2035     player *first ()
2036     CODE:
2037     RETVAL = first_player;
2038     OUTPUT: RETVAL
2039    
2040     bool
2041     cell_visible (player *pl, int dx, int dy)
2042     CODE:
2043 root 1.98 RETVAL = FABS (dx) <= pl->ns->mapx / 2 && FABS (dy) <= pl->ns->mapy / 2
2044     && !pl->blocked_los [dx + pl->ns->mapx / 2][dy + pl->ns->mapy / 2];
2045 root 1.1 OUTPUT:
2046     RETVAL
2047    
2048 root 1.4 void
2049 root 1.1 send (player *pl, SV *packet)
2050     CODE:
2051     {
2052     STRLEN len;
2053     char *buf = SvPVbyte (packet, len);
2054    
2055 root 1.100 if (pl->ns)
2056     pl->ns->send_packet (buf, len);
2057 root 1.1 }
2058    
2059     int
2060     listening (player *pl, int new_value = -1)
2061     CODE:
2062     RETVAL = pl->listening;
2063     if (new_value >= 0)
2064     pl->listening = new_value;
2065     OUTPUT:
2066     RETVAL
2067    
2068 root 1.46 void savebed (player *pl, SV *map_path = 0, SV *x = 0, SV *y = 0)
2069 root 1.45 PROTOTYPE: $;$$$
2070 root 1.1 PPCODE:
2071 root 1.45 if (GIMME_V != G_VOID)
2072     {
2073     EXTEND (SP, 3);
2074     PUSHs (sv_2mortal (newSVpv (pl->savebed_map, 0)));
2075     PUSHs (sv_2mortal (newSViv (pl->bed_x)));
2076     PUSHs (sv_2mortal (newSViv (pl->bed_y)));
2077     }
2078 root 1.46 if (map_path) sv_to (map_path, pl->savebed_map);
2079     if (x) sv_to (x, pl->bed_x);
2080     if (y) sv_to (y, pl->bed_y);
2081 root 1.1
2082     void
2083     list ()
2084     PPCODE:
2085 root 1.128 for_all_players (pl)
2086 root 1.100 XPUSHs (sv_2mortal (to_sv (pl)));
2087 root 1.1
2088    
2089     MODULE = cf PACKAGE = cf::map PREFIX = cf_map_
2090    
2091 root 1.61 int invoke (maptile *map, int event, ...)
2092 root 1.18 CODE:
2093     if (KLASS_OF (event) != KLASS_MAP) croak ("event class must be MAP");
2094 root 1.24 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
2095     for (int i = 2; i < items; i++) av_push (av, SvREFCNT_inc (ST (i)));
2096 root 1.109 RETVAL = map->invoke ((event_type)event, ARG_AV (av), DT_END);
2097 root 1.25 OUTPUT: RETVAL
2098 root 1.18
2099 root 1.61 SV *registry (maptile *map)
2100 root 1.12
2101 root 1.61 INCLUDE: $PERL genacc maptile ../include/map.h |
2102 root 1.1
2103 root 1.116 void
2104     maptile::instantiate ()
2105    
2106     maptile *new ()
2107 root 1.1 PROTOTYPE:
2108     CODE:
2109 root 1.116 RETVAL = new maptile;
2110 root 1.1 OUTPUT:
2111     RETVAL
2112    
2113 root 1.116 void
2114 root 1.117 maptile::players ()
2115     PPCODE:
2116     if (GIMME_V == G_SCALAR)
2117 root 1.118 XPUSHs (sv_2mortal (to_sv (THIS->players)));
2118 root 1.117 else if (GIMME_V == G_ARRAY)
2119     {
2120     EXTEND (SP, THIS->players);
2121     for_all_players (pl)
2122     if (pl->ob && pl->ob->map == THIS)
2123 root 1.118 PUSHs (sv_2mortal (to_sv (pl->ob)));
2124 root 1.117 }
2125    
2126 root 1.61 void play_sound_map (maptile *map, int x, int y, int sound_num)
2127 root 1.1
2128 root 1.74 int out_of_map (maptile *map, int x, int y)
2129    
2130 root 1.29 void
2131 root 1.61 trigger (maptile *map, long connection, bool state = true)
2132 root 1.29 CODE:
2133     activate_connection (map, connection, state);
2134    
2135     void
2136 root 1.61 get_connection (maptile *map, long connection)
2137 root 1.29 PPCODE:
2138     oblinkpt *obp = get_connection_links (map, connection);
2139     if (obp)
2140     for (objectlink *ol = obp->link; ol; ol = ol->next)
2141 root 1.65 XPUSHs (sv_2mortal (newSVcfapi (CFAPI_POBJECT, (object *)ol->ob)));
2142 root 1.29
2143 root 1.61 object *cf_map_insert_object_there (maptile *where, object *op, object *originator, int flags)
2144 root 1.1
2145 root 1.61 object *cf_map_insert_object (maptile *where, object* op, int x, int y)
2146 root 1.1
2147 root 1.61 object* cf_map_present_arch_by_name (maptile *map, const char* str, int nx, int ny)
2148 root 1.1 C_ARGS: str, map, nx, ny
2149    
2150     void
2151 root 1.140 get_map_flags (maptile *map, int x, int y)
2152 root 1.1 PPCODE:
2153     {
2154 root 1.61 maptile *nmap = 0;
2155 root 1.1 I16 nx = 0, ny = 0;
2156 root 1.19 int flags = get_map_flags (map, &nmap, x, y, &nx, &ny);
2157 root 1.1
2158     EXTEND (SP, 4);
2159     PUSHs (sv_2mortal (newSViv (flags)));
2160    
2161     if (GIMME_V == G_ARRAY)
2162     {
2163     PUSHs (sv_2mortal (newSVcfapi (CFAPI_PMAP, nmap)));
2164     PUSHs (sv_2mortal (newSViv (nx)));
2165     PUSHs (sv_2mortal (newSViv (ny)));
2166     }
2167     }
2168    
2169     void
2170 root 1.61 at (maptile *map, unsigned int x, unsigned int y)
2171 root 1.1 PROTOTYPE: $$$
2172     PPCODE:
2173     {
2174     object *o;
2175 root 1.61 maptile *nmap = 0;
2176 root 1.1 I16 nx, ny;
2177    
2178 root 1.19 get_map_flags (map, &nmap, x, y, &nx, &ny);
2179 root 1.1
2180     if (nmap)
2181     for (o = GET_MAP_OB (nmap, nx, ny); o; o = o->above)
2182     XPUSHs (sv_2mortal (newSVcfapi (CFAPI_POBJECT, o)));
2183     }
2184    
2185     SV *
2186 root 1.61 bot_at (maptile *obj, unsigned int x, unsigned int y)
2187 root 1.1 PROTOTYPE: $$$
2188     ALIAS:
2189     top_at = 1
2190     flags_at = 2
2191     light_at = 3
2192     move_block_at = 4
2193     move_slow_at = 5
2194     move_on_at = 6
2195     move_off_at = 7
2196     INIT:
2197 root 1.110 if (x >= obj->width || y >= obj->height) XSRETURN_UNDEF;
2198 root 1.1 CODE:
2199     switch (ix)
2200     {
2201     case 0: RETVAL = newSVcfapi (CFAPI_POBJECT, GET_MAP_OB (obj, x, y)); break;
2202     case 1: RETVAL = newSVcfapi (CFAPI_POBJECT, GET_MAP_TOP (obj, x, y)); break;
2203     case 2: RETVAL = newSVuv ( GET_MAP_FLAGS (obj, x, y)); break;
2204     case 3: RETVAL = newSViv ( GET_MAP_LIGHT (obj, x, y)); break;
2205     case 4: RETVAL = newSVuv ( GET_MAP_MOVE_BLOCK (obj, x, y)); break;
2206     case 5: RETVAL = newSVuv ( GET_MAP_MOVE_SLOW (obj, x, y)); break;
2207     case 6: RETVAL = newSVuv ( GET_MAP_MOVE_ON (obj, x, y)); break;
2208     case 7: RETVAL = newSVuv ( GET_MAP_MOVE_OFF (obj, x, y)); break;
2209     }
2210 root 1.122 OUTPUT: RETVAL
2211 root 1.1
2212 elmex 1.70 void fix_walls (maptile *map, int x, int y)
2213    
2214     void fix_walls_around (maptile *map, int x, int y)
2215 root 1.1
2216 root 1.122 const char *
2217     region_name (maptile *m)
2218     CODE:
2219     RETVAL = get_name_of_region_for_map (m);
2220     OUTPUT: RETVAL
2221    
2222 root 1.117 # worst xs function of my life
2223 root 1.140 bool
2224 root 1.117 _create_random_map (\
2225 root 1.140 maptile *self,\
2226 root 1.117 char *wallstyle,\
2227     char *wall_name,\
2228     char *floorstyle,\
2229     char *monsterstyle,\
2230     char *treasurestyle,\
2231     char *layoutstyle,\
2232     char *doorstyle,\
2233     char *decorstyle,\
2234     char *origin_map,\
2235     char *final_map,\
2236     char *exitstyle,\
2237     char *this_map,\
2238     char *exit_on_final_map,\
2239 root 1.146 int xsize,\
2240     int ysize,\
2241 root 1.117 int expand2x,\
2242     int layoutoptions1,\
2243     int layoutoptions2,\
2244     int layoutoptions3,\
2245     int symmetry,\
2246     int difficulty,\
2247     int difficulty_given,\
2248     float difficulty_increase,\
2249     int dungeon_level,\
2250     int dungeon_depth,\
2251     int decoroptions,\
2252     int orientation,\
2253     int origin_y,\
2254     int origin_x,\
2255 root 1.146 U32 random_seed,\
2256 root 1.117 val64 total_map_hp,\
2257     int map_layout_style,\
2258     int treasureoptions,\
2259     int symmetry_used,\
2260 root 1.137 region *region,\
2261     char *custom\
2262 root 1.117 )
2263     CODE:
2264     {
2265     random_map_params rmp;
2266    
2267     assign (rmp.wallstyle , wallstyle);
2268     assign (rmp.wall_name , wall_name);
2269     assign (rmp.floorstyle , floorstyle);
2270     assign (rmp.monsterstyle , monsterstyle);
2271     assign (rmp.treasurestyle , treasurestyle);
2272     assign (rmp.layoutstyle , layoutstyle);
2273     assign (rmp.doorstyle , doorstyle);
2274     assign (rmp.decorstyle , decorstyle);
2275     assign (rmp.exitstyle , exitstyle);
2276     assign (rmp.exit_on_final_map, exit_on_final_map);
2277    
2278 root 1.122 rmp.origin_map = origin_map;
2279     rmp.final_map = final_map;
2280     rmp.this_map = this_map;
2281 root 1.146 rmp.xsize = xsize;
2282     rmp.ysize = ysize;
2283 root 1.117 rmp.expand2x = expand2x;
2284     rmp.layoutoptions1 = layoutoptions1;
2285     rmp.layoutoptions2 = layoutoptions2;
2286     rmp.layoutoptions3 = layoutoptions3;
2287     rmp.symmetry = symmetry;
2288     rmp.difficulty = difficulty;
2289     rmp.difficulty_given = difficulty_given;
2290     rmp.difficulty_increase = difficulty_increase;
2291     rmp.dungeon_level = dungeon_level;
2292     rmp.dungeon_depth = dungeon_depth;
2293     rmp.decoroptions = decoroptions;
2294     rmp.orientation = orientation;
2295     rmp.origin_y = origin_y;
2296     rmp.origin_x = origin_x;
2297     rmp.random_seed = random_seed;
2298     rmp.total_map_hp = total_map_hp;
2299     rmp.map_layout_style = map_layout_style;
2300     rmp.treasureoptions = treasureoptions;
2301     rmp.symmetry_used = symmetry_used;
2302     rmp.region = region;
2303 root 1.137 rmp.custom = custom;
2304 root 1.117
2305 root 1.140 RETVAL = self->generate_random_map (&rmp);
2306 root 1.117 }
2307     OUTPUT:
2308     RETVAL
2309    
2310 root 1.19 MODULE = cf PACKAGE = cf::arch
2311 root 1.1
2312 elmex 1.36 archetype *find (const char *name)
2313     CODE:
2314 root 1.60 RETVAL = archetype::find (name);
2315 elmex 1.36 OUTPUT:
2316     RETVAL
2317    
2318 root 1.19 archetype *first()
2319 root 1.1 PROTOTYPE:
2320 root 1.19 CODE:
2321     RETVAL = first_archetype;
2322     OUTPUT: RETVAL
2323 root 1.1
2324 root 1.45 INCLUDE: $PERL genacc archetype ../include/object.h |
2325 root 1.1
2326 root 1.19 MODULE = cf PACKAGE = cf::party
2327 root 1.1
2328 root 1.19 partylist *first ()
2329 root 1.1 PROTOTYPE:
2330 root 1.19 CODE:
2331     RETVAL = get_firstparty ();
2332     OUTPUT: RETVAL
2333 root 1.1
2334 root 1.119 INCLUDE: $PERL genacc partylist ../include/player.h |
2335 root 1.1
2336 root 1.19 MODULE = cf PACKAGE = cf::region
2337 root 1.1
2338 root 1.122 region *first ()
2339 root 1.1 PROTOTYPE:
2340 root 1.19 CODE:
2341     RETVAL = first_region;
2342     OUTPUT: RETVAL
2343 root 1.1
2344 root 1.122 region *find (char *name)
2345     PROTOTYPE: $
2346     CODE:
2347     RETVAL = get_region_by_name (name);
2348     OUTPUT: RETVAL
2349    
2350 root 1.119 INCLUDE: $PERL genacc region ../include/map.h |
2351 root 1.1
2352 root 1.19 MODULE = cf PACKAGE = cf::living
2353 root 1.1
2354 root 1.45 INCLUDE: $PERL genacc living ../include/living.h |
2355 root 1.1
2356 root 1.76 MODULE = cf PACKAGE = cf::settings
2357    
2358     INCLUDE: $PERL genacc Settings ../include/global.h |
2359    
2360 root 1.84 MODULE = cf PACKAGE = cf::client
2361 root 1.79
2362 root 1.84 INCLUDE: $PERL genacc client ../include/client.h |
2363 root 1.79
2364 root 1.84 int invoke (client *ns, int event, ...)
2365 root 1.79 CODE:
2366 root 1.88 if (KLASS_OF (event) != KLASS_CLIENT) croak ("event class must be CLIENT");
2367 root 1.79 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
2368     for (int i = 2; i < items; i++) av_push (av, SvREFCNT_inc (ST (i)));
2369 root 1.109 RETVAL = ns->invoke ((event_type)event, ARG_AV (av), DT_END);
2370 root 1.79 OUTPUT: RETVAL
2371    
2372 root 1.84 SV *registry (client *ns)
2373 root 1.79
2374 root 1.100 void
2375     list ()
2376     PPCODE:
2377     EXTEND (SP, clients.size ());
2378     for (sockvec::iterator i = clients.begin (); i != clients.end (); ++i)
2379     PUSHs (sv_2mortal (to_sv (*i)));
2380    
2381 root 1.88 void
2382 root 1.100 client::send_packet (SV *packet)
2383     CODE:
2384     {
2385     STRLEN len;
2386     char *buf = SvPVbyte (packet, len);
2387    
2388     THIS->send_packet (buf, len);
2389     }
2390