Crossfire Server, Branches 1.12  R18729
cfpython_map.c
Go to the documentation of this file.
1 /*****************************************************************************/
2 /* CFPython - A Python module for Crossfire RPG. */
3 /* Version: 2.0beta8 (also known as "Alexander") */
4 /* Contact: yann.chachkoff@myrealbox.com */
5 /*****************************************************************************/
6 /* That code is placed under the GNU General Public Licence (GPL) */
7 /* (C)2001-2005 by Chachkoff Yann (Feel free to deliver your complaints) */
8 /*****************************************************************************/
9 /* CrossFire, A Multiplayer game for X-windows */
10 /* */
11 /* Copyright (C) 2000 Mark Wedel */
12 /* Copyright (C) 1992 Frank Tore Johansen */
13 /* */
14 /* This program is free software; you can redistribute it and/or modify */
15 /* it under the terms of the GNU General Public License as published by */
16 /* the Free Software Foundation; either version 2 of the License, or */
17 /* (at your option) any later version. */
18 /* */
19 /* This program is distributed in the hope that it will be useful, */
20 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
21 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
22 /* GNU General Public License for more details. */
23 /* */
24 /* You should have received a copy of the GNU General Public License */
25 /* along with this program; if not, write to the Free Software */
26 /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
27 /* */
28 /*****************************************************************************/
29 
30 #include <cfpython.h>
31 #include <cfpython_map_private.h>
32 #include <hashtable.h>
33 
34 /* Table for keeping track of which PyObject goes with with Crossfire object */
36 
37 /* Helper functions for dealing with object_assoc_table */
40 }
41 
42 static void add_map_assoc(mapstruct *key, Crossfire_Map *value) {
43  add_ptr_assoc(map_assoc_table, key, value);
44 }
45 
46 static PyObject *find_assoc_pymap(mapstruct *key) {
47  return (PyObject *)find_assoc_value(map_assoc_table, key);
48 }
49 
50 static void free_map_assoc(mapstruct *key) {
52 }
53 
54 static PyObject *Map_GetDifficulty(Crossfire_Map *whoptr, void *closure) {
55  MAPEXISTCHECK(whoptr);
56  return Py_BuildValue("i", cf_map_get_difficulty(whoptr->map));
57 }
58 
59 static PyObject *Map_GetPath(Crossfire_Map *whoptr, void *closure) {
60  MAPEXISTCHECK(whoptr);
61  return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_PATH));
62 }
63 
64 static PyObject *Map_GetTempName(Crossfire_Map *whoptr, void *closure) {
65  MAPEXISTCHECK(whoptr);
66  return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_TMPNAME));
67 }
68 
69 static PyObject *Map_GetName(Crossfire_Map *whoptr, void *closure) {
70  MAPEXISTCHECK(whoptr);
71  return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_NAME));
72 }
73 
74 static PyObject *Map_GetResetTime(Crossfire_Map *whoptr, void *closure) {
75  MAPEXISTCHECK(whoptr);
76  return Py_BuildValue("i", cf_map_get_reset_time(whoptr->map));
77 }
78 
79 static PyObject *Map_GetResetTimeout(Crossfire_Map *whoptr, void *closure) {
80  MAPEXISTCHECK(whoptr);
81  return Py_BuildValue("i", cf_map_get_reset_timeout(whoptr->map));
82 }
83 
84 static PyObject *Map_GetPlayers(Crossfire_Map *whoptr, void *closure) {
85  MAPEXISTCHECK(whoptr);
86  return Py_BuildValue("i", cf_map_get_players(whoptr->map));
87 }
88 
89 static PyObject *Map_GetDarkness(Crossfire_Map *whoptr, void *closure) {
90  MAPEXISTCHECK(whoptr);
91  return Py_BuildValue("i", cf_map_get_darkness(whoptr->map));
92 }
93 
94 static PyObject *Map_GetWidth(Crossfire_Map *whoptr, void *closure) {
95  MAPEXISTCHECK(whoptr);
96  return Py_BuildValue("i", cf_map_get_width(whoptr->map));
97 }
98 
99 static PyObject *Map_GetHeight(Crossfire_Map *whoptr, void *closure) {
100  MAPEXISTCHECK(whoptr);
101  return Py_BuildValue("i", cf_map_get_height(whoptr->map));
102 }
103 
104 static PyObject *Map_GetEnterX(Crossfire_Map *whoptr, void *closure) {
105  MAPEXISTCHECK(whoptr);
106  return Py_BuildValue("i", cf_map_get_int_property(whoptr->map, CFAPI_MAP_PROP_ENTER_X));
107 }
108 
109 static PyObject *Map_GetEnterY(Crossfire_Map *whoptr, void *closure) {
110  MAPEXISTCHECK(whoptr);
111  return Py_BuildValue("i", cf_map_get_enter_x(whoptr->map));
112 }
113 
114 static PyObject *Map_GetMessage(Crossfire_Map *whoptr, void *closure) {
115  MAPEXISTCHECK(whoptr);
116  return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_MESSAGE));
117 }
118 
119 static PyObject *Map_GetRegion(Crossfire_Map *whoptr, void *closure) {
120  MAPEXISTCHECK(whoptr);
122 }
123 
124 static int Map_SetPath(Crossfire_Map *whoptr, PyObject *value, void *closure) {
125  const char *val;
126 
127  MAPEXISTCHECK_INT(whoptr);
128  if (!PyArg_Parse(value, "s", &val))
129  return -1;
130 
132  return 0;
133 
134 }
135 
136 static PyObject *Map_GetUnique(Crossfire_Map *whoptr, void *closure) {
137  MAPEXISTCHECK(whoptr);
138  return Py_BuildValue("i", cf_map_get_int_property(whoptr->map, CFAPI_MAP_PROP_UNIQUE));
139 }
140 
141 static PyObject *Map_Message(Crossfire_Map *map, PyObject *args) {
142  int color = NDI_BLUE|NDI_UNIQUE;
143  char *message;
144 
145  if (!PyArg_ParseTuple(args, "s|i", &message, &color))
146  return NULL;
147 
148  MAPEXISTCHECK(map);
149 
150  cf_map_message(map->map, message, color);
151 
152  Py_INCREF(Py_None);
153  return Py_None;
154 }
155 
156 static PyObject *Map_GetFirstObjectAt(Crossfire_Map *map, PyObject *args) {
157  int x, y;
158  object *val;
159 
160  if (!PyArg_ParseTuple(args, "ii", &x, &y))
161  return NULL;
162 
163  MAPEXISTCHECK(map);
164 
165  val = cf_map_get_object_at(map->map, x, y);
166  return Crossfire_Object_wrap(val);
167 }
168 
169 static PyObject *Map_CreateObject(Crossfire_Map *map, PyObject *args) {
170  char *txt;
171  int x, y;
172  object *op;
173 
174  if (!PyArg_ParseTuple(args, "sii", &txt, &x, &y))
175  return NULL;
176 
177  MAPEXISTCHECK(map);
178 
179  op = cf_create_object_by_name(txt);
180 
181  if (op)
182  op = cf_map_insert_object(map->map, op, x, y);
183  return Crossfire_Object_wrap(op);
184 }
185 
186 static PyObject *Map_Check(Crossfire_Map *map, PyObject *args) {
187  char *what;
188  int x, y;
189  object *foundob;
190  sint16 nx, ny;
191  int mflags;
192 
193  if (!PyArg_ParseTuple(args, "s(ii)", &what, &x, &y))
194  return NULL;
195 
196  MAPEXISTCHECK(map);
197 
198  /* make sure the map is swapped in */
199  if (map->map->in_memory != MAP_IN_MEMORY) {
200  cf_log(llevError, "MAP AIN'T READY !\n");
201  }
202 
203  mflags = cf_map_get_flags(map->map, &(map->map), (sint16)x, (sint16)y, &nx, &ny);
204  if (mflags&P_OUT_OF_MAP) {
205  Py_INCREF(Py_None);
206  return Py_None;
207  }
208  foundob = cf_map_present_arch_by_name(what, map->map, nx, ny);
209  return Crossfire_Object_wrap(foundob);
210 }
211 
212 static PyObject *Map_Next(Crossfire_Map *map, PyObject *args) {
213  MAPEXISTCHECK(map);
215 }
216 
217 static PyObject *Map_Insert(Crossfire_Map *map, PyObject *args) {
218  int x, y;
219  Crossfire_Object *what;
220 
221  if (!PyArg_ParseTuple(args, "O!ii", &Crossfire_ObjectType, &what, &x, &y))
222  return NULL;
223 
224  MAPEXISTCHECK(map);
225 
226  return Crossfire_Object_wrap(cf_map_insert_object(map->map, what->obj, x, y));
227 }
228 
229 static PyObject *Map_ChangeLight(Crossfire_Map *map, PyObject *args) {
230  int change;
231 
232  if (!PyArg_ParseTuple(args, "i", &change))
233  return NULL;
234 
235  MAPEXISTCHECK(map);
236 
237  return Py_BuildValue("i", cf_map_change_light(map->map, change));
238 }
254 static PyObject *Map_TriggerConnected(Crossfire_Map *map, PyObject *args) {
255  objectlink *ol = NULL;
256  int connected;
257  int state;
258  Crossfire_Object *cause = NULL;
259  oblinkpt *olp;
260 
261  if (!PyArg_ParseTuple(args, "ii|O!", &connected, &state, &Crossfire_ObjectType, &cause))
262  return NULL;
263 
264  MAPEXISTCHECK(map);
265  /* locate objectlink for this connected value */
266  if (!map->map->buttons) {
267  cf_log(llevError, "Map %s called for trigger on connected %d but there ain't any button list for that map!\n", cf_map_get_sstring_property(map->map, CFAPI_MAP_PROP_PATH), connected);
268  return NULL;
269  }
270  for (olp = map->map->buttons; olp; olp = olp->next) {
271  if (olp->value == connected) {
272  ol = olp->link;
273  break;
274  }
275  }
276  if (ol == NULL) {
277  cf_log(llevInfo, "Map %s called for trigger on connected %d but there ain't any button list for that map!\n", cf_map_get_sstring_property(map->map, CFAPI_MAP_PROP_PATH), connected);
278  return NULL;
279  }
280  /* run the object link */
281  cf_map_trigger_connected(ol, cause ? cause->obj : NULL, state);
282 
283  Py_INCREF(Py_None);
284  return Py_None;
285 }
286 
288  MAPEXISTCHECK_INT(left);
289  MAPEXISTCHECK_INT(right);
290  return left->map < right->map ? -1 : (left->map == right->map ? 0 : 1);
291 }
292 
293 /* Legacy code: convert to long so that non-object functions work correctly */
294 static PyObject *Crossfire_Map_Long(PyObject *obj) {
296  return Py_BuildValue("l", ((Crossfire_Map *)obj)->map);
297 }
298 
299 #ifndef IS_PY3K
300 static PyObject *Crossfire_Map_Int(PyObject *obj) {
302  return Py_BuildValue("i", ((Crossfire_Map *)obj)->map);
303 }
304 #endif
305 
309 static PyObject *Crossfire_Map_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
310  Crossfire_Map *self;
311 
312  self = (Crossfire_Map *)type->tp_alloc(type, 0);
313  if (self)
314  self->map = NULL;
315 
316  return (PyObject *)self;
317 }
318 
319 static void Crossfire_Map_dealloc(PyObject *obj) {
320  Crossfire_Map *self;
321 
322  self = (Crossfire_Map *)obj;
323  if (self) {
324  if (self->map && self->valid) {
325  free_map_assoc(self->map);
326  }
327  Py_TYPE(self)->tp_free(obj);
328  }
329 }
330 
332  map->valid = 0;
333  free_map_assoc(map->map);
334 }
335 
336 PyObject *Crossfire_Map_wrap(mapstruct *what) {
337  Crossfire_Map *wrapper;
338 
339  /* return None if no object was to be wrapped */
340  if (what == NULL) {
341  Py_INCREF(Py_None);
342  return Py_None;
343  }
344 
345  wrapper = (Crossfire_Map *)find_assoc_pymap(what);
346  if (!wrapper) {
347  wrapper = PyObject_NEW(Crossfire_Map, &Crossfire_MapType);
348  if (wrapper != NULL) {
349  wrapper->map = what;
350  wrapper->valid = 1;
351  add_map_assoc(what, wrapper);
352  }
353  } else {
354  Py_INCREF(wrapper);
355  }
356 
357  return (PyObject *)wrapper;
358 }
static PyObject * Crossfire_Map_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Definition: cfpython_map.c:309
Definition: object.h:132
void cf_map_message(mapstruct *m, const char *msg, int color)
PyObject_HEAD object * obj
#define CFAPI_MAP_PROP_NAME
Definition: plugin.h:288
signed short sint16
Definition: global.h:72
static PyObject * Map_Message(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:141
Definition: object.h:298
static int Map_SetPath(Crossfire_Map *whoptr, PyObject *value, void *closure)
Definition: cfpython_map.c:124
PyObject * Crossfire_Region_wrap(region *what)
PyObject * Crossfire_Map_wrap(mapstruct *what)
Definition: cfpython_map.c:336
static PyObject * Map_GetTempName(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:64
PyTypeObject Crossfire_MapType
static PyObject * Map_GetUnique(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:136
#define MAPEXISTCHECK_INT(map)
Definition: cfpython_map.h:47
ptr_assoc * ptr_assoc_table[PTR_ASSOC_TABLESIZE]
Definition: hashtable.h:15
#define MAPEXISTCHECK(map)
Definition: cfpython_map.h:40
int cf_map_change_light(mapstruct *m, int change)
static PyObject * Map_GetName(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:69
region * cf_map_get_region_property(mapstruct *map, int propcode)
#define NDI_BLUE
Definition: newclient.h:200
static PyObject * Map_GetResetTime(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:74
int cf_map_get_height(mapstruct *map)
int cf_map_get_difficulty(mapstruct *map)
uint32 in_memory
Definition: map.h:366
mapstruct * cf_map_get_map_property(mapstruct *map, int propcode)
void init_map_assoc_table(void)
Definition: cfpython_map.c:38
static int Map_InternalCompare(Crossfire_Map *left, Crossfire_Map *right)
Definition: cfpython_map.c:287
static PyObject * Crossfire_Map_Int(PyObject *obj)
Definition: cfpython_map.c:300
static void add_map_assoc(mapstruct *key, Crossfire_Map *value)
Definition: cfpython_map.c:42
static PyObject * Map_GetWidth(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:94
#define CFAPI_MAP_PROP_NEXT
Definition: plugin.h:299
long value
Definition: object.h:309
static ptr_assoc_table map_assoc_table
Definition: cfpython_map.c:35
struct oblnk * link
Definition: object.h:308
static PyObject * Map_GetDifficulty(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:54
void cf_log(LogLevel logLevel, const char *format,...)
static PyObject * Map_GetPlayers(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:84
#define MAP_IN_MEMORY
Definition: map.h:151
struct oblinkpt * next
Definition: object.h:310
int cf_map_get_players(mapstruct *map)
#define CFAPI_MAP_PROP_UNIQUE
Definition: plugin.h:301
static PyObject * find_assoc_pymap(mapstruct *key)
Definition: cfpython_map.c:46
static PyObject * Crossfire_Map_Long(PyObject *obj)
Definition: cfpython_map.c:294
static PyObject * Map_GetEnterY(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:109
void Handle_Map_Unload_Hook(Crossfire_Map *map)
Definition: cfpython_map.c:331
static PyObject * Map_CreateObject(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:169
object * cf_map_present_arch_by_name(const char *str, mapstruct *map, int nx, int ny)
static void free_map_assoc(mapstruct *key)
Definition: cfpython_map.c:50
object * cf_map_insert_object(mapstruct *where, object *op, int x, int y)
PyObject * Crossfire_Object_wrap(object *what)
int cf_map_get_reset_time(mapstruct *map)
static PyObject * Map_GetHeight(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:99
PyObject_HEAD mapstruct * map
Definition: cfpython_map.h:34
#define P_OUT_OF_MAP
Definition: map.h:272
#define CFAPI_MAP_PROP_MESSAGE
Definition: plugin.h:298
void * find_assoc_value(ptr_assoc **hash_table, void *key)
Definition: hashtable.c:205
void cf_map_set_string_property(mapstruct *map, int propcode, const char *value)
#define CFAPI_MAP_PROP_TMPNAME
Definition: plugin.h:287
static PyObject * Map_GetDarkness(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:89
static PyObject * Map_GetPath(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:59
int cf_map_get_reset_timeout(mapstruct *map)
oblinkpt * buttons
Definition: map.h:373
int cf_map_get_darkness(mapstruct *map)
void cf_map_trigger_connected(objectlink *ol, object *cause, int state)
static PyObject * Map_GetRegion(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:119
void add_ptr_assoc(ptr_assoc **hash_table, void *key, void *value)
Definition: hashtable.c:109
object * cf_map_get_object_at(mapstruct *m, int x, int y)
void init_ptr_assoc_table(ptr_assoc **hash_table)
Definition: hashtable.c:57
static PyObject * Map_GetMessage(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:114
static PyObject * Map_Insert(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:217
static PyObject * Map_GetEnterX(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:104
static PyObject * Map_GetFirstObjectAt(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:156
static PyObject * Map_TriggerConnected(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:254
#define CFAPI_MAP_PROP_PATH
Definition: plugin.h:286
static PyObject * Map_ChangeLight(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:229
#define CFAPI_MAP_PROP_REGION
Definition: plugin.h:300
sstring cf_map_get_sstring_property(mapstruct *map, int propcode)
void free_ptr_assoc(ptr_assoc **hash_table, void *key)
Definition: hashtable.c:222
PyTypeObject Crossfire_ObjectType
static PyObject * Map_GetResetTimeout(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:79
#define Py_TYPE(ob)
Definition: cfpython.h:66
static PyObject * Map_Check(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:186
#define NDI_UNIQUE
Definition: newclient.h:219
Definition: map.h:346
static void Crossfire_Map_dealloc(PyObject *obj)
Definition: cfpython_map.c:319
int cf_map_get_int_property(mapstruct *map, int property)
#define CFAPI_MAP_PROP_ENTER_X
Definition: plugin.h:296
object * cf_create_object_by_name(const char *name)
static PyObject * Map_Next(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:212
int cf_map_get_width(mapstruct *map)
int cf_map_get_enter_x(mapstruct *map)
int cf_map_get_flags(mapstruct *oldmap, mapstruct **newmap, sint16 x, sint16 y, sint16 *nx, sint16 *ny)