Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 274 275 [276] 277 278 ... 373

Author Topic: DFHack 0.34.11 r3  (Read 608135 times)

Kurik Amudnil

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4125 on: June 20, 2013, 05:51:34 pm »

... unfortunately that code didn't fix them. The missing organs disappeared again.. are there any scripts out there that actually work on restoring organs?

I tried to merge the various heal scripts floating around and tested it by trying to resurrect units in one of my test worlds.  I found that setting the body_part_status wouldn't stick unless I also reset the body.components.body_layer_*** values that Urist posted about.  However, setting those with a for ipairs/pairs loop wouldn't stick either but would stick with for idx=0,length,1 do unit.body.components.body_layer_***[idx] = 0.  Getting the body_layer_*** vectors to stick, the body_part_status would then stick (with either type of loop).  Resurrecting a unit is not completely tested but appears to work at the moment.

Spoiler: fullheal.lua (click to show/hide)
EDIT: please be sure to make a backup before testing (especially when testing the resurrection part)


EDIT: hang on, is it possible to make the dead units plugin unload the uninteresting dead units list to a file and then reload it at the end (or when you feel like tabulating the carnage in your fortress)?

That sounds plausable as I think the units still exist in units.all.  Would need to double check that.  If they do still exist in units.all then writing a file listing the unit.id of units removed from the active list would allow reading back those ids to reinsert them into active.



Whoa, that's great Kurik! Thanks for the fix!

Your welcome!
« Last Edit: June 20, 2013, 06:09:40 pm by Kurik Amudnil »
Logged

CaptainArchmage

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4126 on: June 20, 2013, 06:50:29 pm »

How do you check whether the unit still exists in units.all?
Logged

mithosaurion

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4127 on: June 20, 2013, 06:50:38 pm »

First "twice as strong as a dragon" would have to be defined.
How about a command to give a targeted creature 1000000 strength?
I would prefer it be something that can be inserted into dfusion tools... since I kinda know how to do that (and I have no idea how to run a separate lua file with dfusion).
Someone on this board helped me with a tool to modify skills.
« Last Edit: June 20, 2013, 07:29:39 pm by mithosaurion »
Logged

crossmr

  • Bay Watcher
    • View Profile
    • Jeonsa
Re: DFHack 0.34.11 r3
« Reply #4128 on: June 20, 2013, 07:21:14 pm »

... unfortunately that code didn't fix them. The missing organs disappeared again.. are there any scripts out there that actually work on restoring organs?

I tried to merge the various heal scripts floating around and tested it by trying to resurrect units in one of my test worlds.  I found that setting the body_part_status wouldn't stick unless I also reset the body.components.body_layer_*** values that Urist posted about.  However, setting those with a for ipairs/pairs loop wouldn't stick either but would stick with for idx=0,length,1 do unit.body.components.body_layer_***[idx] = 0.  Getting the body_layer_*** vectors to stick, the body_part_status would then stick (with either type of loop).  Resurrecting a unit is not completely tested but appears to work at the moment.

Spoiler: fullheal.lua (click to show/hide)
EDIT: please be sure to make a backup before testing (especially when testing the resurrection part)

Okay, well so far so good. Not a lot of time to test right now, but after work I'll run it for a bit and see if it sticks.
I ran the squad around a little and he didn't break right away. I never noticed how long it took to reset before.
Logged

Kurik Amudnil

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4129 on: June 20, 2013, 08:50:13 pm »

How do you check whether the unit still exists in units.all?

I wrote the unit.id to file when removing from active, the used df.unit.find(unit.id) which gets a unit by id from units.all to see if it returned a unit or nil.  When I tested that, the unit still existed in units.all .

So.. what I have so far is:

add this to the save's init.lua to save the save games path to a persistent entry:
Code: (dwarf fortress/save/regionX/raw/init.lua) [Select]
dfhack.persistent.save({key='SAVE_PATH',value=SAVE_PATH})
modified fix/dead-units (original unit selection criteria):
Code: (fix/clear-dead-units.lua) [Select]
-- Remove uninteresting dead units from the unit list. Use option 'restore' to put them back (if saved)

local restore = false
for _,arg in pairs({...}) do
    if arg == "restore" then restore = true end
end

local units = df.global.world.units.active
local count = 0
local SAVE_PATH = dfhack.persistent.get('SAVE_PATH')
local SAVE_FILE, file, unit, flags1, flags2, remove
if SAVE_PATH then
SAVE_FILE = SAVE_PATH.value .. '/cleared-dead-units.txt'
end

if restore then
if SAVE_FILE then
file = assert(io.open(SAVE_FILE, "r"))
for line in file:lines() do
unit = df.unit.find(tonumber(line))
units:insert('#',unit)
count = count + 1
end
file:close()
else
dfhack.printerr("Error, can't resore cleared dead units without save path from init.lua")
end
else
if SAVE_FILE then
file = assert(io.open(SAVE_FILE, "a"))
end
local dwarf_race = df.global.ui.race_id
local dwarf_civ = df.global.ui.civ_id
for i=#units-1,0,-1 do
unit = units[i]
flags1 = unit.flags1
flags2 = unit.flags2
if flags1.dead and unit.race ~= dwarf_race then
remove = false
if flags2.slaughter then
remove = true
elseif not unit.name.has_name then
remove = true
elseif unit.civ_id ~= dwarf_civ and
not (flags1.merchant or flags1.diplomat) then
remove = true
end
if remove then
count = count + 1
file:write(tostring(units[i].id), NEWLINE)
units:erase(i)
end
end
end
file:close()
print('Units removed from active (Saved): '..count)
end

It needs better error checking and I am not sure what happens if you try to restore more than once since it currently doesn't remove saved ids from the save file when restoring.
« Last Edit: June 20, 2013, 08:58:04 pm by Kurik Amudnil »
Logged

CaptainArchmage

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4130 on: June 20, 2013, 09:19:37 pm »

How do you check whether the unit still exists in units.all?

I wrote the unit.id to file when removing from active, the used df.unit.find(unit.id) which gets a unit by id from units.all to see if it returned a unit or nil.  When I tested that, the unit still existed in units.all .

So.. what I have so far is:

add this to the save's init.lua to save the save games path to a persistent entry:
Code: (dwarf fortress/save/regionX/raw/init.lua) [Select]
dfhack.persistent.save({key='SAVE_PATH',value=SAVE_PATH})
modified fix/dead-units (original unit selection criteria):
Code: (fix/clear-dead-units.lua) [Select]
-- Remove uninteresting dead units from the unit list. Use option 'restore' to put them back (if saved)

local restore = false
for _,arg in pairs({...}) do
    if arg == "restore" then restore = true end
end

local units = df.global.world.units.active
local count = 0
local SAVE_PATH = dfhack.persistent.get('SAVE_PATH')
local SAVE_FILE, file, unit, flags1, flags2, remove
if SAVE_PATH then
SAVE_FILE = SAVE_PATH.value .. '/cleared-dead-units.txt'
end

if restore then
if SAVE_FILE then
file = assert(io.open(SAVE_FILE, "r"))
for line in file:lines() do
unit = df.unit.find(tonumber(line))
units:insert('#',unit)
count = count + 1
end
file:close()
else
dfhack.printerr("Error, can't resore cleared dead units without save path from init.lua")
end
else
if SAVE_FILE then
file = assert(io.open(SAVE_FILE, "a"))
end
local dwarf_race = df.global.ui.race_id
local dwarf_civ = df.global.ui.civ_id
for i=#units-1,0,-1 do
unit = units[i]
flags1 = unit.flags1
flags2 = unit.flags2
if flags1.dead and unit.race ~= dwarf_race then
remove = false
if flags2.slaughter then
remove = true
elseif not unit.name.has_name then
remove = true
elseif unit.civ_id ~= dwarf_civ and
not (flags1.merchant or flags1.diplomat) then
remove = true
end
if remove then
count = count + 1
file:write(tostring(units[i].id), NEWLINE)
units:erase(i)
end
end
end
file:close()
print('Units removed from active (Saved): '..count)
end

It needs better error checking and I am not sure what happens if you try to restore more than once since it currently doesn't remove saved ids from the save file when restoring.

I think that's fine. I'm going to apply it to the Moltenchannels save, so we can finally get more huge migration waves. I hope.
Logged

HugoLuman

  • Bay Watcher
  • Wished it would rain recently
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4131 on: June 20, 2013, 11:23:50 pm »

How would I make a Tigerperson that we got off the elven caravan into a proper citizen? We need her bonedoctoring skills!

Kurik Amudnil

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4132 on: June 21, 2013, 12:36:30 am »

updated clear-dead-units.lua .  I think this is essentially complete as it now clears the saved list when restoring and resaves missing ids if the unit is not found (shouldn't happen) and only restores one copy of duplicate ids in the save file (also shouldn't happen under normal circumstances), doesn't allow clearing the list without the save file, and it should be less likely to fail and lose the saved list. If for some weird reason a unit still exists in the active list and has a saved id from this script (I don't see why it would happen without user editing the list) a duplicate will still be added as duplicates are only detected in the saved list rather than in the active units list.  The save list is appended so future clears add to the saved list. 

The only thing I can things that is missing from making this script complete are: ensuring fortress mode, and clearing the saved list if the fort is lost or abandoned so that the next fort doesn't inherit a saved list of invalid unit ids.  Not that the invalid ids will hurt anything but can lead to duplicate units entries when that id becomes used again by the new fort and is then restored from the saved list.

add this to the save's init.lua to save the save games path to a persistent entry:
CODE

fix/clear-dead-units.lua using fix/dead-units original unit selection criteria, saving removed active unit ids to the save dir:
Code: (fix/clear-dead-units.lua) [Select]
-- Remove uninteresting dead units from the unit list. Use option 'restore' to put them back
local utils = require('utils')

local restore = false
for _,arg in pairs({...}) do
    if arg == "restore" then restore = true end
end

local SAVE_FILE = 'data/save/' .. df.global.world.cur_savegame.save_dir .. '/cleared-dead-units.txt'

if restore then
file = assert(io.open(SAVE_FILE, "r"))
local units = df.global.world.units
local count = 0
local ids = {}
for n in file:lines() do
ids[n] = tonumber(n) -- prevent duplicates, not an array
end
file:close()
file = io.open(SAVE_FILE, "w") -- empty file, re-add failures
for _,id in pairs(ids) do
local unit = utils.binsearch(units.all,id,'id')
if unit then
units.active:insert('#',unit)
count = count + 1
else
file:write(id,NEWLINE)
end
id = table.remove(ids,#ids) -- pop laste element
end
file:close()
print('Restored dead units to active from saved list: '..count)
else
file = assert(io.open(SAVE_FILE, "a"))
local dwarf_race = df.global.ui.race_id
local dwarf_civ = df.global.ui.civ_id
local units = df.global.world.units.active
local count = 0
for i=#units-1,0,-1 do
local unit = units[i]
local flags1 = unit.flags1
local flags2 = unit.flags2
if flags1.dead and unit.race ~= dwarf_race then
local remove = false
if flags2.slaughter then
remove = true
elseif not unit.name.has_name then
remove = true
elseif unit.civ_id ~= dwarf_civ and
not (flags1.merchant or flags1.diplomat) then
remove = true
end
if remove then
count = count + 1
file:write(units[i].id, NEWLINE)
units:erase(i)
end
end
end
file:close()
print('Removed dead units from active to saved list: '..count)
end


EDIT:  applied suggestion from expwnent to use df.global.world.cur_savegame.save_dir so that init.lua is no longer needed.
« Last Edit: June 21, 2013, 06:05:51 pm by Kurik Amudnil »
Logged

expwnent

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4133 on: June 21, 2013, 01:06:33 am »

Instead of all that, consider using

Code: [Select]
df.global.world.cur_savegame.save_dir
to get at the save directory.

crossmr

  • Bay Watcher
    • View Profile
    • Jeonsa
Re: DFHack 0.34.11 r3
« Reply #4134 on: June 21, 2013, 02:37:46 am »

How would I make a Tigerperson that we got off the elven caravan into a proper citizen? We need her bonedoctoring skills!
From what I read, you'd need to change their race to dwarf.
you can tweak makeown them, but the game still treats them like a pet.
So you can't see them in dwarf therapist and stuff like that.
Logged

HugoLuman

  • Bay Watcher
  • Wished it would rain recently
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4135 on: June 21, 2013, 02:44:18 am »

Well, at the very least I just need this tigerperson to hang out in the dining hall and actually talk to the dwarves (evidenced by raising social skills) for the purposes of the succession game.

CaptainArchmage

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4136 on: June 21, 2013, 09:44:31 pm »

I'm now playing Moltenchannels with your script. There are now only 811 units in the list between citizens, pets/livestock, others, and dead/missing.

If I save the game without restoring the dead units, will I still be able to restore them?

Problem I've noticed: Lots of dwarf corpses are showing. These are the un-named beings that siege your fortress when the undead come. Is it possible to get rid of those as well?

It may help if we have a binary patch to fix this problem once and for all. However, at this rate unless we get 189 more named dead or dead dwarves, citizens, traders, or other livestock and pets, we will be OK.
Logged

Kurik Amudnil

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4137 on: June 22, 2013, 03:16:30 am »

I'm now playing Moltenchannels with your script. There are now only 811 units in the list between citizens, pets/livestock, others, and dead/missing.

If I save the game without restoring the dead units, will I still be able to restore them?

Problem I've noticed: Lots of dwarf corpses are showing. These are the un-named beings that siege your fortress when the undead come. Is it possible to get rid of those as well?

It may help if we have a binary patch to fix this problem once and for all. However, at this rate unless we get 189 more named dead or dead dwarves, citizens, traders, or other livestock and pets, we will be OK.

My tests worked with saving, quitting, loading and restoring the list.  As long as a list was successfully created it should work fine.

for the undead.. could try doing something like this:
Quote
      if flags1.dead and unit.race ~= dwarf_race then
         local remove = false
         if flags2.slaughter then
            remove = true
         elseif unit.enemy.undead then
            remove = true
         elseif not unit.name.has_name then
            remove = true
         ...

crossmr

  • Bay Watcher
    • View Profile
    • Jeonsa
Re: DFHack 0.34.11 r3
« Reply #4138 on: June 22, 2013, 03:31:39 am »

... unfortunately that code didn't fix them. The missing organs disappeared again.. are there any scripts out there that actually work on restoring organs?

I tried to merge the various heal scripts floating around and tested it by trying to resurrect units in one of my test worlds.  I found that setting the body_part_status wouldn't stick unless I also reset the body.components.body_layer_*** values that Urist posted about.  However, setting those with a for ipairs/pairs loop wouldn't stick either but would stick with for idx=0,length,1 do unit.body.components.body_layer_***[idx] = 0.  Getting the body_layer_*** vectors to stick, the body_part_status would then stick (with either type of loop).  Resurrecting a unit is not completely tested but appears to work at the moment.

Spoiler: fullheal.lua (click to show/hide)
EDIT: please be sure to make a backup before testing (especially when testing the resurrection part)

Okay, well so far so good. Not a lot of time to test right now, but after work I'll run it for a bit and see if it sticks.
I ran the squad around a little and he didn't break right away. I never noticed how long it took to reset before.

Just to report back, this seems to have done the trick. Spine is replaced, and after extensive play, and many dead goblins it hasn't reappeared.
Logged

Kurik Amudnil

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4139 on: June 22, 2013, 03:45:14 am »

...

Okay, well so far so good. Not a lot of time to test right now, but after work I'll run it for a bit and see if it sticks.
I ran the squad around a little and he didn't break right away. I never noticed how long it took to reset before.

Just to report back, this seems to have done the trick. Spine is replaced, and after extensive play, and many dead goblins it hasn't reappeared.

Awesome!
Pages: 1 ... 274 275 [276] 277 278 ... 373