dfhack/plugins/lua/onStrike.lua

256 lines
6.4 KiB
Lua

local _ENV = mkmodule('onStrike')
local onReport = require 'plugins.onReport'
local utils = require 'utils'
debug = debug or true
triggers = triggers or {}
function getReportString(reportId)
local report = df.report.find(reportId)
local result = report.text
local i = 1
local report2 = df.report.find(reportId+i)
while report2 and report2.flags.continuation do
result = result .. ' ' .. report2.text
i = i+1
report2 = df.report.find(reportId+i)
end
return result
end
onReport.triggers.onStrike = function(reportId)
local report = df.report.find(reportId)
if report["type"] ~= df.announcement_type.COMBAT_STRIKE_DETAILS then
return
end
if report.flags.continuation then
return
end
-- print('\n')
local fighters = {}
for unitId,_ in pairs(onReport.eventToDwarf[reportId]) do
table.insert(fighters,unitId)
end
local reportString = getReportString(reportId)
if #fighters ~= 2 then
if debug then
local ok = string.find(reportString,' skids along ')
if not ok then
print('onStrike: #fighters = ' .. #fighters)
print(reportString)
df.global.pause_state = true
end
end
return
end
local info = {}
local count = 0
fighters[1] = df.unit.find(fighters[1])
fighters[2] = df.unit.find(fighters[2])
local function getWound(fighterA,fighterB)
local wound
for i=#fighterB.body.wounds-1,0,-1 do
local w = fighterB.body.wounds[i]
if w.unit_id == fighterA.id and w.age <= 1 then
wound = w
break
end
end
--[[name,_ = tryParse(reportString,getNames(fighterA))
if not name then
wound = nil
end
--]]
return wound
end
local wound1 = getWound(fighters[1],fighters[2])
local wound2 = getWound(fighters[2],fighters[1])
local flying = string.find(reportString,'The flying')
local name1
local name2
if flying then
name1 = findAny(reportString,getNames(fighters[2]))
name2 = findAny(reportString,getNames(fighters[1]))
else
name1 = tryParse(reportString,getNames(fighters[1]))
name2 = tryParse(reportString,getNames(fighters[2]))
end
if name1 and wound1 and name2 and wound2 then
if debug then
print('ambiguous wounds: ' .. reportString)
print('fighter1 = ' .. fighters[1].id)
print('fighter2 = ' .. fighters[2].id)
df.global.pause_state = true
end
return
elseif not wound1 and not wound2 then
local ok = fighters[1].flags1.dead or fighters[2].flags1.dead or string.find(reportString,' grabs ') or string.find(reportString,'snatches at') or string.find(reportString,'glances away!') or string.find(reportString, ' shakes ')
if not ok and debug then
print('neither wound works: ' .. reportString)
print('fighter1 = ' .. fighters[1].id)
print('fighter2 = ' .. fighters[2].id)
df.global.pause_state = true
end
return
elseif not name1 and not name2 and not string.find(reportString,'The flying ') then
if debug then
print('WTF?')
print('fighter1 = ' .. fighters[1].id)
print('fighter2 = ' .. fighters[2].id)
df.global.pause_state = true
end
return
elseif name1 and wound1 then
else
local temp = fighters[1]
fighters[1] = fighters[2]
fighters[2] = temp
end
local wound = wound1 or wound2
--is it a weapon attack?
local isWeaponAttack
if getWeapon(fighters[1]) and string.find(reportString,getWeaponString(fighters[1])) then
isWeaponAttack = true
else
isWeaponAttack = false
end
isWeaponAttack = isWeaponAttack or flying
local weapon
if isWeaponAttack then
weapon = getWeapon(fighters[1])
end
-- print('triggers')
for _,trigger in pairs(triggers) do
-- print('trigger')
trigger(fighters[1],fighters[2],weapon,wound)
end
end
function myConcat(table1,table2)
local result = {}
for _,v in pairs(table1) do
table.insert(result,v)
end
for _,v in pairs(table2) do
table.insert(result,v)
end
return result
end
function getUnitAttackStrings(unit)
local result = {}
for _,attack in ipairs(unit.body.body_plan.attacks) do
table.insert(result,attack.verb_3rd..' ')
end
return result
end
function getUnitAttack(unit,parsedAttack)
for _,attack in ipairs(unit.body.body_plan.attacks) do
if attack.verb_3rd..' ' == parsedAttack then
return result
end
end
return nil
end
function getWeapon(unit)
function dumb(item)
-- print('\n')
-- print(item)
-- printall(item)
if item.mode ~= df.unit_inventory_item.T_mode.Weapon then
--print('item.mode ' .. item.mode .. ' /= Weapon ' .. df.unit_inventory_item.T_mode.Weapon)
return false
end
if item.item._type ~= df.item_weaponst then
--print('item.item._type ' .. item.item._type .. ' /= df.item_weaponst ' .. df.item_weaponst)
return false
end
return true
end
for _,item in ipairs(unit.inventory) do
if dumb(item) then
return item.item
end
end
return nil
end
function getWeaponAttackStrings(unit)
local result = {}
local weapon = getWeapon(unit)
if not weapon then
print('no weapon')
return result
end
for _,attack in ipairs(weapon.subtype.attacks) do
table.insert(result,attack.verb_3rd..' ')
end
return result
end
function getWeaponAttack(unit,parsedAttack)
local weapon = getWeapon(unit)
if not weapon then
return nil
end
for _,attack in ipairs(weapon.subtype.attacks) do
if attack.verb_3rd..' ' == parsedAttack then
return attack
end
end
return nil
end
function getNames(unit)
local result = {}
table.insert(result,unit.name.first_name .. ' ')
table.insert(result,'The '..dfhack.units.getProfessionName(unit)..' ')
table.insert(result,'the '..dfhack.units.getProfessionName(unit)..' ')
table.insert(result,'The Stray '..dfhack.units.getProfessionName(unit)..' ')
table.insert(result,'the stray '..dfhack.units.getProfessionName(unit)..' ')
return result
end
function getWeaponString(unit,suffix)
local weapon = getWeapon(unit)
if not weapon then
return ''
end
local material = getMaterialString(weapon)
return material .. ' ' .. weapon.subtype.name .. (suffix or '')
end
function getMaterialString(item)
local material = dfhack.matinfo.decode(item.mat_type,item.mat_index)
return material.material.state_name[df.matter_state.Solid]
end
function findAny(parseString,strs)
for _,str in ipairs(strs) do
if string.find(parseString,str) then
return str
end
end
return nil
end
function tryParse(parseString,strs)
for _,str in ipairs(strs) do
if string.sub(parseString,1,#str) == str then
--print('\n"' .. str .. '" matches "' .. parseString .. '"\n')
return str,string.sub(parseString,#str+1,#parseString)
end
--print('\n"' .. str .. '" doesn\'t match "' .. parseString .. '"\n')
end
return nil,nil
end
return _ENV