ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
Revision: 1.177
Committed: Wed Mar 14 00:04:59 2007 UTC (17 years, 2 months ago) by root
Branch: MAIN
Changes since 1.176: +26 -9 lines
Log Message:
- rewrote smooth face handling, as a side-effect, smoothing seems to work
  again and smooth faces can be reloaded.
- the server now sends the full animation for an object the first time
  it is seen, this uses slightly more bandwidth initially, but avoids
  the flickering for objects change their face later.

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