ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
Revision: 1.168
Committed: Thu Feb 15 03:19:02 2007 UTC (17 years, 3 months ago) by root
Branch: MAIN
Changes since 1.167: +56 -8 lines
Log Message:
- implement worldmap underlay and regionset and fill in C++,
  resulting in a *major* speedup in worldmap loading.
- use first arch (e.g. deep_sea) and first region (e.g. panthalassia)
  to fill maps outside the world: less hardcoded content data.
- fix ext/rent.ext to actually check again for entrance.
- temporarily remembver previous map in $ob->{_prev_pos}
  (HACK to make ext/rent.ext work).

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