From 2b544ba2de9ae6d201171fb4d7ffecea9a387995 Mon Sep 17 00:00:00 2001 From: doomchild Date: Tue, 20 Apr 2010 09:19:23 -0500 Subject: [PATCH 01/23] updated compiler flags to get rid of stupid newline warnings --- dfhack/python/setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dfhack/python/setup.py b/dfhack/python/setup.py index f42072986..42ded5d17 100644 --- a/dfhack/python/setup.py +++ b/dfhack/python/setup.py @@ -2,9 +2,10 @@ from distutils.core import setup, Extension e = Extension("pydfhack", - sources=["DF_MemInfo.cpp", "DF_API.cpp", "pydfhack.cpp"], + sources=["pydfhack.cpp"], include_dirs=["..\\", "..\\include", "..\\depends\\md5", "..\\depends\\tinyxml"], library_dirs=["..\\..\\output"], + extra_compile_args=["-w"], libraries=["libdfhack"], export_symbols=["initpydfhack", "ReadRaw", "WriteRaw"]) From 45f81d18bd9bb28eaebfd1d8eacf5528293162dc Mon Sep 17 00:00:00 2001 From: doomchild Date: Tue, 20 Apr 2010 12:19:41 -0500 Subject: [PATCH 02/23] updated type strings/names --- dfhack/python/DF_Constructions.cpp | 4 ++-- dfhack/python/DF_GUI.cpp | 4 ++-- dfhack/python/DF_Translate.cpp | 4 ++-- dfhack/python/pydfhack.cpp | 22 +++++++++++----------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/dfhack/python/DF_Constructions.cpp b/dfhack/python/DF_Constructions.cpp index 237efb479..0bfe99320 100644 --- a/dfhack/python/DF_Constructions.cpp +++ b/dfhack/python/DF_Constructions.cpp @@ -178,7 +178,7 @@ static PyTypeObject DF_Construction_type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - "pydfhack.Construction", /*tp_name*/ + "pydfhack._ConstructionManager", /*tp_name*/ sizeof(DF_Construction), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)DF_Construction_dealloc, /*tp_dealloc*/ @@ -197,7 +197,7 @@ static PyTypeObject DF_Construction_type = 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "pydfhack Construction objects", /* tp_doc */ + "pydfhack ConstructionManager object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ diff --git a/dfhack/python/DF_GUI.cpp b/dfhack/python/DF_GUI.cpp index 015d115b9..e289b7650 100644 --- a/dfhack/python/DF_GUI.cpp +++ b/dfhack/python/DF_GUI.cpp @@ -163,7 +163,7 @@ static PyTypeObject DF_GUI_type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - "pydfhack.GUI", /*tp_name*/ + "pydfhack._GUIManager", /*tp_name*/ sizeof(DF_GUI), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)DF_GUI_dealloc, /*tp_dealloc*/ @@ -182,7 +182,7 @@ static PyTypeObject DF_GUI_type = 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "pydfhack GUI objects", /* tp_doc */ + "pydfhack GUIManager object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ diff --git a/dfhack/python/DF_Translate.cpp b/dfhack/python/DF_Translate.cpp index 274e5ccdd..c61b6065e 100644 --- a/dfhack/python/DF_Translate.cpp +++ b/dfhack/python/DF_Translate.cpp @@ -237,7 +237,7 @@ static PyTypeObject DF_Translate_type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - "pydfhack.Translate", /*tp_name*/ + "pydfhack._TranslationManager", /*tp_name*/ sizeof(DF_Translate), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)DF_Translate_dealloc, /*tp_dealloc*/ @@ -256,7 +256,7 @@ static PyTypeObject DF_Translate_type = 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "pydfhack Translate objects", /* tp_doc */ + "pydfhack TranslationManager object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ diff --git a/dfhack/python/pydfhack.cpp b/dfhack/python/pydfhack.cpp index 323c2ad70..fadb0852b 100644 --- a/dfhack/python/pydfhack.cpp +++ b/dfhack/python/pydfhack.cpp @@ -118,17 +118,17 @@ PyMODINIT_FUNC initpydfhack(void) 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_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); + PyModule_AddObject(module, "_MemInfo", (PyObject*)&DF_MemInfo_type); + PyModule_AddObject(module, "_PositionManager", (PyObject*)&DF_Position_type); + PyModule_AddObject(module, "_MaterialsManager", (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, "_TranslationManager", (PyObject*)&DF_Translate_type); + PyModule_AddObject(module, "_VegetationManager", (PyObject*)&DF_Vegetation_type); + PyModule_AddObject(module, "_BuildingManager", (PyObject*)&DF_Building_type); + PyModule_AddObject(module, "_ConstructionManager", (PyObject*)&DF_Construction_type); + PyModule_AddObject(module, "_MapManager", (PyObject*)&DF_Map_type); + PyModule_AddObject(module, "_GUIManager", (PyObject*)&DF_GUI_type); DoImports(); From 5cc3b5e4c783d14750c7222f26509aed21c83e14 Mon Sep 17 00:00:00 2001 From: doomchild Date: Tue, 20 Apr 2010 12:20:30 -0500 Subject: [PATCH 03/23] added map_type...now I should be able to subclass easier --- dfhack/python/DF_API.cpp | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/dfhack/python/DF_API.cpp b/dfhack/python/DF_API.cpp index 0f227f55f..bb83b4dfe 100644 --- a/dfhack/python/DF_API.cpp +++ b/dfhack/python/DF_API.cpp @@ -29,6 +29,7 @@ distribution. #include #include "DFTypes.h" #include "DFHackAPI.h" +#include "DF_Imports.cpp" #include "DF_MemInfo.cpp" #include "DF_Position.cpp" #include "DF_Material.cpp" @@ -54,6 +55,8 @@ struct DF_API PyObject* construction; PyObject* vegetation; PyObject* gui; + + PyObject* map_type; DFHack::API* api_Ptr; }; @@ -87,6 +90,8 @@ static int DF_API_init(DF_API* self, PyObject* args, PyObject* kwds) self->vegetation = NULL; self->gui = NULL; + self->map_type = (PyObject*)&DF_Map_type; + if(!PyArg_ParseTuple(args, "s", &memFileString)) return -1; @@ -310,7 +315,7 @@ static PyObject* DF_API_getMap(DF_API* self, void* closure) { if(self->api_Ptr != NULL) { - self->map = PyObject_Call((PyObject*)&DF_Map_type, NULL, NULL); + self->map = PyObject_CallObject(self->map_type, NULL); if(self->map != NULL) { @@ -446,6 +451,31 @@ static PyObject* DF_API_getGUI(DF_API* self, void* closure) Py_RETURN_NONE; } +static PyObject* DF_API_getMapType(DF_API* self, void* closure) +{ + return self->map_type; +} + +static int DF_API_setMapType(DF_API* self, PyObject* value) +{ + if(PyType_Check(value) <= 0) + { + PySys_WriteStdout("failed type check"); + PyErr_SetString(PyExc_TypeError, "value must be a type object"); + return NULL; + } + if(PyObject_IsSubclass(value, (PyObject*)&DF_Map_type) <= 0) + { + PySys_WriteStdout("failed subclass check"); + PyErr_SetString(PyExc_TypeError, "value must be descended from pydfhack._MapManager"); + return NULL; + } + + self->map_type = value; + + return 0; +} + static PyGetSetDef DF_API_getterSetters[] = { {"is_attached", (getter)DF_API_getIsAttached, NULL, "is_attached", NULL}, @@ -459,6 +489,7 @@ static PyGetSetDef DF_API_getterSetters[] = {"constructions", (getter)DF_API_getConstruction, NULL, "constructions", NULL}, {"vegetation", (getter)DF_API_getVegetation, NULL, "vegetation", NULL}, {"gui", (getter)DF_API_getGUI, NULL, "gui", NULL}, + {"map_type", (getter)DF_API_getMapType, (setter)DF_API_setMapType, "map_type", NULL}, {NULL} // Sentinel }; From f86cb94d369a215d889fef2afeaf5cb05a0a868f Mon Sep 17 00:00:00 2001 From: doomchild Date: Tue, 20 Apr 2010 12:21:52 -0500 Subject: [PATCH 04/23] updated type string, tweaked reverse designation build --- dfhack/python/DF_Maps.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dfhack/python/DF_Maps.cpp b/dfhack/python/DF_Maps.cpp index 788130444..e397d9ef7 100644 --- a/dfhack/python/DF_Maps.cpp +++ b/dfhack/python/DF_Maps.cpp @@ -301,7 +301,7 @@ static void ReverseBuildDesignations40d(PyObject* list, DFHack::designations40d& for(int i = 0; i < 16; i++) { - innerList = PyList_GetItem(list, i); + innerList = PyList_GET_ITEM(list, i); for(int j = 0; j < 16; j++) des[i][j].whole = (uint32_t)PyInt_AsLong(PyList_GET_ITEM(innerList, j)); @@ -581,6 +581,8 @@ static PyObject* DF_Map_ReadDesignations(DF_Map* self, PyObject* args) Py_RETURN_NONE; } +static DFHack::designations40d writeDes; + static PyObject* DF_Map_WriteDesignations(DF_Map* self, PyObject* args) { PyObject* desList; @@ -591,11 +593,9 @@ static PyObject* DF_Map_WriteDesignations(DF_Map* self, PyObject* args) if(!PyArg_ParseTuple(args, "IIIO", &x, &y, &z, &desList)) return NULL; - designations40d des; - - ReverseBuildDesignations40d(desList, des); + ReverseBuildDesignations40d(desList, writeDes); - if(self->m_Ptr->WriteDesignations(x, y, z, &des)) + if(self->m_Ptr->WriteDesignations(x, y, z, &writeDes)) Py_RETURN_TRUE; else Py_RETURN_FALSE; @@ -817,7 +817,7 @@ static PyTypeObject DF_Map_type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - "pydfhack.Map", /*tp_name*/ + "pydfhack._MapManager", /*tp_name*/ sizeof(DF_Map), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)DF_Map_dealloc, /*tp_dealloc*/ @@ -836,7 +836,7 @@ static PyTypeObject DF_Map_type = 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "pydfhack Map objects", /* tp_doc */ + "pydfhack MapManager object", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ From 16d5175ee5455af4e38f551d762eadcd0c2b01ce Mon Sep 17 00:00:00 2001 From: doomchild Date: Tue, 20 Apr 2010 15:34:10 -0500 Subject: [PATCH 05/23] updated for upstream additions --- dfhack/python/DF_Buildings.cpp | 82 +++++++++-- dfhack/python/DF_CreatureManager.cpp | 22 +++ dfhack/python/DF_Helpers.cpp | 10 ++ dfhack/python/DF_Material.cpp | 194 ++++++++++++++++++++++----- 4 files changed, 263 insertions(+), 45 deletions(-) diff --git a/dfhack/python/DF_Buildings.cpp b/dfhack/python/DF_Buildings.cpp index 1028074f2..2c37aceb0 100644 --- a/dfhack/python/DF_Buildings.cpp +++ b/dfhack/python/DF_Buildings.cpp @@ -38,22 +38,40 @@ static PyObject* BuildBuilding(DFHack::t_building& building) t_dict = PyDict_New(); - temp = PyInt_FromLong(building.origin); - DICTADD(t_dict, "origin", temp); + temp = Py_BuildValue("(si)(si)(si)(sO)(s((ii)(ii)i))", \ + "origin", building.origin, \ + "vtable", building.vtable, \ + "type", building.type, \ + "material", BuildMatglossPair(building.material), \ + "bounds", Py_BuildValue("(ii)(ii)i", building.x1, building.y1, building.x2, building.y2, building.z)); - temp = PyInt_FromLong(building.vtable); - DICTADD(t_dict, "vtable", temp); + PyDict_MergeFromSeq2(t_dict, temp, 0); - temp = PyInt_FromLong(building.type); - DICTADD(t_dict, "type", temp); + return t_dict; +} + +static DFHack::t_building ReverseBuildBuilding(PyObject* bDict) +{ + PyObject* temp; + uint32_t x1, y1, x2, y2, z; + DFHack::t_building building; - temp = BuildMatglossPair(building.material); - DICTADD(t_dict, "material", temp); + building.origin = (uint32_t)PyInt_AsLong(PyDict_GetItemString(bDict, "origin")); + building.vtable = (uint32_t)PyInt_AsLong(PyDict_GetItemString(bDict, "vtable")); + building.material = ReverseBuildMatglossPair(PyDict_GetItemString(bDict, "material")); + building.type = (uint32_t)PyInt_AsLong(PyDict_GetItemString(bDict, "type")); - temp = PyTuple_Pack(2, PyTuple_Pack(2, building.x1, building.y1), PyTuple_Pack(2, building.x2, building.y2)); - DICTADD(t_dict, "bounds", temp); + temp = PyDict_GetItemString(bDict, "bounds"); - return t_dict; + PyArg_ParseTuple(temp, "(ii)(ii)i", &x1, &y1, &x2, &y2, &z); + + building.x1 = x1; + building.y1 = y1; + building.x2 = x2; + building.y2 = y2; + building.z = z; + + return building; } struct DF_Building @@ -151,11 +169,53 @@ static PyObject* DF_Building_Read(DF_Building* self, PyObject* args) Py_RETURN_NONE; } +static PyObject* DF_Building_ReadCustomWorkshopTypes(DF_Building* self, PyObject* args) +{ + PyObject* bDict; + std::map bTypes; + std::map::iterator bIter; + + if(self->b_Ptr != NULL) + { + if(self->b_Ptr->ReadCustomWorkshopTypes(bTypes)) + { + bDict = PyDict_New(); + + for(bIter = bTypes.begin(); bIter != bTypes.end(); bIter++) + { + PyObject* temp = Py_BuildValue("is", (*bIter).first, (*bIter).second); + + PyDict_MergeFromSeq2(bDict, temp, 1); + } + + return bDict; + } + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Building_GetCustomWorkshopType(DF_Building* self, PyObject* args) +{ + DFHack::t_building building; + + if(self->b_Ptr != NULL) + { + building = ReverseBuildBuilding(args); + + return PyInt_FromLong(self->b_Ptr->GetCustomWorkshopType(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, ""}, + {"Read_Custom_Workshop_Types", (PyCFunction)DF_Building_ReadCustomWorkshopTypes, METH_NOARGS, ""}, + {"Get_Custom_Workshop_Type", (PyCFunction)DF_Building_GetCustomWorkshopType, METH_VARARGS, ""}, {NULL} // Sentinel }; diff --git a/dfhack/python/DF_CreatureManager.cpp b/dfhack/python/DF_CreatureManager.cpp index 43e08f230..d27500fc6 100644 --- a/dfhack/python/DF_CreatureManager.cpp +++ b/dfhack/python/DF_CreatureManager.cpp @@ -155,12 +155,34 @@ static PyObject* DF_CreatureManager_ReadCreatureInBox(DF_CreatureManager* self, Py_RETURN_NONE; } +static PyObject* DF_CreatureManager_GetDwarfRaceIndex(DF_CreatureManager* self, PyObject* args) +{ + if(self->creature_Ptr != NULL) + { + return PyInt_FromLong(self->creature_Ptr->GetDwarfRaceIndex()); + } + + Py_RETURN_NONE; +} + +static PyObject* DF_CreatureManager_GetDwarfCivId(DF_CreatureManager* self, PyObject* args) +{ + if(self->creature_Ptr != NULL) + { + return PyInt_FromLong(self->creature_Ptr->GetDwarfCivId()); + } + + Py_RETURN_NONE; +} + static PyMethodDef DF_CreatureManager_methods[] = { {"Start", (PyCFunction)DF_CreatureManager_Start, METH_NOARGS, ""}, {"Finish", (PyCFunction)DF_CreatureManager_Finish, METH_NOARGS, ""}, {"Read_Creature", (PyCFunction)DF_CreatureManager_ReadCreature, METH_VARARGS, ""}, {"Read_Creature_In_Box", (PyCFunction)DF_CreatureManager_ReadCreatureInBox, METH_VARARGS, ""}, + {"Get_Dwarf_Race_Index", (PyCFunction)DF_CreatureManager_GetDwarfRaceIndex, METH_NOARGS, ""}, + {"Get_Dwarf_Civ_id", (PyCFunction)DF_CreatureManager_GetDwarfCivId, METH_NOARGS, ""}, {NULL} // Sentinel }; diff --git a/dfhack/python/DF_Helpers.cpp b/dfhack/python/DF_Helpers.cpp index 9dce8c737..a2a0eb33d 100644 --- a/dfhack/python/DF_Helpers.cpp +++ b/dfhack/python/DF_Helpers.cpp @@ -43,6 +43,16 @@ static PyObject* BuildMatglossPair(DFHack::t_matglossPair& matgloss) return Py_BuildValue("ii", matgloss.type, matgloss.index); } +static DFHack::t_matglossPair ReverseBuildMatglossPair(PyObject* mObj) +{ + DFHack::t_matglossPair mPair; + + mPair.type = (int16_t)PyInt_AsLong(PyTuple_GetItem(mObj, 0)); + mPair.index = (int32_t)PyInt_AsLong(PyTuple_GetItem(mObj, 1)); + + return mPair; +} + static PyObject* BuildSkill(DFHack::t_skill& skill) { return Py_BuildValue("III", skill.id, skill.experience, skill.rating); diff --git a/dfhack/python/DF_Material.cpp b/dfhack/python/DF_Material.cpp index 6cc02cd18..b4f67154a 100644 --- a/dfhack/python/DF_Material.cpp +++ b/dfhack/python/DF_Material.cpp @@ -45,45 +45,20 @@ struct DF_Material static PyObject* BuildMatgloss(t_matgloss& matgloss) { PyObject* matDict; - PyObject* temp; + PyObject* list; matDict = PyDict_New(); + list = PyList_New(5); - if(matgloss.id[0]) - temp = PyString_FromString(matgloss.id); - else - temp = PyString_FromString(""); - - PyDict_SetItemString(matDict, "id", temp); - - Py_DECREF(temp); - - temp = PyInt_FromLong(matgloss.fore); - - PyDict_SetItemString(matDict, "fore", temp); - - Py_DECREF(temp); + PyList_SET_ITEM(list, 0, Py_BuildValue("ss", "id", matgloss.id)); + PyList_SET_ITEM(list, 1, Py_BuildValue("si", "fore", matgloss.fore)); + PyList_SET_ITEM(list, 2, Py_BuildValue("si", "back", matgloss.back)); + PyList_SET_ITEM(list, 3, Py_BuildValue("si", "bright", matgloss.bright)); + PyList_SET_ITEM(list, 4, Py_BuildValue("ss", "name", matgloss.name)); - temp = PyInt_FromLong(matgloss.back); + PyDict_MergeFromSeq2(matDict, list, 0); - PyDict_SetItemString(matDict, "back", temp); - - Py_DECREF(temp); - - temp = PyInt_FromLong(matgloss.bright); - - PyDict_SetItemString(matDict, "bright", temp); - - Py_DECREF(temp); - - if(matgloss.name[0]) - temp = PyString_FromString(matgloss.name); - else - temp = PyString_FromString(""); - - PyDict_SetItemString(matDict, "name", temp); - - Py_DECREF(temp); + Py_DECREF(list); return matDict; } @@ -145,6 +120,125 @@ static PyObject* BuildMatglossList(std::vector & matVec) return matList; } +static PyObject* BuildDescriptorColor(t_descriptor_color& color) +{ + PyObject* matDict; + PyObject* list; + + matDict = PyDict_New(); + list = PyList_New(5); + + PyList_SET_ITEM(list, 0, Py_BuildValue("ss", "id", color.id)); + PyList_SET_ITEM(list, 1, Py_BuildValue("sf", "r", color.r)); + PyList_SET_ITEM(list, 2, Py_BuildValue("sf", "v", color.v)); + PyList_SET_ITEM(list, 3, Py_BuildValue("sf", "b", color.b)); + PyList_SET_ITEM(list, 4, Py_BuildValue("ss", "name", color.name)); + + PyDict_MergeFromSeq2(matDict, list, 0); + + Py_DECREF(list); + + return matDict; +} + +static PyObject* BuildDescriptorColorList(std::vector& colors) +{ + PyObject* colorList; + std::vector::iterator colorIter; + + colorList = PyList_New(0); + + for(colorIter = colors.begin(); colorIter != colors.end(); colorIter++) + { + PyObject* color = BuildDescriptorColor(*colorIter); + + PyList_Append(colorList, color); + + Py_DECREF(colorList); + } + + return colorList; +} + +static PyObject* BuildCreatureCaste(t_creaturecaste& caste) +{ + PyObject* matDict; + PyObject* list; + + matDict = PyDict_New(); + list = PyList_New(4); + + PyList_SET_ITEM(list, 0, Py_BuildValue("ss", "rawname", caste.rawname)); + PyList_SET_ITEM(list, 1, Py_BuildValue("ss", "singular", caste.singular)); + PyList_SET_ITEM(list, 2, Py_BuildValue("ss", "plural", caste.plural)); + PyList_SET_ITEM(list, 3, Py_BuildValue("ss", "adjective", caste.adjective)); + + PyDict_MergeFromSeq2(matDict, list, 0); + + Py_DECREF(list); + + return matDict; +} + +static PyObject* BuildCreatureCasteList(std::vector& castes) +{ + PyObject* casteList; + std::vector::iterator casteIter; + + casteList = PyList_New(0); + + for(casteIter = castes.begin(); casteIter != castes.end(); casteIter++) + { + PyObject* caste = BuildCreatureCaste(*casteIter); + + PyList_Append(casteList, caste); + + Py_DECREF(caste); + } + + return casteList; +} + +static PyObject* BuildCreatureTypeEx(t_creaturetype& creature) +{ + PyObject* c_type; + PyObject* list; + + c_type = PyDict_New(); + list = PyList_New(6); + + PyList_SET_ITEM(list, 0, Py_BuildValue("ss", "rawname", creature.rawname)); + PyList_SET_ITEM(list, 1, Py_BuildValue("sO", "castes", BuildCreatureCasteList(creature.castes))); + PyList_SET_ITEM(list, 2, Py_BuildValue("si", "tile_character", creature.tile_character)); + PyList_SET_ITEM(list, 3, Py_BuildValue("si", "fore", creature.tilecolor.fore)); + PyList_SET_ITEM(list, 4, Py_BuildValue("si", "back", creature.tilecolor.back)); + PyList_SET_ITEM(list, 5, Py_BuildValue("si", "bright", creature.tilecolor.bright)); + + PyDict_MergeFromSeq2(c_type, list, 0); + Py_DECREF(list); + + return c_type; +} + +static PyObject* BuildCreatureTypeExList(std::vector& creatures) +{ + PyObject* creatureList; + std::vector::iterator creatureIter; + + creatureList = PyList_New(0); + + for(creatureIter = creatures.begin(); creatureIter != creatures.end(); creatureIter++) + { + PyObject* creature = BuildCreatureTypeEx(*creatureIter); + + PyList_Append(creatureList, creature); + + Py_DECREF(creature); + } + + return creatureList; +} + // API type Allocation, Deallocation, and Initialization static PyObject* DF_Material_new(PyTypeObject* type, PyObject* args, PyObject* kwds) @@ -266,6 +360,36 @@ static PyObject* DF_Material_ReadCreatureTypes(DF_Material* self, PyObject* args Py_RETURN_NONE; } +static PyObject* DF_Material_ReadCreatureTypesEx(DF_Material* self, PyObject* args) +{ + if(self->mat_Ptr != NULL) + { + std::vector creatureVec; + + if(self->mat_Ptr->ReadCreatureTypesEx(creatureVec)) + { + return BuildCreatureTypeExList(creatureVec); + } + } + + Py_RETURN_NONE; +} + +static PyObject* DF_Material_ReadDescriptorColors(DF_Material* self, PyObject* args) +{ + if(self->mat_Ptr != NULL) + { + std::vector colorVec; + + if(self->mat_Ptr->ReadDescriptorColors(colorVec)) + { + return BuildDescriptorColorList(colorVec); + } + } + + Py_RETURN_NONE; +} + static PyMethodDef DF_Material_methods[] = { {"Read_Inorganic_Materials", (PyCFunction)DF_Material_ReadInorganicMaterials, METH_NOARGS, ""}, @@ -273,6 +397,8 @@ static PyMethodDef DF_Material_methods[] = {"Read_Wood_Materials", (PyCFunction)DF_Material_ReadWoodMaterials, METH_NOARGS, ""}, {"Read_Plant_Materials", (PyCFunction)DF_Material_ReadPlantMaterials, METH_NOARGS, ""}, {"Read_Creature_Types", (PyCFunction)DF_Material_ReadCreatureTypes, METH_NOARGS, ""}, + {"Read_Creature_Types_Ex", (PyCFunction)DF_Material_ReadCreatureTypesEx, METH_NOARGS, ""}, + {"Read_Descriptor_Colors", (PyCFunction)DF_Material_ReadDescriptorColors, METH_NOARGS, ""}, {NULL} //Sentinel }; From 73fc2cf4985d6f9b7d42a27aa4c788d7401f71c5 Mon Sep 17 00:00:00 2001 From: doomchild Date: Wed, 21 Apr 2010 10:40:31 -0500 Subject: [PATCH 06/23] first commit --- dfhack/python/pydfapi.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 dfhack/python/pydfapi.py diff --git a/dfhack/python/pydfapi.py b/dfhack/python/pydfapi.py new file mode 100644 index 000000000..f4bc0d12b --- /dev/null +++ b/dfhack/python/pydfapi.py @@ -0,0 +1,17 @@ +from pydfhack import * + +class API(_API): + def __init__(self, *args, **kwds): + _API.__init__(self, args, kwds) + +class Map(_MapManager): + def __init__(self, *args, **kwds): + _MapManager.__init__(self, args, kwds) + +class Vegetation(_VegetationManager): + def __init__(self, *args, **kwds): + _VegetationManager.__init__(self, args, kwds) + +class GUI(_GUIManager): + def __init__(self, *args, **kwds): + _GUIManager.__init__(self, args, kwds) \ No newline at end of file From 3a94785cc073e3a6abd380d70fa48d83e3bc000c Mon Sep 17 00:00:00 2001 From: doomchild Date: Wed, 21 Apr 2010 10:40:43 -0500 Subject: [PATCH 07/23] changed API type name --- dfhack/python/pydfhack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dfhack/python/pydfhack.cpp b/dfhack/python/pydfhack.cpp index fadb0852b..b01adad1c 100644 --- a/dfhack/python/pydfhack.cpp +++ b/dfhack/python/pydfhack.cpp @@ -117,7 +117,7 @@ PyMODINIT_FUNC initpydfhack(void) Py_INCREF(&DF_Map_type); Py_INCREF(&DF_GUI_type); - PyModule_AddObject(module, "API", (PyObject*)&DF_API_type); + PyModule_AddObject(module, "_API", (PyObject*)&DF_API_type); PyModule_AddObject(module, "_MemInfo", (PyObject*)&DF_MemInfo_type); PyModule_AddObject(module, "_PositionManager", (PyObject*)&DF_Position_type); PyModule_AddObject(module, "_MaterialsManager", (PyObject*)&DF_Material_type); From 7ecdc4a5b46c322cef2cfa5e317a1904c8968734 Mon Sep 17 00:00:00 2001 From: doomchild Date: Wed, 21 Apr 2010 10:41:06 -0500 Subject: [PATCH 08/23] added type changes for vegetation and gui --- dfhack/python/DF_API.cpp | 63 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/dfhack/python/DF_API.cpp b/dfhack/python/DF_API.cpp index bb83b4dfe..9d48089ab 100644 --- a/dfhack/python/DF_API.cpp +++ b/dfhack/python/DF_API.cpp @@ -57,6 +57,9 @@ struct DF_API PyObject* gui; PyObject* map_type; + PyObject* vegetation_type; + PyObject* gui_type; + DFHack::API* api_Ptr; }; @@ -91,6 +94,8 @@ static int DF_API_init(DF_API* self, PyObject* args, PyObject* kwds) self->gui = NULL; self->map_type = (PyObject*)&DF_Map_type; + self->vegetation_type = (PyObject*)&DF_Vegetation_type; + self->gui_type = (PyObject*)&DF_GUI_type; if(!PyArg_ParseTuple(args, "s", &memFileString)) return -1; @@ -402,7 +407,7 @@ static PyObject* DF_API_getVegetation(DF_API* self, void* closure) { if(self->api_Ptr != NULL) { - self->vegetation = PyObject_Call((PyObject*)&DF_Vegetation_type, NULL, NULL); + self->vegetation = PyObject_CallObject(self->vegetation_type, NULL); if(self->vegetation != NULL) { @@ -431,7 +436,7 @@ static PyObject* DF_API_getGUI(DF_API* self, void* closure) { if(self->api_Ptr != NULL) { - self->gui = PyObject_Call((PyObject*)&DF_GUI_type, NULL, NULL); + self->gui = PyObject_CallObject(self->gui_type, NULL); if(self->gui != NULL) { @@ -476,6 +481,56 @@ static int DF_API_setMapType(DF_API* self, PyObject* value) return 0; } +static PyObject* DF_API_getVegetationType(DF_API* self, void* closure) +{ + return self->vegetation_type; +} + +static int DF_API_setVegetationType(DF_API* self, PyObject* value) +{ + if(PyType_Check(value) <= 0) + { + PySys_WriteStdout("failed type check"); + PyErr_SetString(PyExc_TypeError, "value must be a type object"); + return NULL; + } + if(PyObject_IsSubclass(value, (PyObject*)&DF_Vegetation_type) <= 0) + { + PySys_WriteStdout("failed subclass check"); + PyErr_SetString(PyExc_TypeError, "value must be descended from pydfhack._VegetationManager"); + return NULL; + } + + self->vegetation_type = value; + + return 0; +} + +static PyObject* DF_API_getGUIType(DF_API* self, void* closure) +{ + return self->gui_type; +} + +static int DF_API_setGUIType(DF_API* self, PyObject* value) +{ + if(PyType_Check(value) <= 0) + { + PySys_WriteStdout("failed type check"); + PyErr_SetString(PyExc_TypeError, "value must be a type object"); + return NULL; + } + if(PyObject_IsSubclass(value, (PyObject*)&DF_GUI_type) <= 0) + { + PySys_WriteStdout("failed subclass check"); + PyErr_SetString(PyExc_TypeError, "value must be descended from pydfhack._GUIManager"); + return NULL; + } + + self->gui_type = value; + + return 0; +} + static PyGetSetDef DF_API_getterSetters[] = { {"is_attached", (getter)DF_API_getIsAttached, NULL, "is_attached", NULL}, @@ -489,7 +544,9 @@ static PyGetSetDef DF_API_getterSetters[] = {"constructions", (getter)DF_API_getConstruction, NULL, "constructions", NULL}, {"vegetation", (getter)DF_API_getVegetation, NULL, "vegetation", NULL}, {"gui", (getter)DF_API_getGUI, NULL, "gui", NULL}, - {"map_type", (getter)DF_API_getMapType, (setter)DF_API_setMapType, "map_type", NULL}, + {"_map_mgr_type", (getter)DF_API_getMapType, (setter)DF_API_setMapType, "_map_mgr_type", NULL}, + {"_vegetation_mgr_type", (getter)DF_API_getVegetationType, (setter)DF_API_setVegetationType, "_vegetation_mgr_type", NULL}, + {"_gui_mgr_type", (getter)DF_API_getGUIType, (setter)DF_API_setGUIType, "_gui_mgr_type", NULL}, {NULL} // Sentinel }; From 831afd391df9922be46cf65eaf8d467396a85b20 Mon Sep 17 00:00:00 2001 From: doomchild Date: Wed, 21 Apr 2010 14:56:34 -0500 Subject: [PATCH 09/23] add integer conversions for union types --- dfhack/python/pydfhackflags.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/dfhack/python/pydfhackflags.py b/dfhack/python/pydfhackflags.py index ee0399d1c..87a03104d 100644 --- a/dfhack/python/pydfhackflags.py +++ b/dfhack/python/pydfhackflags.py @@ -28,6 +28,9 @@ class DesignationFlags(Union): def __init__(self, initial = 0): self.whole = initial + + def __int__(self): + return self.whole class OccupancyStruct(Structure): _fields_ = [("building", c_uint, 3), @@ -42,6 +45,9 @@ class OccupancyFlags(Union): def __init__(self, initial = 0): self.whole = initial + + def __int__(self): + return self.whole class CreatureStruct1(Structure): _fields_ = [("move_state", c_uint, 1), @@ -83,6 +89,9 @@ class CreatureFlags1(Union): def __init__(self, initial = 0): self.whole = initial + + def __int__(self): + return self.whole class CreatureStruct2(Structure): _fields_ = [("swimming", c_uint, 1), @@ -124,6 +133,9 @@ class CreatureFlags2(Union): def __init__(self, initial = 0): self.whole = initial + + def __int__(self): + return self.whole class ItemStruct(Structure): _fields_ = [("on_ground", c_uint, 1), @@ -165,6 +177,9 @@ class ItemFlags(Union): def __init__(self, initial = 0): self.whole = initial + + def __int__(self): + return self.whole dig_types = { "no" : 0, "default" : 1, @@ -193,3 +208,6 @@ class BlockFlags(Union): def __init__(self, inital = 0): self.whole = initial + + def __int__(self): + return self.whole From b7a9a0d146351ca00d71d0edc3ee4141558704f7 Mon Sep 17 00:00:00 2001 From: doomchild Date: Wed, 21 Apr 2010 14:57:05 -0500 Subject: [PATCH 10/23] include DFTypes.h --- dfhack/python/DF_GUI.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dfhack/python/DF_GUI.cpp b/dfhack/python/DF_GUI.cpp index e289b7650..5e9d064de 100644 --- a/dfhack/python/DF_GUI.cpp +++ b/dfhack/python/DF_GUI.cpp @@ -26,6 +26,7 @@ distribution. #define __DFGUI__ #include "Python.h" +#include "DFTypes.h" #include "modules/Gui.h" using namespace DFHack; From 1a575a2d1905b6c6853d57ad88ff73e04a3f4386 Mon Sep 17 00:00:00 2001 From: doomchild Date: Wed, 21 Apr 2010 14:57:23 -0500 Subject: [PATCH 11/23] include std stuff --- dfhack/python/DF_Buildings.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dfhack/python/DF_Buildings.cpp b/dfhack/python/DF_Buildings.cpp index 2c37aceb0..55c803694 100644 --- a/dfhack/python/DF_Buildings.cpp +++ b/dfhack/python/DF_Buildings.cpp @@ -26,6 +26,12 @@ distribution. #define __DFBUILDINGS__ #include "Python.h" +#include +#include + +using namespace std; + +#include "DFTypes.h" #include "modules/Buildings.h" #include "DF_Helpers.cpp" From 60c41d41dffb109677057b48e1d5944ffb09a10c Mon Sep 17 00:00:00 2001 From: doomchild Date: Wed, 21 Apr 2010 14:57:41 -0500 Subject: [PATCH 12/23] include DFTypes.h --- dfhack/python/DF_Translate.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dfhack/python/DF_Translate.cpp b/dfhack/python/DF_Translate.cpp index c61b6065e..1ce635f5c 100644 --- a/dfhack/python/DF_Translate.cpp +++ b/dfhack/python/DF_Translate.cpp @@ -31,7 +31,9 @@ distribution. using namespace std; +#include "DFTypes.h" #include "modules/Translation.h" +#include "DF_Helpers.cpp" using namespace DFHack; From d148aeecc893561b7be126cb3d82b4325d5b0bed Mon Sep 17 00:00:00 2001 From: doomchild Date: Wed, 21 Apr 2010 14:57:53 -0500 Subject: [PATCH 13/23] updated build script --- dfhack/python/setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dfhack/python/setup.py b/dfhack/python/setup.py index 42ded5d17..a115d1003 100644 --- a/dfhack/python/setup.py +++ b/dfhack/python/setup.py @@ -2,10 +2,10 @@ from distutils.core import setup, Extension e = Extension("pydfhack", - sources=["pydfhack.cpp"], + sources=["DF_API.cpp", "DF_Buildings.cpp", "DF_Constructions.cpp", "DF_CreatureManager.cpp", "DF_GUI.cpp", "DF_Maps.cpp", "DF_Material.cpp", "DF_Position.cpp", "DF_Translate.cpp", "DF_Vegetation.cpp", "pydfhack.cpp"], include_dirs=["..\\", "..\\include", "..\\depends\\md5", "..\\depends\\tinyxml"], library_dirs=["..\\..\\output"], - extra_compile_args=["-w"], + #extra_compile_args=["-w"], libraries=["libdfhack"], export_symbols=["initpydfhack", "ReadRaw", "WriteRaw"]) From 662bb2291b5d4b0f86f9ff35687e29cbb1505344 Mon Sep 17 00:00:00 2001 From: doomchild Date: Wed, 21 Apr 2010 14:58:17 -0500 Subject: [PATCH 14/23] added base type assignments --- dfhack/python/pydfapi.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dfhack/python/pydfapi.py b/dfhack/python/pydfapi.py index f4bc0d12b..76aea332c 100644 --- a/dfhack/python/pydfapi.py +++ b/dfhack/python/pydfapi.py @@ -3,6 +3,10 @@ from pydfhack import * class API(_API): def __init__(self, *args, **kwds): _API.__init__(self, args, kwds) + + self._map_mgr_type = Map + self._vegetation_mgr_type = Vegetation + self._gui_mgr_type = GUI class Map(_MapManager): def __init__(self, *args, **kwds): From dcaeadf4d3c013ed8768d7085375298d869d05e0 Mon Sep 17 00:00:00 2001 From: doomchild Date: Wed, 21 Apr 2010 14:58:38 -0500 Subject: [PATCH 15/23] include DFTypes.h --- dfhack/python/DF_Maps.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dfhack/python/DF_Maps.cpp b/dfhack/python/DF_Maps.cpp index e397d9ef7..e7d4297e6 100644 --- a/dfhack/python/DF_Maps.cpp +++ b/dfhack/python/DF_Maps.cpp @@ -31,6 +31,7 @@ distribution. using namespace std; +#include "DFTypes.h" #include "modules/Maps.h" #include "DF_Imports.cpp" #include "DF_Helpers.cpp" @@ -304,7 +305,7 @@ static void ReverseBuildDesignations40d(PyObject* list, DFHack::designations40d& innerList = PyList_GET_ITEM(list, i); for(int j = 0; j < 16; j++) - des[i][j].whole = (uint32_t)PyInt_AsLong(PyList_GET_ITEM(innerList, j)); + des[i][j].whole = (uint32_t)PyInt_AS_LONG(PyList_GET_ITEM(innerList, j)); } } @@ -581,8 +582,6 @@ static PyObject* DF_Map_ReadDesignations(DF_Map* self, PyObject* args) Py_RETURN_NONE; } -static DFHack::designations40d writeDes; - static PyObject* DF_Map_WriteDesignations(DF_Map* self, PyObject* args) { PyObject* desList; @@ -593,6 +592,8 @@ static PyObject* DF_Map_WriteDesignations(DF_Map* self, PyObject* args) if(!PyArg_ParseTuple(args, "IIIO", &x, &y, &z, &desList)) return NULL; + DFHack::designations40d writeDes; + ReverseBuildDesignations40d(desList, writeDes); if(self->m_Ptr->WriteDesignations(x, y, z, &writeDes)) From b0bda21d8e70dfc470367658fef1a884f6271e9d Mon Sep 17 00:00:00 2001 From: doomchild Date: Wed, 21 Apr 2010 14:59:04 -0500 Subject: [PATCH 16/23] fixed type setters to return -1 instead of NULL on error --- dfhack/python/DF_API.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dfhack/python/DF_API.cpp b/dfhack/python/DF_API.cpp index 9d48089ab..f80534353 100644 --- a/dfhack/python/DF_API.cpp +++ b/dfhack/python/DF_API.cpp @@ -467,13 +467,13 @@ static int DF_API_setMapType(DF_API* self, PyObject* value) { PySys_WriteStdout("failed type check"); PyErr_SetString(PyExc_TypeError, "value must be a type object"); - return NULL; + return -1; } if(PyObject_IsSubclass(value, (PyObject*)&DF_Map_type) <= 0) { PySys_WriteStdout("failed subclass check"); PyErr_SetString(PyExc_TypeError, "value must be descended from pydfhack._MapManager"); - return NULL; + return -1; } self->map_type = value; @@ -492,13 +492,13 @@ static int DF_API_setVegetationType(DF_API* self, PyObject* value) { PySys_WriteStdout("failed type check"); PyErr_SetString(PyExc_TypeError, "value must be a type object"); - return NULL; + return -1; } if(PyObject_IsSubclass(value, (PyObject*)&DF_Vegetation_type) <= 0) { PySys_WriteStdout("failed subclass check"); PyErr_SetString(PyExc_TypeError, "value must be descended from pydfhack._VegetationManager"); - return NULL; + return -1; } self->vegetation_type = value; @@ -517,13 +517,13 @@ static int DF_API_setGUIType(DF_API* self, PyObject* value) { PySys_WriteStdout("failed type check"); PyErr_SetString(PyExc_TypeError, "value must be a type object"); - return NULL; + return -1; } if(PyObject_IsSubclass(value, (PyObject*)&DF_GUI_type) <= 0) { PySys_WriteStdout("failed subclass check"); PyErr_SetString(PyExc_TypeError, "value must be descended from pydfhack._GUIManager"); - return NULL; + return -1; } self->gui_type = value; @@ -653,7 +653,7 @@ static PyTypeObject DF_API_type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ - "pydfhack.API", /*tp_name*/ + "pydfhack._API", /*tp_name*/ sizeof(DF_API), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)DF_API_dealloc, /*tp_dealloc*/ @@ -672,7 +672,7 @@ static PyTypeObject DF_API_type = 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "pydfhack API objects", /* tp_doc */ + "pydfhack _API objects", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ From 73f676bc365976d6e947af1f27f08956976c1e2d Mon Sep 17 00:00:00 2001 From: doomchild Date: Thu, 22 Apr 2010 09:07:04 -0500 Subject: [PATCH 17/23] fixed std::string to Python string conversion in DF_Building_ReadCustomWorkshopTypes --- dfhack/python/DF_Buildings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dfhack/python/DF_Buildings.cpp b/dfhack/python/DF_Buildings.cpp index 55c803694..00bfe146e 100644 --- a/dfhack/python/DF_Buildings.cpp +++ b/dfhack/python/DF_Buildings.cpp @@ -189,7 +189,7 @@ static PyObject* DF_Building_ReadCustomWorkshopTypes(DF_Building* self, PyObject for(bIter = bTypes.begin(); bIter != bTypes.end(); bIter++) { - PyObject* temp = Py_BuildValue("is", (*bIter).first, (*bIter).second); + PyObject* temp = Py_BuildValue("is", (*bIter).first, (*bIter).second.c_str()); PyDict_MergeFromSeq2(bDict, temp, 1); } From b288f43c3e7dbed50df064ab697451729edee0d6 Mon Sep 17 00:00:00 2001 From: doomchild Date: Thu, 22 Apr 2010 13:06:59 -0500 Subject: [PATCH 18/23] first commit --- dfhack/python/examples/attachtest.py | 43 +++++++++++++++ dfhack/python/examples/miscutils.py | 36 +++++++++++++ dfhack/python/examples/position.py | 22 ++++++++ dfhack/python/examples/settlementdump.py | 8 +++ dfhack/python/examples/suspendtest.py | 38 ++++++++++++++ dfhack/python/examples/treedump.py | 66 ++++++++++++++++++++++++ 6 files changed, 213 insertions(+) create mode 100644 dfhack/python/examples/attachtest.py create mode 100644 dfhack/python/examples/miscutils.py create mode 100644 dfhack/python/examples/position.py create mode 100644 dfhack/python/examples/settlementdump.py create mode 100644 dfhack/python/examples/suspendtest.py create mode 100644 dfhack/python/examples/treedump.py diff --git a/dfhack/python/examples/attachtest.py b/dfhack/python/examples/attachtest.py new file mode 100644 index 000000000..2f04437bc --- /dev/null +++ b/dfhack/python/examples/attachtest.py @@ -0,0 +1,43 @@ +import time +import math +import pydfapi + +df = pydfapi.API("Memory.xml") + +def test_attach(): + if not df.Attach(): + print "Unable to attach!" + return False + elif not df.Detach(): + print "Unable to detach!" + return False + else: + return True + +def suspend_test(): + print "Testing suspend/resume" + + df.Attach() + + t1 = time.time() + + for i in xrange(1000): + df.Suspend() + + if i % 10 == 0: + print "%i%%" % (i / 10,) + + df.Resume() + + t2 = time.time() + + df.Detach() + + print "suspend tests done in %0.9f seconds" % (t2 - t1,) + +if __name__ == "__main__": + if test_attach(): + suspend_test() + + print "Done. Press any key to continue" + raw_input() \ No newline at end of file diff --git a/dfhack/python/examples/miscutils.py b/dfhack/python/examples/miscutils.py new file mode 100644 index 000000000..64ccf9031 --- /dev/null +++ b/dfhack/python/examples/miscutils.py @@ -0,0 +1,36 @@ +_splatter_dict = { 0 : "Rock", + 1 : "Amber", + 2 : "Coral", + 3 : "Green Glass", + 4 : "Clear Glass", + 5 : "Crystal Glass", + 6 : "Ice", + 7 : "Coal", + 8 : "Potash", + 9 : "Ash", + 10 : "Pearlash", + 11 : "Lye", + 12 : "Mud", + 13 : "Vomit", + 14 : "Salt", + 15 : "Filth", + 16 : "Frozen? Filth", + 18 : "Grime", + 0xF2 : "Very Specific Blood (references a named creature)" } + +def get_splatter_type(mat1, mat2, creature_types): + from cStringIO import StringIO + + if mat1 in _splatter_dict: + return _splatter_dict[mat1] + elif mat1 == 0x2A or mat1 == 0x2B: + splatter = StringIO() + + if mat2 != -1: + splatter.write(creature_types[mat2]["id"] + " ") + + splatter.write("Blood") + + return splatter.getvalue() + else: + return "Unknown" diff --git a/dfhack/python/examples/position.py b/dfhack/python/examples/position.py new file mode 100644 index 000000000..82aae5b01 --- /dev/null +++ b/dfhack/python/examples/position.py @@ -0,0 +1,22 @@ +import sys +import pydfapi + +df = pydfapi.API("Memory.xml") + +if not df.Attach(): + print "Unable to attach!" + print "Press any key to continue" + raw_input() + sys.exit(1) + +pos = df.position + +print "view coords: %s" % (pos.view_coords,) +print "cursor coords: %s" % (pos.cursor_coords,) +print "window size: %s" % (pos.window_size,) + +if not df.Detach(): + print "Unable to detach!" + +print "Done. Press any key to continue" +raw_input() diff --git a/dfhack/python/examples/settlementdump.py b/dfhack/python/examples/settlementdump.py new file mode 100644 index 000000000..b30538ac9 --- /dev/null +++ b/dfhack/python/examples/settlementdump.py @@ -0,0 +1,8 @@ +import sys +from cStringIO import StringIO +import pydfapi + +df = pydfapi.API("Memory.xml") + +def print_settlement(settlement, english_words, foreign_words): + s = StringIO() diff --git a/dfhack/python/examples/suspendtest.py b/dfhack/python/examples/suspendtest.py new file mode 100644 index 000000000..65f11bf53 --- /dev/null +++ b/dfhack/python/examples/suspendtest.py @@ -0,0 +1,38 @@ +import pydfapi + +if __name__ == "__main__": + df = pydfapi.API("Memory.xml") + + if not df.Attach(): + print "Unable to attach!" + return False + + print "Attached, DF should be suspended now" + raw_input() + + df.Resume() + + print "Resumed, DF should be running" + raw_input() + + df.Suspend() + + print "Suspended, DF should be suspended now" + raw_input() + + df.Resume() + + print "Resumed, testing ForceResume. Suspend using SysInternals Process Explorer" + raw_input() + + df.Force_Resume() + + print "ForceResumed. DF should be running." + raw_input() + + if not df.Detach(): + print "Can't detach from DF" + return False + + print "Detached, DF should be running again" + raw_input() \ No newline at end of file diff --git a/dfhack/python/examples/treedump.py b/dfhack/python/examples/treedump.py new file mode 100644 index 000000000..7b62dfe91 --- /dev/null +++ b/dfhack/python/examples/treedump.py @@ -0,0 +1,66 @@ +import sys +from cStringIO import StringIO +import pydfapi + +df = pydfapi.API("Memory.xml") + +if not df.Attach(): + print "Unable to attach!\nPress any key to continue" + raw_input() + sys.exit(1) + +pos = df.position +veg = df.vegetation +mat = df.materials + +organics = mat.Read_Organic_Materials() + +x, y, z = pos.cursor_coords + +num_vegs = veg.Start() + +if x == -30000: + print "----==== Trees ====----" + + for i in xrange(num_vegs): + tree = veg.Read(i) + + t_x, t_y, t_z = tree["position"] + + print "%f/%f/%f, %f:%f" % (t_x, t_y, t_z, tree["type"], tree["material"]) +else: + print "----==== Tree at %i/%i/%i" % (x, y, z) + + for i in xrange(num_vegs): + tree = veg.Read(i) + + t_x, t_y, t_z = tree["position"] + t_type = tree["address"] + + if t_x == x and t_y == y and t_z == z: + s = StringIO() + + s.write("%f:%f = " % (tree["type"], tree["material"])) + + if t_type in (1, 3): + s.write("near-water ") + + s.write("%i " % (organics[tree["material"]]["id"]),) + + if t_type in (0, 1): + s.write("tree\n") + elif t_type in (2, 3): + s.write("shrub\n") + + print s.getvalue() + print "Address: 0x%x" % (tree["address"],) + + break + +veg.Finish() + +if not df.Detach(): + print "Unable to detach!" + +print "Done. Press any key to continue" +raw_input() From f06f8cc7524862f97da504dc74bbaeae1995d276 Mon Sep 17 00:00:00 2001 From: doomchild Date: Fri, 23 Apr 2010 09:18:01 -0500 Subject: [PATCH 19/23] updated to match upstream flag definition --- dfhack/python/pydfhackflags.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dfhack/python/pydfhackflags.py b/dfhack/python/pydfhackflags.py index 87a03104d..f8c15bef7 100644 --- a/dfhack/python/pydfhackflags.py +++ b/dfhack/python/pydfhackflags.py @@ -18,8 +18,8 @@ class DesignationStruct(Structure): ("traffic", c_uint, 2), ("flow_forbid", c_uint, 1), ("liquid_static", c_uint, 1), - ("moss", c_uint, 1), - ("feature_present", c_uint, 1), + ("feature_local", c_uint, 1), + ("feature_global", c_uint, 1), ("liquid_character", c_uint, 2)] class DesignationFlags(Union): From cabe5d9271446109dc6cc105bde1cff440726b8d Mon Sep 17 00:00:00 2001 From: doomchild Date: Fri, 23 Apr 2010 11:01:34 -0500 Subject: [PATCH 20/23] added WriteLabors --- dfhack/python/DF_CreatureManager.cpp | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/dfhack/python/DF_CreatureManager.cpp b/dfhack/python/DF_CreatureManager.cpp index d27500fc6..4e01bb0b9 100644 --- a/dfhack/python/DF_CreatureManager.cpp +++ b/dfhack/python/DF_CreatureManager.cpp @@ -26,6 +26,7 @@ distribution. #define __DFCREATURES__ #include "Python.h" +#include "stdio.h" #include "DFTypes.h" #include "modules/Creatures.h" #include "DF_CreatureType.cpp" @@ -175,12 +176,54 @@ static PyObject* DF_CreatureManager_GetDwarfCivId(DF_CreatureManager* self, PyOb Py_RETURN_NONE; } +static PyObject* DF_CreatureManager_WriteLabors(DF_CreatureManager* self, PyObject* args) +{ + int32_t index; + PyObject* laborList; + + + if(self->creature_Ptr != NULL) + { + uint8_t laborArray[NUM_CREATURE_LABORS]; + + if(!PyArg_ParseTuple(args, "iO", &index, &laborList)) + return NULL; + + if(!PyList_Check(laborList)) + { + PyErr_SetString(PyExc_TypeError, "argument 2 must be a list"); + return NULL; + } + + if(PyList_Size(laborList) < NUM_CREATURE_LABORS) + { + char errBuff[50]; + + sprintf(errBuff, "list must contain at least %u entries", NUM_CREATURE_LABORS); + + PyErr_SetString(PyExc_StandardError, errBuff) + return NULL; + } + + for(int i = 0; i < NUM_CREATURE_LABORS; i++) + laborArray[i] = (uint8_t)PyInt_AsLong(PyList_GET_ITEM(laborList, i)); + + if(self->creature_Ptr->WriteLabors(index, laborArray)) + Py_RETURN_TRUE; + else + Py_RETURN_FALSE; + } + + Py_RETURN_NONE; +} + static PyMethodDef DF_CreatureManager_methods[] = { {"Start", (PyCFunction)DF_CreatureManager_Start, METH_NOARGS, ""}, {"Finish", (PyCFunction)DF_CreatureManager_Finish, METH_NOARGS, ""}, {"Read_Creature", (PyCFunction)DF_CreatureManager_ReadCreature, METH_VARARGS, ""}, {"Read_Creature_In_Box", (PyCFunction)DF_CreatureManager_ReadCreatureInBox, METH_VARARGS, ""}, + {"Write_Labors", (PyCFunction)DF_CreatureManager_WriteLabors, METH_VARARGS, ""}, {"Get_Dwarf_Race_Index", (PyCFunction)DF_CreatureManager_GetDwarfRaceIndex, METH_NOARGS, ""}, {"Get_Dwarf_Civ_id", (PyCFunction)DF_CreatureManager_GetDwarfCivId, METH_NOARGS, ""}, {NULL} // Sentinel From 365c6dd0ed10272a488ce0e8c39585a966da573a Mon Sep 17 00:00:00 2001 From: doomchild Date: Fri, 23 Apr 2010 11:56:38 -0500 Subject: [PATCH 21/23] updated to Tree tuple type --- dfhack/python/DF_Vegetation.cpp | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/dfhack/python/DF_Vegetation.cpp b/dfhack/python/DF_Vegetation.cpp index 93ba687dd..f549b55c0 100644 --- a/dfhack/python/DF_Vegetation.cpp +++ b/dfhack/python/DF_Vegetation.cpp @@ -33,24 +33,16 @@ using namespace DFHack; static PyObject* BuildTree(DFHack::t_tree& tree) { - PyObject* t_dict; - PyObject* temp; + PyObject* t_Obj; + PyObject* args; - t_dict = PyDict_New(); + args = Py_BuildValue("iiOi", tree.type, tree.material, BuildPosition3D(tree.x, tree.y, tree.z), tree.address); - temp = PyInt_FromLong(tree.type); - DICTADD(t_dict, "type", temp); + t_Obj = PyObject_CallObject(Tree_type, args); - temp = PyInt_FromLong(tree.material); - DICTADD(t_dict, "material", temp); + Py_DECREF(args); - 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; + return t_Obj; } struct DF_Vegetation From 8eacdbe7f9491b8be354accd8accdac29903d9cc Mon Sep 17 00:00:00 2001 From: doomchild Date: Fri, 23 Apr 2010 14:32:24 -0500 Subject: [PATCH 22/23] added new namedtuples --- dfhack/python/pydftypes.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/dfhack/python/pydftypes.py b/dfhack/python/pydftypes.py index 4e77a2b1b..5ff79d7ea 100644 --- a/dfhack/python/pydftypes.py +++ b/dfhack/python/pydftypes.py @@ -1,16 +1,31 @@ from collections import namedtuple +Position2D = namedtuple("Position2D", "x, y") +Position3D = namedtuple("Position3D", "x, y, z") +Rectangle = namedtuple("Rectangle", "x1, y1, x2, y2") 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") +Settlement = namedtuple("Settlement", "origin, name, world_pos, local_pos") +Attribute = namedtuple("Attribute", "level, field_4, field_8, field_C, leveldiff, field_14, field_18"); +Skill = namedtuple("Skill", "id, experience, rating") +Tree = namedtuple("Tree", "type, material, position, address") +CreatureCaste = namedtuple("CreatureCaste", "rawname, singular, plural, adjective") +Matgloss = namedtuple("Matgloss", "id, fore, back, bright, name") +DescriptorColor = namedtuple("DescriptorColor", "id, r, v, b, name") +CreatureTypeEx = namedtuple("CreatureTypeEx", "rawname, castes, tile_character, tilecolor") +TileColor = namedtuple("TileColor", "fore, back, bright") class Name(object): __slots__ = ["first_name", "nickname", "language", "has_name", "words", "parts_of_speech"] class Soul(object): - pass + def __init__(self, *args, **kwds): + if kwds: + for k, v in kwds.iteritems(): + self.__dict__[k] = v class MapBlock40d(object): pass \ No newline at end of file From ee9da5910b7b43c00b75a1204c4fa0481c29a75b Mon Sep 17 00:00:00 2001 From: doomchild Date: Fri, 23 Apr 2010 14:32:38 -0500 Subject: [PATCH 23/23] updated to use new namedtuples --- dfhack/python/DF_CreatureManager.cpp | 2 +- dfhack/python/DF_Helpers.cpp | 134 +++++++++++++++++++-------- dfhack/python/DF_Imports.cpp | 32 ++++++- dfhack/python/DF_Material.cpp | 78 ++++++---------- 4 files changed, 153 insertions(+), 93 deletions(-) diff --git a/dfhack/python/DF_CreatureManager.cpp b/dfhack/python/DF_CreatureManager.cpp index 4e01bb0b9..c9b4136c8 100644 --- a/dfhack/python/DF_CreatureManager.cpp +++ b/dfhack/python/DF_CreatureManager.cpp @@ -201,7 +201,7 @@ static PyObject* DF_CreatureManager_WriteLabors(DF_CreatureManager* self, PyObje sprintf(errBuff, "list must contain at least %u entries", NUM_CREATURE_LABORS); - PyErr_SetString(PyExc_StandardError, errBuff) + PyErr_SetString(PyExc_StandardError, errBuff); return NULL; } diff --git a/dfhack/python/DF_Helpers.cpp b/dfhack/python/DF_Helpers.cpp index a2a0eb33d..6c4b580cd 100644 --- a/dfhack/python/DF_Helpers.cpp +++ b/dfhack/python/DF_Helpers.cpp @@ -28,16 +28,60 @@ distribution. #include "Python.h" #include #include +#include + +using namespace std; + #include "DFTypes.h" #include "DF_Imports.cpp" using namespace DFHack; #include "modules/Creatures.h" +#include "modules/Materials.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* BuildTileColor(uint16_t fore, uint16_t back, uint16_t bright) +{ + PyObject *tObj, *args; + + args = Py_BuildValue("iii", fore, back, bright); + + tObj = PyObject_CallObject(TileColor_type, args); + + Py_DECREF(args); + + return tObj; +} + +static PyObject* BuildPosition2D(uint16_t x, uint16_t y) +{ + PyObject *posObj, *args; + + args = Py_BuildValue("ii", x, y); + + posObj = PyObject_CallObject(Position2D_type, args); + + Py_DECREF(args); + + return posObj; +} + +static PyObject* BuildPosition3D(uint16_t x, uint16_t y, uint16_t z) +{ + PyObject *posObj, *args; + + args = Py_BuildValue("iii", x, y, z); + + posObj = PyObject_CallObject(Position3D_type, args); + + Py_DECREF(args); + + return posObj; +} + static PyObject* BuildMatglossPair(DFHack::t_matglossPair& matgloss) { return Py_BuildValue("ii", matgloss.type, matgloss.index); @@ -55,7 +99,15 @@ static DFHack::t_matglossPair ReverseBuildMatglossPair(PyObject* mObj) static PyObject* BuildSkill(DFHack::t_skill& skill) { - return Py_BuildValue("III", skill.id, skill.experience, skill.rating); + PyObject *args, *skillObj; + + args = Py_BuildValue("III", skill.id, skill.experience, skill.rating); + + skillObj = PyObject_CallObject(Skill_type, args); + + Py_DECREF(args); + + return skillObj; } static PyObject* BuildSkillList(DFHack::t_skill (&skills)[256], uint8_t numSkills) @@ -75,24 +127,20 @@ static PyObject* BuildJob(DFHack::t_job& job) 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); + PyObject *args, *attrObj; + + args = Py_BuildValue("IIIIIII", at.level, at.field_4, at.field_8, at.field_C, at.leveldiff, at.field_14, at.field_18); + + attrObj = PyObject_CallObject(Attribute_type, args); + + Py_DECREF(args); + + return attrObj; } static PyObject* BuildItemType(DFHack::t_itemType& item) { - PyObject *id, *name; - - if(item.id[0]) - id = PyString_FromString(item.id); - else - id = PyString_FromString(""); - - if(item.name[0]) - name = PyString_FromString(item.name); - else - name = PyString_FromString(""); - - return Py_BuildValue("OO", id, name); + return Py_BuildValue("ss", item.id, item.name); } static PyObject* BuildLike(DFHack::t_like& like) @@ -107,19 +155,20 @@ static PyObject* BuildLike(DFHack::t_like& like) static PyObject* BuildNote(DFHack::t_note& note) { PyObject* noteObj; - PyObject *args, *name, *position; + PyObject *args, *position; - if(note.name[0]) - name = PyString_FromString(note.name); - else - name = PyString_FromString(""); + args = Py_BuildValue("III", note.x, note.y, note.z); + + position = PyObject_CallObject(Position3D_type, args); - position = Py_BuildValue("III", note.x, note.y, note.z); + Py_DECREF(args); - args = Py_BuildValue("cIIsO", note.symbol, note.foreground, note.background, name, position); + args = Py_BuildValue("cIIsO", note.symbol, note.foreground, note.background, note.name, position); noteObj = PyObject_CallObject(Note_type, args); + Py_DECREF(args); + return noteObj; } @@ -245,33 +294,36 @@ static DFHack::t_name ReverseBuildName(PyObject* nameObj) static PyObject* BuildSettlement(DFHack::t_settlement& settlement) { - PyObject* setDict; - PyObject *local_pos1, *local_pos2; - PyObject* temp; + PyObject* setObj; + PyObject *world_pos, *local_pos, *args; + + args = Py_BuildValue("ii", settlement.world_x, settlement.world_y); - setDict = PyDict_New(); + world_pos = PyObject_CallObject(Position2D_type, args); - temp = PyInt_FromLong(settlement.origin); - DICTADD(setDict, "origin", temp); + Py_DECREF(args); - temp = BuildName(settlement.name); - DICTADD(setDict, "name", temp); + args = Py_BuildValue("iiii", settlement.local_x1, settlement.local_y1, settlement.local_x2, settlement.local_y2); - temp = Py_BuildValue("ii", settlement.world_x, settlement.world_y); - DICTADD(setDict, "world_pos", temp); + local_pos = PyObject_CallObject(Rectangle_type, args); - local_pos1 = Py_BuildValue("ii", settlement.local_x1, settlement.local_y1); - local_pos2 = Py_BuildValue("ii", settlement.local_x2, settlement.local_y2); + Py_DECREF(args); - temp = Py_BuildValue("OO", local_pos1, local_pos2); - DICTADD(setDict, "local_pos", temp); + args = Py_BuildValue("iOOO", settlement.origin, BuildName(settlement.name), world_pos, local_pos); - return setDict; + setObj = PyObject_CallObject(Settlement_type, args); + + Py_DECREF(args); + + return setObj; } static PyObject* BuildSoul(DFHack::t_soul& soul) { - PyObject *soulDict, *skillList, *temp; + PyObject *soulDict, *skillList, *temp, *emptyArgs; + PyObject* soulObj; + + emptyArgs = Py_BuildValue("()"); soulDict = PyDict_New(); @@ -317,7 +369,11 @@ static PyObject* BuildSoul(DFHack::t_soul& soul) temp = BuildAttribute(soul.social_awareness); DICTADD(soulDict, "social_awareness", temp); - return soulDict; + soulObj = PyObject_Call(Soul_type, emptyArgs, soulDict); + + Py_DECREF(emptyArgs); + + return soulObj; } #endif \ No newline at end of file diff --git a/dfhack/python/DF_Imports.cpp b/dfhack/python/DF_Imports.cpp index 15e93d2b3..b163a8822 100644 --- a/dfhack/python/DF_Imports.cpp +++ b/dfhack/python/DF_Imports.cpp @@ -43,10 +43,23 @@ static PyObject* MapBlock40d_type = NULL; static PyObject* Vein_type = NULL; static PyObject* FrozenLiquidVein_type = NULL; static PyObject* SpatterVein_type = NULL; +static PyObject* Position2D_type = NULL; +static PyObject* Position3D_type = NULL; +static PyObject* Rectangle_type = NULL; +static PyObject* Settlement_type = NULL; +static PyObject* Attribute_type = NULL; +static PyObject* Skill_type = NULL; +static PyObject* Soul_type = NULL; +static PyObject* Tree_type = NULL; +static PyObject* CreatureCaste_type = NULL; +static PyObject* Matgloss_type = NULL; +static PyObject* DescriptorColor_type = NULL; +static PyObject* CreatureTypeEx_type = NULL; +static PyObject* TileColor_type = NULL; static void DoImports() { - if(TypesModule == NULL) + if(FlagsModule == NULL) { FlagsModule = PyImport_ImportModule("pydfhackflags"); @@ -56,7 +69,9 @@ static void DoImports() OccupancyFlags_type = PyObject_GetAttrString(FlagsModule, "OccupancyFlags"); ItemFlags_type = PyObject_GetAttrString(FlagsModule, "ItemFlags"); BlockFlags_type = PyObject_GetAttrString(FlagsModule, "BlockFlags"); - + } + if(TypesModule == NULL) + { TypesModule = PyImport_ImportModule("pydftypes"); Note_type = PyObject_GetAttrString(TypesModule, "Note"); @@ -66,6 +81,19 @@ static void DoImports() Vein_type = PyObject_GetAttrString(TypesModule, "Vein"); FrozenLiquidVein_type = PyObject_GetAttrString(TypesModule, "FrozenLiquidVein"); SpatterVein_type = PyObject_GetAttrString(TypesModule, "SpatterVein"); + Position2D_type = PyObject_GetAttrString(TypesModule, "Position2D"); + Position3D_type = PyObject_GetAttrString(TypesModule, "Position3D"); + Rectangle_type = PyObject_GetAttrString(TypesModule, "Rectangle"); + Settlement_type = PyObject_GetAttrString(TypesModule, "Settlement"); + Attribute_type = PyObject_GetAttrString(TypesModule, "Attribute"); + Skill_type = PyObject_GetAttrString(TypesModule, "Skill"); + Soul_type = PyObject_GetAttrString(TypesModule, "Soul"); + Tree_type = PyObject_GetAttrString(TypesModule, "Tree"); + CreatureCaste_type = PyObject_GetAttrString(TypesModule, "CreatureCaste"); + Matgloss_type = PyObject_GetAttrString(TypesModule, "Matgloss"); + DescriptorColor_type = PyObject_GetAttrString(TypesModule, "DescriptorColor"); + CreatureTypeEx_type = PyObject_GetAttrString(TypesModule, "CreatureTypeEx"); + TileColor_type = PyObject_GetAttrString(TypesModule, "TileColor"); } } diff --git a/dfhack/python/DF_Material.cpp b/dfhack/python/DF_Material.cpp index b4f67154a..56813c5d9 100644 --- a/dfhack/python/DF_Material.cpp +++ b/dfhack/python/DF_Material.cpp @@ -31,6 +31,8 @@ distribution. using namespace std; #include "modules/Materials.h" +#include "DF_Imports.cpp" +#include "DF_Helpers.cpp" using namespace DFHack; @@ -44,23 +46,16 @@ struct DF_Material static PyObject* BuildMatgloss(t_matgloss& matgloss) { - PyObject* matDict; - PyObject* list; - - matDict = PyDict_New(); - list = PyList_New(5); + PyObject* matObj; + PyObject* args; - PyList_SET_ITEM(list, 0, Py_BuildValue("ss", "id", matgloss.id)); - PyList_SET_ITEM(list, 1, Py_BuildValue("si", "fore", matgloss.fore)); - PyList_SET_ITEM(list, 2, Py_BuildValue("si", "back", matgloss.back)); - PyList_SET_ITEM(list, 3, Py_BuildValue("si", "bright", matgloss.bright)); - PyList_SET_ITEM(list, 4, Py_BuildValue("ss", "name", matgloss.name)); + args = Py_BuildValue("siiis", matgloss.id, matgloss.fore, matgloss.back, matgloss.bright, matgloss.name); - PyDict_MergeFromSeq2(matDict, list, 0); + matObj = PyObject_CallObject(Matgloss_type, args); - Py_DECREF(list); + Py_DECREF(args); - return matDict; + return matObj; } static PyObject* BuildMatglossPlant(t_matglossPlant& matgloss) @@ -122,23 +117,16 @@ static PyObject* BuildMatglossList(std::vector & matVec) static PyObject* BuildDescriptorColor(t_descriptor_color& color) { - PyObject* matDict; - PyObject* list; - - matDict = PyDict_New(); - list = PyList_New(5); + PyObject* descObj; + PyObject* args; - PyList_SET_ITEM(list, 0, Py_BuildValue("ss", "id", color.id)); - PyList_SET_ITEM(list, 1, Py_BuildValue("sf", "r", color.r)); - PyList_SET_ITEM(list, 2, Py_BuildValue("sf", "v", color.v)); - PyList_SET_ITEM(list, 3, Py_BuildValue("sf", "b", color.b)); - PyList_SET_ITEM(list, 4, Py_BuildValue("ss", "name", color.name)); + args = Py_BuildValue("sfffs", color.id, color.r, color.v, color.b, color.name); - PyDict_MergeFromSeq2(matDict, list, 0); + descObj = PyObject_CallObject(DescriptorColor_type, args); - Py_DECREF(list); + Py_DECREF(args); - return matDict; + return descObj; } static PyObject* BuildDescriptorColorList(std::vector& colors) @@ -162,22 +150,16 @@ static PyObject* BuildDescriptorColorList(std::vector& color static PyObject* BuildCreatureCaste(t_creaturecaste& caste) { - PyObject* matDict; - PyObject* list; + PyObject* casteObj; + PyObject* args; - matDict = PyDict_New(); - list = PyList_New(4); - - PyList_SET_ITEM(list, 0, Py_BuildValue("ss", "rawname", caste.rawname)); - PyList_SET_ITEM(list, 1, Py_BuildValue("ss", "singular", caste.singular)); - PyList_SET_ITEM(list, 2, Py_BuildValue("ss", "plural", caste.plural)); - PyList_SET_ITEM(list, 3, Py_BuildValue("ss", "adjective", caste.adjective)); + args = Py_BuildValue("ssss", caste.rawname, caste.singular, caste.plural, caste.adjective); - PyDict_MergeFromSeq2(matDict, list, 0); + casteObj = PyObject_CallObject(CreatureCaste_type, args); - Py_DECREF(list); + Py_DECREF(args); - return matDict; + return casteObj; } static PyObject* BuildCreatureCasteList(std::vector& castes) @@ -201,23 +183,17 @@ static PyObject* BuildCreatureCasteList(std::vector& castes) static PyObject* BuildCreatureTypeEx(t_creaturetype& creature) { - PyObject* c_type; - PyObject* list; + PyObject* cObj; + PyObject* args; - c_type = PyDict_New(); - list = PyList_New(6); + args = Py_BuildValue("sOiO", creature.rawname, BuildCreatureCasteList(creature.castes), creature.tile_character, \ + BuildTileColor(creature.tilecolor.fore, creature.tilecolor.back, creature.tilecolor.bright)); - PyList_SET_ITEM(list, 0, Py_BuildValue("ss", "rawname", creature.rawname)); - PyList_SET_ITEM(list, 1, Py_BuildValue("sO", "castes", BuildCreatureCasteList(creature.castes))); - PyList_SET_ITEM(list, 2, Py_BuildValue("si", "tile_character", creature.tile_character)); - PyList_SET_ITEM(list, 3, Py_BuildValue("si", "fore", creature.tilecolor.fore)); - PyList_SET_ITEM(list, 4, Py_BuildValue("si", "back", creature.tilecolor.back)); - PyList_SET_ITEM(list, 5, Py_BuildValue("si", "bright", creature.tilecolor.bright)); + cObj = PyObject_CallObject(CreatureTypeEx_type, args); - PyDict_MergeFromSeq2(c_type, list, 0); - Py_DECREF(list); + Py_DECREF(args); - return c_type; + return cObj; } static PyObject* BuildCreatureTypeExList(std::vector& creatures)