ok so got around to finishing testing the latest version of the 'tofort for player forts only' script called topfort.
so far going from fort mode to adv mode would work, though probably best to make the player fort size around 3x3 until the day I/someone figures out how to adjust the size of the mapedge borders for the site size.
while I might say this version of warmist script is more stable than the previous one it still has some stuff that I probably missed in testing and some bugs that might come up during modded gameplay... or drinking in taverns.
-- changes from advmode to fort safely and back (hopefully) uhh this is version 6 of the alternate tofort script warmist made I been modifying called topfort
-- this version of the script is made for players to jump into their old player forts from adv mode as an alternative means to retiring... so far
-- this method of unretiring doesn't spill the fort's supply of goods...
-- oh yeah be careful on swapping around different player forts or going back to an old Player fort after making a new one as the game doesn't clear mapedge between game modes when retiring
-- so data in fort mode might be stored if retired in adv mode and vice versa
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_entity.site_links[0].target~=inSite().id then
for k,v in pairs(df.global.world.entities.all) do
if v.type==df.historical_entity_type.SiteGovernment and v.site_links[0].target==inSite().id 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
local carter={}
function addToEntity(entity,unit,addtoLead)
local nem=dfhack.units.getNemesis(unit)
local hfig=nem.figure
for k,v in pairs(hfig.entity_links) do
if v.entity_id==entity.id then break else
carter=true
end
end
if carter==true then
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)
end
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
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
ui.civ_id=adv.civ_id
ui.race_id=adv.race
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 or ui.main.fortress_site.id~=ui.site_id then ui.main.fortress_site=site end
--if ui.main.fortress_site==nil or ui.main.fortress_site~=site or ui.main.fortress_site.id~=ui.site_id 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}) end
ui.group_id=h_ent.id
ui.game_state=2
local nem2=dfhack.units.getNemesis(adv)
local hfig2=nem2.figure
local nomad2=hfig2.entity_links[0]
local nomad3=hfig2.entity_links
local Test={}
for co2,mp2 in pairs(nomad3) do
--print(mp2.entity_id,h_ent.id)
if mp2.entity_id~=h_ent.id then Test=true else
Test=false
end
end
if Test==true then
addToEntity(h_ent,adv,false)
end
for co,mp in pairs(df.global.world.units.active) do
if mp.population_id==h_ent.id then
mp.flags2.resident=false
end
if mp.civ_id==h_ent.id or adv.civ_id==mp.civ_id then
mp.flags2.resident=false
end
if mp.relationship_ids.GroupLeader==adv.id then
local comp=mp
if test==true then
addToEntity(h_ent,comp,false)
end
end
end
function filleco(tbl,low,high)
for v =low, high do
tbl.general_items:insert("#",2)
end
tbl.weapons:insert("#",2)
tbl.armor:insert("#",2)
tbl.handwear:insert("#",2)
tbl.footwear:insert("#",2)
tbl.legwear:insert("#",2)
tbl.headwear:insert("#",2)
tbl.prepared_food:insert("#",2)
tbl.wood:insert("#",2)
tbl.thread_cloth:insert("#",2)
tbl.paper:insert("#",2)
tbl.parchment:insert("#",2)
tbl.bone:insert("#",2)
tbl.tooth:insert("#",2)
tbl.horn:insert("#",2)
tbl.pearl:insert("#",2)
tbl.shell:insert("#",2)
tbl.leather:insert("#",2)
tbl.silk:insert("#",2)
tbl.yarn:insert("#",2)
tbl.inorganic:insert("#",2)
tbl.meat:insert("#",2)
tbl.fish:insert("#",2)
tbl.plants:insert("#",2)
tbl.drinks:insert("#",2)
tbl.extract_animal:insert("#",2)
tbl.mill_animal:insert("#",2)
tbl.cheese_animal:insert("#",2)
tbl.extract_plant:insert("#",2)
tbl.mill_plant:insert("#",2)
tbl.cheese_plant:insert("#",2)
tbl.pets:insert("#",2)
end
function filleco2(tbl,low,high)
for v =low, high do
--tbl[v].unk1=site.pos.x
--tbl.unk1:insert("#",site.pos.x)
--tbl.unk2:insert("#",site.pos.y)
tbl.general_items:insert("#",nil)
--tbl[v].unk2=site.pos.y
end
tbl.weapons:insert("#",nil)
tbl.armor:insert("#",nil)
tbl.handwear:insert("#",nil)
tbl.footwear:insert("#",nil)
tbl.legwear:insert("#",nil)
tbl.headwear:insert("#",nil)
tbl.prepared_food:insert("#",nil)
tbl.wood:insert("#",nil)
tbl.thread_cloth:insert("#",nil)
tbl.paper:insert("#",nil)
tbl.parchment:insert("#",nil)
tbl.bone:insert("#",nil)
tbl.tooth:insert("#",nil)
tbl.horn:insert("#",nil)
tbl.pearl:insert("#",nil)
tbl.shell:insert("#",nil)
tbl.leather:insert("#",nil)
tbl.silk:insert("#",nil)
tbl.yarn:insert("#",nil)
tbl.inorganic:insert("#",nil)
tbl.meat:insert("#",nil)
tbl.fish:insert("#",nil)
tbl.plants:insert("#",nil)
tbl.drinks:insert("#",nil)
tbl.extract_animal:insert("#",nil)
tbl.mill_animal:insert("#",nil)
tbl.cheese_animal:insert("#",nil)
tbl.extract_plant:insert("#",nil)
tbl.mill_plant:insert("#",nil)
tbl.cheese_plant:insert("#",nil)
tbl.pets:insert("#",nil)
end
function fill(tbl,low,high)
for v =low, high do
tbl:insert("#",0)
tbl:insert("#",v)
tbl:insert("#",143)
tbl:insert("#",v)
end
end
function fill2(tbl,low,high)
for v =low, high do
tbl:insert("#",v)
tbl:insert("#",143)
tbl:insert("#",v)
tbl:insert("#",0)
end
end
function fillz(tbl,low,high)
for v =low, high do
tbl:insert("#",adv.pos.z)
tbl:insert("#",adv.pos.z)
tbl:insert("#",adv.pos.z)
tbl:insert("#",adv.pos.z)
end
end
function fillunk(tbl,low,high)
for v =low, high do
tbl[v].unk1=site.pos.x
tbl[v].unk2=site.pos.y
end
end
function fillanimal(tbl,low,high)
for v =low, high do
tbl:insert("#",1)
end
end
function fillstone(tbl,low,high)
for v =low, high do
tbl:insert("#",0)
end
end
function mapcheck2()
fill(df.global.ui.unk_mapedge_x,0,143)
fill2(df.global.ui.unk_mapedge_y,0,143)
fillz(df.global.ui.unk_mapedge_z,0,143)
fill(df.global.ui.map_edge.surface_x,0,143)
fill2(df.global.ui.map_edge.surface_y,0,143)
fillz(df.global.ui.map_edge.surface_z,0,143)
for _,Lay in pairs(df.global.ui.map_edge.layer_x) do
fill(Lay,0,143)
end
for _,Lay in pairs(df.global.ui.map_edge.layer_y) do
fill2(Lay,0,143)
end
for _,Lay in pairs(df.global.ui.map_edge.layer_z) do
fillz(Lay,0,143)
end
end
function sigh()
mapcheck()
mapcheck2()
for k,v in pairs(df.global.ui.unk_mapedge_x) do
end
for k,v in pairs(df.global.ui.map_edge.surface_z) do
df.global.ui.map_edge.surface_z[k]=adv.pos.z
--v=152
end
end
function mapcheck()
fillunk(df.global.ui.unk2a8c[0],0,143)
fillunk(df.global.ui.unk2a8c[1],0,143)
fillunk(df.global.ui.unk2a8c[2],0,143)
fillunk(df.global.ui.unk2a8c[3],0,143)
end
Tab={}
Tab2={}
for k,Lay2 in pairs(df.global.ui.map_edge.layer_z) do
for k2,Lay3 in pairs(df.global.ui.unk2a8c[0]) do
if k then break else
Tab:insert("#",k)
end
Tab2:insert("#",k2)
return Tab,Tab2
end
end
if #df.global.ui.map_edge.layer_z[0] == 0 then
print("map edge empty proceed to fill")
sigh()
else
print("welp map edge currently full")
end
if ui.main.fortress_entity.squads==0 then
for Sqa,Ds in pairs (df.global.world.squads.all) do
if Ds.entity_id==ui.main.fortress_entity.id then
ui.main.fortress_entity.squads:insert("#",{new=true,Ds})
end
end
end
if #ui.tasks.discovered_plants==0 then
for k,Lay2 in ipairs(df.global.world.raws.creatures.all) do
fillanimal(df.global.ui.tasks.discovered_creatures,0,k)
--return k
end
for k,Lay2 in ipairs(df.global.world.raws.creatures.all) do
fillanimal(df.global.ui.tasks.discovered_creature_foods,0,k)
--return k
end
for k,Lay2 in ipairs(df.global.world.raws.plants.all) do
fillanimal(df.global.ui.tasks.discovered_plants,0,k)
--return k
end
for k,Lay2 in ipairs(df.global.world.raws.plants.all) do
fillanimal(df.global.ui.tasks.discovered_plant_foods,0,k)
--return k
end
end
if #ui.alerts.list==0 then
ui.alerts.list:insert("#",{new=true,name="Dummy alert"})
ui.alerts.next_id=1
end
if #ui.kitchen.item_types==0 then
ui.kitchen.item_types:insert("#",0)
ui.kitchen.item_subtypes:insert("#",0)
ui.kitchen.mat_types:insert("#",0)
ui.kitchen.mat_indices:insert("#",0)
ui.kitchen.exc_types:insert("#",0)
end
if #ui.unk_9==0 then
ui.unk_9:insert("#",0)
ui.unk_9:insert("#",0)
ui.unk_10:insert("#",0)
ui.unk_10:insert("#",0)
ui.unk_11:insert("#",0)
ui.unk_11:insert("#",0)
end
if #ui.economic_stone==0 then
for k,Lay2 in ipairs(df.global.world.raws.inorganics) do
fillstone(df.global.ui.economic_stone,0,k)
--return k
end
end
if ui.economy_prices.price_adjustment.general_items==0 then
filleco(df.global.ui.economy_prices.price_adjustment,0,114)
filleco2(df.global.ui.economy_prices.price_setter,0,114)
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(adv)
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
so probably best to use this script in the middle of your fort on the surface first if you're going from adv to fort mode, or you might set the mapedge to the middle of solid rock and soil if you do this underground.
that is if the mapedge is cleared.
and if there is any screw ups with fort mapedges at least there's the z level resetting script I made before.
oh yeah syndromes might linger indefintantly still with this use and probably get fixed on map unload via fast traveling... but doing that might cause you to re-set a bunch of fort settings like locations being not adjusted and some folks not having their beds assigned but this script does seem to make some assigned rooms stick so I don't know if that's due to stored ui data or what.
I probably stick with saving the game in the game mode you started in for sanity safety checks... and beware of important location overlaying your site when switching into the different game mode as it might pick up that site instead.
using adv mode talking and personal actions in fort mode scenarios like convincing some guest their book they been carrying is worth the
exchange for a looted battleaxe from some random keep you visited, or applying a chokehold on someone who ambushed the site leading to someone jumping in to kill them for you.
or convince the local 'agent villian' to join your militia dwarves and send them off on a mission to fight some mercinaries and make bets on if they come back alive or not.
exchange goods with folks that trading prevents you too, like hauling corpses and rotting goods off your lands for charity.
be able to interrogate folks with out need of a crime to pin on them.
explore the world then use the discovered locations as prime invasion targets for your group of hand pick militia of different shapes and sizes and possibly use the event rumor of their arrival to mass rescue the locals of the location to then later convert them into another militia group to kickstart another invasion operation.
set up arenas where winner gets to join the fort and the loser gets to also join the fort just later after you resurrect them.
and many more fort mode scenarios I could possibly think of that could use an adventurer's skill set.
edit: ok after some long period of testing I for sure figure out the issue with caravans.
I would have dump the code here but I already gone past the character limit so instead here's a Github link to both updated versions of Tofort and topfort ... called tofort16 and topfort7.
you probably want to use this for mapedge(and additional ui bonus) clearing though I should warn you run this in adv mode before running the tofort scripts.
so this mostly means switching between fort mode and adv mode is mostly stable.
like I could probably flip between the two and not have to worry about Too much stuff going wrong.
outside of like sending the adventurer on a raid which shuffles the active unit list and makes shifting into adv mode a risk where you could pop into the body of some cavern critter... but that' something that could be avoided with remembering that could happen.