Skip to content

Instantly share code, notes, and snippets.

@thistleknot thistleknot/gist:6152724
Last active Dec 20, 2015

Embed
What would you like to do?
-- Bugs
--[[
...rk\MasterworkDF v3e\Dwarf Fortress\hack\scripts/test.lua:199: Cannot read fie
ld unit_attribute[].6: index out of bounds.
stack traceback:
[C]: in function '__index'
...rk\MasterworkDF v3e\Dwarf Fortress\hack\scripts/test.lua:199: in func
tion 'boostValue'
...rk\MasterworkDF v3e\Dwarf Fortress\hack\scripts/test.lua:61: in funct
ion 'boostAttributes'
...rk\MasterworkDF v3e\Dwarf Fortress\hack\scripts/test.lua:244: in main
chunk
(...tail calls...)
]]
-- --------------------------------------------------------------------------
-- Functions
function boostAttributes(selectedUnitCaste, unit)
-- print(selected_unit_caste.attributes.phys_att_range.STRENGTH[0])
-- old
--[[
for i, v in ipairs(Physical_Plus) do
P_Attributes[v].value = Plus[7]
P_Attributes[v].max_value = Plus[7]*2
end
]]
-- print(selected_unit_caste.attributes.phys_att_range.STRENGTH[0])
--[[
0 STRENGTH
1 AGILITY
2 TOUGHNESS
3 ENDURANCE
4 RECUPERATION
5 DISEASE_RESISTANCE
]]
--physical
handleBoostType("Physical", selectedUnitCaste, unit)
handleBoostType("Mental", selectedUnitCaste, unit)
-- printall(rawValue)
end
function handleBoostType(string_type, selectedUnitCaste, unit)
-- Variables
attributeBin = {}
if string_type == "Physical" then
print (string_type)
numberOfAttr = #selected_unit_caste.attributes.phys_att_range
else
print (string_type)
numberOfAttr = #selected_unit_caste.attributes.ment_att_range
end
print ("Number of Attributes: ", numberOfAttr)
-- cycle through attributes
-- for i,j in ipairs(df.physical_attribute_type) do print(i,j) end
for attrNumber = 1, numberOfAttr do
if string_type == "Physical" then
numberOfBins = #selected_unit_caste.attributes.phys_att_range[attrNumber-1]
attribute_name = df.physical_attribute_type[attrNumber-1]
else
numberOfBins = #selected_unit_caste.attributes.ment_att_range[attrNumber-1]
attribute_name = df.mental_attribute_type[attrNumber-1]
end
print("Attribute Name: ", attribute_name)
print("Number of bins: ", numberOfBins)
-- cycle through bins, print each bin
for line = 1, numberOfBins do
if string_type == "Physical" then
attributeBin[line] = selected_unit_caste.attributes.phys_att_range[attrNumber-1][line-1]
else
attributeBin[line] = selected_unit_caste.attributes.ment_att_range[attrNumber-1][line-1]
end
print("Bin: " , line, attributeBin[line])
end
-- Figure out Percent
if string_type == "Physical" then
rawValue = unit.body.physical_attrs[attrNumber-1].value
else
rawValue = unit.status.current_soul.mental_attrs[attrNumber-1].value
end
if string_type == "Physical" then
print("Raw Value: ", unit.body.physical_attrs[attrNumber-1].value)
else
print("Raw Value: ", unit.status.current_soul.mental_attrs[attrNumber-1].value)
end
percent = calcPercent(rawValue, attributeBin)
print ("Percent: ", percent)
-- Boost this attributes value
if string_type == "Physical" then
boostValue(attrNumber, rawValue, percent, attributeBin, unit, type_string, "Physical")
else
boostValue(attrNumber, rawValue, percent, attributeBin, unit, type_string, "Mental")
end
end
end
function figureValueUL_Limit (rawValue, attributeBin)
local counter = #attributeBin
while rawValue < attributeBin[counter] do
l_limit = attributeBin[counter-1]
u_limit = attributeBin[counter]
counter = counter-1
end
return l_limit, u_limit, counter
end
function calcPercent(rawValue, attributeBin)
local l_limit, u_limit, counter = figureValueUL_Limit(rawValue, attributeBin)
print ("l_limit", l_limit)
print ("u_limit", u_limit)
print("counter: ", counter)
local value = (rawValue - l_limit)
value = value / (u_limit - l_limit)
value = value * ( 1/6 )
value = value + ( ( counter - 1 ) * 1/6)
return value
end
function boostValue(attrNumber, rawValue, percent, attributeBin, unit, line, type_string)
-- Check if we're going to boost the value
local randomRoll = math.random()
print("RNG: ", randomRoll)
if randomRoll >= percent then
print ("Boosting!")
local l_limit, u_limit, counter = figureValueUL_Limit(rawValue, attributeBin)
local binsLeft = #attributeBin - counter
print ("Bins Left: ", binsLeft)
percentWithinBin = (rawValue - l_limit) / (u_limit - l_limit)
print("Percent within bin: ", percentWithinBin)
binPercents = {}
for position = 1, binsLeft do
if position == 1 then
binPercents[position] = percentWithinBin
else
binPercents[position] = 1
end
end
-- get sum
sumOfPercents = sum(binPercents)
print("Sum of Percents: ", sumOfPercents)
for position = 1, #binPercents do
binPercents[position] = binPercents[position]/sumOfPercents
end
-- last = 0 ; for ... ; last = last + value ; binPc[i] = last ; end
-- cumulative sum array
for position = 1, #binPercents do
if position == 1 then
else
binPercents[position] = binPercents[position-1]+binPercents[position]
end
end
printall(binPercents)
-- do a second RNG to determine what bin we're going to land in
secondRoll = math.random()
-- found flag
local found = 0
local binPosition = 1
-- search for matching range
while found == 0 do
if secondRoll > binPercents[binPosition] then
binPosition = binPosition + 1
else
found = 1
end
end
print("secondRoll: ", secondRoll)
binP = findBinPosition (l_limit, attributeBin)
l_limit = attributeBin[binP + binPosition - 1]
u_limit = attributeBin[binP + binPosition]
print("new l_limit: ", l_limit)
print("new u_limit: ", u_limit)
-- gen new value!
if rawValue > l_limit then
l_limit = rawValue + 1
end
range = u_limit - l_limit - 1
thirdRoll = math.random()
newValue = (range * thirdRoll ) + l_limit
print("New Value: ", newValue)
-- attribute_locale[attrNumber].value = newValue
print("Attribute Location: ")
-- need to specify whether physical or mental here.
if type_string == "Physical" then
unit.body.physical_attrs[attrNumber-1].value = round(newValue,0)
else
unit.status.current_soul.mental_attrs[attrNumber-1].value = round(newValue,0)
end
else
print ("Value was determined too high on this pass")
end
end
function round(num, idp)
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
function findBinPosition (binValue, attributeBin)
for tempValue = 1, #attributeBin do
if binValue == attributeBin[tempValue] then
return tempValue
end
end
end
function sum(t)
local sum = 0
for k,v in pairs(t) do
sum = sum + v
end
return sum
end
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
-- Main
-- Initilization
unit = dfhack.gui.getSelectedUnit()
race = unit.race
caste = unit.caste
selected_unit_caste = df.global.world.raws.creatures.all[race].caste[caste]
-- --------------------------------------------------------------------------
boostAttributes(selectedUnitCaste, unit)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.