Crossfire Server, Trunk  R20513
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 <hashtable.h>
32 
33 /* Table for keeping track of which PyObject goes with with Crossfire object */
35 
36 /* Helper functions for dealing with object_assoc_table */
39 }
40 
41 static void add_map_assoc(mapstruct *key, Crossfire_Map *value) {
42  add_ptr_assoc(map_assoc_table, key, value);
43 }
44 
45 static PyObject *find_assoc_pymap(mapstruct *key) {
46  return (PyObject *)find_assoc_value(map_assoc_table, key);
47 }
48 
49 static void free_map_assoc(mapstruct *key) {
51 }
52 
53 
56  assert(map->map != NULL);
57  if (map->map->in_memory != MAP_IN_MEMORY) {
58  char* mapname = map->map->path;
59  int is_unique = cf_map_get_int_property(map->map, CFAPI_MAP_PROP_UNIQUE);
60  /* If the map is unique the path name will be freed. We need to handle that. */
61  if (is_unique) {
62  char* tmp = strdup(mapname);
63  if (!tmp) {
64  /* FIXME: We should fatal() here, but that doesn't exist in plugins. */
65  cf_log(llevError, "Out of memory in ensure_map_in_memory()!\n");
66  abort();
67  }
68  mapname = tmp;
69  }
70  cf_log(llevDebug, "MAP %s AIN'T READY ! Loading it...\n", mapname);
71  /* Map pointer may change for player unique maps. */
72  /* Also, is the MAP_PLAYER_UNIQUE logic correct? */
73  map->map = cf_map_get_map(mapname, is_unique ? MAP_PLAYER_UNIQUE : 0);
74  if (is_unique)
75  free(mapname);
76  }
77 }
78 
79 static PyObject *Map_GetDifficulty(Crossfire_Map *whoptr, void *closure) {
80  MAPEXISTCHECK(whoptr);
81  return Py_BuildValue("i", cf_map_get_difficulty(whoptr->map));
82 }
83 
84 static PyObject *Map_GetPath(Crossfire_Map *whoptr, void *closure) {
85  MAPEXISTCHECK(whoptr);
86  return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_PATH));
87 }
88 
89 static PyObject *Map_GetTempName(Crossfire_Map *whoptr, void *closure) {
90  MAPEXISTCHECK(whoptr);
91  return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_TMPNAME));
92 }
93 
94 static PyObject *Map_GetName(Crossfire_Map *whoptr, void *closure) {
95  MAPEXISTCHECK(whoptr);
96  return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_NAME));
97 }
98 
99 static PyObject *Map_GetResetTime(Crossfire_Map *whoptr, void *closure) {
100  MAPEXISTCHECK(whoptr);
101  return Py_BuildValue("i", cf_map_get_reset_time(whoptr->map));
102 }
103 
104 static PyObject *Map_GetResetTimeout(Crossfire_Map *whoptr, void *closure) {
105  MAPEXISTCHECK(whoptr);
106  return Py_BuildValue("i", cf_map_get_reset_timeout(whoptr->map));
107 }
108 
109 static PyObject *Map_GetPlayers(Crossfire_Map *whoptr, void *closure) {
110  MAPEXISTCHECK(whoptr);
111  return Py_BuildValue("i", cf_map_get_players(whoptr->map));
112 }
113 
114 static PyObject *Map_GetDarkness(Crossfire_Map *whoptr, void *closure) {
115  MAPEXISTCHECK(whoptr);
116  return Py_BuildValue("i", cf_map_get_darkness(whoptr->map));
117 }
118 
119 static PyObject *Map_GetWidth(Crossfire_Map *whoptr, void *closure) {
120  MAPEXISTCHECK(whoptr);
121  return Py_BuildValue("i", cf_map_get_width(whoptr->map));
122 }
123 
124 static PyObject *Map_GetHeight(Crossfire_Map *whoptr, void *closure) {
125  MAPEXISTCHECK(whoptr);
126  return Py_BuildValue("i", cf_map_get_height(whoptr->map));
127 }
128 
129 static PyObject *Map_GetEnterX(Crossfire_Map *whoptr, void *closure) {
130  MAPEXISTCHECK(whoptr);
131  return Py_BuildValue("i", cf_map_get_int_property(whoptr->map, CFAPI_MAP_PROP_ENTER_X));
132 }
133 
134 static PyObject *Map_GetEnterY(Crossfire_Map *whoptr, void *closure) {
135  MAPEXISTCHECK(whoptr);
136  return Py_BuildValue("i", cf_map_get_enter_x(whoptr->map));
137 }
138 
139 static PyObject *Map_GetMessage(Crossfire_Map *whoptr, void *closure) {
140  MAPEXISTCHECK(whoptr);
141  return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_MESSAGE));
142 }
143 
144 static PyObject *Map_GetRegion(Crossfire_Map *whoptr, void *closure) {
145  MAPEXISTCHECK(whoptr);
147 }
148 
149 static int Map_SetPath(Crossfire_Map *whoptr, PyObject *value, void *closure) {
150  const char *val;
151 
152  MAPEXISTCHECK_INT(whoptr);
153  if (!PyArg_Parse(value, "s", &val))
154  return -1;
155 
157  return 0;
158 
159 }
160 
161 static PyObject *Map_GetUnique(Crossfire_Map *whoptr, void *closure) {
162  MAPEXISTCHECK(whoptr);
163  return Py_BuildValue("i", cf_map_get_int_property(whoptr->map, CFAPI_MAP_PROP_UNIQUE));
164 }
165 
166 static PyObject *Map_Message(Crossfire_Map *map, PyObject *args) {
167  int color = NDI_BLUE|NDI_UNIQUE;
168  char *message;
169 
170  if (!PyArg_ParseTuple(args, "s|i", &message, &color))
171  return NULL;
172 
173  MAPEXISTCHECK(map);
174 
175  cf_map_message(map->map, message, color);
176 
177  Py_INCREF(Py_None);
178  return Py_None;
179 }
180 
181 static PyObject *Map_GetFirstObjectAt(Crossfire_Map *map, PyObject *args) {
182  int x, y;
183  object *val;
184 
185  if (!PyArg_ParseTuple(args, "ii", &x, &y))
186  return NULL;
187 
188  MAPEXISTCHECK(map);
189 
190  /* make sure the map is swapped in */
192 
193  val = cf_map_get_object_at(map->map, x, y);
194  return Crossfire_Object_wrap(val);
195 }
196 
197 static PyObject *Map_CreateObject(Crossfire_Map *map, PyObject *args) {
198  char *txt;
199  int x, y;
200  object *op;
201 
202  if (!PyArg_ParseTuple(args, "sii", &txt, &x, &y))
203  return NULL;
204 
205  MAPEXISTCHECK(map);
206 
207  /* make sure the map is swapped in */
209 
210  op = cf_create_object_by_name(txt);
211 
212  if (op)
213  op = cf_map_insert_object(map->map, op, x, y);
214  return Crossfire_Object_wrap(op);
215 }
216 
217 static PyObject *Map_Check(Crossfire_Map *map, PyObject *args) {
218  char *what;
219  int x, y;
220  object *foundob;
221  int16_t nx, ny;
222  int mflags;
223 
224  if (!PyArg_ParseTuple(args, "s(ii)", &what, &x, &y))
225  return NULL;
226 
227  MAPEXISTCHECK(map);
228 
229  /* make sure the map is swapped in */
231 
232  mflags = cf_map_get_flags(map->map, &(map->map), (int16_t)x, (int16_t)y, &nx, &ny);
233  if (mflags&P_OUT_OF_MAP) {
234  Py_INCREF(Py_None);
235  return Py_None;
236  }
237  foundob = cf_map_find_by_archetype_name(what, map->map, nx, ny);
238  return Crossfire_Object_wrap(foundob);
239 }
240 
241 static PyObject *Map_Next(Crossfire_Map *map, PyObject *args) {
242  MAPEXISTCHECK(map);
244 }
245 
246 static PyObject *Map_Insert(Crossfire_Map *map, PyObject *args) {
247  int x, y;
248  Crossfire_Object *what;
249 
250  if (!PyArg_ParseTuple(args, "O!ii", &Crossfire_ObjectType, &what, &x, &y))
251  return NULL;
252 
253  MAPEXISTCHECK(map);
254 
255  /* make sure the map is swapped in */
257 
258  return Crossfire_Object_wrap(cf_map_insert_object(map->map, what->obj, x, y));
259 }
260 
261 static PyObject *Map_InsertAround(Crossfire_Map *map, PyObject *args) {
262  int x, y;
263  Crossfire_Object *what;
264 
265  if (!PyArg_ParseTuple(args, "O!ii", &Crossfire_ObjectType, &what, &x, &y))
266  return NULL;
267 
268  MAPEXISTCHECK(map);
269 
270  /* make sure the map is swapped in */
272 
273  return Crossfire_Object_wrap(cf_map_insert_object_around(map->map, what->obj, x, y));
274 }
275 
276 static PyObject *Map_ChangeLight(Crossfire_Map *map, PyObject *args) {
277  int change;
278 
279  if (!PyArg_ParseTuple(args, "i", &change))
280  return NULL;
281 
282  MAPEXISTCHECK(map);
283 
284  return Py_BuildValue("i", cf_map_change_light(map->map, change));
285 }
301 static PyObject *Map_TriggerConnected(Crossfire_Map *map, PyObject *args) {
302  objectlink *ol = NULL;
303  int connected;
304  int state;
305  Crossfire_Object *cause = NULL;
306  oblinkpt *olp;
307 
308  if (!PyArg_ParseTuple(args, "ii|O!", &connected, &state, &Crossfire_ObjectType, &cause))
309  return NULL;
310 
311  MAPEXISTCHECK(map);
312 
313  /* make sure the map is swapped in */
315 
316  /* locate objectlink for this connected value */
317  if (!map->map->buttons) {
318  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);
319  PyErr_SetString(PyExc_ReferenceError, "No objects connected to that ID on this map.");
320  return NULL;
321  }
322  for (olp = map->map->buttons; olp; olp = olp->next) {
323  if (olp->value == connected) {
324  ol = olp->link;
325  break;
326  }
327  }
328  if (ol == NULL) {
329  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);
330  /* FIXME: I'm not sure about this message... */
331  PyErr_SetString(PyExc_ReferenceError, "No objects with that connection ID on this map.");
332  return NULL;
333  }
334  /* run the object link */
335  cf_map_trigger_connected(ol, cause ? cause->obj : NULL, state);
336 
337  Py_INCREF(Py_None);
338  return Py_None;
339 }
340 
342  MAPEXISTCHECK_INT(left);
343  MAPEXISTCHECK_INT(right);
344  return left->map < right->map ? -1 : (left->map == right->map ? 0 : 1);
345 }
346 
347 static PyObject *Crossfire_Map_RichCompare(Crossfire_Map *left, Crossfire_Map *right, int op) {
348  int result;
349  if (!left
350  || !right
351  || !PyObject_TypeCheck((PyObject*)left, &Crossfire_MapType)
352  || !PyObject_TypeCheck((PyObject*)right, &Crossfire_MapType)) {
353  Py_INCREF(Py_NotImplemented);
354  return Py_NotImplemented;
355  }
356  result = Map_InternalCompare(left, right);
357  /* Handle removed maps. */
358  if (result == -1 && PyErr_Occurred())
359  return NULL;
360  /* Based on how Python 3.0 (GPL compatible) implements it for internal types: */
361  switch (op) {
362  case Py_EQ:
363  result = (result == 0);
364  break;
365  case Py_NE:
366  result = (result != 0);
367  break;
368  case Py_LE:
369  result = (result <= 0);
370  break;
371  case Py_GE:
372  result = (result >= 0);
373  break;
374  case Py_LT:
375  result = (result == -1);
376  break;
377  case Py_GT:
378  result = (result == 1);
379  break;
380  }
381  return PyBool_FromLong(result);
382 }
383 
384 /* Legacy code: convert to long so that non-object functions work correctly */
385 static PyObject *Crossfire_Map_Long(PyObject *obj) {
387  return Py_BuildValue("l", ((Crossfire_Map *)obj)->map);
388 }
389 
390 #ifndef IS_PY3K
391 static PyObject *Crossfire_Map_Int(PyObject *obj) {
393  return Py_BuildValue("i", ((Crossfire_Map *)obj)->map);
394 }
395 #endif
396 
400 static PyObject *Crossfire_Map_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
401  Crossfire_Map *self;
402 
403  self = (Crossfire_Map *)type->tp_alloc(type, 0);
404  if (self)
405  self->map = NULL;
406 
407  return (PyObject *)self;
408 }
409 
410 static void Crossfire_Map_dealloc(PyObject *obj) {
411  Crossfire_Map *self;
412 
413  self = (Crossfire_Map *)obj;
414  if (self) {
415  if (self->map && self->valid) {
416  free_map_assoc(self->map);
417  }
418  Py_TYPE(self)->tp_free(obj);
419  }
420 }
421 
423  map->valid = 0;
424  free_map_assoc(map->map);
425 }
426 
427 PyObject *Crossfire_Map_wrap(mapstruct *what) {
428  Crossfire_Map *wrapper;
429 
430  /* return None if no object was to be wrapped */
431  if (what == NULL) {
432  Py_INCREF(Py_None);
433  return Py_None;
434  }
435 
436  wrapper = (Crossfire_Map *)find_assoc_pymap(what);
437  if (!wrapper) {
438  wrapper = PyObject_NEW(Crossfire_Map, &Crossfire_MapType);
439  if (wrapper != NULL) {
440  wrapper->map = what;
441  wrapper->valid = 1;
442  add_map_assoc(what, wrapper);
443  }
444  } else {
445  Py_INCREF(wrapper);
446  }
447 
448  return (PyObject *)wrapper;
449 }
450 
451 /* Python binding */
452 static PyGetSetDef Map_getseters[] = {
453  { "Difficulty", (getter)Map_GetDifficulty, NULL, NULL, NULL },
454  { "Path", (getter)Map_GetPath, (setter)Map_SetPath, NULL, NULL },
455  { "TempName", (getter)Map_GetTempName, NULL, NULL, NULL },
456  { "Name", (getter)Map_GetName, NULL, NULL, NULL },
457  { "ResetTime", (getter)Map_GetResetTime, NULL, NULL, NULL },
458  { "ResetTimeout", (getter)Map_GetResetTimeout, NULL, NULL, NULL },
459  { "Players", (getter)Map_GetPlayers, NULL, NULL, NULL },
460  { "Light", (getter)Map_GetDarkness, NULL, NULL, NULL },
461  { "Darkness", (getter)Map_GetDarkness, NULL, NULL, NULL },
462  { "Width", (getter)Map_GetWidth, NULL, NULL, NULL },
463  { "Height", (getter)Map_GetHeight, NULL, NULL, NULL },
464  { "EnterX", (getter)Map_GetEnterX, NULL, NULL, NULL },
465  { "EnterY", (getter)Map_GetEnterY, NULL, NULL, NULL },
466  { "Message", (getter)Map_GetMessage, NULL, NULL, NULL },
467  { "Region", (getter)Map_GetRegion, NULL, NULL, NULL },
468  { "Unique", (getter)Map_GetUnique, NULL, NULL, NULL },
469  { NULL, NULL, NULL, NULL, NULL }
470 };
471 
472 static PyMethodDef MapMethods[] = {
473  { "Print", (PyCFunction)Map_Message, METH_VARARGS, NULL },
474  { "ObjectAt", (PyCFunction)Map_GetFirstObjectAt, METH_VARARGS, NULL },
475  { "CreateObject", (PyCFunction)Map_CreateObject, METH_VARARGS, NULL },
476  { "Check", (PyCFunction)Map_Check, METH_VARARGS, NULL },
477  { "Next", (PyCFunction)Map_Next, METH_NOARGS, NULL },
478  { "Insert", (PyCFunction)Map_Insert, METH_VARARGS, NULL },
479  { "InsertAround", (PyCFunction)Map_InsertAround, METH_VARARGS, NULL },
480  { "ChangeLight", (PyCFunction)Map_ChangeLight, METH_VARARGS, NULL },
481  { "TriggerConnected", (PyCFunction)Map_TriggerConnected, METH_VARARGS, NULL },
482  { NULL, NULL, 0, NULL }
483 };
484 
485 static PyNumberMethods MapConvert = {
486  NULL, /* binaryfunc nb_add; */ /* __add__ */
487  NULL, /* binaryfunc nb_subtract; */ /* __sub__ */
488  NULL, /* binaryfunc nb_multiply; */ /* __mul__ */
489 #ifndef IS_PY3K
490  NULL, /* binaryfunc nb_divide; */ /* __div__ */
491 #endif
492  NULL, /* binaryfunc nb_remainder; */ /* __mod__ */
493  NULL, /* binaryfunc nb_divmod; */ /* __divmod__ */
494  NULL, /* ternaryfunc nb_power; */ /* __pow__ */
495  NULL, /* unaryfunc nb_negative; */ /* __neg__ */
496  NULL, /* unaryfunc nb_positive; */ /* __pos__ */
497  NULL, /* unaryfunc nb_absolute; */ /* __abs__ */
498 #ifdef IS_PY3K
499  NULL, /* inquiry nb_bool; */ /* __bool__ */
500 #else
501  NULL, /* inquiry nb_nonzero; */ /* __nonzero__ */
502 #endif
503  NULL, /* unaryfunc nb_invert; */ /* __invert__ */
504  NULL, /* binaryfunc nb_lshift; */ /* __lshift__ */
505  NULL, /* binaryfunc nb_rshift; */ /* __rshift__ */
506  NULL, /* binaryfunc nb_and; */ /* __and__ */
507  NULL, /* binaryfunc nb_xor; */ /* __xor__ */
508  NULL, /* binaryfunc nb_or; */ /* __or__ */
509 #ifndef IS_PY3K
510  NULL, /* coercion nb_coerce; */ /* __coerce__ */
511 #endif
512 #ifdef IS_PY3K
513  /* This is not a typo. For Py3k it should be Crossfire_Map_Long
514  * and NOT Crossfire_Map_Int.
515  */
516  Crossfire_Map_Long, /* unaryfunc nb_int; */ /* __int__ */
517  NULL, /* void *nb_reserved; */
518 #else
519  Crossfire_Map_Int, /* unaryfunc nb_int; */ /* __int__ */
520  Crossfire_Map_Long, /* unaryfunc nb_long; */ /* __long__ */
521 #endif
522  NULL, /* unaryfunc nb_float; */ /* __float__ */
523 #ifndef IS_PY3K
524  NULL, /* unaryfunc nb_oct; */ /* __oct__ */
525  NULL, /* unaryfunc nb_hex; */ /* __hex__ */
526 #endif
527  NULL, /* binaryfunc nb_inplace_add; */
528  NULL, /* binaryfunc nb_inplace_subtract; */
529  NULL, /* binaryfunc nb_inplace_multiply; */
530 #ifndef IS_PY3K
531  NULL, /* binaryfunc nb_inplace_divide; */
532 #endif
533  NULL, /* binaryfunc nb_inplace_remainder; */
534  NULL, /* ternaryfunc nb_inplace_power; */
535  NULL, /* binaryfunc nb_inplace_lshift; */
536  NULL, /* binaryfunc nb_inplace_rshift; */
537  NULL, /* binaryfunc nb_inplace_and; */
538  NULL, /* binaryfunc nb_inplace_xor; */
539  NULL, /* binaryfunc nb_inplace_or; */
540 
541  NULL, /* binaryfunc nb_floor_divide; */
542  NULL, /* binaryfunc nb_true_divide; */
543  NULL, /* binaryfunc nb_inplace_floor_divide; */
544  NULL, /* binaryfunc nb_inplace_true_divide; */
545 #if defined(IS_PY25) || defined(IS_PY3K)
546  NULL /* unaryfunc nb_index; */
547 #endif
548 };
549 
550 /* Our actual Python MapType */
551 PyTypeObject Crossfire_MapType = {
552 #ifdef IS_PY3K
553  /* See http://bugs.python.org/issue4385 */
554  PyVarObject_HEAD_INIT(NULL, 0)
555 #else
556  PyObject_HEAD_INIT(NULL)
557  0, /* ob_size*/
558 #endif
559  "Crossfire.Map", /* tp_name*/
560  sizeof(Crossfire_Map), /* tp_basicsize*/
561  0, /* tp_itemsize*/
562  Crossfire_Map_dealloc, /* tp_dealloc*/
563  NULL, /* tp_print*/
564  NULL, /* tp_getattr*/
565  NULL, /* tp_setattr*/
566 #ifdef IS_PY3K
567  NULL, /* tp_reserved */
568 #else
569  (cmpfunc)Map_InternalCompare, /* tp_compare*/
570 #endif
571  NULL, /* tp_repr*/
572  &MapConvert, /* tp_as_number*/
573  NULL, /* tp_as_sequence*/
574  NULL, /* tp_as_mapping*/
575  PyObject_HashNotImplemented, /* tp_hash */
576  NULL, /* tp_call*/
577  NULL, /* tp_str*/
578  PyObject_GenericGetAttr, /* tp_getattro*/
579  PyObject_GenericSetAttr, /* tp_setattro*/
580  NULL, /* tp_as_buffer*/
581  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags*/
582  "Crossfire maps", /* tp_doc */
583  NULL, /* tp_traverse */
584  NULL, /* tp_clear */
585  (richcmpfunc)Crossfire_Map_RichCompare, /* tp_richcompare */
586  0, /* tp_weaklistoffset */
587  NULL, /* tp_iter */
588  NULL, /* tp_iternext */
589  MapMethods, /* tp_methods */
590  NULL, /* tp_members */
591  Map_getseters, /* tp_getset */
592  NULL, /* tp_base */
593  NULL, /* tp_dict */
594  NULL, /* tp_descr_get */
595  NULL, /* tp_descr_set */
596  0, /* tp_dictoffset */
597  NULL, /* tp_init */
598  NULL, /* tp_alloc */
599  Crossfire_Map_new, /* tp_new */
600  NULL, /* tp_free */
601  NULL, /* tp_is_gc */
602  NULL, /* tp_bases */
603  NULL, /* tp_mro */
604  NULL, /* tp_cache */
605  NULL, /* tp_subclasses */
606  NULL, /* tp_weaklist */
607  NULL, /* tp_del */
608 };
static PyObject * Crossfire_Map_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Python initialized.
Definition: cfpython_map.c:400
Error, serious thing.
Definition: logger.h:11
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:365
Main Crossfire structure, one ingame object.
Definition: object.h:274
void cf_map_message(mapstruct *m, const char *msg, int color)
Partial wrapper for ext_info_map().
PyObject_HEAD object * obj
#define CFAPI_MAP_PROP_NAME
Definition: plugin.h:299
Information.
Definition: logger.h:12
static PyObject * Map_Message(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:166
Used to link together several objects.
Definition: object.h:442
static int Map_SetPath(Crossfire_Map *whoptr, PyObject *value, void *closure)
Definition: cfpython_map.c:149
PyObject * Crossfire_Region_wrap(region *what)
PyObject * Crossfire_Map_wrap(mapstruct *what)
Definition: cfpython_map.c:427
static PyObject * Map_GetTempName(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:89
static PyObject * Map_GetUnique(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:161
#define MAPEXISTCHECK_INT(map)
Definition: cfpython_map.h:47
uint32_t in_memory
Combination of IN_MEMORY_xxx flags.
Definition: map.h:345
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)
Wrapper for change_map_light().
static PyObject * Map_GetName(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:94
region * cf_map_get_region_property(mapstruct *map, int propcode)
#define NDI_BLUE
Actually, it is Dodger Blue.
Definition: newclient.h:226
static PyObject * Map_GetResetTime(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:99
int cf_map_get_height(mapstruct *map)
int cf_map_get_difficulty(mapstruct *map)
static PyNumberMethods MapConvert
Definition: cfpython_map.c:485
mapstruct * cf_map_get_map_property(mapstruct *map, int propcode)
void init_map_assoc_table(void)
Definition: cfpython_map.c:37
static int Map_InternalCompare(Crossfire_Map *left, Crossfire_Map *right)
Definition: cfpython_map.c:341
static PyObject * Crossfire_Map_Int(PyObject *obj)
Definition: cfpython_map.c:391
static void add_map_assoc(mapstruct *key, Crossfire_Map *value)
Definition: cfpython_map.c:41
static PyObject * Map_GetWidth(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:119
#define CFAPI_MAP_PROP_NEXT
Definition: plugin.h:310
long value
Used as connected value in buttons/gates.
Definition: object.h:453
int cf_map_get_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Wrapper for get_map_flags().
Used to link together several object links.
Definition: object.h:451
static ptr_assoc_table map_assoc_table
Definition: cfpython_map.c:34
struct oblnk * link
Items for this value.
Definition: object.h:452
static PyObject * Map_GetDifficulty(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:79
static PyObject * Map_InsertAround(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:261
void cf_log(LogLevel logLevel, const char *format,...)
Wrapper for LOG().
static PyObject * Map_GetPlayers(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:109
#define MAP_IN_MEMORY
Map is fully loaded.
Definition: map.h:130
struct oblinkpt * next
Next value in the list.
Definition: object.h:454
static PyObject * Crossfire_Map_RichCompare(Crossfire_Map *left, Crossfire_Map *right, int op)
Definition: cfpython_map.c:347
int cf_map_get_players(mapstruct *map)
static void ensure_map_in_memory(Crossfire_Map *map)
This makes sure the map is in memory and not swapped out.
Definition: cfpython_map.c:55
#define PyObject_HashNotImplemented
Definition: cfpython.h:73
object * cf_map_insert_object_around(mapstruct *where, object *op, int x, int y)
Will insert op in the map where around the spot x, y.
PyTypeObject Crossfire_ObjectType
#define CFAPI_MAP_PROP_UNIQUE
Definition: plugin.h:312
static PyObject * find_assoc_pymap(mapstruct *key)
Definition: cfpython_map.c:45
static PyObject * Crossfire_Map_Long(PyObject *obj)
Definition: cfpython_map.c:385
static PyObject * Map_GetEnterY(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:134
void Handle_Map_Unload_Hook(Crossfire_Map *map)
Definition: cfpython_map.c:422
signed short int16_t
Definition: win32.h:160
static PyObject * Map_CreateObject(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:197
mapstruct * cf_map_get_map(const char *name, int flags)
Wrapper for ready_map_name().
static void free_map_assoc(mapstruct *key)
Definition: cfpython_map.c:49
object * cf_map_insert_object(mapstruct *where, object *op, int x, int y)
Wrapper for object_insert_in_map_at().
PyObject * Crossfire_Object_wrap(object *what)
Python initialized.
int cf_map_get_reset_time(mapstruct *map)
static PyObject * Map_GetHeight(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:124
PyObject_HEAD mapstruct * map
Definition: cfpython_map.h:34
#define P_OUT_OF_MAP
This space is outside the map.
Definition: map.h:251
#define CFAPI_MAP_PROP_MESSAGE
Definition: plugin.h:309
void * find_assoc_value(ptr_assoc **hash_table, void *key)
Find the value associated with a given 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:298
object * cf_map_find_by_archetype_name(const char *str, mapstruct *map, int nx, int ny)
Kinda wrapper for map_find_by_archetype_name().
static PyObject * Map_GetDarkness(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:114
static PyObject * Map_GetPath(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:84
int cf_map_get_reset_timeout(mapstruct *map)
oblinkpt * buttons
Linked list of linked lists of buttons.
Definition: map.h:354
int cf_map_get_darkness(mapstruct *map)
void cf_map_trigger_connected(objectlink *ol, object *cause, int state)
Wrapper for trigger_connected().
static PyObject * Map_GetRegion(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:144
void add_ptr_assoc(ptr_assoc **hash_table, void *key, void *value)
Adds a value to a hash table which one can lookup with key.
Definition: hashtable.c:109
object * cf_map_get_object_at(mapstruct *m, int x, int y)
Wrapper for GET_MAP_OB().
void init_ptr_assoc_table(ptr_assoc **hash_table)
Initialises the hash table for a pointer association table.
Definition: hashtable.c:57
static PyObject * Map_GetMessage(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:139
static PyObject * Map_Insert(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:246
static PyObject * Map_GetEnterX(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:129
#define MAP_PLAYER_UNIQUE
This map is player-specific.
Definition: map.h:97
static PyObject * Map_GetFirstObjectAt(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:181
static PyObject * Map_TriggerConnected(Crossfire_Map *map, PyObject *args)
Python backend method for Map.TriggerConnected(int connected, CfObject cause, int state) ...
Definition: cfpython_map.c:301
Only for debugging purposes.
Definition: logger.h:13
#define CFAPI_MAP_PROP_PATH
Definition: plugin.h:297
static PyGetSetDef Map_getseters[]
Definition: cfpython_map.c:452
static PyObject * Map_ChangeLight(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:276
#define CFAPI_MAP_PROP_REGION
Definition: plugin.h:311
sstring cf_map_get_sstring_property(mapstruct *map, int propcode)
void free_ptr_assoc(ptr_assoc **hash_table, void *key)
Remove the association with a given key.
Definition: hashtable.c:222
static PyObject * Map_GetResetTimeout(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.c:104
#define Py_TYPE(ob)
Definition: cfpython.h:66
static PyObject * Map_Check(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:217
char * strdup(const char *str)
Portable implementation of strdup(3).
Definition: porting.c:200
#define NDI_UNIQUE
Print immediately, don&#39;t buffer.
Definition: newclient.h:245
This is a game-map.
Definition: map.h:325
PyTypeObject Crossfire_MapType
Definition: cfpython_map.c:551
static void Crossfire_Map_dealloc(PyObject *obj)
Definition: cfpython_map.c:410
int cf_map_get_int_property(mapstruct *map, int property)
#define CFAPI_MAP_PROP_ENTER_X
Definition: plugin.h:307
object * cf_create_object_by_name(const char *name)
Wrapper for create_archetype() and create_archetype_by_object_name().
static PyObject * Map_Next(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.c:241
int cf_map_get_width(mapstruct *map)
int cf_map_get_enter_x(mapstruct *map)
static PyMethodDef MapMethods[]
Definition: cfpython_map.c:472