Bay 12 Games Forum

Please login or register.

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

Author Topic: DFHack 0.34.11 r3  (Read 1456141 times)

crossmr

  • Bay Watcher
    • View Profile
    • Jeonsa
Re: DFHack 0.34.11 r3
« Reply #4110 on: June 20, 2013, 04:45:22 am »

Okay, well that didn't work.
As before he stayed fine for awhile, then as an ambush arrived, I sent him and some other squads out to slaugther them, and noticed him blinking. He didn't get injured, but doing bodycheck again, it notes his lower spine is missing and damaged.

do we need to somehow insert a new lower spine, rather than simply flipping the flag that says it's missing?
Logged

Urist Da Vinci

  • Bay Watcher
  • [NATURAL_SKILL: ENGINEER:4]
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4111 on: June 20, 2013, 09:12:47 am »

...
Thanks. the finer points are still all new to me here. He had mentioned using it as "ruby code" so I saved it as an RB file.

After running this, then rerunning body check the spine damage isn't listed anymore. I ran the supermedic script I have to fix the "ability to stand lost" tag and we'll see if it stays gone now.

http://www.bay12forums.com/smf/index.php?topic=91166.msg4332668#msg4332668

Technically, I wrote "You can also use this:{code}{/code} or similar ruby code to repair all nerve damage stored at this location." after previously stating in the same post for some other code "This lua script will detect if any body parts of the creature have status flags set, including motor/sensory nerves severed".

I only mentioned ruby because crossmr's original supermedic script was in ruby ( http://www.bay12forums.com/smf/index.php?topic=91166.msg4297004#msg4297004 ) and I thought that he wrote it (could write it).

crossmr

  • Bay Watcher
    • View Profile
    • Jeonsa
Re: DFHack 0.34.11 r3
« Reply #4112 on: June 20, 2013, 10:00:32 am »

...
Thanks. the finer points are still all new to me here. He had mentioned using it as "ruby code" so I saved it as an RB file.

After running this, then rerunning body check the spine damage isn't listed anymore. I ran the supermedic script I have to fix the "ability to stand lost" tag and we'll see if it stays gone now.

http://www.bay12forums.com/smf/index.php?topic=91166.msg4332668#msg4332668

Technically, I wrote "You can also use this:{code}{/code} or similar ruby code to repair all nerve damage stored at this location." after previously stating in the same post for some other code "This lua script will detect if any body parts of the creature have status flags set, including motor/sensory nerves severed".

I only mentioned ruby because crossmr's original supermedic script was in ruby ( http://www.bay12forums.com/smf/index.php?topic=91166.msg4297004#msg4297004 ) and I thought that he wrote it (could write it).

Nope. I found it somewhere.. i think github. But unfortunately that code didn't fix them. The missing organs disappeared again.. are there any scripts out there that actually work on restoring organs?
Logged

Kurik Amudnil

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4113 on: June 20, 2013, 01:53:18 pm »

I meant a plugin that would clean up the reduction in immigration without clearing the "dead units" list.

modifying fix/dead-units.lua to be less aggressive (target only slaughtered units that were not former pets) I came up with this.  I don't think anyone would miss slaughtered units from the dead list.

Code: (clear-slaughtered-units.lua) [Select]
-- Remove slaughtered dead units from the unit list.

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 flags2.slaughter and flags2.killed and not unit.name.has_name then
        count = count + 1
        units:erase(i)
    end
end

print('Units removed from active: '..count)

CaptainArchmage

  • Bay Watcher
  • Profile Pic has Changed! Sorry for the Delay.
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4114 on: June 20, 2013, 04:58:58 pm »

I meant a plugin that would clean up the reduction in immigration without clearing the "dead units" list.

modifying fix/dead-units.lua to be less aggressive (target only slaughtered units that were not former pets) I came up with this.  I don't think anyone would miss slaughtered units from the dead list.

Code: (clear-slaughtered-units.lua) [Select]
-- Remove slaughtered dead units from the unit list.

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 flags2.slaughter and flags2.killed and not unit.name.has_name then
        count = count + 1
        units:erase(i)
    end
end

print('Units removed from active: '..count)

The real deal is the number of dead invaders, I think. In the end that's going to pile up to more than the number of slaughtered units. However, I will copy over the save and run the script. See what happens.

I think what we need is a hack for the number of immigrants who arrive. Alternatively if someone knows how to locate the code dealing with immigration and patching the bad stuff out, maybe (so it never actually checks the total number of units, just the number of citizens and whether you're over the population cap at that).

The trouble starts at a total list of 1,000 citizens, pets, other, and dead, when the migration wave size goes down to 10. The wave size is reduced by 1 at intervals, until at 3,000 total units you don't get any more migrants.

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)?
« Last Edit: June 20, 2013, 05:24:46 pm by CaptainArchmage »
Logged
Given current events, I've altered my profile pic and I'm sorry it took so long to fix. If you find the old one on any of my accounts elsewhere on the internet, let me know by message (along with the specific site) and I'll fix. Can't link the revised avatar for some reason.

gchristopher

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4115 on: June 20, 2013, 05:42:02 pm »

Kurik, thanks. That looks like a script I can just run, I don't have to hunt down the unit I used the command on?

Also..how do I know to make it a .rb or .lua script? Does it matter?

that script does use getSelectedUnit so you will have to select the unit in one of its supported methods.  I haven't played around with makeown myself so I don't know how feasible it would be to make the script look for any incomplete citizens with which to add historical figure data. 

A thought off the top of my head about why these units can't be placed into a noble position might have to do with a lack of recorded events such as arriving at the fort, birth, or some such.  I might look into that later if no one else does.

The events are probably unimportant, but for completeness we could add a history_event_add_hf_entity_linkst and a history_event_change_hf_statest. 

To get the noble positions working I found that the unit needs a nemesis entry.
Spoiler: fixmakeown.lua (click to show/hide)

changes:
  • new_hist_fig.appeared_year = df.global.cur_year.  Probably irrelevant but this field is usually the year they arrived or created not birth year.
  • new_hist_fig.died_seconds = -1. Also likely to be irrelevant, but = 1 was probably a typo.
  • create and insert nemesis entries.
  • searches for all relevant units instead of only the currently selected unit
still missing and perhaps not needed:
  • history_event_add_hf_entity_linkst and history_event_change_hf_statest events.
  • historical_figure.info, historical_figure.info.skills, historical_figure.info.unk_14.
script to add nemesis to units that have already had historical figures added with the previous version of the fixmakeown or fixhistfig script:
Spoiler: fixnemesis.lua (click to show/hide)
Whoa, that's great Kurik! Thanks for the fix!
Logged

Kurik Amudnil

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4116 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
  • Profile Pic has Changed! Sorry for the Delay.
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4117 on: June 20, 2013, 06:50:29 pm »

How do you check whether the unit still exists in units.all?
Logged
Given current events, I've altered my profile pic and I'm sorry it took so long to fix. If you find the old one on any of my accounts elsewhere on the internet, let me know by message (along with the specific site) and I'll fix. Can't link the revised avatar for some reason.

mithosaurion

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4118 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 #4119 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 #4120 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
  • Profile Pic has Changed! Sorry for the Delay.
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4121 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
Given current events, I've altered my profile pic and I'm sorry it took so long to fix. If you find the old one on any of my accounts elsewhere on the internet, let me know by message (along with the specific site) and I'll fix. Can't link the revised avatar for some reason.

WillowLuman

  • Bay Watcher
  • They/Them Life is weird
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4122 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!
Logged
Dwarf Souls: Prepare to Mine
Keep Me Safe - A Girl and Her Computer (Illustrated Game)
Darkest Garden - Illustrated game. - What mysteries lie in the abandoned dark?

Kurik Amudnil

  • Bay Watcher
    • View Profile
Re: DFHack 0.34.11 r3
« Reply #4123 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 #4124 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.
Logged
Pages: 1 ... 273 274 [275] 276 277 ... 373