diff --git a/dfhack/python/DF_API.cpp b/dfhack/python/DF_API.cpp index 0f227f55f..f80534353 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,11 @@ struct DF_API PyObject* construction; PyObject* vegetation; PyObject* gui; + + PyObject* map_type; + PyObject* vegetation_type; + PyObject* gui_type; + DFHack::API* api_Ptr; }; @@ -87,6 +93,10 @@ 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; + self->vegetation_type = (PyObject*)&DF_Vegetation_type; + self->gui_type = (PyObject*)&DF_GUI_type; + if(!PyArg_ParseTuple(args, "s", &memFileString)) return -1; @@ -310,7 +320,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) { @@ -397,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) { @@ -426,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) { @@ -446,6 +456,81 @@ 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 -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 -1; + } + + self->map_type = 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 -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 -1; + } + + 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 -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 -1; + } + + self->gui_type = value; + + return 0; +} + static PyGetSetDef DF_API_getterSetters[] = { {"is_attached", (getter)DF_API_getIsAttached, NULL, "is_attached", NULL}, @@ -459,6 +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_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 }; @@ -565,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*/ @@ -584,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 */ diff --git a/dfhack/python/DF_Buildings.cpp b/dfhack/python/DF_Buildings.cpp index 1028074f2..00bfe146e 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" @@ -38,22 +44,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 +175,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.c_str()); + + 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_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_CreatureManager.cpp b/dfhack/python/DF_CreatureManager.cpp index 43e08f230..c9b4136c8 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" @@ -155,12 +156,76 @@ 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 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 }; diff --git a/dfhack/python/DF_GUI.cpp b/dfhack/python/DF_GUI.cpp index 015d115b9..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; @@ -163,7 +164,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 +183,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_Helpers.cpp b/dfhack/python/DF_Helpers.cpp index 9dce8c737..6c4b580cd 100644 --- a/dfhack/python/DF_Helpers.cpp +++ b/dfhack/python/DF_Helpers.cpp @@ -28,24 +28,86 @@ 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); } +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); + 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) @@ -65,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) @@ -97,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 = Py_BuildValue("III", note.x, note.y, note.z); + position = PyObject_CallObject(Position3D_type, args); - args = Py_BuildValue("cIIsO", note.symbol, note.foreground, note.background, name, position); + Py_DECREF(args); + + args = Py_BuildValue("cIIsO", note.symbol, note.foreground, note.background, note.name, position); noteObj = PyObject_CallObject(Note_type, args); + Py_DECREF(args); + return noteObj; } @@ -235,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; - setDict = PyDict_New(); + args = Py_BuildValue("ii", settlement.world_x, settlement.world_y); - temp = PyInt_FromLong(settlement.origin); - DICTADD(setDict, "origin", temp); + world_pos = PyObject_CallObject(Position2D_type, args); - temp = BuildName(settlement.name); - DICTADD(setDict, "name", temp); + Py_DECREF(args); - temp = Py_BuildValue("ii", settlement.world_x, settlement.world_y); - DICTADD(setDict, "world_pos", temp); + args = Py_BuildValue("iiii", settlement.local_x1, settlement.local_y1, settlement.local_x2, settlement.local_y2); - local_pos1 = Py_BuildValue("ii", settlement.local_x1, settlement.local_y1); - local_pos2 = Py_BuildValue("ii", settlement.local_x2, settlement.local_y2); + local_pos = PyObject_CallObject(Rectangle_type, args); - temp = Py_BuildValue("OO", local_pos1, local_pos2); - DICTADD(setDict, "local_pos", temp); + Py_DECREF(args); - return setDict; + args = Py_BuildValue("iOOO", settlement.origin, BuildName(settlement.name), world_pos, local_pos); + + 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(); @@ -307,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_Maps.cpp b/dfhack/python/DF_Maps.cpp index 788130444..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" @@ -301,10 +302,10 @@ 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)); + des[i][j].whole = (uint32_t)PyInt_AS_LONG(PyList_GET_ITEM(innerList, j)); } } @@ -591,11 +592,11 @@ static PyObject* DF_Map_WriteDesignations(DF_Map* self, PyObject* args) if(!PyArg_ParseTuple(args, "IIIO", &x, &y, &z, &desList)) return NULL; - designations40d des; + DFHack::designations40d writeDes; - 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 +818,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 +837,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 */ diff --git a/dfhack/python/DF_Material.cpp b/dfhack/python/DF_Material.cpp index 6cc02cd18..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,48 +46,16 @@ struct DF_Material static PyObject* BuildMatgloss(t_matgloss& matgloss) { - PyObject* matDict; - PyObject* temp; - - matDict = PyDict_New(); - - 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); - - temp = PyInt_FromLong(matgloss.back); + PyObject* matObj; + PyObject* args; - PyDict_SetItemString(matDict, "back", temp); + args = Py_BuildValue("siiis", matgloss.id, matgloss.fore, matgloss.back, matgloss.bright, matgloss.name); - Py_DECREF(temp); + matObj = PyObject_CallObject(Matgloss_type, args); - temp = PyInt_FromLong(matgloss.bright); + Py_DECREF(args); - 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); - - return matDict; + return matObj; } static PyObject* BuildMatglossPlant(t_matglossPlant& matgloss) @@ -145,6 +115,106 @@ static PyObject* BuildMatglossList(std::vector & matVec) return matList; } +static PyObject* BuildDescriptorColor(t_descriptor_color& color) +{ + PyObject* descObj; + PyObject* args; + + args = Py_BuildValue("sfffs", color.id, color.r, color.v, color.b, color.name); + + descObj = PyObject_CallObject(DescriptorColor_type, args); + + Py_DECREF(args); + + return descObj; +} + +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* casteObj; + PyObject* args; + + args = Py_BuildValue("ssss", caste.rawname, caste.singular, caste.plural, caste.adjective); + + casteObj = PyObject_CallObject(CreatureCaste_type, args); + + Py_DECREF(args); + + return casteObj; +} + +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* cObj; + PyObject* args; + + args = Py_BuildValue("sOiO", creature.rawname, BuildCreatureCasteList(creature.castes), creature.tile_character, \ + BuildTileColor(creature.tilecolor.fore, creature.tilecolor.back, creature.tilecolor.bright)); + + cObj = PyObject_CallObject(CreatureTypeEx_type, args); + + Py_DECREF(args); + + return cObj; +} + +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 +336,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 +373,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 }; diff --git a/dfhack/python/DF_Translate.cpp b/dfhack/python/DF_Translate.cpp index 274e5ccdd..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; @@ -237,7 +239,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 +258,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/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 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() diff --git a/dfhack/python/pydfapi.py b/dfhack/python/pydfapi.py new file mode 100644 index 000000000..76aea332c --- /dev/null +++ b/dfhack/python/pydfapi.py @@ -0,0 +1,21 @@ +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): + _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 diff --git a/dfhack/python/pydfhack.cpp b/dfhack/python/pydfhack.cpp index 323c2ad70..b01adad1c 100644 --- a/dfhack/python/pydfhack.cpp +++ b/dfhack/python/pydfhack.cpp @@ -117,18 +117,18 @@ 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, "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, "_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); + 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(); diff --git a/dfhack/python/pydfhackflags.py b/dfhack/python/pydfhackflags.py index ee0399d1c..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): @@ -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 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 diff --git a/dfhack/python/setup.py b/dfhack/python/setup.py index f42072986..a115d1003 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=["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"], libraries=["libdfhack"], export_symbols=["initpydfhack", "ReadRaw", "WriteRaw"])