diff --git a/dfhack/APIPrivate.cpp b/dfhack/APIPrivate.cpp index 95da0cf04..d4cb5d7fb 100644 --- a/dfhack/APIPrivate.cpp +++ b/dfhack/APIPrivate.cpp @@ -14,6 +14,7 @@ #include "modules/Translation.h" #include "modules/Vegetation.h" #include "modules/Gui.h" +#include "modules/World.h" #include "modules/Buildings.h" #include "modules/Constructions.h" @@ -26,12 +27,13 @@ APIPrivate::APIPrivate() maps = 0; position = 0; gui = 0; + world = 0; materials = 0; translation = 0; vegetation = 0; buildings = 0; constructions = 0; - items = 0; + items = 0; } APIPrivate::~APIPrivate() @@ -45,6 +47,7 @@ APIPrivate::~APIPrivate() if(vegetation) delete vegetation; if(buildings) delete buildings; if(constructions) delete constructions; + if(world) delete world; } bool APIPrivate::InitReadNames() diff --git a/dfhack/CMakeLists.txt b/dfhack/CMakeLists.txt index 54841700e..92d74b16d 100644 --- a/dfhack/CMakeLists.txt +++ b/dfhack/CMakeLists.txt @@ -36,6 +36,7 @@ depends/tinyxml/tinyxmlparser.cpp modules/Creatures.cpp modules/Gui.cpp +modules/World.cpp modules/Items.cpp modules/Maps.cpp modules/Materials.cpp diff --git a/dfhack/DFHackAPI.cpp b/dfhack/DFHackAPI.cpp index 9aea26544..d4d22f321 100644 --- a/dfhack/DFHackAPI.cpp +++ b/dfhack/DFHackAPI.cpp @@ -40,6 +40,7 @@ distribution. #include "modules/Items.h" #include "modules/Position.h" #include "modules/Gui.h" +#include "modules/World.h" #include "modules/Creatures.h" #include "modules/Translation.h" #include "modules/Vegetation.h" @@ -139,6 +140,11 @@ bool API::Detach() delete d->gui; d->gui = 0; } + if(d->world) + { + delete d->world; + d->world = 0; + } if(d->position) { delete d->position; @@ -149,15 +155,10 @@ bool API::Detach() delete d->materials; d->materials = 0; } - if(d->items) - { - delete d->items; - d->items = 0; - } - if(d->gui) + if(d->items) { - delete d->gui; - d->gui = 0; + delete d->items; + d->items = 0; } if(d->translation) { @@ -257,6 +258,13 @@ Gui * API::getGui() return d->gui; } +World * API::getWorld() +{ + if(!d->world) + d->world = new World(d); + return d->world; +} + Position * API::getPosition() { if(!d->position) diff --git a/dfhack/include/DFHackAPI.h b/dfhack/include/DFHackAPI.h index 188f295ca..9f5d30b80 100644 --- a/dfhack/include/DFHackAPI.h +++ b/dfhack/include/DFHackAPI.h @@ -47,12 +47,13 @@ namespace DFHack class Creatures; class Position; class Gui; + class World; class Materials; class Translation; class Vegetation; class Buildings; class Constructions; - class Items; + class Items; class DFHACK_EXPORT API { @@ -98,6 +99,9 @@ namespace DFHack // get the gui module Gui * getGui(); + + // get the world module + World * getWorld(); // get the position module Position * getPosition(); diff --git a/dfhack/include/modules/Creatures.h b/dfhack/include/modules/Creatures.h index 92d7809aa..bfa661084 100644 --- a/dfhack/include/modules/Creatures.h +++ b/dfhack/include/modules/Creatures.h @@ -348,6 +348,9 @@ namespace DFHack t_soul defaultSoul; uint32_t nbcolors; uint32_t color[MAX_COLORS]; + + uint32_t birth_year; + uint32_t birth_time; }; class APIPrivate; diff --git a/dfhack/include/modules/Materials.h b/dfhack/include/modules/Materials.h index 803443313..73641e10c 100644 --- a/dfhack/include/modules/Materials.h +++ b/dfhack/include/modules/Materials.h @@ -50,6 +50,8 @@ namespace DFHack { char part[128]; std::vector colorlist; + uint32_t startdate; /* in days */ + uint32_t enddate; /* in days */ }; struct t_creaturecaste diff --git a/dfhack/include/modules/World.h b/dfhack/include/modules/World.h new file mode 100644 index 000000000..6c3c12a4a --- /dev/null +++ b/dfhack/include/modules/World.h @@ -0,0 +1,32 @@ +#ifndef CL_MOD_WORLD +#define CL_MOD_WORLD + +/* +* World: all kind of stuff related to the current world state +*/ +#include "Export.h" + +namespace DFHack +{ + class APIPrivate; + class DFHACK_EXPORT World + { + public: + + World(DFHack::APIPrivate * d); + ~World(); + bool Start(); + bool Finish(); + + uint32_t ReadCurrentTick(); + uint32_t ReadCurrentYear(); + uint32_t ReadCurrentMonth(); + uint32_t ReadCurrentDay(); + + private: + struct Private; + Private *d; + }; +} +#endif + diff --git a/dfhack/modules/Creatures.cpp b/dfhack/modules/Creatures.cpp index 004233d66..c083f5d8d 100644 --- a/dfhack/modules/Creatures.cpp +++ b/dfhack/modules/Creatures.cpp @@ -100,6 +100,10 @@ Creatures::Creatures(APIPrivate* _d) // appearance creatures.appearance_vector_offset = minfo->getOffset("creature_appearance_vector"); + + //birth + creatures.birth_year_offset = minfo->getOffset("creature_birth_year"); + creatures.birth_time_offset = minfo->getOffset("creature_birth_time"); // name offsets for the creature module creatures.name_firstname_offset = minfo->getOffset("name_firstname"); @@ -217,6 +221,8 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball) furball.current_job.active = false;; } + furball.birth_year = p->readDWord (temp + offs.birth_year_offset ); + furball.birth_time = p->readDWord (temp + offs.birth_time_offset ); // current job HACK: the job object isn't cleanly represented here /* diff --git a/dfhack/modules/Materials.cpp b/dfhack/modules/Materials.cpp index 9cdab2ffc..417b5a53c 100644 --- a/dfhack/modules/Materials.cpp +++ b/dfhack/modules/Materials.cpp @@ -304,6 +304,8 @@ bool Materials::ReadCreatureTypesEx (void) uint32_t bodypart_singular_offset = mem->getOffset ("bodypart_singular_vector"); uint32_t bodypart_plural_offset = mem->getOffset ("bodypart_plural_vector"); uint32_t color_modifier_part_offset = mem->getOffset ("color_modifier_part"); + uint32_t color_modifier_startdate_offset = mem->getOffset ("color_modifier_startdate"); + uint32_t color_modifier_enddate_offset = mem->getOffset ("color_modifier_enddate"); uint32_t size = p_races.size(); uint32_t sizecas = 0; uint32_t sizecolormod; @@ -341,6 +343,8 @@ bool Materials::ReadCreatureTypesEx (void) for(uint32_t l = 0; l < sizecolorlist; l++) caste.ColorModifier[k].colorlist[l] = p_colorlist[l]; p->readSTLString( p_colormod[k] + color_modifier_part_offset, caste.ColorModifier[k].part, sizeof(caste.ColorModifier[k].part)); + caste.ColorModifier[k].startdate = p->readDWord( p_colormod[k] + color_modifier_startdate_offset ); + caste.ColorModifier[k].enddate = p->readDWord( p_colormod[k] + color_modifier_enddate_offset ); } /* body parts */ diff --git a/dfhack/modules/World.cpp b/dfhack/modules/World.cpp new file mode 100644 index 000000000..fe997da2a --- /dev/null +++ b/dfhack/modules/World.cpp @@ -0,0 +1,94 @@ +/* +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" +#include "modules/World.h" +#include "DFProcess.h" +#include "DFMemInfo.h" +#include "DFTypes.h" + +using namespace DFHack; + +struct World::Private +{ + bool Inited; + bool Started; + uint32_t year_offset; + uint32_t tick_offset; + APIPrivate *d; + Process * owner; +}; + +World::World(APIPrivate * _d) +{ + + d = new Private; + d->d = _d; + d->owner = _d->p; + + memory_info * mem = d->d->offset_descriptor; + d->year_offset = mem->getAddress( "current_year" ); + d->tick_offset = mem->getAddress( "current_tick" ); + d->Inited = d->Started = true; +} + +World::~World() +{ + delete d; +} + +bool World::Start() +{ + return true; +} + +bool World::Finish() +{ + return true; +} + +uint32_t World::ReadCurrentYear() +{ + if(d->Inited) + return(d->owner->readDWord(d->year_offset)); + return 0; +} + +uint32_t World::ReadCurrentTick() +{ + if(d->Inited) + return(d->owner->readDWord(d->tick_offset)); + return 0; +} + +uint32_t World::ReadCurrentMonth() +{ + return this->ReadCurrentTick() / 1200 / 24; +} + +uint32_t World::ReadCurrentDay() +{ + return ((this->ReadCurrentTick() / 1200) % 24) + 1; +} diff --git a/dfhack/private/APIPrivate.h b/dfhack/private/APIPrivate.h index 259730d58..12e11aa0d 100644 --- a/dfhack/private/APIPrivate.h +++ b/dfhack/private/APIPrivate.h @@ -33,10 +33,11 @@ namespace DFHack { class Materials; class Gui; + class World; class Position; class Maps; class Creatures; - class Items; + class Items; class Translation; class Buildings; class ProcessEnumerator; @@ -71,8 +72,9 @@ namespace DFHack Maps * maps; Position * position; Gui * gui; + World * world; Materials * materials; - Items * items; + Items * items; Translation * translation; Vegetation * vegetation; Buildings * buildings; diff --git a/dfhack/shm/mod-creature2010.h b/dfhack/shm/mod-creature2010.h index 93006d827..f52122127 100644 --- a/dfhack/shm/mod-creature2010.h +++ b/dfhack/shm/mod-creature2010.h @@ -65,6 +65,8 @@ typedef struct uint32_t soul_mental_offset; uint32_t soul_traits_offset; uint32_t appearance_vector_offset; + uint32_t birth_year_offset; + uint32_t birth_time_offset; } creature_offsets; typedef struct diff --git a/examples/creaturedump.cpp b/examples/creaturedump.cpp index 50e716137..decd218fb 100644 --- a/examples/creaturedump.cpp +++ b/examples/creaturedump.cpp @@ -16,6 +16,7 @@ using namespace std; #include #include #include +#include #include enum likeType @@ -31,6 +32,8 @@ DFHack::memory_info *mem; vector< vector > englishWords; vector< vector > foreignWords; DFHack::Creatures * Creatures = NULL; +uint32_t current_year; +uint32_t current_tick; /* likeType printLike40d(DFHack::t_like like, const matGlosses & mat,const vector< vector > & itemTypes) { // The function in DF which prints out the likes is a monster, it is a huge switch statement with tons of options and calls a ton of other functions as well, @@ -139,6 +142,7 @@ likeType printLike40d(DFHack::t_like like, const matGlosses & mat,const vector< void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) { + uint32_t dayoflife; cout << "address: " << hex << creature.origin << dec << " creature type: " << Materials->raceEx[creature.race].rawname << "[" << Materials->raceEx[creature.race].tile_character << "," << Materials->raceEx[creature.race].tilecolor.fore @@ -204,6 +208,8 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) } */ cout << endl; + dayoflife = creature.birth_year*12*28 + creature.birth_time/1200; + cout << "Born on the year " << creature.birth_year << ", month " << (creature.birth_time/1200/28) << ", day " << ((creature.birth_time/1200) % 28 + 1) << ", " << dayoflife << " days lived." << endl; cout << "Appearance : "; for(unsigned int i = 0; icolor[color].b*255) << "]"; else cout << Materials->alldesc[color].id; + if( Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].startdate > 0 ) + { + if( (Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].startdate <= dayoflife) && + (Materials->raceEx[creature.race].castes[creature.caste].ColorModifier[i].enddate > dayoflife) ) + cout << "[active]"; + else + cout << "[inactive]"; + } cout << " - "; } @@ -383,6 +397,7 @@ void printCreature(DFHack::API & DF, const DFHack::t_creature & creature) int main (int numargs, char ** args) { + DFHack::World * World; DFHack::API DF("Memory.xml"); try { @@ -402,6 +417,9 @@ int main (int numargs, char ** args) Creatures = DF.getCreatures(); Materials = DF.getMaterials(); + World = DF.getWorld(); + current_year = World->ReadCurrentYear(); + current_tick = World->ReadCurrentTick(); DFHack::Translation * Tran = DF.getTranslation(); uint32_t numCreatures; diff --git a/examples/materialtest.cpp b/examples/materialtest.cpp index ccd62c0ec..16fdeaf01 100644 --- a/examples/materialtest.cpp +++ b/examples/materialtest.cpp @@ -117,7 +117,10 @@ int main (int numargs, const char ** args) cout << endl; for(uint32_t k = 0; k < castes[j].ColorModifier.size(); k++) { - cout << " colormod[" << castes[j].ColorModifier[k].part << "] "; + cout << " colormod[" << castes[j].ColorModifier[k].part; + if(castes[j].ColorModifier[k].startdate>0) + cout << " start:" << castes[j].ColorModifier[k].startdate << " days, end:" << castes[j].ColorModifier[k].enddate << " days"; + cout << "] "; for(uint32_t l = 0; l < castes[j].ColorModifier[k].colorlist.size(); l++) { if( castes[j].ColorModifier[k].colorlist[l] < Materials->color.size() ) diff --git a/output/Memory.xml b/output/Memory.xml index fb9b9e63d..b6d866ddf 100755 --- a/output/Memory.xml +++ b/output/Memory.xml @@ -1132,8 +1132,6 @@ map_data_1b60_offset 0x1B9c 0x1C 0x38 - - Creatures =========
0x0166ecc4
@@ -1156,6 +1154,8 @@ map_data_1b60_offset 0x1B9c 0x28C 0x290 + 0x298 + 0x29C 0x464