ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
Revision: 1.174
Committed: Tue Mar 6 03:06:00 2007 UTC (17 years, 3 months ago) by root
Branch: MAIN
CVS Tags: rel-2_0
Changes since 1.173: +0 -7 lines
Log Message:
- automake insists on naming all libdirs .../cfserver now. i have to concur :/
- correctly reattach to players on reload, this likely fixes the reload crash bug.
- init env vars very early, so perl gets to see them.

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