From dca4c43b0b467fcf6eba147e4f5d7b23d659be47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 18 Sep 2011 13:49:10 +0200 Subject: [PATCH] Creatures module rewrite --- library/include/dfhack/modules/Creatures.h | 449 +++++++++++++++++-- library/include/dfhack/modules/Translation.h | 6 +- library/modules/Creatures.cpp | 407 +++++++---------- library/modules/Items.cpp | 2 +- library/modules/Translation.cpp | 65 ++- plugins/cleanowned.cpp | 12 +- plugins/devel/kittens.cpp | 14 + plugins/stonesense | 2 +- 8 files changed, 616 insertions(+), 341 deletions(-) diff --git a/library/include/dfhack/modules/Creatures.h b/library/include/dfhack/modules/Creatures.h index 967218b56..c5d623edc 100644 --- a/library/include/dfhack/modules/Creatures.h +++ b/library/include/dfhack/modules/Creatures.h @@ -260,6 +260,7 @@ namespace DFHack /** * \ingroup grp_creatures */ + /* struct t_like { int16_t type; @@ -268,25 +269,23 @@ namespace DFHack t_matglossPair material; bool active; }; - + */ // FIXME: THIS IS VERY, VERY BAD. + #define NUM_CREATURE_LABORS 96 #define NUM_CREATURE_TRAITS 30 - #define NUM_CREATURE_LABORS 102 #define NUM_CREATURE_MENTAL_ATTRIBUTES 13 #define NUM_CREATURE_PHYSICAL_ATTRIBUTES 6 /** - * structure for holding a DF creature's soul + * structure for holding a copy of a creature's soul * \ingroup grp_creatures */ struct t_soul { uint8_t numSkills; t_skill skills[256]; - /* - uint8_t numLikes; - t_like likes[32]; - */ + //uint8_t numLikes; + //t_like likes[32]; uint16_t traits[NUM_CREATURE_TRAITS]; t_attrib analytical_ability; t_attrib focus; @@ -302,15 +301,15 @@ namespace DFHack t_attrib empathy; t_attrib social_awareness; }; - #define MAX_COLORS 15 + struct df_creature; /** - * structure for holding a DF creature + * structure for holding a copy of a creature * \ingroup grp_creatures */ struct t_creature { - uint32_t origin; + df_creature * origin; uint16_t x; uint16_t y; uint16_t z; @@ -328,7 +327,7 @@ namespace DFHack t_name artifact_name; uint8_t profession; - char custom_profession[128]; + std::string custom_profession; // enabled labors uint8_t labors[NUM_CREATURE_LABORS]; @@ -346,8 +345,8 @@ namespace DFHack uint8_t sex; uint16_t caste; uint32_t pregnancy_timer; //Countdown timer to giving birth - bool has_default_soul; - t_soul defaultSoul; + //bool has_default_soul; + //t_soul defaultSoul; uint32_t nbcolors; uint32_t color[MAX_COLORS]; @@ -355,7 +354,375 @@ namespace DFHack uint32_t birth_time; }; - class DFContextShared; + /** + * Creature attribute descriptor + * \ingroup grp_creatures + */ + struct df_attrib + { + uint32_t unk_0; + uint32_t unk_4; + uint32_t unk_8; + uint32_t unk_c; + uint32_t unk_10; + uint32_t unk_14; + uint32_t unk_18; + }; + /** + * Creature skil descriptor + * \ingroup grp_creatures + */ + struct df_skill + { + uint16_t id; // 0 + int32_t rating; // 4 + uint32_t experience; // 8 + uint32_t unk_c; + uint32_t rusty; // 10 + uint32_t unk_14; + uint32_t unk_18; + uint32_t unk_1c; + }; + /** + * A creature's soul, as it appears in DF memory + * \ingroup grp_creatures + */ + struct df_soul + { + uint32_t unk_0; + df_name name; // 4 + uint32_t unk_70; + uint16_t unk_74; + uint16_t unk_76; + int32_t unk_78; + int32_t unk_7c; + int32_t unk_80; + int32_t unk_84; + df_attrib mental[NUM_CREATURE_MENTAL_ATTRIBUTES]; // 88..1f3 + std::vector skills; // 1f4; + std::vector unk_204; // pointers to 14 0x14-byte structures ... likes? + uint16_t traits[NUM_CREATURE_TRAITS]; // 214 + std::vector unk_250; // 1 pointer to 2 shorts + uint32_t unk_260; + uint32_t unk_264; + uint32_t unk_268; + uint32_t unk_26c; + }; + /** + * A creature job - what it's supposed to be doing. + * \ingroup grp_creatures + */ + struct df_job + { + + }; + /** + * A creature, as it appears in DF memory + * \ingroup grp_creatures + */ + struct df_creature + { + df_name name; // 0 + std::string custom_profession; // 6c (MSVC) + uint8_t profession; // 88 + uint32_t race; // 8c + uint16_t x; // 90 + uint16_t y; // 92 + uint16_t z; // 94 + + uint16_t unk_x96; // 96 + uint16_t unk_y98; // 98 + uint16_t unk_z9a; // 9a + + uint32_t unk_9c; + uint16_t unk_a0; + int16_t unk_a2; + uint32_t unk_a4; + + uint16_t dest_x; // a8 + uint16_t dest_y; // aa + uint16_t dest_z; // ac + uint16_t unk_ae; // -1 + + std::vector unk_b0; // b0->df (3*4 in MSVC) -> 68->8b (3*3 in glibc) + std::vector unk_c0; + std::vector unk_d0; + + t_creaturflags1 flags1; // e0 + t_creaturflags2 flags2; // e4 + t_creaturflags3 flags3; // e8 + + void ** unk_ec; + int32_t unk_f0; + int16_t unk_f4; + int16_t unk_f6; + uint16_t caste; // f8 + uint8_t sex; // fa + uint32_t id; // fc + uint16_t unk_100; + uint16_t unk_102; + int32_t unk_104; + uint32_t civ; // 108 + uint32_t unk_10c; + int32_t unk_110; + + std::vector unk_114; + std::vector unk_124; + std::vector unk_134; + + uint32_t unk_144; + + std::vector unk_148; + std::vector unk_158; + + int32_t unk_168; + int32_t unk_16c; + uint32_t unk_170; + uint32_t unk_174; + uint16_t unk_178; + + std::vector unk_17c; + std::vector unk_18c; + std::vector unk_19c; + std::vector unk_1ac; + uint32_t pickup_equipment_bit; // 1bc + std::vector unk_1c0; + std::vector unk_1d0; + std::vector unk_1e0; + + int32_t unk_1f0; + int16_t unk_1f4; + int32_t unk_1f8; + int32_t unk_1fc; + int32_t unk_200; + int16_t unk_204; + uint32_t unk_208; + uint32_t unk_20c; + + int16_t mood; // 210 + uint32_t pregnancy_timer; // 214 + void* pregnancy_ptr; // 218 + int32_t unk_21c; + uint32_t unk_220; + uint32_t birth_year; // 224 + uint32_t birth_time; // 228 + uint32_t unk_22c; + uint32_t unk_230; + uint32_t unk_234; + uint32_t unk_238; + int32_t unk_23c; + int32_t unk_240; + int32_t unk_244; + int32_t unk_248; + int32_t unk_24c; + int32_t unk_250; + int32_t unk_254; + int32_t unk_258; + int32_t unk_25c; + int32_t unk_260; + int16_t unk_264; + int32_t unk_268; + int32_t unk_26c; + int16_t unk_270; + int32_t unk_274; + int32_t unk_278; + int32_t unk_27c; + int16_t unk_280; + int32_t unk_284; + + std::vector inventory; // 288 - vector of item pointers + std::vector owned_items; // 298 - vector of item IDs + std::vector unk_2a8; + std::vector unk_2b8; + std::vector unk_2c8; + + uint32_t unk_2d8; + uint32_t unk_2dc; + uint32_t unk_2e0; + uint32_t unk_2e4; + uint32_t unk_2e8; + uint32_t unk_2ec; + uint32_t unk_2f0; + df_job * current_job; // 2f4 + uint32_t unk_2f8; // possibly current skill? + uint32_t unk_2fc; + uint32_t unk_300; + uint32_t unk_304; + + std::vector unk_308; + std::vector unk_318; + std::vector unk_328; + std::vector unk_338; + std::vector unk_348; + std::vector unk_358; + std::vector unk_368; + std::vector unk_378; + std::vector unk_388; + + uint32_t unk_398; + int32_t unk_39c; + int32_t unk_3a0; + int32_t unk_3a4; + int32_t unk_3a8; + int32_t unk_3ac; + int32_t unk_3b0; + int32_t unk_3b4; + int32_t unk_3b8; + int32_t unk_3bc; + int32_t unk_3c0; + uint32_t unk_3c4; + uint32_t unk_3c8; + + df_attrib physical[NUM_CREATURE_PHYSICAL_ATTRIBUTES]; // 3cc..473 + uint32_t unk_474; + uint32_t unk_478; + uint32_t unk_47c; + uint32_t unk_480; + uint32_t unk_484; + uint32_t unk_488; + + uint32_t unk_48c; // blood_max? + uint32_t blood_count; // 490 + uint32_t unk_494; + std::vector unk_498; + std::vector unk_4a8; + std::vector unk_4b8; + uint32_t unk_4c8; + std::vector unk_4cc; + std::vector unk_4dc; + std::vector unk_4ec; + std::vector unk_4fc; + std::vector unk_50c; + void* unk_51c; + uint16_t unk_520; + uint16_t unk_522; + uint16_t* unk_524; + uint16_t unk_528; + uint16_t unk_52a; + std::vector appearance; // 52c + int16_t unk_53c; + int16_t unk_53e; + int16_t unk_540; + int16_t unk_542; + int16_t unk_544; + int16_t unk_546; + int16_t unk_548; + int16_t unk_54a; + int16_t unk_54c; + int16_t unk_54e; + int16_t unk_550; + int16_t unk_552; + int16_t unk_x554; // coords ? (-30.000x3) + int16_t unk_y556; + int16_t unk_z558; + int16_t unk_x55a; // coords again + int16_t unk_y55c; + int16_t unk_z55e; + int16_t unk_560; + int16_t unk_562; + + uint32_t unk_564; + uint32_t unk_568; + uint32_t unk_56c; + uint32_t unk_570; + uint32_t unk_574; + uint32_t unk_578; + uint32_t unk_57c; + uint32_t unk_580; + uint32_t unk_584; + uint32_t unk_588; + uint32_t unk_58c; + uint32_t unk_590; + uint32_t unk_594; + uint32_t unk_598; + uint32_t unk_59c; + + std::vector unk_5a0; + void* unk_5b0; // pointer to X (12?) vector + uint32_t unk_5b4; // 0x3e8 (1000) + uint32_t unk_5b8; // 0x3e8 (1000) + std::vector unk_5bc; + std::vector unk_5cc; + int16_t unk_5dc; + int16_t unk_5de; + df_name artifact_name; // 5e0 + std::vector souls; // 64c + df_soul* current_soul; // 65c + std::vector unk_660; + uint8_t labors[NUM_CREATURE_LABORS]; // 670..6cf + + std::vector unk_6d0; + std::vector unk_6e0; + std::vector unk_6f0; + std::vector unk_700; + uint32_t happiness; // 710 + uint16_t unk_714; + uint16_t unk_716; + std::vector unk_718; + std::vector unk_728; + std::vector unk_738; + std::vector unk_748; + uint16_t unk_758; + uint16_t unk_x75a; // coords (-30000*3) + uint16_t unk_y75c; + uint16_t unk_z75e; + std::vector unk_760; + std::vector unk_770; + std::vector unk_780; + uint32_t hist_figure_id; // 790 + uint16_t able_stand; // 794 + uint16_t able_stand_impair; // 796 + uint16_t able_grasp; // 798 + uint16_t able_grasp_impair; // 79a + uint32_t unk_79c; + uint32_t unk_7a0; + std::vector unk_7a4; + uint32_t unk_7b4; + uint32_t unk_7b8; + uint32_t unk_7bc; + int32_t unk_7c0; + + std::vector unk_7c4; + std::vector unk_7d4; + std::vector unk_7e4; + std::vector unk_7f4; + std::vector unk_804; + std::vector unk_814; + + uint32_t unk_824; + void* unk_828; + void* unk_82c; + uint32_t unk_830; + void* unk_834; + void* unk_838; + void* unk_83c; + + std::vector unk_840; + std::vector unk_850; + std::vector unk_860; + uint32_t unk_870; + uint32_t unk_874; + std::vector unk_878; + std::vector unk_888; + std::vector unk_898; + std::vector unk_8a8; + std::vector unk_8b8; + std::vector unk_8c8; + std::vector unk_8d8; + std::vector unk_8e8; + std::vector unk_8f8; + std::vector unk_908; + + int32_t unk_918; + uint16_t unk_91c; + uint16_t unk_91e; + uint16_t unk_920; + uint16_t unk_922; + uint32_t unk_924; + uint32_t unk_928; + std::vector unk_92c; + uint32_t unk_93c; + }; /** * The Creatures module - allows reading all non-vermin creatures and their properties * \ingroup grp_modules @@ -363,6 +730,8 @@ namespace DFHack */ class DFHACK_EXPORT Creatures : public Module { + public: + std::vector * creatures; public: Creatures(); ~Creatures(); @@ -372,17 +741,19 @@ namespace DFHack /* Read Functions */ // 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, + int32_t GetCreatureInBox(const int32_t index, df_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); - bool ReadJob(const t_creature * furball, std::vector & mat); + df_creature * GetCreature(const int32_t index); + void CopyCreature(df_creature * source, t_creature & target); + + bool ReadJob(const df_creature * unit, std::vector & mat); - bool ReadInventoryIdx(const uint32_t index, std::vector & item); - bool ReadInventoryPtr(const uint32_t index, std::vector & item); + bool ReadInventoryByIdx(const uint32_t index, std::vector & item); + bool ReadInventoryByPtr(const df_creature * unit, std::vector & item); - bool ReadOwnedItemsIdx(const uint32_t index, std::vector & item); - bool ReadOwnedItemsPtr(const uint32_t index, std::vector & item); + bool ReadOwnedItemsByIdx(const uint32_t index, std::vector & item); + bool ReadOwnedItemsByPtr(const df_creature * unit, std::vector & item); int32_t FindIndexById(int32_t id); @@ -391,27 +762,27 @@ namespace DFHack int32_t GetDwarfCivId ( void ); /* Write Functions */ - bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]); - bool WriteHappiness(const uint32_t index, const uint32_t happinessValue); - bool WriteFlags(const uint32_t index, const uint32_t flags1, const uint32_t flags2); - bool WriteFlags(const uint32_t index, const uint32_t flags1, const uint32_t flags2, uint32_t flags3); - bool WriteSkills(const uint32_t index, const t_soul &soul); - bool WriteAttributes(const uint32_t index, const t_creature &creature); - bool WriteSex(const uint32_t index, const uint8_t sex); - bool WriteTraits(const uint32_t index, const t_soul &soul); - bool WriteMood(const uint32_t index, const uint16_t mood); - bool WriteMoodSkill(const uint32_t index, const uint16_t moodSkill); - bool WriteJob(const t_creature * furball, std::vector const& mat); - bool WritePos(const uint32_t index, const t_creature &creature); - bool WriteCiv(const uint32_t index, const int32_t civ); - bool WritePregnancy(const uint32_t index, const uint32_t pregTimer); - - void CopyNameTo(t_creature &creature, uint32_t address); + //bool WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]); + //bool WriteHappiness(const uint32_t index, const uint32_t happinessValue); + //bool WriteFlags(const uint32_t index, const uint32_t flags1, const uint32_t flags2); + //bool WriteFlags(const uint32_t index, const uint32_t flags1, const uint32_t flags2, uint32_t flags3); + //bool WriteSkills(const uint32_t index, const t_soul &soul); + //bool WriteAttributes(const uint32_t index, const t_creature &creature); + //bool WriteSex(const uint32_t index, const uint8_t sex); + //bool WriteTraits(const uint32_t index, const t_soul &soul); + //bool WriteMood(const uint32_t index, const uint16_t mood); + //bool WriteMoodSkill(const uint32_t index, const uint16_t moodSkill); + //bool WriteJob(const t_creature * furball, std::vector const& mat); + //bool WritePos(const uint32_t index, const t_creature &creature); + //bool WriteCiv(const uint32_t index, const int32_t civ); + //bool WritePregnancy(const uint32_t index, const uint32_t pregTimer); + + void CopyNameTo(df_creature *creature, df_name * target); protected: friend class Items; - bool RemoveOwnedItemIdx(const uint32_t index, int32_t id); - bool RemoveOwnedItemPtr(const uint32_t index, int32_t id); + bool RemoveOwnedItemByIdx(const uint32_t index, int32_t id); + bool RemoveOwnedItemByPtr(df_creature * unit, int32_t id); private: struct Private; diff --git a/library/include/dfhack/modules/Translation.h b/library/include/dfhack/modules/Translation.h index ba14c2d0d..e21102d50 100644 --- a/library/include/dfhack/modules/Translation.h +++ b/library/include/dfhack/modules/Translation.h @@ -67,10 +67,10 @@ namespace DFHack // names, used by a few other modules. bool InitReadNames(); - bool readName(t_name & name, uint32_t address); - bool copyName(uint32_t address, uint32_t target); + bool readName(t_name & name, df_name * address); + bool copyName(df_name * address, df_name * target); // translate a name using the loaded dictionaries - std::string TranslateName(const DFHack::t_name& name, bool inEnglish = true); + std::string TranslateName(const DFHack::df_name * name, bool inEnglish = true); private: struct Private; diff --git a/library/modules/Creatures.cpp b/library/modules/Creatures.cpp index af2925c45..c19b6cc93 100644 --- a/library/modules/Creatures.cpp +++ b/library/modules/Creatures.cpp @@ -30,6 +30,7 @@ distribution. #include #include #include +#include using namespace std; @@ -52,6 +53,7 @@ struct Creatures::Private { bool Inited; bool Started; + /* bool Ft_basic; bool Ft_advanced; bool Ft_jobs; @@ -111,12 +113,13 @@ struct Creatures::Private int32_t job_material_flags_o; // creature job material stuff } creatures; + */ uint32_t creature_module; uint32_t dwarf_race_index_addr; uint32_t dwarf_civ_id_addr; bool IdMapReady; std::map IdMap; - DfVector *p_cre; + //DfVector *p_cre; Process *owner; Translation * trans; }; @@ -129,13 +132,13 @@ Module* DFHack::createCreatures() Creatures::Creatures() { Core & c = Core::getInstance(); + creatures = 0; d = new Private; d->owner = c.p; VersionInfo * minfo = c.vinfo; d->Inited = false; d->Started = false; d->IdMapReady = false; - d->p_cre = NULL; d->trans = c.getTranslation(); d->trans->InitReadNames(); // throws on error @@ -146,90 +149,12 @@ Creatures::Creatures() OffsetGroup * OG_name = minfo->getGroup("name"); OffsetGroup * OG_jobs = OG_Creatures->getGroup("job"); OffsetGroup * OG_job_mats = OG_jobs->getGroup("material"); - d->Ft_basic = d->Ft_advanced = d->Ft_jobs = d->Ft_soul = d->Ft_inventory = d->Ft_owned_items = d->Ft_job_materials = false; - Private::t_offsets &creatures = d->creatures; try { - // Creatures - creatures.vector = OG_Creatures->getAddress ("vector"); + creatures = (vector *) OG_Creatures->getAddress ("vector"); d->dwarf_race_index_addr = OG_Creatures->getAddress("current_race"); d->dwarf_civ_id_addr = OG_Creatures->getAddress("current_civ"); - // Creatures/creature - creatures.name_offset = OG_creature->getOffset ("name"); - creatures.custom_profession_offset = OG_creature->getOffset ("custom_profession"); - creatures.profession_offset = OG_creature->getOffset ("profession"); - creatures.race_offset = OG_creature->getOffset ("race"); - creatures.pos_offset = OG_creature->getOffset ("position"); - creatures.flags1_offset = OG_creature->getOffset ("flags1"); - creatures.flags2_offset = OG_creature->getOffset ("flags2"); - creatures.flags3_offset = OG_creature->getOffset ("flags3"); - creatures.sex_offset = OG_creature->getOffset ("sex"); - creatures.caste_offset = OG_creature->getOffset ("caste"); - creatures.id_offset = OG_creature->getOffset ("id"); - creatures.civ_offset = OG_creature->getOffset ("civ"); - // name struct - creatures.name_firstname_offset = OG_name->getOffset("first"); - creatures.name_nickname_offset = OG_name->getOffset("nick"); - creatures.name_words_offset = OG_name->getOffset("second_words"); - d->Ft_basic = true; - try - { - creatures.pickup_equipment_bit = OG_creature_ex->getOffset("pickup_equipment_bit"); - creatures.mood_offset = OG_creature_ex->getOffset("mood"); - creatures.pregnancy_offset = OG_creature_ex->getOffset("pregnancy"); - creatures.pregnancy_ptr_offset = OG_creature_ex->getOffset("pregnancy_ptr"); - creatures.birth_year_offset = OG_creature_ex->getOffset("birth_year"); - creatures.birth_time_offset = OG_creature_ex->getOffset("birth_time"); - creatures.current_job_offset = OG_creature_ex->getOffset("current_job"); - creatures.mood_skill_offset = OG_creature_ex->getOffset("current_job_skill"); - creatures.physical_offset = OG_creature_ex->getOffset("physical"); - creatures.appearance_vector_offset = OG_creature_ex->getOffset("appearance_vector"); - creatures.artifact_name_offset = OG_creature_ex->getOffset("artifact_name"); - creatures.labors_offset = OG_creature_ex->getOffset ("labors"); - creatures.happiness_offset = OG_creature_ex->getOffset ("happiness"); - d->Ft_advanced = true; - }catch(Error::All&){}; - try - { - creatures.inventory_offset = OG_creature_ex->getOffset("inventory_vector"); - d->Ft_inventory = true; - } - catch(Error::All&){}; - try - { - creatures.owned_items_offset = OG_creature_ex->getOffset("owned_items_vector"); - d->Ft_owned_items = true; - } - catch(Error::All&){}; - try - { - creatures.soul_vector_offset = OG_creature_ex->getOffset("soul_vector"); - creatures.default_soul_offset = OG_creature_ex->getOffset("current_soul"); - creatures.soul_mental_offset = OG_soul->getOffset("mental"); - creatures.soul_skills_vector_offset = OG_soul->getOffset("skills_vector"); - creatures.soul_traits_offset = OG_soul->getOffset("traits"); - d->Ft_soul = true; - } - catch(Error::All&){}; - try - { - creatures.job_type_offset = OG_jobs->getOffset("type"); - creatures.job_id_offset = OG_jobs->getOffset("id"); - d->Ft_jobs = true; - try - { - creatures.job_materials_vector = OG_jobs->getOffset("materials_vector"); - creatures.job_material_itemtype_o = OG_job_mats->getOffset("maintype"); - creatures.job_material_subtype_o = OG_job_mats->getOffset("sectype1"); - creatures.job_material_subindex_o = OG_job_mats->getOffset("sectype2"); - creatures.job_material_index_o = OG_job_mats->getOffset("sectype3"); - creatures.job_material_flags_o = OG_job_mats->getOffset("flags"); - d->Ft_job_materials = true; - } - catch(Error::All&){}; - } - catch(Error::All&){}; } catch(Error::All&){}; d->Inited = true; @@ -243,11 +168,10 @@ Creatures::~Creatures() bool Creatures::Start( uint32_t &numcreatures ) { - if(d->Ft_basic) + if(creatures) { - d->p_cre = new DfVector (d->creatures.vector); d->Started = true; - numcreatures = d->p_cre->size(); + numcreatures = creatures->size(); d->IdMapReady = false; return true; } @@ -256,96 +180,116 @@ bool Creatures::Start( uint32_t &numcreatures ) bool Creatures::Finish() { - if(d->p_cre) - { - delete d->p_cre; - d->p_cre = 0; - } d->Started = false; return true; } -bool Creatures::ReadCreature (const int32_t index, t_creature & furball) +df_creature * Creatures::GetCreature (const int32_t index) { - if(!d->Started) return false; - memset(&furball, 0, sizeof(t_creature)); - // SHM fast path - Process * p = d->owner; + if(!d->Started) return nullptr; // read pointer from vector at position - uint32_t addr_cr = d->p_cre->at (index); - furball.origin = addr_cr; - Private::t_offsets &offs = d->creatures; + if(index > creatures->size()) + return nullptr; + return creatures->at(index); +} - //read creature from memory - if(d->Ft_basic) - { - // name - d->trans->readName(furball.name,addr_cr + offs.name_offset); - - // basic stuff - p->readDWord (addr_cr + offs.id_offset, furball.id); - p->read (addr_cr + offs.pos_offset, 3 * sizeof (uint16_t), (uint8_t *) & (furball.x)); // xyz really - p->readDWord (addr_cr + offs.race_offset, furball.race); - furball.civ = p->readDWord (addr_cr + offs.civ_offset); - p->readByte (addr_cr + offs.sex_offset, furball.sex); - p->readWord (addr_cr + offs.caste_offset, furball.caste); - p->readDWord (addr_cr + offs.flags1_offset, furball.flags1.whole); - p->readDWord (addr_cr + offs.flags2_offset, furball.flags2.whole); - p->readDWord (addr_cr + offs.flags3_offset, furball.flags3.whole); - // custom profession - p->readSTLString(addr_cr + offs.custom_profession_offset, furball.custom_profession, sizeof(furball.custom_profession)); - // profession - furball.profession = p->readByte (addr_cr + offs.profession_offset); - } - if(d->Ft_advanced) +// returns index of creature actually read or -1 if no creature can be found +int32_t Creatures::GetCreatureInBox (int32_t index, df_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) +{ + if (!d->Started) + return -1; + + Process *p = d->owner; + uint16_t coords[3]; + uint32_t size = creatures->size(); + while (uint32_t(index) < size) { - // happiness - p->readDWord (addr_cr + offs.happiness_offset, furball.happiness); - - // physical attributes - p->read(addr_cr + offs.physical_offset, - sizeof(t_attrib) * NUM_CREATURE_PHYSICAL_ATTRIBUTES, - (uint8_t *)&furball.strength); - - // mood stuff - furball.mood = (int16_t) p->readWord (addr_cr + offs.mood_offset); - furball.mood_skill = p->readWord (addr_cr + offs.mood_skill_offset); - d->trans->readName(furball.artifact_name, addr_cr + offs.artifact_name_offset); - - // labors - p->read (addr_cr + offs.labors_offset, NUM_CREATURE_LABORS, furball.labors); - - furball.birth_year = p->readDWord (addr_cr + offs.birth_year_offset ); - furball.birth_time = p->readDWord (addr_cr + offs.birth_time_offset ); - - furball.pregnancy_timer = p->readDWord (addr_cr + offs.pregnancy_offset ); - // appearance - DfVector app(addr_cr + offs.appearance_vector_offset); - furball.nbcolors = app.size(); - if(furball.nbcolors>MAX_COLORS) - furball.nbcolors = MAX_COLORS; - for(uint32_t i = 0; i < furball.nbcolors; i++) + // read pointer from vector at position + df_creature * temp = creatures->at(index); + if (temp->x >= x1 && temp->x < x2) { - furball.color[i] = app[i]; + if (temp->y >= y1 && temp->y < y2) + { + if (temp->z >= z1 && temp->z < z2) + { + *furball = temp; + return index; + } + } } + index++; + } + *furball = nullptr; + return -1; +} - //likes - /* - DfVector likes(d->p, temp + offs.creature_likes_offset); - furball.numLikes = likes.getSize(); - for(uint32_t i = 0;iread(temp2,sizeof(t_like),(uint8_t *) &furball.likes[i]); - }*/ +void Creatures::CopyCreature(df_creature * source, t_creature & furball) +{ + if(!d->Started) return; + // read pointer from vector at position + furball.origin = source; + + //read creature from memory + // name + d->trans->readName(furball.name,&source->name); + + // basic stuff + furball.id = source->id; + furball.x = source->x; + furball.y = source->y; + furball.z = source->z; + furball.race = source->race; + furball.civ = source->civ; + furball.sex = source->sex; + furball.caste = source->caste; + furball.flags1.whole = source->flags1.whole; + furball.flags2.whole = source->flags2.whole; + furball.flags3.whole = source->flags3.whole; + // custom profession + furball.custom_profession = source->custom_profession; + // profession + furball.profession = source->profession; + // happiness + furball.happiness = source->happiness; + // physical attributes + memcpy(&furball.strength, source->physical, sizeof(source->physical)); + + // mood stuff + furball.mood = source->mood; + furball.mood_skill = source->unk_2f8; // FIXME: really? More like currently used skill anyway. + d->trans->readName(furball.artifact_name, &source->artifact_name); + + // labors + memcpy(&furball.labors, &source->labors, sizeof(furball.labors)); + + furball.birth_year = source->birth_year; + furball.birth_time = source->birth_time; + furball.pregnancy_timer = source->pregnancy_timer; + // appearance + furball.nbcolors = source->appearance.size(); + if(furball.nbcolors>MAX_COLORS) + furball.nbcolors = MAX_COLORS; + for(uint32_t i = 0; i < furball.nbcolors; i++) + { + furball.color[i] = source->appearance[i]; } + + //likes. FIXME: where do they fit in now? The soul? + /* + DfVector likes(d->p, temp + offs.creature_likes_offset); + furball.numLikes = likes.getSize(); + for(uint32_t i = 0;iread(temp2,sizeof(t_like),(uint8_t *) &furball.likes[i]); + } + */ + /* if(d->Ft_soul) { - /* - // enum soul pointer vector - DfVector souls(p,temp + offs.creature_soul_vector_offset); - */ uint32_t soul = p->readDWord(addr_cr + offs.default_soul_offset); furball.has_default_soul = false; @@ -378,76 +322,39 @@ bool Creatures::ReadCreature (const int32_t index, t_creature & furball) (uint8_t *) &furball.defaultSoul.traits); } } - if(d->Ft_jobs) + */ + /* + furball.current_job.occupationPtr = p->readDWord (addr_cr + offs.current_job_offset); + if(furball.current_job.occupationPtr) { - furball.current_job.occupationPtr = p->readDWord (addr_cr + offs.current_job_offset); - if(furball.current_job.occupationPtr) - { - furball.current_job.active = true; - furball.current_job.jobType = p->readByte (furball.current_job.occupationPtr + offs.job_type_offset ); - furball.current_job.jobId = p->readWord (furball.current_job.occupationPtr + offs.job_id_offset); - } - else - { - furball.current_job.active = false; - } + furball.current_job.active = true; + furball.current_job.jobType = p->readByte (furball.current_job.occupationPtr + offs.job_type_offset ); + furball.current_job.jobId = p->readWord (furball.current_job.occupationPtr + offs.job_id_offset); } else { furball.current_job.active = false; } - return true; -} - -// returns index of creature actually read or -1 if no creature can be found -int32_t Creatures::ReadCreatureInBox (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) -{ - if (!d->Started) - return -1; - - Process *p = d->owner; - uint16_t coords[3]; - uint32_t size = d->p_cre->size(); - while (uint32_t(index) < size) + */ + // no jobs for now... { - // read pointer from vector at position - uint32_t temp = d->p_cre->at(index); - p->read (temp + d->creatures.pos_offset, 3 * sizeof (uint16_t), (uint8_t *) &coords); - if (coords[0] >= x1 && coords[0] < x2) - { - if (coords[1] >= y1 && coords[1] < y2) - { - if (coords[2] >= z1 && coords[2] < z2) - { - ReadCreature (index, furball); - return index; - } - } - } - index++; + furball.current_job.active = false; } - return -1; } - int32_t Creatures::FindIndexById(int32_t creature_id) { - if (!d->Started || !d->Ft_basic) + if (!d->Started) return -1; if (!d->IdMapReady) { d->IdMap.clear(); - Process * p = d->owner; - Private::t_offsets &offs = d->creatures; - - uint32_t size = d->p_cre->size(); + uint32_t size = creatures->size(); for (uint32_t index = 0; index < size; index++) { - uint32_t temp = d->p_cre->at(index); - int32_t id = p->readDWord (temp + offs.id_offset); + df_creature * temp = creatures->at(index); + int32_t id = temp->id; d->IdMap[id] = index; } } @@ -459,7 +366,7 @@ int32_t Creatures::FindIndexById(int32_t creature_id) else return it->second; } - +/* bool Creatures::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS]) { if(!d->Started || !d->Ft_advanced) return false; @@ -665,7 +572,7 @@ bool Creatures::WritePregnancy(const uint32_t index, const uint32_t pregTimer) p->writeDWord(temp + d->creatures.pregnancy_offset, pregTimer); return true; } - +*/ uint32_t Creatures::GetDwarfRaceIndex() { if(!d->Inited) return 0; @@ -688,7 +595,7 @@ bool Creatures::getCurrentCursorCreature(uint32_t & creature_index) return true; } */ - +/* bool Creatures::ReadJob(const t_creature * furball, vector & mat) { unsigned int i; @@ -709,67 +616,56 @@ bool Creatures::ReadJob(const t_creature * furball, vector & mat) } return true; } - -bool Creatures::ReadInventoryIdx(const uint32_t index, std::vector & item) +*/ +bool Creatures::ReadInventoryByIdx(const uint32_t index, std::vector & item) { - if(!d->Started || !d->Ft_inventory) return false; - uint32_t temp = d->p_cre->at (index); - return this->ReadInventoryPtr(temp, item); + if(!d->Started) return false; + if(index >= creatures->size()) return false; + df_creature * temp = creatures->at(index); + return this->ReadInventoryByPtr(temp, item); } -bool Creatures::ReadInventoryPtr(const uint32_t temp, std::vector & item) +bool Creatures::ReadInventoryByPtr(const df_creature * temp, std::vector & items) { - unsigned int i; - if(!d->Started || !d->Ft_inventory) return false; - Process * p = d->owner; - - DfVector citem(temp + d->creatures.inventory_offset); - if(citem.size() == 0) - return false; - item.resize(citem.size()); - for(i=0;ireadDWord(citem[i]); + if(!d->Started) return false; + items = temp->inventory; return true; } -bool Creatures::ReadOwnedItemsIdx(const uint32_t index, std::vector & item) +bool Creatures::ReadOwnedItemsByIdx(const uint32_t index, std::vector & item) { - if(!d->Started || !d->Ft_owned_items) return false; - uint32_t temp = d->p_cre->at (index); - return this->ReadOwnedItemsPtr(temp, item); + if(!d->Started ) return false; + if(index >= creatures->size()) return false; + df_creature * temp = creatures->at(index); + return this->ReadOwnedItemsByPtr(temp, item); } -bool Creatures::ReadOwnedItemsPtr(const uint32_t temp, std::vector & item) +bool Creatures::ReadOwnedItemsByPtr(const df_creature * temp, std::vector & items) { unsigned int i; - if(!d->Started || !d->Ft_owned_items) return false; - Process * p = d->owner; - - DfVector citem(temp + d->creatures.owned_items_offset); - if(citem.size() == 0) - return false; - item.resize(citem.size()); - for(i=0;iStarted) return false; + items = temp->owned_items; return true; } -bool Creatures::RemoveOwnedItemIdx(const uint32_t index, int32_t id) +bool Creatures::RemoveOwnedItemByIdx(const uint32_t index, int32_t id) { - if(!d->Started || !d->Ft_owned_items) + if(!d->Started) { - cerr << "!d->Started || !d->Ft_owned_items FAIL" << endl; + cerr << "!d->Started FAIL" << endl; return false; } - uint32_t temp = d->p_cre->at (index); - return this->RemoveOwnedItemPtr(temp, id); + df_creature * temp = creatures->at (index); + return this->RemoveOwnedItemByPtr(temp, id); } -bool Creatures::RemoveOwnedItemPtr(const uint32_t temp, int32_t id) +bool Creatures::RemoveOwnedItemByPtr(df_creature * temp, int32_t id) { - if(!d->Started || !d->Ft_owned_items) return false; + if(!d->Started) return false; Process * p = d->owner; - + vector & vec = temp->owned_items; + vec.erase(std::remove(vec.begin(), vec.end(), id), vec.end()); +/* DfVector citem(temp + d->creatures.owned_items_offset); for (unsigned i = 0; i < citem.size(); i++) { @@ -778,15 +674,12 @@ bool Creatures::RemoveOwnedItemPtr(const uint32_t temp, int32_t id) if (!citem.remove(i--)) return false; } - +*/ return true; } -void Creatures::CopyNameTo(t_creature &creature, uint32_t address) +void Creatures::CopyNameTo(df_creature * creature, df_name * target) { - Private::t_offsets &offs = d->creatures; - - if(d->Ft_basic) - d->trans->copyName(creature.origin + offs.name_offset, address); + d->trans->copyName(&creature->name, target); } diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 1159acefb..af746b248 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -655,7 +655,7 @@ bool Items::removeItemOwner(dfh_item &item, Creatures *creatures) int32_t & oid = p_refs[i]->value; int32_t ix = creatures->FindIndexById(oid); - if (ix < 0 || !creatures->RemoveOwnedItemIdx(ix, item.base->id)) + if (ix < 0 || !creatures->RemoveOwnedItemByIdx(ix, item.base->id)) { cerr << "RemoveOwnedItemIdx: CREATURE " << ix << " ID " << item.base->id << " FAILED!" << endl; return false; diff --git a/library/modules/Translation.cpp b/library/modules/Translation.cpp index 32223a684..57fcd8757 100644 --- a/library/modules/Translation.cpp +++ b/library/modules/Translation.cpp @@ -168,7 +168,7 @@ bool Translation::InitReadNames() return true; } -bool Translation::readName(t_name & name, uint32_t address) +bool Translation::readName(t_name & name, df_name * source) { Core & c = Core::getInstance(); Process * p = c.p; @@ -180,36 +180,35 @@ bool Translation::readName(t_name & name, uint32_t address) { if(!InitReadNames()) return false; } - p->readSTLString(address + d->name_firstname_offset , name.first_name, 128); - p->readSTLString(address + d->name_nickname_offset , name.nickname, 128); - p->read(address + d->name_words_offset, 7*4, (uint8_t *)name.words); - p->read(address + d->name_parts_offset, 7*2, (uint8_t *)name.parts_of_speech); - name.language = p->readDWord(address + d->name_language_offset); - name.has_name = p->readByte(address + d->name_set_offset); + strncpy(name.first_name,source->first_name.c_str(),127); + strncpy(name.nickname,source->nick_name.c_str(),127); + memcpy(&name.parts_of_speech, &source->parts_of_speech, sizeof (source->parts_of_speech)); + memcpy(&name.words, &source->words, sizeof (source->words)); + name.language = source->language; + name.has_name = source->has_name; return true; } -bool Translation::copyName(uint32_t address, uint32_t target) +bool Translation::copyName(df_name * source, df_name * target) { uint8_t buf[28]; - if (address == target) + if (source == target) return true; Core & c = Core::getInstance(); Process * p = c.p; - p->copySTLString(address + d->name_firstname_offset, target + d->name_firstname_offset); - p->copySTLString(address + d->name_nickname_offset, target + d->name_nickname_offset); - p->read(address + d->name_words_offset, 7*4, buf); - p->write(target + d->name_words_offset, 7*4, buf); - p->read(address + d->name_parts_offset, 7*2, buf); - p->write(target + d->name_parts_offset, 7*2, buf); - p->writeDWord(target + d->name_language_offset, p->readDWord(address + d->name_language_offset)); - p->writeByte(target + d->name_set_offset, p->readByte(address + d->name_set_offset)); + target->first_name = source->first_name; + target->nick_name = source->nick_name; + target->has_name = source->has_name; + target->language = source->language; + memcpy(&target->parts_of_speech, &source->parts_of_speech, sizeof (source->parts_of_speech)); + memcpy(&target->words, &source->words, sizeof (source->words)); + target->unknown = source->unknown; return true; } -string Translation::TranslateName(const t_name &name, bool inEnglish) +string Translation::TranslateName(const df_name * name, bool inEnglish) { string out; assert (d->Started); @@ -218,25 +217,25 @@ string Translation::TranslateName(const t_name &name, bool inEnglish) if(!inEnglish) { - if(name.words[0] >=0 || name.words[1] >=0) + if(name->words[0] >=0 || name->words[1] >=0) { - if(name.words[0]>=0) out.append(d->dicts.foreign_languages[name.language][name.words[0]]); - if(name.words[1]>=0) out.append(d->dicts.foreign_languages[name.language][name.words[1]]); + if(name->words[0]>=0) out.append(d->dicts.foreign_languages[name->language][name->words[0]]); + if(name->words[1]>=0) out.append(d->dicts.foreign_languages[name->language][name->words[1]]); out[0] = toupper(out[0]); } - if(name.words[5] >=0) + if(name->words[5] >=0) { string word; for(int i=2;i<=5;i++) - if(name.words[i]>=0) word.append(d->dicts.foreign_languages[name.language][name.words[i]]); + if(name->words[i]>=0) word.append(d->dicts.foreign_languages[name->language][name->words[i]]); word[0] = toupper(word[0]); if(out.length() > 0) out.append(" "); out.append(word); } - if(name.words[6] >=0) + if(name->words[6] >=0) { string word; - word.append(d->dicts.foreign_languages[name.language][name.words[6]]); + word.append(d->dicts.foreign_languages[name->language][name->words[6]]); word[0] = toupper(word[0]); if(out.length() > 0) out.append(" "); out.append(word); @@ -244,13 +243,13 @@ string Translation::TranslateName(const t_name &name, bool inEnglish) } else { - if(name.words[0] >=0 || name.words[1] >=0) + if(name->words[0] >=0 || name->words[1] >=0) { - if(name.words[0]>=0) out.append(d->dicts.translations[name.parts_of_speech[0]+1][name.words[0]]); - if(name.words[1]>=0) out.append(d->dicts.translations[name.parts_of_speech[1]+1][name.words[1]]); + if(name->words[0]>=0) out.append(d->dicts.translations[name->parts_of_speech[0]+1][name->words[0]]); + if(name->words[1]>=0) out.append(d->dicts.translations[name->parts_of_speech[1]+1][name->words[1]]); out[0] = toupper(out[0]); } - if(name.words[5] >=0) + if(name->words[5] >=0) { if(out.length() > 0) out.append(" the"); @@ -259,22 +258,22 @@ string Translation::TranslateName(const t_name &name, bool inEnglish) string word; for(int i=2;i<=5;i++) { - if(name.words[i]>=0) + if(name->words[i]>=0) { - word = d->dicts.translations[name.parts_of_speech[i]+1][name.words[i]]; + word = d->dicts.translations[name->parts_of_speech[i]+1][name->words[i]]; word[0] = toupper(word[0]); out.append(" " + word); } } } - if(name.words[6] >=0) + if(name->words[6] >=0) { if(out.length() > 0) out.append(" of"); else out.append("Of"); string word; - word.append(d->dicts.translations[name.parts_of_speech[6]+1][name.words[6]]); + word.append(d->dicts.translations[name->parts_of_speech[6]+1][name->words[6]]); word[0] = toupper(word[0]); out.append(" " + word); } diff --git a/plugins/cleanowned.cpp b/plugins/cleanowned.cpp index eea6d3af9..390785fb0 100644 --- a/plugins/cleanowned.cpp +++ b/plugins/cleanowned.cpp @@ -178,14 +178,12 @@ DFhackCExport command_result df_cleanowned (Core * c, vector & paramete if (owner_index >= 0) { - DFHack::t_creature temp; - Creatures->ReadCreature(owner_index,temp); - temp.name.first_name[0] = toupper(temp.name.first_name[0]); - info = temp.name.first_name; - if (temp.name.nickname[0]) - info += std::string(" '") + temp.name.nickname + "'"; + DFHack::df_creature * temp = Creatures->GetCreature(owner_index); + info = temp->name.first_name; + if (!temp->name.nick_name.empty()) + info += std::string(" '") + temp->name.nick_name + "'"; info += " "; - info += Tran->TranslateName(temp.name,false); + info += Tran->TranslateName(&temp->name,false); c->con.print(", owner %s", info.c_str()); } diff --git a/plugins/devel/kittens.cpp b/plugins/devel/kittens.cpp index f333663c1..c82e55194 100644 --- a/plugins/devel/kittens.cpp +++ b/plugins/devel/kittens.cpp @@ -25,6 +25,7 @@ DFhackCExport command_result ktimer (Core * c, vector & parameters); DFhackCExport command_result bflags (Core * c, vector & parameters); DFhackCExport command_result trackmenu (Core * c, vector & parameters); DFhackCExport command_result mapitems (Core * c, vector & parameters); +DFhackCExport command_result test_creature_offsets (Core * c, vector & parameters); DFhackCExport const char * plugin_name ( void ) { @@ -39,6 +40,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector commands.push_back(PluginCommand("blockflags","Look up block flags",bflags)); commands.push_back(PluginCommand("trackmenu","Track menu ID changes (toggle).",trackmenu)); commands.push_back(PluginCommand("mapitems","Check item ids under cursor against item ids in map block.",mapitems)); + commands.push_back(PluginCommand("test_creature_offsets","Bleh.",test_creature_offsets)); return CR_OK; } @@ -287,3 +289,15 @@ DFhackCExport command_result kittens (Core * c, vector & parameters) color = Console::COLOR_BLUE; } } + +#include "dfhack/modules/Creatures.h" +#include "dfhack/VersionInfo.h" +#include + +command_result test_creature_offsets(Core* c, vector< string >& parameters) +{ + uint32_t off_vinfo = c->vinfo->getGroup("Creatures")->getGroup("creature")->/*getGroup("advanced")->*/getOffset("custom_profession"); + uint32_t off_struct = offsetof(df_creature,custom_profession); + c->con.print("Struct 0x%x, vinfo 0x%x\n", off_struct, off_vinfo); + return CR_OK; +}; \ No newline at end of file diff --git a/plugins/stonesense b/plugins/stonesense index 462f6f976..c140ed8d6 160000 --- a/plugins/stonesense +++ b/plugins/stonesense @@ -1 +1 @@ -Subproject commit 462f6f9767c0676c06b78ba2acab48a60a3963f5 +Subproject commit c140ed8d6dbe05854ee1499540814d5f358a960a