370 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
			
		
		
	
	
			370 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
| /*
 | |
| 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 __DFHELPERS__
 | |
| #define __DFHELPERS__
 | |
| 
 | |
| #include "Python.h"
 | |
| #include <stdio.h>
 | |
| #include <string.h>
 | |
| #include <string>
 | |
| #include <vector>
 | |
| 
 | |
| using namespace std;
 | |
| 
 | |
| #include "DFTypes.h"
 | |
| #include "DF_Imports.cpp"
 | |
| 
 | |
| using namespace DFHack;
 | |
| 
 | |
| #include "modules/Materials.h"
 | |
| #include "modules/Creatures.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;
 | |
| 	PyObject* temp;
 | |
| 	
 | |
| 	temp = PyTuple_GetItem(mObj, 0);
 | |
| 	
 | |
| 	mPair.type = (int16_t)PyInt_AsLong(temp);
 | |
| 	
 | |
| 	Py_DECREF(temp);
 | |
| 	
 | |
| 	temp = PyTuple_GetItem(mObj, 1);
 | |
| 	
 | |
| 	mPair.index = (int32_t)PyInt_AsLong(temp);
 | |
| 	
 | |
| 	Py_DECREF(temp);
 | |
| 	
 | |
| 	return mPair;
 | |
| }
 | |
| 
 | |
| static PyObject* BuildSkill(DFHack::t_skill& skill)
 | |
| {
 | |
| 	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)
 | |
| {
 | |
| 	PyObject* list = PyList_New(numSkills);
 | |
| 	
 | |
| 	for(int i = 0; i < numSkills; i++)
 | |
| 		PyList_SET_ITEM(list, i, BuildSkill(skills[i]));
 | |
| 	
 | |
| 	return list;
 | |
| }
 | |
| 
 | |
| static PyObject* BuildJob(DFHack::t_job& job)
 | |
| {
 | |
| 	return Py_BuildValue("Oi", PyBool_FromLong((int)job.active), job.jobId);
 | |
| }
 | |
| 
 | |
| static PyObject* BuildAttribute(DFHack::t_attrib& at)
 | |
| {
 | |
| 	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)
 | |
| {
 | |
| 	return Py_BuildValue("ss", item.id, item.name);
 | |
| }
 | |
| */
 | |
| static PyObject* BuildLike(DFHack::t_like& like)
 | |
| {
 | |
| 	PyObject* item;
 | |
| 	
 | |
| 	item = Py_BuildValue("iii", like.type, like.itemClass, like.itemIndex);
 | |
| 	
 | |
| 	return Py_BuildValue("OOO", item, BuildMatglossPair(like.material), PyBool_FromLong((int)like.active));
 | |
| }
 | |
| 
 | |
| static PyObject* BuildNote(DFHack::t_note& note)
 | |
| {
 | |
| 	PyObject* noteObj;
 | |
| 	PyObject *args, *position;
 | |
| 	
 | |
| 	args = Py_BuildValue("III", note.x, note.y, note.z);
 | |
| 	
 | |
| 	position = PyObject_CallObject(Position3D_type, args);
 | |
| 	
 | |
| 	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;
 | |
| }
 | |
| 
 | |
| static int NAME_WORD_COUNT = 7;
 | |
| 
 | |
| static PyObject* BuildName(DFHack::t_name& name)
 | |
| {
 | |
| 	PyObject* nameObj;
 | |
| 	PyObject *wordList, *speechList, *args;
 | |
| 	
 | |
| 	wordList = PyList_New(NAME_WORD_COUNT);
 | |
| 	speechList = PyList_New(NAME_WORD_COUNT);
 | |
| 	
 | |
| 	for(int i = 0; i < NAME_WORD_COUNT; i++)
 | |
| 	{
 | |
| 		PyList_SET_ITEM(wordList, i, PyInt_FromLong(name.words[i]));
 | |
| 		PyList_SET_ITEM(speechList, i, PyInt_FromLong(name.parts_of_speech[i]));
 | |
| 	}
 | |
| 	
 | |
| 	args = Py_BuildValue("ssiOOO", name.first_name, name.nickname, name.language, \
 | |
| 									PyBool_FromLong((int)name.has_name), wordList, speechList);
 | |
| 	
 | |
| 	nameObj = PyObject_CallObject(Name_type, args);
 | |
| 	
 | |
| 	Py_DECREF(args);
 | |
| 	
 | |
| 	return nameObj;
 | |
| }
 | |
| 
 | |
| static DFHack::t_name ReverseBuildName(PyObject* nameObj)
 | |
| {
 | |
| 	PyObject *temp, *listTemp;
 | |
| 	int boolTemp;
 | |
| 	Py_ssize_t strLength;
 | |
| 	char* strTemp;
 | |
| 	DFHack::t_name name;
 | |
| 	
 | |
| 	temp = PyObject_GetAttrString(nameObj, "language");
 | |
| 	name.language = (uint32_t)PyInt_AsLong(temp);
 | |
| 	
 | |
| 	temp = PyObject_GetAttrString(nameObj, "has_name");
 | |
| 	
 | |
| 	boolTemp = (int)PyInt_AsLong(temp);
 | |
| 	
 | |
| 	Py_DECREF(temp);
 | |
| 	
 | |
| 	if(boolTemp != 0)
 | |
| 		name.has_name = true;
 | |
| 	else
 | |
| 		name.has_name = false;
 | |
| 	
 | |
| 	listTemp = PyObject_GetAttrString(nameObj, "words");
 | |
| 	
 | |
| 	for(int i = 0; i < NAME_WORD_COUNT; i++)
 | |
| 		name.words[i] = (uint32_t)PyInt_AsLong(PyList_GetItem(listTemp, i));
 | |
| 	
 | |
| 	Py_DECREF(listTemp);
 | |
| 	
 | |
| 	listTemp = PyObject_GetAttrString(nameObj, "parts_of_speech");
 | |
| 	
 | |
| 	for(int i = 0; i < NAME_WORD_COUNT; i++)
 | |
| 		name.parts_of_speech[i] = (uint16_t)PyInt_AsLong(PyList_GetItem(listTemp, i));
 | |
| 	
 | |
| 	Py_DECREF(listTemp);
 | |
| 	
 | |
| 	temp = PyObject_GetAttrString(nameObj, "first_name");
 | |
| 	strLength = PyString_Size(temp);
 | |
| 	strTemp = PyString_AsString(temp);
 | |
| 	
 | |
| 	Py_DECREF(temp);
 | |
| 	
 | |
| 	if(strLength > 128)
 | |
| 	{
 | |
| 		strncpy(name.first_name, strTemp, 127);
 | |
| 		name.first_name[127] = '\0';
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		strncpy(name.first_name, strTemp, strLength);
 | |
| 		name.first_name[strLength] = '\0';
 | |
| 	}
 | |
| 	
 | |
| 	temp = PyObject_GetAttrString(nameObj, "nickname");
 | |
| 	strLength = PyString_Size(temp);
 | |
| 	strTemp = PyString_AsString(temp);
 | |
| 	
 | |
| 	Py_DECREF(temp);
 | |
| 	
 | |
| 	if(strLength > 128)
 | |
| 	{
 | |
| 		strncpy(name.nickname, strTemp, 127);
 | |
| 		name.nickname[127] = '\0';
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		strncpy(name.nickname, strTemp, strLength);
 | |
| 		name.nickname[strLength] = '\0';
 | |
| 	}
 | |
| 	
 | |
| 	return name;
 | |
| }
 | |
| 
 | |
| static PyObject* BuildSettlement(DFHack::t_settlement& settlement)
 | |
| {
 | |
| 	PyObject* setObj;
 | |
| 	PyObject *world_pos, *local_pos, *args;
 | |
| 	
 | |
| 	args = Py_BuildValue("ii", settlement.world_x, settlement.world_y);
 | |
| 	
 | |
| 	world_pos = PyObject_CallObject(Position2D_type, args);
 | |
| 	
 | |
| 	Py_DECREF(args);
 | |
| 	
 | |
| 	args = Py_BuildValue("iiii", settlement.local_x1, settlement.local_y1, settlement.local_x2, settlement.local_y2);
 | |
| 	
 | |
| 	local_pos = PyObject_CallObject(Rectangle_type, args);
 | |
| 	
 | |
| 	Py_DECREF(args);
 | |
| 	
 | |
| 	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, *emptyArgs;
 | |
| 	PyObject* soulObj;
 | |
| 	
 | |
| 	emptyArgs = Py_BuildValue("()");
 | |
| 	
 | |
| 	soulDict = PyDict_New();
 | |
| 	
 | |
| 	skillList = BuildSkillList(soul.skills, soul.numSkills);
 | |
| 	DICTADD(soulDict, "skills", skillList);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.analytical_ability);
 | |
| 	DICTADD(soulDict, "analytical_ability", temp);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.focus);
 | |
| 	DICTADD(soulDict, "focus", temp);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.willpower);
 | |
| 	DICTADD(soulDict, "willpower", temp);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.creativity);
 | |
| 	DICTADD(soulDict, "creativity", temp);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.intuition);
 | |
| 	DICTADD(soulDict, "intuition", temp);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.patience);
 | |
| 	DICTADD(soulDict, "patience", temp);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.memory);
 | |
| 	DICTADD(soulDict, "memory", temp);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.linguistic_ability);
 | |
| 	DICTADD(soulDict, "linguistic_ability", temp);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.spatial_sense);
 | |
| 	DICTADD(soulDict, "spatial_sense", temp);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.musicality);
 | |
| 	DICTADD(soulDict, "musicality", temp);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.kinesthetic_sense);
 | |
| 	DICTADD(soulDict, "kinesthetic_sense", temp);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.empathy);
 | |
| 	DICTADD(soulDict, "empathy", temp);
 | |
| 	
 | |
| 	temp = BuildAttribute(soul.social_awareness);	
 | |
| 	DICTADD(soulDict, "social_awareness", temp);
 | |
| 	
 | |
| 	soulObj = PyObject_Call(Soul_type, emptyArgs, soulDict);
 | |
| 	
 | |
| 	Py_DECREF(emptyArgs);
 | |
| 	
 | |
| 	return soulObj;
 | |
| }
 | |
| 
 | |
| #endif
 |