Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 [2] 3 4

Author Topic: Dwarven Heritage Project, version 1.2.1  (Read 17506 times)

Aerval

  • Bay Watcher
    • View Profile
Re: Dwarven Heritage Project, version 1.1
« Reply #15 on: July 30, 2012, 05:01:12 pm »

Wow, another step in dwarven history modding, great script.

I'd like to make a small request. Would it be possible (of cause it is possible) to make a similar script for first names, since I'd like to have the first names gender specific. (I will have a view in your script as soon as my semester ends next week)
Logged

Poonyen

  • Bay Watcher
  • Yarg!
    • View Profile
    • My YouTube page
Re: Dwarven Heritage Project, version 1.1
« Reply #16 on: August 01, 2012, 04:52:39 am »

As someone that draws up family trees like some ultranerd every time I play, I thank you ferociously.

Expect a rock pot of ale in the mail.
Logged
I like to make music especially for Dwarf Fortress and Soundsense in my spare time (https://www.youtube.com/simonswerwer, http://soundcloud.com/simonswerwer). Also check out Toadese Language Utility to read and write DF dwarven texts (http://www.bay12forums.com/smf/index.php?topic=136098). Bang the tankards!

expwnent

  • Bay Watcher
    • View Profile
Re: Dwarven Heritage Project, version 1.1
« Reply #17 on: August 01, 2012, 04:27:20 pm »

Can I have explicit instructions on how to open this?

I have DFHack open and the script in the right folder: now what?

I can't get it to run by typing the whole link you provided; nor can I navigate to it without errors by typing directory commands. 

Sorry to be so ignorant.  Thanks.

When you save the lua script, for simplicity, let's say you put it in your main DF folder as "heritage.lua". Then all you'd have to do is say "lua heritage.lua" and it should work. I'm away from my real computer so I can't check this week, but hopefully you should be able to figure it out from there.

If you put it in df/folder/heritage.lua, the command should be "lua folder/heritage.lua". Try backslashes also if you're running windows.

Wow, another step in dwarven history modding, great script.

I'd like to make a small request. Would it be possible (of cause it is possible) to make a similar script for first names, since I'd like to have the first names gender specific. (I will have a view in your script as soon as my semester ends next week)

What specifically would you want? Inheriting the first name of the parent of the same gender or something? That might lead to more duplicate names.
Logged

Toxicshadow

  • Bay Watcher
    • View Profile
    • github
Re: Dwarven Heritage Project, version 1.1
« Reply #18 on: August 01, 2012, 07:50:21 pm »

Wow, another step in dwarven history modding, great script.

I'd like to make a small request. Would it be possible (of cause it is possible) to make a similar script for first names, since I'd like to have the first names gender specific. (I will have a view in your script as soon as my semester ends next week)

What specifically would you want? Inheriting the first name of the parent of the same gender or something? That might lead to more duplicate names.
My guess is Aerval is asking for a script that divides names to be gender specific. Like how in US Society, you (generally) wouldn't name a boy Sue. (I do hope you get the reference)
This could be achieved by checking the Symbols the name uses. Like for example any name with the FLOWERY symbol would be a female-only name.
Logged
Quote
'ere the Chias get hungry...

expwnent

  • Bay Watcher
    • View Profile
Re: Dwarven Heritage Project, version 1.1
« Reply #19 on: August 01, 2012, 08:02:53 pm »

I guess that would be possible, but it would kind of be a pain to go through every word and decide which ones are male and female only. I guess I could do something like make female names start with a vowel.
Logged

Toxicshadow

  • Bay Watcher
    • View Profile
    • github
Re: Dwarven Heritage Project, version 1.1
« Reply #20 on: August 01, 2012, 08:11:47 pm »

I guess that would be possible, but it would kind of be a pain to go through every word and decide which ones are male and female only. I guess I could do something like make female names start with a vowel.
Just check the word's symbol. Have your script check what symbol each word in the name is. Make some symbols male only, some female, and some both. Check language_SYM.txt for the symbols, and wiki might have them somewhere.
Logged
Quote
'ere the Chias get hungry...

Aerval

  • Bay Watcher
    • View Profile
Re: Dwarven Heritage Project, version 1.1
« Reply #21 on: August 02, 2012, 11:31:33 am »

Wow, another step in dwarven history modding, great script.

I'd like to make a small request. Would it be possible (of cause it is possible) to make a similar script for first names, since I'd like to have the first names gender specific. (I will have a view in your script as soon as my semester ends next week)

What specifically would you want? Inheriting the first name of the parent of the same gender or something? That might lead to more duplicate names.
My guess is Aerval is asking for a script that divides names to be gender specific. Like how in US Society, you (generally) wouldn't name a boy Sue. (I do hope you get the reference)
Yes, exactly this.

For how to accomplish these names: I thought about a special text file (that might even be stored in the raws), that contains names and can be modded easily.
Logged

hanspeter

  • Bay Watcher
    • View Profile
Re: Dwarven Heritage Project
« Reply #22 on: August 02, 2012, 12:37:20 pm »

This is SO cool. I wish that dwarves were able to share a family name though... Your naming system comes pretty close though, and looking at a dwarven family now, I can at least imagine they're related because their last names are pretty similar.
I could have done it that way. It would even have been a lot easier. I just thought this system was more interesting.

Would you mind doing such a script, too? I'd love to have huge family clans with the same last names in my fortress each with their own compound or something.

On a sidenote: Is it possible to automate a script to run every x minutes?
Logged

Hugo_The_Dwarf

  • Bay Watcher
  • Modding Mentor
    • View Profile
    • Regeneration: Forced Evolution
Re: Dwarven Heritage Project
« Reply #23 on: August 02, 2012, 12:50:25 pm »

This is SO cool. I wish that dwarves were able to share a family name though... Your naming system comes pretty close though, and looking at a dwarven family now, I can at least imagine they're related because their last names are pretty similar.
I could have done it that way. It would even have been a lot easier. I just thought this system was more interesting.

Would you mind doing such a script, too? I'd love to have huge family clans with the same last names in my fortress each with their own compound or something.

On a sidenote: Is it possible to automate a script to run every x minutes?
With DfHack you can set it to run with a hotkey, And I don't mean the use of placing the command name in the "zoom" location <SHIFT+H>

make a simple file called "dfhack.init" (yes make sure the extenstion is .init)
then add this line:
keybinding add Shift-P "lua hack\scripts\heritage.lua"

If that doesn't work, typing
lua hack\scripts\heritage.lua

in the DF-Hack console will still do it.
Logged

expwnent

  • Bay Watcher
    • View Profile
Re: Dwarven Heritage Project, version 1.1
« Reply #24 on: August 02, 2012, 02:18:20 pm »

Making it run every so often MIGHT be possible. I'll look into it.

The simple name inheritance would be doable, but I'd have to look at it and test it a bit. I'll attempt it when I get home. I just personally think that dwarven family names and politics should mirror dwarven engineering: unnecessarily complicated, yet strangely logical.

Gendered names I'll look into also, but I like having it all in one file. Makes it that much easier to install.
Logged

hanspeter

  • Bay Watcher
    • View Profile
Re: Dwarven Heritage Project, version 1.1
« Reply #25 on: August 09, 2012, 08:57:43 am »

Any news? :)
Logged

expwnent

  • Bay Watcher
    • View Profile
Re: Dwarven Heritage Project, version 1.1
« Reply #26 on: August 10, 2012, 09:30:08 pm »

I'll get to it when I can. I still have to figure out how to take arguments so that you don't have to have two or more different versions of the script.
Logged

expwnent

  • Bay Watcher
    • View Profile
Re: Dwarven Heritage Project, version 1.1
« Reply #27 on: August 13, 2012, 08:18:01 pm »

I added several options for name inheritance and for name statistics. The download link is the same.

Use "heritage -h" for information about what the options are and how to use them.

edit: also added the ability to make the script automatically repeat every month or every year. See heritage -h for details.
« Last Edit: August 13, 2012, 09:01:37 pm by expwnent »
Logged

Aerval

  • Bay Watcher
    • View Profile
Re: Dwarven Heritage Project, version 1.2
« Reply #28 on: August 20, 2012, 09:03:31 pm »

Thanks for the new version. Especially the mother/farther naming systems are great.

Some Bugs I found:
-you are not consistent with printFortNames or printLocalNames (at least that might be the reason why I get the Errormessage from Line 910 without any arguments)
-the Helpme says "-sortOutputBy" (which is correct) while the Argument-Error handler (which is great) says "-sortBy"
and you may advert to that arguments are cASe sensitive

This is my slightly modified version (hope you don't mind):
-corrected issues above
-some small tweaks (like renaming parent1 "mother")
-might enhance over the next days (and might try out github)
Code: [Select]
function isHistorical(unit)
local type = tostring(unit._type);
--print(type);
if ( string.find(type, "historical_figure") ~= nil ) then
do return true end;
end

if ( string.find(type, "unit") ~= nil ) then
do return false end;
end

dfhack.error("unit is not of a valid type: " .. unit);
do return nil end;
end

function getRelation(figure, typeString)
for index,link in pairs(figure.histfig_links) do
local type = tostring(link._type);
if ( string.find(type, typeString) ~= nil ) then
do return link.anon_1 end;
end
end
do return nil end;
end

function merge(list, lessThan, lo, mid, hi)
local temp = {};
local index_L = lo;
local index_R = mid;
local index_temp = 0;
while(true) do
if ( index_L >= mid ) then
if ( index_R < hi ) then
temp[index_temp] = list[index_R];
index_temp = index_temp+1;
index_R = index_R+1;
else
break;
end
else
if ( index_R < hi ) then
if ( lessThan(index_R, index_L) ) then
temp[index_temp] = list[index_R];
index_temp = index_temp+1;
index_R = index_R+1;
else
temp[index_temp] = list[index_L];
index_temp = index_temp+1;
index_L = index_L + 1;
end
else
temp[index_temp] = list[index_L];
index_temp = index_temp+1;
index_L = index_L + 1;
end
end
end

for i=lo,hi-1 do
list[i] = temp[i-lo];
end
end

local doOnce = 0;

function sort(list, lessThan, lo, hi)
if ( lo == hi or lo > hi or lo+1 == hi ) then
do return end;
end

--print("lo="..lo..", hi="..hi);

--[[--see if some of it is already sorted
local firstUnsorted = 0;
local previous = list[lo];
local index = lo+1;
while(true) do
index = index+1;
if ( index >= hi ) then
break;
end

if ( lessThan(index, index-1) ) then
firstUnsorted = index;
if ( doOnce == 0 ) then
print(firstUnsorted);
doOnce = 1;
end
break;
end
end

if ( firstUnsorted - lo > 10 and firstUnsorted - lo >= (hi-lo)/4 ) then
local mid = firstUnsorted-1;
--sort(list, lessThan, lo, mid);
sort(list, lessThan, mid, hi);
merge(list, lessThan, lo, mid, hi);
do return end;
end]]

local mid = math.floor((lo+hi)/2);
sort(list, lessThan, lo, mid);
sort(list, lessThan, mid, hi);

merge(list, lessThan, lo, mid, hi);
end

function getMax(list)
local result = 0;
for key,value in pairs(list) do
if ( key >= result ) then
result = key+1;
end
end
return result;
end

function computeHeritage(nameScheme, outputType, sortBy, doReverseOutputOrder)
local dwarfRace = df.global.ui.race_id;
local allUnits = {};
local age = {};
local count=0;
local idToHistoricalUnit = {};
local idToLocalUnit = {};
local localToHistorical = {};
local historicalToLocal = {};
local ticksPerYear = 403200; --403200 ticks in a year

--compute allUnits, age, count, idToHistoricalUnit
for index,unit in pairs(df.global.world.history.figures) do
if ( unit.race == dwarfRace ) then
allUnits[count] = unit;
age[unit] = unit.born_year*403200 + unit.born_seconds;
count = count+1;
idToHistoricalUnit[unit.id] = unit;
end
end

--compute allUnits, age, count, idToLocalUnit, localToHistorical, historicalToLocal
for index,unit in pairs(df.global.world.units.all) do
if ( unit.race == dwarfRace ) then
allUnits[count] = unit;
age[unit] = unit.relations.birth_year*ticksPerYear + unit.relations.birth_time;
count = count+1;
idToLocalUnit[unit.id] = unit;

if ( unit.hist_figure_id ~= -1 ) then
local historical_me = idToHistoricalUnit[unit.hist_figure_id];
localToHistorical[unit] = historical_me;
historicalToLocal[historical_me] = unit;
end
end
end

print("Sorting...");
--sort units
function lessThan(index1, index2)
if ( index1 == index2 ) then
do return false end;
end
local unit1 = allUnits[index1];
local unit2 = allUnits[index2];

--print(tostring(index1) .. ", " .. tostring(index2));
--print(tostring(unit1) .. ", " .. tostring(unit2));

if ( isHistorical(unit1) == isHistorical(unit2) ) then
if ( age[unit2] < age[unit1] ) then
do return false end;
end
else
if ( isHistorical(unit2) ) then
do return false end;
end
end

return true;
end
sort(allUnits, lessThan, 0, count);

print("Done sorting!");

function getParent(unit, whichParent)
if ( isHistorical(unit) ) then
local id = getRelation(unit, whichParent);
return idToHistoricalUnit[id];
else
--try the parent of your historical version if you have one
if ( unit.hist_figure_id ~= -1 ) then
local hist_me = idToHistoricalUnit[unit.hist_figure_id];
local hist_parent = getParent(hist_me, whichParent);
if ( hist_parent ~= nil ) then
do return hist_parent end;
end
end
local id;
if ( whichParent == "mother" ) then
id = unit.relations.mother_id;
elseif ( whichParent == "father" ) then
id = unit.relations.father_id;
else
dfhack.error("Invalid relation: " .. whichParent);
end
if ( id == -1 ) then
do return nil end;
end

local ancestor = idToLocalUnit[id];
if ( ancestor == nil ) then
do return nil end;
end

if ( ancestor.hist_figure_id == -1 or idToHistoricalUnit[ancestor.hist_figure_id] == nil )

then
do return ancestor end;
end

do return idToHistoricalUnit[ancestor.hist_figure_id] end;
end
end

local childIndexTable = {};
local allNames = {};
local nameAge = {};

function computeChildIndexTable()
--precondition: units are sorted by birth order
local childTable = {};
local childCount = {};
local result = {};
function helper(unit)
local mother = getParent(unit, "mother");
if ( mother == nil ) then
do return end;
end
local children = childTable[mother];
if ( children == nil ) then
children = {};
childCount[mother] = 0;
end

--if you're historical, you might already be in the list!
if ( not isHistorical(unit) ) then
local alternate = idToHistoricalUnit[unit.hist_figure_id];
if ( alternate == nil ) then
--no alternate, fall through to base case
else
--we do have an alternate: copy his childIndex
result[unit] = result[alternate];
do return end;
end
end

local count = childCount[mother];
children[count] = unit;
childCount[mother] = count+1;
childTable[mother] = children;
result[unit] = count;
end
for index,unit in pairs(allUnits) do
helper(unit);
end
return result;
end

childIndexTable = computeChildIndexTable();

local aliveNames = {};
local nameHistogram = {};
local aliveNameHistogram = {};
local localNameHistogram = {};
local localAliveNameHistogram = {};
local nameFounder = {};
local nameLeader = {};
local localNameLeader = {};
local localNameFounder = {};
local outOfNames = false;
local mostRecentName = -1;
function handleNewName(dwarf)
function newNameHelper(name)
if ( name == -1 ) then
do return end;
end

local old = nameAge[name];
if ( old == nil ) then
nameAge[name] = age[dwarf];
nameFounder[name] = dwarf;
--[[print(string.format("Family founder of %-15s: %s",
df.global.world.raws.language.translations[0].words[name].value,
dfhack.TranslateName(dwarf.name)));]]
mostRecentName = name;
else
if ( age[dwarf] < old ) then
nameAge[name] = age[dwarf];
end
end

allNames[name] = 1;

old = nameHistogram[name];
if ( old == nil ) then
nameHistogram[name] = 1;
else
nameHistogram[name] = old+1;
end

local alive=false;
local isLocal;
if ( isHistorical(dwarf) ) then
if ( dwarf.died_year == -1 ) then
alive = true;
end
if ( historicalToLocal[dwarf] ~= nil ) then
isLocal = true;
else
isLocal = false;
end
else
isLocal = true;
if ( not dwarf.flags1.dead ) then
alive = true;
end
end

if ( isLocal ) then
old = localNameHistogram[name];
if ( old == nil ) then
localNameHistogram[name] = 1;
localNameFounder[name] = dwarf;
else
localNameHistogram[name] = old+1;
end
end

if ( alive ) then
old = aliveNameHistogram[name];
if ( old == nil ) then
nameLeader[name] = dwarf;
aliveNameHistogram[name] = 1;
else
aliveNameHistogram[name] = old+1;
end
end

if ( alive and isLocal ) then
aliveNames[name] = 1;
old = localAliveNameHistogram[name];
if ( old == nil ) then
localAliveNameHistogram[name] = 1;
localNameLeader[name] = dwarf;
else
localAliveNameHistogram[name] = old+1;
end
end
end
for i=0,1 do
local name = dwarf.name.words[i];
newNameHelper(name);
end
end

function resolveConflict(dwarf)
local max = getMax(df.global.world.raws.language.words);
local first = math.random(max)-1;
local guess = first;
while (true) do
if ( nameAge[guess] == nil ) then
dwarf.name.words[1] = guess;
break;
end
guess = (guess+1)%max;
if ( guess >= max ) then
dfhack.error("guess >= max! " .. guess .. ", " .. max);
end
if ( outOfNames or guess == first ) then
outOfNames = true;
dwarf.name.words[1] = first;
--TODO: duplicate full names-----------------------------------------------------
--do return end;
break;
end
end
detectAndResolveConflicts(dwarf);
end

function detectAndResolveConflicts(dwarf)
local name = dfhack.TranslateName(dwarf.name);
if ( allNames[name] ~= nil ) then
resolveConflict(dwarf);
do return end;
end

if ( dwarf.name.words[0] == dwarf.name.words[1] ) then
resolveConflict(dwarf);
do return end;
end

if ( dwarf.name.words[1] == -1 ) then
resolveConflict(dwarf);
do return end;
end

if ( dwarf.name.words[0] == -1 ) then
dwarf.name.words[0] = dwarf.name.words[1];
dwarf.name.words[1] = -1;
resolveConflict(dwarf);
local temp = dwarf.name.words[0];
dwarf.name.words[0] = dwarf.name.words[1];
dwarf.name.words[1] = temp;
end
end

function sortName(dwarf)
local name0 = dwarf.name.words[0];
local name1 = dwarf.name.words[1];

if ( name0 == -1 or name1 == -1 ) then
do return end;
end

local age0 = nameAge[name0];
local age1 = nameAge[name1];

if ( age1 ~= nil and (age0 == nil or age1 < age0) ) then
dwarf.name.words[0] = name1;
dwarf.name.words[1] = name0;
elseif ( age1 == age0 ) then
local str1 = df.global.world.raws.language.translations[0].words[name0].value;
local str2 = df.global.world.raws.language.translations[0].words[name1].value;
if ( str2 < str1 ) then
dwarf.name.words[0] = name1;
dwarf.name.words[1] = name0;
end
end
end

helper = function(dwarf)
if ( dwarf.race ~= dwarfRace ) then
do return end;
end

--sortName(dwarf);

if ( not isHistorical(dwarf) ) then
local hist_me = idToHistoricalUnit[dwarf.hist_figure_id];
if ( hist_me ~= nil ) then
dwarf.name.words[0] = hist_me.name.words[0];
dwarf.name.words[1] = hist_me.name.words[1];
do return end;
end
end

--print("id = " .. dwarf.id);

local mother = getParent(dwarf, "mother");
local father = getParent(dwarf, "father");

local oldName0 = dwarf.name.words[0];
local oldName1 = dwarf.name.words[1];
local oldNameString = dfhack.TranslateName(dwarf.name);

if ( oldName0 == -1 or oldName1 == -1 ) then
handleNewName(dwarf);
do return end; -- don't mess with weird shit
end

if ( mother == nil and father == nil ) then
--print("Generating unique last name for " .. dfhack.TranslateName(dwarf.name));
local seed;
if ( isHistorical(dwarf) ) then
seed = dwarf.id;
else
local hist_me = idToHistoricalUnit[dwarf.hist_figure_id];
if ( hist_me ~= nil ) then
seed = hist_me.id;
else
seed = dwarf.id;
end
end
math.randomseed(seed);
--print("seed = " .. seed);
local max = getMax(df.global.world.raws.language.words);
--print("max = " .. max);
local first = math.random(max)-1;
local guess = first;
while(true) do
if ( nameAge[guess] == nil ) then
dwarf.name.words[0] = guess;
break;
end
guess = (guess+1)%max;
if ( outOfNames or guess == first ) then
outOfNames = true;
dwarf.name.words[0] = first;
--dwarf.name.words[0] = mostRecentName;
--dwarf.name.words[1] = mostRecentName; -- gonna happen anyway
break;
end;
end

first = math.random(max)-1;
if ( first == dwarf.name.words[0] ) then
first = (first+1)%max;
end
guess = first;
local lastNonduplicate;
while(true) do
if ( guess ~= dwarf.name.words[0] and nameAge[guess] == nil ) then
dwarf.name.words[1] = guess;
break;
end
local fullName = dfhack.TranslateName(dwarf.name);
if ( allNames[fullName] == nil ) then
lastNonduplicate = guess;
end
guess = (guess+1)%max;
if ( outOfNames or guess == first ) then
outOfNames = true;
dwarf.name.words[1] = lastNonduplicate;
--dwarf.name.words[1] = mostRecentName;
break;
end;
end

sortName(dwarf);
local newNameString = dfhack.TranslateName(dwarf.name);
if ( oldNameString ~= newNameString ) then
print("No parents: giving new unique last names (if possible):");
print("    old name = " .. oldNameString);
print("    new name = " .. newNameString);
print();
end
--print("    " .. dfhack.TranslateName(dwarf.name));
handleNewName(dwarf);
do return end;
end

if ( mother == nil or father == nil ) then
handleNewName(dwarf);
do return end;
end

local nameTable = {};
nameTable[1] = mother.name.words[0];
nameTable[2] = mother.name.words[1];
nameTable[3] = father.name.words[0];
nameTable[4] = father.name.words[1];

for i=1,5 do
for j=2,4 do
local temp1 = nameTable[j-1];
local temp2 = nameTable[j  ];
local age1 = nameAge[temp1] or 1000000;
local age2 = nameAge[temp2] or 1000000;
if ( age2 < age1 ) then
nameTable[j-1] = temp2;
nameTable[j  ] = temp1;
elseif ( age2 == age1 ) then
--both equal: go by alphabetic
local str1 = df.global.world.raws.language.translations[0].words

[temp1].value;
local str2 = df.global.world.raws.language.translations[0].words

[temp2].value;
if ( str2 < str1 ) then
nameTable[j-1] = temp2;
nameTable[j  ] = temp1;
end
end
end
end

local newName0 = -1;
local newName1 = -1;

local childIndex = childIndexTable[dwarf];
childIndex = childIndex % 6;

--[[if ( childIndex == 0 ) then
newName0 = nameTable[1];
newName1 = nameTable[2];
elseif ( childIndex == 1 ) then
newName0 = nameTable[1];
newName1 = nameTable[3];
elseif ( childIndex == 2 ) then
newName0 = nameTable[1];
newName1 = nameTable[4];
elseif ( childIndex == 3 ) then
newName0 = nameTable[2];
newName1 = nameTable[3];
elseif ( childIndex == 4 ) then
newName0 = nameTable[2];
newName1 = nameTable[4];
elseif ( childIndex == 5 ) then
newName0 = nameTable[3];
newName1 = nameTable[4];
else
dfhack.error("Invalid child index: " .. childIndex);
end--]]

--[[newName0 = nameTable[1];
newName1 = nameTable[2];
if ( newName1 == newName0 ) then
newName1 = nameTable[3];
if ( newName1 == newName0 ) then
newName1 = nameTable[4];
end
end--]]

if ( childIndex == 0 ) then
newName0 = nameTable[1];
newName1 = nameTable[2];
elseif ( childIndex == 1 ) then
newName0 = nameTable[3];
newName1 = nameTable[4];
elseif ( childIndex == 2 ) then
newName0 = nameTable[1];
newName1 = nameTable[3];
elseif ( childIndex == 3 ) then
newName0 = nameTable[2];
newName1 = nameTable[4];
elseif ( childIndex == 4 ) then
newName0 = nameTable[1];
newName1 = nameTable[4];
elseif ( childIndex == 5 ) then
newName0 = nameTable[2];
newName1 = nameTable[3];
else
dfhack.error("Invalid child index: " .. childIndex);
end

local oldNameString = dfhack.TranslateName(dwarf.name);
dwarf.name.words[0] = newName0;
dwarf.name.words[1] = newName1;

if ( nameScheme == 'motherName' ) then
if ( mother == nil ) then
mother = father;
end
if ( mother == nil ) then
do return end;
end
dwarf.name.words[0] = mother.name.words[0];
dwarf.name.words[1] = mother.name.words[1];
--do return end;
elseif ( nameScheme == 'fatherName' ) then
if ( father == nil ) then
father = mother;
end
if ( father == nil ) then
do return end;
end
dwarf.name.words[0] = father.name.words[0];
dwarf.name.words[1] = father.name.words[1];
elseif ( nameScheme == 'eldestParent' ) then
local olderParent;
if ( mother == nil and father ~= nil ) then
olderParent = father;
elseif ( father == nil and mother ~= nil ) then
olderParent = mother;
else
if ( mother == nil or father == nil ) then
dfhack.error('WTF?');
end
if ( age[mother] == age[father] ) then
print('What a coincidence! Parents with the exact same age.');
olderParent = mother;
elseif ( age[mother] < age[father] ) then
olderParent = mother;
else
olderParent = father;
end
end
dwarf.name.words[0] = olderParent.name.words[0];
dwarf.name.words[1] = olderParent.name.words[1];
end

--resolve conflicts
--choose the same new name in the event of a conflict
local seed;
if ( isHistorical(dwarf) ) then
seed = dwarf.id;
else
local hist_me = idToHistoricalUnit[dwarf.hist_figure_id];
if ( hist_me ~= nil ) then
seed = hist_me.id;
else
seed = dwarf.id;
end
end
--print("seed = " .. seed);
math.randomseed(seed);

if ( nameScheme == 'default' ) then
detectAndResolveConflicts(dwarf);
sortName(dwarf);
--only handleNewName when their name is finalized!
handleNewName(dwarf);
end

local newNameString = dfhack.TranslateName(dwarf.name);

if ( oldNameString ~= newNameString ) then
print("old name = " .. oldNameString);
print("new name = " .. newNameString);
print();
end
end

for index,dwarf in pairs(allUnits) do
helper(dwarf);
end

local influence = {};
function getBoss(unit)
local name0 = unit.name.words[0];
local name1 = unit.name.words[1];
local leader0 = nameLeader[name0];
local leader1 = nameLeader[name1];

if ( leader0 == unit ) then
return leader1;
end
if ( leader1 == unit ) then
return leader0;
end

dfhack.error("WTF?");
end

function computeInfluence(name)
local leader = nameLeader[name];
if ( leader == nil ) then
--influence[] = 0;
return 0;
end

local otherName = leader.name.words[0];
if ( otherName == name ) then
otherName = leader.name.words[1];
end

local inf = influence[leader] or 0;
inf = inf + (aliveNameHistogram[name] or 0);
influence[leader] = inf;

local boss = getBoss(leader);

if ( boss == leader ) then
local count2 = aliveNameHistogram[otherName] or 0;
influence[leader] = inf + count2;
return influence[leader];
end

--he's our boss: add our influence to him, all the way up
while(true) do
local count1 = influence[boss] or 0;
influence[boss] = count1 + aliveNameHistogram[name];
local lastBoss = boss;
boss = getBoss(boss);
if ( boss == lastBoss ) then
break;
end
end

return influence[leader];
end

for name,_ in pairs(allNames) do
computeInfluence(name);
end

--print out the age of each name
function printNameInformation()
local count = 0;
local newList = {};
for name,_ in pairs(allNames) do
newList[count] = name;
count = count+1;
end
function ageLessThan(a,b)
if ( a == b ) then
do return false end;
end

local name1 = newList[a];
local name2 = newList[b];
local age1 = nil;
local age2 = nil;

if ( sortBy == 'alphabetic' ) then
--TODO:

------------------------------------------------------------------------------------this line for correct

translations
local str1 = df.global.world.raws.language.translations[0].words[name1].value;
local str2 = df.global.world.raws.language.translations[0].words[name2].value;
if ( doReverseOutputOrder ) then
do return str2 < str1 end;
else
do return str1 < str2 end;
end
elseif ( sortBy == 'aliveUses' ) then
age1 = aliveNameHistogram[name1];
age2 = aliveNameHistogram[name2];
elseif ( sortBy == 'uses' ) then
age1 = nameHistogram[name1];
age2 = nameHistogram[name2];
elseif ( sortBy == 'fortUses' ) then
age1 = localNameHistogram[name1];
age2 = localNameHistogram[name2];
elseif ( sortBy == 'fortAliveUses' ) then
age1 = localAliveNameHistogram[name1];
age2 = localAliveNameHistogram[name2];
elseif ( sortBy == 'nameAge' ) then
age1 = nameAge[name1];
age2 = nameAge[name2];
elseif ( sortBy == 'leaderAge' ) then
if ( nameLeader[name1] == nil ) then
age1 = nil;
else
age1 = age[nameLeader[name1]];
end
if ( nameLeader[name2] == nil ) then
age2 = nil;
else
age2 = age[nameLeader[name2]];
end
elseif ( sortBy == 'fortLeaderAge' ) then
if ( localNameLeader[name1] == nil ) then
age1 = nil;
else
age1 = age[localNameLeader[name1]];
end
if ( localNameLeader[name2] == nil ) then
age2 = nil;
else
age2 = age[localNameLeader[name2]];
end
elseif ( sortBy == 'fortNameAge' ) then
if ( localNameFounder[name1] == nil ) then
age1 = nil;
else
age1 = age[localNameFounder[name1]];
end
if ( localNameFounder[name2] == nil ) then
age2 = nil;
else
age2 = age[localNameFounder[name2]];
end
elseif ( sortBy == 'influence') then
if ( nameLeader[name1] == nil ) then
age1 = nil;
else
age1 = influence[nameLeader[name1]];
end
if ( nameLeader[name2] == nil ) then
age2 = nil;
else
age2 = influence[nameLeader[name2]];
end
else
dfhack.error('Invalid sortBy: "' .. sortBy .. '"');
end

if ( age1 == nil and age2 == nil ) then
do return false end;
end

if ( doReverseOutputOrder ) then
if ( age2 == nil ) then
do return true end;
end
if ( age1 == nil ) then
do return false end;
end
else
--not applicables first
if ( age2 == nil ) then
do return false end;
end
if ( age1 == nil ) then
do return true end;
end
end

if ( doReverseOutputOrder ) then
local temp = age1;
age1 = age2;
age2 = temp;
end

if (age1 < age2) then
do return true end;
elseif (age1 == age2) then
--TODO: other orderings?
--mergesort is stable, so this will be consistent with the current ordering
do return false end;
else
--age1 > age2
do return false end;
end
dfhack.error("This should not be reachable.");
end
sort(newList, ageLessThan, 0, count);

if ( outputType == 'printAllNames' ) then
print("Printing all names:");
elseif (outputType == 'printFortNames' ) then
print("Printing all names represented in this fort at some point in the past or present:");
elseif (outputType == 'printAllAliveNames') then
print("Printing all names with at least one living dwarf:");
elseif (outputType == 'printFortAliveNames') then
print("Printing all names with at least one living dwarf in the current fort:");
else
dfhack.error('Invalid output type: "' .. outputType .. '"');
end
local sortByStr = nil;
if ( sortBy == 'alphabetic' ) then
sortByStr = 'alphabetically';
if ( doReverseOutputOrder ) then
sortByStr = sortByStr .. ', from Z to A';
else
sortByStr = sortByStr .. ', from A to Z';
end
elseif ( sortBy == 'aliveUses' ) then
sortByStr = 'by number of living dwarves with the name';
if ( doReverseOutputOrder ) then
sortByStr = sortByStr .. ', most common names last';
else
sortByStr = sortByStr .. ', most common names first';
end
elseif ( sortBy == 'uses' ) then
sortByStr = 'by number of dwarves living or dead who have had the name';
if ( doReverseOutputOrder ) then
sortByStr = sortByStr .. ', most common names last';
else
sortByStr = sortByStr .. ', most common names first';
end
elseif ( sortBy == 'fortUses' ) then
sortByStr = 'by number of dwarves who have lived in the current fort who have the name,

living or dead';
if ( doReverseOutputOrder ) then
sortByStr = sortByStr .. ', most common names last';
else
sortByStr = sortByStr .. ', most common names first';
end
elseif ( sortBy == 'fortAliveUses' ) then
sortByStr = 'by number of living dwarves in the current fort who have the name';
if ( doReverseOutputOrder ) then
sortByStr = sortByStr .. ', most common names last';
else
sortByStr = sortByStr .. ', most common names first';
end
elseif ( sortBy == 'nameAge' ) then
sortByStr = 'by time since the first dwarf to have the name';
if ( doReverseOutputOrder ) then
sortByStr = sortByStr .. ', oldest names last';
else
sortByStr = sortByStr .. ', oldest names first';
end
elseif ( sortBy == 'leaderAge' ) then
sortByStr = 'by age of the eldest dwarf with the name';
if ( doReverseOutputOrder ) then
sortByStr = sortByStr .. ', oldest last';
else
sortByStr = sortByStr .. ', oldest first';
end
elseif ( sortBy == 'fortLeaderAge' ) then
sortByStr = 'by age of the eldest dwarf in the current fort with the name';
if ( doReverseOutputOrder ) then
sortByStr = sortByStr .. ', oldest last';
else
sortByStr = sortByStr .. ', oldest first';
end
elseif ( sortBy == 'fortNameAge' ) then
sortByStr = 'by time since the birth of the first dwarf who lived in the current fort with

the name';
if ( doReverseOutputOrder ) then
sortByStr = sortByStr .. ', oldest last';
else
sortByStr = sortByStr .. ', oldest first';
end
--[[elseif ( sortBy == '' ) then
sortByStr = '';
if ( doReverseOutputOrder ) then
sortByStr = sortByStr .. '';
else
sortByStr = sortByStr .. '';
end--]]
elseif ( sortBy == 'influence') then
sortByStr = 'by level of influence';
if ( doReverseOutputOrder ) then
sortByStr = sortByStr .. ', most influential last';
else
sortByStr = sortByStr .. ', most influential first';
end
else
dfhack.error('Invalid sortBy: "' .. sortBy .. '"');
end
if ( sortByStr == nil ) then
dfhack.error('sortByStr is nil');
end
print("Sorting " .. sortByStr);
function helper(i)
local name = newList[i];
--print(name);
if ( name == -1 ) then
return;
end

if ( outputType == 'printAllNames' ) then
--print everyone
elseif (outputType == 'printFortNames') then
--print only fort
if ( localNameFounder[name] == nil ) then
return;
end
elseif (outputType == 'printAllAliveNames') then
if ( nameLeader[name] == nil ) then
return;
end
elseif (outputType == 'printFortAliveNames') then
if ( localNameLeader[name] == nil ) then
return;
end
else
dfhack.error('WTF?');
end

local leader = nameLeader[name];
if ( leader ~= getBoss(leader) ) then
return;
end

local str = df.global.world.raws.language.translations[0].words[name].value;
local temp =
print(string.format("    family %-10s: uses = %-4s, aliveUses = %4s, localAliveUses = %4s",
str,
tostring(nameHistogram[name]),
tostring(aliveNameHistogram[name]),
tostring(localAliveNameHistogram[name])));

print(string.format("        founded in %-4.2f by %s",
nameAge[name]/ticksPerYear,
dfhack.TranslateName(nameFounder[name].name)));
if ( nameLeader[name] ~= nil ) then
if ( true ) then
print(string.format("        led by %s, born %-4.2f, who has influence level

%d",
dfhack.TranslateName(nameLeader[name].name),
age[nameLeader[name]]/ticksPerYear,
influence[nameLeader[name]]));
else
print(string.format("        led by %s, born %-4.2f",
dfhack.TranslateName(nameLeader[name].name),
age[nameLeader[name]]/ticksPerYear));
end
end
if ( localNameLeader[name] ~= nil ) then
print(string.format("        locally led by %s, born %-4.2f",
dfhack.TranslateName(localNameLeader[name].name),
age[localNameLeader[name]]/ticksPerYear));
end
print();
end
for i=0,count-1 do
helper(i);
end
end

if ( outputType ~= 'none' ) then
printNameInformation();
end
end

--computeHeritage();
--dfhack.with_suspend(computeHeritage);


local usage =
function()
print('Usage: heritage [-nameScheme {schemeNameHere}]'
..'\n    [-outputType {outputTypeHere}]'
..'\n    [-sortBy {sortTypeHere}]'
..'\n    [-reverse]'
..'\nnameScheme, outputType, sortBy, and reverse are optional and may be used in any

combination and in any order. Do not use any braces in the arguments. The default nameScheme is \'default\', the

default outputType is printFortNames, the default sortBy is fortAliveUses.'
..'For full information on what does what, call heritage -h. For even fuller

information, do this and also read the readme.'
..'\nExamples:'
..'\n    heritage -nameScheme default -outputType printFortAliveNames -sortBy

nameAge'
..'\n        Choose last names based on the default scheme, output statistics

on all names of living dwarves in the current fort, outputting the information on the oldest names first.'
..'\n    heritage -nameScheme eldestParent -outputType printAllAliveNames -sortBy

aliveUses -reverse'
..'\n        Dwarves inherit the last name of the older of their parents,

output statistics on all names of living dwarves in the world, outputting the information on the rarest names first.'
..'\n..Arguments are Case Sensitive!'
);
end

--nameScheme can be default, eldestParent, motherName, fatherName
--[[
--TODO
optional copy output to file
family tree
conflict handling
all races option
correct translation of names
multisort
full last name information
one name from each parent (statically)
dry run option
influence complications
worry about visiting nonlocal dwarves
worry about twin age
sort output by english translation
--]]

local arguments = {...};
local nameScheme = 'unknown';
local outputType = 'printFortNames';
local sortBy = 'fortAliveUses';
local reverse = false;
local prev = nil;
local cancelRepeat = false;
local repeatEvery = nil;
for i,v in pairs(arguments) do
if ( prev == nil ) then
if ( v == '-nameScheme' or v == '-outputType' or v == '-sortBy' or v == '-repeatEvery' ) then
prev = v;
elseif ( v == '-reverse' ) then
reverse = true;
elseif ( v == '-cancelRepeat' ) then
cancelRepeat = true;
elseif ( v == '-h' or v == '-help' or v == '--help' ) then
usage();
print('\n-nameScheme'
..'\n    default: get two names from parents names, which names you get depend on

your birth order.'
..'\n    eldestParent: your last name is the last name of your eldest parent.'
..'\n    fatherName: your last name is the last name of your father.'
..'\n    motherName: your last name is the last name of your mother.'
..'\n-outputType'
..'\n    none: do not print name statistics.' --TODO: actual no output
..'\n    printAllNames: print statistics about all names that any dwarf has had'
..'\n    printFortNames: print statistics about all names that any dwarf in your fort

has had'
..'\n    printAllAliveNames: print statistics about all names that at least one

living dwarf in the world has.'
..'\n    printFortAliveNames: print statistics about all names of living dwarves in

your fort.'
..'\n-sortBy'
..'\n    alphabetic: sort printed names alphabetically.'
..'\n    aliveUses: sort printed names by how many living dwarves have them.'
..'\n    uses: sort printed names by how many dwarves have had them.'
..'\n    fortUses: sort printed names by how many dwarves in your fort have had

them.'
..'\n    fortAliveUses: sort printed names by how many living dwarves in your fort

have them.'
..'\n    nameAge: sort printed names by time since the birth of the first dwarf to

possess it.'
..'\n    leaderAge: sort printed names by the age of the eldest living dwarf with the

name.'
..'\n    fortLeaderAge: sort printed names by the age of the eldest living dwarf in

the fort with the name.'
..'\n    fortNameAge: sort printed names by the time since the birth of the first

dwarf in the fort with the name.'
..'\n    influence: sort printed names by influence.'
..'\n-reverse: reverse the specified sort order.'
..'\n-repeatEvery'
..'\n    year'
..'\n    month'
..'\n-cancelRepeat: cancels any scheduled future calling of this. Implied by -

repeatEvery.'
);
do return end;
else
print('Incorrect usage: "' .. v .. '"');
usage();
do return end;
end
elseif ( prev == '-nameScheme' ) then
if ( v == 'default' or v == 'eldestParent' or v == 'motherName' or v == 'fatherName' ) then
nameScheme = v;
else
print('Incorrect usage: "' .. v .. '"');
usage();
do return end;
end
prev = nil;
elseif ( prev == '-outputType' ) then
if ( v == 'none' or v == 'printAllNames' or v == 'printFortNames' or v == 'printAllAliveNames' or v

== 'printFortAliveNames' ) then
outputType = v;
else
print('Incorrect usage: "' .. v .. '"');
usage();
do return end;
end
prev = nil;
elseif ( prev == '-sortBy' ) then
if ( v == 'alphabetic' or v == 'aliveUses' or v == 'uses' or v == 'fortUses' or v == 'fortAliveUses'

or v == 'nameAge' or v == 'leaderAge' or v == 'fortLeaderAge' or v == 'fortNameAge' or v == 'influence' ) then
sortBy = v;
else
print('Incorrect usage: "' .. v .. '"');
usage();
do return end;
end
prev = nil;
elseif ( prev == '-repeatEvery' ) then
if ( v == 'month' or v == 'year' ) then
repeatEvery = v;
cancelRepeat = true;
else
print('Incorrect usage: "' .. v .. '"');
usage();
do return end;
end
prev = nil;
else
print('Incorrect usage: "' .. v .. '"');
usage();
do return end;
end
end

if ( prev ~= nil ) then
print("Incorrect usage: you must specify a parameter.");
usage();
do return end;
end

--dfhack.with_suspend(computeHeritage, nameScheme, outputType, sortBy, reverse);

--global timer
if ( cancelRepeat ) then
if ( timer ~= nil ) then
dfhack.timeout_active(timer,nil);
end
end

local tempFunction = function(dumbHelper)
--computeHeritange(nameScheme, outputType, sortBy, reverse);
dfhack.with_suspend(computeHeritage, nameScheme, outputType, sortBy, reverse);

function dumb()
dumbHelper(dumbHelper);
end

if ( repeatEvery == 'year' ) then
timer = dfhack.timeout(1,'years',dumb);
elseif ( repeatEvery == 'month' ) then
timer = dfhack.timeout(1,'months',dumb);
elseif ( repeatEvery == nil ) then
--dfhack.with_suspend(computeHeritage, nameScheme, outputType, sortBy, reverse);
else
dfhack.error("Error.");
end
end

tempFunction(tempFunction);

Logged

expwnent

  • Bay Watcher
    • View Profile
Re: Dwarven Heritage Project, version 1.2
« Reply #29 on: August 21, 2012, 04:42:11 pm »

Thanks! I fixed the problem and another one I found with extinct names.

I kept parent1 and parent2 because there was a time when I sorted parents by age. Also, sometimes I switch them around. Also, it keeps them more...uniform.
Logged
Pages: 1 [2] 3 4