Reveal and prospector tools work. Basic inorganic matgloss works. Basic map reading works.

develop
Petr Mrázek 2010-04-03 03:52:46 +02:00
parent 021fb1e0e9
commit 7d48ea49ae
20 changed files with 1414 additions and 1457 deletions

@ -34,8 +34,9 @@ include_directories (${CMAKE_SOURCE_DIR}/dfhack/depends/argstream/)
add_subdirectory (dfhack)
add_subdirectory (dfhack/shm)
add_subdirectory (dfhack/depends/md5)
add_subdirectory (dfhack/depends/tinyxml)
#FIXME: add exports for MSVC
#add_subdirectory (dfhack/depends/md5)
#add_subdirectory (dfhack/depends/tinyxml)
#add_subdirectory (dfhack/depends/argstream)
add_subdirectory (tools)
add_subdirectory (examples)

@ -0,0 +1,35 @@
#include "DFCommonInternal.h"
#include <shms.h>
#include <mod-core.h>
#include <mod-maps.h>
#include <mod-creature40d.h>
using namespace DFHack;
#include "private/APIPrivate.h"
APIPrivate::APIPrivate()
{
}
bool APIPrivate::InitReadNames()
{
try
{
name_firstname_offset = offset_descriptor->getOffset("name_firstname");
name_nickname_offset = offset_descriptor->getOffset("name_nickname");
name_words_offset = offset_descriptor->getOffset("name_words");
}
catch(Error::MissingMemoryDefinition)
{
return false;
}
return true;
}
void APIPrivate::readName(t_name & name, uint32_t address)
{
g_pProcess->readSTLString(address + name_firstname_offset , name.first_name, 128);
g_pProcess->readSTLString(address + name_nickname_offset , name.nickname, 128);
g_pProcess->read(address + name_words_offset ,48, (uint8_t *) name.words);
}

@ -20,15 +20,30 @@ SET(PROJECT_SRCS
DFMemInfo.cpp
DFMemInfoManager.cpp
DFHackAPI.cpp
APIPrivate.cpp
DFTileTypes.cpp
DFVector.cpp
depends/md5/md5.cpp
depends/md5/md5wrapper.cpp
depends/tinyxml/tinystr.cpp
depends/tinyxml/tinyxml.cpp
depends/tinyxml/tinyxmlerror.cpp
depends/tinyxml/tinyxmlparser.cpp
modules/Creatures.cpp
modules/Gui.cpp
modules/Maps.cpp
modules/Materials.cpp
modules/Position.cpp
)
SET(PROJECT_HDRS_LINUX
)
SET(PROJECT_HDRS_WINDOWS
stdint_win.h
include/stdint_win.h
)
SET(PROJECT_SRCS_LINUX
@ -75,9 +90,9 @@ IF(UNIX)
SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -pedantic")
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden")
SET(PROJECT_LIBS ${X11_LIBRARY} rt dfhack-md5 tixml-static)
SET(PROJECT_LIBS ${X11_LIBRARY} rt ) #dfhack-md5 dfhack-tixml
ELSE(UNIX)
SET(PROJECT_LIBS psapi dfhack-md5 tixml-static)
SET(PROJECT_LIBS psapi)
ENDIF(UNIX)
ADD_LIBRARY(dfhack SHARED ${PROJECT_SRCS})

File diff suppressed because it is too large Load Diff

@ -22,8 +22,8 @@ must not be misrepresented as being the original software.
distribution.
*/
#include "DFCommonInternal.h"
#include "../shmserver/shms.h"
#include "../shmserver/mod-core.h"
#include "shms.h"
#include "mod-core.h"
using namespace DFHack;
// a full memory barrier! better be safe than sorry.

@ -1,18 +1 @@
# main project file. use it from a build sub-folder, see COMPILE for details
PROJECT (dfhack-md5)
cmake_minimum_required(VERSION 2.6)
# disable warning, autosearch
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
if("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")
message(SEND_ERROR "In-source builds are not allowed.")
endif("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")
IF(NOT DEFINED CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
ENDIF(NOT DEFINED CMAKE_BUILD_TYPE)
ADD_LIBRARY(dfhack-md5 SHARED md5.cpp md5wrapper.cpp)

@ -1,18 +1 @@
# main project file. use it from a build sub-folder, see COMPILE for details
PROJECT (dfhack-tixml)
cmake_minimum_required(VERSION 2.6)
# disable warning, autosearch
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
if("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")
message(SEND_ERROR "In-source builds are not allowed.")
endif("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")
IF(NOT DEFINED CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.")
ENDIF(NOT DEFINED CMAKE_BUILD_TYPE)
ADD_LIBRARY(tixml-static SHARED tinystr.cpp tinyxml.cpp tinyxmlerror.cpp tinyxmlparser.cpp)
ADD_LIBRARY(dfhack-tixml SHARED tinystr.cpp tinyxml.cpp tinyxmlerror.cpp tinyxmlparser.cpp)

@ -37,15 +37,16 @@ distribution.
namespace DFHack
{
class APIPrivate;
class memory_info;
class Process;
class DFHACK_EXPORT API
{
class Private;
Private * const d;
APIPrivate * const d;
public:
API(const std::string path_to_xml);
~API();
/*
* Basic control over DF's process state
*/
@ -67,235 +68,113 @@ namespace DFHack
/// forces resume on Windows. This can be a bad thing with multiple DF tools running!
bool ForceResume();
/*
* Query the DF's GUI state
*/
///true if paused, false if not
bool ReadPauseState();
/// read the DF menu view state (stock screen, unit screen, other screens
bool ReadViewScreen(t_viewscreen &);
/// read the DF menu state (designation menu ect)
uint32_t ReadMenuState();
/*
* Matgloss. next four methods look very similar. I could use two and move the processing one level up...
* I'll keep it like this, even with the code duplication as it will hopefully get more features and separate data types later.
* Yay for nebulous plans for a rock survey tool that tracks how much of which metal could be smelted from available resorces
*/
bool ReadStoneMatgloss(std::vector<t_matgloss> & output);
bool ReadWoodMatgloss (std::vector<t_matgloss> & output);
bool ReadMetalMatgloss(std::vector<t_matgloss> & output);
bool ReadPlantMatgloss(std::vector<t_matgloss> & output);
bool ReadPlantMatgloss (std::vector<t_matglossPlant> & plants);
bool ReadCreatureMatgloss(std::vector<t_matgloss> & output);
// read region surroundings, get their vectors of geolayers so we can do translation (or just hand the translation table to the client)
// returns an array of 9 vectors of indices into stone matgloss
/**
Method for reading the geological surrounding of the currently loaded region.
assign is a reference to an array of nine vectors of unsigned words that are to be filled with the data
array is indexed by the BiomeOffset enum
I omitted resolving the layer matgloss in this API, because it would
introduce overhead by calling some method for each tile. You have to do it
yourself. First get the stuff from ReadGeology and then for each block get
the RegionOffsets. For each tile get the real region from RegionOffsets and
cross-reference it with the geology stuff (region -- array of vectors, depth --
vector). I'm thinking about turning that Geology stuff into a
two-dimensional array with static size.
this is the algorithm for applying matgloss:
void DfMap::applyGeoMatgloss(Block * b)
{
// load layer matgloss
for(int x_b = 0; x_b < BLOCK_SIZE; x_b++)
{
for(int y_b = 0; y_b < BLOCK_SIZE; y_b++)
{
int geolayer = b->designation[x_b][y_b].bits.geolayer_index;
int biome = b->designation[x_b][y_b].bits.biome;
b->material[x_b][y_b].type = Mat_Stone;
b->material[x_b][y_b].index = v_geology[b->RegionOffsets[biome]][geolayer];
}
}
}
*/
bool ReadGeology( std::vector < std::vector <uint16_t> >& assign );
/*
* BLOCK DATA
*/
/// allocate and read pointers to map blocks
bool InitMap();
/// destroy the mapblock cache
bool DestroyMap();
/// get size of the map in tiles
void getSize(uint32_t& x, uint32_t& y, uint32_t& z);
/**
* Return false/0 on failure, buffer allocated by client app, 256 items long
*/
bool isValidBlock(uint32_t blockx, uint32_t blocky, uint32_t blockz);
/**
* Get the address of a block or 0 if block is not valid
*/
uint32_t getBlockPtr (uint32_t blockx, uint32_t blocky, uint32_t blockz);
/// read the whole map block at block coords (see DFTypes.h for the block structure)
bool ReadBlock40d(uint32_t blockx, uint32_t blocky, uint32_t blockz, mapblock40d * buffer);
/// read/write block tile types
bool ReadTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, tiletypes40d *buffer);
bool WriteTileTypes(uint32_t blockx, uint32_t blocky, uint32_t blockz, tiletypes40d *buffer);
/// read/write block designations
bool ReadDesignations(uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer);
bool WriteDesignations (uint32_t blockx, uint32_t blocky, uint32_t blockz, designations40d *buffer);
/// read/write block occupancies
bool ReadOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer);
bool WriteOccupancy(uint32_t blockx, uint32_t blocky, uint32_t blockz, occupancies40d *buffer);
/// read/write the block dirty bit - this is used to mark a map block so that DF scans it for designated jobs like digging
bool ReadDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool &dirtybit);
bool WriteDirtyBit(uint32_t blockx, uint32_t blocky, uint32_t blockz, bool dirtybit);
/// read/write the block flags
bool ReadBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags &blockflags);
bool WriteBlockFlags(uint32_t blockx, uint32_t blocky, uint32_t blockz, t_blockflags blockflags);
memory_info *getMemoryInfo();
Process * getProcess();
DFWindow * getWindow();
/// read region offsets of a block - used for determining layer stone matgloss
bool ReadRegionOffsets(uint32_t blockx, uint32_t blocky, uint32_t blockz, biome_indices40d *buffer);
/// read/write size bytes of raw data at offset. DANGEROUS, CAN SEGFAULT DF!
void ReadRaw (const uint32_t offset, const uint32_t size, uint8_t *target);
void WriteRaw (const uint32_t offset, const uint32_t size, uint8_t *source);
/// read aggregated veins of a block
bool ReadVeins(uint32_t blockx, uint32_t blocky, uint32_t blockz, std::vector <t_vein> & veins, std::vector <t_frozenliquidvein>& ices);
#include "../modules/Position-proc.h"
#include "../modules/Gui-proc.h"
#include "../modules/Maps-proc.h"
#include "../modules/Materials-proc.h"
#include "../modules/Creatures-proc.h"
/*
* Constructions (costructed walls, floors, ramps, etc...)
*/
/*
/// start reading constructions. numconstructions is an output - total constructions present
bool InitReadConstructions( uint32_t & numconstructions );
/// read a construiction at index
bool ReadConstruction(const int32_t index, t_construction & construction);
/// cleanup after reading constructions
void FinishReadConstructions();
*/
/*
* Buildings - also includes zones and stockpiles
*/
/*
bool InitReadBuildings ( uint32_t & numbuildings );
bool ReadBuilding(const int32_t index, t_building & building);
void FinishReadBuildings();
*/
/*
* Effects like mist, dragonfire or dust
*/
/*
bool InitReadEffects ( uint32_t & numeffects );
bool ReadEffect(const uint32_t index, t_effect_df40d & effect);
bool WriteEffect(const uint32_t index, const t_effect_df40d & effect);
void FinishReadEffects();
*/
/*
* Trees and shrubs
*/
/*
bool InitReadVegetation( uint32_t & numplants );
bool ReadVegetation(const int32_t index, t_tree_desc & shrubbery);
void FinishReadVegetation();
/*
* Creatures
*/
bool InitReadCreatures( uint32_t & numcreatures );
/**
* Read creatures in a box, starting with index. Returns -1 if no more creatures
* found. Call repeatedly do get all creatures in a specified box (uses tile coords)
*/
int32_t ReadCreatureInBox(const int32_t index, t_creature & furball,
const uint16_t x1, const uint16_t y1,const uint16_t z1,
const uint16_t x2, const uint16_t y2,const uint16_t z2);
bool ReadCreature(const int32_t index, t_creature & furball);
void FinishReadCreatures();
/// read/write size bytes of raw data at offset. DANGEROUS, CAN SEGFAULT DF!
void ReadRaw (const uint32_t offset, const uint32_t size, uint8_t *target);
void WriteRaw (const uint32_t offset, const uint32_t size, uint8_t *source);
/// write labors of a creature (for Dwarf Therapist)
bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]);
/*
* Notes placed by the player
*/
/*
/// start reading notes. numnotes is an output - total notes present
bool InitReadNotes( uint32_t & numnotes );
/// read note from the note vector at index
bool ReadNote(const int32_t index, t_note & note);
/// free the note vector
void FinishReadNotes();
*/
/*
* Settlements
*/
/*
bool InitReadSettlements( uint32_t & numsettlements );
bool ReadSettlement(const int32_t index, t_settlement & settlement);
bool ReadCurrentSettlement(t_settlement & settlement);
void FinishReadSettlements();
*/
/*
* Hotkeys (DF's zoom locations)
*/
/*
bool InitReadHotkeys( );
bool ReadHotkeys(t_hotkey hotkeys[]);
/*
* Cursor, and view coords
*/
bool InitViewAndCursor();
bool getViewCoords (int32_t &x, int32_t &y, int32_t &z);
bool setViewCoords (const int32_t x, const int32_t y, const int32_t z);
bool getCursorCoords (int32_t &x, int32_t &y, int32_t &z);
bool setCursorCoords (const int32_t x, const int32_t y, const int32_t z);
/// get the creature vector index of the creature currently under DF' cursor
bool getCurrentCursorCreature (uint32_t & creature_index);
/*
* Window size in tiles
*/
bool InitViewSize();
bool getWindowSize(int32_t & width, int32_t & height);
/*
* DF translation tables and name translation
*/
/*
bool InitReadNameTables (std::vector< std::vector<std::string> > & translations , std::vector< std::vector<std::string> > & foreign_languages);
void FinishReadNameTables();
std::string TranslateName(const t_name & name,const std::vector< std::vector<std::string> > & translations ,const std::vector< std::vector<std::string> > & foreign_languages, bool inEnglish=true);
*/
/*
* Item reading
*/
/*
bool InitReadItems(uint32_t & numitems);
bool getItemIndexesInBox(std::vector<uint32_t> &indexes,
const uint16_t x1, const uint16_t y1, const uint16_t z1,
const uint16_t x2, const uint16_t y2, const uint16_t z2);
bool ReadItem(const uint32_t index, t_item & item);
void FinishReadItems();
*/
/*
* Get the other API parts for raw access
*/
memory_info *getMemoryInfo();
Process * getProcess();
DFWindow * getWindow();
/*
// FIXME: BAD!
bool ReadAllMatgloss(vector< vector< string > > & all);
*/
bool ReadItemTypes(std::vector< std::vector< t_itemType > > & itemTypes);
//bool ReadItemTypes(std::vector< std::vector< t_itemType > > & itemTypes);
};
} // namespace DFHack
#endif // SIMPLEAPI_H_INCLUDED

@ -0,0 +1,206 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
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 "DFCommonInternal.h"
#include "../private/APIPrivate.h"
#define SHMCREATURESHDR ((Creatures::shm_creature_hdr *)d->shm_start)
using namespace DFHack;
/*
bool API::InitReadCreatures( uint32_t &numcreatures )
{
if(!d->InitReadNames()) return false;
try
{
memory_info * minfo = d->offset_descriptor;
Creatures::creature_offsets & off = d->creatures;
off.creature_vector = minfo->getAddress ("creatures");
off.creature_pos_offset = minfo->getOffset ("creature_position");
off.creature_type_offset = minfo->getOffset ("creature_race");
off.creature_flags1_offset = minfo->getOffset ("creature_flags1");
off.creature_flags2_offset = minfo->getOffset ("creature_flags2");
off.creature_name_offset = minfo->getOffset ("creature_name");
off.creature_custom_profession_offset = minfo->getOffset ("creature_custom_profession");
off.creature_profession_offset = minfo->getOffset ("creature_profession");
off.creature_sex_offset = minfo->getOffset ("creature_sex");
off.creature_id_offset = minfo->getOffset ("creature_id");
off.creature_squad_name_offset = minfo->getOffset ("creature_squad_name");
off.creature_squad_leader_id_offset = minfo->getOffset ("creature_squad_leader_id");
off.creature_money_offset = minfo->getOffset ("creature_money");
off.creature_current_job_offset = minfo->getOffset ("creature_current_job");
off.creature_current_job_id_offset = minfo->getOffset ("current_job_id");
off.creature_strength_offset = minfo->getOffset ("creature_strength");
off.creature_agility_offset = minfo->getOffset ("creature_agility");
off.creature_toughness_offset = minfo->getOffset ("creature_toughness");
off.creature_skills_offset = minfo->getOffset ("creature_skills");
off.creature_labors_offset = minfo->getOffset ("creature_labors");
off.creature_happiness_offset = minfo->getOffset ("creature_happiness");
off.creature_traits_offset = minfo->getOffset ("creature_traits");
off.creature_likes_offset = minfo->getOffset("creature_likes");
off.creature_artifact_name_offset = minfo->getOffset("creature_artifact_name");
off.creature_mood_offset = minfo->getOffset("creature_mood");
off.creature_pregnancy_offset = minfo->getOffset("creature_pregnancy");
off.creature_blood_max_offset = minfo->getOffset("creature_blood_max");
off.creature_blood_current_offset = minfo->getOffset("creature_blood_current");
off.creature_bleed_offset = minfo->getOffset("creature_bleed");
// name offsets for the creature module
off.name_firstname_offset = minfo->getOffset("name_firstname");
off.name_nickname_offset = minfo->getOffset("name_nickname");
off.name_words_offset = minfo->getOffset("name_words");
// HACK: vector correction. No longer relevant.
off.vector_correct = 0;
d->p_cre = new DfVector (d->p, off.creature_vector, 4);
d->creaturesInited = true;
numcreatures = d->p_cre->getSize();
// --> SHM initialization (if possible) <--
g_pProcess->getModuleIndex("Creatures40d",1,d->creature_module);
if(d->creature_module)
{
// supply the module with offsets so it can work with them
memcpy(SHMDATA(Creatures::creature_offsets),&d->creatures,sizeof(Creatures::creature_offsets));
const uint32_t cmd = Creatures::CREATURE_INIT + (d->creature_module << 16);
g_pProcess->SetAndWait(cmd);
}
return true;
}
catch (Error::MissingMemoryDefinition&)
{
d->creaturesInited = false;
numcreatures = 0;
throw;
}
}
bool API::ReadCreature (const int32_t index, t_creature & furball)
{
if(!d->creaturesInited) return false;
if(d->creature_module)
{
// supply the module with offsets so it can work with them
SHMCREATURESHDR->index = index;
const uint32_t cmd = Creatures::CREATURE_AT_INDEX + (d->creature_module << 16);
g_pProcess->SetAndWait(cmd);
memcpy(&furball,SHMDATA(t_creature),sizeof(t_creature));
// cerr << "creature read from SHM!" << endl;
return true;
}
// read pointer from vector at position
uint32_t temp = * (uint32_t *) d->p_cre->at (index);
furball.origin = temp;
Creatures::creature_offsets &offs = d->creatures;
//read creature from memory
g_pProcess->read (temp + offs.creature_pos_offset, 3 * sizeof (uint16_t), (uint8_t *) & (furball.x)); // xyz really
g_pProcess->readDWord (temp + offs.creature_type_offset, furball.type);
g_pProcess->readDWord (temp + offs.creature_flags1_offset, furball.flags1.whole);
g_pProcess->readDWord (temp + offs.creature_flags2_offset, furball.flags2.whole);
// names
d->readName(furball.name,temp + offs.creature_name_offset);
d->readName(furball.squad_name, temp + offs.creature_squad_name_offset);
d->readName(furball.artifact_name, temp + offs.creature_artifact_name_offset);
// custom profession
fill_char_buf (furball.custom_profession, d->p->readSTLString (temp + offs.creature_custom_profession_offset));
// labors
g_pProcess->read (temp + offs.creature_labors_offset, NUM_CREATURE_LABORS, furball.labors);
// traits
g_pProcess->read (temp + offs.creature_traits_offset, sizeof (uint16_t) * NUM_CREATURE_TRAITS, (uint8_t *) &furball.traits);
// learned skills
DfVector skills (d->p, temp + offs.creature_skills_offset, 4 );
furball.numSkills = skills.getSize();
for (uint32_t i = 0; i < furball.numSkills;i++)
{
uint32_t temp2 = * (uint32_t *) skills[i];
//skills.read(i, (uint8_t *) &temp2);
// a byte: this gives us 256 skills maximum.
furball.skills[i].id = g_pProcess->readByte (temp2);
furball.skills[i].rating = g_pProcess->readByte (temp2 + 4);
furball.skills[i].experience = g_pProcess->readWord (temp2 + 8);
}
// profession
furball.profession = g_pProcess->readByte (temp + offs.creature_profession_offset);
// current job HACK: the job object isn't cleanly represented here
uint32_t jobIdAddr = g_pProcess->readDWord (temp + offs.creature_current_job_offset);
if (jobIdAddr)
{
furball.current_job.active = true;
furball.current_job.jobId = g_pProcess->readByte (jobIdAddr + offs.creature_current_job_id_offset);
}
else
{
furball.current_job.active = false;
}
//likes
DfVector likes(d->p, temp + offs.creature_likes_offset, 4);
furball.numLikes = likes.getSize();
for(uint32_t i = 0;i<furball.numLikes;i++)
{
uint32_t temp2 = *(uint32_t *) likes[i];
g_pProcess->read(temp2,sizeof(t_like),(uint8_t *) &furball.likes[i]);
}
furball.mood = (int16_t) g_pProcess->readWord (temp + offs.creature_mood_offset);
g_pProcess->readDWord (temp + offs.creature_happiness_offset, furball.happiness);
g_pProcess->readDWord (temp + offs.creature_id_offset, furball.id);
g_pProcess->readDWord (temp + offs.creature_agility_offset, furball.agility);
g_pProcess->readDWord (temp + offs.creature_strength_offset, furball.strength);
g_pProcess->readDWord (temp + offs.creature_toughness_offset, furball.toughness);
g_pProcess->readDWord (temp + offs.creature_money_offset, furball.money);
furball.squad_leader_id = (int32_t) g_pProcess->readDWord (temp + offs.creature_squad_leader_id_offset);
g_pProcess->readByte (temp + offs.creature_sex_offset, furball.sex);
g_pProcess->readDWord(temp + offs.creature_pregnancy_offset, furball.pregnancy_timer);
furball.blood_max = (int32_t) g_pProcess->readDWord(temp + offs.creature_blood_max_offset);
furball.blood_current = (int32_t) g_pProcess->readDWord(temp + offs.creature_blood_current_offset);
g_pProcess->readDWord(temp + offs.creature_bleed_offset, furball.bleed_rate);
return true;
}
bool API::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
{
if(!d->creaturesInited) return false;
uint32_t temp = * (uint32_t *) d->p_cre->at (index);
WriteRaw(temp + d->creatures.creature_labors_offset, NUM_CREATURE_LABORS, labors);
}
bool API::getCurrentCursorCreature(uint32_t & creature_index)
{
if(!d->cursorWindowInited) return false;
creature_index = g_pProcess->readDWord(d->current_cursor_creature_offset);
return true;
}
*/

@ -0,0 +1,59 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
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 "DFCommonInternal.h"
#include "../private/APIPrivate.h"
using namespace DFHack;
bool API::ReadPauseState()
{
// replace with an exception
if(!d->cursorWindowInited) return false;
uint32_t pauseState = g_pProcess->readDWord (d->pause_state_offset);
return pauseState & 1;
}
uint32_t API::ReadMenuState()
{
if(d->cursorWindowInited)
return(g_pProcess->readDWord(d->current_menu_state_offset));
return false;
}
bool API::ReadViewScreen (t_viewscreen &screen)
{
if (!d->cursorWindowInited) return false;
uint32_t last = g_pProcess->readDWord (d->view_screen_offset);
uint32_t screenAddr = g_pProcess->readDWord (last);
uint32_t nextScreenPtr = g_pProcess->readDWord (last + 4);
while (nextScreenPtr != 0)
{
last = nextScreenPtr;
screenAddr = g_pProcess->readDWord (nextScreenPtr);
nextScreenPtr = g_pProcess->readDWord (nextScreenPtr + 4);
}
return d->offset_descriptor->resolveObjectToClassID (last, screen.type);
}

@ -0,0 +1,442 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
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 "DFCommonInternal.h"
#include "../private/APIPrivate.h"
#define SHMMAPSHDR ((Maps::shm_maps_hdr *)d->shm_start)
using namespace DFHack;
/*-----------------------------------*
* Init the mapblock pointer array *
*-----------------------------------*/
bool API::InitMap()
{
uint32_t map_offset = d->offset_descriptor->getAddress ("map_data");
uint32_t x_count_offset = d->offset_descriptor->getAddress ("x_count_block");
uint32_t y_count_offset = d->offset_descriptor->getAddress ("y_count_block");
uint32_t z_count_offset = d->offset_descriptor->getAddress ("z_count_block");
// get the offsets once here
d->tile_type_offset = d->offset_descriptor->getOffset ("type");
d->designation_offset = d->offset_descriptor->getOffset ("designation");
//d->occupancy_offset = d->offset_descriptor->getOffset ("occupancy");
//d->biome_stuffs = d->offset_descriptor->getOffset ("biome_stuffs");
d->veinvector = d->offset_descriptor->getOffset ("v_vein");
// these can fail and will be found when looking at the actual veins later
// basically a cache
d->vein_ice_vptr = 0;
d->offset_descriptor->resolveClassnameToVPtr("block_square_event_frozen_liquid", d->vein_ice_vptr);
d->vein_mineral_vptr = 0;
d->offset_descriptor->resolveClassnameToVPtr("block_square_event_mineral",d->vein_mineral_vptr);
/*
* --> SHM initialization (if possible) <--
*/
g_pProcess->getModuleIndex("Maps2010",1,d->maps_module);
if(d->maps_module)
{
// supply the module with offsets so it can work with them
Maps::maps_offsets *off = SHMDATA(Maps::maps_offsets);
off->designation_offset = d->designation_offset;
off->map_offset = map_offset;
off->tile_type_offset = d->tile_type_offset;
off->vein_ice_vptr = d->vein_ice_vptr; // FIXME: not necessarily true, the shm server side needs a class lookup >_<
off->vein_mineral_vptr = d->vein_mineral_vptr; // FIXME: not necessarily true, the shm server side needs a class lookup >_<
off->veinvector = d->veinvector;
off->x_count_offset = x_count_offset;
off->y_count_offset = y_count_offset;
off->z_count_offset = z_count_offset;
full_barrier
const uint32_t cmd = Maps::MAP_INIT + (d->maps_module << 16);
g_pProcess->SetAndWait(cmd);
//cerr << "Map acceleration enabled!" << endl;
}
// get the map pointer
uint32_t x_array_loc = g_pProcess->readDWord (map_offset);
if (!x_array_loc)
{
return false;
// FIXME: only throw this due to programmer error, in the other map functions
//throw Error::NoMapLoaded();
}
// get the size
uint32_t mx, my, mz;
mx = d->x_block_count = g_pProcess->readDWord (x_count_offset);
my = d->y_block_count = g_pProcess->readDWord (y_count_offset);
mz = d->z_block_count = g_pProcess->readDWord (z_count_offset);
// test for wrong map dimensions
if (mx == 0 || mx > 48 || my == 0 || my > 48 || mz == 0)
{
throw Error::BadMapDimensions(mx, my);
//return false;
}
// alloc array for pointers to all blocks
d->block = new uint32_t[mx*my*mz];
uint32_t *temp_x = new uint32_t[mx];
uint32_t *temp_y = new uint32_t[my];
uint32_t *temp_z = new uint32_t[mz];
g_pProcess->read (x_array_loc, mx * sizeof (uint32_t), (uint8_t *) temp_x);
for (uint32_t x = 0; x < mx; x++)
{
g_pProcess->read (temp_x[x], my * sizeof (uint32_t), (uint8_t *) temp_y);
// y -> map column
for (uint32_t y = 0; y < my; y++)
{
g_pProcess->read (temp_y[y],
mz * sizeof (uint32_t),
(uint8_t *) (d->block + x*my*mz + y*mz));
}
}
delete [] temp_x;
delete [] temp_y;
delete [] temp_z;
return true;
}
bool API::DestroyMap()
{
if (d->block != NULL)
{
delete [] d->block;
d->block = NULL;
}
return true;
}
bool API::isValidBlock (uint32_t x, uint32_t y, uint32_t z)
{
if ( x >= d->x_block_count || y >= d->y_block_count || z >= d->z_block_count)
return false;
return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z] != 0;
}
uint32_t API::getBlockPtr (uint32_t x, uint32_t y, uint32_t z)
{
if ( x >= d->x_block_count || y >= d->y_block_count || z >= d->z_block_count)
return 0;
return d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
}
bool API::ReadBlock40d(uint32_t x, uint32_t y, uint32_t z, mapblock40d * buffer)
{
if(d->shm_start && d->maps_module) // ACCELERATE!
{
SHMMAPSHDR->x = x;
SHMMAPSHDR->y = y;
SHMMAPSHDR->z = z;
volatile uint32_t cmd = Maps::MAP_READ_BLOCK_BY_COORDS + (d->maps_module << 16);
if(!g_pProcess->SetAndWait(cmd))
return false;
memcpy(buffer,SHMDATA(mapblock40d),sizeof(mapblock40d));
return true;
}
else // plain old block read
{
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
g_pProcess->read (addr + d->tile_type_offset, sizeof (buffer->tiletypes), (uint8_t *) buffer->tiletypes);
buffer->origin = addr;
uint32_t addr_of_struct = g_pProcess->readDWord(addr);
buffer->blockflags.whole = g_pProcess->readDWord(addr_of_struct);
return true;
}
return false;
}
}
// 256 * sizeof(uint16_t)
bool API::ReadTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
g_pProcess->read (addr + d->tile_type_offset, sizeof (tiletypes40d), (uint8_t *) buffer);
return true;
}
return false;
}
bool API::ReadDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool &dirtybit)
{
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if(addr)
{
uint32_t addr_of_struct = g_pProcess->readDWord(addr);
dirtybit = g_pProcess->readDWord(addr_of_struct) & 1;
return true;
}
return false;
}
bool API::WriteDirtyBit(uint32_t x, uint32_t y, uint32_t z, bool dirtybit)
{
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
uint32_t addr_of_struct = g_pProcess->readDWord(addr);
uint32_t dirtydword = g_pProcess->readDWord(addr_of_struct);
dirtydword &= 0xFFFFFFFE;
dirtydword |= (uint32_t) dirtybit;
g_pProcess->writeDWord (addr_of_struct, dirtydword);
return true;
}
return false;
}
/// read/write the block flags
bool API::ReadBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags &blockflags)
{
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if(addr)
{
uint32_t addr_of_struct = g_pProcess->readDWord(addr);
blockflags.whole = g_pProcess->readDWord(addr_of_struct);
return true;
}
return false;
}
bool API::WriteBlockFlags(uint32_t x, uint32_t y, uint32_t z, t_blockflags blockflags)
{
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
uint32_t addr_of_struct = g_pProcess->readDWord(addr);
g_pProcess->writeDWord (addr_of_struct, blockflags.whole);
return true;
}
return false;
}
bool API::ReadDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
g_pProcess->read (addr + d->designation_offset, sizeof (designations40d), (uint8_t *) buffer);
return true;
}
return false;
}
// 256 * sizeof(uint16_t)
bool API::WriteTileTypes (uint32_t x, uint32_t y, uint32_t z, tiletypes40d *buffer)
{
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
g_pProcess->write (addr + d->tile_type_offset, sizeof (tiletypes40d), (uint8_t *) buffer);
return true;
}
return false;
}
// 256 * sizeof(uint32_t)
bool API::WriteDesignations (uint32_t x, uint32_t y, uint32_t z, designations40d *buffer)
{
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
g_pProcess->write (addr + d->designation_offset, sizeof (designations40d), (uint8_t *) buffer);
return true;
}
return false;
}
// FIXME: this is bad. determine the real size!
//16 of them? IDK... there's probably just 7. Reading more doesn't cause errors as it's an array nested inside a block
// 16 * sizeof(uint8_t)
/*
bool API::ReadRegionOffsets (uint32_t x, uint32_t y, uint32_t z, biome_indices40d *buffer)
{
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
if (addr)
{
g_pProcess->read (addr + d->biome_stuffs, sizeof (biome_indices40d), (uint8_t *) buffer);
return true;
}
return false;
}
*/
// veins of a block, expects empty vein vectors
bool API::ReadVeins(uint32_t x, uint32_t y, uint32_t z, vector <t_vein> & veins, vector <t_frozenliquidvein>& ices)
{
uint32_t addr = d->block[x*d->y_block_count*d->z_block_count + y*d->z_block_count + z];
veins.clear();
ices.clear();
if (addr && d->veinvector)
{
// veins are stored as a vector of pointers to veins
/*pointer is 4 bytes! we work with a 32bit program here, no matter what architecture we compile khazad for*/
DfVector p_veins (d->p, addr + d->veinvector, 4);
uint32_t size = p_veins.getSize();
veins.reserve (size);
// read all veins
for (uint32_t i = 0; i < size;i++)
{
t_vein v;
t_frozenliquidvein fv;
// read the vein pointer from the vector
uint32_t temp = * (uint32_t *) p_veins[i];
uint32_t type = g_pProcess->readDWord(temp);
try_again:
if(type == d->vein_mineral_vptr)
{
// read the vein data (dereference pointer)
g_pProcess->read (temp, sizeof(t_vein), (uint8_t *) &v);
v.address_of = temp;
// store it in the vector
veins.push_back (v);
}
else if(type == d->vein_ice_vptr)
{
// read the ice vein data (dereference pointer)
g_pProcess->read (temp, sizeof(t_frozenliquidvein), (uint8_t *) &fv);
// store it in the vector
ices.push_back (fv);
}
else if(g_pProcess->readClassName(type) == "block_square_event_frozen_liquid")
{
d->vein_ice_vptr = type;
goto try_again;
}
else if(g_pProcess->readClassName(type) == "block_square_event_mineral")
{
d->vein_mineral_vptr = type;
goto try_again;
}
}
return true;
}
return false;
}
// getter for map size
void API::getSize (uint32_t& x, uint32_t& y, uint32_t& z)
{
x = d->x_block_count;
y = d->y_block_count;
z = d->z_block_count;
}
/*
//vector<uint16_t> v_geology[eBiomeCount];
bool API::ReadGeology (vector < vector <uint16_t> >& assign)
{
memory_info * minfo = d->offset_descriptor;
// get needed addresses and offsets. Now this is what I call crazy.
int region_x_offset = minfo->getAddress ("region_x");
int region_y_offset = minfo->getAddress ("region_y");
int region_z_offset = minfo->getAddress ("region_z");
int world_offset = minfo->getAddress ("world");
int world_regions_offset = minfo->getOffset ("w_regions_arr");
int region_size = minfo->getHexValue ("region_size");
int region_geo_index_offset = minfo->getOffset ("region_geo_index_off");
int world_geoblocks_offset = minfo->getOffset ("w_geoblocks");
int world_size_x = minfo->getOffset ("world_size_x");
int world_size_y = minfo->getOffset ("world_size_y");
int geolayer_geoblock_offset = minfo->getOffset ("geolayer_geoblock_offset");
uint32_t regionX, regionY, regionZ;
uint16_t worldSizeX, worldSizeY;
// read position of the region inside DF world
g_pProcess->readDWord (region_x_offset, regionX);
g_pProcess->readDWord (region_y_offset, regionY);
g_pProcess->readDWord (region_z_offset, regionZ);
// get world size
g_pProcess->readWord (world_offset + world_size_x, worldSizeX);
g_pProcess->readWord (world_offset + world_size_y, worldSizeY);
// get pointer to first part of 2d array of regions
uint32_t regions = g_pProcess->readDWord (world_offset + world_regions_offset);
// read the geoblock vector
DfVector geoblocks (d->p, world_offset + world_geoblocks_offset, 4);
// iterate over 8 surrounding regions + local region
for (int i = eNorthWest; i < eBiomeCount; i++)
{
// check bounds, fix them if needed
int bioRX = regionX / 16 + (i % 3) - 1;
if (bioRX < 0) bioRX = 0;
if (bioRX >= worldSizeX) bioRX = worldSizeX - 1;
int bioRY = regionY / 16 + (i / 3) - 1;
if (bioRY < 0) bioRY = 0;
if (bioRY >= worldSizeY) bioRY = worldSizeY - 1;
// get pointer to column of regions
uint32_t geoX;
g_pProcess->readDWord (regions + bioRX*4, geoX);
// get index into geoblock vector
uint16_t geoindex;
g_pProcess->readWord (geoX + bioRY*region_size + region_geo_index_offset, geoindex);
// get the geoblock from the geoblock vector using the geoindex
// read the matgloss pointer from the vector into temp
uint32_t geoblock_off = * (uint32_t *) geoblocks[geoindex];
// get the vector with pointer to layers
DfVector geolayers (d->p, geoblock_off + geolayer_geoblock_offset , 4); // let's hope
// make sure we don't load crap
assert (geolayers.getSize() > 0 && geolayers.getSize() <= 16);
d->v_geology[i].reserve (geolayers.getSize());
// finally, read the layer matgloss
for (uint32_t j = 0;j < geolayers.getSize();j++)
{
// read pointer to a layer
uint32_t geol_offset = * (uint32_t *) geolayers[j];
// read word at pointer + 2, store in our geology vectors
d->v_geology[i].push_back (g_pProcess->readWord (geol_offset + 2));
}
}
assign.clear();
assign.reserve (eBiomeCount);
// // TODO: clean this up
for (int i = 0; i < eBiomeCount;i++)
{
assign.push_back (d->v_geology[i]);
}
return true;
}
*/

@ -0,0 +1,188 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
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 "DFCommonInternal.h"
#include "../private/APIPrivate.h"
using namespace DFHack;
bool API::ReadWoodMaterials (vector<t_matgloss> & woods)
{
/*
int matgloss_address = d->offset_descriptor->getAddress ("matgloss");
int matgloss_wood_name_offset = d->offset_descriptor->getOffset("matgloss_wood_name");
// TODO: find flag for autumnal coloring?
DfVector p_matgloss(d->p, matgloss_address, 4);
woods.clear();
t_matgloss mat;
// TODO: use brown?
mat.fore = 7;
mat.back = 0;
mat.bright = 0;
uint32_t size = p_matgloss.getSize();
for (uint32_t i = 0; i < size ;i++)
{
// read the matgloss pointer from the vector into temp
uint32_t temp = * (uint32_t *) p_matgloss[i];
// read the string pointed at by
d->p->readSTLString (temp, mat.id, 128);
d->p->readSTLString (temp+matgloss_wood_name_offset, mat.name, 128);
woods.push_back (mat);
}
*/
return true;
}
bool API::ReadInorganicMaterials (vector<t_matgloss> & inorganic)
{
memory_info * minfo = d->offset_descriptor;
int matgloss_address = minfo->getAddress ("mat_inorganics");
//int matgloss_colors = minfo->getOffset ("material_color");
//int matgloss_stone_name_offset = minfo->getOffset("matgloss_stone_name");
DfVector p_matgloss (d->p, matgloss_address, 4);
uint32_t size = p_matgloss.getSize();
inorganic.resize (0);
inorganic.reserve (size);
for (uint32_t i = 0; i < size;i++)
{
// read the matgloss pointer from the vector into temp
uint32_t temp = * (uint32_t *) p_matgloss[i];
// read the string pointed at by
t_matgloss mat;
//fill_char_buf(mat.id, d->p->readSTLString(temp)); // reads a C string given an address
d->p->readSTLString (temp, mat.id, 128);
/*
d->p->readSTLString (temp+matgloss_stone_name_offset, mat.name, 128);
mat.fore = (uint8_t) g_pProcess->readWord (temp + matgloss_colors);
mat.back = (uint8_t) g_pProcess->readWord (temp + matgloss_colors + 2);
mat.bright = (uint8_t) g_pProcess->readWord (temp + matgloss_colors + 4);
*/
inorganic.push_back (mat);
}
return true;
}
bool API::ReadPlantMaterials (vector<t_matgloss> & plants)
{
/*
memory_info * minfo = d->offset_descriptor;
int matgloss_address = minfo->getAddress ("matgloss");
int matgloss_offset = minfo->getHexValue ("matgloss_skip");
int matgloss_plant_name_offset = minfo->getOffset("matgloss_plant_name");
DfVector p_matgloss(d->p, matgloss_address + matgloss_offset * 2, 4);
plants.clear();
// TODO: use green?
t_matgloss mat;
mat.fore = 7;
mat.back = 0;
mat.bright = 0;
for (uint32_t i = 0; i < p_matgloss.getSize();i++)
{
// read the matgloss pointer from the vector into temp
uint32_t temp = * (uint32_t *) p_matgloss[i];
// read the string pointed at by
//fill_char_buf(mat.id, d->p->readSTLString(temp)); // reads a C string given an address
d->p->readSTLString (temp, mat.id, 128);
d->p->readSTLString (temp+matgloss_plant_name_offset, mat.name, 128);
plants.push_back (mat);
}
*/
return true;
}
bool API::ReadPlantMaterials (vector<t_matglossPlant> & plants)
{
/*
memory_info * minfo = d->offset_descriptor;
int matgloss_address = minfo->getAddress ("matgloss");
int matgloss_offset = minfo->getHexValue ("matgloss_skip");
int matgloss_plant_name_offset = minfo->getOffset("matgloss_plant_name");
int matgloss_plant_drink_offset = minfo->getOffset("matgloss_plant_drink");
int matgloss_plant_food_offset = minfo->getOffset("matgloss_plant_food");
int matgloss_plant_extract_offset = minfo->getOffset("matgloss_plant_extract");
DfVector p_matgloss(d->p, matgloss_address + matgloss_offset * 2, 4);
plants.clear();
// TODO: use green?
t_matglossPlant mat;
mat.fore = 7;
mat.back = 0;
mat.bright = 0;
for (uint32_t i = 0; i < p_matgloss.getSize();i++)
{
// read the matgloss pointer from the vector into temp
uint32_t temp = * (uint32_t *) p_matgloss[i];
// read the string pointed at by
//fill_char_buf(mat.id, d->p->readSTLString(temp)); // reads a C string given an address
d->p->readSTLString (temp, mat.id, 128);
d->p->readSTLString (temp+matgloss_plant_name_offset, mat.name, 128);
d->p->readSTLString (temp+matgloss_plant_drink_offset, mat.drink_name, 128);
d->p->readSTLString (temp+matgloss_plant_food_offset, mat.food_name, 128);
d->p->readSTLString (temp+matgloss_plant_extract_offset, mat.extract_name, 128);
//d->p->readSTLString (temp
plants.push_back (mat);
}
*/
return true;
}
bool API::ReadCreatureTypes (vector<t_matgloss> & creatures)
{
/*
memory_info * minfo = d->offset_descriptor;
int matgloss_address = minfo->getAddress ("matgloss");
int matgloss_offset = minfo->getHexValue ("matgloss_skip");
int matgloss_creature_name_offset = minfo->getOffset("matgloss_creature_name");
DfVector p_matgloss (d->p, matgloss_address + matgloss_offset * 6, 4);
creatures.clear();
// TODO: use green?
t_matgloss mat;
mat.fore = 7;
mat.back = 0;
mat.bright = 0;
for (uint32_t i = 0; i < p_matgloss.getSize();i++)
{
// read the matgloss pointer from the vector into temp
uint32_t temp = * (uint32_t *) p_matgloss[i];
// read the string pointed at by
//fill_char_buf(mat.id, d->p->readSTLString(temp)); // reads a C string given an address
d->p->readSTLString (temp, mat.id, 128);
d->p->readSTLString (temp+matgloss_creature_name_offset, mat.name, 128);
creatures.push_back (mat);
}
*/
return true;
}

@ -0,0 +1,103 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
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 "DFCommonInternal.h"
#include "../private/APIPrivate.h"
using namespace DFHack;
bool API::InitViewAndCursor()
{
try
{
d->window_x_offset = d->offset_descriptor->getAddress ("window_x");
d->window_y_offset = d->offset_descriptor->getAddress ("window_y");
d->window_z_offset = d->offset_descriptor->getAddress ("window_z");
d->cursor_xyz_offset = d->offset_descriptor->getAddress ("cursor_xyz");
d->current_cursor_creature_offset = d->offset_descriptor->getAddress ("current_cursor_creature");
d->window_dims_offset = d->offset_descriptor->getAddress ("window_dims");
d->current_menu_state_offset = d->offset_descriptor->getAddress("current_menu_state");
d->pause_state_offset = d->offset_descriptor->getAddress ("pause_state");
d->view_screen_offset = d->offset_descriptor->getAddress ("view_screen");
d->cursorWindowInited = true;
return true;
}
catch (Error::MissingMemoryDefinition&)
{
d->cursorWindowInited = false;
throw;
}
}
bool API::getViewCoords (int32_t &x, int32_t &y, int32_t &z)
{
if (!d->cursorWindowInited) return false;
g_pProcess->readDWord (d->window_x_offset, (uint32_t &) x);
g_pProcess->readDWord (d->window_y_offset, (uint32_t &) y);
g_pProcess->readDWord (d->window_z_offset, (uint32_t &) z);
return true;
}
//FIXME: confine writing of coords to map bounds?
bool API::setViewCoords (const int32_t x, const int32_t y, const int32_t z)
{
if (!d->cursorWindowInited) return false;
g_pProcess->writeDWord (d->window_x_offset, (uint32_t) x);
g_pProcess->writeDWord (d->window_y_offset, (uint32_t) y);
g_pProcess->writeDWord (d->window_z_offset, (uint32_t) z);
return true;
}
bool API::getCursorCoords (int32_t &x, int32_t &y, int32_t &z)
{
if(!d->cursorWindowInited) return false;
int32_t coords[3];
g_pProcess->read (d->cursor_xyz_offset, 3*sizeof (int32_t), (uint8_t *) coords);
x = coords[0];
y = coords[1];
z = coords[2];
if (x == -30000) return false;
return true;
}
//FIXME: confine writing of coords to map bounds?
bool API::setCursorCoords (const int32_t x, const int32_t y, const int32_t z)
{
if (!d->cursorWindowInited) return false;
int32_t coords[3] = {x, y, z};
g_pProcess->write (d->cursor_xyz_offset, 3*sizeof (int32_t), (uint8_t *) coords);
return true;
}
bool API::getWindowSize (int32_t &width, int32_t &height)
{
if(! d->cursorWindowInited) return false;
int32_t coords[2];
g_pProcess->read (d->window_dims_offset, 2*sizeof (int32_t), (uint8_t *) coords);
width = coords[0];
height = coords[1];
return true;
}

@ -0,0 +1,113 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
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.
*/
/*
* WARNING: Only include from API modules
*/
#ifndef APIPRIVATE_H_INCLUDED
#define APIPRIVATE_H_INCLUDED
// we connect to those
#include <shms.h>
#include <mod-core.h>
#include <mod-maps.h>
#include <mod-creature40d.h>
#define SHMCMD(num) ((shm_cmd *)d->shm_start)[num]->pingpong
#define SHMHDR ((shm_core_hdr *)d->shm_start)
#define SHMDATA(type) ((type *)(d->shm_start + SHM_HEADER))
namespace DFHack
{
class APIPrivate
{
public:
APIPrivate();
void readName(t_name & name, uint32_t address);
// get the name offsets
bool InitReadNames();
#include "../modules/Creatures-data.h"
#include "../modules/Maps-data.h"
#include "../modules/Position-data.h"
#include "../modules/Gui-data.h"
#include "../modules/Materials-data.h"
uint32_t name_firstname_offset;
uint32_t name_nickname_offset;
uint32_t name_words_offset;
ProcessEnumerator* pm;
Process* p;
char * shm_start;
memory_info* offset_descriptor;
string xml;
/*
uint32_t item_material_offset;
uint32_t note_foreground_offset;
uint32_t note_background_offset;
uint32_t note_name_offset;
uint32_t note_xyz_offset;
uint32_t hotkey_start;
uint32_t hotkey_mode_offset;
uint32_t hotkey_xyz_offset;
uint32_t hotkey_size;
uint32_t settlement_name_offset;
uint32_t settlement_world_xy_offset;
uint32_t settlement_local_xy_offset;
uint32_t dwarf_lang_table_offset;
bool constructionsInited;
bool buildingsInited;
bool effectsInited;
bool vegetationInited;
bool itemsInited;
bool notesInited;
bool namesInited;
bool hotkeyInited;
bool settlementsInited;
bool nameTablesInited;
uint32_t tree_offset;
DfVector *p_cons;
DfVector *p_bld;
DfVector *p_effect;
DfVector *p_veg;
DfVector *p_itm;
DfVector *p_notes;
DfVector *p_settlements;
DfVector *p_current_settlement;
*/
};
}
#endif

@ -9,17 +9,17 @@ ENDIF(UNIX)
ADD_EXECUTABLE(dfattachtest attachtest.cpp)
TARGET_LINK_LIBRARIES(dfattachtest dfhack)
# buildingsdump - dump buildings and their raw data filtered by type
#ADD_EXECUTABLE(dfbuildingsdump buildingsdump.cpp)
#TARGET_LINK_LIBRARIES(dfbuildingsdump dfhack)
# a benchmark program, reads the map 1000x
ADD_EXECUTABLE(dfexpbench expbench.cpp)
TARGET_LINK_LIBRARIES(dfexpbench dfhack)
# creaturedump - basic creature dump - a test of the creature related exports
ADD_EXECUTABLE(dfcreaturedump creaturedump.cpp)
TARGET_LINK_LIBRARIES(dfcreaturedump dfhack)
# buildingsdump - dump buildings and their raw data filtered by type
ADD_EXECUTABLE(dfbuildingsdump buildingsdump.cpp)
TARGET_LINK_LIBRARIES(dfbuildingsdump dfhack)
# ADD_EXECUTABLE(dfcreaturedump creaturedump.cpp)
# TARGET_LINK_LIBRARIES(dfcreaturedump dfhack)
# materialtest - just list the first material of each type
ADD_EXECUTABLE(dfmaterialtest materialtest.cpp)
@ -35,13 +35,13 @@ ADD_EXECUTABLE(dfsuspend suspendtest.cpp)
TARGET_LINK_LIBRARIES(dfsuspend dfhack)
# itemdump - dump the item under the cursor
ADD_EXECUTABLE(dfitemdump dfitemdump.cpp)
TARGET_LINK_LIBRARIES(dfitemdump dfhack)
# ADD_EXECUTABLE(dfitemdump dfitemdump.cpp)
# TARGET_LINK_LIBRARIES(dfitemdump dfhack)
# hotkeynotedump - dumps the hotkeys and notes for the loaded map
# Author: belal
ADD_EXECUTABLE(dfhotkeynotedump hotkeynotedump.cpp)
TARGET_LINK_LIBRARIES(dfhotkeynotedump dfhack)
# ADD_EXECUTABLE(dfhotkeynotedump hotkeynotedump.cpp)
# TARGET_LINK_LIBRARIES(dfhotkeynotedump dfhack)
# findnameindexes
# Author: belal
@ -50,8 +50,8 @@ TARGET_LINK_LIBRARIES(dfhotkeynotedump dfhack)
# settlementdump - dumps the settlements on the loaded map
# Author: belal
ADD_EXECUTABLE(dfsettlementdump settlementdump.cpp)
TARGET_LINK_LIBRARIES(dfsettlementdump dfhack)
# ADD_EXECUTABLE(dfsettlementdump settlementdump.cpp)
# TARGET_LINK_LIBRARIES(dfsettlementdump dfhack)
# veccheck - read vector values at address
ADD_EXECUTABLE(dfvecc veccheck.cpp)
@ -59,67 +59,67 @@ TARGET_LINK_LIBRARIES(dfvecc dfhack)
# catsplosion - Makes every cat pregnant, and almost due...
# Author: Zhentar
ADD_EXECUTABLE(dfcatsplosion catsplosion.cpp)
TARGET_LINK_LIBRARIES(dfcatsplosion dfhack)
IF(UNIX)
SET(CURSES_NEED_WIDE "YES")
SET(CURSES_NEED_NCURSES "YES")
find_package(Curses)
IF(CURSES_FOUND)
if(CURSES_HAVE_NCURSESW_NCURSES_H)
SET(NCURSES_H "ncursesw/ncurses.h")
elseif(CURSES_HAVE_NCURSESW_CURSES_H)
SET(NCURSES_H "ncursesw/curses.h")
elseif(CURSES_HAVE_NCURSESW_H)
SET(NCURSES_H "ncursesw.h")
elseif(CURSES_HAVE_CURSESW_H)
SET(NCURSES_H "cursesw.h")
endif(CURSES_HAVE_NCURSESW_NCURSES_H)
IF(NCURSES_H)
# OPTION( VARIABLE "Description" Initial state)
#OPTION( WITH_FOO "Enable FOO support" ON )
#OPTION( WITH_BAR "Enable BAR component" OFF )
#SET( BAZ 18 )
CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/fake-curses.h.cmake ${CMAKE_CURRENT_SOURCE_DIR}/fake-curses.h )
# veinlook - look at the map... sort of
ADD_EXECUTABLE(dfveinlook veinlook.cpp)
INCLUDE_DIRECTORIES(${CURSES_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(dfveinlook dfhack ${CURSES_LIBRARIES})
install(TARGETS
dfveinlook
RUNTIME DESTINATION bin
)
ENDIF(NCURSES_H)
ELSE(CURSES_FOUND)
MESSAGE(STATUS "Wide-character ncurses library not found - vainlook can't be built")
ENDIF(CURSES_FOUND)
ENDIF(UNIX)
# ADD_EXECUTABLE(dfcatsplosion catsplosion.cpp)
# TARGET_LINK_LIBRARIES(dfcatsplosion dfhack)
# IF(UNIX)
# SET(CURSES_NEED_WIDE "YES")
# SET(CURSES_NEED_NCURSES "YES")
# find_package(Curses)
#
# IF(CURSES_FOUND)
# if(CURSES_HAVE_NCURSESW_NCURSES_H)
# SET(NCURSES_H "ncursesw/ncurses.h")
# elseif(CURSES_HAVE_NCURSESW_CURSES_H)
# SET(NCURSES_H "ncursesw/curses.h")
# elseif(CURSES_HAVE_NCURSESW_H)
# SET(NCURSES_H "ncursesw.h")
# elseif(CURSES_HAVE_CURSESW_H)
# SET(NCURSES_H "cursesw.h")
# endif(CURSES_HAVE_NCURSESW_NCURSES_H)
# IF(NCURSES_H)
# # OPTION( VARIABLE "Description" Initial state)
# #OPTION( WITH_FOO "Enable FOO support" ON )
# #OPTION( WITH_BAR "Enable BAR component" OFF )
# #SET( BAZ 18 )
# CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/fake-curses.h.cmake ${CMAKE_CURRENT_SOURCE_DIR}/fake-curses.h )
#
# # veinlook - look at the map... sort of
# ADD_EXECUTABLE(dfveinlook veinlook.cpp)
# INCLUDE_DIRECTORIES(${CURSES_INCLUDE_DIR})
# TARGET_LINK_LIBRARIES(dfveinlook dfhack ${CURSES_LIBRARIES})
# install(TARGETS
# dfveinlook
# RUNTIME DESTINATION bin
# )
# ENDIF(NCURSES_H)
# ELSE(CURSES_FOUND)
# MESSAGE(STATUS "Wide-character ncurses library not found - vainlook can't be built")
# ENDIF(CURSES_FOUND)
# ENDIF(UNIX)
# renamer - change the custom names and professions of creatures, sends keys to
# df directly
# Author: belal
ADD_EXECUTABLE(dfrenamer renamer.cpp)
TARGET_LINK_LIBRARIES(dfrenamer dfhack)
#ADD_EXECUTABLE(dfrenamer renamer.cpp)
#TARGET_LINK_LIBRARIES(dfrenamer dfhack)
IF(UNIX)
install(TARGETS
dfattachtest
dfexpbench
dfcreaturedump
dfbuildingsdump
#dfexpbench
#dfcreaturedump
#dfbuildingsdump
dfmaterialtest
dfposition
dfsuspend
dfitemdump
dfhotkeynotedump
#dfitemdump
#dfhotkeynotedump
#dffindnameindexes
dfsettlementdump
dfrenamer
#dfvecc
dfcatsplosion
#dfsettlementdump
#dfrenamer
dfvecc
#dfcatsplosion
RUNTIME DESTINATION bin
)
ENDIF(UNIX)

@ -1,15 +1,51 @@
// Just show some position data
#include <iostream>
#include <climits>
#include <integers.h>
#include <vector>
#include <sstream>
#include <ctime>
using namespace std;
#include <DFTypes.h>
#include <DFHackAPI.h>
#include <DFProcess.h>
#include <DFMemInfo.h>
#include <DFVector.h>
int main (void)
void DumpObjStr0Vector (const char * name, DFHack::Process *p, uint32_t addr)
{
cout << "----==== " << name << " ====----" << endl;
DFHack::DfVector vect(p,addr,4);
for(int i = 0; i < vect.getSize();i++)
{
uint32_t addr = *(uint32_t *) vect[i];
cout << p->readSTLString(addr) << endl;
}
cout << endl;
}
void DumpDWordVector (const char * name, DFHack::Process *p, uint32_t addr)
{
cout << "----==== " << name << " ====----" << endl;
DFHack::DfVector vect(p,addr,4);
for(int i = 0; i < vect.getSize();i++)
{
uint32_t number = *(uint32_t *) vect[i];
cout << number << endl;
}
cout << endl;
}
int main (int numargs, const char ** args)
{
uint32_t addr;
if (numargs == 2)
{
istringstream input (args[1],istringstream::in);
input >> std::hex >> addr;
}
DFHack::API DF("Memory.xml");
try
{
@ -24,48 +60,40 @@ int main (void)
return 1;
}
if(!DF.InitMap())
{
cerr << "No map loaded, it would be unsafe to enumerate materials" << endl;
#ifndef LINUX_BUILD
cin.ignore();
#endif
return 1;
}
DF.DestroyMap();
DFHack::Process* p = DF.getProcess();
DFHack::memory_info* mem = DF.getMemoryInfo();
//const vector<string> * names = mem->getClassIDMapping();
vector <DFHack::t_matgloss> Woods;
DF.ReadWoodMatgloss(Woods);
DumpObjStr0Vector("Material templates",p, mem->getAddress("mat_templates"));
vector <DFHack::t_matgloss> Plants;
DF.ReadPlantMatgloss(Plants);
DumpObjStr0Vector("Inorganics",p, mem->getAddress("mat_inorganics"));
vector <DFHack::t_matgloss> Metals;
DF.ReadMetalMatgloss(Metals);
DumpObjStr0Vector("Organics - all",p, mem->getAddress("mat_organics_all"));
vector <DFHack::t_matgloss> Stones;
DF.ReadStoneMatgloss(Stones);
DumpObjStr0Vector("Organics - plants",p, mem->getAddress("mat_organics_plants"));
vector <DFHack::t_matgloss> CreatureTypes;
DF.ReadCreatureMatgloss(CreatureTypes);
DumpDWordVector("Maybe map between all organics and plants",p, mem->getAddress("mat_unk1_numbers"));
DumpObjStr0Vector("Trees/wood",p, mem->getAddress("mat_organics_trees"));
DumpDWordVector("Maybe map between all organics and trees",p, mem->getAddress("mat_unk2_numbers"));
DumpObjStr0Vector("Body material templates",p, mem->getAddress("mat_body_material_templates"));
DumpObjStr0Vector("Body detail plans",p, mem->getAddress("mat_body_detail_plans"));
DumpObjStr0Vector("Bodies",p, mem->getAddress("mat_bodies"));
DumpObjStr0Vector("Bodygloss",p, mem->getAddress("mat_bodygloss"));
DumpObjStr0Vector("Creature variations",p, mem->getAddress("mat_creature_variations"));
DumpObjStr0Vector("Creature types",p, mem->getAddress("mat_creature_types"));
cout << "Wood: " << Woods[0].id << endl;
cout << "Plant: " << Plants[0].id << endl;
cout << "Metal: " << Metals[0].id << endl;
cout << "Stone: " << Stones[0].id << endl;
cout << "Creature: " << CreatureTypes[0].id << endl;
cout << endl;
cout << "Dumping all stones!" << endl;
for(uint32_t i = 0; i < Stones.size();i++)
{
cout << Stones[i].id << "$" << endl;;
}
DF.Detach();
#ifndef LINUX_BUILD
cout << "Done. Press any key to continue" << endl;
cin.ignore();
#endif
return 0;
}

@ -29,25 +29,18 @@ int main (void)
if (DF.InitViewAndCursor())
{
int32_t x,y,z;
int32_t width,height;
if(DF.getViewCoords(x,y,z))
cout << "view coords: " << x << "/" << y << "/" << z << endl;
if(DF.getCursorCoords(x,y,z))
cout << "cursor coords: " << x << "/" << y << "/" << z << endl;
}
else
{
cerr << "cursor and window parameters are unsupported on your version of DF" << endl;
}
if(DF.InitViewSize())
{
int32_t width,height;
if(DF.getWindowSize(width,height))
cout << "window size : " << width << " " << height << endl;
}
else
{
cerr << "view size is unsupported on your version of DF" << endl;
cerr << "cursor and window parameters are unsupported on your version of DF" << endl;
}
if(!DF.Detach())

@ -3098,7 +3098,7 @@
Map stuff
=========
<Address name="map_data">0x016AD718</Address>
<Offset name="v_vein">0x10</Offset>
<Offset name="v_vein">0x08</Offset>
<Offset name="type">0x0092</Offset>
<Offset name="designation">0x029C</Offset>
<!--

@ -14,8 +14,8 @@ ADD_EXECUTABLE(dfprospector prospector.cpp)
TARGET_LINK_LIBRARIES(dfprospector dfhack)
# cleanmap - removes mud, snow, blood and similar stuff from a map. farmers beware
ADD_EXECUTABLE(dfcleanmap cleanmap.cpp)
TARGET_LINK_LIBRARIES(dfcleanmap dfhack)
#ADD_EXECUTABLE(dfcleanmap cleanmap.cpp)
#TARGET_LINK_LIBRARIES(dfcleanmap dfhack)
IF(UNIX)
# incrementalsearch - a bit like cheat engine, only DF-specific, very basic
@ -26,33 +26,33 @@ ENDIF(UNIX)
# bauxite - turn all mechanisms into bauxite mechanisms
# Author: Alex Legg
ADD_EXECUTABLE(dfbauxite dfbauxite.cpp)
TARGET_LINK_LIBRARIES(dfbauxite dfhack)
#ADD_EXECUTABLE(dfbauxite dfbauxite.cpp)
#TARGET_LINK_LIBRARIES(dfbauxite dfhack)
# digger - designate for digging by tile class
# Author: mizipzor
ADD_EXECUTABLE(dfdigger digger.cpp)
TARGET_LINK_LIBRARIES(dfdigger dfhack)
#ADD_EXECUTABLE(dfdigger digger.cpp)
#TARGET_LINK_LIBRARIES(dfdigger dfhack)
# itemdesignator - change some item designations (dump, forbid, on-fire) for all
# items of a given type and material
# Author: belal
ADD_EXECUTABLE(dfitemdesignator itemdesignator.cpp)
TARGET_LINK_LIBRARIES(dfitemdesignator dfhack)
#ADD_EXECUTABLE(dfitemdesignator itemdesignator.cpp)
#TARGET_LINK_LIBRARIES(dfitemdesignator dfhack)
# a magma creation tool
# Author: Aleric
ADD_EXECUTABLE(dfmagma_create magma_create.cpp)
TARGET_LINK_LIBRARIES(dfmagma_create dfhack)
#ADD_EXECUTABLE(dfmagma_create magma_create.cpp)
#TARGET_LINK_LIBRARIES(dfmagma_create dfhack)
IF(UNIX)
install(TARGETS
dfbauxite
dfcleanmap
dfdigger
#dfbauxite
#dfcleanmap
#dfdigger
dfincremental
dfitemdesignator
dfmagma_create
#dfitemdesignator
#dfmagma_create
dfprospector
dfreveal
RUNTIME DESTINATION bin

@ -81,7 +81,7 @@ int main (int argc, const char* argv[])
DF.getSize(x_max,y_max,z_max);
// get stone matgloss mapping
if(!DF.ReadStoneMatgloss(stonetypes))
if(!DF.ReadInorganicMaterials(stonetypes))
{
//DF.DestroyMap();
cerr << "Can't get the materials." << endl;
@ -90,7 +90,7 @@ int main (int argc, const char* argv[])
#endif
return 1;
}
/*
// get region geology
if(!DF.ReadGeology( layerassign ))
{
@ -100,7 +100,7 @@ int main (int argc, const char* argv[])
#endif
return 1;
}
*/
int16_t tempvein [16][16];
vector <DFHack::t_vein> veins;
vector <DFHack::t_frozenliquidvein> iceveins;
@ -123,7 +123,7 @@ int main (int argc, const char* argv[])
memset(tempvein, -1, sizeof(tempvein));
veins.clear();
DF.ReadVeins(x,y,z,veins,iceveins);
/*
if(showbaselayers)
{
DF.ReadRegionOffsets(x,y,z, &regionoffsets);
@ -147,7 +147,7 @@ int main (int argc, const char* argv[])
}
}
}
*/
// for each vein
for(int i = 0; i < (int)veins.size();i++)
{