ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
Revision: 1.181
Committed: Tue Apr 3 00:21:38 2007 UTC (17 years, 2 months ago) by root
Branch: MAIN
Changes since 1.180: +4 -2 lines
Log Message:
- fix ber encoding
- reduce image checksum length to 6 bytes (from 16)
- implement fx packet, which reduces
  face overhead to amortised 10/12 bytes per face instead of
  21/32 bytes and allows an unlimited number of faces
  instead of 2**16.

File Contents

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