diff --git a/dfhack/python/DF_API.cpp b/dfhack/python/DF_API.cpp index 2d864d04d..0f227f55f 100644 --- a/dfhack/python/DF_API.cpp +++ b/dfhack/python/DF_API.cpp @@ -33,6 +33,11 @@ distribution. #include "DF_Position.cpp" #include "DF_Material.cpp" #include "DF_CreatureManager.cpp" +#include "DF_Maps.cpp" +#include "DF_GUI.cpp" +#include "DF_Vegetation.cpp" +#include "DF_Translate.cpp" +#include "DF_Constructions.cpp" using namespace std; using namespace DFHack; @@ -44,6 +49,11 @@ struct DF_API PyObject* position; PyObject* material; PyObject* creature; + PyObject* map; + PyObject* translate; + PyObject* construction; + PyObject* vegetation; + PyObject* gui; DFHack::API* api_Ptr; }; @@ -71,6 +81,11 @@ static int DF_API_init(DF_API* self, PyObject* args, PyObject* kwds) self->position = NULL; self->material = NULL; self->creature = NULL; + self->map = NULL; + self->translate = NULL; + self->construction = NULL; + self->vegetation = NULL; + self->gui = NULL; if(!PyArg_ParseTuple(args, "s", &memFileString)) return -1; @@ -86,22 +101,52 @@ static int DF_API_init(DF_API* self, PyObject* args, PyObject* kwds) static void DF_API_dealloc(DF_API* self) { + PySys_WriteStdout("API dealloc\n"); + if(self != NULL) { - Py_CLEAR(self->mem_info); - Py_CLEAR(self->position); - Py_CLEAR(self->material); - Py_CLEAR(self->creature); + PySys_WriteStdout("creature xdecref\n"); + Py_XDECREF(self->creature); + + PySys_WriteStdout("mem_info xdecref\n"); + Py_XDECREF(self->mem_info); + + PySys_WriteStdout("position xdecref\n"); + Py_XDECREF(self->position); + + PySys_WriteStdout("material xdecref\n"); + Py_XDECREF(self->material); + + PySys_WriteStdout("map xdecref\n"); + Py_XDECREF(self->map); + + PySys_WriteStdout("translate xdecref\n"); + Py_XDECREF(self->translate); + + PySys_WriteStdout("construction xdecref\n"); + Py_XDECREF(self->construction); + + PySys_WriteStdout("vegetation xdecref\n"); + Py_XDECREF(self->vegetation); + + PySys_WriteStdout("gui xdecref\n"); + Py_XDECREF(self->gui); if(self->api_Ptr != NULL) { + PySys_WriteStdout("api_Ptr = %i\n", (int)self->api_Ptr); + delete self->api_Ptr; + PySys_WriteStdout("api_Ptr deleted\n"); + self->api_Ptr = NULL; } self->ob_type->tp_free((PyObject*)self); } + + PySys_WriteStdout("API dealloc done\n"); } // Accessors @@ -256,6 +301,151 @@ static PyObject* DF_API_getCreature(DF_API* self, void* closure) Py_RETURN_NONE; } +static PyObject* DF_API_getMap(DF_API* self, void* closure) +{ + if(self->map != NULL) + return self->map; + + try + { + if(self->api_Ptr != NULL) + { + self->map = PyObject_Call((PyObject*)&DF_Map_type, NULL, NULL); + + if(self->map != NULL) + { + ((DF_Map*)(self->map))->m_Ptr = self->api_Ptr->getMaps(); + + if(((DF_Map*)(self->map))->m_Ptr != NULL) + return self->map; + } + } + } + catch(...) + { + PyErr_SetString(PyExc_ValueError, "Error trying to read map"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_API_getTranslation(DF_API* self, void* closure) +{ + if(self->translate != NULL) + return self->translate; + + try + { + if(self->api_Ptr != NULL) + { + self->translate = PyObject_Call((PyObject*)&DF_Translate_type, NULL, NULL); + + if(self->translate != NULL) + { + ((DF_Translate*)(self->translate))->tran_Ptr = self->api_Ptr->getTranslation(); + + if(((DF_Translate*)(self->translate))->tran_Ptr != NULL) + return self->translate; + } + } + } + catch(...) + { + PyErr_SetString(PyExc_ValueError, "Error trying to read translation"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_API_getConstruction(DF_API* self, void* closure) +{ + if(self->construction != NULL) + return self->construction; + + try + { + if(self->api_Ptr != NULL) + { + self->construction = PyObject_Call((PyObject*)&DF_Construction_type, NULL, NULL); + + if(self->construction != NULL) + { + ((DF_Construction*)(self->construction))->c_Ptr = self->api_Ptr->getConstructions(); + + if(((DF_Construction*)(self->construction))->c_Ptr != NULL) + return self->construction; + } + } + } + catch(...) + { + PyErr_SetString(PyExc_ValueError, "Error trying to read constructions"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_API_getVegetation(DF_API* self, void* closure) +{ + if(self->vegetation != NULL) + return self->vegetation; + + try + { + if(self->api_Ptr != NULL) + { + self->vegetation = PyObject_Call((PyObject*)&DF_Vegetation_type, NULL, NULL); + + if(self->vegetation != NULL) + { + ((DF_Vegetation*)(self->vegetation))->veg_Ptr = self->api_Ptr->getVegetation(); + + if(((DF_Vegetation*)(self->vegetation))->veg_Ptr != NULL) + return self->vegetation; + } + } + } + catch(...) + { + PyErr_SetString(PyExc_ValueError, "Error trying to read vegetation"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_API_getGUI(DF_API* self, void* closure) +{ + if(self->gui != NULL) + return self->gui; + + try + { + if(self->api_Ptr != NULL) + { + self->gui = PyObject_Call((PyObject*)&DF_GUI_type, NULL, NULL); + + if(self->gui != NULL) + { + ((DF_GUI*)(self->gui))->g_Ptr = self->api_Ptr->getGui(); + + if(((DF_GUI*)(self->gui))->g_Ptr != NULL) + return self->gui; + } + } + } + catch(...) + { + PyErr_SetString(PyExc_ValueError, "Error trying to read gui"); + return NULL; + } + + Py_RETURN_NONE; +} + static PyGetSetDef DF_API_getterSetters[] = { {"is_attached", (getter)DF_API_getIsAttached, NULL, "is_attached", NULL}, @@ -264,6 +454,11 @@ static PyGetSetDef DF_API_getterSetters[] = {"position", (getter)DF_API_getPosition, NULL, "position", NULL}, {"materials", (getter)DF_API_getMaterial, NULL, "materials", NULL}, {"creatures", (getter)DF_API_getCreature, NULL, "creatures", NULL}, + {"maps", (getter)DF_API_getMap, NULL, "maps", NULL}, + {"translation", (getter)DF_API_getTranslation, NULL, "translation", NULL}, + {"constructions", (getter)DF_API_getConstruction, NULL, "constructions", NULL}, + {"vegetation", (getter)DF_API_getVegetation, NULL, "vegetation", NULL}, + {"gui", (getter)DF_API_getGUI, NULL, "gui", NULL}, {NULL} // Sentinel }; diff --git a/dfhack/python/DF_Buildings.cpp b/dfhack/python/DF_Buildings.cpp new file mode 100644 index 000000000..1028074f2 --- /dev/null +++ b/dfhack/python/DF_Buildings.cpp @@ -0,0 +1,205 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef __DFBUILDINGS__ +#define __DFBUILDINGS__ + +#include "Python.h" +#include "modules/Buildings.h" +#include "DF_Helpers.cpp" + +using namespace DFHack; + +static PyObject* BuildBuilding(DFHack::t_building& building) +{ + PyObject* t_dict; + PyObject* temp; + + t_dict = PyDict_New(); + + temp = PyInt_FromLong(building.origin); + DICTADD(t_dict, "origin", temp); + + temp = PyInt_FromLong(building.vtable); + DICTADD(t_dict, "vtable", temp); + + temp = PyInt_FromLong(building.type); + DICTADD(t_dict, "type", temp); + + temp = BuildMatglossPair(building.material); + DICTADD(t_dict, "material", temp); + + temp = PyTuple_Pack(2, PyTuple_Pack(2, building.x1, building.y1), PyTuple_Pack(2, building.x2, building.y2)); + DICTADD(t_dict, "bounds", temp); + + return t_dict; +} + +struct DF_Building +{ + PyObject_HEAD + DFHack::Buildings* b_Ptr; +}; + +static PyObject* DF_Building_new(PyTypeObject* type, PyObject* args, PyObject* kwds) +{ + DF_Building* self; + + self = (DF_Building*)type->tp_alloc(type, 0); + + if(self != NULL) + self->b_Ptr = NULL; + + return (PyObject*)self; +} + +static int DF_Building_init(DF_Building* self, PyObject* args, PyObject* kwds) +{ + return 0; +} + +static void DF_Building_dealloc(DF_Building* self) +{ + PySys_WriteStdout("building dealloc\n"); + + if(self != NULL) + { + PySys_WriteStdout("building not NULL\n"); + + if(self->b_Ptr != NULL) + { + PySys_WriteStdout("b_Ptr = %i\n", (int)self->b_Ptr); + + delete self->b_Ptr; + + PySys_WriteStdout("b_Ptr deleted\n"); + + self->b_Ptr = NULL; + } + + self->ob_type->tp_free((PyObject*)self); + } + + PySys_WriteStdout("building dealloc done\n"); +} + +// Type methods + +static PyObject* DF_Building_Start(DF_Building* self, PyObject* args) +{ + uint32_t numBuildings = 0; + + if(self->b_Ptr != NULL) + { + if(self->b_Ptr->Start(numBuildings)) + return PyInt_FromLong(numBuildings); + else + return PyInt_FromLong(-1); + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Building_Finish(DF_Building* self, PyObject* args) +{ + if(self->b_Ptr != NULL) + { + if(self->b_Ptr->Finish()) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Building_Read(DF_Building* self, PyObject* args) +{ + uint32_t index = 0; + t_building building; + + if(self->b_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "I", &index)) + return NULL; + + if(self->b_Ptr->Read(index, building)) + return BuildBuilding(building); + } + + Py_RETURN_NONE; +} + +static PyMethodDef DF_Building_methods[] = +{ + {"Start", (PyCFunction)DF_Building_Start, METH_NOARGS, ""}, + {"Finish", (PyCFunction)DF_Building_Finish, METH_NOARGS, ""}, + {"Read", (PyCFunction)DF_Building_Read, METH_VARARGS, ""}, + {NULL} // Sentinel +}; + +static PyTypeObject DF_Building_type = +{ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "pydfhack.Building", /*tp_name*/ + sizeof(DF_Building), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)DF_Building_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*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*/ + "pydfhack Building objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + DF_Building_methods, /* 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)DF_Building_init, /* tp_init */ + 0, /* tp_alloc */ + DF_Building_new, /* tp_new */ +}; + +#endif \ No newline at end of file diff --git a/dfhack/python/DF_Constructions.cpp b/dfhack/python/DF_Constructions.cpp new file mode 100644 index 000000000..237efb479 --- /dev/null +++ b/dfhack/python/DF_Constructions.cpp @@ -0,0 +1,220 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef __DFCONSTRUCTIONS__ +#define __DFCONSTRUCTIONS__ + +#include "Python.h" +#include "modules/Constructions.h" +#include "DF_Helpers.cpp" + +using namespace DFHack; + +static PyObject* BuildConstruction(DFHack::t_construction& construction) +{ + PyObject* t_dict; + PyObject* temp; + + t_dict = PyDict_New(); + + temp = PyTuple_Pack(3, construction.x, construction.y, construction.z); + DICTADD(t_dict, "position", temp); + + temp = PyInt_FromLong(construction.form); + DICTADD(t_dict, "form", temp); + + temp = PyInt_FromLong(construction.unk_8); + DICTADD(t_dict, "unk_8", temp); + + temp = PyInt_FromLong(construction.mat_type); + DICTADD(t_dict, "mat_type", temp); + + temp = PyInt_FromLong(construction.mat_idx); + DICTADD(t_dict, "mat_idx", temp); + + temp = PyInt_FromLong(construction.unk3); + DICTADD(t_dict, "unk3", temp); + + temp = PyInt_FromLong(construction.unk4); + DICTADD(t_dict, "unk4", temp); + + temp = PyInt_FromLong(construction.unk5); + DICTADD(t_dict, "unk5", temp); + + temp = PyInt_FromLong(construction.unk6); + DICTADD(t_dict, "unk6", temp); + + temp = PyInt_FromLong(construction.origin); + DICTADD(t_dict, "origin", temp); + + return t_dict; +} + +struct DF_Construction +{ + PyObject_HEAD + DFHack::Constructions* c_Ptr; +}; + +static PyObject* DF_Construction_new(PyTypeObject* type, PyObject* args, PyObject* kwds) +{ + DF_Construction* self; + + self = (DF_Construction*)type->tp_alloc(type, 0); + + if(self != NULL) + self->c_Ptr = NULL; + + return (PyObject*)self; +} + +static int DF_Construction_init(DF_Construction* self, PyObject* args, PyObject* kwds) +{ + return 0; +} + +static void DF_Construction_dealloc(DF_Construction* self) +{ + PySys_WriteStdout("construction dealloc\n"); + + if(self != NULL) + { + PySys_WriteStdout("construction not NULL\n"); + + if(self->c_Ptr != NULL) + { + PySys_WriteStdout("c_Ptr = %i\n", (int)self->c_Ptr); + + delete self->c_Ptr; + + PySys_WriteStdout("c_Ptr deleted\n"); + + self->c_Ptr = NULL; + } + + self->ob_type->tp_free((PyObject*)self); + } + + PySys_WriteStdout("construction dealloc done\n"); +} + +// Type methods + +static PyObject* DF_Construction_Start(DF_Construction* self, PyObject* args) +{ + uint32_t numConstructions = 0; + + if(self->c_Ptr != NULL) + { + if(self->c_Ptr->Start(numConstructions)) + return PyInt_FromLong(numConstructions); + else + return PyInt_FromLong(-1); + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Construction_Finish(DF_Construction* self, PyObject* args) +{ + if(self->c_Ptr != NULL) + { + if(self->c_Ptr->Finish()) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Construction_Read(DF_Construction* self, PyObject* args) +{ + uint32_t index = 0; + t_construction construction; + + if(self->c_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "I", &index)) + return NULL; + + if(self->c_Ptr->Read(index, construction)) + return BuildConstruction(construction); + } + + Py_RETURN_NONE; +} + +static PyMethodDef DF_Construction_methods[] = +{ + {"Start", (PyCFunction)DF_Construction_Start, METH_NOARGS, ""}, + {"Finish", (PyCFunction)DF_Construction_Finish, METH_NOARGS, ""}, + {"Read", (PyCFunction)DF_Construction_Read, METH_VARARGS, ""}, + {NULL} // Sentinel +}; + +static PyTypeObject DF_Construction_type = +{ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "pydfhack.Construction", /*tp_name*/ + sizeof(DF_Construction), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)DF_Construction_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*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*/ + "pydfhack Construction objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + DF_Construction_methods, /* 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)DF_Construction_init, /* tp_init */ + 0, /* tp_alloc */ + DF_Construction_new, /* tp_new */ +}; + +#endif \ No newline at end of file diff --git a/dfhack/python/DF_CreatureManager.cpp b/dfhack/python/DF_CreatureManager.cpp index 9a1d229f2..43e08f230 100644 --- a/dfhack/python/DF_CreatureManager.cpp +++ b/dfhack/python/DF_CreatureManager.cpp @@ -59,17 +59,27 @@ static int DF_CreatureManager_init(DF_CreatureManager* self, PyObject* args, PyO static void DF_CreatureManager_dealloc(DF_CreatureManager* self) { + PySys_WriteStdout("creature manager dealloc\n"); + if(self != NULL) - { + { + PySys_WriteStdout("creature manager not NULL\n"); + if(self->creature_Ptr != NULL) { + PySys_WriteStdout("creature_Ptr = %i\n", (int)self->creature_Ptr); + delete self->creature_Ptr; + PySys_WriteStdout("creature_Ptr deleted\n"); + self->creature_Ptr = NULL; } self->ob_type->tp_free((PyObject*)self); } + + PySys_WriteStdout("creature manager dealloc done\n"); } // Type methods diff --git a/dfhack/python/DF_CreatureType.cpp b/dfhack/python/DF_CreatureType.cpp index 7eae9569e..99a4e081a 100644 --- a/dfhack/python/DF_CreatureType.cpp +++ b/dfhack/python/DF_CreatureType.cpp @@ -27,7 +27,7 @@ distribution. #include "Python.h" #include "structmember.h" -#include "DF_Imports.cpp" +//#include "DF_Imports.cpp" #include "DF_Helpers.cpp" #include "modules/Creatures.h" @@ -39,35 +39,26 @@ struct DF_Creature_Base // simple type stuff uint32_t origin; - uint32_t c_type; + uint32_t race; uint8_t profession; uint16_t mood; uint32_t happiness; uint32_t c_id; - uint32_t agility; - uint32_t strength; - uint32_t toughness; - uint32_t money; int32_t squad_leader_id; uint8_t sex; uint32_t pregnancy_timer; - int32_t blood_max, blood_current; - uint32_t bleed_rate; + uint32_t flags1, flags2; PyObject* custom_profession; // composites PyObject* position; - PyObject *name, *squad_name, *artifact_name; + PyObject *name, *artifact_name; PyObject* current_job; - - // customs - PyObject *flags1, *flags2; + PyObject *strength, *agility, *toughness, *endurance, *recuperation, *disease_resistance; + PyObject* defaultSoul; // lists - PyObject* skill_list; - PyObject* like_list; - PyObject* trait_list; PyObject* labor_list; }; @@ -82,66 +73,63 @@ static PyObject* DF_Creature_Base_new(PyTypeObject* type, PyObject* args, PyObje if(self != NULL) { self->origin = 0; - self->c_type = 0; self->profession = 0; self->mood = 0; self->happiness = 0; self->c_id = 0; - self->agility = 0; - self->strength = 0; - self->toughness = 0; - self->money = 0; self->squad_leader_id = 0; self->sex = 0; self->pregnancy_timer = 0; - self->blood_max = 0; - self->blood_current = 0; - self->bleed_rate = 0; + self->flags1 = 0; + self->flags2 = 0; self->custom_profession = PyString_FromString(""); self->name = PyString_FromString(""); - self->squad_name = PyString_FromString(""); self->artifact_name = PyString_FromString(""); - self->skill_list = NULL; - self->like_list = NULL; - self->trait_list = NULL; + self->position = NULL; + + self->strength = NULL; + self->agility = NULL; + self->toughness = NULL; + self->endurance = NULL; + self->recuperation = NULL; + self->disease_resistance = NULL; + + self->defaultSoul = NULL; + self->labor_list = NULL; } return (PyObject*)self; } +static int DF_Creature_Base_init(DF_Creature_Base* self, PyObject* args, PyObject* kwd) +{ + return 0; +} + static void DF_Creature_Base_dealloc(DF_Creature_Base* self) { if(self != NULL) { Py_XDECREF(self->position); - Py_XDECREF(self->flags1); - Py_XDECREF(self->flags2); Py_XDECREF(self->custom_profession); Py_XDECREF(self->name); - Py_XDECREF(self->squad_name); Py_XDECREF(self->artifact_name); Py_XDECREF(self->current_job); - Py_XDECREF(self->flags1); - Py_XDECREF(self->flags2); + Py_XDECREF(self->strength); + Py_XDECREF(self->agility); + Py_XDECREF(self->toughness); + Py_XDECREF(self->endurance); + Py_XDECREF(self->recuperation); + Py_XDECREF(self->disease_resistance); - Py_XDECREF(self->labor_list); - Py_XDECREF(self->trait_list); - Py_XDECREF(self->skill_list); - Py_XDECREF(self->like_list); + Py_XDECREF(self->defaultSoul); - // if(self->labor_list != NULL) - // PyList_Clear(self->labor_list); - // if(self->trait_list != NULL) - // PyList_Clear(self->trait_list); - // if(self->skill_list != NULL) - // PyList_Clear(self->skill_list); - // if(self->like_list != NULL) - // PyList_Clear(self->like_list); + Py_XDECREF(self->labor_list); self->ob_type->tp_free((PyObject*)self); } @@ -150,15 +138,19 @@ static void DF_Creature_Base_dealloc(DF_Creature_Base* self) static PyMemberDef DF_Creature_Base_members[] = { {"origin", T_UINT, offsetof(DF_Creature_Base, origin), 0, ""}, - {"type", T_UINT, offsetof(DF_Creature_Base, c_type), 0, ""}, - {"flags1", T_OBJECT_EX, offsetof(DF_Creature_Base, flags1), 0, ""}, - {"flags2", T_OBJECT_EX, offsetof(DF_Creature_Base, flags2), 0, ""}, + {"position", T_OBJECT_EX, offsetof(DF_Creature_Base, position), 0, ""}, + {"_flags1", T_UINT, offsetof(DF_Creature_Base, flags1), 0, ""}, + {"_flags2", T_UINT, offsetof(DF_Creature_Base, flags2), 0, ""}, + {"race", T_UINT, offsetof(DF_Creature_Base, race), 0, ""}, {"name", T_OBJECT_EX, offsetof(DF_Creature_Base, name), 0, ""}, - {"squad_name", T_OBJECT_EX, offsetof(DF_Creature_Base, squad_name), 0, ""}, {"artifact_name", T_OBJECT_EX, offsetof(DF_Creature_Base, artifact_name), 0, ""}, {"profession", T_INT, offsetof(DF_Creature_Base, profession), 0, ""}, {"custom_profession", T_OBJECT_EX, offsetof(DF_Creature_Base, custom_profession), 0, ""}, {"happiness", T_SHORT, offsetof(DF_Creature_Base, happiness), 0, ""}, + {"mood", T_SHORT, offsetof(DF_Creature_Base, mood), 0, ""}, + {"squad_leader_id", T_INT, offsetof(DF_Creature_Base, squad_leader_id), 0, ""}, + {"sex", T_UBYTE, offsetof(DF_Creature_Base, sex), 0, ""}, + {"pregnancy_timer", T_UINT, offsetof(DF_Creature_Base, pregnancy_timer), 0, ""}, {NULL} //Sentinel }; @@ -210,7 +202,7 @@ static PyTypeObject DF_Creature_Base_type = 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - 0, /* tp_init */ + (initproc)DF_Creature_Base_init, /* tp_init */ 0, /* tp_alloc */ DF_Creature_Base_new, /* tp_new */ }; @@ -223,56 +215,38 @@ static PyObject* BuildCreature(DFHack::t_creature& creature) if(obj != NULL) { + obj->origin = creature.origin; obj->position = Py_BuildValue("III", creature.x, creature.y, creature.z); obj->profession = creature.profession; - obj->c_type = creature.type; obj->mood = creature.mood; obj->happiness = creature.happiness; obj->c_id = creature.id; - obj->agility = creature.agility; - obj->strength = creature.strength; - obj->toughness = creature.toughness; - obj->money = creature.money; + obj->race = creature.race; + obj->agility = BuildAttribute(creature.agility); + obj->strength = BuildAttribute(creature.strength); + obj->toughness = BuildAttribute(creature.toughness); + obj->endurance = BuildAttribute(creature.endurance); + obj->recuperation = BuildAttribute(creature.recuperation); + obj->disease_resistance = BuildAttribute(creature.disease_resistance); obj->squad_leader_id = creature.squad_leader_id; obj->sex = creature.sex; obj->pregnancy_timer = creature.pregnancy_timer; - obj->blood_max = creature.blood_max; - obj->blood_current = creature.blood_current; - obj->bleed_rate = creature.bleed_rate; if(creature.custom_profession[0]) obj->custom_profession = PyString_FromString(creature.custom_profession); - obj->flags1 = PyObject_Call(CreatureFlags1_type, PyInt_FromLong(creature.flags1.whole), NULL); - obj->flags2 = PyObject_Call(CreatureFlags2_type, PyInt_FromLong(creature.flags2.whole), NULL); + obj->flags1 = creature.flags1.whole; + obj->flags2 = creature.flags2.whole; obj->current_job = BuildJob(creature.current_job); obj->name = BuildName(creature.name); - obj->squad_name = BuildName(creature.squad_name); obj->artifact_name = BuildName(creature.artifact_name); - obj->skill_list = PyList_New(creature.numSkills); - - for(int i = 0; i < creature.numSkills; i++) - PyList_SetItem(obj->skill_list, i, BuildSkill(creature.skills[i])); - - obj->like_list = PyList_New(creature.numLikes); - - for(int i = 0; i < creature.numLikes; i++) - PyList_SetItem(obj->like_list, i, BuildLike(creature.likes[i])); - obj->labor_list = PyList_New(NUM_CREATURE_LABORS); for(int i = 0; i < NUM_CREATURE_LABORS; i++) - PyList_SetItem(obj->labor_list, i, PyInt_FromLong(creature.labors[i])); - - obj->trait_list = PyList_New(NUM_CREATURE_TRAITS); + PyList_SET_ITEM(obj->labor_list, i, PyInt_FromLong(creature.labors[i])); - for(int i = 0; i < NUM_CREATURE_TRAITS; i++) - PyList_SetItem(obj->trait_list, i, PyInt_FromLong(creature.traits[i])); - - Py_INCREF((PyObject*)obj); - return (PyObject*)obj; } diff --git a/dfhack/python/DF_Creatures.cpp b/dfhack/python/DF_Creatures.cpp deleted file mode 100644 index 0960b1722..000000000 --- a/dfhack/python/DF_Creatures.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#ifndef __DFCREATURES__ -#define __DFCREATURES__ - -#include "Python.h" -#include "DFTypes.h" -#include "DF_CreatureType.cpp" - -#endif \ No newline at end of file diff --git a/dfhack/python/DF_GUI.cpp b/dfhack/python/DF_GUI.cpp new file mode 100644 index 000000000..015d115b9 --- /dev/null +++ b/dfhack/python/DF_GUI.cpp @@ -0,0 +1,205 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef __DFGUI__ +#define __DFGUI__ + +#include "Python.h" +#include "modules/Gui.h" + +using namespace DFHack; + +struct DF_GUI +{ + PyObject_HEAD + DFHack::Gui* g_Ptr; +}; + +static PyObject* DF_GUI_new(PyTypeObject* type, PyObject* args, PyObject* kwds) +{ + DF_GUI* self; + + self = (DF_GUI*)type->tp_alloc(type, 0); + + if(self != NULL) + self->g_Ptr = NULL; + + return (PyObject*)self; +} + +static int DF_GUI_init(DF_GUI* self, PyObject* args, PyObject* kwds) +{ + return 0; +} + +static void DF_GUI_dealloc(DF_GUI* self) +{ + PySys_WriteStdout("gui dealloc\n"); + + if(self != NULL) + { + PySys_WriteStdout("gui not NULL\n"); + + if(self->g_Ptr != NULL) + { + PySys_WriteStdout("g_Ptr = %i\n", (int)self->g_Ptr); + + delete self->g_Ptr; + + PySys_WriteStdout("g_Ptr deleted\n"); + + self->g_Ptr = NULL; + } + + self->ob_type->tp_free((PyObject*)self); + } + + PySys_WriteStdout("gui dealloc done\n"); +} + +// Type methods + +static PyObject* DF_GUI_Start(DF_GUI* self, PyObject* args) +{ + if(self->g_Ptr != NULL) + { + if(self->g_Ptr->Start()) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_GUI_Finish(DF_GUI* self, PyObject* args) +{ + if(self->g_Ptr != NULL) + { + if(self->g_Ptr->Finish()) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_GUI_ReadViewScreen(DF_GUI* self, PyObject* args) +{ + DFHack::t_viewscreen viewscreen; + + if(self->g_Ptr != NULL) + { + if(self->g_Ptr->ReadViewScreen(viewscreen)) + return PyInt_FromLong(viewscreen.type); + } + + Py_RETURN_NONE; +} + +static PyMethodDef DF_GUI_methods[] = +{ + {"Start", (PyCFunction)DF_GUI_Start, METH_NOARGS, ""}, + {"Finish", (PyCFunction)DF_GUI_Finish, METH_NOARGS, ""}, + {"Read_View_Screen", (PyCFunction)DF_GUI_ReadViewScreen, METH_NOARGS, ""}, + {NULL} //Sentinel +}; + +// Getter/Setter + +static PyObject* DF_GUI_getPauseState(DF_GUI* self, void* closure) +{ + if(self->g_Ptr != NULL) + { + if(self->g_Ptr->ReadPauseState()) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_GUI_getMenuState(DF_GUI* self, void* closure) +{ + if(self->g_Ptr != NULL) + { + return PyInt_FromLong(self->g_Ptr->ReadMenuState()); + } + + Py_RETURN_NONE; +} + +static PyGetSetDef DF_GUI_getterSetters[] = +{ + {"paused", (getter)DF_GUI_getPauseState, NULL, "paused", NULL}, + {"menu_state", (getter)DF_GUI_getMenuState, NULL, "menu_state", NULL}, + {NULL} // Sentinel +}; + +static PyTypeObject DF_GUI_type = +{ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "pydfhack.GUI", /*tp_name*/ + sizeof(DF_GUI), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)DF_GUI_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*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*/ + "pydfhack GUI objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + DF_GUI_methods, /* tp_methods */ + 0, /* tp_members */ + DF_GUI_getterSetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)DF_GUI_init, /* tp_init */ + 0, /* tp_alloc */ + DF_GUI_new, /* tp_new */ +}; + +#endif \ No newline at end of file diff --git a/dfhack/python/DF_Helpers.cpp b/dfhack/python/DF_Helpers.cpp index 82890a4d8..9dce8c737 100644 --- a/dfhack/python/DF_Helpers.cpp +++ b/dfhack/python/DF_Helpers.cpp @@ -26,33 +26,48 @@ distribution. #define __DFHELPERS__ #include "Python.h" -#include "DF_Imports.cpp" +#include +#include #include "DFTypes.h" +#include "DF_Imports.cpp" using namespace DFHack; #include "modules/Creatures.h" +#define DICTADD(d, name, item) PyDict_SetItemString(d, name, item); Py_DECREF(item) +#define OBJSET(o, name, item) PyObject_SetAttrString(o, name, item); Py_DECREF(item) + static PyObject* BuildMatglossPair(DFHack::t_matglossPair& matgloss) { return Py_BuildValue("ii", matgloss.type, matgloss.index); } -// static PyObject* BuildTreeDesc(DFHack::t_tree_desc& tree) -// { - // return Py_BuildValue("OO", BuildMatglossPair(tree.material), Py_BuildValue("III", tree.x, tree.y, tree.z)); -// } - static PyObject* BuildSkill(DFHack::t_skill& skill) { return Py_BuildValue("III", skill.id, skill.experience, skill.rating); } +static PyObject* BuildSkillList(DFHack::t_skill (&skills)[256], uint8_t numSkills) +{ + PyObject* list = PyList_New(numSkills); + + for(int i = 0; i < numSkills; i++) + PyList_SET_ITEM(list, i, BuildSkill(skills[i])); + + return list; +} + static PyObject* BuildJob(DFHack::t_job& job) { return Py_BuildValue("Oi", PyBool_FromLong((int)job.active), job.jobId); } +static PyObject* BuildAttribute(DFHack::t_attrib& at) +{ + return Py_BuildValue("IIIIIII", at.level, at.field_4, at.field_8, at.field_C, at.leveldiff, at.field_14, at.field_18); +} + static PyObject* BuildItemType(DFHack::t_itemType& item) { PyObject *id, *name; @@ -79,98 +94,143 @@ static PyObject* BuildLike(DFHack::t_like& like) return Py_BuildValue("OOO", item, BuildMatglossPair(like.material), PyBool_FromLong((int)like.active)); } -//PyDict_SetItem and PyDict_SetItemString don't steal references, so this had to get a bit more complicated... static PyObject* BuildNote(DFHack::t_note& note) { - PyObject* noteDict = PyDict_New(); - PyObject* temp; - - temp = PyString_FromFormat("%c", note.symbol); - - PyDict_SetItemString(noteDict, "symbol", temp); - - Py_DECREF(temp); - - temp = Py_BuildValue("II", note.foreground, note.background); - - PyDict_SetItemString(noteDict, "fore_back", temp); - - Py_DECREF(temp); + PyObject* noteObj; + PyObject *args, *name, *position; if(note.name[0]) - temp = PyString_FromString(note.name); + name = PyString_FromString(note.name); else - PyString_FromString(""); - - PyDict_SetItemString(noteDict, "name", temp); + name = PyString_FromString(""); - Py_DECREF(temp); + position = Py_BuildValue("III", note.x, note.y, note.z); - temp = Py_BuildValue("III", note.x, note.y, note.z); - - PyDict_SetItemString(noteDict, "position", temp); + args = Py_BuildValue("cIIsO", note.symbol, note.foreground, note.background, name, position); - Py_DECREF(temp); + noteObj = PyObject_CallObject(Note_type, args); - return noteDict; + return noteObj; } -//same here...reference counting is kind of a pain, assuming I'm even doing it right... static PyObject* BuildName(DFHack::t_name& name) { - PyObject* nameDict; + PyObject* nameObj; PyObject *wordList, *speechList; PyObject* temp; int wordCount = 7; - nameDict = PyDict_New(); + nameObj = PyObject_CallObject(Name_type, NULL); if(name.first_name[0]) temp = PyString_FromString(name.first_name); else temp = PyString_FromString(""); - - PyDict_SetItemString(nameDict, "first_name", temp); - Py_DECREF(temp); + OBJSET(nameObj, "first_name", temp); if(name.nickname[0]) temp = PyString_FromString(name.nickname); else temp = PyString_FromString(""); - - PyDict_SetItemString(nameDict, "nickname", temp); - Py_DECREF(temp); + OBJSET(nameObj, "nickname", temp); temp = PyInt_FromLong(name.language); - - PyDict_SetItemString(nameDict, "language", temp); - - Py_DECREF(temp); + OBJSET(nameObj, "language", temp); temp = PyBool_FromLong((int)name.has_name); - - PyDict_SetItemString(nameDict, "has_name", temp); - - Py_DECREF(temp); + OBJSET(nameObj, "has_name", temp); wordList = PyList_New(wordCount); speechList = PyList_New(wordCount); for(int i = 0; i < wordCount; i++) { - PyList_SetItem(wordList, i, PyInt_FromLong(name.words[i])); - PyList_SetItem(wordList, i, PyInt_FromLong(name.parts_of_speech[i])); + PyList_SET_ITEM(wordList, i, PyInt_FromLong(name.words[i])); + PyList_SET_ITEM(speechList, i, PyInt_FromLong(name.parts_of_speech[i])); + } + + OBJSET(nameObj, "words", wordList); + OBJSET(nameObj, "parts_of_speech", speechList); + + return nameObj; +} + +static DFHack::t_name ReverseBuildName(PyObject* nameObj) +{ + PyObject *temp, *listTemp; + int boolTemp, arrLength; + Py_ssize_t listLength, strLength; + char* strTemp; + DFHack::t_name name; + + temp = PyObject_GetAttrString(nameObj, "language"); + name.language = (uint32_t)PyInt_AsLong(temp); + + temp = PyObject_GetAttrString(nameObj, "has_name"); + + boolTemp = (int)PyInt_AsLong(temp); + + if(boolTemp != 0) + name.has_name = true; + else + name.has_name = false; + + //I seriously doubt the name arrays will change length, but why take chances? + listTemp = PyObject_GetAttrString(nameObj, "words"); + + arrLength = sizeof(name.words) / sizeof(uint32_t); + listLength = PyList_Size(listTemp); + + if(listLength < arrLength) + arrLength = listLength; + + for(int i = 0; i < arrLength; i++) + name.words[i] = (uint32_t)PyInt_AsLong(PyList_GetItem(listTemp, i)); + + listTemp = PyObject_GetAttrString(nameObj, "parts_of_speech"); + + arrLength = sizeof(name.parts_of_speech) / sizeof(uint16_t); + listLength = PyList_Size(listTemp); + + if(listLength < arrLength) + arrLength = listLength; + + for(int i = 0; i < arrLength; i++) + name.parts_of_speech[i] = (uint16_t)PyInt_AsLong(PyList_GetItem(listTemp, i)); + + temp = PyObject_GetAttrString(nameObj, "first_name"); + strLength = PyString_Size(temp); + strTemp = PyString_AsString(temp); + + if(strLength > 128) + { + strncpy(name.first_name, strTemp, 127); + name.first_name[127] = '\0'; + } + else + { + strncpy(name.first_name, strTemp, strLength); + name.first_name[strLength] = '\0'; } - PyDict_SetItemString(nameDict, "words", wordList); - PyDict_SetItemString(nameDict, "parts_of_speech", speechList); + temp = PyObject_GetAttrString(nameObj, "nickname"); + strLength = PyString_Size(temp); + strTemp = PyString_AsString(temp); - Py_DECREF(wordList); - Py_DECREF(speechList); + if(strLength > 128) + { + strncpy(name.nickname, strTemp, 127); + name.nickname[127] = '\0'; + } + else + { + strncpy(name.nickname, strTemp, strLength); + name.nickname[strLength] = '\0'; + } - return nameDict; + return name; } static PyObject* BuildSettlement(DFHack::t_settlement& settlement) @@ -182,32 +242,72 @@ static PyObject* BuildSettlement(DFHack::t_settlement& settlement) setDict = PyDict_New(); temp = PyInt_FromLong(settlement.origin); + DICTADD(setDict, "origin", temp); + + temp = BuildName(settlement.name); + DICTADD(setDict, "name", temp); - PyDict_SetItemString(setDict, "origin", temp); + temp = Py_BuildValue("ii", settlement.world_x, settlement.world_y); + DICTADD(setDict, "world_pos", temp); - Py_DECREF(temp); + local_pos1 = Py_BuildValue("ii", settlement.local_x1, settlement.local_y1); + local_pos2 = Py_BuildValue("ii", settlement.local_x2, settlement.local_y2); - temp = BuildName(settlement.name); + temp = Py_BuildValue("OO", local_pos1, local_pos2); + DICTADD(setDict, "local_pos", temp); - PyDict_SetItemString(setDict, "name", temp); + return setDict; +} + +static PyObject* BuildSoul(DFHack::t_soul& soul) +{ + PyObject *soulDict, *skillList, *temp; - Py_DECREF(temp); + soulDict = PyDict_New(); - temp = Py_BuildValue("ii", settlement.world_x, settlement.world_y); + skillList = BuildSkillList(soul.skills, soul.numSkills); + DICTADD(soulDict, "skills", skillList); - PyDict_SetItemString(setDict, "world_pos", temp); + temp = BuildAttribute(soul.analytical_ability); + DICTADD(soulDict, "analytical_ability", temp); - Py_DECREF(temp); + temp = BuildAttribute(soul.focus); + DICTADD(soulDict, "focus", temp); - local_pos1 = Py_BuildValue("ii", settlement.local_x1, settlement.local_y1); - local_pos2 = Py_BuildValue("ii", settlement.local_x2, settlement.local_y2); + temp = BuildAttribute(soul.willpower); + DICTADD(soulDict, "willpower", temp); - PyDict_SetItemString(setDict, "local_pos", Py_BuildValue("OO", local_pos1, local_pos2)); + temp = BuildAttribute(soul.creativity); + DICTADD(soulDict, "creativity", temp); - Py_DECREF(local_pos1); - Py_DECREF(local_pos2); + temp = BuildAttribute(soul.intuition); + DICTADD(soulDict, "intuition", temp); - return setDict; + temp = BuildAttribute(soul.patience); + DICTADD(soulDict, "patience", temp); + + temp = BuildAttribute(soul.memory); + DICTADD(soulDict, "memory", temp); + + temp = BuildAttribute(soul.linguistic_ability); + DICTADD(soulDict, "linguistic_ability", temp); + + temp = BuildAttribute(soul.spatial_sense); + DICTADD(soulDict, "spatial_sense", temp); + + temp = BuildAttribute(soul.musicality); + DICTADD(soulDict, "musicality", temp); + + temp = BuildAttribute(soul.kinesthetic_sense); + DICTADD(soulDict, "kinesthetic_sense", temp); + + temp = BuildAttribute(soul.empathy); + DICTADD(soulDict, "empathy", temp); + + temp = BuildAttribute(soul.social_awareness); + DICTADD(soulDict, "social_awareness", temp); + + return soulDict; } #endif \ No newline at end of file diff --git a/dfhack/python/DF_Imports.cpp b/dfhack/python/DF_Imports.cpp index 300731e4f..15e93d2b3 100644 --- a/dfhack/python/DF_Imports.cpp +++ b/dfhack/python/DF_Imports.cpp @@ -27,24 +27,45 @@ distribution. #include "Python.h" -static PyObject* TypesModule = NULL; +static PyObject* FlagsModule = NULL; static PyObject* CreatureFlags1_type = NULL; static PyObject* CreatureFlags2_type = NULL; static PyObject* DesignationFlags_type = NULL; static PyObject* OccupancyFlags_type = NULL; static PyObject* ItemFlags_type = NULL; +static PyObject* BlockFlags_type = NULL; + +static PyObject* TypesModule = NULL; +static PyObject* Note_type = NULL; +static PyObject* Construction_type = NULL; +static PyObject* Name_type = NULL; +static PyObject* MapBlock40d_type = NULL; +static PyObject* Vein_type = NULL; +static PyObject* FrozenLiquidVein_type = NULL; +static PyObject* SpatterVein_type = NULL; static void DoImports() { if(TypesModule == NULL) { - TypesModule = PyImport_ImportModule("pydftypes"); + FlagsModule = PyImport_ImportModule("pydfhackflags"); + + CreatureFlags1_type = PyObject_GetAttrString(FlagsModule, "CreatureFlags1"); + CreatureFlags2_type = PyObject_GetAttrString(FlagsModule, "CreatureFlags2"); + DesignationFlags_type = PyObject_GetAttrString(FlagsModule, "DesignationFlags"); + OccupancyFlags_type = PyObject_GetAttrString(FlagsModule, "OccupancyFlags"); + ItemFlags_type = PyObject_GetAttrString(FlagsModule, "ItemFlags"); + BlockFlags_type = PyObject_GetAttrString(FlagsModule, "BlockFlags"); - CreatureFlags1_type = PyObject_GetAttrString(TypesModule, "CreatureFlags1"); - CreatureFlags2_type = PyObject_GetAttrString(TypesModule, "CreatureFlags2"); - DesignationFlags_type = PyObject_GetAttrString(TypesModule, "DesignationFlags"); - OccupancyFlags_type = PyObject_GetAttrString(TypesModule, "OccupancyFlags"); - ItemFlags_type = PyObject_GetAttrString(TypesModule, "ItemFlags"); + TypesModule = PyImport_ImportModule("pydftypes"); + + Note_type = PyObject_GetAttrString(TypesModule, "Note"); + Construction_type = PyObject_GetAttrString(TypesModule, "Construction"); + Name_type = PyObject_GetAttrString(TypesModule, "Name"); + MapBlock40d_type = PyObject_GetAttrString(TypesModule, "MapBlock40d"); + Vein_type = PyObject_GetAttrString(TypesModule, "Vein"); + FrozenLiquidVein_type = PyObject_GetAttrString(TypesModule, "FrozenLiquidVein"); + SpatterVein_type = PyObject_GetAttrString(TypesModule, "SpatterVein"); } } diff --git a/dfhack/python/DF_Maps.cpp b/dfhack/python/DF_Maps.cpp new file mode 100644 index 000000000..788130444 --- /dev/null +++ b/dfhack/python/DF_Maps.cpp @@ -0,0 +1,859 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef __DFMAPS__ +#define __DFMAPS__ + +#include "Python.h" +#include +#include + +using namespace std; + +#include "modules/Maps.h" +#include "DF_Imports.cpp" +#include "DF_Helpers.cpp" + +using namespace DFHack; + +static PyObject* BuildVein(DFHack::t_vein& v) +{ + PyObject* vObj; + PyObject* temp; + + vObj = PyObject_Call(Vein_type, NULL, NULL); + + temp = PyInt_FromLong(v.vtable); + OBJSET(vObj, "vtable", temp); + + temp = PyInt_FromLong(v.type); + OBJSET(vObj, "type", temp); + + temp = PyInt_FromLong(v.flags); + OBJSET(vObj, "flags", temp); + + temp = PyInt_FromLong(v.address_of); + OBJSET(vObj, "address", temp); + + temp = PyList_New(16); + + for(int i = 0; i < 16; i++) + PyList_SET_ITEM(temp, i, PyInt_FromLong(v.assignment[i])); + + OBJSET(vObj, "assignment", temp); + + return vObj; +} + +static PyObject* BuildFrozenLiquidVein(DFHack::t_frozenliquidvein& v) +{ + PyObject* vObj; + PyObject *temp, *list; + + vObj = PyObject_Call(FrozenLiquidVein_type, NULL, NULL); + + temp = PyInt_FromLong(v.vtable); + OBJSET(vObj, "vtable", temp); + + temp = PyInt_FromLong(v.address_of); + OBJSET(vObj, "address", temp); + + list = PyList_New(16); + + for(int i = 0; i < 16; i++) + { + temp = PyList_New(16); + + for(int j = 0; j < 16; j++) + PyList_SET_ITEM(temp, j, PyInt_FromLong(v.tiles[i][j])); + + PyList_SET_ITEM(list, i, temp); + } + + OBJSET(vObj, "tiles", list); + + return vObj; +} + +static PyObject* BuildSpatterVein(DFHack::t_spattervein& v) +{ + PyObject* vObj; + PyObject *temp, *list; + + vObj = PyObject_Call(SpatterVein_type, NULL, NULL); + + temp = PyInt_FromLong(v.vtable); + OBJSET(vObj, "vtable", temp); + + temp = PyInt_FromLong(v.address_of); + OBJSET(vObj, "address", temp); + + temp = PyInt_FromLong(v.mat1); + OBJSET(vObj, "mat1", temp); + + temp = PyInt_FromLong(v.unk1); + OBJSET(vObj, "unk1", temp); + + temp = PyInt_FromLong(v.mat2); + OBJSET(vObj, "mat2", temp); + + temp = PyInt_FromLong(v.mat3); + OBJSET(vObj, "mat3", temp); + + list = PyList_New(16); + + for(int i = 0; i < 16; i++) + { + temp = PyList_New(16); + + for(int j = 0; j < 16; j++) + PyList_SET_ITEM(temp, j, PyInt_FromLong(v.intensity[i][j])); + + PyList_SET_ITEM(list, i, temp); + } + + OBJSET(vObj, "intensity", list); + + return vObj; +} + +static PyObject* BuildVeinDict(std::vector& veins, std::vector& ices, std::vector& splatter) +{ + PyObject* vDict; + PyObject* vList; + int veinSize; + + vDict = PyDict_New(); + + veinSize = veins.size(); + + if(veinSize <= 0) + { + Py_INCREF(Py_None); + DICTADD(vDict, "veins", Py_None); + } + else + { + vList = PyList_New(veinSize); + + for(int i = 0; i < veinSize; i++) + PyList_SET_ITEM(vList, i, BuildVein(veins[i])); + + DICTADD(vDict, "veins", vList); + } + + veinSize = ices.size(); + + if(veinSize <= 0) + { + Py_INCREF(Py_None); + DICTADD(vDict, "ices", Py_None); + } + else + { + vList = PyList_New(veinSize); + + for(int i = 0; i < veinSize; i++) + PyList_SET_ITEM(vList, i, BuildFrozenLiquidVein(ices[i])); + + DICTADD(vDict, "ices", vList); + } + + veinSize = splatter.size(); + + if(veinSize <= 0) + { + Py_INCREF(Py_None); + DICTADD(vDict, "spatter", Py_None); + } + else + { + vList = PyList_New(veinSize); + + for(int i = 0; i < veinSize; i++) + PyList_SET_ITEM(vList, i, BuildSpatterVein(splatter[i])); + + DICTADD(vDict, "spatter", vList); + } + + return vDict; +} + +static PyObject* BuildTileTypes40d(DFHack::tiletypes40d& types) +{ + PyObject *list, *temp; + + list = PyList_New(16); + + for(int i = 0; i < 16; i++) + { + temp = PyList_New(16); + + for(int j = 0; j < 16; j++) + PyList_SET_ITEM(temp, j, PyInt_FromLong(types[i][j])); + + PyList_SET_ITEM(list, i, temp); + } + + return list; +} + +static void ReverseBuildTileTypes40d(PyObject* list, DFHack::tiletypes40d t_types) +{ + PyObject* innerList; + + for(int i = 0; i < 16; i++) + { + innerList = PyList_GetItem(list, i); + + for(int j = 0; j < 16; j++) + t_types[i][j] = (uint16_t)PyInt_AsLong(PyList_GetItem(innerList, j)); + } +} + +static PyObject* BuildOccupancies40d(DFHack::occupancies40d& occ) +{ + PyObject *list, *temp, *args; + + list = PyList_New(16); + + for(int i = 0; i < 16; i++) + { + temp = PyList_New(16); + + for(int j = 0; j < 16; j++) + { + args = Py_BuildValue("(I)", occ[i][j].whole); + + PyList_SET_ITEM(temp, j, PyObject_Call(OccupancyFlags_type, args, NULL)); + + Py_DECREF(args); + } + + PyList_SET_ITEM(list, i, temp); + } + + return list; +} + +static void ReverseBuildOccupancies40d(PyObject* list, DFHack::occupancies40d occ) +{ + PyObject* innerList; + + for(int i = 0; i < 16; i++) + { + innerList = PyList_GetItem(list, i); + + for(int j = 0; j < 16; j++) + occ[i][j].whole = (uint32_t)PyInt_AsLong(PyList_GetItem(innerList, j)); + } +} + +static PyObject* BuildDesignations40d(DFHack::designations40d& des) +{ + PyObject *list, *temp, *args; + + list = PyList_New(16); + + for(int i = 0; i < 16; i++) + { + temp = PyList_New(16); + + for(int j = 0; j < 16; j++) + { + args = Py_BuildValue("(I)", des[i][j].whole); + + PyList_SET_ITEM(temp, j, PyObject_Call(DesignationFlags_type, args, NULL)); + + Py_DECREF(args); + } + + PyList_SET_ITEM(list, i, temp); + } + + return list; +} + +static void ReverseBuildDesignations40d(PyObject* list, DFHack::designations40d& des) +{ + PyObject* innerList; + + for(int i = 0; i < 16; i++) + { + innerList = PyList_GetItem(list, i); + + for(int j = 0; j < 16; j++) + des[i][j].whole = (uint32_t)PyInt_AsLong(PyList_GET_ITEM(innerList, j)); + } +} + +static PyObject* BuildBiomeIndices40d(DFHack::biome_indices40d& idx) +{ + PyObject *list; + + list = PyList_New(16); + + for(int i = 0; i < 16; i++) + PyList_SET_ITEM(list, i, PyInt_FromLong(idx[i])); + + return list; +} + +static void ReverseBuildBiomeIndices40d(PyObject* list, DFHack::biome_indices40d bio) +{ + for(int i = 0; i < 16; i++) + bio[i] = (uint8_t)PyInt_AsLong(PyList_GetItem(list, i)); +} + +static PyObject* BuildMapBlock40d(DFHack::mapblock40d& block) +{ + PyObject *b_Obj; + PyObject *temp, *args; + + b_Obj = PyObject_Call(MapBlock40d_type, NULL, NULL); + + temp = BuildTileTypes40d(block.tiletypes); + OBJSET(b_Obj, "tiletypes", temp); + + temp = BuildDesignations40d(block.designation); + OBJSET(b_Obj, "designation", temp); + + temp = BuildOccupancies40d(block.occupancy); + OBJSET(b_Obj, "occupancy", temp); + + temp = BuildBiomeIndices40d(block.biome_indices); + OBJSET(b_Obj, "biome_indices", temp); + + temp = PyInt_FromLong(block.origin); + OBJSET(b_Obj, "origin", temp); + + args = Py_BuildValue("(I)", block.blockflags.whole); + temp = PyObject_CallObject(BlockFlags_type, args); + + temp = PyInt_FromLong(block.blockflags.whole); + OBJSET(b_Obj, "blockflags", temp); + + return b_Obj; +} + +struct DF_Map +{ + PyObject_HEAD + DFHack::Maps* m_Ptr; +}; + +static PyObject* DF_Map_new(PyTypeObject* type, PyObject* args, PyObject* kwds) +{ + DF_Map* self; + + self = (DF_Map*)type->tp_alloc(type, 0); + + if(self != NULL) + self->m_Ptr = NULL; + + return (PyObject*)self; +} + +static int DF_Map_init(DF_Map* self, PyObject* args, PyObject* kwds) +{ + return 0; +} + +static void DF_Map_dealloc(DF_Map* self) +{ + PySys_WriteStdout("map dealloc\n"); + + if(self != NULL) + { + PySys_WriteStdout("map not NULL\n"); + + if(self->m_Ptr != NULL) + { + PySys_WriteStdout("m_Ptr = %i\n", (int)self->m_Ptr); + + delete self->m_Ptr; + + PySys_WriteStdout("m_Ptr deleted\n"); + + self->m_Ptr = NULL; + } + + self->ob_type->tp_free((PyObject*)self); + } + + PySys_WriteStdout("map dealloc done\n"); +} + +// Type methods + +static PyObject* DF_Map_Start(DF_Map* self, PyObject* args) +{ + if(self->m_Ptr != NULL) + { + if(self->m_Ptr->Start()) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_Finish(DF_Map* self, PyObject* args) +{ + if(self->m_Ptr != NULL) + { + if(self->m_Ptr->Finish()) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_ReadGeology(DF_Map* self, PyObject* args) +{ + PyObject *list, *temp; + int outerSize, innerSize; + + if(self->m_Ptr != NULL) + { + std::vector< std::vector > geoVec; + + if(self->m_Ptr->ReadGeology(geoVec)) + { + outerSize = geoVec.size(); + + list = PyList_New(outerSize); + + for(int i = 0; i < outerSize; i++) + { + std::vector innerVec = geoVec[i]; + + innerSize = innerVec.size(); + + temp = PyList_New(innerSize); + + for(int j = 0; j < innerSize; j++) + PyList_SET_ITEM(temp, j, PyInt_FromLong(innerVec[i])); + + PyList_SET_ITEM(list, i, temp); + } + + return list; + } + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_IsValidBlock(DF_Map* self, PyObject* args) +{ + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "III", &x, &y, &z)) + return NULL; + + if(self->m_Ptr->isValidBlock(x, y, z)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_GetBlockPtr(DF_Map* self, PyObject* args) +{ + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "III", &x, &y, &z)) + return NULL; + + return PyInt_FromLong(self->m_Ptr->getBlockPtr(x, y, z)); + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_ReadBlock40d(DF_Map* self, PyObject* args) +{ + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "III", &x, &y, &z)) + return NULL; + + mapblock40d mapblock; + + if(self->m_Ptr->ReadBlock40d(x, y, z, &mapblock)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_ReadTileTypes(DF_Map* self, PyObject* args) +{ + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "III", &x, &y, &z)) + return NULL; + + tiletypes40d t_types; + + if(self->m_Ptr->ReadTileTypes(x, y, z, &t_types)) + return BuildTileTypes40d(t_types); + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_WriteTileTypes(DF_Map* self, PyObject* args) +{ + PyObject* tileList; + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "IIIO", &x, &y, &z, &tileList)) + return NULL; + + tiletypes40d t_types; + + ReverseBuildTileTypes40d(tileList, t_types); + + if(self->m_Ptr->WriteTileTypes(x, y, z, &t_types)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_ReadDesignations(DF_Map* self, PyObject* args) +{ + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "III", &x, &y, &z)) + return NULL; + + DFHack::designations40d des; + + if(self->m_Ptr->ReadDesignations(x, y, z, &des)) + return BuildDesignations40d(des); + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_WriteDesignations(DF_Map* self, PyObject* args) +{ + PyObject* desList; + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "IIIO", &x, &y, &z, &desList)) + return NULL; + + designations40d des; + + ReverseBuildDesignations40d(desList, des); + + if(self->m_Ptr->WriteDesignations(x, y, z, &des)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_ReadOccupancy(DF_Map* self, PyObject* args) +{ + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "III", &x, &y, &z)) + return NULL; + + occupancies40d occ; + + if(self->m_Ptr->ReadOccupancy(x, y, z, &occ)) + return BuildOccupancies40d(occ); + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_WriteOccupancy(DF_Map* self, PyObject* args) +{ + PyObject* occList; + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "IIIO", &x, &y, &z, &occList)) + return NULL; + + occupancies40d occ; + + ReverseBuildOccupancies40d(occList, occ); + + if(self->m_Ptr->WriteOccupancy(x, y, z, &occ)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_ReadDirtyBit(DF_Map* self, PyObject* args) +{ + uint32_t x, y, z; + bool bit = false; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "III", &x, &y, &z)) + return NULL; + + self->m_Ptr->ReadDirtyBit(x, y, z, bit); + + if(bit) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_WriteDirtyBit(DF_Map* self, PyObject* args) +{ + uint32_t x, y, z, b; + bool bit; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "IIIi", &x, &y, &z, &b)) + return NULL; + + if(b != 0) + bit = true; + else + bit = false; + + if(self->m_Ptr->WriteDirtyBit(x, y, z, bit)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_ReadBlockFlags(DF_Map* self, PyObject* args) +{ + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "III", &x, &y, &z)) + return NULL; + + t_blockflags flags; + + if(self->m_Ptr->ReadBlockFlags(x, y, z, flags)) + return PyInt_FromLong(flags.whole); + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_WriteBlockFlags(DF_Map* self, PyObject* args) +{ + uint32_t x, y, z, whole; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "IIII", &x, &y, &z, &whole)) + return NULL; + + t_blockflags blockFlags; + + blockFlags.whole = whole; + + if(self->m_Ptr->WriteBlockFlags(x, y, z, blockFlags)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_ReadRegionOffsets(DF_Map* self, PyObject* args) +{ + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "III", &x, &y, &z)) + return NULL; + + biome_indices40d biome; + + if(self->m_Ptr->ReadRegionOffsets(x, y, z, &biome)) + return BuildBiomeIndices40d(biome); + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Map_ReadVeins(DF_Map* self, PyObject* args, PyObject* kwds) +{ + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "III", &x, &y, &z)) + return NULL; + + std::vector veins; + std::vector ices; + std::vector splatter; + + if(self->m_Ptr->ReadVeins(x, y, z, &veins, &ices, &splatter)) + { + return BuildVeinDict(veins, ices, splatter); + } + } + + Py_RETURN_NONE; +} + +static PyMethodDef DF_Map_methods[] = +{ + {"Start", (PyCFunction)DF_Map_Start, METH_NOARGS, ""}, + {"Finish", (PyCFunction)DF_Map_Finish, METH_NOARGS, ""}, + {"Read_Geology", (PyCFunction)DF_Map_ReadGeology, METH_NOARGS, ""}, + {"Is_Valid_Block", (PyCFunction)DF_Map_IsValidBlock, METH_VARARGS, ""}, + {"Read_Block_40d", (PyCFunction)DF_Map_ReadBlock40d, METH_VARARGS, ""}, + {"Read_Tile_Types", (PyCFunction)DF_Map_ReadTileTypes, METH_VARARGS, ""}, + {"Write_Tile_Types", (PyCFunction)DF_Map_WriteTileTypes, METH_VARARGS, ""}, + {"Read_Designations", (PyCFunction)DF_Map_ReadDesignations, METH_VARARGS, ""}, + {"Write_Designations", (PyCFunction)DF_Map_WriteDesignations, METH_VARARGS, ""}, + {"Read_Occupancy", (PyCFunction)DF_Map_ReadOccupancy, METH_VARARGS, ""}, + {"Write_Occupancy", (PyCFunction)DF_Map_WriteOccupancy, METH_VARARGS, ""}, + {"Read_Dirty_Bit", (PyCFunction)DF_Map_ReadDirtyBit, METH_VARARGS, ""}, + {"Write_Dirty_Bit", (PyCFunction)DF_Map_WriteDirtyBit, METH_VARARGS, ""}, + {"Read_Block_Flags", (PyCFunction)DF_Map_ReadBlockFlags, METH_VARARGS, ""}, + {"Write_Block_Flags", (PyCFunction)DF_Map_WriteBlockFlags, METH_VARARGS, ""}, + {"Read_Region_Offsets", (PyCFunction)DF_Map_ReadRegionOffsets, METH_VARARGS, ""}, + {NULL} //Sentinel +}; + +// Getter/Setter + +static PyObject* DF_Map_getSize(DF_Map* self, void* closure) +{ + uint32_t x, y, z; + + if(self->m_Ptr != NULL) + { + self->m_Ptr->getSize(x, y, z); + + return Py_BuildValue("III", x, y, z); + } + + Py_RETURN_NONE; +} + +static PyGetSetDef DF_Map_getterSetters[] = +{ + {"size", (getter)DF_Map_getSize, NULL, "size", NULL}, + {NULL} // Sentinel +}; + +static PyTypeObject DF_Map_type = +{ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "pydfhack.Map", /*tp_name*/ + sizeof(DF_Map), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)DF_Map_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*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*/ + "pydfhack Map objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + DF_Map_methods, /* tp_methods */ + 0, /* tp_members */ + DF_Map_getterSetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)DF_Map_init, /* tp_init */ + 0, /* tp_alloc */ + DF_Map_new, /* tp_new */ +}; + +#endif \ No newline at end of file diff --git a/dfhack/python/DF_Material.cpp b/dfhack/python/DF_Material.cpp index 6e4615441..6cc02cd18 100644 --- a/dfhack/python/DF_Material.cpp +++ b/dfhack/python/DF_Material.cpp @@ -166,17 +166,27 @@ static int DF_Material_init(DF_Material* self, PyObject* args, PyObject* kwds) static void DF_Material_dealloc(DF_Material* self) { + PySys_WriteStdout("material dealloc\n"); + if(self != NULL) { + PySys_WriteStdout("material not NULL\n"); + if(self->mat_Ptr != NULL) { + PySys_WriteStdout("mat_Ptr = %i\n", (int)self->mat_Ptr); + delete self->mat_Ptr; + PySys_WriteStdout("mat_Ptr deleted\n"); + self->mat_Ptr = NULL; } self->ob_type->tp_free((PyObject*)self); } + + PySys_WriteStdout("material dealloc done\n"); } // Type methods diff --git a/dfhack/python/DF_MemInfo.cpp b/dfhack/python/DF_MemInfo.cpp index 86efd35ff..4680b502e 100644 --- a/dfhack/python/DF_MemInfo.cpp +++ b/dfhack/python/DF_MemInfo.cpp @@ -63,17 +63,27 @@ static int DF_MemInfo_init(DF_MemInfo* self, PyObject* args, PyObject* kwds) static void DF_MemInfo_dealloc(DF_MemInfo* self) { + PySys_WriteStdout("mem_info dealloc\n"); + if(self != NULL) { + PySys_WriteStdout("mem_info not NULL\n"); + if(self->mem_Ptr != NULL) { + PySys_WriteStdout("mem_Ptr = %i\n", (int)self->mem_Ptr); + delete self->mem_Ptr; + PySys_WriteStdout("mem_Ptr deleted\n"); + self->mem_Ptr = NULL; } self->ob_type->tp_free((PyObject*)self); } + + PySys_WriteStdout("mem_info dealloc done\n"); } // Setters/Getters diff --git a/dfhack/python/DF_Translate.cpp b/dfhack/python/DF_Translate.cpp new file mode 100644 index 000000000..274e5ccdd --- /dev/null +++ b/dfhack/python/DF_Translate.cpp @@ -0,0 +1,279 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef __DFTRANSLATE__ +#define __DFTRANSLATE__ + +#include "Python.h" +#include +#include + +using namespace std; + +#include "modules/Translation.h" + +using namespace DFHack; + +struct DF_Translate +{ + PyObject_HEAD + PyObject* dict; + DFHack::Translation* tran_Ptr; +}; + +// API type Allocation, Deallocation, and Initialization + +static PyObject* DF_Translate_new(PyTypeObject* type, PyObject* args, PyObject* kwds) +{ + DF_Translate* self; + + self = (DF_Translate*)type->tp_alloc(type, 0); + + if(self != NULL) + self->tran_Ptr = NULL; + + return (PyObject*)self; +} + +static int DF_Translate_init(DF_Translate* self, PyObject* args, PyObject* kwds) +{ + return 0; +} + +static void DF_Translate_dealloc(DF_Translate* self) +{ + PySys_WriteStdout("translate dealloc\n"); + + if(self != NULL) + { + PySys_WriteStdout("translate not NULL\n"); + + if(self->tran_Ptr != NULL) + { + Py_XDECREF(self->dict); + + PySys_WriteStdout("tran_Ptr = %i\n", (int)self->tran_Ptr); + + delete self->tran_Ptr; + + PySys_WriteStdout("tran_Ptr deleted\n"); + + self->tran_Ptr = NULL; + } + + self->ob_type->tp_free((PyObject*)self); + } + + PySys_WriteStdout("translate dealloc done\n"); +} + +// Type methods + +static PyObject* DF_Translate_Start(DF_Translate* self, PyObject* args) +{ + DFHack::Dicts* t_dicts; + std::vector wordVec; + PyObject *list, *tempDict; + + if(self->tran_Ptr != NULL) + { + if(self->tran_Ptr->Start()) + { + Py_CLEAR(self->dict); + + t_dicts = self->tran_Ptr->getDicts(); + + DFHack::DFDict & translations = t_dicts->translations; + DFHack::DFDict & foreign_languages = t_dicts->foreign_languages; + + self->dict = PyDict_New(); + tempDict = PyDict_New(); + + for(uint32_t i = 0; i < translations.size(); i++) + { + uint32_t size = translations[i].size(); + uint32_t j = 0; + + list = PyList_New(size); + + for(; j < size; j++) + PyList_SET_ITEM(list, j, PyString_FromString(translations[i][j].c_str())); + + PyObject* key = PyInt_FromLong(j); + PyDict_SetItem(tempDict, key, list); + + Py_DECREF(key); + Py_DECREF(list); + } + + PyDict_SetItemString(self->dict, "translations", tempDict); + + Py_DECREF(tempDict); + + tempDict = PyDict_New(); + + for(uint32_t i = 0; i < foreign_languages.size(); i++) + { + uint32_t size = foreign_languages[i].size(); + uint32_t j = 0; + + list = PyList_New(size); + + for(; j < size; j++) + PyList_SET_ITEM(list, j, PyString_FromString(foreign_languages[i][j].c_str())); + + PyObject* key = PyInt_FromLong(j); + PyDict_SetItem(tempDict, key, list); + + Py_DECREF(key); + Py_DECREF(list); + } + + PyDict_SetItemString(self->dict, "foreign_languages", tempDict); + + Py_DECREF(tempDict); + + Py_RETURN_TRUE; + } + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Translate_Finish(DF_Translate* self, PyObject* args) +{ + if(self->tran_Ptr != NULL) + { + if(self->tran_Ptr->Finish()) + { + if(self->dict != NULL) + PyDict_Clear(self->dict); + + Py_CLEAR(self->dict); + + Py_RETURN_TRUE; + } + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Translate_TranslateName(DF_Translate* self, PyObject* args) +{ + PyObject *nameObj, *retString; + DFHack::t_name name; + int inEnglish = 1; + + if(self->tran_Ptr != NULL) + { + if(PyArg_ParseTuple(args, "O|i", &nameObj, &inEnglish)) + return NULL; + + name = ReverseBuildName(nameObj); + + std::string nameStr = self->tran_Ptr->TranslateName(name, (bool)inEnglish); + + retString = PyString_FromString(nameStr.c_str()); + + return retString; + } + + Py_RETURN_NONE; +} + +static PyMethodDef DF_Translate_methods[] = +{ + {"Start", (PyCFunction)DF_Translate_Start, METH_NOARGS, ""}, + {"Finish", (PyCFunction)DF_Translate_Finish, METH_NOARGS, ""}, + {"Translate_Name", (PyCFunction)DF_Translate_TranslateName, METH_VARARGS, ""}, + {NULL} //Sentinel +}; + +// Getters/Setters + +static PyObject* DF_Translate_getDicts(DF_Translate* self, PyObject* args) +{ + if(self->tran_Ptr != NULL) + { + if(self->dict != NULL) + return self->dict; + } + + Py_RETURN_NONE; +} + +static PyGetSetDef DF_Translate_getterSetters[] = +{ + {"dictionaries", (getter)DF_Translate_getDicts, NULL, "dictionaries", NULL}, + {NULL} // Sentinel +}; + +static PyTypeObject DF_Translate_type = +{ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "pydfhack.Translate", /*tp_name*/ + sizeof(DF_Translate), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)DF_Translate_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*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*/ + "pydfhack Translate objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + DF_Translate_methods, /* tp_methods */ + 0, /* tp_members */ + DF_Translate_getterSetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)DF_Translate_init, /* tp_init */ + 0, /* tp_alloc */ + DF_Translate_new, /* tp_new */ +}; + +#endif \ No newline at end of file diff --git a/dfhack/python/DF_Translation.cpp b/dfhack/python/DF_Translation.cpp deleted file mode 100644 index ce34a28cb..000000000 --- a/dfhack/python/DF_Translation.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#ifndef __DFTRANSLATION__ -#define __DFTRANSLATION__ - -#include "Python.h" -#include "modules/Translation.h" - -using namespace - -struct DF_Translation -{ - PyObject_HEAD - DFHack::Translation* trans_Ptr; -}; - -// API type Allocation, Deallocation, and Initialization - -static PyObject* DF_Translation_new(PyTypeObject* type, PyObject* args, PyObject* kwds) -{ - DF_Translation* self; - - self = (DF_Translation*)type->tp_alloc(type, 0); - - if(self != NULL) - self->trans_Ptr = NULL; - - return (PyObject*)self; -} - -static int DF_Translation_init(DF_Translation* self, PyObject* args, PyObject* kwds) -{ - return 0; -} - -static void DF_Translation_dealloc(DF_Translation* self) -{ - if(self != NULL) - { - if(self->trans_Ptr != NULL) - { - delete self->trans_Ptr; - - self->trans_Ptr = NULL; - } - - self->ob_type->tp_free((PyObject*)self); - } -} - -// Type methods - -static PyObject* DF_Translation_Start(DF_Translation* self, PyObject* args) -{ - if(self->trans_Ptr != NULL) - { - if(self->trans_Ptr->Start()) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; - } - - Py_RETURN_NONE; -} - -static PyObject* DF_Translation_Finish(DF_Translation* self, PyObject* args) -{ - if(self->trans_Ptr != NULL) - { - if(self->trans_Ptr->Finish()) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; - } - - Py_RETURN_NONE; -} - -static PyObject* DF_Translation_TranslateName(DF_Translation* self, PyObject* args) -{ -} - -#endif \ No newline at end of file diff --git a/dfhack/python/DF_Vegetation.cpp b/dfhack/python/DF_Vegetation.cpp new file mode 100644 index 000000000..93ba687dd --- /dev/null +++ b/dfhack/python/DF_Vegetation.cpp @@ -0,0 +1,202 @@ +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef __DFVEGETATION__ +#define __DFVEGETATION__ + +#include "Python.h" +#include "modules/Vegetation.h" +#include "DF_Helpers.cpp" + +using namespace DFHack; + +static PyObject* BuildTree(DFHack::t_tree& tree) +{ + PyObject* t_dict; + PyObject* temp; + + t_dict = PyDict_New(); + + temp = PyInt_FromLong(tree.type); + DICTADD(t_dict, "type", temp); + + temp = PyInt_FromLong(tree.material); + DICTADD(t_dict, "material", temp); + + temp = PyTuple_Pack(3, tree.x, tree.y, tree.z); + DICTADD(t_dict, "position", temp); + + temp = PyInt_FromLong(tree.address); + DICTADD(t_dict, "address", temp); + + return t_dict; +} + +struct DF_Vegetation +{ + PyObject_HEAD + DFHack::Vegetation* veg_Ptr; +}; + +static PyObject* DF_Vegetation_new(PyTypeObject* type, PyObject* args, PyObject* kwds) +{ + DF_Vegetation* self; + + self = (DF_Vegetation*)type->tp_alloc(type, 0); + + if(self != NULL) + self->veg_Ptr = NULL; + + return (PyObject*)self; +} + +static int DF_Vegetation_init(DF_Vegetation* self, PyObject* args, PyObject* kwds) +{ + return 0; +} + +static void DF_Vegetation_dealloc(DF_Vegetation* self) +{ + PySys_WriteStdout("vegetation dealloc\n"); + + if(self != NULL) + { + PySys_WriteStdout("vegetation not NULL\n"); + + if(self->veg_Ptr != NULL) + { + PySys_WriteStdout("veg_Ptr = %i\n", (int)self->veg_Ptr); + + delete self->veg_Ptr; + + PySys_WriteStdout("veg_Ptr deleted\n"); + + self->veg_Ptr = NULL; + } + + self->ob_type->tp_free((PyObject*)self); + } + + PySys_WriteStdout("vegetation dealloc done\n"); +} + +// Type methods + +static PyObject* DF_Vegetation_Start(DF_Vegetation* self, PyObject* args) +{ + uint32_t numTrees = 0; + + if(self->veg_Ptr != NULL) + { + if(self->veg_Ptr->Start(numTrees)) + return PyInt_FromLong(numTrees); + else + return PyInt_FromLong(-1); + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Vegetation_Finish(DF_Vegetation* self, PyObject* args) +{ + if(self->veg_Ptr != NULL) + { + if(self->veg_Ptr->Finish()) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Vegetation_Read(DF_Vegetation* self, PyObject* args) +{ + uint32_t index = 0; + t_tree tree; + + if(self->veg_Ptr != NULL) + { + if(!PyArg_ParseTuple(args, "I", &index)) + return NULL; + + if(self->veg_Ptr->Read(index, tree)) + return BuildTree(tree); + } + + Py_RETURN_NONE; +} + +static PyMethodDef DF_Vegetation_methods[] = +{ + {"Start", (PyCFunction)DF_Vegetation_Start, METH_NOARGS, ""}, + {"Finish", (PyCFunction)DF_Vegetation_Finish, METH_NOARGS, ""}, + {"Read", (PyCFunction)DF_Vegetation_Read, METH_VARARGS, ""}, + {NULL} // Sentinel +}; + +static PyTypeObject DF_Vegetation_type = +{ + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ + "pydfhack.Vegetation", /*tp_name*/ + sizeof(DF_Vegetation), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)DF_Vegetation_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*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*/ + "pydfhack Vegetation objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + DF_Vegetation_methods, /* 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)DF_Vegetation_init, /* tp_init */ + 0, /* tp_alloc */ + DF_Vegetation_new, /* tp_new */ +}; + +#endif \ No newline at end of file diff --git a/dfhack/python/build.bat b/dfhack/python/build.bat new file mode 100644 index 000000000..6165530b1 --- /dev/null +++ b/dfhack/python/build.bat @@ -0,0 +1,4 @@ +python setup.py build_ext +copy /Y .\build\lib.win32-2.6\pydfhack.pyd ..\..\output\pydfhack.pyd +rmdir /S /Q .\build +pause \ No newline at end of file diff --git a/dfhack/python/pydfhack.cpp b/dfhack/python/pydfhack.cpp index feb2da2cc..323c2ad70 100644 --- a/dfhack/python/pydfhack.cpp +++ b/dfhack/python/pydfhack.cpp @@ -28,6 +28,10 @@ distribution. #include "DF_Material.cpp" #include "DF_CreatureType.cpp" #include "DF_CreatureManager.cpp" +#include "DF_Translate.cpp" +#include "DF_Vegetation.cpp" +#include "DF_Buildings.cpp" +#include "DF_Constructions.cpp" #include "DF_API.cpp" #ifndef PyMODINIT_FUNC @@ -80,6 +84,24 @@ PyMODINIT_FUNC initpydfhack(void) if(PyType_Ready(&DF_CreatureManager_type) < 0) return; + if(PyType_Ready(&DF_Translate_type) < 0) + return; + + if(PyType_Ready(&DF_Vegetation_type) < 0) + return; + + if(PyType_Ready(&DF_Building_type) < 0) + return; + + if(PyType_Ready(&DF_Construction_type) < 0) + return; + + if(PyType_Ready(&DF_Map_type) < 0) + return; + + if(PyType_Ready(&DF_GUI_type) < 0) + return; + module = Py_InitModule3("pydfhack", module_methods, "pydfhack extension module"); Py_INCREF(&DF_API_type); @@ -88,13 +110,26 @@ PyMODINIT_FUNC initpydfhack(void) Py_INCREF(&DF_Material_type); Py_INCREF(&DF_Creature_Base_type); Py_INCREF(&DF_CreatureManager_type); + Py_INCREF(&DF_Translate_type); + Py_INCREF(&DF_Vegetation_type); + Py_INCREF(&DF_Building_type); + Py_INCREF(&DF_Construction_type); + Py_INCREF(&DF_Map_type); + Py_INCREF(&DF_GUI_type); PyModule_AddObject(module, "API", (PyObject*)&DF_API_type); PyModule_AddObject(module, "MemInfo", (PyObject*)&DF_MemInfo_type); PyModule_AddObject(module, "Position", (PyObject*)&DF_Position_type); PyModule_AddObject(module, "Materials", (PyObject*)&DF_Material_type); - PyModule_AddObject(module, "Creature_Base", (PyObject*)&DF_Position_type); - PyModule_AddObject(module, "CreatureManager", (PyObject*)&DF_Material_type); + PyModule_AddObject(module, "Creature_Base", (PyObject*)&DF_Creature_Base_type); + PyModule_AddObject(module, "CreatureManager", (PyObject*)&DF_CreatureManager_type); + PyModule_AddObject(module, "Translate", (PyObject*)&DF_Translate_type); + PyModule_AddObject(module, "Vegetation", (PyObject*)&DF_Vegetation_type); + PyModule_AddObject(module, "Building", (PyObject*)&DF_Building_type); + PyModule_AddObject(module, "ConstructionManager", (PyObject*)&DF_Construction_type); + PyModule_AddObject(module, "Map", (PyObject*)&DF_Map_type); + PyModule_AddObject(module, "GUI", (PyObject*)&DF_GUI_type); + DoImports(); } \ No newline at end of file diff --git a/dfhack/python/pydfhackflags.py b/dfhack/python/pydfhackflags.py new file mode 100644 index 000000000..ee0399d1c --- /dev/null +++ b/dfhack/python/pydfhackflags.py @@ -0,0 +1,195 @@ +# -*- coding: utf-8 -*- +from ctypes import Structure, Union, c_uint + +class DesignationStruct(Structure): + _fields_ = [("flow_size", c_uint, 3), + ("pile", c_uint, 1), + ("dig", c_uint, 3), + ("smooth", c_uint, 2), + ("hidden", c_uint, 1), + ("geolayer_index", c_uint, 4), + ("light", c_uint, 1), + ("subterranean", c_uint, 1), + ("skyview", c_uint, 1), + ("biome", c_uint, 4), + ("liquid_type", c_uint, 1), + ("water_table", c_uint, 1), + ("rained", c_uint, 1), + ("traffic", c_uint, 2), + ("flow_forbid", c_uint, 1), + ("liquid_static", c_uint, 1), + ("moss", c_uint, 1), + ("feature_present", c_uint, 1), + ("liquid_character", c_uint, 2)] + +class DesignationFlags(Union): + _fields_ = [("whole", c_uint, 32), + ("bits", DesignationStruct)] + + def __init__(self, initial = 0): + self.whole = initial + +class OccupancyStruct(Structure): + _fields_ = [("building", c_uint, 3), + ("unit", c_uint, 1), + ("unit_grounded", c_uint, 1), + ("item", c_uint, 1), + ("splatter", c_uint, 26)] + +class OccupancyFlags(Union): + _fields_ = [("whole", c_uint, 32), + ("bits", OccupancyStruct)] + + def __init__(self, initial = 0): + self.whole = initial + +class CreatureStruct1(Structure): + _fields_ = [("move_state", c_uint, 1), + ("dead", c_uint, 1), + ("has_mood", c_uint, 1), + ("had_mood", c_uint, 1), + ("marauder", c_uint, 1), + ("drowning", c_uint, 1), + ("merchant", c_uint, 1), + ("forest", c_uint, 1), + ("left", c_uint, 1), + ("rider", c_uint, 1), + ("incoming", c_uint, 1), + ("diplomat", c_uint, 1), + ("zombie", c_uint, 1), + ("skeleton", c_uint, 1), + ("can_swap", c_uint, 1), + ("on_ground", c_uint, 1), + ("projectile", c_uint, 1), + ("active_invader", c_uint, 1), + ("hidden_in_ambush", c_uint, 1), + ("invader_origin", c_uint, 1), + ("coward", c_uint, 1), + ("hidden_ambusher", c_uint, 1), + ("invades", c_uint, 1), + ("check_flows", c_uint, 1), + ("ridden", c_uint, 1), + ("caged", c_uint, 1), + ("tame", c_uint, 1), + ("chained", c_uint, 1), + ("royal_guard", c_uint, 1), + ("fortress_guard", c_uint, 1), + ("suppress_wield", c_uint, 1), + ("important_historical_figure", c_uint, 1)] + +class CreatureFlags1(Union): + _fields_ = [("whole", c_uint, 32), + ("bits", CreatureStruct1)] + + def __init__(self, initial = 0): + self.whole = initial + +class CreatureStruct2(Structure): + _fields_ = [("swimming", c_uint, 1), + ("sparring", c_uint, 1), + ("no_notify", c_uint, 1), + ("unused", c_uint, 1), + ("calculated_nerves", c_uint, 1), + ("calculated_bodyparts", c_uint, 1), + ("important_historical_figure", c_uint, 1), + ("killed", c_uint, 1), + ("cleanup_1", c_uint, 1), + ("cleanup_2", c_uint, 1), + ("cleanup_3", c_uint, 1), + ("for_trade", c_uint, 1), + ("trade_resolved", c_uint, 1), + ("has_breaks", c_uint, 1), + ("gutted", c_uint, 1), + ("circulatory_spray", c_uint, 1), + ("locked_in_for_trading", c_uint, 1), + ("slaughter", c_uint, 1), + ("underworld", c_uint, 1), + ("resident", c_uint, 1), + ("cleanup_4", c_uint, 1), + ("calculated_insulation", c_uint, 1), + ("visitor_uninvited", c_uint, 1), + ("visitor", c_uint, 1), + ("calculated_inventory", c_uint, 1), + ("vision_good", c_uint, 1), + ("vision_damaged", c_uint, 1), + ("vision_missing", c_uint, 1), + ("breathing_good", c_uint, 1), + ("breathing_problem", c_uint, 1), + ("roaming_wilderness_population_source", c_uint, 1), + ("roaming_wilderness_population_source_not_a_map_feature", c_uint, 1)] + +class CreatureFlags2(Union): + _fields_ = [("whole", c_uint, 32), + ("bits", CreatureStruct2)] + + def __init__(self, initial = 0): + self.whole = initial + +class ItemStruct(Structure): + _fields_ = [("on_ground", c_uint, 1), + ("in_job", c_uint, 1), + ("in_inventory", c_uint, 1), + ("u_ngrd1", c_uint, 1), + ("in_workshop", c_uint, 1), + ("u_ngrd2", c_uint, 1), + ("u_ngrd3", c_uint, 1), + ("rotten", c_uint, 1), + ("unk1", c_uint, 1), + ("u_ngrd4", c_uint, 1), + ("unk2", c_uint, 1), + ("u_ngrd5", c_uint, 1), + ("unk3", c_uint, 1), + ("u_ngrd6", c_uint, 1), + ("narrow", c_uint, 1), + ("u_ngrd7", c_uint, 1), + ("worn", c_uint, 1), + ("unk4", c_uint, 1), + ("u_ngrd8", c_uint, 1), + ("forbid", c_uint, 1), + ("unk5", c_uint, 1), + ("dump", c_uint, 1), + ("on_fire", c_uint, 1), + ("melt", c_uint, 1), + ("hidden", c_uint, 1), + ("u_ngrd9", c_uint, 1), + ("unk6", c_uint, 1), + ("unk7", c_uint, 1), + ("unk8", c_uint, 1), + ("unk9", c_uint, 1), + ("unk10", c_uint, 1), + ("unk11", c_uint, 1)] + +class ItemFlags(Union): + _fields_ = [("whole", c_uint, 32), + ("bits", ItemStruct)] + + def __init__(self, initial = 0): + self.whole = initial + +dig_types = { "no" : 0, + "default" : 1, + "ud_stair" : 2, + "channel" : 3, + "ramp" : 4, + "d_stair" : 5, + "u_stair" : 6, + "whatever" : 7 } + +traffic_types = { "normal" : 0, + "low" : 1, + "high" : 2, + "restricted" : 3 } + +class BlockFlagStruct(Structure): + _fields_ = [("designated", c_uint, 1), + ("unk_1", c_uint, 1), + ("liquid_1", c_uint, 1), + ("liquid_2", c_uint, 1), + ("unk_2", c_uint, 28)] + +class BlockFlags(Union): + _fields_ = [("whole", c_uint, 32), + ("bits", BlockFlagStruct)] + + def __init__(self, inital = 0): + self.whole = initial diff --git a/dfhack/python/pydftypes.py b/dfhack/python/pydftypes.py index 3061277bf..4e77a2b1b 100644 --- a/dfhack/python/pydftypes.py +++ b/dfhack/python/pydftypes.py @@ -1,224 +1,16 @@ -# -*- coding: utf-8 -*- -from pydfhack import * -from ctypes import * +from collections import namedtuple -class DFAPI(API): - def Read_Designations(self, x, y, z): - temp = API.Read_Designations(self, x, y, z) - - d_list = [] +Note = namedtuple("Note", "symbol, foreground, background, name, position") +Construction = namedtuple("Construction", "position, form, unk_8, mat_type, mat_idx, unk3, unk4, unk5, unk6, origin") +Vein = namedtuple("Vein", "vtable, type, flags, address, assignment") +FrozenLiquidVein = namedtuple("FrozenLiquidVein", "vtable, address, tiles") +SpatterVein = namedtuple("SpatterVein", "vtable, address, mat1, unk1, mat2, mat3, intensity") - for i in temp: - d = [] +class Name(object): + __slots__ = ["first_name", "nickname", "language", "has_name", "words", "parts_of_speech"] - for j in i: - d.append(DesignationFlags(j)) +class Soul(object): + pass - d_list.append(d) - - return d_list - def Write_Designations(self, x, y, z, d_list): - temp = [] - - for i in d_list: - t = [] - - for j in i: - t.append(j.whole) - - temp.append(t) - - API.Write_Designations(self, x, y, z, temp) - def Read_Occupancy(self, x, y, z): - temp = API.Read_Occupancy(self, x, y, z) - - o_list = [] - - for i in temp: - o = [] - - for j in i: - o.append(OccupancyFlags(j)) - - o_list.append(o) - - return o_list - -class DesignationStruct(Structure): - _fields_ = [("flow_size", c_uint, 3), - ("pile", c_uint, 1), - ("dig", c_uint, 3), - ("smooth", c_uint, 2), - ("hidden", c_uint, 1), - ("geolayer_index", c_uint, 4), - ("light", c_uint, 1), - ("subterranean", c_uint, 1), - ("skyview", c_uint, 1), - ("biome", c_uint, 4), - ("liquid_type", c_uint, 1), - ("water_table", c_uint, 1), - ("rained", c_uint, 1), - ("traffic", c_uint, 2), - ("flow_forbid", c_uint, 1), - ("liquid_static", c_uint, 1), - ("moss", c_uint, 1), - ("feature_present", c_uint, 1), - ("liquid_character", c_uint, 2)] - -class DesignationFlags(Union): - _fields_ = [("whole", c_uint, 32), - ("bits", DesignationStruct)] - - def __init__(self, initial = 0): - self.whole = initial - -class OccupancyStruct(Strucure): - _fields_ = [("building", c_uint, 3), - ("unit", c_uint, 1), - ("unit_grounded", c_uint, 1), - ("item", c_uint, 1), - ("splatter", c_uint, 26)] - -class OccupancyFlags(Union): - _fields_ = [("whole", c_uint, 32), - ("bits", OccupancyStruct)] - - def __init__(self, initial = 0): - self.whole = initial - -class CreatureStruct1(Structure): - _fields_ = [("move_state", c_uint, 1), - ("dead", c_uint, 1), - ("has_mood", c_uint, 1), - ("had_mood", c_uint, 1), - ("marauder", c_uint, 1), - ("drowning", c_uint, 1), - ("merchant", c_uint, 1), - ("forest", c_uint, 1), - ("left", c_uint, 1), - ("rider", c_uint, 1), - ("incoming", c_uint, 1), - ("diplomat", c_uint, 1), - ("zombie", c_uint, 1), - ("skeleton", c_uint, 1), - ("can_swap", c_uint, 1), - ("on_ground", c_uint, 1), - ("projectile", c_uint, 1), - ("active_invader", c_uint, 1), - ("hidden_in_ambush", c_uint, 1), - ("invader_origin", c_uint, 1), - ("coward", c_uint, 1), - ("hidden_ambusher", c_uint, 1), - ("invades", c_uint, 1), - ("check_flows", c_uint, 1), - ("ridden", c_uint, 1), - ("caged", c_uint, 1), - ("tame", c_uint, 1), - ("chained", c_uint, 1), - ("royal_guard", c_uint, 1), - ("fortress_guard", c_uint, 1), - ("suppress_wield", c_uint, 1), - ("important_historical_figure", c_uint, 1)] - -class CreatureFlags1(Union): - _fields_ = [("whole", c_uint, 32), - ("bits", CreatureStruct1)] - - def __init__(self, initial = 0): - self.whole = initial - -class CreatureStruct2(Structure): - _fields_ = [("swimming", c_uint, 1), - ("sparring", c_uint, 1), - ("no_notify", c_uint, 1), - ("unused", c_uint, 1), - ("calculated_nerves", c_uint, 1), - ("calculated_bodyparts", c_uint, 1), - ("important_historical_figure", c_uint, 1), - ("killed", c_uint, 1), - ("cleanup_1", c_uint, 1), - ("cleanup_2", c_uint, 1), - ("cleanup_3", c_uint, 1), - ("for_trade", c_uint, 1), - ("trade_resolved", c_uint, 1), - ("has_breaks", c_uint, 1), - ("gutted", c_uint, 1), - ("circulatory_spray", c_uint, 1), - ("locked_in_for_trading", c_uint, 1), - ("slaughter", c_uint, 1), - ("underworld", c_uint, 1), - ("resident", c_uint, 1), - ("cleanup_4", c_uint, 1), - ("calculated_insulation", c_uint, 1), - ("visitor_uninvited", c_uint, 1), - ("visitor", c_uint, 1), - ("calculated_inventory", c_uint, 1), - ("vision_good", c_uint, 1), - ("vision_damaged", c_uint, 1), - ("vision_missing", c_uint, 1), - ("breathing_good", c_uint, 1), - ("breathing_problem", c_uint, 1), - ("roaming_wilderness_population_source", c_uint, 1), - ("roaming_wilderness_population_source_not_a_map_feature", c_uint, 1)] - -class CreatureFlags2(Union): - _fields_ = [("whole", c_uint, 32), - ("bits", CreatureStruct2)] - - def __init__(self, initial = 0): - self.whole = initial - -class ItemStruct(Structure): - _fields_ = [("on_ground", c_uint, 1), - ("in_job", c_uint, 1), - ("in_inventory", c_uint, 1), - ("u_ngrd1", c_uint, 1), - ("in_workshop", c_uint, 1), - ("u_ngrd2", c_uint, 1), - ("u_ngrd3", c_uint, 1), - ("rotten", c_uint, 1), - ("unk1", c_uint, 1), - ("u_ngrd4", c_uint, 1), - ("unk2", c_uint, 1), - ("u_ngrd5", c_uint, 1), - ("unk3", c_uint, 1), - ("u_ngrd6", c_uint, 1), - ("narrow", c_uint, 1), - ("u_ngrd7", c_uint, 1), - ("worn", c_uint, 1), - ("unk4", c_uint, 1), - ("u_ngrd8", c_uint, 1), - ("forbid", c_uint, 1), - ("unk5", c_uint, 1), - ("dump", c_uint, 1), - ("on_fire", c_uint, 1), - ("melt", c_uint, 1), - ("hidden", c_uint, 1), - ("u_ngrd9", c_uint, 1), - ("unk6", c_uint, 1), - ("unk7", c_uint, 1), - ("unk8", c_uint, 1), - ("unk9", c_uint, 1), - ("unk10", c_uint, 1), - ("unk11", c_uint, 1)] - -class ItemFlags(Union): - _fields_ = [("whole", c_uint, 32), - ("bits", ItemStruct)] - - def __init__(self, initial = 0): - self.whole = initial - -dig_types = { "no" : 0, - "default" : 1, - "ud_stair" : 2, - "channel" : 3, - "ramp" : 4, - "d_stair" : 5, - "u_stair" : 6, - "whatever" : 7 } - -traffic_types = { "normal" : 0, - "low" : 1, - "high" : 2, - "restricted" : 3 } +class MapBlock40d(object): + pass \ No newline at end of file