From 2b544ba2de9ae6d201171fb4d7ffecea9a387995 Mon Sep 17 00:00:00 2001 From: doomchild Date: Tue, 20 Apr 2010 09:19:23 -0500 Subject: [PATCH 01/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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 9bd7a6ea9badaa140de89abba451ca1108e460f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 23 Apr 2010 18:51:54 +0200 Subject: [PATCH 21/30] Fixes for DFError.h --- dfhack/include/DFError.h | 106 +++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 42 deletions(-) diff --git a/dfhack/include/DFError.h b/dfhack/include/DFError.h index 15086b9bb..34cd69839 100644 --- a/dfhack/include/DFError.h +++ b/dfhack/include/DFError.h @@ -78,14 +78,22 @@ namespace DFHack class DFHACK_EXPORT MissingMemoryDefinition : public std::exception { public: - MissingMemoryDefinition(const char* _type, const char* _key) : type(_type), key(_key) {} + MissingMemoryDefinition(const char* _type, const char* _key) : type(_type), key(_key) + { + std::stringstream s; + s << "memory definition missing: type " << type << " key " << key; + full = s.str(); + } // Used by functios using integer keys, such as getTrait MissingMemoryDefinition(const char* _type, uint32_t _key) : type(_type) { - // FIXME fancy hex printer goes here + std::stringstream s1; + s1 << _key; + key = s1.str(); + std::stringstream s; - s << _key; - key = s.str(); + s << "memory definition missing: type " << type << " key " << key; + full = s.str(); } virtual ~MissingMemoryDefinition() throw(){}; @@ -102,14 +110,13 @@ namespace DFHack // trait // traitname // labor + std::string full; const std::string type; std::string key; virtual const char* what() const throw() { - std::stringstream s; - s << "memory definition missing: type " << type << " key " << key; - return s.str().c_str(); + return full.c_str(); } }; @@ -117,9 +124,16 @@ namespace DFHack class DFHACK_EXPORT MemoryXmlParse : public std::exception { public: - MemoryXmlParse(const char* _desc, int _id, int _row, int _col) : - desc(_desc), id(_id), row(_row), col(_col) {} + MemoryXmlParse(const char* _desc, int _id, int _row, int _col) + :desc(_desc), id(_id), row(_row), col(_col) + { + std::stringstream s; + s << "error " << id << ": " << desc << ", at row " << row << " col " << col; + full = s.str(); + } + + std::string full; const std::string desc; const int id; const int row; @@ -129,26 +143,27 @@ namespace DFHack virtual const char* what() const throw() { - std::stringstream s; - s << "error " << id << ": " << desc << ", at row " << row << " col " << col; - return s.str().c_str(); + return full.c_str(); } }; class DFHACK_EXPORT MemoryXmlBadAttribute : public std::exception { public: - MemoryXmlBadAttribute(const char* _attr) : attr(_attr) {} - + MemoryXmlBadAttribute(const char* _attr) : attr(_attr) + { + std::stringstream s; + s << "attribute is either missing or invalid: " << attr; + full = s.str(); + } + std::string full; std::string attr; virtual ~MemoryXmlBadAttribute() throw(){}; virtual const char* what() const throw() { - std::stringstream s; - s << "attribute is either missing or invalid: " << attr; - return s.str().c_str(); + return full.c_str(); } }; @@ -168,46 +183,58 @@ namespace DFHack class DFHACK_EXPORT MemoryXmlNoDFExtractor : public std::exception { public: - MemoryXmlNoDFExtractor(const char* _name) : name(_name) {} + MemoryXmlNoDFExtractor(const char* _name) : name(_name) + { + std::stringstream s; + s << "DFExtractor != " << name; + full = s.str(); + } virtual ~MemoryXmlNoDFExtractor() throw(){}; std::string name; + std::string full; virtual const char* what() const throw() { - std::stringstream s; - s << "DFExtractor != " << name; - return s.str().c_str(); + return full.c_str(); } }; class DFHACK_EXPORT MemoryXmlUnderspecifiedEntry : public std::exception { public: - MemoryXmlUnderspecifiedEntry(const char * _where) : where(_where) {} + MemoryXmlUnderspecifiedEntry(const char * _where) : where(_where) + { + std::stringstream s; + s << "underspecified MemInfo entry, each entry needs to set both the name attribute and have a value. parent: " << where; + full = s.str(); + } virtual ~MemoryXmlUnderspecifiedEntry() throw(){}; std::string where; + std::string full; virtual const char* what() const throw() { - std::stringstream s; - s << "underspecified MemInfo entry, each entry needs to set both the name attribute and have a value. parent: " << where; - return s.str().c_str(); + return full.c_str(); } }; class DFHACK_EXPORT MemoryXmlUnknownType : public std::exception { public: - MemoryXmlUnknownType(const char* _type) : type(_type) {} + MemoryXmlUnknownType(const char* _type) : type(_type) + { + std::stringstream s; + s << "unknown MemInfo type: " << type; + full = s.str(); + } virtual ~MemoryXmlUnknownType() throw(){}; std::string type; + std::string full; virtual const char* what() const throw() { - std::stringstream s; - s << "unknown MemInfo type: " << type; - return s.str().c_str(); + return full.c_str(); } }; @@ -224,16 +251,20 @@ namespace DFHack class DFHACK_EXPORT SHMLockingError : public std::exception { public: - SHMLockingError(const char* _type) : type(_type) {} + SHMLockingError(const char* _type) : type(_type) + { + std::stringstream s; + s << "SHM locking error: " << type; + full = s.str(); + } virtual ~SHMLockingError() throw(){}; std::string type; + std::string full; virtual const char* what() const throw() { - std::stringstream s; - s << "SHM locking error: " << type; - return s.str().c_str(); + return full.c_str(); } }; class DFHACK_EXPORT MemoryAccessDenied : public std::exception @@ -241,9 +272,6 @@ namespace DFHack public: MemoryAccessDenied() {} virtual ~MemoryAccessDenied() throw(){}; - - std::string type; - virtual const char* what() const throw() { return "SHM ACCESS DENIED"; @@ -254,9 +282,6 @@ namespace DFHack public: SHMVersionMismatch() {} virtual ~SHMVersionMismatch() throw(){}; - - std::string type; - virtual const char* what() const throw() { return "SHM VERSION MISMATCH"; @@ -267,9 +292,6 @@ namespace DFHack public: SHMAttachFailure() {} virtual ~SHMAttachFailure() throw(){}; - - std::string type; - virtual const char* what() const throw() { return "SHM ATTACH FAILURE"; From 365c6dd0ed10272a488ce0e8c39585a966da573a Mon Sep 17 00:00:00 2001 From: doomchild Date: Fri, 23 Apr 2010 11:56:38 -0500 Subject: [PATCH 22/30] 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 23/30] 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 24/30] 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) From 815646982517f3b14466a76a8448e238901cdb81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sat, 24 Apr 2010 01:15:15 +0200 Subject: [PATCH 25/30] Global, local feature reading in Maps --- dfhack/include/modules/Maps.h | 45 +++++++- dfhack/modules/Maps.cpp | 195 ++++++++++++++++++++++++++++------ dfhack/shm/mod-maps.h | 15 ++- examples/veinlook.cpp | 4 +- tools/prospector.cpp | 101 ++++++++++++++++-- 5 files changed, 311 insertions(+), 49 deletions(-) diff --git a/dfhack/include/modules/Maps.h b/dfhack/include/modules/Maps.h index 883fa61ae..433937603 100644 --- a/dfhack/include/modules/Maps.h +++ b/dfhack/include/modules/Maps.h @@ -11,7 +11,37 @@ namespace DFHack /*************************************************************************** T Y P E S ***************************************************************************/ - + + enum e_feature + { + feature_Adamantine_Tube, + feature_Underworld, + // add stuff here, don't reorder or delete + feature_Other = 10000, + }; + union planecoord + { + uint32_t xy; + struct + { + uint16_t x; + uint16_t y; + } dim; + bool operator<(const planecoord &other) const + { + if(other.xy < xy) return true; + return false; + } + }; + struct t_feature + { + e_feature type; + int16_t main_material; + int32_t sub_material; + bool discovered; // maybe, placeholder. should work for rivers in adventure mode + uint32_t origin; + }; + struct t_vein { uint32_t vtable; @@ -52,7 +82,7 @@ namespace DFHack eSouthEast, eBiomeCount }; - + enum e_traffic { traffic_normal, @@ -210,6 +240,8 @@ namespace DFHack biome_indices40d biome_indices; uint32_t origin; // the address where it came from t_blockflags blockflags; + int16_t global_feature; + int16_t local_feature; } mapblock40d; /*************************************************************************** @@ -259,7 +291,14 @@ namespace DFHack } */ bool ReadGeology( std::vector < std::vector >& assign ); - + vector global_features; + // map between feature address and the read object + map local_feature_store; + // map between mangled coords and pointer to feature + + + bool ReadGlobalFeatures( std::vector & features); + bool ReadLocalFeatures( std::map > & local_features ); /* * BLOCK DATA */ diff --git a/dfhack/modules/Maps.cpp b/dfhack/modules/Maps.cpp index b562ed655..69e04ef72 100644 --- a/dfhack/modules/Maps.cpp +++ b/dfhack/modules/Maps.cpp @@ -54,9 +54,136 @@ struct Maps::Private Process * owner; bool Inited; bool Started; + + vector global_features; + // map between feature address and the read object + map local_feature_store; + // map between mangled coords and pointer to feature + map > local_features; + vector v_geology[eBiomeCount]; }; +bool Maps::ReadLocalFeatures( std::map > & local_features ) +{ + Process * p = d->owner; + memory_info * mem = p->getDescriptor(); + // deref pointer to the humongo-structure + uint32_t base = p->readDWord(mem->getAddress("local_feature_start_ptr")); + uint32_t sizeof_vec = mem->getHexValue("sizeof_vector"); + const uint32_t sizeof_elem = 16; + const uint32_t offset_elem = 4; + + local_features.clear(); + + for(uint blockX = 0; blockX < d->x_block_count; blockX ++) + for(uint blockY = 0; blockY < d->x_block_count; blockY ++) + { + //uint64_t block48_x = blockX / 3 + d->regionX; + //uint16_t region_x_plus8 = ( block48_x + 8 ) / 16; + + // region X coord offset by 8 big blocks (48x48 tiles) + uint16_t region_x_plus8 = ( blockX / 3 + d->regionX + 8 ) / 16; + + // plain region Y coord + uint64_t region_y_local = ( blockY / 3 + d->regionY ) / 16; + + // this is just a few pointers to arrays of 16B (4 DWORD) structs + uint32_t array_elem = p->readDWord(base + (region_x_plus8 / 16) * 4); + + // 16B structs, second DWORD of the struct is a pointer + uint32_t wtf = p->readDWord(array_elem + ( sizeof_elem * (region_y_local/16)) + offset_elem); + if(wtf) + { + // wtf + sizeof(vector) * crap; + uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_plus8 % 16) + (region_y_local % 16)); + DfVector p_features(p, feat_vector); + uint size = p_features.size(); + planecoord pc; + pc.dim.x = blockX; + pc.dim.y = blockY; + std::vector tempvec; + for(uint i = 0; i < size; i++) + { + uint32_t cur_ptr = p_features[i]; + + map ::iterator it; + it = d->local_feature_store.find(cur_ptr); + // do we already have the feature? + if(it != d->local_feature_store.end()) + { + // push pointer to existing feature + tempvec.push_back(&((*it).second)); + } + // no? + else + { + // create, add to store + t_feature tftemp; + tftemp.discovered = p->readDWord(cur_ptr + 4); + tftemp.origin = cur_ptr; + string name = p->readClassName(p->readDWord( cur_ptr )); + if(name == "feature_init_deep_special_tubest") + { + tftemp.main_material = p->readWord( cur_ptr + 0x30 ); + tftemp.sub_material = p->readDWord( cur_ptr + 0x34 ); + tftemp.type = feature_Adamantine_Tube; + } + else + { + tftemp.main_material = -1; + tftemp.sub_material = -1; + tftemp.type = feature_Other; + } + d->local_feature_store[cur_ptr] = tftemp; + // push pointer + tempvec.push_back(&(d->local_feature_store[cur_ptr])); + } + } + local_features[pc] = tempvec; + } + } + return true; +} + +bool Maps::ReadGlobalFeatures( std::vector & features) +{ + Process * p = d->owner; + memory_info * mem = p->getDescriptor(); + + uint32_t global_feature_vector = mem->getAddress("global_feature_vector"); + uint32_t global_feature_funcptr = mem->getOffset("global_feature_funcptr_"); + DfVector p_features (p,global_feature_vector); + + features.clear(); + uint size = p_features.size(); + features.reserve(size); + for(uint i = 0; i < size; i++) + { + t_feature temp; + uint32_t feat_ptr = p->readDWord(p_features[i] + global_feature_funcptr ); + temp.origin = feat_ptr; + temp.discovered = p->readDWord( feat_ptr + 4 ); // maybe, placeholder + + // FIXME: use the memory_info cache mechanisms + string name = p->readClassName(p->readDWord( feat_ptr)); + if(name == "feature_init_underworld_from_layerst") + { + temp.main_material = p->readWord( feat_ptr + 0x34 ); + temp.sub_material = p->readDWord( feat_ptr + 0x38 ); + temp.type = feature_Underworld; + } + else + { + temp.main_material = -1; + temp.sub_material = -1; + temp.type = feature_Other; + } + features.push_back(temp); + } + return true; +} + Maps::Maps(APIPrivate* _d) { d = new Private; @@ -77,9 +204,29 @@ Maps::Maps(APIPrivate* _d) off.occupancy_offset = mem->getOffset("map_data_occupancy"); off.biome_stuffs = mem->getOffset ("map_data_biome_stuffs"); off.veinvector = mem->getOffset ("map_data_vein_vector"); + off.local_feature_offset = mem->getOffset ("map_data_feature_local"); + off.global_feature_offset = mem->getOffset ("map_data_feature_global"); + off.temperature1_offset = mem->getOffset ("map_data_temperature1_offset"); off.temperature2_offset = mem->getOffset ("map_data_temperature2_offset"); - + off.region_x_offset = mem->getAddress ("region_x"); + off.region_y_offset = mem->getAddress ("region_y"); + off.region_z_offset = mem->getAddress ("region_z"); + + + off.world_regions = mem->getAddress ("ptr2_region_array"); + off.region_size = mem->getHexValue ("region_size"); + off.region_geo_index_offset = mem->getOffset ("region_geo_index_off"); + off.geolayer_geoblock_offset = mem->getOffset ("geolayer_geoblock_offset"); + off.world_geoblocks_vector = mem->getAddress ("geoblock_vector"); + off.type_inside_geolayer = mem->getOffset ("type_inside_geolayer"); + + off.world_size_x = mem->getAddress ("world_size_x"); + off.world_size_y = mem->getAddress ("world_size_y"); + + + + // these can fail and will be found when looking at the actual veins later // basically a cache off.vein_ice_vptr = 0; @@ -138,6 +285,11 @@ bool Maps::Start() //return false; } + // read position of the region inside DF world + p->readDWord (off.region_x_offset, d->regionX); + p->readDWord (off.region_y_offset, d->regionY); + p->readDWord (off.region_z_offset, d->regionZ); + // alloc array for pointers to all blocks d->block = new uint32_t[mx*my*mz]; uint32_t *temp_x = new uint32_t[mx]; @@ -219,6 +371,8 @@ bool Maps::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer p->read (addr + d->offsets.designation_offset, sizeof (buffer->designation), (uint8_t *) buffer->designation); p->read (addr + d->offsets.occupancy_offset, sizeof (buffer->occupancy), (uint8_t *) buffer->occupancy); p->read (addr + d->offsets.biome_stuffs, sizeof (biome_indices40d), (uint8_t *) buffer->biome_indices); + p->readWord(addr + d->offsets.global_feature_offset, (uint16_t&) buffer->global_feature); + p->readWord(addr + d->offsets.local_feature_offset, (uint16_t&)buffer->local_feature); buffer->origin = addr; uint32_t addr_of_struct = p->readDWord(addr); buffer->blockflags.whole = p->readDWord(addr_of_struct); @@ -557,45 +711,26 @@ bool Maps::ReadGeology (vector < vector >& assign) memory_info * minfo = d->d->offset_descriptor; Process *p = d->owner; // get needed addresses and offsets. Now this is what I call crazy. - int region_x_offset = minfo->getAddress ("region_x"); - int region_y_offset = minfo->getAddress ("region_y"); - int region_z_offset = minfo->getAddress ("region_z"); - int world_regions = minfo->getAddress ("ptr2_region_array"); - int region_size = minfo->getHexValue ("region_size"); - int region_geo_index_offset = minfo->getOffset ("region_geo_index_off"); - int world_geoblocks_vector = minfo->getAddress ("geoblock_vector"); - int world_size_x = minfo->getAddress ("world_size_x"); - int world_size_y = minfo->getAddress ("world_size_y"); - int geolayer_geoblock_offset = minfo->getOffset ("geolayer_geoblock_offset"); - - int type_inside_geolayer = minfo->getOffset ("type_inside_geolayer"); - - uint32_t regionX, regionY, regionZ; uint16_t worldSizeX, worldSizeY; - - // read position of the region inside DF world - p->readDWord (region_x_offset, regionX); - p->readDWord (region_y_offset, regionY); - p->readDWord (region_z_offset, regionZ); - + Server::Maps::maps_offsets &off = d->offsets; // get world size - p->readWord (world_size_x, worldSizeX); - p->readWord (world_size_y, worldSizeY); + p->readWord (off.world_size_x, worldSizeX); + p->readWord (off.world_size_y, worldSizeY); // get pointer to first part of 2d array of regions - uint32_t regions = p->readDWord (world_regions); + uint32_t regions = p->readDWord (off.world_regions); // read the geoblock vector - DfVector geoblocks (d->d->p, world_geoblocks_vector); + DfVector geoblocks (d->d->p, off.world_geoblocks_vector); // iterate over 8 surrounding regions + local region for (int i = eNorthWest; i < eBiomeCount; i++) { // check against worldmap boundaries, fix if needed - int bioRX = regionX / 16 + (i % 3) - 1; + int bioRX = d->regionX / 16 + (i % 3) - 1; if (bioRX < 0) bioRX = 0; if (bioRX >= worldSizeX) bioRX = worldSizeX - 1; - int bioRY = regionY / 16 + (i / 3) - 1; + int bioRY = d->regionY / 16 + (i / 3) - 1; if (bioRY < 0) bioRY = 0; if (bioRY >= worldSizeY) bioRY = worldSizeY - 1; @@ -607,7 +742,7 @@ bool Maps::ReadGeology (vector < vector >& assign) // get index into geoblock vector uint16_t geoindex; - p->readWord (geoX + bioRY*region_size + region_geo_index_offset, geoindex); + p->readWord (geoX + bioRY*off.region_size + off.region_geo_index_offset, geoindex); /// geology blocks are assigned to regions from a vector // get the geoblock from the geoblock vector using the geoindex @@ -616,7 +751,7 @@ bool Maps::ReadGeology (vector < vector >& assign) /// geology blocks have a vector of layer descriptors // get the vector with pointer to layers - DfVector geolayers (p, geoblock_off + geolayer_geoblock_offset); // let's hope + DfVector geolayers (p, geoblock_off + off.geolayer_geoblock_offset); // let's hope // make sure we don't load crap assert (geolayers.size() > 0 && geolayers.size() <= 16); @@ -628,7 +763,7 @@ bool Maps::ReadGeology (vector < vector >& assign) // read pointer to a layer uint32_t geol_offset = geolayers[j]; // read word at pointer + 2, store in our geology vectors - d->v_geology[i].push_back (p->readWord (geol_offset + type_inside_geolayer)); + d->v_geology[i].push_back (p->readWord (geol_offset + off.type_inside_geolayer)); } } assign.clear(); diff --git a/dfhack/shm/mod-maps.h b/dfhack/shm/mod-maps.h index 832c4e8c8..de3a9812f 100644 --- a/dfhack/shm/mod-maps.h +++ b/dfhack/shm/mod-maps.h @@ -42,6 +42,9 @@ typedef struct uint32_t x_count_offset;// = d->offset_descriptor->getAddress ("x_count"); uint32_t y_count_offset;// = d->offset_descriptor->getAddress ("y_count"); uint32_t z_count_offset;// = d->offset_descriptor->getAddress ("z_count"); + /* + Block + */ uint32_t tile_type_offset;// = d->offset_descriptor->getOffset ("type"); uint32_t designation_offset;// = d->offset_descriptor->getOffset ("designation"); uint32_t occupancy_offset;// = d->offset_descriptor->getOffset ("occupancy"); @@ -49,23 +52,27 @@ typedef struct uint32_t veinvector;// = d->offset_descriptor->getOffset ("v_vein"); uint32_t temperature1_offset; uint32_t temperature2_offset; + uint32_t global_feature_offset; + uint32_t local_feature_offset; + uint32_t vein_mineral_vptr; uint32_t vein_ice_vptr; uint32_t vein_spatter_vptr; /* GEOLOGY + */ uint32_t region_x_offset;// = minfo->getAddress ("region_x"); uint32_t region_y_offset;// = minfo->getAddress ("region_y"); uint32_t region_z_offset;// = minfo->getAddress ("region_z"); - uint32_t world_offset;// = minfo->getAddress ("world"); - uint32_t world_regions_offset;// = minfo->getOffset ("w_regions_arr"); + + uint32_t world_regions;// mem->getAddress ("ptr2_region_array"); uint32_t region_size;// = minfo->getHexValue ("region_size"); uint32_t region_geo_index_offset;// = minfo->getOffset ("region_geo_index_off"); - uint32_t world_geoblocks_offset;// = minfo->getOffset ("w_geoblocks"); + uint32_t world_geoblocks_vector;// = minfo->getOffset ("geoblock_vector"); uint32_t world_size_x;// = minfo->getOffset ("world_size_x"); uint32_t world_size_y;// = minfo->getOffset ("world_size_y"); uint32_t geolayer_geoblock_offset;// = minfo->getOffset ("geolayer_geoblock_offset"); - */ + uint32_t type_inside_geolayer;// = mem->getOffset ("type_inside_geolayer"); } maps_offsets; typedef struct diff --git a/examples/veinlook.cpp b/examples/veinlook.cpp index 5c084e211..7b78342d0 100644 --- a/examples/veinlook.cpp +++ b/examples/veinlook.cpp @@ -345,11 +345,11 @@ void do_features(Process* p, uint32_t blockaddr, uint32_t blockX, uint32_t block cout << name << endl; } */ - gotoxy(printX,printY+7); + gotoxy(printX,printY + 7); cprintf("feature %d addr: 0x%x\n", idx, p_features[idx]); if(idx >= p_features.size()) { - gotoxy(printX,printY+8); + gotoxy(printX,printY + 8); cprintf("ERROR, out of vector bounds."); } else diff --git a/tools/prospector.cpp b/tools/prospector.cpp index b64790793..2c5e686e1 100644 --- a/tools/prospector.cpp +++ b/tools/prospector.cpp @@ -49,12 +49,18 @@ int main (int argc, const char* argv[]) showhidden = true; #endif uint32_t x_max,y_max,z_max; + /* DFHack::tiletypes40d tiletypes; DFHack::designations40d designations; DFHack::biome_indices40d regionoffsets; + */ + DFHack::mapblock40d Block; map materials; materials.clear(); vector stonetypes; + vector global_features; + std::map > local_features; + vector< vector > layerassign; DFHack::API DF("Memory.xml"); @@ -86,6 +92,23 @@ int main (int argc, const char* argv[]) } Maps->getSize(x_max,y_max,z_max); + if(!Maps->ReadGlobalFeatures(global_features)) + { + cerr << "Can't get global features." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + + if(!Maps->ReadLocalFeatures(local_features)) + { + cerr << "Can't get local features." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } // get stone matgloss mapping if(!Mats->ReadInorganicMaterials(stonetypes)) { @@ -122,8 +145,9 @@ int main (int argc, const char* argv[]) continue; // read data - Maps->ReadTileTypes(x,y,z, &tiletypes); - Maps->ReadDesignations(x,y,z, &designations); + Maps->ReadBlock40d(x,y,z, &Block); + //Maps->ReadTileTypes(x,y,z, &tiletypes); + //Maps->ReadDesignations(x,y,z, &designations); memset(tempvein, -1, sizeof(tempvein)); veins.clear(); @@ -131,24 +155,24 @@ int main (int argc, const char* argv[]) if(showbaselayers) { - Maps->ReadRegionOffsets(x,y,z, ®ionoffsets); + //Maps->ReadRegionOffsets(x,y,z, ®ionoffsets); // get the layer materials for(uint32_t xx = 0;xx<16;xx++) { for (uint32_t yy = 0; yy< 16;yy++) { - uint8_t test = designations[xx][yy].bits.biome; + uint8_t test = Block.designation[xx][yy].bits.biome; if(test > maximum_regionoffset) maximum_regionoffset = test; - if( test >= sizeof(regionoffsets)) + if( test >= sizeof(Block.biome_indices)) { num_overflows++; continue; } tempvein[xx][yy] = layerassign - [regionoffsets[test]] - [designations[xx][yy].bits.geolayer_index]; + [Block.biome_indices[test]] + [Block.designation[xx][yy].bits.geolayer_index]; } } } @@ -172,6 +196,56 @@ int main (int argc, const char* argv[]) } } } + + // global feature overrides + int16_t idx = Block.global_feature; + if( idx != -1 && uint16_t(idx) < global_features.size() && global_features[idx].type == DFHack::feature_Underworld) + { + for(uint32_t xi = 0 ; xi< 16 ; xi++) for(uint32_t yi = 0 ; yi< 16 ; yi++) + { + if(Block.designation[xi][yi].bits.feature_global) + { + if(global_features[idx].main_material == 0) // stone + { + tempvein[xi][yi] = global_features[idx].sub_material; + } + else + { + tempvein[xi][yi] = -1; + } + } + } + } + + idx = Block.local_feature; + if( idx != -1 ) + { + DFHack::planecoord pc; + pc.dim.x = x; + pc.dim.y = y; + std::map >::iterator it; + it = local_features.find(pc); + if(it != local_features.end()) + { + std::vector& vectr = (*it).second; + if(uint16_t(idx) < vectr.size() && vectr[idx]->type == DFHack::feature_Adamantine_Tube) + for(uint32_t xi = 0 ; xi< 16 ; xi++) for(uint32_t yi = 0 ; yi< 16 ; yi++) + { + if(Block.designation[xi][yi].bits.feature_global) + { + if(vectr[idx]->main_material == 0) // stone + { + tempvein[xi][yi] = vectr[idx]->sub_material; + } + else + { + tempvein[xi][yi] = -1; + } + } + } + } + } + // count the material types for(uint32_t xi = 0 ; xi< 16 ; xi++) { @@ -179,7 +253,7 @@ int main (int argc, const char* argv[]) { // hidden tiles are ignored unless '-a' is provided on the command line // non-wall tiles are ignored - if( (designations[xi][yi].bits.hidden && !showhidden) || !DFHack::isWallTerrain(tiletypes[xi][yi])) + if( (Block.designation[xi][yi].bits.hidden && !showhidden) || !DFHack::isWallTerrain(Block.tiletypes[xi][yi])) continue; if(tempvein[xi][yi] < 0) continue; @@ -199,7 +273,7 @@ int main (int argc, const char* argv[]) } // print report cout << "Maximal regionoffset seen: " << maximum_regionoffset << "."; - if(maximum_regionoffset >= sizeof(regionoffsets) ) + if(maximum_regionoffset >= sizeof(Block.biome_indices) ) { cout << " This is above the regionoffsets array size!" << endl; cout << "Number of overflows: " << num_overflows; @@ -209,7 +283,14 @@ int main (int argc, const char* argv[]) map::iterator p; for(p = materials.begin(); p != materials.end(); p++) { - cout << stonetypes[p->first].id << " : " << p->second << endl; + if(p->first == -1) + { + cout << "Non-stone" << " : " << p->second << endl; + } + else + { + cout << stonetypes[p->first].id << " : " << p->second << endl; + } } DF.Detach(); #ifndef LINUX_BUILD From 340b0cf91c95e882a316d0b5ce23f074b6601ffc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sat, 24 Apr 2010 01:50:04 +0200 Subject: [PATCH 26/30] Veinlook uses Map features --- dfhack/include/modules/Maps.h | 2 +- dfhack/modules/Maps.cpp | 250 +++++++++++++++++----------------- examples/veinlook.cpp | 98 +++++++++++-- 3 files changed, 215 insertions(+), 135 deletions(-) diff --git a/dfhack/include/modules/Maps.h b/dfhack/include/modules/Maps.h index 433937603..ddeac55de 100644 --- a/dfhack/include/modules/Maps.h +++ b/dfhack/include/modules/Maps.h @@ -38,7 +38,7 @@ namespace DFHack e_feature type; int16_t main_material; int32_t sub_material; - bool discovered; // maybe, placeholder. should work for rivers in adventure mode + bool discovered; // placeholder. uint32_t origin; }; diff --git a/dfhack/modules/Maps.cpp b/dfhack/modules/Maps.cpp index 69e04ef72..64041b9e7 100644 --- a/dfhack/modules/Maps.cpp +++ b/dfhack/modules/Maps.cpp @@ -55,135 +55,12 @@ struct Maps::Private bool Inited; bool Started; - vector global_features; // map between feature address and the read object map local_feature_store; - // map between mangled coords and pointer to feature - map > local_features; vector v_geology[eBiomeCount]; }; -bool Maps::ReadLocalFeatures( std::map > & local_features ) -{ - Process * p = d->owner; - memory_info * mem = p->getDescriptor(); - // deref pointer to the humongo-structure - uint32_t base = p->readDWord(mem->getAddress("local_feature_start_ptr")); - uint32_t sizeof_vec = mem->getHexValue("sizeof_vector"); - const uint32_t sizeof_elem = 16; - const uint32_t offset_elem = 4; - - local_features.clear(); - - for(uint blockX = 0; blockX < d->x_block_count; blockX ++) - for(uint blockY = 0; blockY < d->x_block_count; blockY ++) - { - //uint64_t block48_x = blockX / 3 + d->regionX; - //uint16_t region_x_plus8 = ( block48_x + 8 ) / 16; - - // region X coord offset by 8 big blocks (48x48 tiles) - uint16_t region_x_plus8 = ( blockX / 3 + d->regionX + 8 ) / 16; - - // plain region Y coord - uint64_t region_y_local = ( blockY / 3 + d->regionY ) / 16; - - // this is just a few pointers to arrays of 16B (4 DWORD) structs - uint32_t array_elem = p->readDWord(base + (region_x_plus8 / 16) * 4); - - // 16B structs, second DWORD of the struct is a pointer - uint32_t wtf = p->readDWord(array_elem + ( sizeof_elem * (region_y_local/16)) + offset_elem); - if(wtf) - { - // wtf + sizeof(vector) * crap; - uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_plus8 % 16) + (region_y_local % 16)); - DfVector p_features(p, feat_vector); - uint size = p_features.size(); - planecoord pc; - pc.dim.x = blockX; - pc.dim.y = blockY; - std::vector tempvec; - for(uint i = 0; i < size; i++) - { - uint32_t cur_ptr = p_features[i]; - - map ::iterator it; - it = d->local_feature_store.find(cur_ptr); - // do we already have the feature? - if(it != d->local_feature_store.end()) - { - // push pointer to existing feature - tempvec.push_back(&((*it).second)); - } - // no? - else - { - // create, add to store - t_feature tftemp; - tftemp.discovered = p->readDWord(cur_ptr + 4); - tftemp.origin = cur_ptr; - string name = p->readClassName(p->readDWord( cur_ptr )); - if(name == "feature_init_deep_special_tubest") - { - tftemp.main_material = p->readWord( cur_ptr + 0x30 ); - tftemp.sub_material = p->readDWord( cur_ptr + 0x34 ); - tftemp.type = feature_Adamantine_Tube; - } - else - { - tftemp.main_material = -1; - tftemp.sub_material = -1; - tftemp.type = feature_Other; - } - d->local_feature_store[cur_ptr] = tftemp; - // push pointer - tempvec.push_back(&(d->local_feature_store[cur_ptr])); - } - } - local_features[pc] = tempvec; - } - } - return true; -} - -bool Maps::ReadGlobalFeatures( std::vector & features) -{ - Process * p = d->owner; - memory_info * mem = p->getDescriptor(); - - uint32_t global_feature_vector = mem->getAddress("global_feature_vector"); - uint32_t global_feature_funcptr = mem->getOffset("global_feature_funcptr_"); - DfVector p_features (p,global_feature_vector); - - features.clear(); - uint size = p_features.size(); - features.reserve(size); - for(uint i = 0; i < size; i++) - { - t_feature temp; - uint32_t feat_ptr = p->readDWord(p_features[i] + global_feature_funcptr ); - temp.origin = feat_ptr; - temp.discovered = p->readDWord( feat_ptr + 4 ); // maybe, placeholder - - // FIXME: use the memory_info cache mechanisms - string name = p->readClassName(p->readDWord( feat_ptr)); - if(name == "feature_init_underworld_from_layerst") - { - temp.main_material = p->readWord( feat_ptr + 0x34 ); - temp.sub_material = p->readDWord( feat_ptr + 0x38 ); - temp.type = feature_Underworld; - } - else - { - temp.main_material = -1; - temp.sub_material = -1; - temp.type = feature_Other; - } - features.push_back(temp); - } - return true; -} - Maps::Maps(APIPrivate* _d) { d = new Private; @@ -320,8 +197,10 @@ void Maps::getSize (uint32_t& x, uint32_t& y, uint32_t& z) z = d->z_block_count; } +// invalidates local and global features! bool Maps::Finish() { + d->local_feature_store.clear(); if (d->block != NULL) { delete [] d->block; @@ -774,3 +653,128 @@ bool Maps::ReadGeology (vector < vector >& assign) } return true; } + +bool Maps::ReadLocalFeatures( std::map > & local_features ) +{ + Process * p = d->owner; + memory_info * mem = p->getDescriptor(); + // deref pointer to the humongo-structure + uint32_t base = p->readDWord(mem->getAddress("local_feature_start_ptr")); + uint32_t sizeof_vec = mem->getHexValue("sizeof_vector"); + const uint32_t sizeof_elem = 16; + const uint32_t offset_elem = 4; + const uint32_t main_mat_offset = 0x30; + const uint32_t sub_mat_offset = 0x34; + + local_features.clear(); + + for(uint blockX = 0; blockX < d->x_block_count; blockX ++) + for(uint blockY = 0; blockY < d->x_block_count; blockY ++) + { + //uint64_t block48_x = blockX / 3 + d->regionX; + //uint16_t region_x_plus8 = ( block48_x + 8 ) / 16; + + // region X coord offset by 8 big blocks (48x48 tiles) + uint16_t region_x_plus8 = ( blockX / 3 + d->regionX + 8 ) / 16; + + // plain region Y coord + uint64_t region_y_local = ( blockY / 3 + d->regionY ) / 16; + + // this is just a few pointers to arrays of 16B (4 DWORD) structs + uint32_t array_elem = p->readDWord(base + (region_x_plus8 / 16) * 4); + + // 16B structs, second DWORD of the struct is a pointer + uint32_t wtf = p->readDWord(array_elem + ( sizeof_elem * (region_y_local/16)) + offset_elem); + if(wtf) + { + // wtf + sizeof(vector) * crap; + uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_plus8 % 16) + (region_y_local % 16)); + DfVector p_features(p, feat_vector); + uint size = p_features.size(); + planecoord pc; + pc.dim.x = blockX; + pc.dim.y = blockY; + std::vector tempvec; + for(uint i = 0; i < size; i++) + { + uint32_t cur_ptr = p_features[i]; + + map ::iterator it; + it = d->local_feature_store.find(cur_ptr); + // do we already have the feature? + if(it != d->local_feature_store.end()) + { + // push pointer to existing feature + tempvec.push_back(&((*it).second)); + } + // no? + else + { + // create, add to store + t_feature tftemp; + tftemp.discovered = false; //= p->readDWord(cur_ptr + 4); + tftemp.origin = cur_ptr; + string name = p->readClassName(p->readDWord( cur_ptr )); + if(name == "feature_init_deep_special_tubest") + { + tftemp.main_material = p->readWord( cur_ptr + main_mat_offset ); + tftemp.sub_material = p->readDWord( cur_ptr + sub_mat_offset ); + tftemp.type = feature_Adamantine_Tube; + } + else + { + tftemp.main_material = -1; + tftemp.sub_material = -1; + tftemp.type = feature_Other; + } + d->local_feature_store[cur_ptr] = tftemp; + // push pointer + tempvec.push_back(&(d->local_feature_store[cur_ptr])); + } + } + local_features[pc] = tempvec; + } + } + return true; +} + +bool Maps::ReadGlobalFeatures( std::vector & features) +{ + Process * p = d->owner; + memory_info * mem = p->getDescriptor(); + + uint32_t global_feature_vector = mem->getAddress("global_feature_vector"); + uint32_t global_feature_funcptr = mem->getOffset("global_feature_funcptr_"); + const uint32_t main_mat_offset = 0x34; + const uint32_t sub_mat_offset = 0x38; + DfVector p_features (p,global_feature_vector); + + features.clear(); + uint size = p_features.size(); + features.reserve(size); + for(uint i = 0; i < size; i++) + { + t_feature temp; + uint32_t feat_ptr = p->readDWord(p_features[i] + global_feature_funcptr ); + temp.origin = feat_ptr; + //temp.discovered = p->readDWord( feat_ptr + 4 ); // maybe, placeholder + temp.discovered = false; + + // FIXME: use the memory_info cache mechanisms + string name = p->readClassName(p->readDWord( feat_ptr)); + if(name == "feature_init_underworld_from_layerst") + { + temp.main_material = p->readWord( feat_ptr + main_mat_offset ); + temp.sub_material = p->readDWord( feat_ptr + sub_mat_offset ); + temp.type = feature_Underworld; + } + else + { + temp.main_material = -1; + temp.sub_material = -1; + temp.type = feature_Other; + } + features.push_back(temp); + } + return true; +} \ No newline at end of file diff --git a/examples/veinlook.cpp b/examples/veinlook.cpp index 7b78342d0..7dfd992dd 100644 --- a/examples/veinlook.cpp +++ b/examples/veinlook.cpp @@ -281,6 +281,7 @@ void hexdump (DFHack::API& DF, uint32_t address, uint32_t length, int filenum) // blockaddr = address of the block // blockX, blockY = local map X and Y coords in 16x16 of the block // printX, printX = where to print stuff on the screen +/* void do_features(Process* p, uint32_t blockaddr, uint32_t blockX, uint32_t blockY, int printX, int printY, vector &stonetypes) { memory_info* mem = p->getDescriptor(); @@ -337,14 +338,6 @@ void do_features(Process* p, uint32_t blockaddr, uint32_t blockX, uint32_t block gotoxy(printX,printY+6); cprintf("local feature vector: 0x%x\n", feat_vector); DfVector p_features(p, feat_vector); - /* - for(int k = 0 ; k < p_features.size();k++) - { - printf("feature %d addr: 0x%x\n", k, p_features[k]); - string name = p->readClassName(p->readDWord( p_features[k] )); - cout << name << endl; - } - */ gotoxy(printX,printY + 7); cprintf("feature %d addr: 0x%x\n", idx, p_features[idx]); if(idx >= p_features.size()) @@ -418,8 +411,91 @@ void do_features(Process* p, uint32_t blockaddr, uint32_t blockX, uint32_t block } } } - - +*/ +void do_features(API& DF, mapblock40d * block, uint32_t blockX, uint32_t blockY, int printX, int printY, vector &stonetypes) +{ + Maps * Maps = DF.getMaps(); + Process * p = DF.getProcess(); + if(!Maps) + return; + vector global_features; + std::map > local_features; + if(!Maps->ReadGlobalFeatures(global_features)) + return; + if(!Maps->ReadLocalFeatures(local_features)) + return; + + planecoord pc; + pc.dim.x = blockX; + pc.dim.y = blockY; + int16_t idx =block->global_feature; + if(idx != -1) + { + t_feature &ftr =global_features[idx]; + gotoxy(printX,printY); + cprintf( "global feature present: %d @ 0x%x\n", idx, ftr.origin); + if(ftr.discovered ) + { + gotoxy(printX,printY+1); + cprintf("You've discovered it already!"); + } + if(ftr.type == feature_Underworld) + { + char * matname = "unknown"; + // is stone? + if(ftr.main_material == 0) + { + matname = stonetypes[ftr.sub_material].id; + } + gotoxy(printX,printY+2); + cprintf("Underworld, material %d/%d : %s", ftr.main_material, ftr.sub_material, matname); + } + else + { + gotoxy(printX,printY+2); + string name = p->readClassName(p->readDWord( ftr.origin )); + cprintf("%s", name.c_str()); + } + } + idx =block->local_feature; + if(idx != -1) + { + vector &ftrv = local_features[pc]; + if(idx < ftrv.size()) + { + t_feature & ftr = *ftrv[idx]; + gotoxy(printX,printY + 4); + cprintf( "local feature present: %d @ 0x%x\n", idx, ftr.origin); + if(ftr.discovered ) + { + gotoxy(printX,printY+ 5); + cprintf("You've discovered it already!"); + } + if(ftr.type == feature_Adamantine_Tube) + { + char * matname = "unknown"; + // is stone? + if(ftr.main_material == 0) + { + matname = stonetypes[ftr.sub_material].id; + } + gotoxy(printX,printY+6); + cprintf("Underworld, material %d/%d : %s", ftr.main_material, ftr.sub_material, matname); + } + else + { + gotoxy(printX,printY+6); + string name = p->readClassName(p->readDWord( ftr.origin )); + cprintf("%s", name.c_str()); + } + } + else + { + gotoxy(printX,printY + 4); + cprintf( "local feature vector overflow: %d", idx); + } + } +} main(int argc, char *argv[]) { @@ -677,7 +753,7 @@ main(int argc, char *argv[]) // extra processing of the block in the middle if(i == 0 && j == 0) { - do_features(p, Block->origin, cursorX, cursorY, 50,10, stonetypes); + do_features(DF, Block, cursorX, cursorY, 50,10, stonetypes); // read veins Maps->ReadVeins(cursorX+i,cursorY+j,cursorZ,&veinVector,&IceVeinVector,&splatter); From abaee5ce45a6da2b5aad708ab653ddf977cee8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sat, 24 Apr 2010 16:36:41 +0200 Subject: [PATCH 27/30] uint -> uint32_t, removed 8 unit offset from the local feature dump method --- dfhack/DFMemInfo.cpp | 2 +- dfhack/modules/Maps.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dfhack/DFMemInfo.cpp b/dfhack/DFMemInfo.cpp index 7f0d9ef0a..549842c4b 100644 --- a/dfhack/DFMemInfo.cpp +++ b/dfhack/DFMemInfo.cpp @@ -227,7 +227,7 @@ void memory_info::setProfession (const string & key, const string & value) uint32_t keyInt = strtol(key.c_str(), NULL, 10); if(d->professions.size() <= keyInt) { - d->professions.resize(keyInt+1); + d->professions.resize(keyInt+1,""); } d->professions[keyInt] = value; } diff --git a/dfhack/modules/Maps.cpp b/dfhack/modules/Maps.cpp index 64041b9e7..7d4efbd4e 100644 --- a/dfhack/modules/Maps.cpp +++ b/dfhack/modules/Maps.cpp @@ -668,14 +668,14 @@ bool Maps::ReadLocalFeatures( std::map > & local_features.clear(); - for(uint blockX = 0; blockX < d->x_block_count; blockX ++) - for(uint blockY = 0; blockY < d->x_block_count; blockY ++) + for(uint32_t blockX = 0; blockX < d->x_block_count; blockX ++) + for(uint32_t blockY = 0; blockY < d->x_block_count; blockY ++) { //uint64_t block48_x = blockX / 3 + d->regionX; //uint16_t region_x_plus8 = ( block48_x + 8 ) / 16; // region X coord offset by 8 big blocks (48x48 tiles) - uint16_t region_x_plus8 = ( blockX / 3 + d->regionX + 8 ) / 16; + uint16_t region_x_plus8 = ( blockX / 3 + d->regionX /*+ 8*/ ) / 16; // plain region Y coord uint64_t region_y_local = ( blockY / 3 + d->regionY ) / 16; @@ -690,12 +690,12 @@ bool Maps::ReadLocalFeatures( std::map > & // wtf + sizeof(vector) * crap; uint32_t feat_vector = wtf + sizeof_vec * (16 * (region_x_plus8 % 16) + (region_y_local % 16)); DfVector p_features(p, feat_vector); - uint size = p_features.size(); + uint32_t size = p_features.size(); planecoord pc; pc.dim.x = blockX; pc.dim.y = blockY; std::vector tempvec; - for(uint i = 0; i < size; i++) + for(uint32_t i = 0; i < size; i++) { uint32_t cur_ptr = p_features[i]; @@ -750,9 +750,9 @@ bool Maps::ReadGlobalFeatures( std::vector & features) DfVector p_features (p,global_feature_vector); features.clear(); - uint size = p_features.size(); + uint32_t size = p_features.size(); features.reserve(size); - for(uint i = 0; i < size; i++) + for(uint32_t i = 0; i < size; i++) { t_feature temp; uint32_t feat_ptr = p->readDWord(p_features[i] + global_feature_funcptr ); From 6268d6622144ff4d7fb38a6e76de9205e56a23c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 25 Apr 2010 11:05:11 +0200 Subject: [PATCH 28/30] API::Attach doesn't trash the current attached process and its modules. --- dfhack/DFHackAPI.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dfhack/DFHackAPI.cpp b/dfhack/DFHackAPI.cpp index b023ccbd6..995a7326c 100644 --- a/dfhack/DFHackAPI.cpp +++ b/dfhack/DFHackAPI.cpp @@ -66,6 +66,10 @@ API::~API() bool API::Attach() { + if(d->p != NULL) + { + return d->p->suspend(); + } // detach all processes, destroy manager if (d->pm == 0) { From 78dbe8cca69d90bb475b66aa0aba466caa63fe68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 25 Apr 2010 20:52:57 +0200 Subject: [PATCH 29/30] Fixes for Maps, local features still problematic --- dfhack/modules/Maps.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/dfhack/modules/Maps.cpp b/dfhack/modules/Maps.cpp index 7d4efbd4e..f2e6df197 100644 --- a/dfhack/modules/Maps.cpp +++ b/dfhack/modules/Maps.cpp @@ -186,6 +186,7 @@ bool Maps::Start() } delete [] temp_x; delete [] temp_y; + d->Started = true; return true; } @@ -656,6 +657,10 @@ bool Maps::ReadGeology (vector < vector >& assign) bool Maps::ReadLocalFeatures( std::map > & local_features ) { + // can't be used without a map! + if(!d->block) + return false; + Process * p = d->owner; memory_info * mem = p->getDescriptor(); // deref pointer to the humongo-structure @@ -675,10 +680,12 @@ bool Maps::ReadLocalFeatures( std::map > & //uint16_t region_x_plus8 = ( block48_x + 8 ) / 16; // region X coord offset by 8 big blocks (48x48 tiles) - uint16_t region_x_plus8 = ( blockX / 3 + d->regionX /*+ 8*/ ) / 16; - + uint16_t region_x_plus8 = ( (blockX / 3 ) + d->regionX /*+ 8*/ ) / 16; + //((BYTE4(region_x_local) & 0xF) + (_DWORD)region_x_local) >> 4; + //int16_t region_x_local = (blockX / 3) + d->regionX; + //int16_t region_x_plus8 = ((region_x_local & 0xF) + region_x_local) >> 4; // plain region Y coord - uint64_t region_y_local = ( blockY / 3 + d->regionY ) / 16; + uint64_t region_y_local = ( (blockY / 3) + d->regionY ) / 16; // this is just a few pointers to arrays of 16B (4 DWORD) structs uint32_t array_elem = p->readDWord(base + (region_x_plus8 / 16) * 4); @@ -740,6 +747,10 @@ bool Maps::ReadLocalFeatures( std::map > & bool Maps::ReadGlobalFeatures( std::vector & features) { + // can't be used without a map! + if(!d->block) + return false; + Process * p = d->owner; memory_info * mem = p->getDescriptor(); From 51f6dbd981862715e7008bd8d07007870cc14b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 26 Apr 2010 00:51:45 +0200 Subject: [PATCH 30/30] Fix local features in prospector. --- tools/prospector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/prospector.cpp b/tools/prospector.cpp index 2c5e686e1..73ac9bcd2 100644 --- a/tools/prospector.cpp +++ b/tools/prospector.cpp @@ -231,7 +231,7 @@ int main (int argc, const char* argv[]) if(uint16_t(idx) < vectr.size() && vectr[idx]->type == DFHack::feature_Adamantine_Tube) for(uint32_t xi = 0 ; xi< 16 ; xi++) for(uint32_t yi = 0 ; yi< 16 ; yi++) { - if(Block.designation[xi][yi].bits.feature_global) + if(Block.designation[xi][yi].bits.feature_local && DFHack::isWallTerrain(Block.tiletypes[xi][yi])) { if(vectr[idx]->main_material == 0) // stone {