ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
Revision: 1.190
Committed: Tue Apr 17 18:24:31 2007 UTC (17 years, 1 month ago) by root
Branch: MAIN
Changes since 1.189: +0 -3 lines
Log Message:
- treasurelists and regions can now be freely mixed within the same
  generic resource file. more to come.

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