develop
Petr Mrázek 2010-05-06 22:41:11 +02:00
commit c32d9d6d8e
36 changed files with 2493 additions and 56 deletions

7
.gitignore vendored

@ -21,3 +21,10 @@ build*/
#fake curses header
examples/fake-curses.h
# Python binding binaries
*.pyc
dfhack/python/pydfhack/_pydfhack.so
dfhack/python/PyDFHack.egg-info
dfhack/python/build
dfhack/python/dist

@ -46,6 +46,8 @@ modules/Buildings.cpp
modules/Constructions.cpp
modules/Position_C.cpp
modules/Gui_C.cpp
modules/Materials_C.cpp
)
SET(PROJECT_HDRS_LINUX

@ -49,11 +49,14 @@ DFHackObject* API_Alloc(const char* path_to_xml)
}
//FIXME: X:\dfhack\DFHackAPI_C.cpp:56: warning: deleting `DFHackObject* ' is undefined
//DC: Yeah, I forgot that trying to delete a void pointer might be a bad idea. This works now.
void API_Free(DFHackObject* api)
{
if(api != NULL)
{
delete api;
DFHack::API* a = (DFHack::API*)api;
delete a;
api = NULL;
}
}
@ -137,6 +140,128 @@ int API_AsyncSuspend(DFHackObject* api)
return -1;
}
//module getters
DFHackObject* API_getMemoryInfo(DFHackObject* api)
{
if(api != NULL)
{
return (DFHackObject*)((DFHack::API*)api)->getMemoryInfo();
}
return NULL;
}
DFHackObject* API_getProcess(DFHackObject* api)
{
if(api != NULL)
{
return (DFHackObject*)((DFHack::API*)api)->getProcess();
}
return NULL;
}
DFHackObject* API_getWindow(DFHackObject* api)
{
if(api != NULL)
{
return (DFHackObject*)((DFHack::API*)api)->getWindow();
}
return NULL;
}
DFHackObject* API_getCreatures(DFHackObject* api)
{
if(api != NULL)
{
return (DFHackObject*)((DFHack::API*)api)->getCreatures();
}
return NULL;
}
DFHackObject* API_getMaps(DFHackObject* api)
{
if(api != NULL)
{
return (DFHackObject*)((DFHack::API*)api)->getMaps();
}
return NULL;
}
DFHackObject* API_getGui(DFHackObject* api)
{
if(api != NULL)
{
return (DFHackObject*)((DFHack::API*)api)->getGui();
}
return NULL;
}
DFHackObject* API_getPosition(DFHackObject* api)
{
if(api != NULL)
{
return (DFHackObject*)((DFHack::API*)api)->getPosition();
}
return NULL;
}
DFHackObject* API_getMaterials(DFHackObject* api)
{
if(api != NULL)
{
return (DFHackObject*)((DFHack::API*)api)->getMaterials();
}
return NULL;
}
DFHackObject* API_getTranslation(DFHackObject* api)
{
if(api != NULL)
{
return (DFHackObject*)((DFHack::API*)api)->getTranslation();
}
return NULL;
}
DFHackObject* API_getVegetation(DFHackObject* api)
{
if(api != NULL)
{
return (DFHackObject*)((DFHack::API*)api)->getVegetation();
}
return NULL;
}
DFHackObject* API_getBuildings(DFHackObject* api)
{
if(api != NULL)
{
return (DFHackObject*)((DFHack::API*)api)->getBuildings();
}
return NULL;
}
DFHackObject* API_getConstructions(DFHackObject* api)
{
if(api != NULL)
{
return (DFHackObject*)((DFHack::API*)api)->getConstructions();
}
return NULL;
}
void API_ReadRaw(DFHackObject* api, const uint32_t offset, const uint32_t size, uint8_t* target)
{
if(api != NULL)

@ -47,6 +47,21 @@ DFHACK_EXPORT int API_isSuspended(DFHackObject* api);
DFHACK_EXPORT int API_ForceResume(DFHackObject* api);
DFHACK_EXPORT int API_AsyncSuspend(DFHackObject* api);
DFHACK_EXPORT DFHackObject* API_getMemoryInfo(DFHackObject* api);
DFHACK_EXPORT DFHackObject* API_getProcess(DFHackObject* api);
DFHACK_EXPORT DFHackObject* API_getWindow(DFHackObject* api);
DFHACK_EXPORT DFHackObject* API_getCreatures(DFHackObject* api);
DFHACK_EXPORT DFHackObject* API_getMaps(DFHackObject* api);
DFHACK_EXPORT DFHackObject* API_getGui(DFHackObject* api);
DFHACK_EXPORT DFHackObject* API_getPosition(DFHackObject* api);
DFHACK_EXPORT DFHackObject* API_getMaterials(DFHackObject* api);
DFHACK_EXPORT DFHackObject* API_getTranslation(DFHackObject* api);
DFHACK_EXPORT DFHackObject* API_getVegetation(DFHackObject* api);
DFHACK_EXPORT DFHackObject* API_getBuildings(DFHackObject* api);
DFHACK_EXPORT DFHackObject* API_getConstructions(DFHackObject* api);
//these are DANGEROUS...can crash/segfault DF, turn the seas to blood, call up the Antichrist, etc
DFHACK_EXPORT void API_ReadRaw(DFHackObject* api, const uint32_t offset, const uint32_t size, uint8_t* target);
DFHACK_EXPORT void API_WriteRaw(DFHackObject* api, const uint32_t offset, const uint32_t size, uint8_t* source);

@ -0,0 +1,49 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#ifndef GUI_C_API
#define GUI_C_API
#include "Export.h"
#include "integers.h"
#include "DFTypes.h"
#include "DFHackAPI_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif
DFHACK_EXPORT int Gui_Start(DFHackObject* gui);
DFHACK_EXPORT int Gui_Finish(DFHackObject* gui);
DFHACK_EXPORT int Gui_ReadPauseState(DFHackObject* gui);
DFHACK_EXPORT int Gui_ReadViewScreen(DFHackObject* gui, t_viewscreen* viewscreen);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,75 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#ifndef MATERIALS_C_API
#define MATERIALS_C_API
#include "Export.h"
#include "integers.h"
#include "DFTypes.h"
#include "modules/Materials.h"
#include "DFHackAPI_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif
DFHACK_EXPORT int Materials_ReadInorganicMaterials(DFHackObject* mat);
DFHACK_EXPORT int Materials_ReadOrganicMaterials(DFHackObject* mat);
DFHACK_EXPORT int Materials_ReadWoodMaterials(DFHackObject* mat);
DFHACK_EXPORT int Materials_ReadPlantMaterials(DFHackObject* mat);
DFHACK_EXPORT int Materials_ReadCreatureTypes(DFHackObject* mat);
DFHACK_EXPORT int Materials_ReadCreatureTypesEx(DFHackObject* mat);
DFHACK_EXPORT int Materials_ReadDescriptorColors(DFHackObject* mat);
DFHACK_EXPORT int Materials_ReadOthers(DFHackObject* mat);
DFHACK_EXPORT void Materials_ReadAllMaterials(DFHackObject* mat);
DFHACK_EXPORT const char* Materials_getDescription(DFHackObject* mat, t_material* material);
DFHACK_EXPORT int Materials_getInorganicSize(DFHackObject* mat);
DFHACK_EXPORT int Materials_getOrganicSize(DFHackObject* mat);
DFHACK_EXPORT int Materials_getTreeSize(DFHackObject* mat);
DFHACK_EXPORT int Materials_getPlantSize(DFHackObject* mat);
DFHACK_EXPORT int Materials_getRaceSize(DFHackObject* mat);
DFHACK_EXPORT int Materials_getRaceExSize(DFHackObject* mat);
DFHACK_EXPORT int Materials_getColorSize(DFHackObject* mat);
DFHACK_EXPORT int Materials_getOtherSize(DFHackObject* mat);
DFHACK_EXPORT int Materials_getInorganic(DFHackObject* mat, void* (*t_matgloss_buffer_create)(int));
DFHACK_EXPORT int Materials_getOrganic(DFHackObject* mat, void* (*t_matgloss_buffer_create)( int));
DFHACK_EXPORT int Materials_getTree(DFHackObject* mat, void* (*t_matgloss_buffer_create)(int));
DFHACK_EXPORT int Materials_getPlant(DFHackObject* mat, void* (*t_matgloss_buffer_create)(int));
DFHACK_EXPORT int Materials_getRace(DFHackObject* mat, void* (*t_matgloss_buffer_create)(int));
// DFHACK_EXPORT int Materials_getRaceEx(DFHackObject* mat, t_creaturetype* (*t_creaturetype_buffer_create)(int));
DFHACK_EXPORT int Materials_getColor(DFHackObject* mat, void* (*t_descriptor_color_buffer_create)(int));
DFHACK_EXPORT int Materials_getOther(DFHackObject* mat, void* (*t_matglossOther_buffer_create)(int));
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,81 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "modules/Gui_C.h"
#include "integers.h"
#include "DFCommonInternal.h"
#include "modules/Gui.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif
int Gui_Start(DFHackObject* gui)
{
if(gui != NULL)
{
return ((DFHack::Gui*)gui)->Start();
}
return -1;
}
int Gui_Finish(DFHackObject* gui)
{
if(gui != NULL)
{
return ((DFHack::Gui*)gui)->Finish();
}
return -1;
}
int Gui_ReadPauseState(DFHackObject* gui)
{
if(gui != NULL)
{
return ((DFHack::Gui*)gui)->ReadPauseState();
}
return -1;
}
int Gui_ReadViewScreen(DFHackObject* gui, t_viewscreen* viewscreen)
{
int result;
if(gui != NULL)
{
return ((DFHack::Gui*)gui)->ReadViewScreen(*viewscreen);
}
return -1;
}
#ifdef __cplusplus
}
#endif

@ -0,0 +1,412 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf, doomchild
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include "integers.h"
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
#include "DFCommonInternal.h"
#include "modules/Materials.h"
#include "modules/Materials_C.h"
using namespace DFHack;
#ifdef __cplusplus
extern "C" {
#endif
int Materials_ReadInorganicMaterials(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->ReadInorganicMaterials();
}
return -1;
}
int Materials_ReadOrganicMaterials(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->ReadOrganicMaterials();
}
return -1;
}
int Materials_ReadWoodMaterials(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->ReadWoodMaterials();
}
return -1;
}
int Materials_ReadPlantMaterials(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->ReadPlantMaterials();
}
return -1;
}
int Materials_ReadCreatureTypes(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->ReadCreatureTypes();
}
return -1;
}
int Materials_ReadCreatureTypesEx(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->ReadCreatureTypesEx();
}
return -1;
}
int Materials_ReadDescriptorColors(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->ReadDescriptorColors();
}
return -1;
}
int Materials_ReadOthers(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->ReadOthers();
}
return -1;
}
void Materials_ReadAllMaterials(DFHackObject* mat)
{
if(mat != NULL)
{
((DFHack::Materials*)mat)->ReadAllMaterials();
}
}
const char* Materials_getDescription(DFHackObject* mat, t_material* material)
{
if(mat != NULL)
{
std::string description = ((DFHack::Materials*)mat)->getDescription(*material);
return description.c_str();
}
return "\0";
}
//vector size getters
int Materials_getInorganicSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->inorganic.size();
}
return -1;
}
int Materials_getOrganicSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->organic.size();
}
return -1;
}
int Materials_getTreeSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->tree.size();
}
return -1;
}
int Materials_getPlantSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->plant.size();
}
return -1;
}
int Materials_getRaceSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->race.size();
}
return -1;
}
int Materials_getRaceExSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->raceEx.size();
}
return -1;
}
int Materials_getColorSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->color.size();
}
return -1;
}
int Materials_getOtherSize(DFHackObject* mat)
{
if(mat != NULL)
{
return ((DFHack::Materials*)mat)->other.size();
}
return -1;
}
//vector getters
int Materials_getInorganic(DFHackObject* mat, void* (*t_matgloss_buffer_create)(int))
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->inorganic.size() > 0)
{
t_matgloss* buf = (t_matgloss*)((*t_matgloss_buffer_create)(materials->inorganic.size()));
if(buf != NULL)
{
copy(materials->inorganic.begin(), materials->inorganic.end(), buf);
return 1;
}
else
return -1;
}
else
return 0;
}
return -1;
}
int Materials_getOrganic(DFHackObject* mat, void* (*t_matgloss_buffer_create)(int))
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->organic.size() > 0)
{
t_matgloss* buf = (t_matgloss*)((*t_matgloss_buffer_create)(materials->organic.size()));
if(buf != NULL)
{
copy(materials->organic.begin(), materials->organic.end(), buf);
return 1;
}
else
return -1;
}
else
return 0;
}
return -1;
}
int Materials_getTree(DFHackObject* mat, void* (*t_matgloss_buffer_create)(int))
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->tree.size() > 0)
{
t_matgloss* buf = (t_matgloss*)((*t_matgloss_buffer_create)(materials->tree.size()));
if(buf != NULL)
{
copy(materials->tree.begin(), materials->tree.end(), buf);
return 1;
}
else
return -1;
}
else
return 0;
}
return -1;
}
int Materials_getPlant(DFHackObject* mat, void* (*t_matgloss_buffer_create)(int))
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->plant.size() > 0)
{
t_matgloss* buf = (t_matgloss*)((*t_matgloss_buffer_create)(materials->plant.size()));
if(buf != NULL)
{
copy(materials->plant.begin(), materials->plant.end(), buf);
return 1;
}
else
return -1;
}
else
return 0;
}
return -1;
}
int Materials_getRace(DFHackObject* mat, void* (*t_matgloss_buffer_create)(int))
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->race.size() > 0)
{
t_matgloss* buf = (t_matgloss*)((*t_matgloss_buffer_create)(materials->race.size()));
if(buf != NULL)
{
copy(materials->race.begin(), materials->race.end(), buf);
return 1;
}
else
return -1;
}
else
return 0;
}
return -1;
}
//race_ex getter goes here...
int Materials_getColor(DFHackObject* mat, void* (*t_matgloss_buffer_create)(int))
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->color.size() > 0)
{
t_descriptor_color* buf = (t_descriptor_color*)((*t_matgloss_buffer_create)(materials->color.size()));
if(buf != NULL)
{
copy(materials->color.begin(), materials->color.end(), buf);
return 1;
}
else
return -1;
}
else
return 0;
}
return -1;
}
int Materials_getOther(DFHackObject* mat, void* (*t_matgloss_buffer_create)(int))
{
if(mat != NULL)
{
DFHack::Materials* materials = (DFHack::Materials*)mat;
if(materials->other.size() > 0)
{
t_matglossOther* buf = (t_matglossOther*)((*t_matgloss_buffer_create)(materials->other.size()));
if(buf != NULL)
{
copy(materials->other.begin(), materials->other.end(), buf);
return 1;
}
else
return -1;
}
else
return 0;
}
return -1;
}
#ifdef __cplusplus
}
#endif

@ -58,7 +58,13 @@ struct DF_API
PyObject* vegetation;
PyObject* gui;
PyObject* mem_info_type;
PyObject* position_type;
PyObject* material_type;
PyObject* creature_type;
PyObject* map_type;
PyObject* translate_type;
PyObject* construction_type;
PyObject* vegetation_type;
PyObject* gui_type;
@ -95,6 +101,7 @@ static int DF_API_init(DF_API* self, PyObject* args, PyObject* kwds)
self->vegetation = NULL;
self->gui = NULL;
self->position_type = (PyObject*)&DF_Position_type;
self->map_type = (PyObject*)&DF_Map_type;
self->vegetation_type = (PyObject*)&DF_Vegetation_type;
self->gui_type = (PyObject*)&DF_GUI_type;
@ -206,7 +213,10 @@ static PyObject* DF_API_getMemoryInfo(DF_API* self, void* closure)
{
if(self->api_Ptr != NULL)
{
self->mem_info = PyObject_Call((PyObject*)&DF_MemInfo_type, NULL, NULL);
PyObject *apiarg;
apiarg = PyTuple_New(1);
PyTuple_SetItem(apiarg, 0, (PyObject*)self);
self->mem_info = PyObject_CallObject(self->mem_info_type, apiarg);
if(self->mem_info != NULL)
{
@ -235,7 +245,10 @@ static PyObject* DF_API_getPosition(DF_API* self, void* closure)
{
if(self->api_Ptr != NULL)
{
self->position = PyObject_Call((PyObject*)&DF_Position_type, NULL, NULL);
PyObject *apiarg;
apiarg = PyTuple_New(1);
PyTuple_SetItem(apiarg, 0, (PyObject*)self);
self->position = PyObject_CallObject(self->position_type, apiarg);
if(self->position != NULL)
{
@ -264,7 +277,10 @@ static PyObject* DF_API_getMaterial(DF_API* self, void* closure)
{
if(self->api_Ptr != NULL)
{
self->material = PyObject_Call((PyObject*)&DF_Material_type, NULL, NULL);
PyObject *apiarg;
apiarg = PyTuple_New(1);
PyTuple_SetItem(apiarg, 0, (PyObject*)self);
self->material = PyObject_CallObject(self->material_type, apiarg);
if(self->material != NULL)
{
@ -293,7 +309,10 @@ static PyObject* DF_API_getCreature(DF_API* self, void* closure)
{
if(self->api_Ptr != NULL)
{
self->creature = PyObject_Call((PyObject*)&DF_CreatureManager_type, NULL, NULL);
PyObject *apiarg;
apiarg = PyTuple_New(1);
PyTuple_SetItem(apiarg, 0, (PyObject*)self);
self->creature = PyObject_CallObject(self->creature_type, apiarg);
if(self->creature != NULL)
{
@ -322,7 +341,10 @@ static PyObject* DF_API_getMap(DF_API* self, void* closure)
{
if(self->api_Ptr != NULL)
{
self->map = PyObject_CallObject(self->map_type, NULL);
PyObject *apiarg;
apiarg = PyTuple_New(1);
PyTuple_SetItem(apiarg, 0, (PyObject*)self);
self->map = PyObject_CallObject(self->map_type, apiarg);
if(self->map != NULL)
{
@ -351,7 +373,10 @@ static PyObject* DF_API_getTranslation(DF_API* self, void* closure)
{
if(self->api_Ptr != NULL)
{
self->translate = PyObject_Call((PyObject*)&DF_Translate_type, NULL, NULL);
PyObject *apiarg;
apiarg = PyTuple_New(1);
PyTuple_SetItem(apiarg, 0, (PyObject*)self);
self->translate = PyObject_CallObject(self->translate_type, apiarg);
if(self->translate != NULL)
{
@ -380,7 +405,10 @@ static PyObject* DF_API_getConstruction(DF_API* self, void* closure)
{
if(self->api_Ptr != NULL)
{
self->construction = PyObject_Call((PyObject*)&DF_Construction_type, NULL, NULL);
PyObject *apiarg;
apiarg = PyTuple_New(1);
PyTuple_SetItem(apiarg, 0, (PyObject*)self);
self->construction = PyObject_CallObject(self->construction_type, apiarg);
if(self->construction != NULL)
{
@ -409,7 +437,10 @@ static PyObject* DF_API_getVegetation(DF_API* self, void* closure)
{
if(self->api_Ptr != NULL)
{
self->vegetation = PyObject_CallObject(self->vegetation_type, NULL);
PyObject *apiarg;
apiarg = PyTuple_New(1);
PyTuple_SetItem(apiarg, 0, (PyObject*)self);
self->vegetation = PyObject_CallObject(self->vegetation_type, apiarg);
if(self->vegetation != NULL)
{
@ -438,7 +469,10 @@ static PyObject* DF_API_getGUI(DF_API* self, void* closure)
{
if(self->api_Ptr != NULL)
{
self->gui = PyObject_CallObject(self->gui_type, NULL);
PyObject *apiarg;
apiarg = PyTuple_New(1);
PyTuple_SetItem(apiarg, 0, (PyObject*)self);
self->gui = PyObject_CallObject(self->gui_type, apiarg);
if(self->gui != NULL)
{
@ -457,6 +491,105 @@ static PyObject* DF_API_getGUI(DF_API* self, void* closure)
Py_RETURN_NONE;
}
static PyObject* DF_API_getMemInfoType(DF_API* self, void* closure)
{
return self->mem_info_type;
}
static int DF_API_setMemInfoType(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_MemInfo_type) <= 0)
{
PySys_WriteStdout("failed subclass check");
PyErr_SetString(PyExc_TypeError, "value must be descended from _pydfhack._MemInfo");
return -1;
}
self->mem_info_type = value;
return 0;
}
static PyObject* DF_API_getPositionType(DF_API* self, void* closure)
{
return self->position_type;
}
static int DF_API_setPositionType(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_Position_type) <= 0)
{
PySys_WriteStdout("failed subclass check");
PyErr_SetString(PyExc_TypeError, "value must be descended from _pydfhack._PositionManager");
return -1;
}
self->position_type = value;
return 0;
}
static PyObject* DF_API_getMaterialType(DF_API* self, void* closure)
{
return self->material_type;
}
static int DF_API_setMaterialType(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_Material_type) <= 0)
{
PySys_WriteStdout("failed subclass check");
PyErr_SetString(PyExc_TypeError, "value must be descended from pydfhack._MaterialManager");
return -1;
}
self->material_type = value;
return 0;
}
static PyObject* DF_API_getCreatureType(DF_API* self, void* closure)
{
return self->creature_type;
}
static int DF_API_setCreatureType(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_CreatureManager_type) <= 0)
{
PySys_WriteStdout("failed subclass check");
PyErr_SetString(PyExc_TypeError, "value must be descended from pydfhack._CreatureManager");
return -1;
}
self->creature_type = value;
return 0;
}
static PyObject* DF_API_getMapType(DF_API* self, void* closure)
{
@ -482,6 +615,54 @@ static int DF_API_setMapType(DF_API* self, PyObject* value)
return 0;
}
static PyObject* DF_API_getTranslateType(DF_API* self, void* closure)
{
return self->translate_type;
}
static int DF_API_setTranslateType(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_Translate_type) <= 0)
{
PySys_WriteStdout("failed subclass check");
PyErr_SetString(PyExc_TypeError, "value must be descended from pydfhack._TranslateManager");
return -1;
}
self->translate_type = value;
return 0;
}
static PyObject* DF_API_getConstructionType(DF_API* self, void* closure)
{
return self->construction_type;
}
static int DF_API_setConstructionType(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_Construction_type) <= 0)
{
PySys_WriteStdout("failed subclass check");
PyErr_SetString(PyExc_TypeError, "value must be descended from pydfhack._ConstructionManager");
return -1;
}
self->construction_type = value;
return 0;
}
static PyObject* DF_API_getVegetationType(DF_API* self, void* closure)
{
@ -546,7 +727,13 @@ 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},
{"_mem_info_mgr_type", (getter)DF_API_getMemInfoType, (setter)DF_API_setMemInfoType, "_mem_info_mgr_type", NULL},
{"_position_mgr_type", (getter)DF_API_getPositionType, (setter)DF_API_setPositionType, "_position_mgr_type", NULL},
{"_material_mgr_type", (getter)DF_API_getMaterialType, (setter)DF_API_setMaterialType, "_material_mgr_type", NULL},
{"_creature_mgr_type", (getter)DF_API_getCreatureType, (setter)DF_API_setCreatureType, "_creature_mgr_type", NULL},
{"_map_mgr_type", (getter)DF_API_getMapType, (setter)DF_API_setMapType, "_map_mgr_type", NULL},
{"_translate_mgr_type", (getter)DF_API_getTranslateType, (setter)DF_API_setTranslateType, "_translate_mgr_type", NULL},
{"_construction_mgr_type", (getter)DF_API_getConstructionType, (setter)DF_API_setConstructionType, "_construction_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

@ -61,7 +61,12 @@ static void DoImports()
{
if(FlagsModule == NULL)
{
FlagsModule = PyImport_ImportModule("pydfhackflags");
FlagsModule = PyImport_ImportModule("pydfhack.pydfhackflags");
if (PyErr_Occurred())
{
PyErr_Print();
return ;
}
CreatureFlags1_type = PyObject_GetAttrString(FlagsModule, "CreatureFlags1");
CreatureFlags2_type = PyObject_GetAttrString(FlagsModule, "CreatureFlags2");
@ -72,7 +77,12 @@ static void DoImports()
}
if(TypesModule == NULL)
{
TypesModule = PyImport_ImportModule("pydftypes");
TypesModule = PyImport_ImportModule("pydfhack.pydftypes");
if (PyErr_Occurred())
{
PyErr_Print();
return ;
}
Note_type = PyObject_GetAttrString(TypesModule, "Note");
Construction_type = PyObject_GetAttrString(TypesModule, "Construction");

@ -0,0 +1,273 @@
from ctypes import *
from pydftypes import *
int_ptr = POINTER(c_int)
uint_ptr = POINTER(c_uint)
libdfhack = cdll.libdfhack
libdfhack.API_Alloc.restype = c_void_p
libdfhack.API_Free.argtypes = [ c_void_p ]
libdfhack.API_getMemoryInfo.restype = c_void_p
libdfhack.API_getProcess.restype = c_void_p
libdfhack.API_getWindow.restype = c_void_p
libdfhack.API_getCreatures.restype = c_void_p
libdfhack.API_getMaps.restype = c_void_p
libdfhack.API_getGui.restype = c_void_p
libdfhack.API_getPosition.restype = c_void_p
libdfhack.API_getMaterials.restype = c_void_p
libdfhack.API_getTranslation.restype = c_void_p
libdfhack.API_getVegetation.restype = c_void_p
libdfhack.API_getBuildings.restype = c_void_p
libdfhack.API_getConstructions.restype = c_void_p
class API(object):
def __init__(self, memory_path):
self._api_ptr = libdfhack.API_Alloc(create_string_buffer(memory_path))
self._pos_obj = None
self._mat_obj = None
def __del__(self):
libdfhack.API_Free(self._api_ptr)
def attach(self):
return libdfhack.API_Attach(self._api_ptr) > 0
def detach(self):
return libdfhack.API_Detach(self._api_ptr) > 0
def suspend(self):
return libdfhack.API_Suspend(self._api_ptr) > 0
def resume(self):
return libdfhack.API_Resume(self._api_ptr) > 0
def force_resume(self):
return libdfhack.API_ForceResume(self._api_ptr) > 0
def async_suspend(self):
return libdfhack.API_AsyncSuspend(self._api_ptr) > 0
@property
def is_attached(self):
return libdfhack.API_isAttached(self._api_ptr) > 0
@property
def is_suspended(self):
return libdfhack.API_isSuspended(self._api_ptr) > 0
@property
def position(self):
if self._pos_obj is None:
ptr = libdfhack.API_getPosition(self._api_ptr)
if ptr is not None:
return Position(ptr)
else:
return None
else:
return self._pos_obj
@property
def materials(self):
if self._mat_obj is None:
ptr = libdfhack.API_getMaterials(self._api_ptr)
if ptr is not None:
return Materials(ptr)
else:
return None
else:
return self._mat_obj
class Position(object):
def __init__(self, ptr):
self._pos_ptr = ptr
self._vx, self._vy, self._vz = c_int(), c_int(), c_int()
self._cx, self._cy, self._cz = c_int(), c_int(), c_int()
self._ww, self._wh = c_int(), c_int()
def get_view_coords(self):
if libdfhack.Position_getViewCoords(self._pos_ptr, byref(self._vx), byref(self._vy), byref(self._vz)) > 0:
return (self._vx.value, self._vy.value, self._vz.value)
else:
return (-1, -1, -1)
def set_view_coords(self, v_coords):
self._vx.value, self._vy.value, self._vz.value = v_coords
libdfhack.Position_setViewCoords(self._pos_ptr, self._vx, self._vy, self._vz)
view_coords = property(get_view_coords, set_view_coords)
def get_cursor_coords(self):
if libdfhack.Position_getCursorCoords(self._pos_ptr, byref(self._cx), byref(self._cy), byref(self._cz)) > 0:
return (self._cx.value, self._cy.value, self._cz.value)
else:
return (-1, -1, -1)
def set_cursor_coords(self, c_coords):
self._cx.value, self._cy.value, self_cz.value = c_coords
libdfhack.Position_setCursorCoords(self._pos_ptr, self._cx, self._cy, self._cz)
cursor_coords = property(get_cursor_coords, set_cursor_coords)
@property
def window_size(self):
if libdfhack.Position_getWindowSize(self._pos_ptr, byref(self._ww), byref(self._wh)) > 0:
return (self._ww.value, self._wh.value)
else:
return (-1, -1)
libdfhack.Gui_ReadViewScreen.argtypes = [ c_void_p, c_void_p ]
class Gui(object):
def __init__(self, ptr):
self._gui_ptr = ptr
def start(self):
return libdfhack.Gui_Start(self._gui_ptr)
def finish(self):
return libdfhack.Gui_Finish(self._gui_ptr)
def read_pause_state(self):
return libdfhack.Gui_ReadPauseState(self._pos_ptr) > 0
def read_view_screen(self):
s = ViewScreen()
if libdfhack.Gui_ReadViewScreen(self._gui_ptr, byref(s)) > 0:
return s
else:
return None
arr_create_func = CFUNCTYPE(c_void_p, c_int)
get_arg_types = [ c_void_p, arr_create_func ]
libdfhack.Materials_getInorganic.argtypes = get_arg_types
libdfhack.Materials_getOrganic.argtypes = get_arg_types
libdfhack.Materials_getTree.argtypes = get_arg_types
libdfhack.Materials_getPlant.argtypes = get_arg_types
libdfhack.Materials_getRace.argtypes = get_arg_types
libdfhack.Materials_getRaceEx.argtypes = get_arg_types
libdfhack.Materials_getColor.argtypes = get_arg_types
libdfhack.Materials_getOther.argtypes = get_arg_types
class Materials(object):
def __init__(self, ptr):
self._mat_ptr = ptr
self.inorganic = None
self.organic = None
self.tree = None
self.plant = None
self.race = None
self.race_ex = None
self.color = None
self.other = None
def read_inorganic(self):
return libdfhack.Materials_ReadInorganicMaterials(self._mat_ptr)
def read_organic(self):
return libdfhack.Materials_ReadOrganicMaterials(self._mat_ptr)
def read_wood(self):
return libdfhack.Materials_ReadWoodMaterials(self._mat_ptr)
def read_plant(self):
return libdfhack.Materials_ReadPlantMaterials(self._mat_ptr)
def read_creature_types(self):
return libdfhack.Materials_ReadCreatureTypes(self._mat_ptr)
def read_creature_types_ex(self):
return libdfhack.Materials_ReadCreatureTypesEx(self._mat_ptr)
def read_descriptor_colors(self):
return libdfhack.Materials_ReadDescriptorColors(self._mat_ptr)
def read_others(self):
return libdfhack.Materials_ReadOthers(self._mat_ptr)
def read_all(self):
libdfhack.Materials_ReadAllMaterials(self._mat_ptr)
def get_description(self, material):
return libdfhack.Materials_getDescription(self._mat_ptr, byref(material))
def _allocate_matgloss_array(self, count):
arr_type = Matgloss * count
arr = arr_type()
ptr = c_void_p()
ptr = addressof(arr)
return (arr, ptr)
def update_inorganic_cache(self):
def update_callback(count):
allocated = self._allocate_matgloss_array(count)
self.inorganic = allocated[0]
return allocated[1]
callback = arr_create_func(update_callback)
return libdfhack.Materials_getInorganic(self._mat_ptr, callback)
def update_organic_cache(self):
def update_callback(count):
allocated = self._allocate_matgloss_array(count)
self.organic = allocated[0]
return allocated[1]
callback = arr_create_func(update_callback)
return libdfhack.Materials_getOrganic(self._mat_ptr, callback)
def update_tree_cache(self):
def update_callback(count):
allocated = self._allocate_matgloss_array(count)
self.tree = allocated[0]
return allocated[1]
callback = arr_create_func(update_callback)
return libdfhack.Materials_getTree(self._mat_ptr, callback)
def update_plant_cache(self):
def update_callback(count):
allocated = self._allocate_matgloss_array(count)
self.plant = allocated[0]
return allocated[1]
callback = arr_create_func(update_callback)
return libdfhack.Materials_getPlant(self._mat_ptr, callback)
def update_race_cache(self):
def update_callback(count):
allocated = self._allocate_matgloss_array(count)
self.race = allocated[0]
return allocated[1]
callback = arr_create_func(update_callback)
return libdfhack.Materials_getRace(self._mat_ptr, callback)

@ -0,0 +1,284 @@
#!python
"""Bootstrap setuptools installation
If you want to use setuptools in your package's setup.py, just include this
file in the same directory with it, and add this to the top of your setup.py::
from ez_setup import use_setuptools
use_setuptools()
If you want to require a specific version of setuptools, set a download
mirror, or use an alternate download directory, you can do so by supplying
the appropriate options to ``use_setuptools()``.
This file can also be run as a script to install or upgrade setuptools.
"""
import sys
DEFAULT_VERSION = "0.6c11"
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
md5_data = {
'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
}
import sys, os
try: from hashlib import md5
except ImportError: from md5 import md5
def _validate_md5(egg_name, data):
if egg_name in md5_data:
digest = md5(data).hexdigest()
if digest != md5_data[egg_name]:
print >>sys.stderr, (
"md5 validation of %s failed! (Possible download problem?)"
% egg_name
)
sys.exit(2)
return data
def use_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
download_delay=15
):
"""Automatically find/download setuptools and make it available on sys.path
`version` should be a valid setuptools version number that is available
as an egg for download under the `download_base` URL (which should end with
a '/'). `to_dir` is the directory where setuptools will be downloaded, if
it is not already available. If `download_delay` is specified, it should
be the number of seconds that will be paused before initiating a download,
should one be required. If an older version of setuptools is installed,
this routine will print a message to ``sys.stderr`` and raise SystemExit in
an attempt to abort the calling script.
"""
was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
def do_download():
egg = download_setuptools(version, download_base, to_dir, download_delay)
sys.path.insert(0, egg)
import setuptools; setuptools.bootstrap_install_from = egg
try:
import pkg_resources
except ImportError:
return do_download()
try:
pkg_resources.require("setuptools>="+version); return
except pkg_resources.VersionConflict, e:
if was_imported:
print >>sys.stderr, (
"The required version of setuptools (>=%s) is not available, and\n"
"can't be installed while this script is running. Please install\n"
" a more recent version first, using 'easy_install -U setuptools'."
"\n\n(Currently using %r)"
) % (version, e.args[0])
sys.exit(2)
else:
del pkg_resources, sys.modules['pkg_resources'] # reload ok
return do_download()
except pkg_resources.DistributionNotFound:
return do_download()
def download_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
delay = 15
):
"""Download setuptools from a specified location and return its filename
`version` should be a valid setuptools version number that is available
as an egg for download under the `download_base` URL (which should end
with a '/'). `to_dir` is the directory where the egg will be downloaded.
`delay` is the number of seconds to pause before an actual download attempt.
"""
import urllib2, shutil
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
url = download_base + egg_name
saveto = os.path.join(to_dir, egg_name)
src = dst = None
if not os.path.exists(saveto): # Avoid repeated downloads
try:
from distutils import log
if delay:
log.warn("""
---------------------------------------------------------------------------
This script requires setuptools version %s to run (even to display
help). I will attempt to download it for you (from
%s), but
you may need to enable firewall access for this script first.
I will start the download in %d seconds.
(Note: if this machine does not have network access, please obtain the file
%s
and place it in this directory before rerunning this script.)
---------------------------------------------------------------------------""",
version, download_base, delay, url
); from time import sleep; sleep(delay)
log.warn("Downloading %s", url)
src = urllib2.urlopen(url)
# Read/write all in one block, so we don't create a corrupt file
# if the download is interrupted.
data = _validate_md5(egg_name, src.read())
dst = open(saveto,"wb"); dst.write(data)
finally:
if src: src.close()
if dst: dst.close()
return os.path.realpath(saveto)
def main(argv, version=DEFAULT_VERSION):
"""Install or upgrade setuptools and EasyInstall"""
try:
import setuptools
except ImportError:
egg = None
try:
egg = download_setuptools(version, delay=0)
sys.path.insert(0,egg)
from setuptools.command.easy_install import main
return main(list(argv)+[egg]) # we're done here
finally:
if egg and os.path.exists(egg):
os.unlink(egg)
else:
if setuptools.__version__ == '0.0.1':
print >>sys.stderr, (
"You have an obsolete version of setuptools installed. Please\n"
"remove it from your system entirely before rerunning this script."
)
sys.exit(2)
req = "setuptools>="+version
import pkg_resources
try:
pkg_resources.require(req)
except pkg_resources.VersionConflict:
try:
from setuptools.command.easy_install import main
except ImportError:
from easy_install import main
main(list(argv)+[download_setuptools(delay=0)])
sys.exit(0) # try to force an exit
else:
if argv:
from setuptools.command.easy_install import main
main(argv)
else:
print "Setuptools version",version,"or greater has been installed."
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
def update_md5(filenames):
"""Update our built-in md5 registry"""
import re
for name in filenames:
base = os.path.basename(name)
f = open(name,'rb')
md5_data[base] = md5(f.read()).hexdigest()
f.close()
data = [" %r: %r,\n" % it for it in md5_data.items()]
data.sort()
repl = "".join(data)
import inspect
srcfile = inspect.getsourcefile(sys.modules[__name__])
f = open(srcfile, 'rb'); src = f.read(); f.close()
match = re.search("\nmd5_data = {\n([^}]+)}", src)
if not match:
print >>sys.stderr, "Internal error!"
sys.exit(2)
src = src[:match.start(1)] + repl + src[match.end(1):]
f = open(srcfile,'w')
f.write(src)
f.close()
if __name__=='__main__':
if len(sys.argv)>2 and sys.argv[1]=='--md5update':
update_md5(sys.argv[2:])
else:
main(sys.argv[1:])

@ -1,28 +0,0 @@
import pydfhack, os
class API(pydfhack._API):
for file in ["Memory.xml", os.path.join("..","..","output","Memory.xml")]:
if os.path.isfile(file):
datafile = file
break
else:
raise ImportError, "Memory.xml not found."
def __init__(self, *args, **kwds):
pydfhack._API.__init__(self, API.datafile)
self._map_mgr_type = Map
self._vegetation_mgr_type = Vegetation
self._gui_mgr_type = GUI
class Map(pydfhack._MapManager):
def __init__(self, *args, **kwds):
pydfhack._MapManager.__init__(self, args, kwds)
class Vegetation(pydfhack._VegetationManager):
def __init__(self, *args, **kwds):
pydfhack._VegetationManager.__init__(self, args, kwds)
class GUI(pydfhack._GUIManager):
def __init__(self, *args, **kwds):
pydfhack._GUIManager.__init__(self, args, kwds)

@ -62,7 +62,7 @@ static PyMethodDef module_methods[] =
{NULL} //Sentinel
};
PyMODINIT_FUNC initpydfhack(void)
PyMODINIT_FUNC init_pydfhack(void)
{
PyObject* module;
@ -102,7 +102,7 @@ PyMODINIT_FUNC initpydfhack(void)
if(PyType_Ready(&DF_GUI_type) < 0)
return;
module = Py_InitModule3("pydfhack", module_methods, "pydfhack extension module");
module = Py_InitModule3("_pydfhack", module_methods, "pydfhack extension module");
Py_INCREF(&DF_API_type);
Py_INCREF(&DF_MemInfo_type);

@ -0,0 +1 @@
from .pydfapi import API

@ -0,0 +1,139 @@
# -*- coding: utf-8 -*-
"""
Module for high-level abstraction of tiles
"""
from collections import namedtuple
from .pydftypes import Rectangle
from .mixins import NoStart
from .decorators import suspend
class Point(object):
x = None
y = None
z = None
block = False
def __init__(self, x, y, z, block=False):
self.x = x
self.y = y
self.z = z
self.block = block
def get_block(self):
if not self.block:
return Point(self.x/16, self.y/16, self.z, True)
else:
return self
@property
def xyz(self):
return (self.x, self.y, self.z)
@property
def rect(self):
"""
Return block coords in form (x1, y1, x2, y2)
"""
block = self.get_block()
x1 = block.x * 16
y1 = block.y * 16
return Rectangle(x1, y1, x1+15, y1+15)
def __repr__(self):
b = ''
if self.block:
b = ', Block'
return "<Point(X:{0.x}, Y:{0.y}, Z:{0.z}{1})>".format(self, b)
class Block(NoStart):
"""
16x16 tiles block
"""
api = None
tiles = None
coords = None
x1 = None
y1 = None
def __init__(self, api, coords):
"""
api is instance of API, which is used for read/write operations
coords is Point object
"""
self.api = api
if not isinstance(coords, Point):
raise Exception(u"coords parameter should be Point")
coords = coords.get_block()
self.coords = coords
self.rect = self.coords.rect
self.reload()
@suspend
def reload(self):
tile_types = self.api.maps.Read_Tile_Types(point=self.coords)
tile_flags = self.api.maps.Read_Designations(point=self.coords)
if self.tiles:
for x in range(16):
for y in range(16):
self.tiles[x][y].update(ttype=tile_types[x][y], flags=tile_flags[x][y])
else:
self.tiles = []
for x in range(16):
row = []
for y in range(16):
row.append(Tile(self, tile_types[x][y], tile_flags[x][y], self.rect.x1 + x, self.rect.y1 + y, self.coords.z))
self.tiles.append(row)
@suspend
def save(self):
tile_types = map(lambda x:range(16), range(16))
tile_flags = map(lambda x:range(16), range(16))
for x in range(16):
for y in range(16):
tile_types[x][y] = self.tiles[x][y].ttype
tile_flags[x][y] = self.tiles[x][y].flags
self.api.maps.Write_Tile_Types(point=self.coords, tiles=tile_types)
# Designations are bugged
#self.api.maps.Write_Designations(point=self.coords, tiles=tile_flags)
def get_tile(self, x=0, y=0, z=0, point=None):
if point:
x, y, z = point.xyz
if z == self.coords.z and (self.rect.y1 <= y <= self.rect.y2) and (self.rect.x1 <= x <= self.rect.x2):
return self.tiles[x%16][y%16]
else:
raise Exception("This tile does not belong to this block")
def __repr__(self):
return "<Block(X:{2}-{4}, Y:{3}-{5}, Z:{1.z})>".format(self, self.coords, *self.coords.rect)
class Tile(object):
coords = None
block = None
ttype = None
temperature = None
flags = None
def __init__(self, block, ttype, flags, x=0, y=0, z=0, point=None):
self.ttype = ttype
self.flags = flags
if not point:
point = Point(x, y, z)
self.coords = point
self.block = block
def update(self, ttype, flags):
self.ttype = ttype
self.flags = flags
def reload(self):
self.block.reload()
def save(self):
self.block.save()
def __repr__(self):
return "<Tile({0.ttype} at {1.x}, {1.y}, {1.z})>".format(self, self.coords)

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
"""
Python class for DF_Hack::Construction
"""
from ._pydfhack import _ConstructionManager
from .mixins import NeedsStart
from .decorators import suspend
class Construction(NeedsStart, _ConstructionManager):
api = None
cls = _ConstructionManager
def __init__(self, api, *args, **kwds):
self.cls.__init__(self, args, kwds)
self.api = api
@suspend
def Read(self, *args, **kw):
return self.cls.Read(self, *args, **kw)

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
"""
Python class for DF_Hack::Creature
"""
from ._pydfhack import _CreatureManager
from .mixins import NeedsStart
from .decorators import suspend
class Creature(NeedsStart, _CreatureManager):
api = None
cls = _CreatureManager
def __init__(self, api, *args, **kwds):
self.cls.__init__(self, args, kwds)
self.api = api
@suspend
def Read_Creature(self, *args, **kw):
return self.cls.Read_Creature(self, *args, **kw)
@suspend
def Get_Dwarf_Race_Index(self, *args, **kw):
return self.cls.Get_Dwarf_Race_Index(self, *args, **kw)
@suspend
def Write_Labors(self, *args, **kw):
return self.cls.Write_Labors(self, *args, **kw)
@suspend
def Read_Creature_In_Box(self, *args, **kw):
return self.cls.Read_Creature_In_Box(self, *args, **kw)
@suspend
def Get_Dwarf_Civ_id(self, *args, **kw):
return self.cls.Get_Dwarf_Civ_id(self, *args, **kw)

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
"""
Decorators for bound classes
"""
from decorator import decorator
@decorator
def suspend(func, self, *args, **kw):
"""
This decorator will try to suspend DF and start needed module before running func.
If DF was resumed when decorator was run, it will try to resume back after executing func
"""
susp = not self.api.is_attached or self.api.is_suspended
if self.prepare():
res = func(self, *args, **kw)
if not susp:
self.api.Resume()
return res
else:
raise Exception(u"Could not suspend/start")

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
"""
Python class for DF_Hack::GUI
"""
from ._pydfhack import _GUIManager
class GUI(_GUIManager):
api = None
started = False
def __init__(self, api, *args, **kwds):
_GUIManager.__init__(self, args, kwds)
self.api = api
def prepare(self):
"""
Enforce Suspend/Start
"""
if self.api.prepare():
if not self.started:
self.started = self.Start()
return self.started
else:
return False

@ -0,0 +1,116 @@
# -*- coding: utf-8 -*-
"""
Python class for DF_Hack::Maps
"""
from ._pydfhack import _MapManager
from .mixins import NeedsStart
from .decorators import suspend
from .blocks import Block, Point
class Map(NeedsStart, _MapManager):
api = None
cls = _MapManager
def __init__(self, api, *args, **kwds):
self.cls.__init__(self, args, kwds)
self.api = api
@suspend
def get_size(self):
return self.size
@suspend
def Is_Valid_Block(self, x=0, y=0, z=0, point=None):
"""
Checks if coords are valid
"""
if point:
point = point.get_block()
x, y, z = point.xyz
return self.cls.Is_Valid_Block(self, x, y, z)
@suspend
def Read_Tile_Types(self, x=0, y=0, z=0, point=None):
"""
Returns 16x16 block in form of list of lists.
Should be called either by point or x,y,z coords. Coords are in block form.
"""
if point:
point = point.get_block()
x, y, z = point.xyz
return self.cls.Read_Tile_Types(self, x, y, z)
@suspend
def Write_Tile_Types(self, x=0, y=0, z=0, tiles=None, point=None):
if point:
point = point.get_block()
x, y, z = point.xyz
return self.cls.Write_Tile_Types(self, x, y, z, tiles)
@suspend
def Read_Designations(self, x=0, y=0, z=0, point=None):
"""
Returns 16x16 block in form of list of lists.
"""
if point:
point = point.get_block()
x, y, z = point.xyz
return self.cls.Read_Designations(self, x, y, z)
@suspend
def Write_Designations(self, x=0, y=0, z=0, tiles=None, point=None):
if point:
point = point.get_block()
x, y, z = point.xyz
return self.cls.Write_Designations(self, x, y, z, tiles)
@suspend
def Write_Occupancy(self, *args, **kw):
return self.cls.Write_Occupancy(self, *args, **kw)
@suspend
def Write_Dirty_Bit(self, *args, **kw):
return self.cls.Write_Dirty_Bit(self, *args, **kw)
@suspend
def Write_Block_Flags(self, *args, **kw):
return self.cls.Write_Block_Flags(self, *args, **kw)
@suspend
def Read_Region_Offsets(self, *args, **kw):
return self.cls.Read_Region_Offsets(self, *args, **kw)
@suspend
def Read_Dirty_Bit(self, *args, **kw):
return self.cls.Read_Dirty_Bit(self, *args, **kw)
@suspend
def Read_Occupancy(self, *args, **kw):
return self.cls.Read_Occupancy(self, *args, **kw)
@suspend
def Read_Block_Flags(self, *args, **kw):
return self.cls.Read_Block_Flags(self, *args, **kw)
@suspend
def Read_Geology(self, *args, **kw):
return self.cls.Read_Geology(self, *args, **kw)
@suspend
def Read_Block_40d(self, *args, **kw):
return self.cls.Read_Block_40d(self, *args, **kw)
@suspend
def get_block(self, point):
point = point.get_block()
block = Block(api=self.api, coords=point)
return block
@suspend
def get_tile(self, x=0, y=0, z=0, point=None):
if not point:
point = Point(x, y, z)
block = Block(api=self.api, coords=point.get_block())
return block.get_tile(point=point)

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
"""
Python class for DF_Hack::Materials
"""
from ._pydfhack import _MaterialsManager
from .mixins import NoStart
from .decorators import suspend
class Materials(NoStart, _MaterialsManager):
api = None
cls = _MaterialsManager
def __init__(self, api, *args, **kwds):
cls.__init__(self, args, kwds)
self.api = api
@suspend
def Read_Wood_Materials(self, *args, **kw):
return self.cls.Read_Wood_Materials(self, *args, **kw)
@suspend
def Read_Plant_Materials(self, *args, **kw):
return self.cls.Read_Plant_Materials(self, *args, **kw)
@suspend
def Read_Inorganic_Materials(self, *args, **kw):
return self.cls.Read_Inorganic_Materials(self, *args, **kw)
@suspend
def Read_Descriptor_Colors(self, *args, **kw):
return self.cls.Read_Descriptor_Colors(self, *args, **kw)
@suspend
def Read_Creature_Types(self, *args, **kw):
return self.cls.Read_Creature_Types(self, *args, **kw)
@suspend
def Read_Organic_Materials(self, *args, **kw):
return self.cls.Read_Organic_Materials(self, *args, **kw)
@suspend
def Read_Creature_Types_Ex(self, *args, **kw):
return self.cls.Read_Creature_Types_Ex(self, *args, **kw)

@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
"""
Python class for DF_Hack::MemInfo
"""
from ._pydfhack import _MemInfo
from .mixins import NoStart
from .decorators import suspend
class MemInfo(NoStart, _MemInfo):
api = None
cls = _MemInfo
def __init__(self, api, *args, **kwds):
self.cls.__init__(self, args, kwds)
self.api = api
## Properties:
# version
# base
## No idea if these should work only on suspend. To check later.
def Rebase_All(self, *args, **kw):
return self.cls.Rebase_All(self, *args, **kw)
def Set_String(self, *args, **kw):
return self.cls.Set_String(self, *args, **kw)
def Resolve_Object_To_Class_ID(self, *args, **kw):
return self.cls.Resolve_Object_To_Class_ID(self, *args, **kw)
def Get_Trait(self, *args, **kw):
return self.cls.Get_Trait(self, *args, **kw)
def Get_Job(self, *args, **kw):
return self.cls.Get_Job(self, *args, **kw)
def Rebase_VTable(self, *args, **kw):
return self.cls.Rebase_VTable(self, *args, **kw)
def Get_String(self, *args, **kw):
return self.cls.Get_String(self, *args, **kw)
def Get_Trait_Name(self, *args, **kw):
return self.cls.Get_Trait_Name(self, *args, **kw)
def Set_Job(self, *args, **kw):
return self.cls.Set_Job(self, *args, **kw)
def Set_Offset(self, *args, **kw):
return self.cls.Set_Offset(self, *args, **kw)
def Rebase_Addresses(self, *args, **kw):
return self.cls.Rebase_Addresses(self, *args, **kw)
def Resolve_Classname_To_Class_ID(self, *args, **kw):
return self.cls.Resolve_Classname_To_Class_ID(self, *args, **kw)
def Set_Labor(self, *args, **kw):
return self.cls.Set_Labor(self, *args, **kw)
def Get_Skill(self, *args, **kw):
return self.cls.Get_Skill(self, *args, **kw)
def Set_Profession(self, *args, **kw):
return self.cls.Set_Profession(self, *args, **kw)
def Get_Profession(self, *args, **kw):
return self.cls.Get_Profession(self, *args, **kw)
def Get_Offset(self, *args, **kw):
return self.cls.Get_Offset(self, *args, **kw)
def Get_HexValue(self, *args, **kw):
return self.cls.Get_HexValue(self, *args, **kw)
def Set_Address(self, *args, **kw):
return self.cls.Set_Address(self, *args, **kw)
def Set_HexValue(self, *args, **kw):
return self.cls.Set_HexValue(self, *args, **kw)
def Get_Address(self, *args, **kw):
return self.cls.Get_Address(self, *args, **kw)
def Set_Trait(self, *args, **kw):
return self.cls.Set_Trait(self, *args, **kw)
def Resolve_Classname_To_VPtr(self, *args, **kw):
return self.cls.Resolve_Classname_To_VPtr(self, *args, **kw)
def Get_Labor(self, *args, **kw):
return self.cls.Get_Labor(self, *args, **kw)
def Set_Skill(self, *args, **kw):
return self.cls.Set_Skill(self, *args, **kw)
def Resolve_Class_ID_To_Classname(self, *args, **kw):
return self.cls.Resolve_Class_ID_To_Classname(self, *args, **kw)

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
"""
Mix-ins for bound classes
"""
class NeedsStart(object):
"""
This mixin enforces Start/Finish routines
"""
started = False
def prepare(self):
"""
Enforce Suspend/Start
"""
if self.api.prepare():
if not self.started:
self.Start()
return self.started
else:
return False
def Start(self):
if self.started:
return True
if self.api.prepare():
self.started = self.cls.Start(self)
if self.started:
self.api.started.append(self)
return self.started
else:
return False
start = Start
def Finish(self):
if self.started:
self.cls.Finish(self)
self.started = False
if self in self.api.started:
self.api.started.remove(self)
finish = Finish
class NoStart(object):
"""
This mixin enforces Suspend, and disables Start/Finish
"""
def prepare(self):
"""
Enforce Suspend
"""
return self.api.prepare()
def Start(self):
raise Exception("{0.cls} does not need Start()".format(self))
start = Start
def Finish(self):
raise Exception("{0.cls} does not need Finish()".format(self))
finish = Finish

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
"""
Python class for DF_Hack::Position
"""
from ._pydfhack import _PositionManager
from .blocks import Point, Block
from .mixins import NoStart
from .decorators import suspend
class Position(NoStart, _PositionManager):
api = None
cls = _PositionManager
def __init__(self, api, *args, **kwds):
self.cls.__init__(self, args, kwds)
self.api = api
@suspend
def get_cursor(self):
coords = self.cursor_coords
if coords:
return Point(*coords)
else:
return None
@suspend
def get_window_size(self):
wsize = self.window_size
return wsize
@suspend
def get_view_coords(self):
coords = self.view_coords
return Point(*coords)
@suspend
def get_cursor_tile(self):
point = self.get_cursor()
if point:
tile = self.api.maps.get_tile(point=point)
return tile
else:
return None

@ -0,0 +1,71 @@
import _pydfhack, os, copy
from .blocks import Point, Block
from .meminfo import MemInfo
from .position import Position
from .materials import Materials
from .creature import Creature
from .map import Map
from .translation import Translation
from .construction import Construction
from .vegetation import Vegetation
from .gui import GUI
class API(_pydfhack._API):
started = None
path = os.path.dirname(os.path.abspath(__file__))
datafile = os.path.join(path, "Memory.xml")
if not os.path.isfile(datafile):
raise ImportError, "Memory.xml not found."
# Rude hack to bypass xml location restrictions
datafile = "./" + "../"*20 + datafile
def prepare(self):
"""
Enforce Attach/Suspend behavior.
Return True if succeeded, else False
"""
r = True
if not self.is_attached:
r = self.Attach()
if r and not self.is_suspended:
r = self.Suspend()
return r
def __init__(self, *args, **kwds):
_pydfhack._API.__init__(self, API.datafile)
self._mem_info_mgr_type = MemInfo
self._position_mgr_type = Position
self._material_mgr_type = Materials
self._creature_mgr_type = Creature
self._map_mgr_type = Map
self._translate_mgr_type = Translation
self._construction_mgr_type = Construction
self._vegetation_mgr_type = Vegetation
self._gui_mgr_type = GUI
self.started = []
def Attach(self, *args, **kw):
print "API.Attach()"
return _pydfhack._API.Attach(self, *args, **kw)
def Detach(self, *args, **kw):
print "API.Detach()"
return _pydfhack._API.Detach(self, *args, **kw)
def Suspend(self, *args, **kw):
print "API.Suspend()"
return _pydfhack._API.Suspend(self, *args, **kw)
def Resume(self):
print "API.Resume()"
# Reference counting is fcked, so leave it alone for now
## Explicitly Finish() all started modules
#print self.started
#started = copy.copy(self.started)
#print started
#for m in started:
# print m
# m.Finish()
#self.started = []
return _pydfhack._API.Resume(self)

@ -1,3 +1,4 @@
from ctypes import *
from collections import namedtuple
Position2D = namedtuple("Position2D", "x, y")
@ -13,12 +14,12 @@ Attribute = namedtuple("Attribute", "level, field_4, field_8, field_C, leveldiff
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")
Name = namedtuple("Name", "first_name, nickname, language, has_name, words, parts_of_speech")
char_array = c_char * 128
class Soul(object):
def __init__(self, *args, **kwds):
if kwds:
@ -26,4 +27,24 @@ class Soul(object):
self.__dict__[k] = v
class MapBlock40d(object):
pass
pass
class ViewScreen(Structure):
_fields_ = [("type", c_int)]
class Matgloss(Structure):
_fields_ = [("id", char_array),
("fore", c_byte),
("back", c_byte),
("bright", c_byte),
("name", char_array)]
class Descriptor_Color(Structure):
_fields_ = [("id", char_array),
("r", c_float),
("v", c_float),
("b", c_float),
("name", char_array)]
class MatglossOther(Structure):
_fields_ = [("rawname", char_array)]

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
"""
Python class for DF_Hack::Translation
"""
from ._pydfhack import _TranslationManager
from .mixins import NeedsStart
from .decorators import suspend
class Translation(NeedsStart, _TranslationManager):
api = None
cls = _TranslationManager
def __init__(self, api, *args, **kwds):
self.cls.__init__(self, args, kwds)
self.api = api
def get_dictionaries(self):
return self.dictionaries
def Translate_Name(self, *args, **kw):
return self.cls.Translate_Name(self, *args, **kw)

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
"""
Python class for DF_Hack::Vegetation
"""
from ._pydfhack import _VegetationManager
from .mixins import NeedsStart
from .decorators import suspend
class Vegetation(NeedsStart, _VegetationManager):
api = None
cls = _VegetationManager
def __init__(self, api, *args, **kwds):
self.cls.__init__(self, args, kwds)
self.api = api
@suspend
def Read(self, *args, **kw):
return self.cls.Read(self, *args, **kw)

@ -1,12 +1,59 @@
# -*- coding: utf-8 -*-
from distutils.core import setup, Extension
try:
from setuptools import setup, find_packages
except ImportError:
from ez_setup import use_setuptools
use_setuptools()
from setuptools import setup, find_packages
from distutils.core import Extension
from os import path
import platform
e = Extension("pydfhack",
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"])
if platform.system() == 'Windows':
# dfhack.lib location can differ, search for it
for libdir in ["..", path.join("..",".."), path.join("..", "..", "output"), path.join("..", "..", "output", "Release")]:
if path.isfile(path.join(libdir, "dfhack.lib")):
lib_dirs = libdir
libraries=["dfhack"]
break
if path.isfile(path.join(libdir, "libdfhack.dll")):
lib_dirs = libdir
libraries = ["libdfhack"]
break
else:
raise Exception("dfhack.lib is not found")
osspec = dict(library_dirs=[lib_dirs],
libraries=libraries)
elif platform.system() == 'Linux':
osspec = dict(extra_compile_args=["-DLINUX_BUILD", "-w"],
library_dirs=[path.join("..","..","output")],
libraries=["dfhack"])
setup(name="PyDFHack", version="1.0", ext_modules=[e])
e = Extension("pydfhack._pydfhack",
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=["../", path.join("..", "include"), path.join("..","depends","md5"), path.join("..","depends","tinyxml")],
export_symbols=["init_pydfhack", "ReadRaw", "WriteRaw"],
**osspec)
for file in ["Memory.xml", path.join("..","..","output","Memory.xml")]:
if path.isfile(file):
datafile = file
break
else:
raise Exception("Memory.xml is not found.")
setup(
name="PyDFHack",
description="Python wrapper and bindings for DFHack library",
version="1.0",
packages=find_packages(exclude=['ez_setup']),
data_files=[('pydfhack', [datafile])],
include_package_data=True,
test_suite='nose.collector',
zip_safe=False,
ext_modules=[e],
)

@ -0,0 +1,38 @@
#!/usr/bin/python
import sys
import pydfhack
DF = pydfhack.API("Memory.xml")
DF.Attach()
pos = DF.position
maps = DF.maps
refc = dict(pydfhack=pydfhack, API=pydfhack.API, DF=DF, pos=pos, maps=maps)
cursor = pos.get_cursor()
msize = maps.get_size()
block = None
tile = None
if cursor:
block = maps.get_block(point=cursor)
if block:
tile = block.get_tile(point=cursor)
DF.Resume()
locs = dict(pydfhack=pydfhack, API=pydfhack.API, DF=DF, pos=pos, maps=maps, msize=msize, cursor=cursor, block=block, tile=tile)
banner = """DFHack Shell\n\n"""\
"""\tpydfhack = {pydfhack}\n"""\
"""\tAPI = {API}\n"""\
"""\tDF = {DF}\n"""\
"""\tpos = {pos}\n"""\
"""\tmaps = {maps}\n"""\
"""\tmsize = {msize}\n"""\
"""\tcursor = {cursor}\n"""\
"""\tblock = {block}\n"""\
"""\ttile = {tile}\n""".format(**locs)
from IPython.Shell import IPShellEmbed
shell = IPShellEmbed()
shell.set_banner(shell.IP.BANNER + '\n\n' + banner)
shell(local_ns=locs, global_ns={})
DF.Detach()

@ -0,0 +1,45 @@
#!/usr/bin/python
import sys
import pydfhack
from pydfhack.blocks import Point
DF = pydfhack.API("Memory.xml")
DF.Attach()
pos = DF.position
maps = DF.maps
cursor = pos.get_cursor()
refc = dict(pydfhack=pydfhack, API=pydfhack.API, DF=DF, pos=pos, maps=maps)
msize = maps.get_size()
print msize
locs = dict(pydfhack=pydfhack, API=pydfhack.API, DF=DF, pos=pos, maps=maps, msize=msize, cursor=cursor)
for z in range(msize[2]):
trees = 0
saplings = 0
dead_saplings = 0
for x in range(msize[0]):
for y in range(msize[1]):
p = Point(x, y, z, True)
block = maps.get_block(point=p)
changed = False
if not block.tiles:
break
for tx in range(16):
for ty in range(16):
tile = block.tiles[tx][ty]
if tile.ttype == 24:
trees += 1
elif tile.ttype == 231:
saplings += 1
tile.ttype = 24
changed = True
elif tile.ttype == 392:
dead_saplings += 1
tile.ttype = 24
changed = True
if changed:
block.save()
print "Saved block {0}".format(block)
print "Z-Level {0}: Trees {1}, Saplings {2}, Dead saplings {3}".format(z, trees, saplings, dead_saplings)
DF.Resume()
DF.Detach()

@ -74,6 +74,10 @@ TARGET_LINK_LIBRARIES(dfspatterdump dfhack)
ADD_EXECUTABLE(dfcatsplosion catsplosion.cpp)
TARGET_LINK_LIBRARIES(dfcatsplosion dfhack)
# flows - check flows impact on fps
ADD_EXECUTABLE(dfflows flows.cpp)
TARGET_LINK_LIBRARIES(dfflows dfhack)
IF(UNIX)
SET(CURSES_NEED_WIDE "YES")
SET(CURSES_NEED_NCURSES "NO")

@ -0,0 +1,83 @@
// This is a reveal program. It reveals the map.
#include <iostream>
#include <integers.h>
#include <vector>
using namespace std;
#include <DFTypes.h>
#include <DFHackAPI.h>
#include <modules/Maps.h>
int main (void)
{
uint32_t x_max,y_max,z_max;
DFHack::designations40d designations;
DFHack::API DF("Memory.xml");
try
{
DF.Attach();
}
catch (exception& e)
{
cerr << e.what() << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::Maps *Maps =DF.getMaps();
// init the map
if(!Maps->Start())
{
cerr << "Can't init map." << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DFHack::t_blockflags bflags;
Maps->getSize(x_max,y_max,z_max);
// walk the map, count flowing tiles, magma, water
uint32_t flow1=0, flow2=0, flowboth=0, water=0, magma=0;
cout << "Counting flows and liquids .";
for(uint32_t x = 0; x< x_max;x++)
{
for(uint32_t y = 0; y< y_max;y++)
{
for(uint32_t z = 0; z< z_max;z++)
{
if(Maps->isValidBlock(x,y,z))
{
Maps->ReadBlockFlags(x, y, z, bflags);
Maps->ReadDesignations(x, y, z, &designations);
if (bflags.bits.liquid_1)
flow1++;
if (bflags.bits.liquid_2)
flow2++;
if (bflags.bits.liquid_1 && bflags.bits.liquid_2)
flowboth++;
for (uint32_t i = 0; i < 16;i++) for (uint32_t j = 0; j < 16;j++)
{
if (designations[i][j].bits.liquid_type == DFHack::liquid_magma)
magma++;
if (designations[i][j].bits.liquid_type == DFHack::liquid_water)
water++;
}
// Maps->WriteDesignations(x, y, z, &designations);
// Maps->WriteBlockFlags(x, y, z, bflags);
cout << ".";
}
}
}
}
cout << endl << "Done." << endl;
cout << "Blocks with liquid_1=true: " << flow1 << endl;
cout << "Blocks with liquid_2=true: " << flow2 << endl;
cout << "Blocks with both: " << flowboth << endl;
cout << "Water tiles: " << water << endl;
cout << "Magma tiles: " << magma << endl;
return 0;
}

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
import pydfhack
DF = pydfhack._API("Memory.xml")
from pydfhack import API
DF = API("Memory.xml")
if DF.Attach():
Mats = DF.materials