ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
Revision: 1.183
Committed: Mon Apr 9 04:40:39 2007 UTC (17 years, 1 month ago) by root
Branch: MAIN
Changes since 1.182: +50 -52 lines
Log Message:
make an effort of explicitly stating wether a string is a text string (where we use utf8) or binary, likely fixing the palyershop corruption bug

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