ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
(Generate patch)

Comparing deliantra/server/server/cfperl.xs (file contents):
Revision 1.154 by root, Fri Jan 26 21:44:11 2007 UTC vs.
Revision 1.186 by root, Sat Apr 14 07:23:00 2007 UTC

4 4
5/* 5/*
6 * This code is placed under the GNU General Public Licence (GPL) 6 * This code is placed under the GNU General Public Licence (GPL)
7 * 7 *
8 * Copyright (C) 2001-2005 by Chachkoff Yann 8 * Copyright (C) 2001-2005 by Chachkoff Yann
9 * Copyright (C) 2006 by Marc Lehmann <cf@schmorp.de> 9 * Copyright (C) 2006,2007 by Marc Lehmann <cf@schmorp.de>
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 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 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 13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version. 14 * (at your option) any later version.
29#include <plugin_common.h> 29#include <plugin_common.h>
30#include <sounds.h> 30#include <sounds.h>
31#include <cstdarg> 31#include <cstdarg>
32#include <sproto.h> 32#include <sproto.h>
33 33
34#include "loader.h"
34#include "cfperl.h" 35#include "cfperl.h"
35#include "shstr.h" 36#include "shstr.h"
36 37
37#include <unistd.h> 38#include <unistd.h>
38#if _POSIX_MEMLOCK 39#if _POSIX_MEMLOCK
48 49
49extern sint64 *levels; // the experience table 50extern sint64 *levels; // the experience table
50 51
51typedef object object_ornull; 52typedef object object_ornull;
52typedef maptile maptile_ornull; 53typedef maptile maptile_ornull;
54
55typedef char *octet_string;
56typedef char *utf8_string;
57typedef const char *const_octet_string;
58typedef const char *const_utf8_string;
53 59
54#if IVSIZE >= 8 60#if IVSIZE >= 8
55 typedef IV val64; 61 typedef IV val64;
56# define newSVval64 newSViv 62# define newSVval64 newSViv
57# define SvVAL64 SvIV 63# define SvVAL64 SvIV
101 107
102unordered_vector<attachable *> attachable::mortals; 108unordered_vector<attachable *> attachable::mortals;
103 109
104attachable::~attachable () 110attachable::~attachable ()
105{ 111{
112 flags |=0x3300;//D
106 assert (!self); 113 assert (!self);
107 assert (!cb); 114 assert (!cb);
108} 115}
109 116
110int 117int
111attachable::refcnt_cnt () const 118attachable::refcnt_cnt () const
112{ 119{
113 return refcnt + (self ? SvREFCNT (self) - 1 : 0); 120 return refcnt + (self ? SvREFCNT (self) - 1 : 0);
121}
122
123void
124attachable::sever_self ()
125{
126 if (HV *self = this->self)
127 {
128 // keep a refcount because sv_unmagic might call attachable_free,
129 // which might clear self, causing sv_unmagic to crash on a now
130 // invalid object.
131 SvREFCNT_inc (self);
132 hv_clear (self);
133 sv_unmagic ((SV *)self, PERL_MAGIC_ext);
134 SvREFCNT_dec (self);
135
136 // self *must* be null now because thats sv_unmagic's job.
137 assert (!this->self);
138 flags |= 0x80; // severed //D
139 }
114} 140}
115 141
116void 142void
117attachable::optimise () 143attachable::optimise ()
118{ 144{
119 if (self 145 if (self
120 && SvREFCNT (self) == 1 146 && SvREFCNT (self) == 1
121 && !HvTOTALKEYS (self)) 147 && !HvTOTALKEYS (self))
122 { 148 flags |= 0x40,//D
123 SV *self = (SV *)this->self; 149 sever_self ();
124
125 SvREFCNT_inc (self);
126 sv_unmagic (self, PERL_MAGIC_ext);
127 SvREFCNT_dec (self);
128 assert (!this->self);
129 }
130} 150}
131 151
132// check wether the object really is dead 152// check wether the object really is dead
133void 153void
134attachable::do_check () 154attachable::do_check ()
149 SvREFCNT_dec (cb); 169 SvREFCNT_dec (cb);
150 cb = 0; 170 cb = 0;
151 } 171 }
152 172
153 if (self) 173 if (self)
154 { 174 sever_self ();
155 hv_clear (self);
156 175
157 SV *self = (SV *)this->self; 176 flags |= 0x20; //D
158 SvREFCNT_inc (self);
159 sv_unmagic (self, PERL_MAGIC_ext);
160 SvREFCNT_dec (self);
161 // self is now 0
162 assert (!this->self);//D//TODO remove soon
163 }
164
165 mortals.push_back (this); 177 mortals.push_back (this);
166} 178}
167 179
168void 180void
169attachable::destroy () 181attachable::destroy ()
264 276
265 if (!obj->self) 277 if (!obj->self)
266 { 278 {
267 obj->self = newHV (); 279 obj->self = newHV ();
268 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0); 280 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0);
281 obj->flags |= (obj->flags & 0xc0) << 8;
282 obj->flags &= ~0xc0;//D
283 obj->flags |= 0x10;//D
269 284
270 // now bless the object _once_ 285 // now bless the object _once_
271 return sv_bless (newRV_inc ((SV *)obj->self), stash); 286 return sv_bless (newRV_inc ((SV *)obj->self), stash);
272 } 287 }
273 else 288 else
339inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); } 354inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); }
340 355
341inline SV *to_sv (object & v) { return to_sv (&v); } 356inline SV *to_sv (object & v) { return to_sv (&v); }
342inline SV *to_sv (living & v) { return to_sv (&v); } 357inline SV *to_sv (living & v) { return to_sv (&v); }
343 358
344inline SV *to_sv (facetile * v) { return to_sv (v->name); } 359//inline SV *to_sv (faceinfo * v) { return to_sv (v->name); }
345inline SV *to_sv (treasurelist * v) { return to_sv (v->name); } 360inline SV *to_sv (treasurelist * v) { return to_sv (v->name); }
361inline SV *to_sv (std::string & v) { return newSVpvn (v.data (), v.size ()); }
346 362
347inline SV *to_sv (UUID v) 363inline SV *to_sv (UUID v)
348{ 364{
349 char buf[128]; 365 char buf[128];
350 snprintf (buf, 128, "<1,%" PRIx64 ">", v.seq); 366 snprintf (buf, 128, "<1.%" PRIx64 ">", v.seq);
351 return newSVpv (buf, 0); 367 return newSVpv (buf, 0);
352} 368}
353 369
354inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; } 370inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; }
355inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; } 371inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; }
374inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); } 390inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); }
375inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); } 391inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); }
376inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); } 392inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); }
377inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); } 393inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); }
378 394
379inline void sv_to (SV *sv, facetile * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; } 395//inline void sv_to (SV *sv, faceinfo * &v) { v = &faces [face_find (SvPV_nolen (sv), 0)]; }
380inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); } 396inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); }
381 397
382template<class T> 398template<class T>
383inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; } 399inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; }
384 400
388inline void sv_to (SV *sv, rangetype &v) { v = (rangetype) SvIV (sv); } 404inline void sv_to (SV *sv, rangetype &v) { v = (rangetype) SvIV (sv); }
389inline void sv_to (SV *sv, bowtype_t &v) { v = (bowtype_t) SvIV (sv); } 405inline void sv_to (SV *sv, bowtype_t &v) { v = (bowtype_t) SvIV (sv); }
390inline void sv_to (SV *sv, petmode_t &v) { v = (petmode_t) SvIV (sv); } 406inline void sv_to (SV *sv, petmode_t &v) { v = (petmode_t) SvIV (sv); }
391inline void sv_to (SV *sv, usekeytype &v) { v = (usekeytype) SvIV (sv); } 407inline void sv_to (SV *sv, usekeytype &v) { v = (usekeytype) SvIV (sv); }
392inline void sv_to (SV *sv, unapplymode &v) { v = (unapplymode) SvIV (sv); } 408inline void sv_to (SV *sv, unapplymode &v) { v = (unapplymode) SvIV (sv); }
409
410inline void sv_to (SV *sv, std::string &v)
411{
412 STRLEN len;
413 char *data = SvPVbyte (sv, len);
414 v.assign (data, len);
415}
393 416
394inline void sv_to (SV *sv, UUID &v) 417inline void sv_to (SV *sv, UUID &v)
395{ 418{
396 unsigned int version; 419 unsigned int version;
397 420
588 perl = perl_alloc (); 611 perl = perl_alloc ();
589 perl_construct (perl); 612 perl_construct (perl);
590 613
591 PL_exit_flags |= PERL_EXIT_DESTRUCT_END; 614 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
592 615
593 char *argv[] = { 616 const char *argv[] = {
594 "", 617 "",
595 "-e" 618 "-e"
596 "use Event; use Coro;" // required for bootstrap 619 "use Event; use Coro;" // required for bootstrap
597 "cf->bootstrap;" // required for datadir :*> 620 "cf->bootstrap;" // required for datadir :*>
598 "unshift @INC, cf::datadir ();" 621 "unshift @INC, cf::datadir ();"
599 "require cf;" 622 "require cf;"
600 }; 623 };
601 624
602 if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl)) 625 if (perl_parse (perl, xs_init, 2, (char **)argv, (char **)NULL)
626 || perl_run (perl))
603 { 627 {
604 printf ("unable to initialize perl-interpreter, aborting.\n"); 628 printf ("unable to initialize perl-interpreter, aborting.\n");
605 exit (EXIT_FAILURE); 629 exit (EXIT_FAILURE);
606 } 630 }
631
632 {
633 dSP;
634
635 PUSHMARK (SP);
636 PUTBACK;
637 call_pv ("cf::init", G_DISCARD | G_VOID);
638 }
607} 639}
608 640
609void cfperl_main () 641void cfperl_main ()
610{ 642{
611 dSP; 643 dSP;
832 CALL_BEGIN (0); 864 CALL_BEGIN (0);
833 CALL_CALL ("cf::emergency_save", G_VOID); 865 CALL_CALL ("cf::emergency_save", G_VOID);
834 CALL_END; 866 CALL_END;
835} 867}
836 868
869void
870cfperl_cleanup (int make_core)
871{
872 CALL_BEGIN (1);
873 CALL_ARG (make_core);
874 CALL_CALL ("cf::post_cleanup", G_VOID);
875 CALL_END;
876}
877
837maptile * 878maptile *
838maptile::find_sync (const char *path, maptile *origin) 879maptile::find_sync (const char *path, maptile *origin)
839{ 880{
840 CALL_BEGIN (2); 881 CALL_BEGIN (2);
841 CALL_ARG (path); 882 CALL_ARG (path);
1015# define const_iv(name) { # name, (IV)name }, 1056# define const_iv(name) { # name, (IV)name },
1016 const_iv (llevError) 1057 const_iv (llevError)
1017 const_iv (llevInfo) 1058 const_iv (llevInfo)
1018 const_iv (llevDebug) 1059 const_iv (llevDebug)
1019 const_iv (llevMonster) 1060 const_iv (llevMonster)
1061
1062 const_iv (Map0Cmd)
1063 const_iv (Map1Cmd)
1064 const_iv (Map1aCmd)
1065
1066 const_iv (MAP_CLIENT_X)
1067 const_iv (MAP_CLIENT_Y)
1020 1068
1021 const_iv (MAX_TIME) 1069 const_iv (MAX_TIME)
1022 const_iv (PLAYER) 1070 const_iv (PLAYER)
1023 const_iv (TRANSPORT) 1071 const_iv (TRANSPORT)
1024 const_iv (ROD) 1072 const_iv (ROD)
1559{ 1607{
1560 // reattach to all attachable objects in the game. 1608 // reattach to all attachable objects in the game.
1561 for_all_clients (ns) 1609 for_all_clients (ns)
1562 ns->reattach (); 1610 ns->reattach ();
1563 1611
1564 for_all_players (pl)
1565 pl->reattach ();
1566
1567 //TODO
1568 //for (map_container::iterator i = maps.begin (); i != maps.end (); ++i)
1569 // i->second->reattach ();
1570
1571 for_all_objects (op) 1612 for_all_objects (op)
1572 op->reattach (); 1613 op->reattach ();
1573} 1614}
1574 1615
1575NV floor (NV x) 1616NV floor (NV x)
1592 CODE: 1633 CODE:
1593 runtime = SvNVx (sv_runtime); 1634 runtime = SvNVx (sv_runtime);
1594 server_tick (); 1635 server_tick ();
1595 1636
1596void 1637void
1597LOG (int level, char *msg) 1638LOG (int level, utf8_string msg)
1598 PROTOTYPE: $$ 1639 PROTOTYPE: $$
1599 C_ARGS: (LogLevel)level, "%s", msg 1640 C_ARGS: (LogLevel)level, "%s", msg
1600 1641
1601char *path_combine (char *base, char *path) 1642octet_string path_combine (octet_string base, octet_string path)
1602 PROTOTYPE: $$ 1643 PROTOTYPE: $$
1603 1644
1604char *path_combine_and_normalize (char *base, char *path) 1645octet_string path_combine_and_normalize (octet_string base, octet_string path)
1605 PROTOTYPE: $$ 1646 PROTOTYPE: $$
1606 1647
1607const char * 1648const_octet_string
1608get_maps_directory (char *path) 1649get_maps_directory (octet_string path)
1609 PROTOTYPE: $ 1650 PROTOTYPE: $
1610 ALIAS: maps_directory = 0 1651 ALIAS: maps_directory = 0
1611 CODE: 1652 CODE:
1612 RETVAL = create_pathname (path); 1653 RETVAL = create_pathname (path);
1613 OUTPUT: RETVAL 1654 OUTPUT: RETVAL
1615void 1656void
1616sub_generation_inc () 1657sub_generation_inc ()
1617 CODE: 1658 CODE:
1618 PL_sub_generation++; 1659 PL_sub_generation++;
1619 1660
1620char * 1661const_octet_string
1621mapdir () 1662mapdir ()
1622 PROTOTYPE: 1663 PROTOTYPE:
1623 ALIAS: 1664 ALIAS:
1624 mapdir = 0 1665 mapdir = 0
1625 uniquedir = 1 1666 uniquedir = 1
1641 } 1682 }
1642 OUTPUT: RETVAL 1683 OUTPUT: RETVAL
1643 1684
1644void abort () 1685void abort ()
1645 1686
1646void fork_abort (char *cause = "cf::fork_abort") 1687void fork_abort (octet_string cause = "cf::fork_abort")
1647 1688
1648void cleanup (const char *cause, bool make_core = false) 1689void cleanup (octet_string cause, bool make_core = false)
1649 1690
1650void emergency_save () 1691void emergency_save ()
1692
1693void _exit (int status = EXIT_SUCCESS)
1651 1694
1652UV sv_2watcher (SV *w) 1695UV sv_2watcher (SV *w)
1653 CODE: 1696 CODE:
1654 RETVAL = (UV)GEventAPI->sv_2watcher (w); 1697 RETVAL = (UV)GEventAPI->sv_2watcher (w);
1655 OUTPUT: 1698 OUTPUT:
1656 RETVAL 1699 RETVAL
1657 1700
1658void _exit (int status = 0)
1659
1660#if _POSIX_MEMLOCK 1701#if _POSIX_MEMLOCK
1661 1702
1662int mlockall (int flags = MCL_CURRENT | MCL_FUTURE) 1703int mlockall (int flags = MCL_CURRENT | MCL_FUTURE)
1663 1704
1664int munlockall () 1705int munlockall ()
1665 1706
1666#endif 1707#endif
1667 1708
1668int find_animation (char *text) 1709int find_animation (utf8_string text)
1669 PROTOTYPE: $ 1710 PROTOTYPE: $
1670 1711
1671int random_roll (int min, int max, object *op, int goodbad); 1712int random_roll (int min, int max, object *op, int goodbad);
1672 1713
1673const char *cost_string_from_value(uint64 cost, int approx = 0) 1714const_utf8_string cost_string_from_value(uint64 cost, int approx = 0)
1674 1715
1675int 1716int
1676exp_to_level (val64 exp) 1717exp_to_level (val64 exp)
1677 CODE: 1718 CODE:
1678{ 1719{
1709 RETVAL = newSVpv (resist_plus[atnr], 0); 1750 RETVAL = newSVpv (resist_plus[atnr], 0);
1710 else 1751 else
1711 XSRETURN_UNDEF; 1752 XSRETURN_UNDEF;
1712 OUTPUT: RETVAL 1753 OUTPUT: RETVAL
1713 1754
1755bool
1756load_resource_file (octet_string filename)
1757
1714MODULE = cf PACKAGE = cf::attachable 1758MODULE = cf PACKAGE = cf::attachable
1715 1759
1716int 1760int
1717valid (SV *obj) 1761valid (SV *obj)
1718 CODE: 1762 CODE:
1719 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext); 1763 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext);
1720 OUTPUT: 1764 OUTPUT:
1721 RETVAL 1765 RETVAL
1766
1767void
1768debug_trace (attachable *obj, bool on = true)
1769 CODE:
1770 obj->flags &= ~attachable::F_DEBUG_TRACE;
1771 if (on)
1772 obj->flags |= attachable::F_DEBUG_TRACE;
1722 1773
1723int mortals_size () 1774int mortals_size ()
1724 CODE: 1775 CODE:
1725 RETVAL = attachable::mortals.size (); 1776 RETVAL = attachable::mortals.size ();
1726 OUTPUT: RETVAL 1777 OUTPUT: RETVAL
1728#object *mortals (U32 index) 1779#object *mortals (U32 index)
1729# CODE: 1780# CODE:
1730# RETVAL = index < attachable::mortals.size () ? attachable::mortals [index] : 0; 1781# RETVAL = index < attachable::mortals.size () ? attachable::mortals [index] : 0;
1731# OUTPUT: RETVAL 1782# OUTPUT: RETVAL
1732 1783
1733INCLUDE: $PERL genacc attachable ../include/cfperl.h | 1784INCLUDE: $PERL $srcdir/genacc attachable ../include/cfperl.h |
1734 1785
1735MODULE = cf PACKAGE = cf::global 1786MODULE = cf PACKAGE = cf::global
1736 1787
1737int invoke (SV *klass, int event, ...) 1788int invoke (SV *klass, int event, ...)
1738 CODE: 1789 CODE:
1742 RETVAL = gbl_ev.invoke ((event_type)event, ARG_AV (av), DT_END); 1793 RETVAL = gbl_ev.invoke ((event_type)event, ARG_AV (av), DT_END);
1743 OUTPUT: RETVAL 1794 OUTPUT: RETVAL
1744 1795
1745MODULE = cf PACKAGE = cf::object PREFIX = cf_object_ 1796MODULE = cf PACKAGE = cf::object PREFIX = cf_object_
1746 1797
1747INCLUDE: $PERL genacc object ../include/object.h | 1798INCLUDE: $PERL $srcdir/genacc object ../include/object.h |
1748 1799
1749int invoke (object *op, int event, ...) 1800int invoke (object *op, int event, ...)
1750 CODE: 1801 CODE:
1751 if (KLASS_OF (event) != KLASS_OBJECT) croak ("event class must be OBJECT"); 1802 if (KLASS_OF (event) != KLASS_OBJECT) croak ("event class must be OBJECT");
1752 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); 1803 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
1803void 1854void
1804set_animation (object *op, int idx) 1855set_animation (object *op, int idx)
1805 CODE: 1856 CODE:
1806 SET_ANIMATION (op, idx); 1857 SET_ANIMATION (op, idx);
1807 1858
1859int
1860num_animations (object *op)
1861 CODE:
1862 RETVAL = NUM_ANIMATIONS (op);
1863 OUTPUT: RETVAL
1864
1808object *find_best_object_match (object *op, const char *match) 1865object *find_best_object_match (object *op, utf8_string match)
1809 1866
1810object *find_marked_object (object *op) 1867object *find_marked_object (object *op)
1811 1868
1812int need_identify (object *obj); 1869int need_identify (object *obj);
1813 1870
1814int apply_shop_mat (object *shop_mat, object *op); 1871int apply_shop_mat (object *shop_mat, object *op);
1872
1873int move_player (object *op, int dir)
1874 CODE:
1875 RETVAL = move_player (op, dir);
1876 OUTPUT:
1877 RETVAL
1815 1878
1816int move (object *op, int dir, object *originator = op) 1879int move (object *op, int dir, object *originator = op)
1817 CODE: 1880 CODE:
1818 RETVAL = move_ob (op, dir, originator); 1881 RETVAL = move_ob (op, dir, originator);
1819 OUTPUT: 1882 OUTPUT:
1825 1888
1826void apply_below (object *op) 1889void apply_below (object *op)
1827 CODE: 1890 CODE:
1828 player_apply_below (op); 1891 player_apply_below (op);
1829 1892
1893int cast_heal (object *op, object *caster, object *spell, int dir = 0)
1894
1830object *cf_object_present_archname_inside (object *op, char *whatstr) 1895object *cf_object_present_archname_inside (object *op, utf8_string whatstr)
1831 1896
1832int cf_object_transfer (object *op, int x, int y, int r = 0, object_ornull *orig = 0) 1897int cf_object_transfer (object *op, int x, int y, int r = 0, object_ornull *orig = 0)
1833 1898
1834int cf_object_change_map (object *op, int x, int y, maptile *map) 1899int cf_object_change_map (object *op, int x, int y, maptile *map)
1835 1900
1855 RETVAL = pay_for_amount (amount, op); 1920 RETVAL = pay_for_amount (amount, op);
1856 OUTPUT: RETVAL 1921 OUTPUT: RETVAL
1857 1922
1858void pay_player (object *op, uint64 amount) 1923void pay_player (object *op, uint64 amount)
1859 1924
1860val64 pay_player_arch (object *op, const char *arch, uint64 amount) 1925val64 pay_player_arch (object *op, utf8_string arch, uint64 amount)
1861 1926
1862int cast_spell (object *op, object *caster, int dir, object *spell_ob, char *stringarg = 0) 1927int cast_spell (object *op, object *caster, int dir, object *spell_ob, utf8_string stringarg = 0)
1863 1928
1864void learn_spell (object *op, object *sp, int special_prayer = 0) 1929void learn_spell (object *op, object *sp, int special_prayer = 0)
1865 CODE: 1930 CODE:
1866 do_learn_spell (op, sp, special_prayer); 1931 do_learn_spell (op, sp, special_prayer);
1867 1932
1868void forget_spell (object *op, object *sp) 1933void forget_spell (object *op, object *sp)
1869 CODE: 1934 CODE:
1870 do_forget_spell (op, query_name (sp)); 1935 do_forget_spell (op, query_name (sp));
1871 1936
1872object *check_for_spell (object *op, char *spellname) 1937object *check_for_spell (object *op, utf8_string spellname)
1873 CODE: 1938 CODE:
1874 RETVAL = check_spell_known (op, spellname); 1939 RETVAL = check_spell_known (op, spellname);
1875 OUTPUT: RETVAL 1940 OUTPUT: RETVAL
1876 1941
1877int query_money (object *op) 1942int query_money (object *op)
1890 1955
1891int cf_object_teleport (object *op, maptile *map, int x, int y) 1956int cf_object_teleport (object *op, maptile *map, int x, int y)
1892 1957
1893void update_object (object *op, int action) 1958void update_object (object *op, int action)
1894 1959
1895object *cf_create_object_by_name (const char *name) 1960object *cf_create_object_by_name (utf8_string name)
1896 1961
1897void change_exp (object *op, uint64 exp, const char *skill_name = 0, int flag = 0) 1962void change_exp (object *op, uint64 exp, utf8_string skill_name = 0, int flag = 0)
1898 1963
1899void player_lvl_adj (object *who, object *skill = 0) 1964void player_lvl_adj (object *who, object *skill = 0)
1900 1965
1901int kill_object (object *op, int dam = 0, object *hitter = 0, int type = AT_PHYSICAL) 1966int kill_object (object *op, int dam = 0, object *hitter = 0, int type = AT_PHYSICAL)
1902 1967
1916object *cf_insert_ob_in_ob (object *ob, object *where) 1981object *cf_insert_ob_in_ob (object *ob, object *where)
1917 1982
1918# no clean way to get an object from an archetype - stupid idiotic 1983# no clean way to get an object from an archetype - stupid idiotic
1919# dumb kludgy misdesigned plug-in api slowly gets on my nerves. 1984# dumb kludgy misdesigned plug-in api slowly gets on my nerves.
1920 1985
1921object *new (const char *archetype = 0) 1986object *new (utf8_string archetype = 0)
1922 PROTOTYPE: ;$ 1987 PROTOTYPE: ;$
1923 CODE: 1988 CODE:
1924 RETVAL = archetype ? get_archetype (archetype) : cf_create_object (); 1989 RETVAL = archetype ? get_archetype (archetype) : cf_create_object ();
1925 OUTPUT: 1990 OUTPUT:
1926 RETVAL 1991 RETVAL
1931{ 1996{
1932 int unused_type; 1997 int unused_type;
1933 RETVAL = (object *)object_insert (&unused_type, ob, 0, where, orig, flag, x, y); 1998 RETVAL = (object *)object_insert (&unused_type, ob, 0, where, orig, flag, x, y);
1934} 1999}
1935 2000
1936# syntatic sugar for easier use in event callbacks.
1937const char *options (object *op)
1938 CODE:
1939 RETVAL = op->name;
1940 OUTPUT:
1941 RETVAL
1942
1943player *contr (object *op) 2001player *contr (object *op)
1944 CODE: 2002 CODE:
1945 RETVAL = op->contr; 2003 RETVAL = op->contr;
1946 OUTPUT: RETVAL 2004 OUTPUT: RETVAL
1947 2005
1948const char *get_ob_key_value (object *op, const char *key) 2006const_utf8_string get_ob_key_value (object *op, utf8_string key)
1949 2007
1950bool set_ob_key_value (object *op, const char *key, const char *value = 0, int add_key = 1) 2008bool set_ob_key_value (object *op, utf8_string key, utf8_string value = 0, int add_key = 1)
1951 2009
1952object *get_nearest_player (object *ob) 2010object *get_nearest_player (object *ob)
1953 ALIAS: nearest_player = 0 2011 ALIAS: nearest_player = 0
1954 PREINIT: 2012 PREINIT:
1955 extern object *get_nearest_player (object *); 2013 extern object *get_nearest_player (object *);
1971bool on_same_map_as (object *ob, object *other) 2029bool on_same_map_as (object *ob, object *other)
1972 CODE: 2030 CODE:
1973 RETVAL = on_same_map (ob, other); 2031 RETVAL = on_same_map (ob, other);
1974 OUTPUT: RETVAL 2032 OUTPUT: RETVAL
1975 2033
1976const char * 2034const_utf8_string
1977base_name (object *op, int plural = op->nrof > 1) 2035base_name (object *op, int plural = op->nrof > 1)
1978 CODE: 2036 CODE:
1979 RETVAL = query_base_name (op, plural); 2037 RETVAL = query_base_name (op, plural);
1980 OUTPUT: RETVAL 2038 OUTPUT: RETVAL
1981 2039
1988 RETVAL = op->contr; 2046 RETVAL = op->contr;
1989 OUTPUT: RETVAL 2047 OUTPUT: RETVAL
1990 2048
1991void check_score (object *op) 2049void check_score (object *op)
1992 2050
1993void message (object *op, char *txt, int flags = NDI_ORANGE | NDI_UNIQUE) 2051void message (object *op, utf8_string txt, int flags = NDI_ORANGE | NDI_UNIQUE)
1994 CODE: 2052 CODE:
1995 new_draw_info (flags, 0, op, txt); 2053 new_draw_info (flags, 0, op, txt);
1996 2054
1997object *cf_player_send_inventory (object *op) 2055object *cf_player_send_inventory (object *op)
1998 2056
1999char *cf_player_get_ip (object *op) 2057octet_string cf_player_get_ip (object *op)
2000 ALIAS: ip = 0 2058 ALIAS: ip = 0
2001 2059
2002object *cf_player_get_marked_item (object *op) 2060object *cf_player_get_marked_item (object *op)
2003 ALIAS: marked_item = 0 2061 ALIAS: marked_item = 0
2004 2062
2014void esrv_update_item (object *op, int what, object *item) 2072void esrv_update_item (object *op, int what, object *item)
2015 C_ARGS: what, op, item 2073 C_ARGS: what, op, item
2016 2074
2017void clear_los (object *op) 2075void clear_los (object *op)
2018 2076
2019int command_summon (object *op, char *params) 2077int command_summon (object *op, utf8_string params)
2020 2078
2021int command_arrest (object *op, char *params) 2079int command_arrest (object *op, utf8_string params)
2022
2023int command_kick (object *op, char *params)
2024
2025int command_banish (object *op, char *params)
2026 2080
2027 2081
2028MODULE = cf PACKAGE = cf::player PREFIX = cf_player_ 2082MODULE = cf PACKAGE = cf::player PREFIX = cf_player_
2029 2083
2030INCLUDE: $PERL genacc player ../include/player.h | 2084INCLUDE: $PERL $srcdir/genacc player ../include/player.h |
2031 2085
2032int invoke (player *pl, int event, ...) 2086int invoke (player *pl, int event, ...)
2033 CODE: 2087 CODE:
2034 if (KLASS_OF (event) != KLASS_PLAYER) croak ("event class must be PLAYER"); 2088 if (KLASS_OF (event) != KLASS_PLAYER) croak ("event class must be PLAYER");
2035 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); 2089 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
2048 pl->orig_stats = pl->ob->stats; 2102 pl->orig_stats = pl->ob->stats;
2049 2103
2050void cf_player_move (player *pl, int dir) 2104void cf_player_move (player *pl, int dir)
2051 2105
2052void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0); 2106void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0);
2053
2054player *first ()
2055 CODE:
2056 RETVAL = first_player;
2057 OUTPUT: RETVAL
2058 2107
2059bool 2108bool
2060cell_visible (player *pl, int dx, int dy) 2109cell_visible (player *pl, int dx, int dy)
2061 CODE: 2110 CODE:
2062 RETVAL = FABS (dx) <= pl->ns->mapx / 2 && FABS (dy) <= pl->ns->mapy / 2 2111 RETVAL = FABS (dx) <= pl->ns->mapx / 2 && FABS (dy) <= pl->ns->mapy / 2
2115 RETVAL = map->invoke ((event_type)event, ARG_AV (av), DT_END); 2164 RETVAL = map->invoke ((event_type)event, ARG_AV (av), DT_END);
2116 OUTPUT: RETVAL 2165 OUTPUT: RETVAL
2117 2166
2118SV *registry (maptile *map) 2167SV *registry (maptile *map)
2119 2168
2120INCLUDE: $PERL genacc maptile ../include/map.h | 2169INCLUDE: $PERL $srcdir/genacc maptile ../include/map.h |
2121 2170
2122void 2171void
2123maptile::instantiate () 2172maptile::instantiate ()
2124 2173
2125maptile *new () 2174maptile *new ()
2139 EXTEND (SP, THIS->players); 2188 EXTEND (SP, THIS->players);
2140 for_all_players (pl) 2189 for_all_players (pl)
2141 if (pl->ob && pl->ob->map == THIS) 2190 if (pl->ob && pl->ob->map == THIS)
2142 PUSHs (sv_2mortal (to_sv (pl->ob))); 2191 PUSHs (sv_2mortal (to_sv (pl->ob)));
2143 } 2192 }
2193
2194void
2195maptile::add_underlay (SV *data, int offset, int stride, SV *palette)
2196 CODE:
2197{
2198 if (!SvROK (palette) || SvTYPE (SvRV (palette)) != SVt_PVAV)
2199 croak ("maptile::add_underlay: palette must be arrayref");
2200
2201 palette = SvRV (palette);
2202
2203 STRLEN idxlen;
2204 const uint8_t *idx = (const uint8_t *)SvPVbyte (data, idxlen);
2205
2206 for (int x = 0; x < THIS->width; ++x)
2207 for (int y = 0; y < THIS->height; ++y)
2208 {
2209 for (object *op = THIS->at (x, y).bot; op; op = op->above)
2210 if (op->flag [FLAG_IS_FLOOR])
2211 goto skip_space;
2212
2213 {
2214 int offs = offset + y * stride + x;
2215 if (IN_RANGE_EXC (offs, 0, idxlen))
2216 {
2217 if (SV **elem = av_fetch ((AV *)palette, idx [offs], 0))
2218 {
2219 object *ob = get_archetype (SvPVutf8_nolen (*elem));
2220 ob->flag [FLAG_NO_MAP_SAVE] = true;
2221 THIS->insert (ob, x, y, 0, INS_ABOVE_FLOOR_ONLY);
2222 }
2223 }
2224 }
2225
2226 skip_space: ;
2227 }
2228}
2229
2230void
2231maptile::set_regiondata (SV *data, int offset, int stride, SV *palette)
2232 CODE:
2233{
2234 if (!SvROK (palette) || SvTYPE (SvRV (palette)) != SVt_PVAV)
2235 croak ("maptile::set_regiondata: palette must be arrayref");
2236
2237 palette = SvRV (palette);
2238
2239 STRLEN idxlen;
2240 const uint8_t *idx = (const uint8_t *)SvPVbyte (data, idxlen);
2241
2242 region **regionmap = (region **)malloc (
2243 (av_len ((AV *)palette) + 1) * sizeof (region *));
2244 uint8_t *regions = salloc<uint8_t> (THIS->size ());
2245
2246 for (int i = av_len ((AV *)palette) + 1; i--; )
2247 regionmap [i] = region::find (
2248 SvPVutf8_nolen (*av_fetch ((AV *)palette, i, 1)));
2249
2250 for (int y = 0; y < THIS->height; ++y)
2251 memcpy (regions + y * THIS->width, idx + offset + y * stride, THIS->width);
2252
2253 sfree (THIS->regions, THIS->size ());
2254 free (THIS->regionmap);
2255
2256 THIS->regions = regions;
2257 THIS->regionmap = regionmap;
2258}
2144 2259
2145void play_sound_map (maptile *map, int x, int y, int sound_num) 2260void play_sound_map (maptile *map, int x, int y, int sound_num)
2146 2261
2147int out_of_map (maptile *map, int x, int y) 2262int out_of_map (maptile *map, int x, int y)
2148 2263
2230 2345
2231void fix_walls (maptile *map, int x, int y) 2346void fix_walls (maptile *map, int x, int y)
2232 2347
2233void fix_walls_around (maptile *map, int x, int y) 2348void fix_walls_around (maptile *map, int x, int y)
2234 2349
2235const char *
2236region_name (maptile *m)
2237 CODE:
2238 RETVAL = get_name_of_region_for_map (m);
2239 OUTPUT: RETVAL
2240
2241# worst xs function of my life 2350# worst xs function of my life
2242bool 2351bool
2243_create_random_map (\ 2352_create_random_map (\
2244 maptile *self,\ 2353 maptile *self,\
2245 char *wallstyle,\ 2354 utf8_string wallstyle,\
2246 char *wall_name,\ 2355 utf8_string wall_name,\
2247 char *floorstyle,\ 2356 utf8_string floorstyle,\
2248 char *monsterstyle,\ 2357 utf8_string monsterstyle,\
2249 char *treasurestyle,\ 2358 utf8_string treasurestyle,\
2250 char *layoutstyle,\ 2359 utf8_string layoutstyle,\
2251 char *doorstyle,\ 2360 utf8_string doorstyle,\
2252 char *decorstyle,\ 2361 utf8_string decorstyle,\
2253 char *origin_map,\ 2362 utf8_string origin_map,\
2254 char *final_map,\ 2363 utf8_string final_map,\
2255 char *exitstyle,\ 2364 utf8_string exitstyle,\
2256 char *this_map,\ 2365 utf8_string this_map,\
2257 char *exit_on_final_map,\ 2366 utf8_string exit_on_final_map,\
2258 int xsize,\ 2367 int xsize,\
2259 int ysize,\ 2368 int ysize,\
2260 int expand2x,\ 2369 int expand2x,\
2261 int layoutoptions1,\ 2370 int layoutoptions1,\
2262 int layoutoptions2,\ 2371 int layoutoptions2,\
2275 val64 total_map_hp,\ 2384 val64 total_map_hp,\
2276 int map_layout_style,\ 2385 int map_layout_style,\
2277 int treasureoptions,\ 2386 int treasureoptions,\
2278 int symmetry_used,\ 2387 int symmetry_used,\
2279 region *region,\ 2388 region *region,\
2280 char *custom\ 2389 utf8_string custom\
2281) 2390)
2282 CODE: 2391 CODE:
2283{ 2392{
2284 random_map_params rmp; 2393 random_map_params rmp;
2285 2394
2326 OUTPUT: 2435 OUTPUT:
2327 RETVAL 2436 RETVAL
2328 2437
2329MODULE = cf PACKAGE = cf::arch 2438MODULE = cf PACKAGE = cf::arch
2330 2439
2331archetype *find (const char *name) 2440archetype *find (utf8_string name)
2332 CODE: 2441 CODE:
2333 RETVAL = archetype::find (name); 2442 RETVAL = archetype::find (name);
2334 OUTPUT: 2443 OUTPUT:
2335 RETVAL 2444 RETVAL
2336 2445
2338 PROTOTYPE: 2447 PROTOTYPE:
2339 CODE: 2448 CODE:
2340 RETVAL = first_archetype; 2449 RETVAL = first_archetype;
2341 OUTPUT: RETVAL 2450 OUTPUT: RETVAL
2342 2451
2343INCLUDE: $PERL genacc archetype ../include/object.h | 2452INCLUDE: $PERL $srcdir/genacc archetype ../include/object.h |
2344 2453
2345MODULE = cf PACKAGE = cf::party 2454MODULE = cf PACKAGE = cf::party
2346 2455
2347partylist *first () 2456partylist *first ()
2348 PROTOTYPE: 2457 PROTOTYPE:
2349 CODE: 2458 CODE:
2350 RETVAL = get_firstparty (); 2459 RETVAL = get_firstparty ();
2351 OUTPUT: RETVAL 2460 OUTPUT: RETVAL
2352 2461
2353INCLUDE: $PERL genacc partylist ../include/player.h | 2462INCLUDE: $PERL $srcdir/genacc partylist ../include/player.h |
2354 2463
2355MODULE = cf PACKAGE = cf::region 2464MODULE = cf PACKAGE = cf::region
2356 2465
2357region *first () 2466void
2358 PROTOTYPE: 2467list ()
2359 CODE: 2468 PPCODE:
2360 RETVAL = first_region; 2469 for_all_regions (rgn)
2361 OUTPUT: RETVAL 2470 XPUSHs (sv_2mortal (to_sv (rgn)));
2362 2471
2363region *find (char *name) 2472region *find (utf8_string name)
2364 PROTOTYPE: $ 2473 PROTOTYPE: $
2365 CODE: 2474 CODE:
2366 RETVAL = get_region_by_name (name); 2475 RETVAL = region::find (name);
2367 OUTPUT: RETVAL 2476 OUTPUT: RETVAL
2368 2477
2478region *find_fuzzy (utf8_string name)
2479 PROTOTYPE: $
2480 CODE:
2481 RETVAL = region::find_fuzzy (name);
2482 OUTPUT: RETVAL
2483
2484int specificity (region *rgn)
2485 CODE:
2486 RETVAL = 0;
2487 while (rgn = rgn->parent)
2488 RETVAL++;
2489 OUTPUT: RETVAL
2490
2369INCLUDE: $PERL genacc region ../include/map.h | 2491INCLUDE: $PERL $srcdir/genacc region ../include/map.h |
2370 2492
2371MODULE = cf PACKAGE = cf::living 2493MODULE = cf PACKAGE = cf::living
2372 2494
2373INCLUDE: $PERL genacc living ../include/living.h | 2495INCLUDE: $PERL $srcdir/genacc living ../include/living.h |
2374 2496
2375MODULE = cf PACKAGE = cf::settings 2497MODULE = cf PACKAGE = cf::settings
2376 2498
2377INCLUDE: $PERL genacc Settings ../include/global.h | 2499INCLUDE: $PERL $srcdir/genacc Settings ../include/global.h |
2378 2500
2379MODULE = cf PACKAGE = cf::client 2501MODULE = cf PACKAGE = cf::client
2380 2502
2381INCLUDE: $PERL genacc client ../include/client.h | 2503INCLUDE: $PERL $srcdir/genacc client ../include/client.h |
2382 2504
2383int invoke (client *ns, int event, ...) 2505int invoke (client *ns, int event, ...)
2384 CODE: 2506 CODE:
2385 if (KLASS_OF (event) != KLASS_CLIENT) croak ("event class must be CLIENT"); 2507 if (KLASS_OF (event) != KLASS_CLIENT) croak ("event class must be CLIENT");
2386 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); 2508 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
2405 char *buf = SvPVbyte (packet, len); 2527 char *buf = SvPVbyte (packet, len);
2406 2528
2407 THIS->send_packet (buf, len); 2529 THIS->send_packet (buf, len);
2408} 2530}
2409 2531
2532MODULE = cf PACKAGE = cf::face PREFIX = face_
2533
2534#INCLUDE: $PERL $srcdir/genacc faceset ../include/face.h |
2535
2536faceidx face_find (utf8_string name, faceidx defidx = 0)
2537
2538faceidx alloc (utf8_string name)
2539 CODE:
2540{
2541 do
2542 {
2543 RETVAL = faces.size ();
2544 faces.resize (RETVAL + 1);
2545 }
2546 while (!RETVAL); // crude way to leave index 0
2547
2548 faces [RETVAL].name = name;
2549 facehash.insert (std::make_pair (faces [RETVAL].name, RETVAL));
2550
2551 if (!strcmp (name, BLANK_FACE_NAME)) blank_face = RETVAL;
2552 if (!strcmp (name, EMPTY_FACE_NAME)) empty_face = RETVAL;
2553}
2554 OUTPUT: RETVAL
2555
2556void set (faceidx idx, int visibility, int magicmap)
2557 CODE:
2558 faceinfo *f = face_info (idx);
2559 assert (f);
2560 f->visibility = visibility;
2561 f->magicmap = magicmap;
2562
2563void set_smooth (faceidx idx, faceidx smooth, int smoothlevel)
2564 CODE:
2565 faceinfo *f = face_info (idx); assert (f);
2566 f->smooth = smooth;
2567 f->smoothlevel = smoothlevel;
2568
2569void set_data (faceidx idx, int faceset, SV *data, SV *chksum)
2570 CODE:
2571{
2572 facedata *d = face_data (idx, faceset);
2573 assert (d);
2574 sv_to (data, d->data);
2575 STRLEN clen;
2576 char *cdata = SvPVbyte (chksum, clen);
2577 clen = min (CHKSUM_SIZE, clen);
2578
2579 if (memcmp (d->chksum, cdata, clen))
2580 {
2581 memcpy (d->chksum, cdata, clen);
2582
2583 // invalidate existing client face info
2584 for_all_clients (ns)
2585 if (ns->faceset == faceset)
2586 {
2587 ns->faces_sent [idx] = false;
2588 ns->force_newmap = true;
2589 }
2590 }
2591}
2592
2593void invalidate (faceidx idx)
2594 CODE:
2595 for_all_clients (ns)
2596 {
2597 ns->faces_sent [idx] = false;
2598 ns->force_newmap = true;
2599 }
2600
2601void invalidate_all ()
2602 CODE:
2603 for_all_clients (ns)
2604 {
2605 ns->faces_sent.reset ();
2606 ns->force_newmap = true;
2607 }
2608
2609MODULE = cf PACKAGE = cf::anim PREFIX = anim_
2610
2611#INCLUDE: $PERL $srcdir/genacc faceset ../include/anim.h |
2612
2613animidx anim_find (utf8_string name)
2614 CODE:
2615 RETVAL = animation::find (name).number;
2616 OUTPUT: RETVAL
2617
2618animidx set (utf8_string name, SV *frames, int facings = 1)
2619 CODE:
2620{
2621 if (!SvROK (frames) && SvTYPE (SvRV (frames)) != SVt_PVAV)
2622 croak ("frames must be an arrayref");
2623
2624 AV *av = (AV *)SvRV (frames);
2625
2626 animation *anim = &animation::find (name);
2627 if (anim->number)
2628 {
2629 anim->resize (av_len (av) + 1);
2630 anim->facings = facings;
2631 }
2632 else
2633 anim = &animation::create (name, av_len (av) + 1, facings);
2634
2635 for (int i = 0; i < anim->num_animations; ++i)
2636 anim->faces [i] = face_find (SvPVutf8_nolen (*av_fetch (av, i, 1)));
2637}
2638 OUTPUT: RETVAL
2639
2640void invalidate_all ()
2641 CODE:
2642 for_all_clients (ns)
2643 ns->anims_sent.reset ();
2644

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines