Accelerated reading of creatures

develop
Petr Mrázek 2010-03-28 17:22:15 +02:00
parent 6522d0c498
commit 85d347442d
9 changed files with 468 additions and 121 deletions

@ -23,9 +23,10 @@ distribution.
*/
#include "DFCommonInternal.h"
#include "../shmserver/shms.h"
#include "../shmserver/mod-core.h"
#include "../shmserver/mod-maps.h"
#include <shms.h>
#include <mod-core.h>
#include <mod-maps.h>
#include <mod-creature40d.h>
using namespace DFHack;
/*
@ -58,6 +59,8 @@ public:
uint32_t veinsize;
uint32_t vein_mineral_vptr;
uint32_t vein_ice_vptr;
uint32_t maps_module;
uint32_t window_x_offset;
uint32_t window_y_offset;
@ -69,39 +72,14 @@ public:
uint32_t view_screen_offset;
uint32_t current_menu_state_offset;
uint32_t name_firstname_offset;
uint32_t name_nickname_offset;
uint32_t name_words_offset;
uint32_t creature_pos_offset;
uint32_t creature_type_offset;
uint32_t creature_flags1_offset;
uint32_t creature_flags2_offset;
uint32_t creature_name_offset;
uint32_t creature_custom_profession_offset;
uint32_t creature_profession_offset;
uint32_t creature_sex_offset;
uint32_t creature_id_offset;
uint32_t creature_squad_name_offset;
uint32_t creature_squad_leader_id_offset;
uint32_t creature_money_offset;
uint32_t creature_current_job_offset;
uint32_t creature_current_job_id_offset;
uint32_t creature_strength_offset;
uint32_t creature_agility_offset;
uint32_t creature_toughness_offset;
uint32_t creature_skills_offset;
uint32_t creature_labors_offset;
uint32_t creature_happiness_offset;
uint32_t creature_traits_offset;
uint32_t creature_likes_offset;
uint32_t creature_artifact_name_offset;
uint32_t creature_mood_offset;
uint32_t creature_pregnancy_offset;
uint32_t creature_blood_max_offset;
uint32_t creature_blood_current_offset;
uint32_t creature_bleed_offset;
uint32_t name_firstname_offset;
uint32_t name_nickname_offset;
uint32_t name_words_offset;
Creatures::creature_offsets creatures;
uint32_t creature_module;
uint32_t item_material_offset;
uint32_t note_foreground_offset;
@ -139,8 +117,6 @@ public:
bool hotkeyInited;
bool settlementsInited;
bool nameTablesInited;
uint32_t maps_module;
uint32_t tree_offset;
DfVector *p_cre;
@ -197,7 +173,9 @@ API::API (const string path_to_xml)
d->nameTablesInited = false;
d->pm = NULL;
d->shm_start = 0;
d->maps_module = 0;
d->creature_module = 0;
}
API::~API()
@ -210,6 +188,7 @@ API::~API()
#define SHMCMD(num) ((shm_cmd *)d->shm_start)[num]->pingpong
#define SHMHDR ((shm_core_hdr *)d->shm_start)
#define SHMMAPSHDR ((Maps::shm_maps_hdr *)d->shm_start)
#define SHMCREATURESHDR ((Creatures::shm_creature_hdr *)d->shm_start)
#define SHMDATA(type) ((type *)(d->shm_start + SHM_HEADER))
/*-----------------------------------*
@ -322,14 +301,14 @@ bool API::DestroyMap()
bool API::isValidBlock (uint32_t x, uint32_t y, uint32_t z)
{
if (x < 0 || x >= d->x_block_count || y < 0 || y >= d->y_block_count || z < 0 || z >= d->z_block_count)
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 < 0 || x >= d->x_block_count || y < 0 || y >= d->y_block_count || z < 0 || z >= d->z_block_count)
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];
}
@ -1063,40 +1042,66 @@ bool API::InitReadCreatures( uint32_t &numcreatures )
try
{
memory_info * minfo = d->offset_descriptor;
int creatures = d->offset_descriptor->getAddress ("creatures");
d->creature_pos_offset = minfo->getOffset ("creature_position");
d->creature_type_offset = minfo->getOffset ("creature_race");
d->creature_flags1_offset = minfo->getOffset ("creature_flags1");
d->creature_flags2_offset = minfo->getOffset ("creature_flags2");
d->creature_name_offset = minfo->getOffset ("creature_name");
d->creature_custom_profession_offset = minfo->getOffset ("creature_custom_profession");
d->creature_profession_offset = minfo->getOffset ("creature_profession");
d->creature_sex_offset = minfo->getOffset ("creature_sex");
d->creature_id_offset = minfo->getOffset ("creature_id");
d->creature_squad_name_offset = minfo->getOffset ("creature_squad_name");
d->creature_squad_leader_id_offset = minfo->getOffset ("creature_squad_leader_id");
d->creature_money_offset = minfo->getOffset ("creature_money");
d->creature_current_job_offset = minfo->getOffset ("creature_current_job");
d->creature_current_job_id_offset = minfo->getOffset ("current_job_id");
d->creature_strength_offset = minfo->getOffset ("creature_strength");
d->creature_agility_offset = minfo->getOffset ("creature_agility");
d->creature_toughness_offset = minfo->getOffset ("creature_toughness");
d->creature_skills_offset = minfo->getOffset ("creature_skills");
d->creature_labors_offset = minfo->getOffset ("creature_labors");
d->creature_happiness_offset = minfo->getOffset ("creature_happiness");
d->creature_traits_offset = minfo->getOffset ("creature_traits");
d->creature_likes_offset = minfo->getOffset("creature_likes");
d->creature_artifact_name_offset = minfo->getOffset("creature_artifact_name");
d->creature_mood_offset = minfo->getOffset("creature_mood");
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");
d->creature_pregnancy_offset = minfo->getOffset("creature_pregnancy");
d->creature_blood_max_offset = minfo->getOffset("creature_blood_max");
d->creature_blood_current_offset = minfo->getOffset("creature_blood_current");
d->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");
d->p_cre = new DfVector (d->p->readVector (creatures, 4));
d->p_cre = new DfVector (d->p->readVector (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);
//cerr << "Creature acceleration enabled!" << endl;
}
/*
else
{
cerr << "Creature acceleration NOT enabled!" << endl;
}
*/
return true;
}
catch (Error::MissingMemoryDefinition&)
@ -1248,27 +1253,46 @@ int32_t API::ReadCreatureInBox (int32_t index, t_creature & furball,
const uint16_t x2, const uint16_t y2, const uint16_t z2)
{
if (!d->creaturesInited) return -1;
uint16_t coords[3];
uint32_t size = d->p_cre->getSize();
while (uint32_t(index) < size)
{
// read pointer from vector at position
uint32_t temp = * (uint32_t *) d->p_cre->at (index);
g_pProcess->read (temp + d->creature_pos_offset, 3 * sizeof (uint16_t), (uint8_t *) &coords);
if (coords[0] >= x1 && coords[0] < x2)
if(d->creature_module)
{
// supply the module with offsets so it can work with them
SHMCREATURESHDR->index = index;
SHMCREATURESHDR->x = x1;
SHMCREATURESHDR->y = y1;
SHMCREATURESHDR->z = z1;
SHMCREATURESHDR->x2 = x2;
SHMCREATURESHDR->y2 = y2;
SHMCREATURESHDR->z2 = z2;
const uint32_t cmd = Creatures::CREATURE_FIND_IN_BOX + (d->creature_module << 16);
g_pProcess->SetAndWait(cmd);
if(SHMCREATURESHDR->index != -1)
memcpy(&furball,SHMDATA(void),sizeof(t_creature));
return SHMCREATURESHDR->index;
}
else
{
uint16_t coords[3];
uint32_t size = d->p_cre->getSize();
while (uint32_t(index) < size)
{
if (coords[1] >= y1 && coords[1] < y2)
// read pointer from vector at position
uint32_t temp = * (uint32_t *) d->p_cre->at (index);
g_pProcess->read (temp + d->creatures.creature_pos_offset, 3 * sizeof (uint16_t), (uint8_t *) &coords);
if (coords[0] >= x1 && coords[0] < x2)
{
if (coords[2] >= z1 && coords[2] < z2)
if (coords[1] >= y1 && coords[1] < y2)
{
ReadCreature (index, furball);
return index;
if (coords[2] >= z1 && coords[2] < z2)
{
ReadCreature (index, furball);
return index;
}
}
}
index++;
}
index++;
return -1;
}
return -1;
}
bool API::getItemIndexesInBox(vector<uint32_t> &indexes,
@ -1305,27 +1329,38 @@ bool API::getItemIndexesInBox(vector<uint32_t> &indexes,
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 + d->creature_pos_offset, 3 * sizeof (uint16_t), (uint8_t *) & (furball.x)); // xyz really
g_pProcess->readDWord (temp + d->creature_type_offset, furball.type);
g_pProcess->readDWord (temp + d->creature_flags1_offset, furball.flags1.whole);
g_pProcess->readDWord (temp + d->creature_flags2_offset, furball.flags2.whole);
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 + d->creature_name_offset);
d->readName(furball.squad_name, temp + d->creature_squad_name_offset);
d->readName(furball.artifact_name, temp + d->creature_artifact_name_offset);
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 + d->creature_custom_profession_offset));
fill_char_buf (furball.custom_profession, d->p->readSTLString (temp + offs.creature_custom_profession_offset));
// labors
g_pProcess->read (temp + d->creature_labors_offset, NUM_CREATURE_LABORS, furball.labors);
g_pProcess->read (temp + offs.creature_labors_offset, NUM_CREATURE_LABORS, furball.labors);
// traits
g_pProcess->read (temp + d->creature_traits_offset, sizeof (uint16_t) * NUM_CREATURE_TRAITS, (uint8_t *) &furball.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->readVector (temp + d->creature_skills_offset, 4));
DfVector skills (d->p->readVector (temp + offs.creature_skills_offset, 4));
furball.numSkills = skills.getSize();
for (uint32_t i = 0; i < furball.numSkills;i++)
{
@ -1337,54 +1372,55 @@ bool API::ReadCreature (const int32_t index, t_creature & furball)
furball.skills[i].experience = g_pProcess->readWord (temp2 + 8);
}
// profession
furball.profession = g_pProcess->readByte (temp + d->creature_profession_offset);
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 + d->creature_current_job_offset);
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 + d->creature_current_job_id_offset);
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->readVector(temp+d->creature_likes_offset,4));
DfVector likes(d->p->readVector(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 + d->creature_mood_offset);
furball.mood = (int16_t) g_pProcess->readWord (temp + offs.creature_mood_offset);
g_pProcess->readDWord (temp + d->creature_happiness_offset, furball.happiness);
g_pProcess->readDWord (temp + d->creature_id_offset, furball.id);
g_pProcess->readDWord (temp + d->creature_agility_offset, furball.agility);
g_pProcess->readDWord (temp + d->creature_strength_offset, furball.strength);
g_pProcess->readDWord (temp + d->creature_toughness_offset, furball.toughness);
g_pProcess->readDWord (temp + d->creature_money_offset, furball.money);
furball.squad_leader_id = (int32_t) g_pProcess->readDWord (temp + d->creature_squad_leader_id_offset);
g_pProcess->readByte (temp + d->creature_sex_offset, furball.sex);
g_pProcess->readDWord(temp+d->creature_pregnancy_offset, furball.pregnancy_timer);
furball.blood_max = (int32_t) g_pProcess->readDWord(temp+d->creature_blood_max_offset);
furball.blood_current = (int32_t) g_pProcess->readDWord(temp+d->creature_blood_current_offset);
g_pProcess->readDWord(temp+d->creature_bleed_offset, furball.bleed_rate);
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;
}
void API::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
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->creature_labors_offset, NUM_CREATURE_LABORS, labors);
WriteRaw(temp + d->creatures.creature_labors_offset, NUM_CREATURE_LABORS, labors);
}
bool API::InitReadNameTables(vector<vector<string> > & translations , vector<vector<string> > & foreign_languages) //(map< string, vector<string> > & nameTable)

@ -221,7 +221,7 @@ namespace DFHack
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)
void WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]);
bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]);
/*
* Notes placed by the player

@ -9,6 +9,7 @@ mod-maps.h
SET(PROJECT_SRCS
mod-core.cpp
mod-maps.cpp
mod-creature40d.cpp
)
SET(PROJECT_HDRS_LINUX

@ -38,6 +38,7 @@ distribution.
#include "shms.h"
#include "mod-core.h"
#include "mod-maps.h"
#include "mod-creature40d.h"
std::vector <DFPP_module> module_registry;
@ -234,7 +235,12 @@ void InitModules (void)
{
// create the core module
module_registry.push_back(InitCore());
module_registry.push_back(InitMaps());
module_registry.push_back(DFHack::Maps::Init());
module_registry.push_back(DFHack::Creatures::Init());
for(int i = 0; i < module_registry.size();i++)
{
fprintf(stderr,"Initialized module %s, version %d\n",module_registry[i].name.c_str(),module_registry[i].version);
}
// TODO: dynamic module init
}

@ -0,0 +1,195 @@
#include <string>
#include <vector>
#include <integers.h>
#include "shms.h"
#include "mod-core.h"
#include "mod-creature40d.h"
#include <DFTypes.h>
#include <string.h>
#include <malloc.h>
#include <vector>
#include <stdio.h>
extern char *shm;
namespace DFHack{ namespace Creatures{ // start of namespace
#define SHMHDR ((shm_creature_hdr *)shm)
#define SHMDATA(type) ((type *)(shm + SHM_HEADER))
void readName(t_name & name, char * address, creature_offsets & offsets)
{
// custom profession
std::string * fname = (std::string *) (address + offsets.name_firstname_offset);
strncpy(name.first_name,fname->c_str(),127);
name.first_name[127] = 0;
std::string * nname = (std::string *) (address + offsets.name_nickname_offset);
strncpy(name.nickname,nname->c_str(),127);
name.nickname[127] = 0;
memcpy(name.words, (void *)(address + offsets.name_words_offset), 48);
}
void InitOffsets (void* data)
{
creature_modulestate * state = (creature_modulestate *) data;
memcpy((void *) &(state->offsets), SHMDATA(void), sizeof(creature_offsets));
((creature_modulestate *) data)->inited = true;
}
void ReadCreatureAtIndex(void *data)
{
creature_modulestate * state = (creature_modulestate *) data;
creature_offsets & offsets = state->offsets;
std::vector<char *> * creaturev = (std::vector<char *> *) offsets.creature_vector;
uint32_t length = creaturev->size();
int32_t index = SHMHDR->index;
// read pointer from vector at position
char * temp = (char *) creaturev->at (index);
t_creature *furball = SHMDATA(t_creature);
furball->origin = (uint32_t) temp;
//read creature from memory
memcpy(&(furball->x),temp + offsets.creature_pos_offset,3* sizeof(uint16_t));
furball->type = *(uint32_t *) (temp + offsets.creature_type_offset);
furball->flags1.whole = *(uint32_t *) (temp + offsets.creature_flags1_offset);
furball->flags2.whole = *(uint32_t *) (temp + offsets.creature_flags2_offset);
// names
readName(furball->name,temp + offsets.creature_name_offset, offsets);
readName(furball->squad_name, temp + offsets.creature_squad_name_offset, offsets);
readName(furball->artifact_name, temp + offsets.creature_artifact_name_offset, offsets);
// custom profession
std::string * custprof = (std::string *) (temp + offsets.creature_custom_profession_offset);
strncpy(furball->custom_profession,custprof->c_str(),127);
furball->custom_profession[127] = 0;
// labors
memcpy(furball->labors, temp + offsets.creature_labors_offset, NUM_CREATURE_LABORS);
// traits
memcpy(furball->traits, temp + offsets.creature_traits_offset, sizeof (uint16_t) * NUM_CREATURE_TRAITS);
typedef struct
{
uint8_t id;
junk_fill <3> fill1;
uint8_t rating;
junk_fill <3> fill2;
uint16_t experience;
} raw_skill;
// learned skills
std::vector <void *> * skillv = (std::vector <void *> *) (temp + offsets.creature_skills_offset);
//DfVector skills (d->p->readVector (temp + offsets.creature_skills_offset, 4));
furball->numSkills = skillv->size();
for (uint32_t i = 0; i < furball->numSkills;i++)
{
//skills.read(i, (uint8_t *) &temp2);
// a byte: this gives us 256 skills maximum.
furball->skills[i].id = ( (raw_skill*) skillv->at(i))->id;
furball->skills[i].rating = ( (raw_skill*) skillv->at(i))->rating;
furball->skills[i].experience = ( (raw_skill*) skillv->at(i))->experience;
}
// profession
furball->profession = *(uint8_t *) (temp + offsets.creature_profession_offset);
// current job HACK: the job object isn't cleanly represented here
uint32_t jobIdAddr = *(uint32_t *) (temp + offsets.creature_current_job_offset);
if (jobIdAddr)
{
furball->current_job.active = true;
furball->current_job.jobId = *(uint8_t *) (jobIdAddr + offsets.creature_current_job_id_offset);
}
else
{
furball->current_job.active = false;
}
//likes
std::vector <t_like *> * likev = (std::vector <t_like *> *) (temp + offsets.creature_likes_offset);
furball->numLikes = likev->size();
for(uint32_t i = 0;i<furball->numLikes;i++)
{
memcpy(&furball->likes[i], likev->at(i), sizeof(t_skill));
}
furball->mood = *(int16_t *) (temp + offsets.creature_mood_offset);
furball->happiness = *(uint32_t *) (temp + offsets.creature_happiness_offset);
furball->id = *(uint32_t *) (temp + offsets.creature_id_offset);
furball->agility = *(uint32_t *) (temp + offsets.creature_agility_offset);
furball->strength = *(uint32_t *) (temp + offsets.creature_strength_offset);
furball->toughness = *(uint32_t *) (temp + offsets.creature_toughness_offset);
furball->money = *(uint32_t *) (temp + offsets.creature_money_offset);
furball->squad_leader_id = *(int32_t*) (temp + offsets.creature_squad_leader_id_offset);
furball->sex = *(uint8_t*) (temp + offsets.creature_sex_offset);
furball->pregnancy_timer = *(uint32_t *)(temp+offsets.creature_pregnancy_offset);
furball->blood_max = *(int32_t*) (temp+offsets.creature_blood_max_offset);
furball->blood_current = *(int32_t*) (temp+offsets.creature_blood_current_offset);
furball->bleed_rate = *(uint32_t*) (temp+offsets.creature_bleed_offset);
}
void FindNextCreatureInBox (void * data)
{
int32_t index = SHMHDR->index;
// sanity
if(index == -1) return;
creature_modulestate * state = (creature_modulestate *) data;
creature_offsets & offsets = state->offsets;
uint32_t x,y,z,x2,y2,z2;
x = SHMHDR->x; x2 = SHMHDR->x2;
y = SHMHDR->y; y2 = SHMHDR->y2;
z = SHMHDR->z; z2 = SHMHDR->x2;
std::vector<char *> * creaturev = (std::vector<char *> *) offsets.creature_vector;
uint32_t length = creaturev->size();
typedef uint16_t coords[3];
// look at all creatures, starting at index
// if you find one in the specified 'box', return the creature in the data
// section and the index in the header
for(;index < length;index++)
{
coords& coo = *(coords*) (creaturev->at(index) + offsets.creature_pos_offset);
if(coo[0] >=x && coo[0] < x2
&& coo[1] >=y && coo[1] < y2
&& coo[2] >=z && coo[2] < z2)
{
// we found a creature!
SHMHDR->index = index;
ReadCreatureAtIndex(data);
return; // we're done here
}
}
// nothing found
SHMHDR->index = -1;
}
DFPP_module Init( void )
{
DFPP_module creatures;
creatures.name = "Creatures40d";
creatures.version = CREATURES40D_VERSION;
// freed by the core
creatures.modulestate = malloc(sizeof(creature_modulestate)); // we store a flag
memset(creatures.modulestate,0,sizeof(creature_modulestate));
creatures.reserve(NUM_CREATURE_CMDS);
creatures.set_command(CREATURE_INIT, FUNCTION, "Supply the Creature40d module with offsets",InitOffsets,CORE_SUSPENDED);
creatures.set_command(CREATURE_FIND_IN_BOX, FUNCTION, "Get next creature in a box, return new index or -1", FindNextCreatureInBox, CORE_SUSPENDED);
creatures.set_command(CREATURE_AT_INDEX, FUNCTION, "Get creature at index", ReadCreatureAtIndex, CORE_SUSPENDED);
return creatures;
}
}} // end of namespace

@ -0,0 +1,104 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix)
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 MOD_CREATURES40D_H
#define MOD_CREATURES40D_H
namespace DFHack
{
namespace Creatures
{
#define CREATURES40D_VERSION 1
typedef struct
{
// creature offsets
uint32_t creature_vector;
uint32_t creature_pos_offset;
uint32_t creature_type_offset;
uint32_t creature_flags1_offset;
uint32_t creature_flags2_offset;
uint32_t creature_name_offset;
uint32_t creature_custom_profession_offset;
uint32_t creature_profession_offset;
uint32_t creature_sex_offset;
uint32_t creature_id_offset;
uint32_t creature_squad_name_offset;
uint32_t creature_squad_leader_id_offset;
uint32_t creature_money_offset;
uint32_t creature_current_job_offset;
uint32_t creature_current_job_id_offset;
uint32_t creature_strength_offset;
uint32_t creature_agility_offset;
uint32_t creature_toughness_offset;
uint32_t creature_skills_offset;
uint32_t creature_labors_offset;
uint32_t creature_happiness_offset;
uint32_t creature_traits_offset;
uint32_t creature_likes_offset;
uint32_t creature_artifact_name_offset;
uint32_t creature_mood_offset;
uint32_t creature_pregnancy_offset;
uint32_t creature_blood_max_offset;
uint32_t creature_blood_current_offset;
uint32_t creature_bleed_offset;
// name offsets (needed for reading creature names)
uint32_t name_firstname_offset;
uint32_t name_nickname_offset;
uint32_t name_words_offset;
} creature_offsets;
typedef struct
{
bool inited;
creature_offsets offsets;
} creature_modulestate;
typedef struct
{
shm_cmd cmd[SHM_MAX_CLIENTS]; // MANDATORY!
// box
uint32_t x;
uint32_t y;
uint32_t z;
uint32_t x2;
uint32_t y2;
uint32_t z2;
// starting index
int32_t index;
} shm_creature_hdr;
enum CREATURE_COMMAND
{
CREATURE_INIT = 0, // initialization
CREATURE_FIND_IN_BOX,
CREATURE_AT_INDEX,
NUM_CREATURE_CMDS,
};
DFPP_module Init(void);
}
}
#endif

@ -17,6 +17,8 @@ extern char *shm;
//TODO: circular buffer streaming primitives required
//TODO: commands can fail without the proper offsets. Hot to handle that?
namespace DFHack{ namespace Maps{ // start of namespace
#define SHMHDR ((shm_maps_hdr *)shm)
#define SHMCMD ((shm_cmd *)shm)->pingpong
#define SHMDATA(type) ((type *)(shm + SHM_HEADER))
@ -92,7 +94,7 @@ void ReadBlockByCoords (void * data)
ReadBlockByAddress(data); // I wonder... will this inline properly?
}
DFPP_module InitMaps( void )
DFPP_module Init( void )
{
DFPP_module maps;
maps.name = "Maps";
@ -116,4 +118,6 @@ DFPP_module InitMaps( void )
maps.set_command(MAP_READ_BLOCKS_3D, FUNCTION, "Read a range of blocks between two sets of coords", NullCommand, CORE_SUSPENDED);
return maps;
}
}
}} // end of namespace

@ -96,6 +96,8 @@ enum MAPS_COMMAND
MAP_REVEAL, // reveal the whole map
NUM_MAPS_CMDS,
};
DFPP_module Init(void);
}
}

@ -108,7 +108,6 @@ void InitModules (void);
void KillModules (void);
bool isValidSHM(int current);
uint32_t OS_getPID();
DFPP_module InitMaps(void);
uint32_t OS_getAffinity(); // limited to 32 processors. Silly, eh?
void OS_releaseSuspendLock(int currentClient);
void OS_lockSuspendLock(int currentClient);