Crossfire Server, Trunk
cfpython_map.cpp
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 <map>
32 
33 /* Table for keeping track of which PyObject goes with with Crossfire object */
34 static std::map<mapstruct *, Crossfire_Map *> map_assoc_table;
35 
38 }
39 
41  auto f = map_assoc_table.find(key);
42  return f == map_assoc_table.end() ? nullptr : f->second;
43 }
44 
45 static void free_map_assoc(mapstruct *key) {
46  map_assoc_table.erase(key);
47 }
48 
49 
52  assert(map->map != NULL);
53  if (map->map->in_memory != MAP_IN_MEMORY) {
54  char* mapname = map->map->path;
55  int is_unique = cf_map_get_int_property(map->map, CFAPI_MAP_PROP_UNIQUE);
56  /* If the map is unique the path name will be freed. We need to handle that. */
57  if (is_unique) {
58  char* tmp = strdup(mapname);
59  if (!tmp) {
60  /* FIXME: We should fatal() here, but that doesn't exist in plugins. */
61  cf_log(llevError, "Out of memory in ensure_map_in_memory()!\n");
62  abort();
63  }
64  mapname = tmp;
65  }
66  cf_log(llevDebug, "MAP %s AIN'T READY ! Loading it...\n", mapname);
67  /* Map pointer may change for player unique maps. */
68  /* Also, is the MAP_PLAYER_UNIQUE logic correct? */
69  map->map = cf_map_get_map(mapname, is_unique ? MAP_PLAYER_UNIQUE : 0);
70  if (is_unique)
71  free(mapname);
72  }
73 }
74 
75 static PyObject *Map_GetDifficulty(Crossfire_Map *whoptr, void *closure) {
76  (void)closure;
77  MAPEXISTCHECK(whoptr);
78  return Py_BuildValue("i", cf_map_get_difficulty(whoptr->map));
79 }
80 
81 static PyObject *Map_GetPath(Crossfire_Map *whoptr, void *closure) {
82  (void)closure;
83  MAPEXISTCHECK(whoptr);
84  return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_PATH));
85 }
86 
87 static PyObject *Map_GetTempName(Crossfire_Map *whoptr, void *closure) {
88  (void)closure;
89  MAPEXISTCHECK(whoptr);
90  return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_TMPNAME));
91 }
92 
93 static PyObject *Map_GetName(Crossfire_Map *whoptr, void *closure) {
94  (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  (void)closure;
101  MAPEXISTCHECK(whoptr);
102  return Py_BuildValue("i", cf_map_get_reset_time(whoptr->map));
103 }
104 
105 static PyObject *Map_GetResetTimeout(Crossfire_Map *whoptr, void *closure) {
106  (void)closure;
107  MAPEXISTCHECK(whoptr);
108  return Py_BuildValue("i", cf_map_get_reset_timeout(whoptr->map));
109 }
110 
111 static PyObject *Map_GetPlayers(Crossfire_Map *whoptr, void *closure) {
112  (void)closure;
113  MAPEXISTCHECK(whoptr);
114  return Py_BuildValue("i", cf_map_get_players(whoptr->map));
115 }
116 
117 static PyObject *Map_GetDarkness(Crossfire_Map *whoptr, void *closure) {
118  (void)closure;
119  MAPEXISTCHECK(whoptr);
120  return Py_BuildValue("i", cf_map_get_darkness(whoptr->map));
121 }
122 
123 static PyObject *Map_GetWidth(Crossfire_Map *whoptr, void *closure) {
124  (void)closure;
125  MAPEXISTCHECK(whoptr);
126  return Py_BuildValue("i", cf_map_get_width(whoptr->map));
127 }
128 
129 static PyObject *Map_GetHeight(Crossfire_Map *whoptr, void *closure) {
130  (void)closure;
131  MAPEXISTCHECK(whoptr);
132  return Py_BuildValue("i", cf_map_get_height(whoptr->map));
133 }
134 
135 static PyObject *Map_GetEnterX(Crossfire_Map *whoptr, void *closure) {
136  (void)closure;
137  MAPEXISTCHECK(whoptr);
138  return Py_BuildValue("i", cf_map_get_enter_x(whoptr->map));
139 }
140 
141 static PyObject *Map_GetEnterY(Crossfire_Map *whoptr, void *closure) {
142  (void)closure;
143  MAPEXISTCHECK(whoptr);
144  return Py_BuildValue("i", cf_map_get_enter_y(whoptr->map));
145 }
146 
147 static PyObject *Map_GetMessage(Crossfire_Map *whoptr, void *closure) {
148  (void)closure;
149  MAPEXISTCHECK(whoptr);
150  return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_MESSAGE));
151 }
152 
153 static PyObject *Map_GetRegion(Crossfire_Map *whoptr, void *closure) {
154  (void)closure;
155  MAPEXISTCHECK(whoptr);
157 }
158 
159 static int Map_SetPath(Crossfire_Map *whoptr, PyObject *value, void *closure) {
160  const char *val;
161  (void)closure;
162 
163  MAPEXISTCHECK_INT(whoptr);
164  if (!PyArg_Parse(value, "s", &val))
165  return -1;
166 
168  return 0;
169 
170 }
171 
172 static PyObject *Map_GetUnique(Crossfire_Map *whoptr, void *closure) {
173  (void)closure;
174  MAPEXISTCHECK(whoptr);
175  return Py_BuildValue("i", cf_map_get_int_property(whoptr->map, CFAPI_MAP_PROP_UNIQUE));
176 }
177 
178 static PyObject *Map_Message(Crossfire_Map *map, PyObject *args) {
179  int color = NDI_BLUE|NDI_UNIQUE;
180  char *message;
181 
182  if (!PyArg_ParseTuple(args, "s|i", &message, &color))
183  return NULL;
184 
186 
188 
189  Py_INCREF(Py_None);
190  return Py_None;
191 }
192 
193 static PyObject *Map_GetFirstObjectAt(Crossfire_Map *map, PyObject *args) {
194  int x, y;
195  object *val;
196 
197  if (!PyArg_ParseTuple(args, "ii", &x, &y))
198  return NULL;
199 
201 
202  /* make sure the map is swapped in */
204 
205  val = cf_map_get_object_at(map->map, x, y);
206  return Crossfire_Object_wrap(val);
207 }
208 
209 static PyObject *Map_CreateObject(Crossfire_Map *map, PyObject *args) {
210  char *txt;
211  int x, y;
212  object *op;
213 
214  if (!PyArg_ParseTuple(args, "sii", &txt, &x, &y))
215  return NULL;
216 
218 
219  /* make sure the map is swapped in */
221 
223 
224  if (op)
225  op = cf_map_insert_object(map->map, op, x, y);
226  return Crossfire_Object_wrap(op);
227 }
228 
229 static PyObject *Map_Check(Crossfire_Map *map, PyObject *args) {
230  char *what;
231  int x, y;
232  object *foundob;
233  int16_t nx, ny;
234  int mflags;
235 
236  if (!PyArg_ParseTuple(args, "s(ii)", &what, &x, &y))
237  return NULL;
238 
240 
241  /* make sure the map is swapped in */
243 
244  mflags = cf_map_get_flags(map->map, &(map->map), (int16_t)x, (int16_t)y, &nx, &ny);
245  if (mflags&P_OUT_OF_MAP) {
246  Py_INCREF(Py_None);
247  return Py_None;
248  }
249  foundob = cf_map_find_by_archetype_name(what, map->map, nx, ny);
250  return Crossfire_Object_wrap(foundob);
251 }
252 
253 static PyObject *Map_Next(Crossfire_Map *map, PyObject *args) {
254  (void)args;
257 }
258 
259 static PyObject *Map_Insert(Crossfire_Map *map, PyObject *args) {
260  int x, y;
261  Crossfire_Object *what;
262 
263  if (!PyArg_ParseTuple(args, "O!ii", &Crossfire_ObjectType, &what, &x, &y))
264  return NULL;
265 
267 
268  /* make sure the map is swapped in */
270 
271  return Crossfire_Object_wrap(cf_map_insert_object(map->map, what->obj, x, y));
272 }
273 
274 static PyObject *Map_InsertAround(Crossfire_Map *map, PyObject *args) {
275  int x, y;
276  Crossfire_Object *what;
277 
278  if (!PyArg_ParseTuple(args, "O!ii", &Crossfire_ObjectType, &what, &x, &y))
279  return NULL;
280 
282 
283  /* make sure the map is swapped in */
285 
287 }
288 
289 static PyObject *Map_ChangeLight(Crossfire_Map *map, PyObject *args) {
290  int change;
291 
292  if (!PyArg_ParseTuple(args, "i", &change))
293  return NULL;
294 
296 
297  return Py_BuildValue("i", cf_map_change_light(map->map, change));
298 }
314 static PyObject *Map_TriggerConnected(Crossfire_Map *map, PyObject *args) {
315  objectlink *ol = NULL;
316  int connected;
317  int state;
318  Crossfire_Object *cause = NULL;
319  oblinkpt *olp;
320 
321  if (!PyArg_ParseTuple(args, "ii|O!", &connected, &state, &Crossfire_ObjectType, &cause))
322  return NULL;
323 
325 
326  /* make sure the map is swapped in */
328 
329  /* locate objectlink for this connected value */
330  if (!map->map->buttons) {
331  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);
332  PyErr_SetString(PyExc_ReferenceError, "No objects connected to that ID on this map.");
333  return NULL;
334  }
335  for (olp = map->map->buttons; olp; olp = olp->next) {
336  if (olp->value == connected) {
337  ol = olp->link;
338  break;
339  }
340  }
341  if (ol == NULL) {
342  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);
343  /* FIXME: I'm not sure about this message... */
344  PyErr_SetString(PyExc_ReferenceError, "No objects with that connection ID on this map.");
345  return NULL;
346  }
347  /* run the object link */
348  cf_map_trigger_connected(ol, cause ? cause->obj : NULL, state);
349 
350  Py_INCREF(Py_None);
351  return Py_None;
352 }
353 
355  MAPEXISTCHECK_INT(left);
356  MAPEXISTCHECK_INT(right);
357  return left->map < right->map ? -1 : (left->map == right->map ? 0 : 1);
358 }
359 
360 static PyObject *Crossfire_Map_RichCompare(Crossfire_Map *left, Crossfire_Map *right, int op) {
361  int result;
362  if (!left
363  || !right
364  || !PyObject_TypeCheck((PyObject*)left, &Crossfire_MapType)
365  || !PyObject_TypeCheck((PyObject*)right, &Crossfire_MapType)) {
366  Py_INCREF(Py_NotImplemented);
367  return Py_NotImplemented;
368  }
369  result = Map_InternalCompare(left, right);
370  /* Handle removed maps. */
371  if (result == -1 && PyErr_Occurred())
372  return NULL;
373  /* Based on how Python 3.0 (GPL compatible) implements it for internal types: */
374  switch (op) {
375  case Py_EQ:
376  result = (result == 0);
377  break;
378  case Py_NE:
379  result = (result != 0);
380  break;
381  case Py_LE:
382  result = (result <= 0);
383  break;
384  case Py_GE:
385  result = (result >= 0);
386  break;
387  case Py_LT:
388  result = (result == -1);
389  break;
390  case Py_GT:
391  result = (result == 1);
392  break;
393  }
394  return PyBool_FromLong(result);
395 }
396 
397 /* Legacy code: convert to long so that non-object functions work correctly */
398 static PyObject *Crossfire_Map_Long(PyObject *obj) {
400  return Py_BuildValue("l", ((Crossfire_Map *)obj)->map);
401 }
402 
406 static PyObject *Crossfire_Map_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
407  Crossfire_Map *self;
408  (void)args;
409  (void)kwds;
410 
411  self = (Crossfire_Map *)type->tp_alloc(type, 0);
412  if (self)
413  self->map = NULL;
414 
415  return (PyObject *)self;
416 }
417 
418 static void Crossfire_Map_dealloc(PyObject *obj) {
419  Crossfire_Map *self;
420 
421  self = (Crossfire_Map *)obj;
422  if (self) {
423  if (self->map && self->valid) {
424  free_map_assoc(self->map);
425  }
426  Py_TYPE(self)->tp_free(obj);
427  }
428 }
429 
431  map->valid = 0;
432  free_map_assoc(map->map);
433 }
434 
435 PyObject *Crossfire_Map_wrap(mapstruct *what) {
436  Crossfire_Map *wrapper;
437 
438  /* return None if no object was to be wrapped */
439  if (what == NULL) {
440  Py_INCREF(Py_None);
441  return Py_None;
442  }
443 
444  wrapper = find_assoc_pymap(what);
445  if (!wrapper) {
446  wrapper = PyObject_NEW(Crossfire_Map, &Crossfire_MapType);
447  if (wrapper != NULL) {
448  wrapper->map = what;
449  wrapper->valid = 1;
450  add_map_assoc(what, wrapper);
451  }
452  } else {
453  Py_INCREF(wrapper);
454  }
455 
456  return (PyObject *)wrapper;
457 }
458 
459 /* Python binding */
460 static PyGetSetDef Map_getseters[] = {
461  { "Difficulty", (getter)Map_GetDifficulty, NULL, NULL, NULL },
462  { "Path", (getter)Map_GetPath, (setter)Map_SetPath, NULL, NULL },
463  { "TempName", (getter)Map_GetTempName, NULL, NULL, NULL },
464  { "Name", (getter)Map_GetName, NULL, NULL, NULL },
465  { "ResetTime", (getter)Map_GetResetTime, NULL, NULL, NULL },
466  { "ResetTimeout", (getter)Map_GetResetTimeout, NULL, NULL, NULL },
467  { "Players", (getter)Map_GetPlayers, NULL, NULL, NULL },
468  { "Light", (getter)Map_GetDarkness, NULL, NULL, NULL },
469  { "Darkness", (getter)Map_GetDarkness, NULL, NULL, NULL },
470  { "Width", (getter)Map_GetWidth, NULL, NULL, NULL },
471  { "Height", (getter)Map_GetHeight, NULL, NULL, NULL },
472  { "EnterX", (getter)Map_GetEnterX, NULL, NULL, NULL },
473  { "EnterY", (getter)Map_GetEnterY, NULL, NULL, NULL },
474  { "Message", (getter)Map_GetMessage, NULL, NULL, NULL },
475  { "Region", (getter)Map_GetRegion, NULL, NULL, NULL },
476  { "Unique", (getter)Map_GetUnique, NULL, NULL, NULL },
477  { NULL, NULL, NULL, NULL, NULL }
478 };
479 
480 static PyMethodDef MapMethods[] = {
481  { "Print", (PyCFunction)Map_Message, METH_VARARGS, NULL },
482  { "ObjectAt", (PyCFunction)Map_GetFirstObjectAt, METH_VARARGS, NULL },
483  { "CreateObject", (PyCFunction)Map_CreateObject, METH_VARARGS, NULL },
484  { "Check", (PyCFunction)Map_Check, METH_VARARGS, NULL },
485  { "Next", (PyCFunction)Map_Next, METH_NOARGS, NULL },
486  { "Insert", (PyCFunction)Map_Insert, METH_VARARGS, NULL },
487  { "InsertAround", (PyCFunction)Map_InsertAround, METH_VARARGS, NULL },
488  { "ChangeLight", (PyCFunction)Map_ChangeLight, METH_VARARGS, NULL },
489  { "TriggerConnected", (PyCFunction)Map_TriggerConnected, METH_VARARGS, NULL },
490  { NULL, NULL, 0, NULL }
491 };
492 
494 
495 /* Our actual Python MapType */
498  &MapConvert,
499  PyObject_HashNotImplemented,
500  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
501  "Crossfire maps",
502  (richcmpfunc) Crossfire_Map_RichCompare,
503  MapMethods,
505  NULL,
507  );
add_map_assoc
static void add_map_assoc(mapstruct *key, Crossfire_Map *value)
Definition: cfpython_map.cpp:36
cf_map_get_region_property
region * cf_map_get_region_property(mapstruct *map, int propcode)
Definition: plugin_common.cpp:288
MAPEXISTCHECK_INT
#define MAPEXISTCHECK_INT(map)
Definition: cfpython_map.h:47
cf_log
void cf_log(LogLevel logLevel, const char *format,...)
Definition: plugin_common.cpp:1522
cf_map_get_height
int cf_map_get_height(mapstruct *map)
Definition: plugin_common.cpp:1404
Map_GetDifficulty
static PyObject * Map_GetDifficulty(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:75
cf_map_get_sstring_property
sstring cf_map_get_sstring_property(mapstruct *map, int propcode)
Definition: plugin_common.cpp:270
CFAPI_MAP_PROP_TMPNAME
#define CFAPI_MAP_PROP_TMPNAME
Definition: plugin.h:248
free_map_assoc
static void free_map_assoc(mapstruct *key)
Definition: cfpython_map.cpp:45
cf_map_get_int_property
int cf_map_get_int_property(mapstruct *map, int property)
Definition: plugin_common.cpp:254
llevError
@ llevError
Definition: logger.h:11
cf_map_get_players
int cf_map_get_players(mapstruct *map)
Definition: plugin_common.cpp:1392
Map_SetPath
static int Map_SetPath(Crossfire_Map *whoptr, PyObject *value, void *closure)
Definition: cfpython_map.cpp:159
altar_valkyrie.obj
obj
Definition: altar_valkyrie.py:33
diamondslots.x
x
Definition: diamondslots.py:15
Map_Insert
static PyObject * Map_Insert(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.cpp:259
CFAPI_MAP_PROP_NEXT
#define CFAPI_MAP_PROP_NEXT
Definition: plugin.h:260
oblinkpt::next
oblinkpt * next
Definition: object.h:463
Map_GetHeight
static PyObject * Map_GetHeight(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:129
cf_create_object_by_name
object * cf_create_object_by_name(const char *name)
Definition: plugin_common.cpp:1093
cf_map_get_reset_time
int cf_map_get_reset_time(mapstruct *map)
Definition: plugin_common.cpp:1384
Map_ChangeLight
static PyObject * Map_ChangeLight(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.cpp:289
cf_map_insert_object_around
object * cf_map_insert_object_around(mapstruct *where, object *op, int x, int y)
Definition: plugin_common.cpp:1351
Ice.tmp
int tmp
Definition: Ice.py:207
Map_getseters
static PyGetSetDef Map_getseters[]
Definition: cfpython_map.cpp:460
MAP_PLAYER_UNIQUE
#define MAP_PLAYER_UNIQUE
Definition: map.h:93
oblinkpt
Definition: object.h:460
cf_map_insert_object
object * cf_map_insert_object(mapstruct *where, object *op, int x, int y)
Definition: plugin_common.cpp:1329
CF_PYTHON_OBJECT
CF_PYTHON_OBJECT(Map, Crossfire_Map_dealloc, &MapConvert, PyObject_HashNotImplemented, Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, "Crossfire maps",(richcmpfunc) Crossfire_Map_RichCompare, MapMethods, Map_getseters, NULL, Crossfire_Map_new)
CFAPI_MAP_PROP_UNIQUE
#define CFAPI_MAP_PROP_UNIQUE
Definition: plugin.h:262
smoking_pipe.color
color
Definition: smoking_pipe.py:5
Handle_Map_Unload_Hook
void Handle_Map_Unload_Hook(Crossfire_Map *map)
Definition: cfpython_map.cpp:430
NDI_BLUE
#define NDI_BLUE
Definition: newclient.h:236
push.connected
connected
Definition: push.py:59
Map_GetEnterY
static PyObject * Map_GetEnterY(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:141
Crossfire_Object_wrap
PyObject * Crossfire_Object_wrap(object *what)
Definition: cfpython_object.cpp:1606
Map_GetTempName
static PyObject * Map_GetTempName(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:87
MAPEXISTCHECK
#define MAPEXISTCHECK(map)
Definition: cfpython_map.h:40
CFAPI_MAP_PROP_REGION
#define CFAPI_MAP_PROP_REGION
Definition: plugin.h:261
Map_GetPath
static PyObject * Map_GetPath(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:81
MAP_IN_MEMORY
#define MAP_IN_MEMORY
Definition: map.h:127
Crossfire_Map_new
static PyObject * Crossfire_Map_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Definition: cfpython_map.cpp:406
disinfect.map
map
Definition: disinfect.py:4
oblinkpt::link
objectlink * link
Definition: object.h:461
make_face_from_files.args
args
Definition: make_face_from_files.py:37
cf_map_get_object_at
object * cf_map_get_object_at(mapstruct *m, int x, int y)
Definition: plugin_common.cpp:655
rotate-tower.result
bool result
Definition: rotate-tower.py:13
Map_Message
static PyObject * Map_Message(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.cpp:178
CFAPI_MAP_PROP_MESSAGE
#define CFAPI_MAP_PROP_MESSAGE
Definition: plugin.h:259
Crossfire_Map::map
PyObject_HEAD mapstruct * map
Definition: cfpython_map.h:34
cf_map_get_enter_y
int cf_map_get_enter_y(mapstruct *map)
Definition: plugin_common.cpp:1412
oblinkpt::value
long value
Definition: object.h:462
Crossfire_Object
Definition: cfpython_object.h:32
Map_GetUnique
static PyObject * Map_GetUnique(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:172
cfpython.h
Map
Definition: newserver.h:48
map_assoc_table
static std::map< mapstruct *, Crossfire_Map * > map_assoc_table
Definition: cfpython_map.cpp:34
guild_questpoints_apply.mapname
mapname
Definition: guild_questpoints_apply.py:8
message
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your message
Definition: survival-guide.txt:34
CFAPI_MAP_PROP_PATH
#define CFAPI_MAP_PROP_PATH
Definition: plugin.h:247
cf_map_message
void cf_map_message(mapstruct *m, const char *msg, int color)
Definition: plugin_common.cpp:667
cf_map_get_reset_timeout
int cf_map_get_reset_timeout(mapstruct *map)
Definition: plugin_common.cpp:1388
Crossfire_Region_wrap
PyObject * Crossfire_Region_wrap(region *what)
Definition: cfpython_region.cpp:72
cf_map_get_enter_x
int cf_map_get_enter_x(mapstruct *map)
Definition: plugin_common.cpp:1408
nlohmann::detail::void
j template void())
Definition: json.hpp:4099
cf_map_get_map_property
mapstruct * cf_map_get_map_property(mapstruct *map, int propcode)
Definition: plugin_common.cpp:279
cf_map_get_flags
int cf_map_get_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: plugin_common.cpp:1461
P_OUT_OF_MAP
#define P_OUT_OF_MAP
Definition: map.h:248
CFAPI_MAP_PROP_NAME
#define CFAPI_MAP_PROP_NAME
Definition: plugin.h:249
cf_map_set_string_property
void cf_map_set_string_property(mapstruct *map, int propcode, const char *value)
Definition: plugin_common.cpp:305
llevInfo
@ llevInfo
Definition: logger.h:12
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:251
Crossfire_Map_Long
static PyObject * Crossfire_Map_Long(PyObject *obj)
Definition: cfpython_map.cpp:398
Map_GetResetTimeout
static PyObject * Map_GetResetTimeout(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:105
Crossfire_Map::valid
int valid
Definition: cfpython_map.h:35
cf_map_trigger_connected
void cf_map_trigger_connected(objectlink *ol, object *cause, int state)
Definition: plugin_common.cpp:1028
mapstruct
Definition: map.h:314
Map_TriggerConnected
static PyObject * Map_TriggerConnected(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.cpp:314
Map_GetPlayers
static PyObject * Map_GetPlayers(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:111
find_assoc_pymap
static Crossfire_Map * find_assoc_pymap(mapstruct *key)
Definition: cfpython_map.cpp:40
Map_GetFirstObjectAt
static PyObject * Map_GetFirstObjectAt(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.cpp:193
give.op
op
Definition: give.py:33
Map_GetResetTime
static PyObject * Map_GetResetTime(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:99
autojail.value
value
Definition: autojail.py:6
Map_GetRegion
static PyObject * Map_GetRegion(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:153
MapMethods
static PyMethodDef MapMethods[]
Definition: cfpython_map.cpp:480
diamondslots.y
y
Definition: diamondslots.py:16
Map_GetDarkness
static PyObject * Map_GetDarkness(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:117
ensure_map_in_memory
static void ensure_map_in_memory(Crossfire_Map *map)
Definition: cfpython_map.cpp:51
Crossfire_Map_dealloc
static void Crossfire_Map_dealloc(PyObject *obj)
Definition: cfpython_map.cpp:418
Map_Check
static PyObject * Map_Check(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.cpp:229
castle_read.key
key
Definition: castle_read.py:64
cf_map_get_difficulty
int cf_map_get_difficulty(mapstruct *map)
Definition: plugin_common.cpp:1380
Map_GetName
static PyObject * Map_GetName(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:93
quest.state
state
Definition: quest.py:13
cf_map_get_darkness
int cf_map_get_darkness(mapstruct *map)
Definition: plugin_common.cpp:1396
cf_map_get_map
mapstruct * cf_map_get_map(const char *name, int flags)
Definition: plugin_common.cpp:935
Map_InternalCompare
static int Map_InternalCompare(Crossfire_Map *left, Crossfire_Map *right)
Definition: cfpython_map.cpp:354
Crossfire_Object::obj
PyObject_HEAD object * obj
Definition: cfpython_object.h:34
Map_GetMessage
static PyObject * Map_GetMessage(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:147
Crossfire_Map_wrap
PyObject * Crossfire_Map_wrap(mapstruct *what)
Definition: cfpython_map.cpp:435
Map_GetWidth
static PyObject * Map_GetWidth(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:123
Crossfire_ObjectType
PyTypeObject Crossfire_ObjectType
cf_map_find_by_archetype_name
object * cf_map_find_by_archetype_name(const char *str, mapstruct *map, int nx, int ny)
Definition: plugin_common.cpp:1371
Map_GetEnterX
static PyObject * Map_GetEnterX(Crossfire_Map *whoptr, void *closure)
Definition: cfpython_map.cpp:135
cf_map_get_width
int cf_map_get_width(mapstruct *map)
Definition: plugin_common.cpp:1400
cf_map_change_light
int cf_map_change_light(mapstruct *m, int change)
Definition: plugin_common.cpp:1420
Map_Next
static PyObject * Map_Next(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.cpp:253
Map_CreateObject
static PyObject * Map_CreateObject(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.cpp:209
llevDebug
@ llevDebug
Definition: logger.h:13
Crossfire_Map_RichCompare
static PyObject * Crossfire_Map_RichCompare(Crossfire_Map *left, Crossfire_Map *right, int op)
Definition: cfpython_map.cpp:360
is_valid_types_gen.type
list type
Definition: is_valid_types_gen.py:25
Map_InsertAround
static PyObject * Map_InsertAround(Crossfire_Map *map, PyObject *args)
Definition: cfpython_map.cpp:274
CF_PYTHON_NUMBER_METHODS
CF_PYTHON_NUMBER_METHODS(Map, Crossfire_Map_Long)
Crossfire_MapType
PyTypeObject Crossfire_MapType
Crossfire_Map
Definition: cfpython_map.h:32