ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
Revision: 1.188
Committed: Mon Apr 16 11:09:32 2007 UTC (17 years, 1 month ago) by root
Branch: MAIN
Changes since 1.187: +24 -1 lines
Log Message:
load archetypes and treasures from perl, make terasures reloadable

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.187 inline void sv_to (SV *sv, treasurelist * &v) { v = treasurelist::find (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.188 void
957     coroapi::wait_for_tick ()
958     {
959     CALL_BEGIN (0);
960     CALL_CALL ("cf::wait_for_tick", G_DISCARD);
961     CALL_END;
962     }
963    
964     void
965     coroapi::wait_for_tick_begin ()
966     {
967     CALL_BEGIN (0);
968     CALL_CALL ("cf::wait_for_tick_begin", G_DISCARD);
969     CALL_END;
970     }
971    
972     static void
973     iw_dispatch (pe_event *ev)
974 root 1.85 {
975     iw *w = (iw *)ev->ext_data;
976     w->call (*w);
977     }
978    
979     void
980     iw::alloc ()
981     {
982     pe = GEventAPI->new_idle (0, 0);
983    
984 root 1.150 WaREENTRANT_off (pe);
985 root 1.85 pe->base.callback = (void *)iw_dispatch;
986     pe->base.ext_data = (void *)this;
987     }
988    
989 root 1.80 static void iow_dispatch (pe_event *ev)
990     {
991     iow *w = (iow *)ev->ext_data;
992     w->call (*w, ((pe_ioevent *)ev)->got);
993     }
994    
995     void
996     iow::alloc ()
997     {
998     pe = GEventAPI->new_io (0, 0);
999    
1000 root 1.150 WaREENTRANT_off (pe);
1001 root 1.80 pe->base.callback = (void *)iow_dispatch;
1002     pe->base.ext_data = (void *)this;
1003    
1004 root 1.81 pe->fd = -1;
1005     pe->poll = 0;
1006 root 1.80 }
1007    
1008 root 1.85 void
1009 root 1.80 iow::fd (int fd)
1010     {
1011     pe->fd = fd;
1012     }
1013    
1014     int
1015     iow::poll ()
1016     {
1017     return pe->poll;
1018     }
1019    
1020 root 1.85 void
1021 root 1.80 iow::poll (int events)
1022     {
1023 root 1.81 if (pe->poll != events)
1024     {
1025     if (pe->poll) stop ();
1026     pe->poll = events;
1027     if (pe->poll) start ();
1028     }
1029 root 1.80 }
1030    
1031 root 1.109 void
1032     _connect_to_perl ()
1033     {
1034     stash_cf = gv_stashpv ("cf" , 1);
1035    
1036     stash_cf_object_wrap = gv_stashpv ("cf::object::wrap", 1);
1037     stash_cf_object_player_wrap = gv_stashpv ("cf::object::player::wrap", 1);
1038     stash_cf_player_wrap = gv_stashpv ("cf::player::wrap", 1);
1039     stash_cf_map_wrap = gv_stashpv ("cf::map::wrap" , 1);
1040     stash_cf_client_wrap = gv_stashpv ("cf::client::wrap", 1);
1041     stash_cf_arch_wrap = gv_stashpv ("cf::arch::wrap" , 1);
1042     stash_cf_party_wrap = gv_stashpv ("cf::party::wrap" , 1);
1043     stash_cf_region_wrap = gv_stashpv ("cf::region::wrap", 1);
1044     stash_cf_living_wrap = gv_stashpv ("cf::living::wrap", 1);
1045    
1046 root 1.116 sv_runtime = get_sv ("cf::RUNTIME", 1);
1047     sv_upgrade (sv_runtime, SVt_NV);
1048    
1049 root 1.109 cb_global = get_av ("cf::CB_GLOBAL", 1);
1050     cb_attachable = get_av ("cf::CB_ATTACHABLE", 1);
1051     cb_object = get_av ("cf::CB_OBJECT", 1);
1052     cb_player = get_av ("cf::CB_PLAYER", 1);
1053     cb_client = get_av ("cf::CB_CLIENT", 1);
1054     cb_type = get_av ("cf::CB_TYPE" , 1);
1055     cb_map = get_av ("cf::CB_MAP" , 1);
1056     }
1057    
1058 root 1.1 MODULE = cf PACKAGE = cf PREFIX = cf_
1059    
1060     BOOT:
1061     {
1062 root 1.109 _connect_to_perl ();
1063 root 1.1
1064 root 1.116 I_EVENT_API (PACKAGE); watcher_base::GEventAPI = GEventAPI;
1065     I_CORO_API (PACKAGE); coroapi::GCoroAPI = GCoroAPI;
1066 root 1.80
1067 root 1.109 newCONSTSUB (stash_cf, "VERSION", newSVpv (VERSION, sizeof (VERSION) - 1));
1068 root 1.63
1069 root 1.1 static const struct {
1070     const char *name;
1071     IV iv;
1072     } *civ, const_iv[] = {
1073     # define const_iv(name) { # name, (IV)name },
1074     const_iv (llevError)
1075     const_iv (llevInfo)
1076     const_iv (llevDebug)
1077     const_iv (llevMonster)
1078    
1079 root 1.180 const_iv (Map0Cmd)
1080     const_iv (Map1Cmd)
1081     const_iv (Map1aCmd)
1082    
1083     const_iv (MAP_CLIENT_X)
1084     const_iv (MAP_CLIENT_Y)
1085    
1086 root 1.5 const_iv (MAX_TIME)
1087 root 1.1 const_iv (PLAYER)
1088     const_iv (TRANSPORT)
1089     const_iv (ROD)
1090     const_iv (TREASURE)
1091     const_iv (POTION)
1092     const_iv (FOOD)
1093     const_iv (POISON)
1094     const_iv (BOOK)
1095     const_iv (CLOCK)
1096     const_iv (ARROW)
1097     const_iv (BOW)
1098     const_iv (WEAPON)
1099     const_iv (ARMOUR)
1100     const_iv (PEDESTAL)
1101     const_iv (ALTAR)
1102     const_iv (LOCKED_DOOR)
1103     const_iv (SPECIAL_KEY)
1104     const_iv (MAP)
1105     const_iv (DOOR)
1106     const_iv (KEY)
1107     const_iv (TIMED_GATE)
1108     const_iv (TRIGGER)
1109     const_iv (GRIMREAPER)
1110     const_iv (MAGIC_EAR)
1111     const_iv (TRIGGER_BUTTON)
1112     const_iv (TRIGGER_ALTAR)
1113     const_iv (TRIGGER_PEDESTAL)
1114     const_iv (SHIELD)
1115     const_iv (HELMET)
1116     const_iv (HORN)
1117     const_iv (MONEY)
1118     const_iv (CLASS)
1119     const_iv (GRAVESTONE)
1120     const_iv (AMULET)
1121     const_iv (PLAYERMOVER)
1122     const_iv (TELEPORTER)
1123     const_iv (CREATOR)
1124     const_iv (SKILL)
1125     const_iv (EARTHWALL)
1126     const_iv (GOLEM)
1127     const_iv (THROWN_OBJ)
1128     const_iv (BLINDNESS)
1129     const_iv (GOD)
1130     const_iv (DETECTOR)
1131     const_iv (TRIGGER_MARKER)
1132     const_iv (DEAD_OBJECT)
1133     const_iv (DRINK)
1134     const_iv (MARKER)
1135     const_iv (HOLY_ALTAR)
1136     const_iv (PLAYER_CHANGER)
1137     const_iv (BATTLEGROUND)
1138     const_iv (PEACEMAKER)
1139     const_iv (GEM)
1140     const_iv (FIREWALL)
1141     const_iv (ANVIL)
1142     const_iv (CHECK_INV)
1143     const_iv (MOOD_FLOOR)
1144     const_iv (EXIT)
1145     const_iv (ENCOUNTER)
1146     const_iv (SHOP_FLOOR)
1147     const_iv (SHOP_MAT)
1148     const_iv (RING)
1149     const_iv (FLOOR)
1150     const_iv (FLESH)
1151     const_iv (INORGANIC)
1152     const_iv (SKILL_TOOL)
1153     const_iv (LIGHTER)
1154 elmex 1.92 const_iv (BUILDABLE_WALL)
1155 root 1.1 const_iv (MISC_OBJECT)
1156     const_iv (LAMP)
1157     const_iv (DUPLICATOR)
1158     const_iv (SPELLBOOK)
1159     const_iv (CLOAK)
1160     const_iv (SPINNER)
1161     const_iv (GATE)
1162     const_iv (BUTTON)
1163     const_iv (CF_HANDLE)
1164     const_iv (HOLE)
1165     const_iv (TRAPDOOR)
1166     const_iv (SIGN)
1167     const_iv (BOOTS)
1168     const_iv (GLOVES)
1169     const_iv (SPELL)
1170     const_iv (SPELL_EFFECT)
1171     const_iv (CONVERTER)
1172     const_iv (BRACERS)
1173     const_iv (POISONING)
1174     const_iv (SAVEBED)
1175     const_iv (WAND)
1176     const_iv (SCROLL)
1177     const_iv (DIRECTOR)
1178     const_iv (GIRDLE)
1179     const_iv (FORCE)
1180     const_iv (POTION_EFFECT)
1181     const_iv (EVENT_CONNECTOR)
1182     const_iv (CLOSE_CON)
1183     const_iv (CONTAINER)
1184     const_iv (ARMOUR_IMPROVER)
1185     const_iv (WEAPON_IMPROVER)
1186     const_iv (SKILLSCROLL)
1187     const_iv (DEEP_SWAMP)
1188     const_iv (IDENTIFY_ALTAR)
1189     const_iv (MENU)
1190     const_iv (RUNE)
1191     const_iv (TRAP)
1192     const_iv (POWER_CRYSTAL)
1193     const_iv (CORPSE)
1194     const_iv (DISEASE)
1195     const_iv (SYMPTOM)
1196     const_iv (BUILDER)
1197     const_iv (MATERIAL)
1198     const_iv (ITEM_TRANSFORMER)
1199    
1200 root 1.14 const_iv (NUM_SUBTYPES)
1201    
1202 root 1.1 const_iv (ST_BD_BUILD)
1203     const_iv (ST_BD_REMOVE)
1204    
1205     const_iv (ST_MAT_FLOOR)
1206     const_iv (ST_MAT_WALL)
1207     const_iv (ST_MAT_ITEM)
1208    
1209     const_iv (AT_PHYSICAL)
1210     const_iv (AT_MAGIC)
1211     const_iv (AT_FIRE)
1212     const_iv (AT_ELECTRICITY)
1213     const_iv (AT_COLD)
1214     const_iv (AT_CONFUSION)
1215     const_iv (AT_ACID)
1216     const_iv (AT_DRAIN)
1217     const_iv (AT_WEAPONMAGIC)
1218     const_iv (AT_GHOSTHIT)
1219     const_iv (AT_POISON)
1220     const_iv (AT_SLOW)
1221     const_iv (AT_PARALYZE)
1222     const_iv (AT_TURN_UNDEAD)
1223     const_iv (AT_FEAR)
1224     const_iv (AT_CANCELLATION)
1225     const_iv (AT_DEPLETE)
1226     const_iv (AT_DEATH)
1227     const_iv (AT_CHAOS)
1228     const_iv (AT_COUNTERSPELL)
1229     const_iv (AT_GODPOWER)
1230     const_iv (AT_HOLYWORD)
1231     const_iv (AT_BLIND)
1232     const_iv (AT_INTERNAL)
1233     const_iv (AT_LIFE_STEALING)
1234     const_iv (AT_DISEASE)
1235    
1236     const_iv (WEAP_HIT)
1237     const_iv (WEAP_SLASH)
1238     const_iv (WEAP_PIERCE)
1239     const_iv (WEAP_CLEAVE)
1240     const_iv (WEAP_SLICE)
1241     const_iv (WEAP_STAB)
1242     const_iv (WEAP_WHIP)
1243     const_iv (WEAP_CRUSH)
1244     const_iv (WEAP_BLUD)
1245    
1246     const_iv (FLAG_ALIVE)
1247     const_iv (FLAG_WIZ)
1248     const_iv (FLAG_REMOVED)
1249     const_iv (FLAG_FREED)
1250     const_iv (FLAG_WAS_WIZ)
1251     const_iv (FLAG_APPLIED)
1252     const_iv (FLAG_UNPAID)
1253     const_iv (FLAG_USE_SHIELD)
1254     const_iv (FLAG_NO_PICK)
1255     const_iv (FLAG_ANIMATE)
1256     const_iv (FLAG_MONSTER)
1257     const_iv (FLAG_FRIENDLY)
1258     const_iv (FLAG_GENERATOR)
1259     const_iv (FLAG_IS_THROWN)
1260     const_iv (FLAG_AUTO_APPLY)
1261     const_iv (FLAG_PLAYER_SOLD)
1262     const_iv (FLAG_SEE_INVISIBLE)
1263     const_iv (FLAG_CAN_ROLL)
1264     const_iv (FLAG_OVERLAY_FLOOR)
1265     const_iv (FLAG_IS_TURNABLE)
1266     const_iv (FLAG_IS_USED_UP)
1267     const_iv (FLAG_IDENTIFIED)
1268     const_iv (FLAG_REFLECTING)
1269     const_iv (FLAG_CHANGING)
1270     const_iv (FLAG_SPLITTING)
1271     const_iv (FLAG_HITBACK)
1272     const_iv (FLAG_STARTEQUIP)
1273     const_iv (FLAG_BLOCKSVIEW)
1274     const_iv (FLAG_UNDEAD)
1275     const_iv (FLAG_SCARED)
1276     const_iv (FLAG_UNAGGRESSIVE)
1277     const_iv (FLAG_REFL_MISSILE)
1278     const_iv (FLAG_REFL_SPELL)
1279     const_iv (FLAG_NO_MAGIC)
1280     const_iv (FLAG_NO_FIX_PLAYER)
1281     const_iv (FLAG_IS_LIGHTABLE)
1282     const_iv (FLAG_TEAR_DOWN)
1283     const_iv (FLAG_RUN_AWAY)
1284     const_iv (FLAG_PICK_UP)
1285     const_iv (FLAG_UNIQUE)
1286     const_iv (FLAG_NO_DROP)
1287     const_iv (FLAG_WIZCAST)
1288     const_iv (FLAG_CAST_SPELL)
1289     const_iv (FLAG_USE_SCROLL)
1290     const_iv (FLAG_USE_RANGE)
1291     const_iv (FLAG_USE_BOW)
1292     const_iv (FLAG_USE_ARMOUR)
1293     const_iv (FLAG_USE_WEAPON)
1294     const_iv (FLAG_USE_RING)
1295     const_iv (FLAG_READY_RANGE)
1296     const_iv (FLAG_READY_BOW)
1297     const_iv (FLAG_XRAYS)
1298     const_iv (FLAG_NO_APPLY)
1299     const_iv (FLAG_IS_FLOOR)
1300     const_iv (FLAG_LIFESAVE)
1301     const_iv (FLAG_NO_STRENGTH)
1302     const_iv (FLAG_SLEEP)
1303     const_iv (FLAG_STAND_STILL)
1304     const_iv (FLAG_RANDOM_MOVE)
1305     const_iv (FLAG_ONLY_ATTACK)
1306     const_iv (FLAG_CONFUSED)
1307     const_iv (FLAG_STEALTH)
1308     const_iv (FLAG_WIZPASS)
1309     const_iv (FLAG_IS_LINKED)
1310     const_iv (FLAG_CURSED)
1311     const_iv (FLAG_DAMNED)
1312     const_iv (FLAG_SEE_ANYWHERE)
1313     const_iv (FLAG_KNOWN_MAGICAL)
1314     const_iv (FLAG_KNOWN_CURSED)
1315     const_iv (FLAG_CAN_USE_SKILL)
1316     const_iv (FLAG_BEEN_APPLIED)
1317     const_iv (FLAG_READY_SCROLL)
1318     const_iv (FLAG_USE_ROD)
1319     const_iv (FLAG_USE_HORN)
1320     const_iv (FLAG_MAKE_INVIS)
1321     const_iv (FLAG_INV_LOCKED)
1322     const_iv (FLAG_IS_WOODED)
1323     const_iv (FLAG_IS_HILLY)
1324     const_iv (FLAG_READY_SKILL)
1325     const_iv (FLAG_READY_WEAPON)
1326     const_iv (FLAG_NO_SKILL_IDENT)
1327     const_iv (FLAG_BLIND)
1328     const_iv (FLAG_SEE_IN_DARK)
1329     const_iv (FLAG_IS_CAULDRON)
1330     const_iv (FLAG_NO_STEAL)
1331     const_iv (FLAG_ONE_HIT)
1332     const_iv (FLAG_CLIENT_SENT)
1333     const_iv (FLAG_BERSERK)
1334     const_iv (FLAG_NEUTRAL)
1335     const_iv (FLAG_NO_ATTACK)
1336     const_iv (FLAG_NO_DAMAGE)
1337     const_iv (FLAG_OBJ_ORIGINAL)
1338     const_iv (FLAG_OBJ_SAVE_ON_OVL)
1339     const_iv (FLAG_ACTIVATE_ON_PUSH)
1340     const_iv (FLAG_ACTIVATE_ON_RELEASE)
1341     const_iv (FLAG_IS_WATER)
1342     const_iv (FLAG_CONTENT_ON_GEN)
1343     const_iv (FLAG_IS_A_TEMPLATE)
1344     const_iv (FLAG_IS_BUILDABLE)
1345 root 1.138 const_iv (FLAG_DESTROY_ON_DEATH)
1346 root 1.147 const_iv (FLAG_NO_MAP_SAVE)
1347 root 1.1
1348     const_iv (NDI_BLACK)
1349     const_iv (NDI_WHITE)
1350     const_iv (NDI_NAVY)
1351     const_iv (NDI_RED)
1352     const_iv (NDI_ORANGE)
1353     const_iv (NDI_BLUE)
1354     const_iv (NDI_DK_ORANGE)
1355     const_iv (NDI_GREEN)
1356     const_iv (NDI_LT_GREEN)
1357     const_iv (NDI_GREY)
1358     const_iv (NDI_BROWN)
1359     const_iv (NDI_GOLD)
1360     const_iv (NDI_TAN)
1361     const_iv (NDI_MAX_COLOR)
1362     const_iv (NDI_COLOR_MASK)
1363     const_iv (NDI_UNIQUE)
1364     const_iv (NDI_ALL)
1365    
1366 root 1.58 const_iv (UPD_LOCATION)
1367     const_iv (UPD_FLAGS)
1368     const_iv (UPD_WEIGHT)
1369     const_iv (UPD_FACE)
1370     const_iv (UPD_NAME)
1371     const_iv (UPD_ANIM)
1372     const_iv (UPD_ANIMSPEED)
1373     const_iv (UPD_NROF)
1374    
1375     const_iv (UPD_SP_MANA)
1376     const_iv (UPD_SP_GRACE)
1377     const_iv (UPD_SP_DAMAGE)
1378    
1379 root 1.1 const_iv (F_APPLIED)
1380     const_iv (F_LOCATION)
1381     const_iv (F_UNPAID)
1382     const_iv (F_MAGIC)
1383     const_iv (F_CURSED)
1384     const_iv (F_DAMNED)
1385     const_iv (F_OPEN)
1386     const_iv (F_NOPICK)
1387     const_iv (F_LOCKED)
1388    
1389     const_iv (F_BUY)
1390     const_iv (F_SHOP)
1391     const_iv (F_SELL)
1392    
1393     const_iv (P_BLOCKSVIEW)
1394 root 1.91 const_iv (P_PLAYER)
1395 root 1.1 const_iv (P_NO_MAGIC)
1396     const_iv (P_IS_ALIVE)
1397     const_iv (P_NO_CLERIC)
1398     const_iv (P_OUT_OF_MAP)
1399     const_iv (P_NEW_MAP)
1400 root 1.121 const_iv (P_UPTODATE)
1401 root 1.1
1402     const_iv (UP_OBJ_INSERT)
1403     const_iv (UP_OBJ_REMOVE)
1404     const_iv (UP_OBJ_CHANGE)
1405     const_iv (UP_OBJ_FACE)
1406    
1407     const_iv (INS_NO_MERGE)
1408     const_iv (INS_ABOVE_FLOOR_ONLY)
1409     const_iv (INS_NO_WALK_ON)
1410     const_iv (INS_ON_TOP)
1411     const_iv (INS_BELOW_ORIGINATOR)
1412     const_iv (INS_MAP_LOAD)
1413    
1414     const_iv (WILL_APPLY_HANDLE)
1415     const_iv (WILL_APPLY_TREASURE)
1416     const_iv (WILL_APPLY_EARTHWALL)
1417     const_iv (WILL_APPLY_DOOR)
1418     const_iv (WILL_APPLY_FOOD)
1419    
1420     const_iv (SAVE_MODE)
1421     const_iv (SAVE_DIR_MODE)
1422    
1423     const_iv (M_PAPER)
1424     const_iv (M_IRON)
1425     const_iv (M_GLASS)
1426     const_iv (M_LEATHER)
1427     const_iv (M_WOOD)
1428     const_iv (M_ORGANIC)
1429     const_iv (M_STONE)
1430     const_iv (M_CLOTH)
1431     const_iv (M_ADAMANT)
1432     const_iv (M_LIQUID)
1433     const_iv (M_SOFT_METAL)
1434     const_iv (M_BONE)
1435     const_iv (M_ICE)
1436     const_iv (M_SPECIAL)
1437    
1438     const_iv (SK_EXP_ADD_SKILL)
1439     const_iv (SK_EXP_TOTAL)
1440     const_iv (SK_EXP_NONE)
1441     const_iv (SK_SUBTRACT_SKILL_EXP)
1442 elmex 1.39 const_iv (SK_EXP_SKILL_ONLY)
1443 root 1.1
1444     const_iv (SK_LOCKPICKING)
1445     const_iv (SK_HIDING)
1446     const_iv (SK_SMITHERY)
1447     const_iv (SK_BOWYER)
1448     const_iv (SK_JEWELER)
1449     const_iv (SK_ALCHEMY)
1450     const_iv (SK_STEALING)
1451     const_iv (SK_LITERACY)
1452     const_iv (SK_BARGAINING)
1453     const_iv (SK_JUMPING)
1454     const_iv (SK_DET_MAGIC)
1455     const_iv (SK_ORATORY)
1456     const_iv (SK_SINGING)
1457     const_iv (SK_DET_CURSE)
1458     const_iv (SK_FIND_TRAPS)
1459     const_iv (SK_MEDITATION)
1460     const_iv (SK_PUNCHING)
1461     const_iv (SK_FLAME_TOUCH)
1462     const_iv (SK_KARATE)
1463     const_iv (SK_CLIMBING)
1464     const_iv (SK_WOODSMAN)
1465     const_iv (SK_INSCRIPTION)
1466     const_iv (SK_ONE_HANDED_WEAPON)
1467     const_iv (SK_MISSILE_WEAPON)
1468     const_iv (SK_THROWING)
1469     const_iv (SK_USE_MAGIC_ITEM)
1470     const_iv (SK_DISARM_TRAPS)
1471     const_iv (SK_SET_TRAP)
1472     const_iv (SK_THAUMATURGY)
1473     const_iv (SK_PRAYING)
1474     const_iv (SK_CLAWING)
1475     const_iv (SK_LEVITATION)
1476     const_iv (SK_SUMMONING)
1477     const_iv (SK_PYROMANCY)
1478     const_iv (SK_EVOCATION)
1479     const_iv (SK_SORCERY)
1480     const_iv (SK_TWO_HANDED_WEAPON)
1481     const_iv (SK_SPARK_TOUCH)
1482     const_iv (SK_SHIVER)
1483     const_iv (SK_ACID_SPLASH)
1484     const_iv (SK_POISON_NAIL)
1485    
1486     const_iv (SOUND_NEW_PLAYER)
1487     const_iv (SOUND_FIRE_ARROW)
1488     const_iv (SOUND_LEARN_SPELL)
1489     const_iv (SOUND_FUMBLE_SPELL)
1490     const_iv (SOUND_WAND_POOF)
1491     const_iv (SOUND_OPEN_DOOR)
1492     const_iv (SOUND_PUSH_PLAYER)
1493     const_iv (SOUND_PLAYER_HITS1)
1494     const_iv (SOUND_PLAYER_HITS2)
1495     const_iv (SOUND_PLAYER_HITS3)
1496     const_iv (SOUND_PLAYER_HITS4)
1497     const_iv (SOUND_PLAYER_IS_HIT1)
1498     const_iv (SOUND_PLAYER_IS_HIT2)
1499     const_iv (SOUND_PLAYER_IS_HIT3)
1500     const_iv (SOUND_PLAYER_KILLS)
1501     const_iv (SOUND_PET_IS_KILLED)
1502     const_iv (SOUND_PLAYER_DIES)
1503     const_iv (SOUND_OB_EVAPORATE)
1504     const_iv (SOUND_OB_EXPLODE)
1505     const_iv (SOUND_CLOCK)
1506     const_iv (SOUND_TURN_HANDLE)
1507     const_iv (SOUND_FALL_HOLE)
1508     const_iv (SOUND_DRINK_POISON)
1509     const_iv (SOUND_CAST_SPELL_0)
1510    
1511     const_iv (PREFER_LOW)
1512     const_iv (PREFER_HIGH)
1513    
1514     const_iv (ATNR_PHYSICAL)
1515     const_iv (ATNR_MAGIC)
1516     const_iv (ATNR_FIRE)
1517     const_iv (ATNR_ELECTRICITY)
1518     const_iv (ATNR_COLD)
1519     const_iv (ATNR_CONFUSION)
1520     const_iv (ATNR_ACID)
1521     const_iv (ATNR_DRAIN)
1522     const_iv (ATNR_WEAPONMAGIC)
1523     const_iv (ATNR_GHOSTHIT)
1524     const_iv (ATNR_POISON)
1525     const_iv (ATNR_SLOW)
1526     const_iv (ATNR_PARALYZE)
1527     const_iv (ATNR_TURN_UNDEAD)
1528     const_iv (ATNR_FEAR)
1529     const_iv (ATNR_CANCELLATION)
1530     const_iv (ATNR_DEPLETE)
1531     const_iv (ATNR_DEATH)
1532     const_iv (ATNR_CHAOS)
1533     const_iv (ATNR_COUNTERSPELL)
1534     const_iv (ATNR_GODPOWER)
1535     const_iv (ATNR_HOLYWORD)
1536     const_iv (ATNR_BLIND)
1537     const_iv (ATNR_INTERNAL)
1538     const_iv (ATNR_LIFE_STEALING)
1539     const_iv (ATNR_DISEASE)
1540    
1541     const_iv (MAP_IN_MEMORY)
1542     const_iv (MAP_SWAPPED)
1543     const_iv (MAP_LOADING)
1544     const_iv (MAP_SAVING)
1545 root 1.7
1546 root 1.109 const_iv (KLASS_ATTACHABLE)
1547 root 1.7 const_iv (KLASS_GLOBAL)
1548     const_iv (KLASS_OBJECT)
1549 root 1.96 const_iv (KLASS_CLIENT)
1550 root 1.7 const_iv (KLASS_PLAYER)
1551     const_iv (KLASS_MAP)
1552 root 1.99
1553 root 1.100 const_iv (CS_QUERY_YESNO)
1554     const_iv (CS_QUERY_SINGLECHAR)
1555     const_iv (CS_QUERY_HIDEINPUT)
1556    
1557 root 1.99 const_iv (ST_DEAD)
1558     const_iv (ST_SETUP)
1559     const_iv (ST_PLAYING)
1560     const_iv (ST_CUSTOM)
1561    
1562     const_iv (ST_CHANGE_CLASS)
1563 root 1.116
1564     const_iv (IO_HEADER)
1565     const_iv (IO_OBJECTS)
1566     const_iv (IO_UNIQUES)
1567 root 1.117
1568     // random map generator
1569     const_iv (LAYOUT_NONE)
1570     const_iv (LAYOUT_ONION)
1571     const_iv (LAYOUT_MAZE)
1572     const_iv (LAYOUT_SPIRAL)
1573     const_iv (LAYOUT_ROGUELIKE)
1574     const_iv (LAYOUT_SNAKE)
1575     const_iv (LAYOUT_SQUARE_SPIRAL)
1576    
1577     const_iv (RMOPT_RANDOM)
1578     const_iv (RMOPT_CENTERED)
1579     const_iv (RMOPT_LINEAR)
1580     const_iv (RMOPT_BOTTOM_C)
1581     const_iv (RMOPT_BOTTOM_R)
1582     const_iv (RMOPT_IRR_SPACE)
1583     const_iv (RMOPT_WALL_OFF)
1584     const_iv (RMOPT_WALLS_ONLY)
1585     const_iv (RMOPT_NO_DOORS)
1586    
1587     const_iv (SYMMETRY_RANDOM)
1588     const_iv (SYMMETRY_NONE)
1589     const_iv (SYMMETRY_X)
1590     const_iv (SYMMETRY_Y)
1591     const_iv (SYMMETRY_XY)
1592 root 1.1 };
1593    
1594     for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
1595 root 1.109 newCONSTSUB (stash_cf, (char *)civ->name, newSViv (civ->iv));
1596 root 1.1
1597     static const struct {
1598     const char *name;
1599 root 1.14 int skip;
1600 root 1.7 IV klass;
1601 root 1.1 IV iv;
1602 root 1.6 } *eiv, event_iv[] = {
1603 root 1.14 # define def(klass,name) { "EVENT_" # klass "_" # name, sizeof ("EVENT_" # klass), (IV)KLASS_ ## klass, (IV)EVENT_ ## klass ## _ ## name },
1604 root 1.6 # include "eventinc.h"
1605     # undef def
1606     };
1607    
1608     AV *av = get_av ("cf::EVENT", 1);
1609    
1610     for (eiv = event_iv + sizeof (event_iv) / sizeof (event_iv [0]); eiv-- > event_iv; )
1611 root 1.7 {
1612     AV *event = newAV ();
1613 root 1.14 av_push (event, newSVpv ((char *)eiv->name + eiv->skip, 0));
1614 root 1.7 av_push (event, newSViv (eiv->klass));
1615     av_store (av, eiv->iv, newRV_noinc ((SV *)event));
1616 root 1.109 newCONSTSUB (stash_cf, (char *)eiv->name, newSViv (eiv->iv));
1617 root 1.7 }
1618 root 1.14 }
1619    
1620 root 1.109 void _connect_to_perl ()
1621 root 1.14
1622 root 1.47 void _global_reattach ()
1623 root 1.14 CODE:
1624     {
1625     // reattach to all attachable objects in the game.
1626 root 1.128 for_all_clients (ns)
1627     ns->reattach ();
1628 root 1.96
1629 root 1.128 for_all_objects (op)
1630 root 1.109 op->reattach ();
1631 root 1.1 }
1632    
1633     NV floor (NV x)
1634    
1635     NV ceil (NV x)
1636    
1637 root 1.143 NV rndm (...)
1638     CODE:
1639     switch (items)
1640     {
1641     case 0: RETVAL = rndm (); break;
1642     case 1: RETVAL = rndm (SvUV (ST (0))); break;
1643     case 2: RETVAL = rndm (SvIV (ST (0)), SvIV (ST (1))); break;
1644     default: croak ("cf::rndm requires none, one or two parameters."); break;
1645     }
1646     OUTPUT:
1647     RETVAL
1648    
1649 root 1.5 void server_tick ()
1650 root 1.116 CODE:
1651     runtime = SvNVx (sv_runtime);
1652     server_tick ();
1653 root 1.5
1654 root 1.1 void
1655 root 1.183 LOG (int level, utf8_string msg)
1656 root 1.1 PROTOTYPE: $$
1657     C_ARGS: (LogLevel)level, "%s", msg
1658    
1659 root 1.183 octet_string path_combine (octet_string base, octet_string path)
1660 root 1.1 PROTOTYPE: $$
1661    
1662 root 1.183 octet_string path_combine_and_normalize (octet_string base, octet_string path)
1663 root 1.1 PROTOTYPE: $$
1664    
1665 root 1.183 const_octet_string
1666     get_maps_directory (octet_string path)
1667 root 1.1 PROTOTYPE: $
1668     ALIAS: maps_directory = 0
1669 root 1.19 CODE:
1670     RETVAL = create_pathname (path);
1671     OUTPUT: RETVAL
1672 root 1.1
1673     void
1674     sub_generation_inc ()
1675     CODE:
1676     PL_sub_generation++;
1677    
1678 root 1.183 const_octet_string
1679 root 1.1 mapdir ()
1680     PROTOTYPE:
1681     ALIAS:
1682     mapdir = 0
1683     uniquedir = 1
1684     tmpdir = 2
1685     confdir = 3
1686     localdir = 4
1687     playerdir = 5
1688     datadir = 6
1689     CODE:
1690 root 1.19 switch (ix)
1691     {
1692     case 0: RETVAL = settings.mapdir ; break;
1693     case 1: RETVAL = settings.uniquedir; break;
1694     case 2: RETVAL = settings.tmpdir ; break;
1695     case 3: RETVAL = settings.confdir ; break;
1696     case 4: RETVAL = settings.localdir ; break;
1697     case 5: RETVAL = settings.playerdir; break;
1698     case 6: RETVAL = settings.datadir ; break;
1699     }
1700 root 1.1 OUTPUT: RETVAL
1701    
1702 root 1.120 void abort ()
1703    
1704 root 1.183 void fork_abort (octet_string cause = "cf::fork_abort")
1705 root 1.144
1706 root 1.183 void cleanup (octet_string cause, bool make_core = false)
1707 root 1.134
1708 root 1.116 void emergency_save ()
1709    
1710 root 1.156 void _exit (int status = EXIT_SUCCESS)
1711    
1712 root 1.149 UV sv_2watcher (SV *w)
1713     CODE:
1714     RETVAL = (UV)GEventAPI->sv_2watcher (w);
1715     OUTPUT:
1716     RETVAL
1717    
1718 root 1.125 #if _POSIX_MEMLOCK
1719    
1720     int mlockall (int flags = MCL_CURRENT | MCL_FUTURE)
1721    
1722     int munlockall ()
1723    
1724     #endif
1725    
1726 root 1.183 int find_animation (utf8_string text)
1727 root 1.1 PROTOTYPE: $
1728    
1729 root 1.74 int random_roll (int min, int max, object *op, int goodbad);
1730 root 1.1
1731 root 1.183 const_utf8_string cost_string_from_value(uint64 cost, int approx = 0)
1732 root 1.1
1733     int
1734     exp_to_level (val64 exp)
1735     CODE:
1736     {
1737     int i = 0;
1738    
1739     RETVAL = settings.max_level;
1740    
1741     for (i = 1; i <= settings.max_level; i++)
1742     {
1743     if (levels[i] > exp)
1744     {
1745     RETVAL = i - 1;
1746     break;
1747     }
1748     }
1749     }
1750     OUTPUT: RETVAL
1751    
1752     val64
1753     level_to_min_exp (int level)
1754     CODE:
1755     if (level > settings.max_level)
1756     RETVAL = levels[settings.max_level];
1757     else if (level < 1)
1758     RETVAL = 0;
1759     else
1760     RETVAL = levels[level];
1761     OUTPUT: RETVAL
1762    
1763     SV *
1764     resistance_to_string (int atnr)
1765     CODE:
1766     if (atnr >= 0 && atnr < NROFATTACKS)
1767     RETVAL = newSVpv (resist_plus[atnr], 0);
1768     else
1769     XSRETURN_UNDEF;
1770     OUTPUT: RETVAL
1771    
1772 root 1.162 bool
1773 root 1.183 load_resource_file (octet_string filename)
1774 root 1.162
1775 root 1.188 bool
1776     load_archetype_file (octet_string filename)
1777    
1778     bool
1779     load_treasure_file (octet_string filename)
1780    
1781 root 1.97 MODULE = cf PACKAGE = cf::attachable
1782    
1783 root 1.27 int
1784 root 1.97 valid (SV *obj)
1785 root 1.27 CODE:
1786     RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext);
1787     OUTPUT:
1788     RETVAL
1789    
1790 root 1.164 void
1791     debug_trace (attachable *obj, bool on = true)
1792     CODE:
1793     obj->flags &= ~attachable::F_DEBUG_TRACE;
1794     if (on)
1795     obj->flags |= attachable::F_DEBUG_TRACE;
1796    
1797 root 1.153 int mortals_size ()
1798     CODE:
1799     RETVAL = attachable::mortals.size ();
1800     OUTPUT: RETVAL
1801    
1802     #object *mortals (U32 index)
1803     # CODE:
1804     # RETVAL = index < attachable::mortals.size () ? attachable::mortals [index] : 0;
1805     # OUTPUT: RETVAL
1806    
1807 root 1.173 INCLUDE: $PERL $srcdir/genacc attachable ../include/cfperl.h |
1808 root 1.115
1809 root 1.101 MODULE = cf PACKAGE = cf::global
1810    
1811     int invoke (SV *klass, int event, ...)
1812     CODE:
1813     if (KLASS_OF (event) != KLASS_GLOBAL) croak ("event class must be GLOBAL");
1814     AV *av = (AV *)sv_2mortal ((SV *)newAV ());
1815     for (int i = 1; i < items; i++) av_push (av, SvREFCNT_inc (ST (i)));
1816 root 1.109 RETVAL = gbl_ev.invoke ((event_type)event, ARG_AV (av), DT_END);
1817 root 1.101 OUTPUT: RETVAL
1818    
1819 root 1.1 MODULE = cf PACKAGE = cf::object PREFIX = cf_object_
1820    
1821 root 1.173 INCLUDE: $PERL $srcdir/genacc object ../include/object.h |
1822 root 1.62
1823 root 1.18 int invoke (object *op, int event, ...)
1824     CODE:
1825     if (KLASS_OF (event) != KLASS_OBJECT) croak ("event class must be OBJECT");
1826 root 1.24 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
1827     for (int i = 2; i < items; i++) av_push (av, SvREFCNT_inc (ST (i)));
1828 root 1.109 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END);
1829 root 1.18 OUTPUT: RETVAL
1830    
1831     SV *registry (object *op)
1832    
1833 root 1.134 int objects_size ()
1834     CODE:
1835     RETVAL = objects.size ();
1836     OUTPUT: RETVAL
1837    
1838     object *objects (U32 index)
1839     CODE:
1840     RETVAL = index < objects.size () ? objects [index] : 0;
1841     OUTPUT: RETVAL
1842    
1843     int actives_size ()
1844     CODE:
1845     RETVAL = actives.size ();
1846     OUTPUT: RETVAL
1847    
1848     object *actives (U32 index)
1849 root 1.57 CODE:
1850 root 1.134 RETVAL = index < actives.size () ? actives [index] : 0;
1851 root 1.57 OUTPUT: RETVAL
1852    
1853 root 1.1 # missing properties
1854    
1855 root 1.54 object *head (object *op)
1856     PROTOTYPE: $
1857     CODE:
1858 root 1.134 RETVAL = op->head_ ();
1859 root 1.54 OUTPUT: RETVAL
1860    
1861     int is_head (object *op)
1862     PROTOTYPE: $
1863     CODE:
1864 root 1.134 RETVAL = op->head_ () == op;
1865 root 1.54 OUTPUT: RETVAL
1866    
1867 root 1.1 void
1868     inv (object *obj)
1869     PROTOTYPE: $
1870     PPCODE:
1871     {
1872     object *o;
1873     for (o = obj->inv; o; o = o->below)
1874 root 1.100 XPUSHs (sv_2mortal (to_sv (o)));
1875 root 1.1 }
1876    
1877 root 1.102 void
1878     set_animation (object *op, int idx)
1879     CODE:
1880     SET_ANIMATION (op, idx);
1881    
1882 elmex 1.160 int
1883     num_animations (object *op)
1884     CODE:
1885     RETVAL = NUM_ANIMATIONS (op);
1886     OUTPUT: RETVAL
1887    
1888 root 1.183 object *find_best_object_match (object *op, utf8_string match)
1889 root 1.58
1890     object *find_marked_object (object *op)
1891    
1892 root 1.109 int need_identify (object *obj);
1893 root 1.1
1894     int apply_shop_mat (object *shop_mat, object *op);
1895    
1896 pippijn 1.172 int move_player (object *op, int dir)
1897     CODE:
1898     RETVAL = move_player (op, dir);
1899     OUTPUT:
1900     RETVAL
1901    
1902 root 1.27 int move (object *op, int dir, object *originator = op)
1903     CODE:
1904     RETVAL = move_ob (op, dir, originator);
1905     OUTPUT:
1906     RETVAL
1907 root 1.1
1908 root 1.74 void apply (object *applier, object *applied, int flags = 0)
1909     CODE:
1910     manual_apply (applied, applier, flags);
1911 root 1.1
1912 root 1.74 void apply_below (object *op)
1913     CODE:
1914     player_apply_below (op);
1915 root 1.1
1916 root 1.167 int cast_heal (object *op, object *caster, object *spell, int dir = 0)
1917    
1918 root 1.183 object *cf_object_present_archname_inside (object *op, utf8_string whatstr)
1919 root 1.1
1920     int cf_object_transfer (object *op, int x, int y, int r = 0, object_ornull *orig = 0)
1921    
1922 root 1.61 int cf_object_change_map (object *op, int x, int y, maptile *map)
1923 root 1.1
1924 root 1.116 #//TODO
1925     object *clone_ (object *op, int recursive = 0)
1926 root 1.74 CODE:
1927     if (recursive)
1928     RETVAL = object_create_clone (op);
1929     else
1930     {
1931     RETVAL = object::create ();
1932 root 1.75 op->copy_to (RETVAL);
1933 root 1.74 }
1934     OUTPUT: RETVAL
1935 root 1.1
1936 root 1.74 int pay_item (object *op, object *buyer)
1937     CODE:
1938     RETVAL = pay_for_item (op, buyer);
1939     OUTPUT: RETVAL
1940 root 1.1
1941 root 1.74 int pay_amount (object *op, uint64 amount)
1942     CODE:
1943     RETVAL = pay_for_amount (amount, op);
1944     OUTPUT: RETVAL
1945 root 1.1
1946     void pay_player (object *op, uint64 amount)
1947    
1948 root 1.183 val64 pay_player_arch (object *op, utf8_string arch, uint64 amount)
1949 root 1.1
1950 root 1.183 int cast_spell (object *op, object *caster, int dir, object *spell_ob, utf8_string stringarg = 0)
1951 root 1.1
1952 root 1.74 void learn_spell (object *op, object *sp, int special_prayer = 0)
1953     CODE:
1954     do_learn_spell (op, sp, special_prayer);
1955 root 1.1
1956 root 1.74 void forget_spell (object *op, object *sp)
1957     CODE:
1958     do_forget_spell (op, query_name (sp));
1959 root 1.1
1960 root 1.183 object *check_for_spell (object *op, utf8_string spellname)
1961 root 1.74 CODE:
1962     RETVAL = check_spell_known (op, spellname);
1963     OUTPUT: RETVAL
1964 root 1.1
1965 root 1.74 int query_money (object *op)
1966 root 1.1 ALIAS: money = 0
1967    
1968 elmex 1.108 val64 query_cost (object *op, object *who, int flags)
1969 root 1.1 ALIAS: cost = 0
1970    
1971 root 1.74 void spring_trap (object *op, object *victim)
1972 root 1.1
1973 root 1.74 int check_trigger (object *op, object *cause)
1974 root 1.1
1975 root 1.74 void drop (object *who, object *op)
1976 root 1.1
1977 root 1.74 void pick_up (object *who, object *op)
1978 root 1.1
1979 root 1.61 int cf_object_teleport (object *op, maptile *map, int x, int y)
1980 root 1.1
1981 root 1.102 void update_object (object *op, int action)
1982 root 1.1
1983 root 1.183 object *cf_create_object_by_name (utf8_string name)
1984 root 1.1
1985 root 1.183 void change_exp (object *op, uint64 exp, utf8_string skill_name = 0, int flag = 0)
1986 root 1.1
1987     void player_lvl_adj (object *who, object *skill = 0)
1988    
1989     int kill_object (object *op, int dam = 0, object *hitter = 0, int type = AT_PHYSICAL)
1990    
1991     int calc_skill_exp (object *who, object *op, object *skill);
1992    
1993     void push_button (object *op);
1994    
1995     void use_trigger (object *op);
1996    
1997 root 1.61 void add_button_link (object *button, maptile *map, int connected);
1998 root 1.1
1999     void remove_button_link (object *op);
2000    
2001    
2002     MODULE = cf PACKAGE = cf::object PREFIX = cf_
2003    
2004     object *cf_insert_ob_in_ob (object *ob, object *where)
2005    
2006     # no clean way to get an object from an archetype - stupid idiotic
2007     # dumb kludgy misdesigned plug-in api slowly gets on my nerves.
2008    
2009 root 1.183 object *new (utf8_string archetype = 0)
2010 root 1.1 PROTOTYPE: ;$
2011     CODE:
2012     RETVAL = archetype ? get_archetype (archetype) : cf_create_object ();
2013     OUTPUT:
2014     RETVAL
2015    
2016 root 1.61 object *insert_ob_in_map_at (object *ob, maptile *where, object_ornull *orig, int flag, int x, int y)
2017 root 1.1 PROTOTYPE: $$$$$$
2018     CODE:
2019     {
2020     int unused_type;
2021     RETVAL = (object *)object_insert (&unused_type, ob, 0, where, orig, flag, x, y);
2022     }
2023    
2024     player *contr (object *op)
2025     CODE:
2026     RETVAL = op->contr;
2027     OUTPUT: RETVAL
2028    
2029 root 1.183 const_utf8_string get_ob_key_value (object *op, utf8_string key)
2030 root 1.1
2031 root 1.183 bool set_ob_key_value (object *op, utf8_string key, utf8_string value = 0, int add_key = 1)
2032 root 1.1
2033     object *get_nearest_player (object *ob)
2034     ALIAS: nearest_player = 0
2035     PREINIT:
2036     extern object *get_nearest_player (object *);
2037    
2038     void rangevector (object *ob, object *other, int flags = 0)
2039     PROTOTYPE: $$;$
2040     PPCODE:
2041     {
2042     rv_vector rv;
2043     get_rangevector (ob, other, &rv, flags);
2044     EXTEND (SP, 5);
2045     PUSHs (newSVuv (rv.distance));
2046     PUSHs (newSViv (rv.distance_x));
2047     PUSHs (newSViv (rv.distance_y));
2048     PUSHs (newSViv (rv.direction));
2049     PUSHs (newSVcfapi (CFAPI_POBJECT, rv.part));
2050     }
2051    
2052     bool on_same_map_as (object *ob, object *other)
2053     CODE:
2054     RETVAL = on_same_map (ob, other);
2055     OUTPUT: RETVAL
2056    
2057 root 1.183 const_utf8_string
2058 root 1.58 base_name (object *op, int plural = op->nrof > 1)
2059 root 1.1 CODE:
2060 root 1.58 RETVAL = query_base_name (op, plural);
2061 root 1.1 OUTPUT: RETVAL
2062    
2063 elmex 1.86 object *decrease_ob_nr (object *op, unsigned long i)
2064    
2065 root 1.1 MODULE = cf PACKAGE = cf::object::player PREFIX = cf_player_
2066    
2067     player *player (object *op)
2068     CODE:
2069     RETVAL = op->contr;
2070     OUTPUT: RETVAL
2071    
2072 root 1.105 void check_score (object *op)
2073    
2074 root 1.183 void message (object *op, utf8_string txt, int flags = NDI_ORANGE | NDI_UNIQUE)
2075 root 1.120 CODE:
2076     new_draw_info (flags, 0, op, txt);
2077 root 1.1
2078     object *cf_player_send_inventory (object *op)
2079    
2080 root 1.183 octet_string cf_player_get_ip (object *op)
2081 root 1.1 ALIAS: ip = 0
2082    
2083     object *cf_player_get_marked_item (object *op)
2084     ALIAS: marked_item = 0
2085    
2086     void cf_player_set_marked_item (object *op, object *ob)
2087    
2088     partylist *cf_player_get_party (object *op)
2089     ALIAS: party = 0
2090    
2091     void cf_player_set_party (object *op, partylist *party)
2092    
2093     void kill_player (object *op)
2094    
2095 root 1.58 void esrv_update_item (object *op, int what, object *item)
2096     C_ARGS: what, op, item
2097    
2098 root 1.66 void clear_los (object *op)
2099    
2100 root 1.183 int command_summon (object *op, utf8_string params)
2101 root 1.67
2102 root 1.183 int command_arrest (object *op, utf8_string params)
2103 root 1.67
2104 root 1.66
2105 root 1.12 MODULE = cf PACKAGE = cf::player PREFIX = cf_player_
2106 root 1.1
2107 root 1.173 INCLUDE: $PERL $srcdir/genacc player ../include/player.h |
2108 root 1.62
2109 root 1.18 int invoke (player *pl, int event, ...)
2110     CODE:
2111     if (KLASS_OF (event) != KLASS_PLAYER) croak ("event class must be PLAYER");
2112 root 1.24 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
2113     for (int i = 2; i < items; i++) av_push (av, SvREFCNT_inc (ST (i)));
2114 root 1.109 RETVAL = pl->invoke ((event_type)event, ARG_AV (av), DT_END);
2115 root 1.18 OUTPUT: RETVAL
2116    
2117 root 1.12 SV *registry (player *pl)
2118 root 1.1
2119 root 1.102 void
2120     save_stats (player *pl)
2121     CODE:
2122     pl->ob->stats.hp = pl->ob->stats.maxhp;
2123     pl->ob->stats.sp = pl->ob->stats.maxsp;
2124     pl->ob->stats.grace = pl->ob->stats.maxgrace;
2125     pl->orig_stats = pl->ob->stats;
2126    
2127 root 1.1 void cf_player_move (player *pl, int dir)
2128    
2129     void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0);
2130    
2131     bool
2132     cell_visible (player *pl, int dx, int dy)
2133     CODE:
2134 root 1.98 RETVAL = FABS (dx) <= pl->ns->mapx / 2 && FABS (dy) <= pl->ns->mapy / 2
2135     && !pl->blocked_los [dx + pl->ns->mapx / 2][dy + pl->ns->mapy / 2];
2136 root 1.1 OUTPUT:
2137     RETVAL
2138    
2139 root 1.4 void
2140 root 1.1 send (player *pl, SV *packet)
2141     CODE:
2142     {
2143     STRLEN len;
2144     char *buf = SvPVbyte (packet, len);
2145    
2146 root 1.100 if (pl->ns)
2147     pl->ns->send_packet (buf, len);
2148 root 1.1 }
2149    
2150     int
2151     listening (player *pl, int new_value = -1)
2152     CODE:
2153     RETVAL = pl->listening;
2154     if (new_value >= 0)
2155     pl->listening = new_value;
2156     OUTPUT:
2157     RETVAL
2158    
2159 root 1.46 void savebed (player *pl, SV *map_path = 0, SV *x = 0, SV *y = 0)
2160 root 1.45 PROTOTYPE: $;$$$
2161 root 1.1 PPCODE:
2162 root 1.45 if (GIMME_V != G_VOID)
2163     {
2164     EXTEND (SP, 3);
2165     PUSHs (sv_2mortal (newSVpv (pl->savebed_map, 0)));
2166     PUSHs (sv_2mortal (newSViv (pl->bed_x)));
2167     PUSHs (sv_2mortal (newSViv (pl->bed_y)));
2168     }
2169 root 1.46 if (map_path) sv_to (map_path, pl->savebed_map);
2170     if (x) sv_to (x, pl->bed_x);
2171     if (y) sv_to (y, pl->bed_y);
2172 root 1.1
2173     void
2174     list ()
2175     PPCODE:
2176 root 1.128 for_all_players (pl)
2177 root 1.100 XPUSHs (sv_2mortal (to_sv (pl)));
2178 root 1.1
2179    
2180     MODULE = cf PACKAGE = cf::map PREFIX = cf_map_
2181    
2182 root 1.61 int invoke (maptile *map, int event, ...)
2183 root 1.18 CODE:
2184     if (KLASS_OF (event) != KLASS_MAP) croak ("event class must be MAP");
2185 root 1.24 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
2186     for (int i = 2; i < items; i++) av_push (av, SvREFCNT_inc (ST (i)));
2187 root 1.109 RETVAL = map->invoke ((event_type)event, ARG_AV (av), DT_END);
2188 root 1.25 OUTPUT: RETVAL
2189 root 1.18
2190 root 1.61 SV *registry (maptile *map)
2191 root 1.12
2192 root 1.173 INCLUDE: $PERL $srcdir/genacc maptile ../include/map.h |
2193 root 1.1
2194 root 1.116 void
2195     maptile::instantiate ()
2196    
2197     maptile *new ()
2198 root 1.1 PROTOTYPE:
2199     CODE:
2200 root 1.116 RETVAL = new maptile;
2201 root 1.1 OUTPUT:
2202     RETVAL
2203    
2204 root 1.116 void
2205 root 1.117 maptile::players ()
2206     PPCODE:
2207     if (GIMME_V == G_SCALAR)
2208 root 1.118 XPUSHs (sv_2mortal (to_sv (THIS->players)));
2209 root 1.117 else if (GIMME_V == G_ARRAY)
2210     {
2211     EXTEND (SP, THIS->players);
2212     for_all_players (pl)
2213     if (pl->ob && pl->ob->map == THIS)
2214 root 1.118 PUSHs (sv_2mortal (to_sv (pl->ob)));
2215 root 1.117 }
2216    
2217 root 1.156 void
2218 root 1.168 maptile::add_underlay (SV *data, int offset, int stride, SV *palette)
2219 root 1.156 CODE:
2220     {
2221 root 1.168 if (!SvROK (palette) || SvTYPE (SvRV (palette)) != SVt_PVAV)
2222     croak ("maptile::add_underlay: palette must be arrayref");
2223 root 1.156
2224 root 1.168 palette = SvRV (palette);
2225 root 1.156
2226 root 1.168 STRLEN idxlen;
2227     const uint8_t *idx = (const uint8_t *)SvPVbyte (data, idxlen);
2228 root 1.156
2229 root 1.168 for (int x = 0; x < THIS->width; ++x)
2230     for (int y = 0; y < THIS->height; ++y)
2231     {
2232     for (object *op = THIS->at (x, y).bot; op; op = op->above)
2233     if (op->flag [FLAG_IS_FLOOR])
2234     goto skip_space;
2235    
2236     {
2237     int offs = offset + y * stride + x;
2238     if (IN_RANGE_EXC (offs, 0, idxlen))
2239     {
2240     if (SV **elem = av_fetch ((AV *)palette, idx [offs], 0))
2241     {
2242     object *ob = get_archetype (SvPVutf8_nolen (*elem));
2243     ob->flag [FLAG_NO_MAP_SAVE] = true;
2244     THIS->insert (ob, x, y, 0, INS_ABOVE_FLOOR_ONLY);
2245     }
2246     }
2247     }
2248 root 1.156
2249 root 1.168 skip_space: ;
2250     }
2251     }
2252    
2253     void
2254     maptile::set_regiondata (SV *data, int offset, int stride, SV *palette)
2255     CODE:
2256     {
2257     if (!SvROK (palette) || SvTYPE (SvRV (palette)) != SVt_PVAV)
2258     croak ("maptile::set_regiondata: palette must be arrayref");
2259    
2260     palette = SvRV (palette);
2261    
2262     STRLEN idxlen;
2263     const uint8_t *idx = (const uint8_t *)SvPVbyte (data, idxlen);
2264    
2265     region **regionmap = (region **)malloc (
2266     (av_len ((AV *)palette) + 1) * sizeof (region *));
2267     uint8_t *regions = salloc<uint8_t> (THIS->size ());
2268    
2269     for (int i = av_len ((AV *)palette) + 1; i--; )
2270     regionmap [i] = region::find (
2271     SvPVutf8_nolen (*av_fetch ((AV *)palette, i, 1)));
2272    
2273     for (int y = 0; y < THIS->height; ++y)
2274     memcpy (regions + y * THIS->width, idx + offset + y * stride, THIS->width);
2275    
2276     sfree (THIS->regions, THIS->size ());
2277     free (THIS->regionmap);
2278    
2279     THIS->regions = regions;
2280 root 1.156 THIS->regionmap = regionmap;
2281     }
2282    
2283 root 1.61 void play_sound_map (maptile *map, int x, int y, int sound_num)
2284 root 1.1
2285 root 1.74 int out_of_map (maptile *map, int x, int y)
2286    
2287 root 1.29 void
2288 root 1.61 trigger (maptile *map, long connection, bool state = true)
2289 root 1.29 CODE:
2290     activate_connection (map, connection, state);
2291    
2292     void
2293 root 1.61 get_connection (maptile *map, long connection)
2294 root 1.29 PPCODE:
2295     oblinkpt *obp = get_connection_links (map, connection);
2296     if (obp)
2297     for (objectlink *ol = obp->link; ol; ol = ol->next)
2298 root 1.65 XPUSHs (sv_2mortal (newSVcfapi (CFAPI_POBJECT, (object *)ol->ob)));
2299 root 1.29
2300 root 1.61 object *cf_map_insert_object_there (maptile *where, object *op, object *originator, int flags)
2301 root 1.1
2302 root 1.61 object *cf_map_insert_object (maptile *where, object* op, int x, int y)
2303 root 1.1
2304 root 1.61 object* cf_map_present_arch_by_name (maptile *map, const char* str, int nx, int ny)
2305 root 1.1 C_ARGS: str, map, nx, ny
2306    
2307     void
2308 root 1.140 get_map_flags (maptile *map, int x, int y)
2309 root 1.1 PPCODE:
2310     {
2311 root 1.61 maptile *nmap = 0;
2312 root 1.1 I16 nx = 0, ny = 0;
2313 root 1.19 int flags = get_map_flags (map, &nmap, x, y, &nx, &ny);
2314 root 1.1
2315     EXTEND (SP, 4);
2316     PUSHs (sv_2mortal (newSViv (flags)));
2317    
2318     if (GIMME_V == G_ARRAY)
2319     {
2320     PUSHs (sv_2mortal (newSVcfapi (CFAPI_PMAP, nmap)));
2321     PUSHs (sv_2mortal (newSViv (nx)));
2322     PUSHs (sv_2mortal (newSViv (ny)));
2323     }
2324     }
2325    
2326     void
2327 root 1.61 at (maptile *map, unsigned int x, unsigned int y)
2328 root 1.1 PROTOTYPE: $$$
2329     PPCODE:
2330     {
2331     object *o;
2332 root 1.61 maptile *nmap = 0;
2333 root 1.1 I16 nx, ny;
2334    
2335 root 1.19 get_map_flags (map, &nmap, x, y, &nx, &ny);
2336 root 1.1
2337     if (nmap)
2338     for (o = GET_MAP_OB (nmap, nx, ny); o; o = o->above)
2339     XPUSHs (sv_2mortal (newSVcfapi (CFAPI_POBJECT, o)));
2340     }
2341    
2342     SV *
2343 root 1.61 bot_at (maptile *obj, unsigned int x, unsigned int y)
2344 root 1.1 PROTOTYPE: $$$
2345     ALIAS:
2346     top_at = 1
2347     flags_at = 2
2348     light_at = 3
2349     move_block_at = 4
2350     move_slow_at = 5
2351     move_on_at = 6
2352     move_off_at = 7
2353     INIT:
2354 root 1.110 if (x >= obj->width || y >= obj->height) XSRETURN_UNDEF;
2355 root 1.1 CODE:
2356     switch (ix)
2357     {
2358     case 0: RETVAL = newSVcfapi (CFAPI_POBJECT, GET_MAP_OB (obj, x, y)); break;
2359     case 1: RETVAL = newSVcfapi (CFAPI_POBJECT, GET_MAP_TOP (obj, x, y)); break;
2360     case 2: RETVAL = newSVuv ( GET_MAP_FLAGS (obj, x, y)); break;
2361     case 3: RETVAL = newSViv ( GET_MAP_LIGHT (obj, x, y)); break;
2362     case 4: RETVAL = newSVuv ( GET_MAP_MOVE_BLOCK (obj, x, y)); break;
2363     case 5: RETVAL = newSVuv ( GET_MAP_MOVE_SLOW (obj, x, y)); break;
2364     case 6: RETVAL = newSVuv ( GET_MAP_MOVE_ON (obj, x, y)); break;
2365     case 7: RETVAL = newSVuv ( GET_MAP_MOVE_OFF (obj, x, y)); break;
2366     }
2367 root 1.122 OUTPUT: RETVAL
2368 root 1.1
2369 elmex 1.70 void fix_walls (maptile *map, int x, int y)
2370    
2371     void fix_walls_around (maptile *map, int x, int y)
2372 root 1.1
2373 root 1.117 # worst xs function of my life
2374 root 1.140 bool
2375 root 1.117 _create_random_map (\
2376 root 1.140 maptile *self,\
2377 root 1.183 utf8_string wallstyle,\
2378     utf8_string wall_name,\
2379     utf8_string floorstyle,\
2380     utf8_string monsterstyle,\
2381     utf8_string treasurestyle,\
2382     utf8_string layoutstyle,\
2383     utf8_string doorstyle,\
2384     utf8_string decorstyle,\
2385     utf8_string origin_map,\
2386     utf8_string final_map,\
2387     utf8_string exitstyle,\
2388     utf8_string this_map,\
2389     utf8_string exit_on_final_map,\
2390 root 1.146 int xsize,\
2391     int ysize,\
2392 root 1.117 int expand2x,\
2393     int layoutoptions1,\
2394     int layoutoptions2,\
2395     int layoutoptions3,\
2396     int symmetry,\
2397     int difficulty,\
2398     int difficulty_given,\
2399     float difficulty_increase,\
2400     int dungeon_level,\
2401     int dungeon_depth,\
2402     int decoroptions,\
2403     int orientation,\
2404     int origin_y,\
2405     int origin_x,\
2406 root 1.146 U32 random_seed,\
2407 root 1.117 val64 total_map_hp,\
2408     int map_layout_style,\
2409     int treasureoptions,\
2410     int symmetry_used,\
2411 root 1.137 region *region,\
2412 root 1.183 utf8_string custom\
2413 root 1.117 )
2414     CODE:
2415     {
2416     random_map_params rmp;
2417    
2418     assign (rmp.wallstyle , wallstyle);
2419     assign (rmp.wall_name , wall_name);
2420     assign (rmp.floorstyle , floorstyle);
2421     assign (rmp.monsterstyle , monsterstyle);
2422     assign (rmp.treasurestyle , treasurestyle);
2423     assign (rmp.layoutstyle , layoutstyle);
2424     assign (rmp.doorstyle , doorstyle);
2425     assign (rmp.decorstyle , decorstyle);
2426     assign (rmp.exitstyle , exitstyle);
2427     assign (rmp.exit_on_final_map, exit_on_final_map);
2428    
2429 root 1.122 rmp.origin_map = origin_map;
2430     rmp.final_map = final_map;
2431     rmp.this_map = this_map;
2432 root 1.146 rmp.xsize = xsize;
2433     rmp.ysize = ysize;
2434 root 1.117 rmp.expand2x = expand2x;
2435     rmp.layoutoptions1 = layoutoptions1;
2436     rmp.layoutoptions2 = layoutoptions2;
2437     rmp.layoutoptions3 = layoutoptions3;
2438     rmp.symmetry = symmetry;
2439     rmp.difficulty = difficulty;
2440     rmp.difficulty_given = difficulty_given;
2441     rmp.difficulty_increase = difficulty_increase;
2442     rmp.dungeon_level = dungeon_level;
2443     rmp.dungeon_depth = dungeon_depth;
2444     rmp.decoroptions = decoroptions;
2445     rmp.orientation = orientation;
2446     rmp.origin_y = origin_y;
2447     rmp.origin_x = origin_x;
2448     rmp.random_seed = random_seed;
2449     rmp.total_map_hp = total_map_hp;
2450     rmp.map_layout_style = map_layout_style;
2451     rmp.treasureoptions = treasureoptions;
2452     rmp.symmetry_used = symmetry_used;
2453     rmp.region = region;
2454 root 1.137 rmp.custom = custom;
2455 root 1.117
2456 root 1.140 RETVAL = self->generate_random_map (&rmp);
2457 root 1.117 }
2458     OUTPUT:
2459     RETVAL
2460    
2461 root 1.19 MODULE = cf PACKAGE = cf::arch
2462 root 1.1
2463 root 1.183 archetype *find (utf8_string name)
2464 elmex 1.36 CODE:
2465 root 1.60 RETVAL = archetype::find (name);
2466 elmex 1.36 OUTPUT:
2467     RETVAL
2468    
2469 root 1.19 archetype *first()
2470 root 1.1 PROTOTYPE:
2471 root 1.19 CODE:
2472     RETVAL = first_archetype;
2473     OUTPUT: RETVAL
2474 root 1.1
2475 root 1.173 INCLUDE: $PERL $srcdir/genacc archetype ../include/object.h |
2476 root 1.1
2477 root 1.19 MODULE = cf PACKAGE = cf::party
2478 root 1.1
2479 root 1.19 partylist *first ()
2480 root 1.1 PROTOTYPE:
2481 root 1.19 CODE:
2482     RETVAL = get_firstparty ();
2483     OUTPUT: RETVAL
2484 root 1.1
2485 root 1.173 INCLUDE: $PERL $srcdir/genacc partylist ../include/player.h |
2486 root 1.1
2487 root 1.19 MODULE = cf PACKAGE = cf::region
2488 root 1.1
2489 root 1.161 void
2490     list ()
2491     PPCODE:
2492     for_all_regions (rgn)
2493     XPUSHs (sv_2mortal (to_sv (rgn)));
2494    
2495 root 1.183 region *find (utf8_string name)
2496 root 1.161 PROTOTYPE: $
2497 root 1.19 CODE:
2498 root 1.161 RETVAL = region::find (name);
2499 root 1.19 OUTPUT: RETVAL
2500 root 1.1
2501 root 1.183 region *find_fuzzy (utf8_string name)
2502 root 1.122 PROTOTYPE: $
2503     CODE:
2504 root 1.161 RETVAL = region::find_fuzzy (name);
2505 root 1.122 OUTPUT: RETVAL
2506    
2507 root 1.186 int specificity (region *rgn)
2508     CODE:
2509     RETVAL = 0;
2510     while (rgn = rgn->parent)
2511     RETVAL++;
2512     OUTPUT: RETVAL
2513    
2514 root 1.173 INCLUDE: $PERL $srcdir/genacc region ../include/map.h |
2515 root 1.1
2516 root 1.19 MODULE = cf PACKAGE = cf::living
2517 root 1.1
2518 root 1.173 INCLUDE: $PERL $srcdir/genacc living ../include/living.h |
2519 root 1.1
2520 root 1.76 MODULE = cf PACKAGE = cf::settings
2521    
2522 root 1.173 INCLUDE: $PERL $srcdir/genacc Settings ../include/global.h |
2523 root 1.76
2524 root 1.84 MODULE = cf PACKAGE = cf::client
2525 root 1.79
2526 root 1.173 INCLUDE: $PERL $srcdir/genacc client ../include/client.h |
2527 root 1.79
2528 root 1.84 int invoke (client *ns, int event, ...)
2529 root 1.79 CODE:
2530 root 1.88 if (KLASS_OF (event) != KLASS_CLIENT) croak ("event class must be CLIENT");
2531 root 1.79 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
2532     for (int i = 2; i < items; i++) av_push (av, SvREFCNT_inc (ST (i)));
2533 root 1.109 RETVAL = ns->invoke ((event_type)event, ARG_AV (av), DT_END);
2534 root 1.79 OUTPUT: RETVAL
2535    
2536 root 1.84 SV *registry (client *ns)
2537 root 1.79
2538 root 1.100 void
2539     list ()
2540     PPCODE:
2541     EXTEND (SP, clients.size ());
2542     for (sockvec::iterator i = clients.begin (); i != clients.end (); ++i)
2543     PUSHs (sv_2mortal (to_sv (*i)));
2544    
2545 root 1.88 void
2546 root 1.100 client::send_packet (SV *packet)
2547     CODE:
2548     {
2549     STRLEN len;
2550     char *buf = SvPVbyte (packet, len);
2551    
2552     THIS->send_packet (buf, len);
2553     }
2554    
2555 root 1.176 MODULE = cf PACKAGE = cf::face PREFIX = face_
2556    
2557 root 1.185 #INCLUDE: $PERL $srcdir/genacc faceset ../include/face.h |
2558 root 1.176
2559 root 1.183 faceidx face_find (utf8_string name, faceidx defidx = 0)
2560 root 1.176
2561 root 1.183 faceidx alloc (utf8_string name)
2562 root 1.176 CODE:
2563     {
2564     do
2565     {
2566     RETVAL = faces.size ();
2567 root 1.177 faces.resize (RETVAL + 1);
2568 root 1.176 }
2569     while (!RETVAL); // crude way to leave index 0
2570    
2571     faces [RETVAL].name = name;
2572     facehash.insert (std::make_pair (faces [RETVAL].name, RETVAL));
2573    
2574     if (!strcmp (name, BLANK_FACE_NAME)) blank_face = RETVAL;
2575     if (!strcmp (name, EMPTY_FACE_NAME)) empty_face = RETVAL;
2576     }
2577     OUTPUT: RETVAL
2578    
2579 root 1.177 void set (faceidx idx, int visibility, int magicmap)
2580 root 1.176 CODE:
2581 root 1.177 faceinfo *f = face_info (idx);
2582     assert (f);
2583     f->visibility = visibility;
2584     f->magicmap = magicmap;
2585 root 1.176
2586 root 1.184 void set_smooth (faceidx idx, faceidx smooth, int smoothlevel)
2587 root 1.177 CODE:
2588 root 1.184 faceinfo *f = face_info (idx); assert (f);
2589     f->smooth = smooth;
2590     f->smoothlevel = smoothlevel;
2591 root 1.177
2592     void set_data (faceidx idx, int faceset, SV *data, SV *chksum)
2593 root 1.176 CODE:
2594 root 1.182 {
2595 root 1.176 facedata *d = face_data (idx, faceset);
2596 root 1.177 assert (d);
2597 root 1.181 sv_to (data, d->data);
2598     STRLEN clen;
2599     char *cdata = SvPVbyte (chksum, clen);
2600 root 1.182 clen = min (CHKSUM_SIZE, clen);
2601    
2602     if (memcmp (d->chksum, cdata, clen))
2603     {
2604     memcpy (d->chksum, cdata, clen);
2605    
2606     // invalidate existing client face info
2607     for_all_clients (ns)
2608     if (ns->faceset == faceset)
2609     {
2610     ns->faces_sent [idx] = false;
2611     ns->force_newmap = true;
2612     }
2613     }
2614     }
2615 root 1.176
2616 root 1.177 void invalidate (faceidx idx)
2617     CODE:
2618     for_all_clients (ns)
2619 root 1.182 {
2620     ns->faces_sent [idx] = false;
2621     ns->force_newmap = true;
2622     }
2623 root 1.177
2624     void invalidate_all ()
2625     CODE:
2626     for_all_clients (ns)
2627 root 1.182 {
2628     ns->faces_sent.reset ();
2629     ns->force_newmap = true;
2630     }
2631 root 1.177
2632 root 1.185 MODULE = cf PACKAGE = cf::anim PREFIX = anim_
2633    
2634     #INCLUDE: $PERL $srcdir/genacc faceset ../include/anim.h |
2635    
2636     animidx anim_find (utf8_string name)
2637     CODE:
2638     RETVAL = animation::find (name).number;
2639     OUTPUT: RETVAL
2640    
2641     animidx set (utf8_string name, SV *frames, int facings = 1)
2642     CODE:
2643     {
2644     if (!SvROK (frames) && SvTYPE (SvRV (frames)) != SVt_PVAV)
2645     croak ("frames must be an arrayref");
2646    
2647     AV *av = (AV *)SvRV (frames);
2648    
2649     animation *anim = &animation::find (name);
2650     if (anim->number)
2651     {
2652     anim->resize (av_len (av) + 1);
2653     anim->facings = facings;
2654     }
2655     else
2656     anim = &animation::create (name, av_len (av) + 1, facings);
2657    
2658     for (int i = 0; i < anim->num_animations; ++i)
2659     anim->faces [i] = face_find (SvPVutf8_nolen (*av_fetch (av, i, 1)));
2660     }
2661     OUTPUT: RETVAL
2662    
2663     void invalidate_all ()
2664     CODE:
2665     for_all_clients (ns)
2666     ns->anims_sent.reset ();
2667