don't know why I never tested adding a view to the game but yeah
I think this mini script probably decent enough of a step to get to switching between fort mode and adventure mode.
and possibly bringing back the old dfhack fort retire, and uhhh give players the means to quicksave in adventure mode.
ok so as I was writing this I got hit with two issues, one being if fort mode side ever unpause you will auto ruin the run which will end the run which could be fixed with a test to see if fort mode is unpaused then re-pausing it.
and if you made a quicksave you pretty much have to do a manual save after that to clean the save state or the game will crash if you try to fast travel.
if dfhack.world.isFortressMode() then
df.global.gview.view.child=df.viewscreen_dungeonmodest:new()
df.global.gview.view.child.parent=df.global.gview.view
df.global.gamemode=1
df.global.gametype=1
else
df.global.gview.view.child=df.viewscreen_dwarfmodest:new()
df.global.gview.view.child.parent=df.global.gview.view
df.global.gamemode=0
df.global.gametype=0
end
so here's the code beware this could lead to some other unstable stuff down the road I haven't tested or found but I think for a fort mode player perspective this should let one just jump into playing anyone if you set the unit up as an adventurer or well unit active 0
edit: additional quick test to see how well switching between adv mode and fort mode goes.
extremely experimental adv mode quicksave test which requires use of the previous script to fix the autosaves when you reload.
-- Makes the game immediately save the state.
--[====[
Adv quicksave
=========
If called in adv mode, makes DF immediately switches to fort mode then saves the game by setting a flag
normally used in seasonal auto-save. then switches back to adv mode big warning the saves that are backup are set to fort mode so probably best run say a mode set script to switch back to adv mode then save the game again as last I check that seems to fix one crash after switching back to adv mode and fast traveling a bit.
]====]
local gui = require("gui")
--luacheck: defclass={run:bool}
QuicksaveOverlay = defclass(QuicksaveOverlay, gui.Screen)
function QuicksaveOverlay:render()
if not self.run then
self.run = true
save()
self:renderParent()
self:dismiss()
end
end
if not dfhack.isMapLoaded() then
qerror("World and map aren't loaded.")
end
function adv2fort ()
if dfhack.world.isFortressMode() then
df.global.gview.view.child=df.viewscreen_dungeonmodest:new()
df.global.gview.view.child.parent=df.global.gview.view
df.global.gamemode=1
df.global.gametype=1
else
df.global.gview.view.child=df.viewscreen_dwarfmodest:new()
df.global.gview.view.child.parent=df.global.gview.view
df.global.gamemode=0
df.global.gametype=0
end
end
if not dfhack.world.isFortressMode() then
adv2fort()
end
local ui_main = df.global.ui.main
local flags4 = df.global.d_init.flags4
local function restore_autobackup()
if ui_main.autosave_request and dfhack.isMapLoaded() then
dfhack.timeout(10, 'frames', restore_autobackup)
else
flags4.AUTOBACKUP = true
end
end
function save()
-- Request auto-save
ui_main.autosave_request = true
-- And since it will overwrite the backup, disable it temporarily
if flags4.AUTOBACKUP then
flags4.AUTOBACKUP = false
restore_autobackup()
end
print 'The game should save the state now.'
end
QuicksaveOverlay():show()
dfhack.timeout(10, 'frames',adv2fort)
edit: ok so went and fix some issues that came up with this script mostly the fort mode side tends to break if you attempt to zoom on a unit, and the solution was I was missing the parent section on the viewscreen open legends had this solved since 2015 and I should have scan that lua script for tips.
so this should probably work for fort mode players who want to switch from fort mode to adv mode then back to fort mode if they don't leave the fort site and also if they assign an unit on field as an adventurer.
there's a tofort script warmist made that would benefit on this update but like I'm currently checking that one out and seeing if there's any more unforeseen errors that comes from using that and making minor tweaks.
oh while I'm here I should probably post the script I use to clear designation spam from using these scripts
df.global.ui.main.mode=10
df.global.selection_rect.start_x=0
df.global.selection_rect.start_y=0
df.global.selection_rect.start_z=610
df.global.selection_rect.end_x=-1430
df.global.selection_rect.end_y=900
df.global.selection_rect.end_z=0
df.global.cursor.x=400
df.global.cursor.y=400
df.global.cursor.z=0
this script should select the entire map and let you clear designations with little scrolling as possible... though this will clear previously set designations so probably best to use this for returning to a fort after finishing up or making an adv closet to shove the adv in, to make the designation spam that would pop up from the adventurer's field of view be smaller to deal with and not lead to the entire fort digging up the place.
edit: ok so went back and updated the clear designation script to include the script selecting the clear designation menu so all you need to do is just hit enter after running the script... but also click on the header of the window of DF as any mouse support will mess with the cursor placement.
also here's the current attempt at modifying warmist's tofort script with viewscreen switching
hereshould be warned it's unstable to a degree so far in my testing it's possible to at least build on just about any site and any scripts that un-residents the whole town would be advised to be used.
like this one
function DeresidentCiv(unit,trgunit)
local adv=df.global.world.units.active[0].civ_id
for k,v in pairs(df.global.world.units.active) do
if v.civ_id==adv then
if v== nil then
error("Invalid creature")
end
v.flags2.resident=false
end
end
return true
end
edit edit: ok so I ended up making two different versions of warmist's tofort(well 8ish this one is 6.0) and this one has the accidental mechanic of letting you keep access to your fort's military and squad while you explore the world in adv mode and switch back into fort mode, setting up means to do Squad level attack commands if you brought along your fort military on the trip or lets you enlist folks on site and command them to fight.
-- changes from advmode to fort safely and back (hopefully)
--this version of warmist's tofort works really well going from fort mode to adv mode as you gain access to the fort's military
if df.global.gamemode==df.game_mode.ADVENTURE then
local adv=df.global.world.units.active[0]
local ui=df.global.ui
function advGlobalPos()
local wd=df.global.world.world_data
return wd.adv_region_x*16+wd.adv_emb_x,wd.adv_region_y*16+wd.adv_emb_y
end
function inSite()
local tx,ty=advGlobalPos()
for k,v in pairs(df.global.world.world_data.sites) do
local tp2={v.global_min_x, v.global_min_y, v.global_max_x, v.global_max_y}
if tx>=tp2[1] and tx<=tp2[3] and
ty>=tp2[2] and ty<=tp2[4] then
return v
end
end
end
local site=inSite()
if site==nil then
qerror("No site you are in found.")
end
local h_ent
if ui.main.fortress_entity==nil then
for k,v in pairs(df.global.world.entities.all) do
if v.type==df.historical_entity_type.SiteGovernment then --maybe match race too?
h_ent=v
break
end
end
if h_ent==nil then
qerror("Valid historical entity not found. sorry...")
end
ui.main.fortress_entity=h_ent
else
h_ent=ui.main.fortress_entity
end
function addToEntity(entity,unit,addtoLead)
local nem=dfhack.units.getNemesis(unit)
local hfig=nem.figure
hfig.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=entity.id,link_strength=100})
entity.nemesis_ids:insert("#",nem.id)
entity.nemesis:insert("#",nem)
entity.histfig_ids:insert("#",hfig.id)
entity.hist_figures:insert("#",hfig)
if addtoLead then
local lead_id
for k,v in pairs(entity.positions.own) do
if v.flags.IS_LEADER==true then
lead_id=v.id
break
end
end
if lead_id~=nil then
for k,v in pairs(entity.positions.assignments) do
if v.position_id==lead_id then
v.histfig=hfig.id
break
end
end
end
end
end
ui.civ_id=adv.civ_id
ui.race_id=adv.race
--[[for kui,vra in pairs(ui.unk_races) do
if vra~=nil then
print=("hey does this work")
vra:insert("#", ui.race_id)
--df.global.ui.unk_races:insert("#",adv.race)
else
break
end
end]]--
ui.unk_races:insert("#",adv.race)
ui.site_id=site.id
if ui.main.fortress_site==nil then ui.main.fortress_site=site end
if site.entity_links==nil then site.entity_links:insert("#", {new=true, df.entity_site_link, target=site.id, entity_id=ui.fortress_entity.id}) end
ui.group_id=h_ent.id
ui.game_state=2
addToEntity(h_ent,adv,true)
if #ui.alerts.list==0 then
ui.alerts.list:insert("#",{new=true,name="Dummy alert"})
ui.alerts.next_id=1
end
--fix training info
if h_ent.training_knowledge == nil then
h_ent.training_knowledge={new=true}
end
df.global.gamemode=df.game_mode.DWARF
df.global.gametype=df.game_type.DWARF_MAIN
if df.global.gview.view.child.child==nil then df.global.gview.view.child=df.viewscreen_dwarfmodest:new()
df.global.gview.view.child.parent=df.global.gview.view
end
print("Mode change complete. Now save and load")
else
local adv=dfhack.gui.getSelectedUnit(true)
if adv then
--swap units...
end
df.global.gamemode=df.game_mode.ADVENTURE
df.global.gametype=df.game_type.ADVENTURE_MAIN
df.global.gview.view.child=df.viewscreen_dungeonmodest:new()
df.global.gview.view.child.parent=df.global.gview.view
print("Mode change complete. Now save and load")
end
-- changes from advmode to fort safely and back (hopefully)
if df.global.gamemode==df.game_mode.ADVENTURE then
local adv=df.global.world.units.active[0]
local ui=df.global.ui
function advGlobalPos()
local wd=df.global.world.world_data
return wd.adv_region_x*16+wd.adv_emb_x,wd.adv_region_y*16+wd.adv_emb_y
end
function inSite()
local tx,ty=advGlobalPos()
for k,v in pairs(df.global.world.world_data.sites) do
local tp2={v.global_min_x, v.global_min_y, v.global_max_x, v.global_max_y}
if tx>=tp2[1] and tx<=tp2[3] and
ty>=tp2[2] and ty<=tp2[4] then
return v
end
end
end
local site=inSite()
if site==nil then
qerror("No site you are in found.")
end
local h_ent
if ui.main.fortress_entity~=nil or ui.main.fortress_site~=nil then
ui.main.fortress_entity=nil
ui.main.fortress_site=nil
end
if ui.main.fortress_entity==nil then
for k,v in pairs(df.global.world.entities.all) do
if v.type==df.historical_entity_type.SiteGovernment then --maybe match race too?
h_ent=v
break
end
end
if h_ent==nil then
qerror("Valid historical entity not found. sorry...")
end
ui.main.fortress_entity=h_ent
else
h_ent=ui.main.fortress_entity
end
function cleardesignate(adv)
local adv=df.global.world.units.active[0]
df.global.ui.main.mode=10
df.global.selection_rect.start_x=0
df.global.selection_rect.start_y=0
df.global.selection_rect.start_z=610
df.global.selection_rect.end_x=-14300
df.global.selection_rect.end_y=9000
df.global.selection_rect.end_z=0
df.global.cursor.x=400
df.global.cursor.y=400
df.global.cursor.z=0
dfhack.gui.getCurViewscreen():feed_key(1)
df.global.cursor.x=adv.pos.x
df.global.cursor.y=adv.pos.y
df.global.cursor.z=adv.pos.z
dfhack.gui.getCurViewscreen():feed_key(1)
dfhack.run_command('revflood')
end
function addToEntity(entity,unit,addtoLead)
local nem=dfhack.units.getNemesis(unit)
local hfig=nem.figure
hfig.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=entity.id,link_strength=100})
entity.nemesis_ids:insert("#",nem.id)
entity.nemesis:insert("#",nem)
entity.histfig_ids:insert("#",hfig.id)
entity.hist_figures:insert("#",hfig)
if addtoLead then
local lead_id
for k,v in pairs(entity.positions.own) do
if v.flags.IS_LEADER==true then
lead_id=v.id
break
end
end
if lead_id~=nil then
for k,v in pairs(entity.positions.assignments) do
if v.position_id==lead_id then
v.histfig=hfig.id
break
end
end
end
end
end
ui.civ_id=adv.civ_id
ui.race_id=adv.race
df.global.pause_state=true
ui.unk_races:insert("#",adv.race)
ui.site_id=site.id
if ui.main.fortress_site==nil then ui.main.fortress_site=site end
if site.entity_links==nil then site.entity_links:insert("#", {new=true, df.entity_site_link, target=site.id, entity_id=ui.fortress_entity.id}) end
ui.group_id=h_ent.id
ui.game_state=2
addToEntity(h_ent,adv,true)
if #ui.alerts.list==0 then
ui.alerts.list:insert("#",{new=true,name="Dummy alert"})
ui.alerts.next_id=1
end
--fix training info
if h_ent.training_knowledge == nil then
h_ent.training_knowledge={new=true}
end
df.global.gamemode=df.game_mode.DWARF
df.global.gametype=df.game_type.DWARF_MAIN
if df.global.gview.view.child.child==nil then df.global.gview.view.child=df.viewscreen_dwarfmodest:new()
df.global.gview.view.child.parent=df.global.gview.view
end
cleardesignate()
print("Mode change complete. Now save and load")
else
local adv=dfhack.gui.getSelectedUnit(true)
if adv then
--swap units...
end
df.global.gamemode=df.game_mode.ADVENTURE
df.global.gametype=df.game_type.ADVENTURE_MAIN
df.global.gview.view.child=df.viewscreen_dungeonmodest:new()
df.global.gview.view.child.parent=df.global.gview.view
print("Mode change complete. Now save and load")
end
-- changes from advmode to fort safely and back (hopefully)
if df.global.gamemode==df.game_mode.ADVENTURE then
local adv=df.global.world.units.active[0]
local ui=df.global.ui
function advGlobalPos()
local wd=df.global.world.world_data
return wd.adv_region_x*16+wd.adv_emb_x,wd.adv_region_y*16+wd.adv_emb_y
end
--[[function inSite()
local tx,ty=advGlobalPos()
for k,v in pairs(df.global.world.world_data.sites) do
local tp={v.pos.x,v.pos.y}
if tx>=tp[1]*16+v.rgn_min_x and tx<=tp[1]*16+v.rgn_max_x and
ty>=tp[2]*16+v.rgn_min_y and ty<=tp[2]*16+v.rgn_max_y then
return v
end
end
end]]--
function inSite()
local tx,ty=advGlobalPos()
for k,v in pairs(df.global.world.world_data.sites) do
local tp2={v.global_min_x, v.global_min_y, v.global_max_x, v.global_max_y}
if tx>=tp2[1] and tx<=tp2[3] and
ty>=tp2[2] and ty<=tp2[4] then
return v
end
end
end
local site=inSite()
if site==nil then
qerror("No site you are in found.")
end
local h_ent
if ui.main.fortress_entity~=nil or ui.main.fortress_site~=nil then
ui.main.fortress_entity=nil
ui.main.fortress_site=nil
end
if ui.main.fortress_entity==nil then
for k,v in pairs(df.global.world.entities.all) do
if v.type==df.historical_entity_type.SiteGovernment then --maybe match race too?
h_ent=v
break
end
end
if h_ent==nil then
qerror("Valid historical entity not found. sorry...")
end
ui.main.fortress_entity=h_ent
else
h_ent=ui.main.fortress_entity
end
function cleardesignate(adv)
local adv=df.global.world.units.active[0]
df.global.ui.main.mode=10
df.global.selection_rect.start_x=0
df.global.selection_rect.start_y=0
df.global.selection_rect.start_z=610
df.global.selection_rect.end_x=-14300
df.global.selection_rect.end_y=9000
df.global.selection_rect.end_z=0
df.global.cursor.x=400
df.global.cursor.y=400
df.global.cursor.z=0
dfhack.gui.getCurViewscreen():feed_key(1)
df.global.cursor.x=adv.pos.x
df.global.cursor.y=adv.pos.y
df.global.cursor.z=adv.pos.z
dfhack.gui.getCurViewscreen():feed_key(1)
dfhack.run_command('revflood')
end
function addToEntity(entity,unit,addtoLead)
local nem=dfhack.units.getNemesis(unit)
local hfig=nem.figure
hfig.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=entity.id,link_strength=100})
entity.nemesis_ids:insert("#",nem.id)
entity.nemesis:insert("#",nem)
entity.histfig_ids:insert("#",hfig.id)
entity.hist_figures:insert("#",hfig)
if addtoLead then
local lead_id
for k,v in pairs(entity.positions.own) do
if v.flags.IS_LEADER==true then
lead_id=v.id
break
end
end
if lead_id~=nil then
for k,v in pairs(entity.positions.assignments) do
if v.position_id==lead_id then
v.histfig=hfig.id
break
end
end
end
end
end
ui.civ_id=adv.civ_id
ui.race_id=adv.race
--[[for kui,vra in pairs(ui.unk_races) do
if vra~=nil then
print=("hey does this work")
vra:insert("#", ui.race_id)
--df.global.ui.unk_races:insert("#",adv.race)
else
break
end
end]]--
df.global.pause_state=true
ui.unk_races:insert("#",adv.race)
--if ui.unk_races==0 then ui.unk_races:insert("#",adv.race) end
ui.site_id=site.id
if ui.main.fortress_site==nil then ui.main.fortress_site=site end
--if site.entity_links==nil then site.entity_links:insert("#", {new=true, df.entity_site_link, target=site.id, entity_id=ui.fortress_entity.id, flags[0]=true, flags[5]=true }) end end
if site.entity_links==nil then site.entity_links:insert("#", {new=true, df.entity_site_link, target=site.id, entity_id=ui.fortress_entity.id,entity_site_link_flags.residence, entity_site_link_flags.trade_partner }) end
--if site.entity_links==nil then site.entity_links:insert("#", {new=true, df.entity_site_link, target=site.id, entity_id=ui.fortress_entity.id}) end
ui.group_id=h_ent.id
ui.game_state=2
addToEntity(h_ent,adv,true)
if #ui.alerts.list==0 then
ui.alerts.list:insert("#",{new=true,name="Dummy alert"})
ui.alerts.next_id=1
end
--fix training info
if h_ent.training_knowledge == nil then
h_ent.training_knowledge={new=true}
end
df.global.gamemode=df.game_mode.DWARF
df.global.gametype=df.game_type.DWARF_MAIN
if df.global.gview.view.child.child==nil then df.global.gview.view.child=df.viewscreen_dwarfmodest:new()
df.global.gview.view.child.parent=df.global.gview.view
end
cleardesignate()
print("Mode change complete. Now save and load")
else
local adv=dfhack.gui.getSelectedUnit(true)
if adv then
--swap units...
end
df.global.gamemode=df.game_mode.ADVENTURE
df.global.gametype=df.game_type.ADVENTURE_MAIN
df.global.gview.view.child=df.viewscreen_dungeonmodest:new()
df.global.gview.view.child.parent=df.global.gview.view
print("Mode change complete. Now save and load")
end
this is still a work in progress as it's potential to say lose progress or crash, or accidentally maroon your citizens in locations.
edit: ok so after some time I think I got most of my concerns with switching between fort mode and adv mode and now probably don't need to run a bunch of extra scripts after running the modified tofort script warmist made
which I updated and added under the title tofort7.lua so all you really need is for going from fort mode to adv mode is that you assign an adventurer first using any bodyswap script.
edit: ok so uhh went and added another additional tofort modification called tofort8.