Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 230 231 [232] 233 234 ... 244

Author Topic: DFHack 50.14-r1.1  (Read 875451 times)

Rumrusher

  • Bay Watcher
  • current project : searching...
    • View Profile
Re: DFHack 50.09-r1
« Reply #3465 on: July 07, 2023, 12:49:27 pm »

Spoiler: " gif showcase" (click to show/hide)
Code: (nomadfast.lua) [Select]
--script using warmist spellbook code to make a cheap gui for expanding and contracting a player fort.
-- this script is pretty dangerous in that it reveals the expanded map chunk, and when contracting it culls anyone in that map chunk.
-- so far probably best to use this with the void fort scripts as it allows one to expand and explore the world while keeping your site.
--oh warning if you're about to collapse a map chunk make sure to clear any stockpiles and civ zones you made in that map chunk.
--oh and don't retire unless you're back to the original fort embark size or the game will corrupt that fort and or crash.
--also it will take a while for any results to happen. I have no idea on speeding up the process.
--:edit 7/7/2023 this version of nomad script speeds up the process instantly due to messing with cur_season_ticks
--if you use this for some nomad playstyle best learn how to haul goods across map and burrowing folks.
--as you might lose folks while traveling.
 
local dlg=require("gui.dialogs")

function GoN()
local Site=df.global.plotinfo.main.fortress_site
local Nor=Site.global_min_y-1
Site.global_min_y=Nor
df.global.cur_season_tick=3999
end

function NoN()
local Site=df.global.plotinfo.main.fortress_site
local Nor=Site.global_min_y+1
Site.global_min_y=Nor
df.global.cur_season_tick=3999
end
function GoS()
local Site=df.global.plotinfo.main.fortress_site
local Sor=Site.global_max_y+1
Site.global_max_y=Sor
df.global.cur_season_tick=3999
end
function NoS()
local Site=df.global.plotinfo.main.fortress_site
local Sor=Site.global_max_y-1
Site.global_max_y=Sor
df.global.cur_season_tick=3999
end
function GoE()
local Site=df.global.plotinfo.main.fortress_site
local Eor=Site.global_max_x+1
Site.global_max_x=Eor
df.global.cur_season_tick=3999
end
function NoE()
local Site=df.global.plotinfo.main.fortress_site
local Eor=Site.global_max_x-1
Site.global_max_x=Eor
df.global.cur_season_tick=3999
end
function GoW()
local Site=df.global.plotinfo.main.fortress_site
local Wor=Site.global_min_x-1
Site.global_min_x=Wor
df.global.cur_season_tick=3999
end
function NoW()
local Site=df.global.plotinfo.main.fortress_site
local Wor=Site.global_min_x+1
Site.global_min_x=Wor
df.global.cur_season_tick=3999
end

function Go()
for k,v in pairs(df.global.world.armies.all) do
if v.flags[0]== true  then
local Nor=v.pos.y-1
v.pos.y=Nor
df.global.cur_season_tick=3999
end
end
end
function doNothing()
print("doing nothing real good but here have a site")
--require("plugins.dfusion.adv_tools").addSite(nil,nil,nil,nil,nil,nil,df.global.world.units.active[0].civ_id)
end
function doNothing2()
dlg.showMessage("Travel-Hack","Bypassing Message to access FastTravel")
df.global.ui_advmode.message=""
--require("plugins.dfusion.adv_tools").addSite(nil,nil,nil,nil,nil,nil,df.global.world.units.active[0].civ_id)
end

function greetAndStuff()
dlg.showMessage("Greetings", "Seasons greatings and lols")
end
MOVEMENT_KEYS = {
    A_CARE_MOVE_N = { 0, -1, 0 }, A_CARE_MOVE_S = { 0, 1, 0 },
    A_CARE_MOVE_W = { -1, 0, 0 }, A_CARE_MOVE_E = { 1, 0, 0 },
    A_CARE_MOVE_NW = { -1, -1, 0 }, A_CARE_MOVE_NE = { 1, -1, 0 },
    A_CARE_MOVE_SW = { -1, 1, 0 }, A_CARE_MOVE_SE = { 1, 1, 0 },
    --[[A_MOVE_N = { 0, -1, 0 }, A_MOVE_S = { 0, 1, 0 },
    A_MOVE_W = { -1, 0, 0 }, A_MOVE_E = { 1, 0, 0 },
    A_MOVE_NW = { -1, -1, 0 }, A_MOVE_NE = { 1, -1, 0 },
    A_MOVE_SW = { -1, 1, 0 }, A_MOVE_SE = { 1, 1, 0 },--]]
    A_CUSTOM_CTRL_D = { 0, 0, -1 },
    A_CUSTOM_CTRL_E = { 0, 0, 1 },
    CURSOR_UP_Z_AUX = { 0, 0, 1 }, CURSOR_DOWN_Z_AUX = { 0, 0, -1 },
    A_MOVE_SAME_SQUARE={0,0,0},
    SELECT={0,0,0},
}
ALLOWED_KEYS={
    A_MOVE_N=true,A_MOVE_S=true,A_MOVE_W=true,A_MOVE_E=true,A_MOVE_NW=true,
    A_MOVE_NE=true,A_MOVE_SW=true,A_MOVE_SE=true,A_STANCE=true,SELECT=true,A_MOVE_DOWN_AUX=true,
    A_MOVE_UP_AUX=true,A_LOOK=true,CURSOR_DOWN=true,CURSOR_UP=true,CURSOR_LEFT=true,CURSOR_RIGHT=true,
    CURSOR_UPLEFT=true,CURSOR_UPRIGHT=true,CURSOR_DOWNLEFT=true,CURSOR_DOWNRIGHT=true,A_CLEAR_ANNOUNCEMENTS=true,
    CURSOR_UP_Z=true,CURSOR_DOWN_Z=true,
}

listofspells={
{text="nothing", spell=doNothing,icon='*'},
{text="expand: North+", spell=GoN,key="CUSTOM_W"},
{text="expand: South+", spell=GoS,key="CUSTOM_S"},
{text="expand: East+", spell=GoE,key="CUSTOM_D"},
{text="expand: West+", spell=GoW,key="CUSTOM_A"},
{text="Contract: North-", spell=NoN,key="CUSTOM_T"},
{text="Contract: South-", spell=NoS,key="CUSTOM_G"},
{text="Contract: East-", spell=NoE,key="CUSTOM_H"},
{text="Contract: West-", spell=NoW,key="CUSTOM_F"},
}
 
dlg.showListPrompt("Directions","Choze Direct",nil, listofspells,function(index,choice) choice.spell() end)

ok so here's an updated version of nomad now with less waiting all thanks to cur_season_tick being set to 3999 and letting time progress to 4000
this does mean going through nomad fast might require seeing what happens if you mess with seasonal timers.

also here's an liquids gui edit for future proofing scripts with
the personal keyboard cursor gui script
Spoiler: gif showcase 2 (click to show/hide)

Code: (keyboardcursor.lua) [Select]
--keyboard cursor that uses the widget of gui/liquids as I don't know how to write widgets
--proof of concept for adding an extra keyboard cursor to df50 that doesn't rely on mining tools.

local gui = require('gui')
local guidm = require('gui.dwarfmode')
local widgets = require('gui.widgets')



local SpawnLiquidCursor = {
    [df.tile_liquid.Water] = dfhack.screen.findGraphicsTile('MINING_INDICATORS', 0, 0),
    [df.tile_liquid.Magma] = dfhack.screen.findGraphicsTile('MINING_INDICATORS', 1, 0),
    [df.tiletype.RiverSource] = dfhack.screen.findGraphicsTile('LIQUIDS', 0, 0),
}

SpawnLiquid = defclass(SpawnLiquid, widgets.Window)
SpawnLiquid.ATTRS {
    frame_title='Cursor Keyboard menu',
    frame={b = 4, r = 4, w = 50, h = 12},
}

function SpawnLiquid:init()
    self.type = df.tile_liquid.Water
    self.tile = SpawnLiquidCursor[self.type]

    self:addviews{
        widgets.Label{
            frame = {l = 0, t = 0},
            text = {{ text = self:callback('getLabel') }}
        },
        widgets.HotkeyLabel{
            frame = {l = 0, b = 1},
            label = 'does nothing',
            auto_width = true,
            key = 'KEYBOARD_CURSOR_LEFT',
            on_activate = self:callback('moveleft'),
            disabled = function() return self.level == 1 end
        },
        widgets.HotkeyLabel{
            frame = { l = 19, b = 1},
            label = 'also Does nothing',
            auto_width = true,
            key = 'KEYBOARD_CURSOR_RIGHT',
            on_activate = self:callback('moveright'),
            disabled = function() return self.level == 7 end
        },
        widgets.HotkeyLabel{
            frame = { l = 19, b = 1},
            label = 'also Does nothing',
            auto_width = true,
            key = 'KEYBOARD_CURSOR_UP',
            on_activate = self:callback('moveup'),
            disabled = function() return self.level == 7 end
        },
        widgets.HotkeyLabel{
            frame = { l = 19, b = 1},
            label = 'also Does nothing',
            auto_width = true,
            key = 'KEYBOARD_CURSOR_DOWN',
            on_activate = self:callback('movedown'),
            disabled = function() return self.level == 7 end
        },
        widgets.CycleHotkeyLabel{
            frame = {l = 0, b = 2},
            label = 'cursor color:',
            auto_width = true,
            key = 'CUSTOM_Q',
            options = {
                { label = "Water", value = df.tile_liquid.Water, pen = COLOR_CYAN },
                { label = "Magma", value = df.tile_liquid.Magma, pen = COLOR_RED },
                { label = "River", value = df.tiletype.RiverSource, pen = COLOR_BLUE },
            },
            initial_option = 0,
            on_change = function(new, _)
                self.type = new
                self.tile = SpawnLiquidCursor[new]
            end,
        },
    }
end

-- TODO: More reactive label dependant on options selected.
function SpawnLiquid:getLabel()
    return ([[Click on a tile to spawn a %s/7 level of %s]]):format(
        self.level,
        self.type == 0 and "Water" or self.type == 1 and "Magma" or "River"
    )
end

function SpawnLiquid:getLiquidLevel(position)
    local tile = dfhack.maps.getTileFlags(position)

    if self.mode == SpawnLiquidMode.ADD then
        return math.max(0, math.min(tile.flow_size + self.level, 7))
    elseif self.mode == SpawnLiquidMode.REMOVE then
        return math.max(0, math.min(tile.flow_size - self.level, 7))
    end

    return self.level
end

function SpawnLiquid:increaseLiquidLevel()
    self.level = math.min(self.level + 1, 7)
end

function SpawnLiquid:decreaseLiquidLevel()
    self.level = math.max(self.level - 1, 1)
end
function SpawnLiquid:moveleft()
    local move=df.global.cursor
move.x=move.x-1
end
function SpawnLiquid:moveright()
    local move=df.global.cursor
move.x=move.x+1
end
function SpawnLiquid:moveup()
    local move=df.global.cursor
move.y=move.y-1
end
function SpawnLiquid:movedown()
    local move=df.global.cursor
move.y=move.y+1
end

function SpawnLiquid:spawn(pos)
--local MapCure=df.global.gview.view.child
mouse_pos = dfhack.gui.getMousePos()
df.global.cursor.x=mouse_pos.x
df.global.cursor.y=mouse_pos.y
df.global.cursor.z=mouse_pos.z
end

function SpawnLiquid:getPen()
    return self.type == df.tile_liquid.Water and COLOR_BLUE or COLOR_RED, "X", self.tile
end

function SpawnLiquid:getBounds(start_position, end_position)
    return {
        x1=math.min(start_position.x, end_position.x),
        x2=math.max(start_position.x, end_position.x),
        y1=math.min(start_position.y, end_position.y),
        y2=math.max(start_position.y, end_position.y),
        z1=math.min(start_position.z, end_position.z),
        z2=math.max(start_position.z, end_position.z),
    }
end

function SpawnLiquid:onRenderFrame(dc, rect)
    SpawnLiquid.super.onRenderFrame(self, dc, rect)

    local mouse_pos = dfhack.gui.getMousePos()

    if self.is_dragging then
        if df.global.enabler.mouse_lbut == 0 then
            self.is_dragging = false
        elseif mouse_pos and not self:getMouseFramePos() then
            self:spawn(mouse_pos)
        end
    end

       guidm.renderMapOverlay(self:callback('getPen'), self:getBounds(
  self.area_first_pos or df.global.cursor, df.global.cursor
  ))
end

function SpawnLiquid:onInput(keys)
    if SpawnLiquid.super.onInput(self, keys) then return true end

    if keys._MOUSE_L_DOWN and not self:getMouseFramePos() then
        local mouse_pos = dfhack.gui.getMousePos()
            self:spawn()
end
end

SpawnLiquidScreen = defclass(SpawnLiquidScreen, gui.ZScreen)
SpawnLiquidScreen.ATTRS {
    focus_path = 'spawnliquid',
    pass_movement_keys = true,
    pass_mouse_clicks = false,
    force_pause = true,
}

function SpawnLiquidScreen:init()
    self:addviews{SpawnLiquid{}}
end

function SpawnLiquidScreen:onDismiss()
    view = nil
end

view = view and view:raise() or SpawnLiquidScreen{}:show()

oh and here's a script for telling where you are on the global min x and y coords of the site you're on the info shown is going off the top left corner of the map to the bottom right it probably best to not use this after changing the site's coords as the script looks at the site's current global min and max coords to get the second info from for the folks who dip into gui gm-editoring as their means to nomad around the world.

oh and this only works if the wagon is named Nomad as do most of my nomad scripts as it grabs the wagon's coords to check where it is on the game field embark space wise.
Code: (wagon-sense) [Select]
function wagon(curx,cury,curz)
for de,oe in pairs(df.global.world.buildings.other.WAGON) do
if oe.name == 'Nomad' then

local regionx=math.floor(oe.centerx/47)
local regiony=math.floor(oe.centery/47)
print("X region", regionx,
"Y region", regiony)
local site=df.global.plotinfo.main.fortress_site
print("X region + min", regionx + site.global_min_x,
"Y region + min", regiony + site.global_min_y )

end
end
end

wagon()
I think this is prime for folks to fully explore the worlds with their fort citizens... combine this with that force petition script and you could play out series of oregon trail like sessions.
usually with the nomad scripts
oh and uhh if you leave your starting location and you dig out a bunch of stuff in the process the game will undo any changes you did on a digging and construction wise, buildings are safe though. folks stored in cages that are stored in the wagon will stay in the wagon while you travel around the world.

getting mayors and nobles who like to stay in a room would make nomad playstyle a bit rough as you would be building up and tearing down their rooms while you prep to travel to a new location.
this playstyle does open up to some different challenges one could take on like the no-build run where you just strip mine the land and harvest the fields to trek to one of the dwarven fortress entrances that houses all workshops for you to use.
this also means no trading until you get to a trade depot this challenge is probably more rough if you play it with dwarves as the strange mood would mean ditching the dwarf to avoid the mood hit or dealing with staying at the dwarven fortress entrance longer for hoping to get that artifact built.

I just realize folks could build a magma pump that leads to a tunnel that pours the magma into the ocean to make an island then just settle their group on the island... and probably with a lil extra void fort set up sail the seas on their remote obsidian casts landmass and harvest all the fish from the sea.
Logged
I thought I would I had never hear my daughter's escapades from some boy...
DAMN YOU RUMRUSHER!!!!!!!!
"body swapping and YOU!"
Adventure in baby making!Adv Homes

Bjorn

  • Bay Watcher
    • View Profile
Re: DFHack 50.09-r1
« Reply #3466 on: July 08, 2023, 01:17:21 pm »

Is there any command to forcefully assign a specific noble position to a dwarf? (The current dwarf holding the position can't be removed)
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack 50.09-r1
« Reply #3467 on: July 08, 2023, 03:27:07 pm »

Not an easy command, no. A tool like that is under discussion, though.
Logged

scriver

  • Bay Watcher
  • City streets ain't got much pity
    • View Profile
Re: DFHack 50.09-r1
« Reply #3468 on: July 17, 2023, 03:15:08 am »

DFhack on steam frontpage? :D

Quote
Logged
Love, scriver~

myk

  • Bay Watcher
    • View Profile
Re: DFHack 50.09-r1
« Reply #3469 on: July 17, 2023, 03:16:51 pm »

Thanks for the rec, Putnam!
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack 50.09-r1
« Reply #3470 on: July 18, 2023, 08:57:19 pm »

New unit pasture assignment screen coming in the next DFHack version:


Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack 50.09-r1
« Reply #3471 on: July 22, 2023, 06:49:26 pm »

Logged

0x517A5D

  • Bay Watcher
  • Hex Editor‬‬
    • View Profile
Re: DFHack 50.09-r2
« Reply #3472 on: July 25, 2023, 12:48:11 pm »

Will tubefill be returning anytime soon?

I experimented a bit in Lua, and it looks like the entire pipe, not just the raw adamantine tiles, are now flagged as .local_feature type feature_init_deep_special_tubest .

I don't see a way to tell which already-mined tiles had adamantine.

All the jewels are in map_block.block_events, but the raw adamantine 'vein' isn't.

I'm at a loss.  I'm just hoping someone who knows more can figure it out.
Logged

ab9rf

  • Bay Watcher
    • View Profile
    • ab9rf@github
Re: DFHack 50.09-r1
« Reply #3473 on: July 25, 2023, 01:03:14 pm »

DFhack on steam frontpage? :D

Quote
Steam's "front page" is dynamically generated by Steam for each user, but yes, DFHack is (now) eligible for consideration in that process and so it is possible that Steam's adaptive marketing system will promote DFHack to people that Steam thinks might be interested.
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack 50.09-r2
« Reply #3474 on: July 28, 2023, 01:24:38 am »

I experimented a bit in Lua, and it looks like the entire pipe, not just the raw adamantine tiles, are now flagged as .local_feature type feature_init_deep_special_tubest .

I don't see a way to tell which already-mined tiles had adamantine.

Accurate is preferable, but it might not be terrible to just fill all non-wall deep_special tiles with walls of adamantine. If the player is using tubefill, then they probably won't complain if they get a little extra adamantine.
Logged

0x517A5D

  • Bay Watcher
  • Hex Editor‬‬
    • View Profile
Re: DFHack 50.09-r2
« Reply #3475 on: July 29, 2023, 11:05:42 am »

Proposal for a 99% solution:

The tubefill plugin runs at every map load.

If it hasn't seen the map yet, it inspects and records the locations of all raw adamantine tiles.

This could be recorded as plugin-specific persistent data, or recorded by actually creating the mineral vein definition that really ought to be there in the first place.

When invoked manually, the plugin just uses that list of raw adamantine tiles to recreate the feature.

The only way this fails is the case where mining has already taken place before the tool first analyzes the map.

I would also note that this could be done in a mod Lua script, with the serious downside that the player would need to install and select the mod at world generation time.

I'm kind of tempted to write this as a mod, and figure out how to retrofit it into my current 23-year-old fort.
Logged

myk

  • Bay Watcher
    • View Profile
Re: DFHack 50.09-r2
« Reply #3476 on: July 31, 2023, 07:11:30 am »

I would also note that this could be done in a mod Lua script, with the serious downside that the player would need to install and select the mod at world generation time.

This is something I anticipated, and the downside is no longer a downside. If you put your script in a folder named scripts_modinstalled inside your mod, then DFHack will find and load the script without requiring that the player make the mod "active" in a generated world. If the mod is on the Steam Workshop, DFHack will find the script if the player is subscribed to the mod.

More info at: https://docs.dfhack.org/en/stable/docs/guides/modding-guide.html#dfhack-modding-guide
Logged

Eric Blank

  • Bay Watcher
  • *Remain calm*
    • View Profile
Re: DFHack 50.09-r2
« Reply #3477 on: August 01, 2023, 01:40:56 am »

Is it possible to get a function to read and display wilderness/cavern agitation levels, to say monitor how close you are to attracting agitated wildlife or cavern ambushes?
Logged
I make Spellcrafts!
I have no idea where anything is. I have no idea what anything does. This is not merely a madhouse designed by a madman, but a madhouse designed by many madmen, each with an intense hatred for the previous madman's unique flavour of madness.

A_Curious_Cat

  • Bay Watcher
    • View Profile
Re: DFHack 50.09-r2
« Reply #3478 on: August 01, 2023, 12:29:16 pm »

Is it possible to get a function to read and display wilderness/cavern agitation levels, to say monitor how close you are to attracting agitated wildlife or cavern ambushes?

If I’m reading df.map.xml right, it should be under df.map.feature.irritation_level.  Dividing that by 10K should give the chance of an attack.

Also, @Myk, df.map.xml also says:

Quote from: df.map.xml
<int16_t name='irritation_attacks' comment='maxes at 10?'/>

Does that mean that there can be no more than 10 attacks by agitated creatures at one time?
Logged
Really hoping somebody puts this in their signature.

0x517A5D

  • Bay Watcher
  • Hex Editor‬‬
    • View Profile
Re: DFHack 50.09-r2
« Reply #3479 on: August 01, 2023, 01:33:26 pm »

If I’m reading df.map.xml right, it should be under df.map.feature.irritation_level.  Dividing that by 10K should give the chance of an attack.

Also, @Myk, df.map.xml also says:

Quote from: df.map.xml
<int16_t name='irritation_attacks' comment='maxes at 10?'/>

Does that mean that there can be no more than 10 attacks by agitated creatures at one time?

gui/gm-editor tells me the structure is
    df.global.world.features.map_features[].feature.irritation_level
and
    df.global.world.features.map_features[].feature.irritation_attacks


Is it possible to get a function to read and display wilderness/cavern agitation levels, to say monitor how close you are to attracting agitated wildlife or cavern ambushes?

This horrible one-liner prints (some of) the data for each map feature.  But I don't think it covers the surface.  I don't know at the moment where that data is.  Run from the DFHack prompt.
Code: [Select]
:lua for i,mf in ipairs(df.global.world.features.map_features) do l=-1;pcall(function()l=mf.layer;end);print(string.format("feature %d %s %s-%s underground_region #%d irritation_level %d irritation_attacks %d",i,mf._type,df.layer_type[mf.start_depth],df.layer_type[mf.end_depth],l,mf.feature.irritation_level,mf.feature.irritation_attacks));end;
Sample output:
Code: [Select]
feature 0 <type: feature_init_subterranean_from_layerst> Cavern1-Cavern1 underground_region #11 irritation_level 4008 irritation_attacks 0
feature 1 <type: feature_init_subterranean_from_layerst> Cavern2-Cavern2 underground_region #31 irritation_level 7924 irritation_attacks 0
feature 2 <type: feature_init_subterranean_from_layerst> Cavern3-Cavern3 underground_region #56 irritation_level 11408 irritation_attacks 0
feature 3 <type: feature_init_magma_core_from_layerst> MagmaSea-MagmaSea underground_region #81 irritation_level 3180 irritation_attacks 0
feature 4 <type: feature_init_underworld_from_layerst> Underworld-Underworld underground_region #106 irritation_level 0 irritation_attacks 0
feature 5 <type: feature_init_outdoor_riverst> Surface-Surface underground_region #-1 irritation_level 288 irritation_attacks 0
feature 6 <type: feature_init_subterranean_from_layerst> Cavern1-Cavern1 underground_region #6 irritation_level 1760 irritation_attacks 0
feature 7 <type: feature_init_deep_special_tubest> MagmaSea-Underworld underground_region #-1 irritation_level 20040 irritation_attacks 0
feature 8 <type: feature_init_deep_special_tubest> MagmaSea-Underworld underground_region #-1 irritation_level 0 irritation_attacks 0

Hmm.  Outdoor irritation is kept separate from that, in a variable in plotinfo.
Code: [Select]
:lua print(string.format("outdoor_irritation:%d",df.global.plotinfo.outdoor_irritation))
Sample output:
Code: [Select]
outdoor_irritation:35000
« Last Edit: August 01, 2023, 01:55:23 pm by 0x517A5D »
Logged
Pages: 1 ... 230 231 [232] 233 234 ... 244