This script does the follow:
- Recovers lost invading armies so that you can kill them and remove the [Siege] Tag
- Recover forgotten beasts that never appear despite the announcement
- Recover packs of wildlife that are missing from your surface/caverns
- Recover caravans that are partially or completely missing, fixing the caravans that are constantly 'unloading'
(5-8-2017 Edit: The missing i's have been found. It should now work as copied. Many thanks to Lethosar)
Note: Fort version 40.24. Posting in hopes it works for newer versions as well.
Open up Notepad++, copy the text below, save as unitretrieval.lua in the Scripts folder of your DFhack folder. If you wish the spawned units to retain their hidden status, remove the line containing "hidden_in_ambush = false". Type 'unitrevieval' in DF hack with your fort open to run it.
-- Spawns stuck invaders/guests.
--[====[
unitretrieval
=================
]====]
function unitretrieval ()
for i = 0, #df.global.world.units.active - 1 do
if df.global.world.units.active [i].flags1.dead then
if df.global.world.units.active [i].flags1.incoming then
dfhack.println ("Retrieving from the abyss ")
df.global.world.units.active [i].flags1.move_state = true
df.global.world.units.active [i].flags1.dead = false
df.global.world.units.active [i].flags1.incoming = false
df.global.world.units.active [i].flags1.can_swap = true
df.global.world.units.active [i].flags1.hidden_in_ambush = false
end
end
end
end
unitretrieval ()
It should look something like this:
(5-18-2017 Edit: Note that this code will only look at the first 6 or 7 units of the fort; I will swap it out later with one showing code that checks all the active units Updated image)
(http://i.imgur.com/KVq8tMR.png)
Backstory:
My generational fort has had a constant issue with siege tags being stuck, forgotten beasts saying they have arrived when they really did not, and years of 1 or 2 herds of wildlife despite having a surface and three caverns. Using a recent siege whose tag still remained, a recent forgotten beast that stood me up, and PatrikLundell's mention of df.global.world.units.active, I found that not only were the 'missing' units on the active unit list, but their flags could be altered using DFHack.
(http://i.imgur.com/CIIL8rw.png)
It turns out that the 'missing' units universally had move_state=false, dead=true, and incoming=true, invaders and forgotten beast alike. When reversing the aforementioned three flags, and ensuring can_swap is true which *most of the other units had, I was able to manually 'spawn' the unit where it should have been and add it to the Unit List.
I then used PatrikLundell's script for Dismissmerchants (http://www.bay12forums.com/smf/index.php?topic=159297.45) as a base and adapted it to search the unit list for anything with dead=true and incoming=true, then making flag changes to those that fit the parameters.
Results:
(http://i.imgur.com/JSebpNp.png)
(http://i.imgur.com/7qjupz3.png)
(http://i.imgur.com/HvaFQ6g.png)
(http://i.imgur.com/fDT5v50.png)
(http://i.imgur.com/Kxbt6Ce.png)
Kill the retrieved invaders and the siege tag will disappear.
I imagine that, so long as an overseer is prompt in dealing with squatters in the void, no group spawned with this will be very large.
That said, I am unsure of this script's usefulness for my own fort. I think my computer will die if I unpause with 6000+ Other Units.
(5-18-2017 Edit: For now, it is unlikely it works in the most recent version of DF, 43.05. I will make a current fort and see what can be done with the script, if anything.)
I hadn't thought of that. And it works; I changed the iterative formula to only go after the last 200 active units, and pretty much just the last siege and a relative handful of wildlife appeared.
for i = #df.global.world.units.active-200, #df.global.world.units.active - 1 do
(http://i.imgur.com/9nIKnLZ.png)
It will take a while, but I am sure I can work my way through my own fort's backlog now. Thanks!
No output. I typed in unitretrieval in the console, and it just goes to another line. I just copy-pasted the text in the spoiler tag above: -- Spawns stuck invaders/guests.
--[====[
unitretrieval
=================
]====]
function unitretrieval ()
for i = 0, #df.global.world.units.active - 1 do
if df.global.world.units.active .flags1.dead then
if df.global.world.units.active .flags1.incoming then
dfhack.println ("Retrieving from the abyss ")
df.global.world.units.active .flags1.move_state = true
df.global.world.units.active .flags1.dead = false
df.global.world.units.active .flags1.incoming = false
df.global.world.units.active .flags1.can_swap = true
df.global.world.units.active .flags1.hidden_in_ambush = false
end
end
end
end
unitretrieval ()
After it didn't work, I edited it to look like the following screenshot. Same thing, no output, no error messages, nothing. (http://i.imgur.com/y870uQs.png)
Dismissmerchants doesn't work either, though it did work on a stuck caravan when I first tested it, so that's not it. I tried fix-unit-occupancy as well. It didn't detect any occupancy issues. Last I walked a squad around the borders of the map, in an attempt to draw them from off the map edge. No one came out.
It's as if the invaders were never created at all.
It's been 8 months straight, siege continues with no end and no actual invaders.
The code Azrael4h pasted was from the original post without the code tag and missing the i's. And if the code was copied exactly from the screenshot posted after that, then it would only look at the first 6 or so units of the embark. The first will not work and the second will not look at the besieging units; both my fault, as I did not originally post with the code tag and the screenshot was for a test... I will have to go back and correct the screenshot as well.
(Edit: Well, scratch that. I notice that the code pasted by Azrael4h was not in a code tag itself; the i's are there. So while the 2nd code attempted would still only look at the first 6 or 7 active units, the first should have worked. Statement above: Retracted.)
That said, Azrael4h's case makes me wonder if the script really needs to be looking at the dead tag. Would it still work if it only looked for the incoming flag? It would make a certain amount of sense if only the incoming flag was relevant.
-- Spawns stuck invaders/guests.
--[====[
unitretrieval
=================
]====]
function unitretrieval ()
for i = 0, #df.global.world.units.active - 1 do
if df.global.world.units.active [i].flags1.incoming then
dfhack.println ("Retrieving from the abyss ")
df.global.world.units.active [i].flags1.move_state = true
df.global.world.units.active [i].flags1.dead = false
df.global.world.units.active [i].flags1.incoming = false
df.global.world.units.active [i].flags1.can_swap = true
df.global.world.units.active [i].flags1.hidden_in_ambush = false
end
end
end
unitretrieval ()
I will try it out later on my own fort, which still occasionally gets missing forgotten beasts/sieges.