develop
Petr Mrázek 2010-04-25 22:24:39 +02:00
commit d03cb827f3
22 changed files with 817 additions and 138 deletions

@ -29,6 +29,7 @@ distribution.
#include <string>
#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 */

@ -26,6 +26,12 @@ distribution.
#define __DFBUILDINGS__
#include "Python.h"
#include <map>
#include <string>
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<uint32_t, string> bTypes;
std::map<uint32_t, string>::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
};

@ -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 */

@ -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
};

@ -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 */

@ -28,24 +28,86 @@ distribution.
#include "Python.h"
#include <stdio.h>
#include <string.h>
#include <vector>
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

@ -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");
}
}

@ -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 */

@ -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<t_matgloss> & 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<t_descriptor_color>& colors)
{
PyObject* colorList;
std::vector<t_descriptor_color>::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<t_creaturecaste>& castes)
{
PyObject* casteList;
std::vector<t_creaturecaste>::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<t_creaturetype>& creatures)
{
PyObject* creatureList;
std::vector<t_creaturetype>::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<DFHack::t_creaturetype> 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<DFHack::t_descriptor_color> 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
};

@ -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 */

@ -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

@ -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()

@ -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"

@ -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()

@ -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()

@ -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()

@ -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()

@ -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)

@ -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();

@ -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

@ -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

@ -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"])