diff --git a/Memory.xml b/Memory.xml
index bb0c78fdd..775eee771 100644
--- a/Memory.xml
+++ b/Memory.xml
@@ -29,6 +29,9 @@
+
+
+
@@ -782,6 +785,9 @@
+
+
+
@@ -1068,6 +1074,9 @@
+
+
+
@@ -1605,6 +1614,9 @@
+
+
+
@@ -2215,6 +2227,9 @@
+
+
+
diff --git a/library/ContextShared.cpp b/library/ContextShared.cpp
index 0dd099b3c..840acec64 100644
--- a/library/ContextShared.cpp
+++ b/library/ContextShared.cpp
@@ -35,6 +35,9 @@ bool DFContextShared::InitReadNames()
name_firstname_offset = OG->getOffset("first");
name_nickname_offset = OG->getOffset("nick");
name_words_offset = OG->getOffset("second_words");
+ name_parts_offset = OG->getOffset("parts_of_speech");
+ name_language_offset = OG->getOffset("language");
+ name_set_offset = OG->getOffset("has_name");
return true;
}
@@ -42,5 +45,25 @@ void DFContextShared::readName(t_name & name, uint32_t address)
{
p->readSTLString(address + name_firstname_offset , name.first_name, 128);
p->readSTLString(address + name_nickname_offset , name.nickname, 128);
- p->read(address + name_words_offset ,28, (uint8_t *) name.words);
+ p->read(address + name_words_offset, 7*4, (uint8_t *)name.words);
+ p->read(address + name_parts_offset, 7*2, (uint8_t *)name.parts_of_speech);
+ name.language = p->readDWord(address + name_language_offset);
+ name.has_name = p->readByte(address + name_set_offset);
+}
+
+void DFContextShared::copyName(uint32_t address, uint32_t target)
+{
+ uint8_t buf[28];
+
+ if (address == target)
+ return;
+
+ p->copySTLString(address + name_firstname_offset, target + name_firstname_offset);
+ p->copySTLString(address + name_nickname_offset, target + name_nickname_offset);
+ p->read(address + name_words_offset, 7*4, buf);
+ p->write(target + name_words_offset, 7*4, buf);
+ p->read(address + name_parts_offset, 7*2, buf);
+ p->write(target + name_parts_offset, 7*2, buf);
+ p->writeDWord(target + name_language_offset, p->readDWord(address + name_language_offset));
+ p->writeByte(target + name_set_offset, p->readByte(address + name_set_offset));
}
diff --git a/library/DFProcess-linux.cpp b/library/DFProcess-linux.cpp
index 6d91b162d..ca8d835f4 100644
--- a/library/DFProcess-linux.cpp
+++ b/library/DFProcess-linux.cpp
@@ -66,6 +66,7 @@ namespace {
const std::string readSTLString (uint32_t offset);
size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity);
void writeSTLString(const uint32_t address, const std::string writeString){};
+ void copySTLString(const uint32_t address, const uint32_t target);
// get class name of an object with rtti/type info
std::string readClassName(uint32_t vptr);
};
@@ -161,6 +162,29 @@ const string NormalProcess::readSTLString (uint32_t offset)
return ret;
}
+void NormalProcess::copySTLString (uint32_t offset, uint32_t target)
+{
+ _Rep_base header;
+
+ offset = Process::readDWord(offset);
+ uint32_t old_target = Process::readDWord(target);
+
+ if (offset == old_target)
+ return;
+
+ read(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header);
+
+ // destroying the leaked state
+ if (header._M_refcount == -1)
+ header._M_refcount = 1;
+ else
+ header._M_refcount++;
+
+ write(offset - sizeof(_Rep_base),sizeof(_Rep_base),(uint8_t *)&header);
+
+ writeDWord(target, offset);
+}
+
string NormalProcess::readClassName (uint32_t vptr)
{
int typeinfo = Process::readDWord(vptr - 0x4);
diff --git a/library/include/dfhack/DFProcess.h b/library/include/dfhack/DFProcess.h
index f8c12a22f..12e82ae22 100644
--- a/library/include/dfhack/DFProcess.h
+++ b/library/include/dfhack/DFProcess.h
@@ -163,6 +163,10 @@ namespace DFHack
virtual size_t readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) = 0;
/// write an STL string
virtual void writeSTLString(const uint32_t address, const std::string writeString) = 0;
+ /// share the string at source with target; may leak target
+ virtual void copySTLString(const uint32_t address, const uint32_t target) {
+ writeSTLString(target, readSTLString(address));
+ }
/// read a STL vector
virtual void readSTLVector(const uint32_t address, t_vecTriplet & triplet) = 0;
/// get class name of an object with rtti/type info
diff --git a/library/include/dfhack/modules/Creatures.h b/library/include/dfhack/modules/Creatures.h
index 6a1218dd8..3d0520c40 100644
--- a/library/include/dfhack/modules/Creatures.h
+++ b/library/include/dfhack/modules/Creatures.h
@@ -341,6 +341,8 @@ namespace DFHack
bool WritePos(const uint32_t index, const t_creature &creature);
bool WriteCiv(const uint32_t index, const int32_t civ);
+ void CopyNameTo(t_creature &creature, uint32_t address);
+
private:
struct Private;
Private *d;
diff --git a/library/modules/Creatures.cpp b/library/modules/Creatures.cpp
index 9e91a1e76..daa31ead9 100644
--- a/library/modules/Creatures.cpp
+++ b/library/modules/Creatures.cpp
@@ -686,3 +686,12 @@ bool Creatures::ReadInventoryPtr(const uint32_t temp, std::vector & it
item[i] = p->readDWord(citem[i]);
return true;
}
+
+void Creatures::CopyNameTo(t_creature &creature, uint32_t address)
+{
+ Private::t_offsets &offs = d->creatures;
+
+ if(d->Ft_basic)
+ d->d->copyName(creature.origin + offs.name_offset, address);
+}
+
diff --git a/library/private/ContextShared.h b/library/private/ContextShared.h
index 727bb8a0e..f8b24491e 100644
--- a/library/private/ContextShared.h
+++ b/library/private/ContextShared.h
@@ -56,11 +56,15 @@ namespace DFHack
// names, used by a few other modules.
void readName(t_name & name, uint32_t address);
+ void copyName(uint32_t address, uint32_t target);
// get the name offsets
bool InitReadNames();
uint32_t name_firstname_offset;
uint32_t name_nickname_offset;
uint32_t name_words_offset;
+ uint32_t name_parts_offset;
+ uint32_t name_language_offset;
+ uint32_t name_set_offset;
bool namesInited;
ProcessEnumerator* pm;