Crossfire Server, Branch 1.12
R12190
|
00001 /*****************************************************************************/ 00002 /* CFPython - A Python module for Crossfire RPG. */ 00003 /* Version: 2.0beta8 (also known as "Alexander") */ 00004 /* Contact: yann.chachkoff@myrealbox.com */ 00005 /*****************************************************************************/ 00006 /* That code is placed under the GNU General Public Licence (GPL) */ 00007 /* (C)2001-2005 by Chachkoff Yann (Feel free to deliver your complaints) */ 00008 /*****************************************************************************/ 00009 /* CrossFire, A Multiplayer game for X-windows */ 00010 /* */ 00011 /* Copyright (C) 2000 Mark Wedel */ 00012 /* Copyright (C) 1992 Frank Tore Johansen */ 00013 /* */ 00014 /* This program is free software; you can redistribute it and/or modify */ 00015 /* it under the terms of the GNU General Public License as published by */ 00016 /* the Free Software Foundation; either version 2 of the License, or */ 00017 /* (at your option) any later version. */ 00018 /* */ 00019 /* This program is distributed in the hope that it will be useful, */ 00020 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 00021 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ 00022 /* GNU General Public License for more details. */ 00023 /* */ 00024 /* You should have received a copy of the GNU General Public License */ 00025 /* along with this program; if not, write to the Free Software */ 00026 /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 00027 /* */ 00028 /*****************************************************************************/ 00029 00030 #include <cfpython.h> 00031 #include <cfpython_map_private.h> 00032 #include <hashtable.h> 00033 00034 /* Table for keeping track of which PyObject goes with with Crossfire object */ 00035 static ptr_assoc_table map_assoc_table; 00036 00037 /* Helper functions for dealing with object_assoc_table */ 00038 void init_map_assoc_table(void) { 00039 init_ptr_assoc_table(map_assoc_table); 00040 } 00041 00042 static void add_map_assoc(mapstruct *key, Crossfire_Map *value) { 00043 add_ptr_assoc(map_assoc_table, key, value); 00044 } 00045 00046 static PyObject *find_assoc_pymap(mapstruct *key) { 00047 return (PyObject *)find_assoc_value(map_assoc_table, key); 00048 } 00049 00050 static void free_map_assoc(mapstruct *key) { 00051 free_ptr_assoc(map_assoc_table, key); 00052 } 00053 00054 static PyObject *Map_GetDifficulty(Crossfire_Map *whoptr, void *closure) { 00055 MAPEXISTCHECK(whoptr); 00056 return Py_BuildValue("i", cf_map_get_difficulty(whoptr->map)); 00057 } 00058 00059 static PyObject *Map_GetPath(Crossfire_Map *whoptr, void *closure) { 00060 MAPEXISTCHECK(whoptr); 00061 return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_PATH)); 00062 } 00063 00064 static PyObject *Map_GetTempName(Crossfire_Map *whoptr, void *closure) { 00065 MAPEXISTCHECK(whoptr); 00066 return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_TMPNAME)); 00067 } 00068 00069 static PyObject *Map_GetName(Crossfire_Map *whoptr, void *closure) { 00070 MAPEXISTCHECK(whoptr); 00071 return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_NAME)); 00072 } 00073 00074 static PyObject *Map_GetResetTime(Crossfire_Map *whoptr, void *closure) { 00075 MAPEXISTCHECK(whoptr); 00076 return Py_BuildValue("i", cf_map_get_reset_time(whoptr->map)); 00077 } 00078 00079 static PyObject *Map_GetResetTimeout(Crossfire_Map *whoptr, void *closure) { 00080 MAPEXISTCHECK(whoptr); 00081 return Py_BuildValue("i", cf_map_get_reset_timeout(whoptr->map)); 00082 } 00083 00084 static PyObject *Map_GetPlayers(Crossfire_Map *whoptr, void *closure) { 00085 MAPEXISTCHECK(whoptr); 00086 return Py_BuildValue("i", cf_map_get_players(whoptr->map)); 00087 } 00088 00089 static PyObject *Map_GetDarkness(Crossfire_Map *whoptr, void *closure) { 00090 MAPEXISTCHECK(whoptr); 00091 return Py_BuildValue("i", cf_map_get_darkness(whoptr->map)); 00092 } 00093 00094 static PyObject *Map_GetWidth(Crossfire_Map *whoptr, void *closure) { 00095 MAPEXISTCHECK(whoptr); 00096 return Py_BuildValue("i", cf_map_get_width(whoptr->map)); 00097 } 00098 00099 static PyObject *Map_GetHeight(Crossfire_Map *whoptr, void *closure) { 00100 MAPEXISTCHECK(whoptr); 00101 return Py_BuildValue("i", cf_map_get_height(whoptr->map)); 00102 } 00103 00104 static PyObject *Map_GetEnterX(Crossfire_Map *whoptr, void *closure) { 00105 MAPEXISTCHECK(whoptr); 00106 return Py_BuildValue("i", cf_map_get_int_property(whoptr->map, CFAPI_MAP_PROP_ENTER_X)); 00107 } 00108 00109 static PyObject *Map_GetEnterY(Crossfire_Map *whoptr, void *closure) { 00110 MAPEXISTCHECK(whoptr); 00111 return Py_BuildValue("i", cf_map_get_enter_x(whoptr->map)); 00112 } 00113 00114 static PyObject *Map_GetMessage(Crossfire_Map *whoptr, void *closure) { 00115 MAPEXISTCHECK(whoptr); 00116 return Py_BuildValue("s", cf_map_get_sstring_property(whoptr->map, CFAPI_MAP_PROP_MESSAGE)); 00117 } 00118 00119 static PyObject *Map_GetRegion(Crossfire_Map *whoptr, void *closure) { 00120 MAPEXISTCHECK(whoptr); 00121 return Crossfire_Region_wrap(cf_map_get_region_property(whoptr->map, CFAPI_MAP_PROP_REGION)); 00122 } 00123 00124 static int Map_SetPath(Crossfire_Map *whoptr, PyObject *value, void *closure) { 00125 const char *val; 00126 00127 MAPEXISTCHECK_INT(whoptr); 00128 if (!PyArg_Parse(value, "s", &val)) 00129 return -1; 00130 00131 cf_map_set_string_property(whoptr->map, CFAPI_MAP_PROP_PATH, val); 00132 return 0; 00133 00134 } 00135 00136 static PyObject *Map_GetUnique(Crossfire_Map *whoptr, void *closure) { 00137 MAPEXISTCHECK(whoptr); 00138 return Py_BuildValue("i", cf_map_get_int_property(whoptr->map, CFAPI_MAP_PROP_UNIQUE)); 00139 } 00140 00141 static PyObject *Map_Message(Crossfire_Map *map, PyObject *args) { 00142 int color = NDI_BLUE|NDI_UNIQUE; 00143 char *message; 00144 00145 if (!PyArg_ParseTuple(args, "s|i", &message, &color)) 00146 return NULL; 00147 00148 MAPEXISTCHECK(map); 00149 00150 cf_map_message(map->map, message, color); 00151 00152 Py_INCREF(Py_None); 00153 return Py_None; 00154 } 00155 00156 static PyObject *Map_GetFirstObjectAt(Crossfire_Map *map, PyObject *args) { 00157 int x, y; 00158 object *val; 00159 00160 if (!PyArg_ParseTuple(args, "ii", &x, &y)) 00161 return NULL; 00162 00163 MAPEXISTCHECK(map); 00164 00165 val = cf_map_get_object_at(map->map, x, y); 00166 return Crossfire_Object_wrap(val); 00167 } 00168 00169 static PyObject *Map_CreateObject(Crossfire_Map *map, PyObject *args) { 00170 char *txt; 00171 int x, y; 00172 object *op; 00173 00174 if (!PyArg_ParseTuple(args, "sii", &txt, &x, &y)) 00175 return NULL; 00176 00177 MAPEXISTCHECK(map); 00178 00179 op = cf_create_object_by_name(txt); 00180 00181 if (op) 00182 op = cf_map_insert_object(map->map, op, x, y); 00183 return Crossfire_Object_wrap(op); 00184 } 00185 00186 static PyObject *Map_Check(Crossfire_Map *map, PyObject *args) { 00187 char *what; 00188 int x, y; 00189 object *foundob; 00190 sint16 nx, ny; 00191 int mflags; 00192 00193 if (!PyArg_ParseTuple(args, "s(ii)", &what, &x, &y)) 00194 return NULL; 00195 00196 MAPEXISTCHECK(map); 00197 00198 /* make sure the map is swapped in */ 00199 if (map->map->in_memory != MAP_IN_MEMORY) { 00200 cf_log(llevError, "MAP AIN'T READY !\n"); 00201 } 00202 00203 mflags = cf_map_get_flags(map->map, &(map->map), (sint16)x, (sint16)y, &nx, &ny); 00204 if (mflags&P_OUT_OF_MAP) { 00205 Py_INCREF(Py_None); 00206 return Py_None; 00207 } 00208 foundob = cf_map_present_arch_by_name(what, map->map, nx, ny); 00209 return Crossfire_Object_wrap(foundob); 00210 } 00211 00212 static PyObject *Map_Next(Crossfire_Map *map, PyObject *args) { 00213 MAPEXISTCHECK(map); 00214 return Crossfire_Map_wrap(cf_map_get_map_property(map->map, CFAPI_MAP_PROP_NEXT)); 00215 } 00216 00217 static PyObject *Map_Insert(Crossfire_Map *map, PyObject *args) { 00218 int x, y; 00219 Crossfire_Object *what; 00220 00221 if (!PyArg_ParseTuple(args, "O!ii", &Crossfire_ObjectType, &what, &x, &y)) 00222 return NULL; 00223 00224 MAPEXISTCHECK(map); 00225 00226 return Crossfire_Object_wrap(cf_map_insert_object(map->map, what->obj, x, y)); 00227 } 00228 00229 static PyObject *Map_ChangeLight(Crossfire_Map *map, PyObject *args) { 00230 int change; 00231 00232 if (!PyArg_ParseTuple(args, "i", &change)) 00233 return NULL; 00234 00235 MAPEXISTCHECK(map); 00236 00237 return Py_BuildValue("i", cf_map_change_light(map->map, change)); 00238 } 00254 static PyObject *Map_TriggerConnected(Crossfire_Map *map, PyObject *args) { 00255 objectlink *ol = NULL; 00256 int connected; 00257 int state; 00258 Crossfire_Object *cause = NULL; 00259 oblinkpt *olp; 00260 00261 if (!PyArg_ParseTuple(args, "ii|O!", &connected, &state, &Crossfire_ObjectType, &cause)) 00262 return NULL; 00263 00264 MAPEXISTCHECK(map); 00265 /* locate objectlink for this connected value */ 00266 if (!map->map->buttons) { 00267 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); 00268 return NULL; 00269 } 00270 for (olp = map->map->buttons; olp; olp = olp->next) { 00271 if (olp->value == connected) { 00272 ol = olp->link; 00273 break; 00274 } 00275 } 00276 if (ol == NULL) { 00277 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); 00278 return NULL; 00279 } 00280 /* run the object link */ 00281 cf_map_trigger_connected(ol, cause ? cause->obj : NULL, state); 00282 00283 Py_INCREF(Py_None); 00284 return Py_None; 00285 } 00286 00287 static int Map_InternalCompare(Crossfire_Map *left, Crossfire_Map *right) { 00288 MAPEXISTCHECK_INT(left); 00289 MAPEXISTCHECK_INT(right); 00290 return left->map < right->map ? -1 : (left->map == right->map ? 0 : 1); 00291 } 00292 00293 /* Legacy code: convert to long so that non-object functions work correctly */ 00294 static PyObject *Crossfire_Map_Long(PyObject *obj) { 00295 MAPEXISTCHECK((Crossfire_Map *)obj); 00296 return Py_BuildValue("l", ((Crossfire_Map *)obj)->map); 00297 } 00298 00299 #ifndef IS_PY3K 00300 static PyObject *Crossfire_Map_Int(PyObject *obj) { 00301 MAPEXISTCHECK((Crossfire_Map *)obj); 00302 return Py_BuildValue("i", ((Crossfire_Map *)obj)->map); 00303 } 00304 #endif 00305 00309 static PyObject *Crossfire_Map_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { 00310 Crossfire_Map *self; 00311 00312 self = (Crossfire_Map *)type->tp_alloc(type, 0); 00313 if (self) 00314 self->map = NULL; 00315 00316 return (PyObject *)self; 00317 } 00318 00319 static void Crossfire_Map_dealloc(PyObject *obj) { 00320 Crossfire_Map *self; 00321 00322 self = (Crossfire_Map *)obj; 00323 if (self) { 00324 if (self->map && self->valid) { 00325 free_map_assoc(self->map); 00326 } 00327 Py_TYPE(self)->tp_free(obj); 00328 } 00329 } 00330 00331 void Handle_Map_Unload_Hook(Crossfire_Map *map) { 00332 map->valid = 0; 00333 free_map_assoc(map->map); 00334 } 00335 00336 PyObject *Crossfire_Map_wrap(mapstruct *what) { 00337 Crossfire_Map *wrapper; 00338 00339 /* return None if no object was to be wrapped */ 00340 if (what == NULL) { 00341 Py_INCREF(Py_None); 00342 return Py_None; 00343 } 00344 00345 wrapper = (Crossfire_Map *)find_assoc_pymap(what); 00346 if (!wrapper) { 00347 wrapper = PyObject_NEW(Crossfire_Map, &Crossfire_MapType); 00348 if (wrapper != NULL) { 00349 wrapper->map = what; 00350 wrapper->valid = 1; 00351 add_map_assoc(what, wrapper); 00352 } 00353 } else { 00354 Py_INCREF(wrapper); 00355 } 00356 00357 return (PyObject *)wrapper; 00358 }