//***************************************************************************** // // pyroom.c // // Contains the implementation of a module that contains all of the methods // for dealing with rooms. Also contains a Python Class implementation of // NakedMud rooms. // //***************************************************************************** #include <Python.h> #include <structmember.h> #include "../mud.h" #include "../utils.h" #include "../world.h" #include "../room.h" #include "../exit.h" #include "../extra_descs.h" #include "../character.h" #include "../handler.h" #include "../prototype.h" #include "../commands.h" #include "pyplugs.h" #include "scripts.h" #include "pychar.h" #include "pyobj.h" #include "pyexit.h" #include "pyroom.h" #include "pymud.h" #include "pyauxiliary.h" //***************************************************************************** // mandatory modules //***************************************************************************** #include "../dyn_vars/dyn_vars.h" //***************************************************************************** // local structures and defines //***************************************************************************** // a list of the get/setters on the Room class LIST *pyroom_getsetters = NULL; // a list of the methods on the Room class LIST *pyroom_methods = NULL; typedef struct { PyObject_HEAD int uid; } PyRoom; //***************************************************************************** // allocation, deallocation, initialization, and comparison //***************************************************************************** void PyRoom_dealloc(PyRoom *self) { self->ob_type->tp_free((PyObject*)self); } PyObject *PyRoom_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyRoom *self; self = (PyRoom *)type->tp_alloc(type, 0); self->uid = NOWHERE; return (PyObject *)self; } int PyRoom_init(PyRoom *self, PyObject *args, PyObject *kwds) { char *kwlist[] = {"uid", NULL}; int uid = NOTHING; // get the vnum if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &uid)) { PyErr_Format(PyExc_TypeError, "Rooms may only be created using a uid"); return -1; } // make sure a room with the uid exists if(!propertyTableGet(room_table, uid)) { PyErr_Format(PyExc_TypeError, "Room with uid, %d, does not exist", uid); return -1; } self->uid = uid; return 0; } int PyRoom_compare(PyRoom *room1, PyRoom *room2) { if(room1->uid == room2->uid) return 0; else if(room1->uid < room2->uid) return -1; else return 1; } long PyRoom_Hash(PyRoom *room) { return room->uid; } //***************************************************************************** // methods in the room module //***************************************************************************** PyObject *PyRoom_get_room(PyObject *self, PyObject *args) { char *room_key = NULL; ROOM_DATA *room = NULL; if (!PyArg_ParseTuple(args, "s", &room_key)) { PyErr_Format(PyExc_TypeError, "get room failed - it needs a room key/locale."); return NULL; } // try to find the room room = worldGetRoom(gameworld, get_fullkey_relative(room_key, get_script_locale())); if(room == NULL) { PyErr_Format(PyExc_TypeError, "get room failed: room does not exist or " "is abstract."); return NULL; } // create a python object for the new char, and return it return Py_BuildValue("O", roomGetPyFormBorrowed(room)); } //***************************************************************************** // getters and setters for the Room class //***************************************************************************** PyObject *PyRoom_getclass(PyRoom *self, void *closure) { ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room != NULL) return Py_BuildValue("s", roomGetClass(room)); else return NULL; } PyObject *PyRoom_getuid(PyRoom *self, void *closure) { return Py_BuildValue("i", self->uid); } PyObject *PyRoom_getname(PyRoom *self, void *closure) { ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room != NULL) return Py_BuildValue("s", roomGetName(room)); else return NULL; } PyObject *PyRoom_getterrain(PyRoom *self, void *closure) { ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room != NULL) return Py_BuildValue("s", terrainGetName(roomGetTerrain(room))); else return NULL; } PyObject *PyRoom_getdesc(PyRoom *self, void *closure) { ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room != NULL) return Py_BuildValue("s", roomGetDesc(room)); else return NULL; } PyObject *PyRoom_getexnames(PyRoom *self, void *closure) { ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room == NULL) return NULL; PyObject *list = PyList_New(0); LIST *ex_list = roomGetExitNames(room); LIST_ITERATOR *ex_i = newListIterator(ex_list); char *dir = NULL; ITERATE_LIST(dir, ex_i) { PyObject *cont = Py_BuildValue("s", dir); PyList_Append(list, cont); Py_DECREF(cont); } deleteListIterator(ex_i); deleteListWith(ex_list, free); return list; } PyObject *PyRoom_getchars(PyRoom *self, PyObject *args) { ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room == NULL) return NULL; else { LIST_ITERATOR *char_i = newListIterator(roomGetCharacters(room)); PyObject *list = PyList_New(0); CHAR_DATA *ch; // for each char in the room list, add him to a Python list ITERATE_LIST(ch, char_i) PyList_Append(list, charGetPyFormBorrowed(ch)); deleteListIterator(char_i); PyObject *retval = Py_BuildValue("O", list); Py_DECREF(list); return retval; } } PyObject *PyRoom_getobjs(PyRoom *self, PyObject *args) { ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room == NULL) return NULL; else { LIST_ITERATOR *obj_i = newListIterator(roomGetContents(room)); PyObject *list = PyList_New(0); OBJ_DATA *obj; // for each obj in the room list, add him to a Python list ITERATE_LIST(obj, obj_i) PyList_Append(list, objGetPyFormBorrowed(obj)); deleteListIterator(obj_i); PyObject *retval = Py_BuildValue("O", list); Py_DECREF(list); return retval; } } PyObject *PyRoom_getbits(PyRoom *self, void *closure) { ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room!=NULL) return Py_BuildValue("s", bitvectorGetBits(roomGetBits(room))); else return NULL; } // // Standard check to make sure the room exists when trying to set a value for // it. If successful, assign the room to rm. Otherwise, return -1 (error) #define PYROOM_CHECK_ROOM_EXISTS(uid, room) \ room = propertyTableGet(room_table, uid); \ if(room == NULL) { \ PyErr_Format(PyExc_TypeError, \ "Tried to modify nonexistent room, %d", uid); \ return -1; \ } int PyRoom_setname(PyRoom *self, PyObject *value, void *closure) { if (value == NULL) { PyErr_Format(PyExc_TypeError, "Cannot delete room's name"); return -1; } if (!PyString_Check(value)) { PyErr_Format(PyExc_TypeError, "Room names must be strings"); return -1; } ROOM_DATA *room; PYROOM_CHECK_ROOM_EXISTS(self->uid, room); roomSetName(room, PyString_AsString(value)); return 0; } int PyRoom_setdesc(PyRoom *self, PyObject *value, void *closure) { if (value == NULL) { PyErr_Format(PyExc_TypeError, "Cannot delete room's desc"); return -1; } if (!PyString_Check(value)) { PyErr_Format(PyExc_TypeError, "Room descs must be strings"); return -1; } ROOM_DATA *room; PYROOM_CHECK_ROOM_EXISTS(self->uid, room); roomSetDesc(room, PyString_AsString(value)); return 0; } int PyRoom_setterrain(PyRoom *self, PyObject *value, void *closure) { if (value == NULL) { PyErr_Format(PyExc_TypeError, "Cannot delete room's terrain"); return -1; } if (!PyString_Check(value)) { PyErr_Format(PyExc_TypeError, "Room terrain type must be a string"); return -1; } if(terrainGetNum(PyString_AsString(value)) == TERRAIN_NONE) { PyErr_Format(PyExc_TypeError, "Invalid terrain type, %s", PyString_AsString(value)); return -1; } ROOM_DATA *room; PYROOM_CHECK_ROOM_EXISTS(self->uid, room); roomSetTerrain(room, terrainGetNum(PyString_AsString(value))); return 0; } int PyRoom_setbits(PyRoom *self, PyObject *value, void *closure) { if(value == NULL) { PyErr_Format(PyExc_TypeError, "Cannot delete room's bits"); return -1; } if (!PyString_Check(value)) { PyErr_Format(PyExc_TypeError, "Room bits must be strings"); return -1; } ROOM_DATA *room; PYROOM_CHECK_ROOM_EXISTS(self->uid, room); bitClear(roomGetBits(room)); bitSet(roomGetBits(room), PyString_AsString(value)); return 0; } //***************************************************************************** // methods for the room class //***************************************************************************** // // Send a newline-tagged message to everyone in the room PyObject *PyRoom_send(PyRoom *self, PyObject *value) { char *mssg = NULL; if (!PyArg_ParseTuple(value, "s", &mssg)) { PyErr_Format(PyExc_TypeError, "Characters may only be sent strings"); return NULL; } ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room) { send_to_list(roomGetCharacters(room), "%s\r\n", mssg); return Py_BuildValue("i", 1); } else { PyErr_Format(PyExc_TypeError, "Tried to send message to nonexistant room, %d.", self->uid); return NULL; } } // // create a new extra description for the room PyObject *PyRoom_edesc(PyRoom *self, PyObject *value) { char *keywords = NULL; char *desc = NULL; if (!PyArg_ParseTuple(value, "ss", &keywords, &desc)) { PyErr_Format(PyExc_TypeError, "Extra descs must be strings."); return NULL; } ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room != NULL) { EDESC_DATA *edesc = newEdesc(keywords, desc); edescSetPut(roomGetEdescs(room), edesc); return Py_BuildValue("i", 1); } else { PyErr_Format(PyExc_TypeError, "Tried to set edesc for nonexistent room, %d.", self->uid); return NULL; } } // // Get an exit in the room by its direction name PyObject *PyRoom_get_exit(PyRoom *self, PyObject *value) { ROOM_DATA *room = NULL; char *dir = NULL; if (!PyArg_ParseTuple(value, "s", &dir)) { PyErr_Format(PyExc_TypeError, "Direction of exit not supplied."); return NULL; } if((room = PyRoom_AsRoom((PyObject *)self)) == NULL) { PyErr_Format(PyExc_TypeError, "Tried to get exit of nonexistent room, %d.", self->uid); return NULL; } // get the exit const char *cdir = dir; if(dirGetAbbrevNum(dir) != DIR_NONE) cdir = dirGetName(dirGetAbbrevNum(dir)); EXIT_DATA *exit = roomGetExit(room, cdir); if(exit != NULL) { PyObject *pyex = newPyExit(exit); PyObject *retval = Py_BuildValue("O", pyex); Py_DECREF(pyex); return retval; } else return Py_BuildValue("O", Py_None); } // // Returns the direction of the exit PyObject *PyRoom_get_exit_dir(PyObject *self, PyObject *args) { ROOM_DATA *room = NULL; EXIT_DATA *exit = NULL; PyObject *pyex = NULL; if (!PyArg_ParseTuple(args, "O", &pyex)) { PyErr_Format(PyExc_TypeError, "Exit must be supplied."); return NULL; } if((room = PyRoom_AsRoom((PyObject *)self)) == NULL) { PyErr_Format(PyExc_TypeError, "Tried to get exit dir of nonexistent room" ", %d.", PyRoom_AsUid(self)); return NULL; } // get the exit if(!PyExit_Check(pyex)) { PyErr_Format(PyExc_TypeError, "an exit must be supplied to exdir"); return NULL; } // make sure the exit exists exit = PyExit_AsExit(pyex); if(exit == NULL) { PyErr_Format(PyExc_StandardError, "Tried to get direction of nonexistant " "exit, %d.", PyExit_AsUid(pyex)); return NULL; } return Py_BuildValue("s", roomGetExitDir(room, exit)); } // // Fills an exit in the given direction PyObject *PyRoom_fill(PyRoom *self, PyObject *value) { ROOM_DATA *room = NULL; char *dir = NULL; if (!PyArg_ParseTuple(value, "s", &dir)) { PyErr_Format(PyExc_TypeError, "Direction not supplied to fill."); return NULL; } if((room = PyRoom_AsRoom((PyObject *)self)) == NULL) { PyErr_Format(PyExc_TypeError, "Tried to fill in non-existant room, %d.", self->uid); return NULL; } // remove the exit EXIT_DATA *exit = roomRemoveExit(room, dir); if(exit != NULL) { exit_from_game(exit); deleteExit(exit); // is it a special exit? If so, we may need to remove the command as well if(dirGetNum(dir) == DIR_NONE) { CMD_DATA *cmd = nearMapRemove(roomGetCmdTable(room), dir); if(cmd != NULL) deleteCmd(cmd); } } return Py_BuildValue("i", 1); } // // Links a room to another room, in the specified direction PyObject *PyRoom_dig(PyRoom *self, PyObject *value) { ROOM_DATA *room = NULL; PyObject *py_dest = NULL; char *dir = NULL; const char *cdir = NULL; const char *dest = NULL; if (!PyArg_ParseTuple(value, "sO", &dir, &py_dest)) { PyErr_Format(PyExc_TypeError, "When digging, a direction and destination are needed."); return NULL; } if((room = PyRoom_AsRoom((PyObject *)self)) == NULL) { PyErr_Format(PyExc_TypeError, "Tried to dig in non-existant room, %d.", self->uid); return NULL; } // make sure we have a valid destination if(PyString_Check(py_dest)) dest = get_fullkey_relative(PyString_AsString(py_dest),get_script_locale()); else if(PyRoom_Check(py_dest)) { ROOM_DATA *to_room = PyRoom_AsRoom(py_dest); if(to_room != NULL) dest = roomGetClass(to_room); else { PyErr_Format(PyExc_StandardError, "Tried to dig from %s to invalid room, %d", roomGetClass(room), PyRoom_AsUid(py_dest)); return NULL; } } else { PyErr_Format(PyExc_TypeError, "Invalid destination type in room, %s.", roomGetClass(room)); return NULL; } // are we using a special direction name? int dir_num = dirGetNum(dir); int dir_abbrev_num = dirGetAbbrevNum(dir); if(dir_abbrev_num != DIR_NONE) cdir = dirGetName(dir_abbrev_num); else cdir = dir; // do we already have an exit? EXIT_DATA *exit = roomGetExit(room, cdir); if(exit != NULL) { exitSetTo(exit, dest); } else { exit = newExit(); exit_to_game(exit); exitSetTo(exit, dest); roomSetExit(room, cdir, exit); // if we're digging a special exit, add a cmd for it to the room cmd table if(get_cmd_move() && dir_num == DIR_NONE && dir_abbrev_num == DIR_NONE) { CMD_DATA *cmd = newPyCmd(cdir, get_cmd_move(), "player", TRUE); cmdAddCheck(cmd, chk_can_move); nearMapPut(roomGetCmdTable(room), cdir, NULL, cmd); } } PyObject *pyex = newPyExit(exit); PyObject *retval = Py_BuildValue("O", pyex); Py_DECREF(pyex); return retval; } PyObject *PyRoom_attach(PyRoom *self, PyObject *args) { char *key = NULL; // make sure we're getting passed the right type of data if (!PyArg_ParseTuple(args, "s", &key)) { PyErr_Format(PyExc_TypeError, "To attach a script, the key must be supplied."); return NULL; } // pull out the room and do the attaching ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room == NULL) { PyErr_Format(PyExc_StandardError, "Tried to attach script to nonexistant room, %d.", self->uid); return NULL; } TRIGGER_DATA *trig = worldGetType(gameworld, "trigger", get_fullkey_relative(key, get_script_locale())); if(trig != NULL) { triggerListAdd(roomGetTriggers(room), triggerGetKey(trig)); return Py_BuildValue("i", 1); } else { PyErr_Format(PyExc_StandardError, "Tried to attach nonexistant script, %s, to room %s.", key, roomGetClass(room)); return NULL; } } PyObject *PyRoom_detach(PyRoom *self, PyObject *args) { char *key = NULL; // make sure we're getting passed the right type of data if (!PyArg_ParseTuple(args, "s", &key)) { PyErr_Format(PyExc_TypeError, "To detach a script, the key must be suppplied."); return NULL; } // pull out the room and do the attaching ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room != NULL) { const char *fkey = get_fullkey_relative(key, get_script_locale()); triggerListRemove(roomGetTriggers(room), fkey); return Py_BuildValue("i", 1); } else { PyErr_Format(PyExc_StandardError, "Tried to detach script from nonexistant room, %d.",self->uid); return NULL; } } // // adds a new command to the room PyObject *PyRoom_add_cmd(PyRoom *self, PyObject *args) { PyObject *func = NULL; char *name = NULL, *sort_by = NULL, *group = NULL; bool interrupts = FALSE; // parse all of the values if (!PyArg_ParseTuple(args, "szOsb", &name, &sort_by, &func, &group, &interrupts)) { PyErr_Format(PyExc_TypeError, "Could not add new room command. Improper arguments supplied"); return NULL; } // make sure the room exists ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room == NULL) { PyErr_Format(PyExc_StandardError, "Tried to add command to nonexistent room, %d", self->uid); return NULL; } // add the command to the game nearMapPut(roomGetCmdTable(room), name, sort_by, newPyCmd(name, func, group, TRUE)); return Py_BuildValue("O", Py_None); } // // adds a pre-check to a room command PyObject *PyRoom_add_cmd_check(PyRoom *self, PyObject *args) { PyObject *func = NULL; char *name = NULL; // parse all of the values if (!PyArg_ParseTuple(args, "sO", &name, &func)) { PyErr_Format(PyExc_TypeError, "Could not add new room command check. " "Improper arguments supplied"); return NULL; } // make sure the room exists ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room == NULL) { PyErr_Format(PyExc_StandardError, "Tried to add command check to nonexistent room, %d", self->uid); return NULL; } // get the command CMD_DATA *cmd = nearMapGet(roomGetCmdTable(room), name, FALSE); if(cmd != NULL) cmdAddPyCheck(cmd, func); return Py_BuildValue("O", Py_None); } // // returns whether or not the character is an instance of the prototype PyObject *PyRoom_isinstance(PyRoom *self, PyObject *args) { char *type = NULL; // make sure we're getting passed the right type of data if (!PyArg_ParseTuple(args, "s", &type)) { PyErr_Format(PyExc_TypeError, "isinstance only accepts strings."); return NULL; } // pull out the object and check the type ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room != NULL) return Py_BuildValue("i", roomIsInstance(room, get_fullkey_relative(type, get_script_locale()))); else { PyErr_Format(PyExc_StandardError, "Tried to check instances of nonexistent room, %d.",self->uid); return NULL; } } // // returns the specified piece of auxiliary data from the room // if it is a piece of python auxiliary data. PyObject *PyRoom_get_auxiliary(PyRoom *self, PyObject *args) { char *keyword = NULL; if(!PyArg_ParseTuple(args, "s", &keyword)) { PyErr_Format(PyExc_TypeError, "getAuxiliary() must be supplied with the name that the " "auxiliary data was installed under!"); return NULL; } // make sure we exist ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room == NULL) { PyErr_Format(PyExc_StandardError, "Tried to get auxiliary data for a nonexistant room."); return NULL; } // make sure the auxiliary data exists if(!pyAuxiliaryDataExists(keyword)) { PyErr_Format(PyExc_StandardError, "No auxiliary data named '%s' exists!", keyword); return NULL; } PyObject *data = roomGetAuxiliaryData(room, keyword); if(data == NULL) data = Py_None; PyObject *retval = Py_BuildValue("O", data); // Py_DECREF(data); return retval; } // // Returns TRUE if the room has the given variable set PyObject *PyRoom_hasvar(PyRoom *self, PyObject *arg) { char *var = NULL; if (!PyArg_ParseTuple(arg, "s", &var)) { PyErr_Format(PyExc_TypeError, "Room variables must have string names."); return NULL; } ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room != NULL) return Py_BuildValue("b", roomHasVar(room, var)); PyErr_Format(PyExc_TypeError, "Tried to get a variable value for nonexistant room, %d", self->uid); return NULL; } // // Delete the variable set on the room with the specified name PyObject *PyRoom_deletevar(PyRoom *self, PyObject *arg) { char *var = NULL; if (!PyArg_ParseTuple(arg, "s", &var)) { PyErr_Format(PyExc_TypeError, "Room variables must have string names."); return NULL; } ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room != NULL) { roomDeleteVar(room, var); return Py_BuildValue("i", 1); } PyErr_Format(PyExc_TypeError, "Tried to get a variable value for nonexistant room, %d", self->uid); return NULL; } // // Get the value of a variable stored on the room PyObject *PyRoom_getvar(PyRoom *self, PyObject *arg) { char *var = NULL; if (!PyArg_ParseTuple(arg, "s", &var)) { PyErr_Format(PyExc_TypeError, "Room variables must have string names."); return NULL; } ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room != NULL) { int vartype = roomGetVarType(room, var); if(vartype == DYN_VAR_INT) return Py_BuildValue("i", roomGetInt(room, var)); else if(vartype == DYN_VAR_LONG) return Py_BuildValue("i", roomGetLong(room, var)); else if(vartype == DYN_VAR_DOUBLE) return Py_BuildValue("d", roomGetDouble(room, var)); else return Py_BuildValue("s", roomGetString(room, var)); } else { PyErr_Format(PyExc_TypeError, "Tried to get a variable value for nonexistant room, %d", self->uid); return NULL; } } // // Set the value of a variable assocciated with the character PyObject *PyRoom_setvar(PyRoom *self, PyObject *args) { char *var = NULL; PyObject *val = NULL; if (!PyArg_ParseTuple(args, "sO", &var, &val)) { PyErr_Format(PyExc_TypeError, "Room setvar must be supplied with a var name and integer value."); return NULL; } ROOM_DATA *room = PyRoom_AsRoom((PyObject *)self); if(room != NULL) { if(PyInt_Check(val)) roomSetInt(room, var, (int)PyInt_AsLong(val)); else if(PyFloat_Check(val)) roomSetDouble(room, var, PyFloat_AsDouble(val)); else if(PyString_Check(val)) roomSetString(room, var, PyString_AsString(val)); else { PyErr_Format(PyExc_TypeError, "Tried to store a room_var of invalid type on room %d.", self->uid); return NULL; } return Py_BuildValue("i", 1); } else { PyErr_Format(PyExc_TypeError, "Tried to set a variable value for nonexistant room, %d", self->uid); return NULL; } } //***************************************************************************** // structures to define our methods and classes //***************************************************************************** PyTypeObject PyRoom_Type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "room.Room", /*tp_name*/ sizeof(PyRoom), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PyRoom_dealloc,/*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ (cmpfunc)PyRoom_compare, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)PyRoom_Hash, /*tp_hash */ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ "Python Room object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)PyRoom_init, /* tp_init */ 0, /* tp_alloc */ PyRoom_new, /* tp_new */ }; PyMethodDef room_module_methods[] = { { "get_room", (PyCFunction)PyRoom_get_room, METH_VARARGS, "Takes a room key/locale and returns a pointer to that room." }, {NULL, NULL, 0, NULL} /* Sentinel */ }; //***************************************************************************** // implementation of pyroom.h //***************************************************************************** void PyRoom_addGetSetter(const char *name, void *g, void *s, const char *doc) { // make sure our list of get/setters is created if(pyroom_getsetters == NULL) pyroom_getsetters = newList(); // make the GetSetter def PyGetSetDef *def = calloc(1, sizeof(PyGetSetDef)); def->name = strdup(name); def->get = (getter)g; def->set = (setter)s; def->doc = (doc ? strdup(doc) : NULL); def->closure = NULL; listPut(pyroom_getsetters, def); } void PyRoom_addMethod(const char *name, void *f, int flags, const char *doc) { // make sure our list of methods is created if(pyroom_methods == NULL) pyroom_methods = newList(); // make the Method def PyMethodDef *def = calloc(1, sizeof(PyMethodDef)); def->ml_name = strdup(name); def->ml_meth = (PyCFunction)f; def->ml_flags = flags; def->ml_doc = (doc ? strdup(doc) : NULL); listPut(pyroom_methods, def); } // initialize rooms for use. This must be called AFTER PyMODINIT_FUNC init_PyRoom(void) { PyObject* module = NULL; // add all of the basic getsetters PyRoom_addGetSetter("name", PyRoom_getname, PyRoom_setname, "the room's name"); PyRoom_addGetSetter("desc", PyRoom_getdesc, PyRoom_setdesc, "the room's desc"); PyRoom_addGetSetter("proto", PyRoom_getclass, NULL, "The room's class"); PyRoom_addGetSetter("chars", PyRoom_getchars, NULL, "chars in the room"); PyRoom_addGetSetter("objs", PyRoom_getobjs, NULL, "objects in the room"); PyRoom_addGetSetter("contents",PyRoom_getobjs, NULL, "objects in the room"); PyRoom_addGetSetter("exnames", PyRoom_getexnames, NULL, "the room's exits"); PyRoom_addGetSetter("uid", PyRoom_getuid, NULL, "the room's uid"); PyRoom_addGetSetter("terrain", PyRoom_getterrain, PyRoom_setterrain, "the room's terrain type"); PyRoom_addGetSetter("bits", PyRoom_getbits, PyRoom_setbits, "the room's bits"); // add all of the basic methods PyRoom_addMethod("attach", PyRoom_attach, METH_VARARGS, "attach a new script to the room."); PyRoom_addMethod("detach", PyRoom_detach, METH_VARARGS, "detach a script from the room, by vnum."); PyRoom_addMethod("dig", PyRoom_dig, METH_VARARGS, "digs in direction to the target room. Returns exit."); PyRoom_addMethod("fill", PyRoom_fill, METH_VARARGS, "fills in direction for the room."); PyRoom_addMethod("exit", PyRoom_get_exit, METH_VARARGS, "gets an exit in the room with the given direction name."); PyRoom_addMethod("exdir", PyRoom_get_exit_dir, METH_VARARGS, "returns the direction of the exit."); PyRoom_addMethod("send", PyRoom_send, METH_VARARGS, "send a message to everyone in the room."); PyRoom_addMethod("edesc", PyRoom_edesc, METH_VARARGS, "adds an extra description to the room."); PyRoom_addMethod("add_cmd", PyRoom_add_cmd, METH_VARARGS, "adds a command to the room."); PyRoom_addMethod("add_cmd_check", PyRoom_add_cmd_check, METH_VARARGS, "adds a pre-check to a room command."); PyRoom_addMethod("isinstance", PyRoom_isinstance, METH_VARARGS, "returns whether or not the room inherits from the proto"); PyRoom_addMethod("getAuxiliary", PyRoom_get_auxiliary, METH_VARARGS, "get's the specified piece of aux data from the room"); PyRoom_addMethod("getvar", PyRoom_getvar, METH_VARARGS, "get the value of a special variable the room has."); PyRoom_addMethod("setvar", PyRoom_setvar, METH_VARARGS, "set the value of a special variable the room has."); PyRoom_addMethod("hasvar", PyRoom_hasvar, METH_VARARGS, "return whether or not the room has a given variable."); PyRoom_addMethod("deletevar", PyRoom_deletevar, METH_VARARGS, "delete a variable from the room's variable table."); PyRoom_addMethod("delvar", PyRoom_deletevar, METH_VARARGS, "delete a variable from the room's variable table."); // add in all the getsetters and methods makePyType(&PyRoom_Type, pyroom_getsetters, pyroom_methods); deleteListWith(pyroom_getsetters, free); pyroom_getsetters = NULL; deleteListWith(pyroom_methods, free); pyroom_methods = NULL; // make sure the room class is ready to be made if (PyType_Ready(&PyRoom_Type) < 0) return; // initialize the module module = Py_InitModule3("room", room_module_methods, "The room module, for all MUD room-related stuff."); // make sure the module parsed OK if (module == NULL) return; // add the Room class to the room module PyTypeObject *type = &PyRoom_Type; PyModule_AddObject(module, "Room", (PyObject *)type); Py_INCREF(&PyRoom_Type); } int PyRoom_AsUid(PyObject *room) { return ((PyRoom *)room)->uid; } ROOM_DATA *PyRoom_AsRoom(PyObject *room) { return propertyTableGet(room_table, PyRoom_AsUid(room)); } int PyRoom_Check(PyObject *value) { return PyObject_TypeCheck(value, &PyRoom_Type); } PyObject * newPyRoom(ROOM_DATA *room) { PyRoom *py_room = (PyRoom *)PyRoom_new(&PyRoom_Type, NULL, NULL); py_room->uid = roomGetUID(room); return (PyObject *)py_room; }