-
Notifications
You must be signed in to change notification settings - Fork 231
add new tool entomb
#1482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
add new tool entomb
#1482
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
86e636f
Add entomb.lua and docs/entomb.rst
amade-w f684542
Update changelog.txt to add new tool: entomb
amade-w 07594b5
Apply revisions to entomb.lua according to PR comments
amade-w 0f75b56
Apply 2nd revision to entomb.lua: improve PutInCoffin()
amade-w 36b7771
entomb.lua Implement a function that creates a job to haul an item to…
SilasD b359cba
entomb.lua Very Important Bugfix completely assign unit to tomb.
SilasD 6a185fd
entomb.lua Update the unit's owned buildings with the newly-assigned …
SilasD a2f4548
Undo commit b359cbaa4c7ea3b62da9ccea24ca3fdf6e025581
SilasD 3c62cda
Merge pull request #1 from SilasD/entomb
SilasD 25714bf
Add function to validate moving items, separate job removal into own …
amade-w 7952e13
Assign new name to unnamed tombs during assignment
amade-w f484912
Move logic to call HaulToCoffin() and TeleportToCoffin() into new fun…
amade-w ba5e5d1
Implement add-item option, revise Main() logic, switch to use argpars…
amade-w e11d968
Disable teleport function, update documentation
amade-w 8f4feca
Fix argparse short-form conflict
amade-w 785741b
Fix documentation
amade-w 062ef18
Assign only active tomb zones and make it unavailable for auto assigm…
amade-w 5f1c7b7
Remove duplicated code in IterateTombZones()
amade-w c343176
Merge branch 'master' into entomb
amade-w File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| entomb | ||
| ====== | ||
|
|
||
| .. dfhack-tool:: | ||
| :summary: Entomb any corpse into tomb zones. | ||
| :tags: fort items buildings | ||
|
|
||
| Assign any corpse regardless of citizenship, residency, pet status, | ||
| or affiliation to an unassigned tomb zone for burial. | ||
|
|
||
| Usage | ||
| ----- | ||
|
|
||
| ``entomb [<options>]`` | ||
|
|
||
| This script must be executed with either a unit's corpse or body part | ||
| selected or with a unit ID specified. An unassigned tomb zone will then | ||
| be assigned to the unit for burial and all its corpse and/or body parts | ||
| will become valid items for interment. | ||
|
|
||
| Optionally, the zone ID may also be specified to assign a specific tomb | ||
| zone to the unit. | ||
|
|
||
| A non-citizen, non-resident, or non-pet unit that is still alive may | ||
| even be assigned a tomb zone if they have lost any body part that can | ||
| be placed inside a tomb, e.g. teeth or severed limbs. New corpse items | ||
| after a tomb has already been assigned will not be properly interred | ||
| until the script is executed again on either the unit, its corpse, or | ||
| any of its body parts. | ||
|
|
||
| If executed on slaughtered animals, all its butchering returns will | ||
| become valid burial items and no longer usable for cooking or crafting. | ||
|
|
||
| Examples | ||
| -------- | ||
|
|
||
| ``entomb unit <id>`` | ||
| Assign an unassigned tomb zone to the unit with the specified ID. | ||
|
|
||
| ``entomb tomb <id>`` | ||
| Assign a tomb zone with the specified ID to the selected corpse | ||
| item's unit. | ||
|
|
||
| ``entomb unit <id> tomb <id> now`` | ||
| Assign a tomb zone with the specified ID to the unit with the | ||
| specified ID and teleport its corpse and/or body parts into the | ||
| coffin in the tomb zone. | ||
|
|
||
| Options | ||
| ------- | ||
|
|
||
| ``unit <id>`` | ||
| Specify the ID of the unit to be assigned to a tomb zone. | ||
|
|
||
| ``tomb <id>`` | ||
| Specify the ID of the zone into which a unit will be interred. | ||
|
|
||
| ``now`` | ||
| Instantly teleport the unit's corpse and/or body parts into the | ||
| coffin of its assigned tomb zone. This option can be called on | ||
| corpse items or units that are already assigned a tomb zone. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,193 @@ | ||
| -- Entomb corpse items of any dead unit. | ||
| --@module = true | ||
|
|
||
| local utils = require('utils') | ||
|
|
||
| local unit_id | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| local unit | ||
| local building_id | ||
| local tomb | ||
| local forceBurial | ||
|
|
||
| local args = {...} | ||
|
|
||
| -- Get unit from selected corpse or corpse piece item. | ||
| local function GetUnitFromCorpse() | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| local item = dfhack.gui.getSelectedItem(true) | ||
| if item then | ||
| if df.item_corpsest:is_instance(item) or df.item_corpsepiecest:is_instance(item) then | ||
| unit_id = item.unit_id | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| unit = df.unit.find(unit_id) | ||
| else | ||
| qerror('Selected item is not a corpse or body part.') | ||
| end | ||
| else | ||
| qerror('No item selected or unit specified.') | ||
| end | ||
| end | ||
|
amade-w marked this conversation as resolved.
|
||
|
|
||
| -- Validate tomb zone assignment. | ||
| local function CheckTombZone(building, id) | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| if df.building_civzonest:is_instance(building) then | ||
| if building.type == 97 then | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| if building.assigned_unit_id == id then | ||
| return true | ||
| end | ||
| end | ||
| end | ||
| end | ||
|
amade-w marked this conversation as resolved.
|
||
|
|
||
| -- Iterate through all available tomb zones. | ||
| local function IterateTombZone(id) | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| for _, building in pairs(df.global.world.buildings.all) do | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| if CheckTombZone(building, id) then return building end | ||
| end | ||
| end | ||
|
amade-w marked this conversation as resolved.
|
||
|
|
||
| -- Check if any of the unit's corpse items are still not in a coffin. | ||
| local function isNotBuried() | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| for _, item_id in pairs(unit.corpse_parts) do | ||
| local item = df.item.find(item_id) | ||
| if item then | ||
| local inCoffin = dfhack.items.getGeneralRef(item, df.general_ref_type.BUILDING_HOLDER) | ||
| local coffinBuilding_id = inCoffin and inCoffin.building_id or nil | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| local coffin = coffinBuilding_id and df.building.find(coffinBuilding_id) or nil | ||
| local isCoffin = coffin and df.building_coffinst:is_instance(coffin) or nil | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| -- Return TRUE if even one item is not interred. | ||
| if not isCoffin then | ||
| return true | ||
| end | ||
| end | ||
| end | ||
| end | ||
|
amade-w marked this conversation as resolved.
|
||
|
|
||
| local function GetEmptyTombZone() | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| -- Check if unit is already assigned to a tomb zone. | ||
| local isAlreadyAssigned = IterateTombZone(unit_id) | ||
| if isAlreadyAssigned then | ||
| if isNotBuried() or forceBurial then | ||
| tomb = isAlreadyAssigned | ||
| print('Unit is already assigned to a tomb zone but may still have uninterred corpse or body part(s).') | ||
| else | ||
| qerror('Unit is already interred in a tomb zone.') | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| end | ||
| else | ||
| -- Find an unassigned tomb zone. | ||
| tomb = IterateTombZone(-1) | ||
| end | ||
| if not tomb then | ||
| qerror('No unassigned tomb zones are available.') | ||
| end | ||
| end | ||
|
amade-w marked this conversation as resolved.
|
||
|
|
||
| -- Set corpse items to be valid for burial. | ||
| local function FlagForBurial(corpseParts) | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| -- Undead units have empty corpse_parts vector. | ||
| if unit.enemy.undead then | ||
| for _, item in pairs(df.global.world.items.other.IN_PLAY) do | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| if df.item_corpsest:is_instance(item) or df.item_corpsepiecest:is_instance(item) then | ||
| if item.unit_id == unit_id then | ||
| corpseParts:insert(#corpseParts, item.id) | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| end | ||
| end | ||
| end | ||
| utils.sort_vector(corpseParts) | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| end | ||
| local burialItemCount = 0 | ||
| for _, item_id in pairs(corpseParts) do | ||
| local item = df.item.find(item_id) | ||
| if item then | ||
| item.flags.dead_dwarf = true | ||
| -- Some corpse items may be lost/destroyed before burial. | ||
| burialItemCount = burialItemCount + 1 | ||
| end | ||
| end | ||
| if burialItemCount == 0 then | ||
| qerror('Unit has no corpse or body parts available for burial.') | ||
| end | ||
| tomb.assigned_unit_id = unit_id | ||
| return burialItemCount | ||
| end | ||
|
|
||
| local function PutInCoffin(corpseParts) | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| local coffin | ||
| for _, building in pairs(tomb.contained_buildings) do | ||
| if df.building_coffinst:is_instance(building) then coffin = building end | ||
| end | ||
| if coffin then | ||
| -- Set df.building_item_role_type.PERM first before changing | ||
| -- it to TEMP to turn it into an interred corpse item. | ||
| for _, item_id in pairs(corpseParts) do | ||
| local item = df.item.find(item_id) | ||
| if item then | ||
| dfhack.items.moveToBuilding(item, coffin, 2) | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| end | ||
| end | ||
| for _, buildingItem in pairs(coffin.contained_items) do | ||
| local item = buildingItem.item | ||
| if not df.item_coffinst:is_instance(item) then | ||
| buildingItem.use_mode = 0 | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| end | ||
| end | ||
| print('Corpse items have been teleported into a coffin.') | ||
| else | ||
| print('No coffin in the assigned tomb zone.\nCorpse items will not be teleported into the tomb zone.') | ||
| end | ||
| end | ||
|
|
||
| local function AssignToTomb() | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| local corpseParts = unit.corpse_parts | ||
| local strBurial = '%s assigned to a tomb zone for burial.' | ||
| local strCorpseItems = '(%d corpse or body part%s)' | ||
| local strUnitName = unit and dfhack.units.getReadableName(unit) | ||
| local strPlural = '' | ||
| local incident_id = unit.counters.death_id | ||
| if incident_id ~= -1 then | ||
| local incident = df.incident.find(incident_id) | ||
| -- Corpse will not be interred if not yet discovered. | ||
| incident.flags.discovered = true | ||
| end | ||
| local burialItemCount = FlagForBurial(corpseParts) | ||
| print(string.format(strBurial, strUnitName)) | ||
| if forceBurial then PutInCoffin(corpseParts) end | ||
| if burialItemCount > 1 then strPlural = 's' end | ||
| print(string.format(strCorpseItems, burialItemCount, strPlural)) | ||
| end | ||
|
|
||
| local function parseArgs() | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| local building | ||
| if #args > 0 then | ||
| for i, v in ipairs(args) do | ||
| if v == 'unit' then | ||
| unit_id = tonumber(args[i+1]) or nil | ||
| unit = unit_id and df.unit.find(unit_id) | ||
| if not unit then qerror('Invalid unit ID.') end | ||
| end | ||
| if v == 'tomb' then | ||
| building_id = tonumber(args[i+1]) or nil | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| building = building_id and df.building.find(building_id) | ||
| if not building then qerror('Invalid zone ID.') end | ||
| -- Check if tomb zone is unassigned. | ||
| if CheckTombZone(building, -1) then | ||
| tomb = building | ||
| else | ||
| qerror('Specified zone ID does not point to an unassigned tomb zone.') | ||
| end | ||
| end | ||
| if v == 'now' then forceBurial = true end | ||
| end | ||
| end | ||
| end | ||
|
|
||
| local function Main() | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| parseArgs() | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| if not unit then GetUnitFromCorpse() end | ||
| if unit then | ||
| if not tomb then GetEmptyTombZone() end | ||
| if tomb then AssignToTomb() end | ||
| end | ||
| end | ||
|
|
||
| if not dfhack_flags.module then | ||
| Main() | ||
|
amade-w marked this conversation as resolved.
Outdated
|
||
| end | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.