From ff71199931f45aafaf3fc1bff920963195e0a00e Mon Sep 17 00:00:00 2001 From: expwnent Date: Thu, 3 Jul 2014 14:37:47 -0400 Subject: [PATCH] modtools/invader-item-destroyer.lua: destroy invader items when they die --- scripts/modtools/invader-item-destroyer.lua | 151 ++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 scripts/modtools/invader-item-destroyer.lua diff --git a/scripts/modtools/invader-item-destroyer.lua b/scripts/modtools/invader-item-destroyer.lua new file mode 100644 index 000000000..d3533e405 --- /dev/null +++ b/scripts/modtools/invader-item-destroyer.lua @@ -0,0 +1,151 @@ +--modtools/invader-item-destroyer.lua +--author expwnent +--configurably deletes invader items when they die + +local eventful = require 'plugins.eventful' +local utils = require 'utils' + +--invaders = invaders or {} +entities = entities or {} +items = items or {} + +allEntities = allEntities or false +allItems = allitems or true + +eventful.enableEvent(eventful.eventType.UNIT_DEATH, 1) --requires iterating through all units +eventful.onUnitDeath.invaderItemDestroyer = function(unitId) + local unit = df.unit.find(unitId) + if not unit then + return + end + + local entity = df.historical_entity.find(unit.civ_id) + if not allEntities and not entity then + return + end + + if not allEntities and not entities[entity.entity_raw.code] then + return + end + + if dfhack.units.isCitizen(unit) then + return + end + + local function forEach(item) + if not allItems and not items[dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()).id] then + return + end + if not (item.flags.foreign and item.flags.forbid) then + return + end + if item.pos.x ~= unit.pos.x then + return + end + if item.pos.y ~= unit.pos.y then + return + end + if item.pos.z ~= unit.pos.z then + return + end + item.flags.garbage_collect = true + item.flags.forbid = true + item.flags.hidden = true + end + + for _,item in ipairs(unit.inventory) do + local item2 = df.item.find(item.item) + forEach(item2) + end + --for each item on the ground + local block = dfhack.maps.getTileBlock(unit.pos.x, unit.pos.y, unit.pos.z) + for _,item in ipairs(block.items) do + local item2 = df.item.find(item) + forEach(item2) + end +end +--[[eventful.onUnitDeath.invaderItemDestroyer = function(unit) + if invaders[unit] then + print ('Invader ' .. unit .. ' dies.') + end + for _,item in ipairs(invaders[unit] or {}) do + local item2 = df.item.find(item) + if item2 then + print ('deleting item ' .. item) + item2.flags.garbage_collect = true + item2.flags.forbid = true + item2.flags.hidden = true + item2.flags.encased = true + end + end + invaders[unit] = nil + --TODO: delete corpses? +end]] + +validArgs = --[[validArgs or]] utils.invert({ + 'clear', + 'help', + 'allRaces', + 'allEntities', + 'allItems', + 'item', + 'entity', + 'race', +}) + +local args = utils.processArgs({...}, validArgs) + +if args.clear then + entities = {} + items = {} + allEntities = false + allItems = true +end + +if args.help then + --TODO: print help string + return +end + +if args.allEntities then + if args.allEntities == 'true' then + allEntities = true + else + allEntities = false + end +end +if args.allItems then + if args.allItems == 'true' then + allItems = true + else + allItems = false + end +end + +if args.item then + local itemType + for _,itemdef in ipairs(df.global.world.raws.itemdefs.all) do + if itemdef.id == args.item then + itemType = itemdef.id + break + end + end + if not itemType then + error ('Invalid item type: ' .. args.item) + end + items[itemType] = true +end +if args.entity then + local success + for _,entity in ipairs(df.global.world.entities.all) do + if entity.entity_raw.code == args.entity then + success = true + break + end + end + if not success then + error 'Invalid entity' + end + entities[args.entity] = true +end +