Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Anon_404

Pages: [1]
1
DF Dwarf Mode Discussion / Re: What's going on in your fort?
« on: March 07, 2019, 10:54:46 pm »
Fire breathing swampland titan Shows Up... Breathing fire He Kills a recruit and Sets a tree in fire. Tree kills the Titan... Lol...

See! Even Mother Nature hates titans!

2
DF Dwarf Mode Discussion / Re: What's going on in your fort?
« on: March 06, 2019, 06:23:14 pm »
Playing a slow fort game (cap pop set to zero so have to rely on growing naturally or from visitors), had a rather important dwarf take a dive into a underground pool from an isolated wall. Yeah, he promptly drowned.

Long and short, was trying to build around some trees that were based in an underground lake and the one dwarf somehow/for some reason climbed a nearby tree and got himself stuck on top of a pair of isolated walls. While trying to build a staircase up to him through some branches (note: you can build down into branches and from the sides, but the pathing messes up if you try building up into them), the dwarf in question decided that I was taking too long and tried to jump/climb and promptly fell into the water below and drowned :(

Fortunately, his legacy will live on in his two children, so more frustrated at the dwarfs choices rather than the loss.

3
Utilities and 3rd Party Applications / Re: DFHack Job Triggers
« on: February 12, 2019, 10:03:36 pm »
What version of DFHack are you using? and how are you doing this test? I just copied that code into a script and it worked for me. Where do you set what enabled is?

Using DFHack 0.44.12-r2.

The enabled script is a tidbit that I should have removed, sorry.

Also, apparently functions do not like being called multiple times while previous iterations are running. I had been making changes to the code and re-running it without exiting DF between attempts, so there must have been hold-overs that didn't like me doing that. Bad habit and lack of foresight.

Thanks for the help and enjoy the laugh.

4
Utilities and 3rd Party Applications / Re: DFHack Job Triggers
« on: February 12, 2019, 07:49:20 pm »
Really out of my depth when it comes to trying to use environment functions and having a hard timing understanding what I am doing wrong compared to what others have done. For example, the current problem I am having is that the below code throws an error saying "attempt to index a function (field 'onJobInitiated')
Code: [Select]
local ev=require 'plugins.eventful'

ev.onJobInitiated.test = function(JOB)
if enabled then
print("Job started!")
end
end

ev.enableEvent(ev.eventType.JOB_INITIATED, 0)

According to examples such as item-trigger.lua, innteraction-trigger.lua, etc there should be something there, but I do not understand what the rules are or what I am missing (removing the .test causes it to run without error but it does not seem to recognize when new jobs are started).

Any help would be appreciated.

5
Utilities and 3rd Party Applications / Re: DFHack Job Triggers
« on: February 10, 2019, 02:47:33 pm »
https://dfhack.readthedocs.io/en/stable/docs/Lua%20API.html#eventful


There is already an event manager trigger for onJobInitiated and onJobCompleted. For examples of other scripts that use the event manager triggers you can look at modtools/interaction-trigger and modtools/item-trigger

EDIT: Both of which are lua scripts

Thank you. That is exactly what I was looking for. Didn't see those used in any of the built in-scripts and wasn't sure where else to look. Will give it a few tries and see what I can do with it.

6
Utilities and 3rd Party Applications / DFHack Job Triggers
« on: February 09, 2019, 06:34:10 pm »
Was curious if there are any options for having a lua-script be triggered when certain jobs are completed. Basically, looking for something like the dfhack.onStateChange but for jobs. Alternatively, if there is any way of triggering for lua-scripts when the job_next_id advances.

As I currently understand it, there are two options:
1.) Have a lua-script with a dfhack.timeout of 1 "frames" and have it check the existing job list for the job_type in question. My concern here is that this could be process intensive as it would be checking the job list every frame.

2.) Use a Ruby script similar to autounsuspend.rb which appears to check the job list for suspended buildings before unsuspending them if they meet certain criteria. (Seems to use df.onupdate_register as a trigger but not sure if it works with lua code)

Open to suggestions or thoughts on the matter.

Troll question: is Ruby superior to Lua or is this just a case of me being dumb?

7
DF Modding / Re: Converting "wild animals" to "guests"
« on: May 16, 2018, 08:02:10 pm »
You have to assign it the next histfig ID in line and set up a bunch of references. Check out the create-unit.lua script included with DFHack; it should contain the code you need.

Thank you, the create-unit.lua does appear to have exactly what I'm looking for (in particular hist_figure_next_id).

Hopefully shouldn't have to mess around with it too much.

8
DF Modding / Re: Converting "wild animals" to "guests"
« on: May 15, 2018, 06:12:53 pm »
Think I found the cause: the lack of a proper historical_figure id (-1) appeared to be causing the crash as changing it to any value (999 for example) will name the unit and display why they are there (such as "traveler"). My main concern now is how to check if a historical_figure id is already in use.

Any thoughts?

9
DF Modding / Converting "wild animals" to "guests"
« on: May 13, 2018, 05:20:48 pm »
Been trying to figure out what tags are needed to convert a "wild animal" such as a gorlak or other "can_learn" to a guest to allow for the citizenship path. So far, I know that flag2:visitor will convert the unit into a friendly unit but will label it as a "visitor". Setting flag3:unk31 to true will display the unit as being a "Guest" and will display it's current activity (typically "No activity"). However, trying to "Zoom to unit" on the new guest or "View Units" them crashes the game.

Any thoughts on what the cause could be and how or if it could be fixed? (Error logs have been thoroughly unhelpful)

10
DF Dwarf Mode Discussion / Re: What's going on in your fort?
« on: May 06, 2018, 12:39:59 pm »
In the latest fort that I've been running where I'm trying to get it to grown naturally from 20 dwarves, had the most annoying forgotten beast to date: a winged toad with a poisonous bite and warty skin[or sting can't recall].

This is not that difficult of a forgotten beast and the containment measures worked (double bridges were closed so the thing was trapped). The problem is that I spent the good part of a year in-game shooting it with a combination of bone (yeah, I know) and iron bolts and it showed no signs of dying :( So I decided to get a bit more creative. A long trained giant cave spider was released into the archer gallery to spray the annoying pest with webs since the flooring was covered with cage traps; easy capture right? Except the pest was not moving and despite the prodigious webs everywhere, none of the traps were activating.

Okay, fine. I'll open the bridges and then it'll move, get stuck and promptly caught, right? No :/ The pest refused to budge until a dwarf accidentally open the door he was sitting in front of. The dwarf survived but the door was now stuck open (dropped item) and the pest was in no hurry to move. At some point another dwarf tried to get past to do god knows what, got attacked and promptly got themselves caged. Not too bad, since nobodies died yet (leads to an inevitable boatload of caged dwarves, but that's an aside). Containment fails as the pest finally decides to move around, and somehow avoids getting caged. Time for the close quarters military right?

Except this is DF remember, and getting squads to move exactly where you want them to is not easy. One of my spearmasters gets ahead of everyone of goes charging (without orders) into the bolt covered pest .... and promptly starts bashing it with his shield and kicking it. Despite being equipped with a spear and trained with it, the dwarf in question decided his best weapon was his natural weapons (he actually bit the pest o.O ) and his shield. Despite lasting much longer than I thought he would, he still ultimately took a hit to his head that crushed it despite his steel helm. In that time, the rest of the militia was busy gathering provisions and sleep for the long run down the stairs to the location.

The pest got itself cornered in a side room and hunkered down. After months of trying to gather enough of the militia in one spot for an assault, I got tired and order the two dwarves who were there to attack: one promptly walked off to gather provisions again and the other one crawled his way towards his foe. Yes, the one dwarf who decided he was ready to fight had lost the ability to stand from a previous military mishap. Said dwarf crawled his way to the beast and successfully stabbed the thing to death. He promptly named his spear. -_- When the cripple is smarter and fights better than your uninjured compartiots, you know you have a problem.

11
Updated the code to fix the issue with it still running after the cap limit has been reached. It should default back to the standard Migrant event triggers (namely, no more migrants).

Also, as it has been indirectly pointed out, the code makes the incorrect assumption that fortress wealth is a good indicator of population level. This is not true as the hypothetical situation of a large loss of population (via siege, etc) does not necessarily mean a loss of wealth. With that in mind, I changed the code for calculating the wealth ratio to the below:
Code: [Select]
local wRatio = 10000 * (math.floor(ui.fortress_age/40320) + ui_stats.total_deaths + 1)
This means that as a fort gets older (in years) the wealth required to generate additional migrants beyond the base wave of 2 gets higher. Furthermore, dwarven combat deaths (presumably only, as insanities and executions are recorded in a separate variable) will increase this ratio much faster. Thus a 100 dwarf massacre will force the ratio up 100 times. This makes the minimum replacement wealth 200 million at least (100 million for 100 dwarves remaining, 100 million to generate 100 dwarves). This should solve or limit any late-game issues regarding massive replacement migrant waves.

12
Twice your population means you could get waves of 100's later in game

Allow me to rephrase, it is capped at twice. The wave number cannot go higher than that. In order to get a 100 migrant wave, you would have to have a total wealth and exported wealth of over 2 million (1 million would satisfy the current population of 100, 1 million would allow for the extra 100).

As an aside, anyone know if the Migrants timed_event still gets called after the population cap gets reached? Because my code does not take that into account :(

13
You can change the pop cap after each migrant wave. Sure, it requires saving/exiting/change pop cap/start DF/load/continue, but not that many times. When I don't play dead civs I change the pop cap to current pop + 10. I don't know if you can change the pop can dynamically and have it take effect, but if it did, it would probably be a better script basis.

you can also adjust it at df.global.d_init.population_cap; in my experience init stuff, including such things as colors, can be edited at runtime and work as expected, but that's not a particularly good assumption and testing should be carried out

Tried changing df.global.d_init.population_cap while the game was running and found that it had no effect on migrant waves. Additionally, using the force-migrants command is not a good indicator as it can either display "Fortress attracted no migrants" or generate a migrant wave of 7. (Believe this only happens if called multiple times in the same season)

Quote
create-unit might be making crashy dwarves, this script technically increases your population exponentially so actually makes population growth much faster past the early game

What part of the code makes the population expand exponentially? The number of new dwarves has a max value of twice your population, a minimum value of 4, and outside of the random number generator for 0-3 the only growth aspect is with relation to how much value you have created. (ie: 100k total wealth and exports allows for a whopping 10 total supported dwarves; this is including your current population, and the base 4 migrant wave).

Any tips on particular log files that might help identify if it is crashing because of the create-unit call?

14
Utilities and 3rd Party Applications / Script: Migrants Replacement
« on: March 21, 2018, 06:51:57 pm »
Just wanted to drop this script off for anyone interested.

Haven't played DF for long, but one thing which bothered me was the extremely high rate of migrants that seemed to come to forts (particularly if you weren't ready for them). Between the alternatives of either trying to roll with groups of 20+ migrants or modding the population cap such that you were reliant on natural growth, neither appeals to me. Playing without migrants gets tedious as you can/will expand so much faster than your population. Not to mention it starts to feel weird breathing heavily at your screen demanding that your dwarves "breed already!" Hence my short-term quest to build a script to replace the in-game migrant waves.

Please note that I am not experienced with Lua-scripting or coding in general. (Translation: the code looks like garbage, but I have tested it and it seems to work.) Also, it makes use of Milo's announce.lua script (see http://www.bay12forums.com/smf/index.php?topic=137011.msg5076999#msg5076999)

See code below:
migrantsreplace.lua --Updated 2018-03-26
Code: [Select]
-- Last edited: 2018-03-24
-- Anon_404
-- Made for use with DFhack 0.44.05-r1

--[[This is a basic script that is meant to be used with the "enable"/"disable" commands.

What it does is test regularly for the Migrants timed_event. Once the event comes close to occuring, it erases the event and triggers a new
set of code to replace the incoming migrants. The new code is meant to provide easier control over the number of migrants coming (seeing as
 previous tests to do so have failed; changing df.global.ui.tasks.wealth appears to have no effect)
 
 Current issues/limitations:
 - only produces peasants (completely unskilled)
 - does not account for or include generating domesticated animals (you will have to buy them)
 - on test map, some dwarfs would spawn underground in water :s (workaround: test for outside)[Fixed?]
 - concern: how will the game react to 20 units spawning in one location?
 - unsure if related but DF has appeared to crash while running this script
]]

local args = {...}
-- Code ripped from emigration.lua
if args[1] == "enable" then
    enabled = true
elseif args[1] == "disable" then
    enabled = false
end
----------------------------------
-- Code ripped from population-cap.lua
local ui = df.global.ui
local ui_stats = ui.tasks
local civ = df.historical_entity.find(ui.civ_id)
----------------------------------

local event = df.global.timed_events
local CAP = df.global.d_init.population_cap

----------------------------------
-- This is a basic function for finding and removing the programmed migrant wave just before it occurs.
function migrantsReplace()
local N = #event
if N > 0 and ui_stats.migrant_wave_idx < 2 and ui_stats.population <= CAP then --if there is an event to be had AND if the event is supposed to create migrants AND population is less than cap
-- Note on following line: unsure of how close season_tick + 200 will bring the event to the timeout period of 1 day
if event[0].type == df.timed_event_type.Migrants and event[0].season == df.global.cur_season and event[0].season_ticks <= df.global.cur_season_tick + 200 then
event:erase(0)
print("Migrants replaced")
new_migrants()
df.global.pause_state = true
dfhack.run_command('announce "Migrants have arrived."')  --attempt to call 3rd party announce.lua
end
end
print("Monitoring")

end

-- This is the code to create new migrants using modtools/create-unit
function new_migrants()
-- This code is meant to determine how many migrants will appear. Attempting to have it linked to relative wealth of the fortress.
math.randomseed(os.clock())
local mbase = 2 --base wave
local wRatio = 10000 * (math.floor(ui.fortress_age/40320) + ui_stats.total_deaths + 1) --ratio of wealth to population desired; added fort age multiplier and total_deaths (combat deaths?)
-- Line below calculates the number of additional migrants based on the forts wealth (total + exported)
local wPop = math.floor((ui_stats.wealth.total + ui_stats.wealth.exported)/wRatio) - ui_stats.population - mbase
if wPop + ui_stats.population + mbase > CAP then -- should limit migrant wave to the population_cap value
wPop = CAP - ui_stats.population - mbase
elseif wPop > ui_stats.population then -- meant to help cap the overall population growth (basically allows for doubling the population, but nothing more)
wPop = ui_stats.population
end
if wPop < 0 then -- makes negative values invalid (don't want to bother dealing with negative migrants :p )
wPop = 0
end
-----------------------------------------------------------------------------------------------------
-- This code is for determining where the migrants will start (for simplicity, starting at a corner)
maxXYZ = {select(1, dfhack.maps.getTileSize())}
local xpos = 0
local ypos = 0
if math.random(0,2) <= 1 then
xpos = 0
else
xpos = maxXYZ[1] - 1 --map corner
end
if math.random(0,2) <= 1 then
ypos = 0
else
ypos = maxXYZ[2] - 1 --map corner
end
local Zcount = 0
::Zreset::
local zpos = maxXYZ[3] - 1
-- Line below compares the 'shape' of the tile to 'floor' (should result in ground level tile as air tiles do not have 'shape' 'floor' and below ground level at the map edge should be solid object)
while df.tiletype.attrs[dfhack.maps.getTileType(xpos,ypos,zpos)].shape ~= df.tiletype_shape.FLOOR do
zpos = zpos - 1
--what happens if the current x,y coordinates never meet condition? Need to start circling the map
--really unhappy about not being able to get the liquid type to work right. Instead having to rely on 'outside' field
if dfhack.maps.getTileType(xpos,ypos,zpos) == nil or zpos == 0 or dfhack.maps.getTileBlock(xpos,ypos,zpos).designation[xpos%16][ypos%16].outside == false then
Zcount = Zcount + 1 -- Zcount starts outside of looped goto and should trigger break in event of no proper positions
if Zcount > 500 then
return 1 -- error return
end
if xpos > 0 and ypos == maxXYZ[2] - 1 then
xpos = xpos - 1
goto Zreset
elseif xpos == 0 and ypos > 0 then
ypos = ypos - 1
goto Zreset
elseif xpos < maxXYZ[1] - 1 and ypos == 0 then
xpos = xpos + 1
goto Zreset
elseif xpos == maxXYZ[1] - 1 and ypos >= 0 then
ypos = ypos + 1
goto Zreset
end
end
end
-----------------------------------------------------------------------------------------------------

local N = mbase + math.floor(math.random(0,3)) + wPop
while N > 0 do
N = N - 1
local R = math.floor(math.random(1,2) + 0.5)
local gender = {"MALE","FEMALE"}
-- Was unable to determine how to get the dofile() or loadfile() commands to take specific arguments :s (this is a workaround)
dfhack.run_command('modtools/create-unit -race DWARF -caste '.. gender[R] ..' -setUnitToFort TRUE -name MOUNTAIN -location [ '.. xpos ..' '.. ypos ..' '.. zpos ..' ]')
end
return 0 -- succesful completion
end

-- Code initially ripped from emigration.lua
-- Changed the looping to occur close to when a timed_event is supposed to occur
local function event_loop()
    if enabled then
        migrantsReplace()
local N = #event
local T = 0
if N > 0 then
T = math.floor((event[0].season_ticks - df.global.cur_season_tick)/120) - 3
if T <= 1 then
dfhack.timeout(1, 'days', event_loop)
else
dfhack.timeout(T, 'days', event_loop)
end
else
dfhack.timeout(1, 'months', event_loop)
end
    end
end

dfhack.onStateChange.loadmigrantsreplace = function(code)
    if code==SC_MAP_LOADED then
        if enabled then
            print("migrantsreplace enabled.")
            event_loop()
        else
            print("migrantsreplace disabled.")
        end
    end
end

if dfhack.isMapLoaded() then
    dfhack.onStateChange.loadmigrantsreplace(SC_MAP_LOADED)
end
---------------------------------

Brief explanation: The script compares when the timed_event "Migrants" is supposed to occur and removes it shortly before the game calls it. It then runs a new set of code that creates named peasant dwarves using the modtools/create-unit command. It produces a minimum of 2 dwarves but will not produce more than 5 + your fort population (basically, a single migrant wave can only double your population).

As far as I've tested so far, the script works as intended. I have noticed that my game does tend to crash (program closes without prompting errors), but I am not sure if its code related or computer related as it is not repeatable. If you want to use it, mod it, etc, please feel free.

Furthermore, is there anyplace in particular I should post regarding what variables do not affect migrant wave size? Before I created this script I tried changing different reported values (wealth.exported, wealth.total, etc) and found that it had no effect on the number of migrants arriving. Might save someone else some time.

Enjoy.

Edit: Updated the code as of 2018-03-26.

15
DF General Discussion / Re: What Would Urist Do?
« on: March 12, 2018, 10:13:27 pm »
(Walked into the !!Magma Supercomputer!! or Urist? :p)

Perform a dance for the forgotten beast.

WWUD if he found himself with a goblin lover.

Pages: [1]