This is a release for 0.43.03 (*not* 0.43.04, 0.43.05, or anything newer - support for those is in progress, but likely to take longer than usual, so we decided to make a release for 0.43.03 in the meantime). Please do let us know about any issues - we can always make another 0.43.03 release, even if support for newer versions isn't done.
Changes since 0.42.06:
Lua
---
- Label widgets can now easily register handlers for mouse clicks
New Features
------------
- `add-thought`: allow syndrome name as ``-thought`` argument
- `gui/gm-editor`
- Added ability to insert default types into containers. For primitive types leave the type entry empty, and for references use ``*``.
- Added ``shift-esc`` binding to fully exit from editor
- Added ``gui/gm-editor toggle`` command to toggle editor visibility (saving position)
- `modtools/create-unit`:
- Added an option to attach units to an existing wild animal population
- Added an option to attach units to a map feature
Fixes
-----
- `autofarm`: Can now handle crops that grow for more than a season
- `combine-plants`: Fixed recursion into sub-containers
- `createitem`: Now moves multiple created items to cursor correctly
- `exportlegends`: Improved handling of unknown enum items (fixes many errors)
- `gui/create-item`: Fixed quality when creating multiple items
- `gui/mod-manager`: Fixed error when mods folder doesn't exist
- `modtools/item-trigger`: Fixed handling of items with subtypes
- `stockflow`:
- Can order metal mechanisms
- Fixed material category of thread-spinning jobs
Misc Improvements
-----------------
- The built-in ``ls`` command now wraps the descriptions of commands
- `catsplosion`: now a lua script instead of a plugin
- `fix/diplomats`: replaces ``fixdiplomats``
- `fix/merchants`: replaces ``fixmerchants``
- Unified script documentation and in-terminal help options
Removed
-------
- `tweak` manager-quantity: no longer needed
I noticed that the Readme link goes to expwnent/dfhack, while the other links are to DFHack/dfhack - is this intentional, and are there any plans regarding the organisation page?The 0.34.11-r5 branch hasn't been merged back into DFHack/dfhack yet.
I noticed that the Readme link goes to expwnent/dfhack, while the other links are to DFHack/dfhack - is this intentional, and are there any plans regarding the organisation page?The 0.34.11-r5 branch hasn't been merged back into DFHack/dfhack yet.
peterix/dfhack redirects to DFHack/dfhack, the new official repo (the links in the readme are outdated, as is the link in the first post). Expwnent made this release from a branch in expwnent/dfhack, which should be merged back into DFHack/dfhack once someone with write access decides to.I noticed that the Readme link goes to expwnent/dfhack, while the other links are to DFHack/dfhack - is this intentional, and are there any plans regarding the organisation page?The 0.34.11-r5 branch hasn't been merged back into DFHack/dfhack yet.
The Readme (https://github.com/expwnent/dfhack/blob/0.34.11-r5/Readme.rst) linked in the top post, under "Getting DFHack", links to http://github.com/peterix/dfhack and says releases are announced in http://tinyurl.com/dfhack-ng which redirects to the r3 forum thread (http://www.bay12forums.com/smf/index.php?topic=91166).
It's all very confusing.
EDIT: Which plugin lets you manage jobs and check emotions? Because it doesn't seem to be on automatically.
EDIT: Which plugin lets you manage jobs and check emotions? Because it doesn't seem to be on automatically.
I believe you're referring to "manipulator" (this is the ASCII version of Therapist, which you get by pressing u l) and "dwarfmonitor", which puts the colored numbers in the lower right corner of the main screen.
I have a question, one that is rather important for MasterworkDF. Especially considering that I myself cannot code C++. Lua I understand a bit by now.
How much cross-compability exists between r4 and r5, and, if any assumptions can be made, how much updating will need to be done for the DF2014 release?
Where the r5 release has 36 scripts in the script folder, Masterwork has 151. If most of them break, a big portion of the mod becomes broken as well.
That's because all plugins are disabled by default and must be explicitly enabled. You can automatically enable them by adding the appropriate commands to dfhack.init - see "dfhack.init-example" for more information.EDIT: Which plugin lets you manage jobs and check emotions? Because it doesn't seem to be on automatically.
I believe you're referring to "manipulator" (this is the ASCII version of Therapist, which you get by pressing u l) and "dwarfmonitor", which puts the colored numbers in the lower right corner of the main screen.
I was referring to the "manipulator", except pressing "u" shows no "l" option, and pressing "l" does as much as it does in normal DF when in the unit menu.
That's because all plugins are disabled by default and must be explicitly enabled. You can automatically enable them by adding the appropriate commands to dfhack.init - see "dfhack.init-example" for more information.Ah, thanks.EDIT: Which plugin lets you manage jobs and check emotions? Because it doesn't seem to be on automatically.
I believe you're referring to "manipulator" (this is the ASCII version of Therapist, which you get by pressing u l) and "dwarfmonitor", which puts the colored numbers in the lower right corner of the main screen.
On an unrelated note, using invasion-now to make two dwarven sieges, I lost 3 of my starting 7. I forgot I gave them the axegun.
Time to see if four unhappy metal beings can duke it out with GOBLINS.
They don't have axeguns.
I was referring to the "manipulator", except pressing "u" shows no "l" option, and pressing "l" does as much as it does in normal DF when in the unit menu.
Meph: I updated the main post with all of the renamed variables. It does not include newly discovered variables, just ones that had not-obviously-temporary-names that were changed. Took forever, but it's done now.Thank you. :)
How much cross-compability exists between r4 and r5, and, if any assumptions can be made, how much updating will need to be done for the DF2014 release?
Most of the changes only add newly identified variables, so they don't break backwards compatibility unless you were using a variable and referring to it by its temporary name without knowing what it does.
diff -ur MWDF-tmp/Dwarf Fortress/hack/scripts/construct-creature.lua MWDF/Dwarf
Fortress/hack/scripts/construct-creature.lua
--- MWDF-tmp/Dwarf Fortress/hack/scripts/construct-creature.lua 2014-03-28 10:06
:56.000000000 -0400
+++ MWDF/Dwarf Fortress/hack/scripts/construct-creature.lua 2014-06-13 21:04
:23.477664448 -0400
@@ -290,8 +290,8 @@
--unit.relations.old_time=?? --TODO add normal age
--[[ interataction stuff, probably timers ]]--
local num_inter=#caste.body_info.interactions -- new for interactions
- unit.curse.anon_4:resize(num_inter) -- new for interactions
- unit.curse.anon_5:resize(num_inter) -- new for interactions
+ unit.curse.own_interaction:resize(num_inter) -- new for interactions
+ unit.curse.own_interaction_delay:resize(num_inter) -- new for interactions
--[[ body stuff ]]
local body=unit.body
diff -ur MWDF-tmp/Dwarf Fortress/hack/scripts/itemsyndrome.lua MWDF/Dwarf Fortre
ss/hack/scripts/itemsyndrome.lua
--- MWDF-tmp/Dwarf Fortress/hack/scripts/itemsyndrome.lua 2014-06-08 17:29
:30.000000000 -0400
+++ MWDF/Dwarf Fortress/hack/scripts/itemsyndrome.lua 2014-06-19 10:07:05.4013
87096 -0400
@@ -120,7 +120,7 @@
newSyndrome.year=df.global.cur_year
newSyndrome.year_time=df.global.cur_year_tick
newSyndrome.ticks=0
- newSyndrome.unk1=0
+ newSyndrome.wound_id=0
--newSyndrome.flags=0
for k,v in ipairs(target_syndrome.ce) do
local sympt=df.unit_syndrome.T_symptoms:new()
diff -ur MWDF-tmp/Dwarf Fortress/hack/scripts/spawnkid.lua MWDF/Dwarf Fortress/h
ack/scripts/spawnkid.lua
--- MWDF-tmp/Dwarf Fortress/hack/scripts/spawnkid.lua 2014-05-26 02:18:24.0000
00000 -0400
+++ MWDF/Dwarf Fortress/hack/scripts/spawnkid.lua 2014-06-14 13:06:34.231613947 -0400
@@ -163,7 +163,7 @@
--todo set weapon bodypart
local num_inter=#caste.body_info.interactions
- unit.curse.anon_5:resize(num_inter)
+ unit.curse.own_interaction_delay:resize(num_inter)
return unit
end
function findRace(name)
diff -ur MWDF-tmp/Dwarf Fortress/hack/scripts/spawn.lua MWDF/Dwarf Fortress/hack
/scripts/spawn.lua
--- MWDF-tmp/Dwarf Fortress/hack/scripts/spawn.lua 2014-06-07 06:49:20.0000
00000 -0400
+++ MWDF/Dwarf Fortress/hack/scripts/spawn.lua 2014-06-14 13:06:52.951893393 -0
400
@@ -97,8 +97,8 @@
--unit.relations.old_time=?? --TODO add normal age
--[[ interataction stuff, probably timers ]]--
local num_inter=#caste.body_info.interactions -- new for interactions
- unit.curse.anon_4:resize(num_inter) -- new for interactions
- unit.curse.anon_5:resize(num_inter) -- new for interactions
+ unit.curse.own_interaction:resize(num_inter) -- new for interactions
+ unit.curse.own_interaction_delay:resize(num_inter) -- new for interactions
--[[ body stuff ]]
local body=unit.body
@@ -190,7 +190,7 @@
--todo set weapon bodypart
local num_inter=#caste.body_info.interactions
- unit.curse.anon_5:resize(num_inter)
+ unit.curse.own_interaction_delay:resize(num_inter)
return unit
end
function findRace(name)
diff -ur MWDF-tmp/Dwarf Fortress/hack/scripts/spawnunit.lua MWDF/Dwarf Fortress/
hack/scripts/spawnunit.lua
--- MWDF-tmp/Dwarf Fortress/hack/scripts/spawnunit.lua 2014-06-11 10:12:17.0000
00000 -0400
+++ MWDF/Dwarf Fortress/hack/scripts/spawnunit.lua 2014-06-14 13:05:58.3110
77739 -0400
@@ -74,8 +74,8 @@
end
unit.sex=caste.gender
local num_inter=#caste.body_info.interactions -- new for interactions
- unit.curse.anon_4:resize(num_inter) -- new for interactions
- unit.curse.anon_5:resize(num_inter) -- new for interactions
+ unit.curse.own_interaction:resize(num_inter) -- new for interactions
+ unit.curse.own_interaction_delay:resize(num_inter) -- new for interactions
local body=unit.body
body.body_plan=caste.body_info
@@ -169,7 +169,7 @@
df.global.world.units.other.ANY_ANIMAL:insert("#",unit)
local num_inter=#caste.body_info.interactions
- unit.curse.anon_5:resize(num_inter)
+ unit.curse.own_interaction_delay:resize(num_inter)
return unit
end
function findRace(name)
Stonesense should be updated in the next day or two.
Stonesense should be updated in the next day or two.
The problem seems to be that StoneSense does not support PRINT_MODE:STANDARD on OS X 10.9.
It crashes even on vanilla "dfhack 0.34.11 r3 for osx" if init/init.txt is changed to the PRINT_MODE:STANDARD.
TWBT needs PRINT_MODE:STANDARD or PRINT_MODE:SHADER to work, thus they are not compatible for now.
Seems like something only StoneSense developers can fix.
unit.body.body_plan.attacks i.e. caste_attack appears to have problems. DFhack crashed when trying to printall the tissue_layer_idx. Other data such as the skill used for body part attacks is always printed as 0.Looks like I got something messed up when mapping out that structure; remapping it now.
See https://github.com/angavrilov/df-structures/blob/master/df.creature-raws.xml#L559
What do you mean, biased? At least you know how the scripts are done. :P
Here my thoughts:
- Autofixhandedness is a must, otherwise custom gloves cant be done.
- Embark dwarves and embark points, for more dwarves/points at the start.
- A script for skill training, I have several ones I use in the mod.
- Boltguns conversion scripts. He can charm captured invaders and make civ members of them.
- Everything Roses has written, ever. Seriously, they do so much for raw modders.
- An announcements script.
- Urist DaVincis scripts to add/remove materials and pets to civs.
- Emigration by IndigoFenix, to handle unhappy dwarves.
- Empregnate to replenish civ members.
- Putnams Itemsyndrome, ProjectileExpansion, Gods, HackWish and more. Lots of this is basis for enchanted weapons, special ammo...
- Force Event, also Putnam. Forces caravans, migrants, sieges... super useful for more interaction with the world, and to make reactions that might trigger a full blown attack. Good for bored people that want a challenge.
- A feed script that sets hunger/thirst to 0, to allow keeping grazing animals indoor, which are fed manually.
- Quietusts make-monarch, which allows people that play with low pop-limits to get kings. Usually you need 140 dwarves to trigger the possible arrival of the king, the script allows smaller forts to do that.
- Add/Remove thoughts. Scripts that temper with thoughts, adding good or bad ones. Necessary for finer balancing, and to help save almost miserable dwarves.
- Spawnunit is included now? Warmists creature spawning. This fixed the holy grail of modding, creating new units.
If you want any of them, I can have a look through my folder and send them to you/post them here. But most of them are in the dfhack script collection already. :)
IndigoFenix has written dozens of awesome features for the Masterwork Gnomes as well. Druidium and animal speech/taming, custom machines that allow turing complete setups (much easier than in vanilla), and for example a gun that shoots a cage as projectile and traps the unit it hits. Better ask him for details.... although he would have to write some form of readme. ^^
FWIW, here's the scripts that I include in the Starter Pack that were not in r3 (excluding those in r5):
force (http://www.bay12forums.com/smf/index.php?topic=123817), unit info viewer GUI (http://dffd.wimbli.com/file.php?id=7717), plugin to fix growthbug (http://dffd.wimbli.com/file.php?id=7849), forumdwarves (http://dffd.wimbli.com/file.php?id=7245), showunitsyndromes (http://www.bay12forums.com/smf/index.php?topic=91166.msg4214644#msg4214644), removewear (http://www.bay12forums.com/smf/index.php?topic=91166.msg4094347#msg4094347), repeat (http://www.bay12forums.com/smf/index.php?topic=91166.msg4698983#msg4698983), feeding-timers (http://www.bay12forums.com/smf/index.php?topic=138609.msg5288227#msg5288227)
Edit: particularly the growth-bug fix - here's the source (https://github.com/KurikAmudnil/dfhack/tree/master/plugins/growthfix) - since it seems that r5 doesn't fix that at all. I'll have to track down one of the script versions in the meantime.
Edit: and with the stonesense build, I get an error right at the top when I open DF: "plugin stonesense has no enabled var" in red.I have the same since a dozen version or so of my mod. Never figured out what it is, Japa doesnt now either. Doesnt seem to do any harm.
Huh. If it's not causing any issues I guess I'll stick it in, and hope the overlay version comes out soon...QuoteEdit: and with the stonesense build, I get an error right at the top when I open DF: "plugin stonesense has no enabled var" in red.I have the same since a dozen version or so of my mod. Never figured out what it is, Japa doesnt now either. Doesnt seem to do any harm.
Are falconnes plugins in this mix?
Huh. If it's not causing any issues I guess I'll stick it in, and hope the overlay version comes out soon...QuoteEdit: and with the stonesense build, I get an error right at the top when I open DF: "plugin stonesense has no enabled var" in red.I have the same since a dozen version or so of my mod. Never figured out what it is, Japa doesnt now either. Doesnt seem to do any harm.
Are falconnes plugins in this mix?
Falconne's plugins are in, but as they were about a month ago - v43 or v44 probably - and the drop-in set should update soon.
Quietusts make-monarch, which allows people that play with low pop-limits to get kings. Usually you need 140 dwarves to trigger the possible arrival of the king, the script allows smaller forts to do that.I don't recall writing that script, and a quick check against the DFHack repository shows that it was Warmist who added it. I may have provided guidance on writing it, but I'm pretty sure I didn't actually write it (since I would've insisted on also adding history events for assigning the new monarch and possibly also for removing the old one).
Sorry Warmist/Quietust, I remember you (Quietust) posting the command you just quoted, and I added it to my scripts. I thought it was make-monarch. ^^Quietusts make-monarch, which allows people that play with low pop-limits to get kings. Usually you need 140 dwarves to trigger the possible arrival of the king, the script allows smaller forts to do that.I don't recall writing that script, and a quick check against the DFHack repository shows that it was Warmist who added it. I may have provided guidance on writing it, but I'm pretty sure I didn't actually write it (since I would've insisted on also adding history events for assigning the new monarch and possibly also for removing the old one).
Besides, there's a much easier way to get a King in a smaller fortress - run the command ":lua df.global.ui.fortress_rank = 5" to become a Metropolis.
#Adds pet types to civs on world load
AddMinionToCiv
AddMountToCiv
AddPackToCiv
AddPullToCiv
AddWagonToCiv
AddPetToCiv
#embark points and embark group
points 1274
dwarves 7
#patches the armor stands
enable fix-armory
#putnams awesome items
itemsyndrome contaminantsOn enable
itemsyndrome enable
@Meph - thanks, that's all I needed. The basic idea is that I can keep it small enough to just generate a new file based on selected options, and leave everything else in dfhack.init
I'm also doing some unrelated cleanup and need to update a script, but I can't work out what "unit.appearance.unk_4c8" is these days (which I think is the problem).
My suggestion would be to diff the DFHack r3 sources with the DFhack r5 sources and hunt it down.It would be a fun challenge to make a script that automates that. Lets say that you pass it git commit X and git commit Y and it outputs fields which changes in form "unit.wounds.unk48->unit.wounds.emotional_trauma"
I can do one better. I've been doing a lot of Lua recently and I happened to have already updated that script. There was one script in that folder that I forgot to test, so maybe it's that one, but I'd give this an 80% chance of working.
By the way, to any experienced raw modders out there: what scripts are commonly used that are not included in DFHack by default? Scripts are pretty small, so as long as they work and are useful to a large number of people, they should be included. I know my way around DFHack internals, but I don't know as much about how stuff is used.
...
as a regular player I often use callmedic.lua (http://www.bay12forums.com/smf/index.php?topic=91166.msg4858685;topicseen#msg4858685) and blooddel.lua (http://www.bay12forums.com/smf/index.php?topic=91166.msg4246062#msg4246062) from UristDaVinci
...
... And since we're talking about what scripts should be included, DFHack spells/script list (whatever its name is nowadays) should be in....
DFHack is ready. Have a nice day!
Type in '?' or 'help' for general help, 'ls' to see all commands.
Detected spatter add reactions - enabling plugin.
Detected reaction hooks - enabling plugin.
Fixing cloth stockpile handling (bug 5739)...
Patched 200506 bad references in 6046 materials.
FixGrowth: Fixed 6 units so that their size will grow/thicken.
[DFHack]# spells/base_upgradebuilding
Upgradable Buildings: Loaded
1 = upgrade
2 = 500
0 = here
2 <== #args
0 <== should be 500 if #args == 3
500 <== args[2]
[DFHack]#
The # operator doesn't count all the items in the table (!), instead it finds the last integer (not-fractional number) key. Because of how it's implemented, its results are undefined if all the integer keys in the table aren't consecutive (that is, don't use it for tables used as sparse arrays[2]).
Many of those require complex interactions between plugins, scripts, and parsing raw file strings hidden in things like syndrome classes. It isn't something you can just drop onto an existing game.What I usually do is use a Masterwork build and remove most of the extra stuff like metals and Succubi until I'm left with a practically vanilla game to play with. It'd be a pain to re-add all this stuff on top of a vanilla game by hand.
seedwatch all 25
seedwatch MUSHROOM_HELMET_PLUMP 50
seedwatch start
seedwatch supervision started.
seedwatch deactivated due to game load/unload
Protecting 62 jobs.
DFHack is ready. Have a nice day!
Type in '?' or 'help' for general help, 'ls' to see all commands.
[DFHack]# seedwatch info
seedwatch Info:
seedwatch is not supervising. Use 'seedwatch start' to start supervision.
There are no bin patches for OS X in dfhack r5?Most of the binary patches were only written for Windows and Linux - considerable extra effort is required in order to port them to OSX, so it hasn't been done yet.
In trying to run DFHack on Linux, I'm experiencing an error where libstdc++.so.6 does not contain versions GLIBCXX_3.4.20, GLIBCXX_3.4.18, GLIBCXX_3.4.15, CXXABI_1.3.8, or CXXABI_1.3.5, and as such, I cannot run it. Libstdc++.so.6 is in the libs folder, so it is accounted for.Remove libstdc++ from libs/ and let DFHack use your system libc++.
I hate to be that guy, but am I missing packages or libraries, goon up somewhere in unzipping the file, generally emit stupidity, or...?
local base = dfhack.internal.getImageBase()
tolocal base = (dfhack.getOSType() == 'darwin' and 0x1000) or dfhack.internal.getImageBase()
This fix is also possible with DFHack r3/r4, but I have not tested the binpatch with those versions yet.Most of the binary patches were only written for Windows and Linux - considerable extra effort is required in order to port them to OSX, so it hasn't been done yet.Unfortunately, assembler isn't my cup of tea.
[edit] For the record, I've located all of the patch points (http://www.qmtpro.com/~quietust/df/df_osx_patches.txt) for the various patches, though I currently don't have the means to write the patches myself.
Thanks to jj`` and Quietust, the hospital-overstocking binpatch now works on OS X: \Thanks! Works on 0.34.11 r5 / OS X 10.9.3, no overstocking
what happened to the fullheal command?That doesn't appear to have ever been part of the DFHack repository. An older version for r3 can be found here (http://www.bay12forums.com/smf/index.php?topic=91166.4125) - it isn't compatible with r5, but parts of it still work.
Excellent. I checked the list, and there are 2 more binpatches that could make the list:There are no bin patches for OS X in dfhack r5?Most of the binary patches were only written for Windows and Linux - considerable extra effort is required in order to port them to OSX, so it hasn't been done yet.
[edit] For the record, I've located all of the patch points (http://www.qmtpro.com/~quietust/df/df_osx_patches.txt) for the various patches, though I currently don't have the means to write the patches myself.
And a bit noob question. The patch that jj posted looks like this:Code: [Select]00110776: 75 90
Do I need to use it as it is, or only the lines with the plus signs? I'm asking because I've seen github patches that marked the line changes with minus and plus signs, and I'm unsure about this one. The game accepts the binpatch either way, but I can't confirm if it's working correctly or not. :(
00110777: D8 90
006602C4: 04 3C
006602CE: 40 47
Actually the important part is those four lines at the end. The rest is just documentation.Thx!
Excellent. I checked the list, and there are 2 more binpatches that could make the list:I've tried this patch for OS X and it's not working for me (this is the point where I give up due to my absent binary debugging skills)
User2's manager unlimiter (http://www.bay12forums.com/smf/index.php?topic=91166.msg5318968#msg5318968)
soundsense-season appears to be doing nothing at all.
ss_fix.log file doesn't get created or updated.
soundsense-season appears to be doing nothing at all.
ss_fix.log file doesn't get created or updated.
It's been a while, but I'm pretty sure that soundsense-season writes to the gamelog. The "soundsense" script writes to the other file, and is distributed with the utility not with dfhack.
Here's a script (https://github.com/lethosor/dfhack-scripts/blob/master/manager-quantity.lua) I wrote that does the same thing (call it from the main manager screen with a job selected).Excellent. I checked the list, and there are 2 more binpatches that could make the list:I've tried this patch for OS X and it's not working for me (this is the point where I give up due to my absent binary debugging skills)
User2's manager unlimiter (http://www.bay12forums.com/smf/index.php?topic=91166.msg5318968#msg5318968)
Here's a script (https://github.com/lethosor/dfhack-scripts/blob/master/manager-quantity.lua) I wrote that does the same thing (call it from the main manager screen with a job selected).Thanks! Here it is in the context
keybinding add M@jobmanagement "manager-quantity"
https://github.com/expwnent/dfhack/commit/596ab0e1b85dff4107a65847247d4b7ec1eafa12
All the scripts I've added are in there. They should be safe for the current version. There are a lot of them, so go check them out! I also added a few convenience things like the "repeat" command / repeatUtil / etc.
I added an onReport event that happens when a combat report happens (much more often than you think: it doesn't have to be visible to the user). More exciting is the onStrike event which triggers when any unit hits another. For convenience, it also tries to compute whether they hit the target with a weapon or with a unit attack. It needs testing, so let me know how it goes.
[glen@arch df_linux-phoebus]$ ./dfhack
Gtk-Message: Failed to load module "canberra-gtk-module"
Sound devices available:
OpenAL Soft
Picking OpenAL Soft. If your desired device was missing, make sure you have the appropriate 32-bit libraries installed. If you wanted a different device, configure ~/.openalrc appropriately.
Perfect OpenAL context attributes GET
Loading bindings from data/init/interface.txt
New window size: 1280x400
Font size: 16x16
Resizing grid to 80x25
Resizing font to 16x16
Resetting textures
https://github.com/expwnent/dfhack/commit/596ab0e1b85dff4107a65847247d4b7ec1eafa12
All the scripts I've added are in there. They should be safe for the current version. There are a lot of them, so go check them out! I also added a few convenience things like the "repeat" command / repeatUtil / etc.
I added an onReport event that happens when a combat report happens (much more often than you think: it doesn't have to be visible to the user). More exciting is the onStrike event which triggers when any unit hits another. For convenience, it also tries to compute whether they hit the target with a weapon or with a unit attack. It needs testing, so let me know how it goes.
Having a problem running growthbug with the new repeat command. osx, dfhack-r5 Here is what I did:...and dwarf fortress becomes unresponsive immediately, tried letting it run for 5 minutes to see if it returns, but no luck.
- save growthbug.lua to hack/script
- save repeat.lua to hack/script
- save repeatUtil.lua to hack/lua/plugins
- add to dfhack.init: "repeat enable 1 months growthbug now"
EDIT: same result with feeding-timers. Even trying to run "repeat enable" without arguments in the console freezes the game.
/snip
The documentation was wrong. I changed the syntax of the repeat command and forgot to document it properly. It should work now. Also there was a minor error in removewear which I fixed.
..._8.6/Macnewbie/Dwarf Fortress/hack/scripts/growthbug.lua:19: attempt to index field 'units' (a nil value)
stack traceback:
..._8.6/Macnewbie/Dwarf Fortress/hack/scripts/growthbug.lua:19: in main chunk
(...tail calls...)
and this, if run in the onload.init:..._8.6/Macnewbie/Dwarf Fortress/hack/scripts/growthbug.lua:19: attempt to index field 'units' (a nil value)
stack traceback:
..._8.6/Macnewbie/Dwarf Fortress/hack/scripts/growthbug.lua:19: in main chunk
(...tail calls...)
[C]: in function 'runCommand'
./hack/lua/dfhack.lua:384: in function 'run_command'
...bie_8.6/Macnewbie/Dwarf Fortress/hack/scripts/repeat.lua:70: in function 'func'
./hack/lua/plugins/repeatUtil.lua:27: in function 'helper'
./hack/lua/plugins/repeatUtil.lua:30: in function 'scheduleEvery'
...bie_8.6/Macnewbie/Dwarf Fortress/hack/scripts/repeat.lua:69: in main chunk
(...tail calls...)
For now you should add it to onLoad.init in your raws folder, not dfhack.init. The problem is that it was running before your world loads.
These scripts should be light on your FPS, so that shouldn't have any noticeable effect.Cool, one month it is!
Oh, that should be df.global.world.units.all instead of df.world.units.all.Perfect!
Plus I have a question about item-occupancy.lua: What does it do, should I run it with repeat, or at all.
That script is an extremely slow process intended to diagnose and fix corruption from buggy scripts or plugins teleporting items around. It should only be used if you encounter problems like dwarves claiming there is an item in a tile when there is none. It's somewhat similar to programs like chkdisk that fix your filesystem.Thx, noted, deleted from onload.
The thing I'm grappling with is that (as I understand) there's a separate Onload.init for each save, which creates some issues for people who move old saves over to a new pack and probably a support headache when someone changes settings and it doesn't behave as they expect.Two solutions come to mind:
You can probably do it fairly easily by calling "script onload.init" whenever a region loads.
Serious questions to dfhack people: how hard would it be to have a single Onload.init in the same place as dfhack.init?
You can probably do it fairly easily by calling "script onload.init" whenever a region loads.I'll look into this if I have a day free sometime, but that might not happen for a while.
:lua dfhack.onStateChange.onloadscript = function(state) if state == SC_WORLD_LOADED then dfhack.run_command('script onload.init') end end
If you want output to be displayed, use this instead::lua dfhack.onStateChange.onloadscript = function(state) if state == SC_WORLD_LOADED then print((dfhack.run_command('script onload.init'))) end end
I had thought of the first, and I plan to do this eventually - but it's a real pain, with way more special cases than I want to consider. The second could work - I'd have to check how selectively the windows GUI copies those folders over. On the other hand, it makes all the issues with propagating settings even worse if I want to use it for more that always-on bugfixing.
Serious questions to dfhack people: how hard would it be to have a single Onload.init in the same place as dfhack.init?
This would be a huge plus for my setup in the Starter Pack. If keeping the current function is desired, it could be overridden when an in-save-folder init file is found.
One more: I tried running the blooddel command to test if it works, and it won't delete blood barrels from an already arrived caravan. Is it intended behaviour? Is it only effective on future caravans?
One more: I tried running the blooddel command to test if it works, and it won't delete blood barrels from an already arrived caravan. Is it intended behaviour? Is it only effective on future caravans?
Yes, only future caravans.
What's the simplest way(probably on the wiki) to find out what string I should be using with workflow?If you mean the item/material tokens, they can be found at http://dwarffortresswiki.org/index.php/DF2012:Item_token and http://dwarffortresswiki.org/index.php/DF2012:Material_token, respectively. The createitem page (http://dwarffortresswiki.org/index.php/Utility:DFHack/createitem) may also be useful.
This should work in dfhack.init:What is the syntax, if I want to run a script at embark/after embark. Will the script only act on the active world, or any saves?Code: [Select]:lua dfhack.onStateChange.onloadscript = function(state) if state == SC_WORLD_LOADED then dfhack.run_command('script onload.init') end end
What is an "embark offset patch"? Because I'm getting an "embark offset patch not found" when trying to use "embark anywhere" or "embark nano".Yeah, the embark script does that, use the embark-tools instead: enable embark-tools in the console, then you get a GUI option.
What's the simplest way(probably on the wiki) to find out what string I should be using with workflow?Use this as a base (https://db.tt/SD5s609Q), copypaste into dfhack, or add to dfhack.init or onload.init.
def OutputDorfInfo(dorf)
str = "#{dorf.name}" if dorf.name.has_name
if dorf.custom_profession != ""
str << " the #{dorf.custom_profession}"
else
str << dorf.profession.inspect()
end
str << " member of the militia squad #{dorf.military.squad_tg.name}" if dorf.military.squad_id != -1
str << ". \nBorn in the year #{dorf.relations.birth_year}."
if dorf.relations.spouse_id != -1
str << "\nMarried to #{dorf.relations.spouse_tg.name}."
end
if dorf.relations.lover_id != -1
str << "\nLover of #{dorf.relations.lover_tg.name}."
end
artifactName = dorf.status.artifact_name.to_s()
if artifactName && artifactName.length > 0
str << "\nCreator of the artifact #{artifactName}."
end
puts str
end
dorfs = DFHack.unit_citizens
dorfs.each { |d|
OutputDorfInfo(d)
puts ""
}
CMake Error at depends/protobuf/CMakeLists.txt:60 (MESSAGE):
Could not find a working hash map implementation. Please install GCC >=
4.4, and all necessary 32-bit C++ development libraries.
https://github.com/expwnent/dfhack/commit/596ab0e1b85dff4107a65847247d4b7ec1eafa12
All the scripts I've added are in there. They should be safe for the current version. There are a lot of them, so go check them out! I also added a few convenience things like the "repeat" command / repeatUtil / etc.
I added an onReport event that happens when a combat report happens (much more often than you think: it doesn't have to be visible to the user). More exciting is the onStrike event which triggers when any unit hits another. For convenience, it also tries to compute whether they hit the target with a weapon or with a unit attack. It needs testing, so let me know how it goes.
I would recommend renaming hackWish to something more descriptive like gui/createitems or something along those lines.
Perhaps the ability to spawn a creature in Fortress Mode as a citizen could be added in another version/update?
I'm pretty sure spawnunit can do most of this (except for age and skills, which are fairly easy to set manually).Perhaps the ability to spawn a creature in Fortress Mode as a citizen could be added in another version/update?
Yes. YES. Please yes. I want that so badly you could not even know, and it would be useful in so many ways. Being able to decide its name, age, and skill/attribute levels would be good too.
you can't even set age in arena so it can do all of those by editing the newly created unit.I'm pretty sure spawnunit can do most of this (except for age and skills, which are fairly easy to set manually).Perhaps the ability to spawn a creature in Fortress Mode as a citizen could be added in another version/update?
Yes. YES. Please yes. I want that so badly you could not even know, and it would be useful in so many ways. Being able to decide its name, age, and skill/attribute levels would be good too.
Edit: link (https://gist.github.com/warmist/8563110)
I'm working on converting spawn-unit to C++ and also other things. Does anyone have a working, tested script that has to do with adding units to historical entities and groups? It would help.https://gist.github.com/warmist/8563110#file-spawn-unit-lua-L364
Is anyone still working on autolabor? I was trying to teach my wife dwarf fortress and she hated micromanaging workers, but I just discovered autolabor can halt your fortress, due to it assigning 7 woodcutters (even though I only have one axe) and then being unable to assign them to the mining duty due to the equipment bug.
Danaris has put up an experimental version of Stonesense here (http://topazgryphon.org/~tcollett/df/dfhack-0.34.11-r5-stonesense-Darwin.tar.bz2). It's not that stable or official yet, but it should work well enough for screenshots and experiments (be sure to save before using it).
Hi everyone.I love it. :)
I spent few minutes on writing something that seems to me useful.
DF normally doesn't give you any small 'reward' when you play it.
By reward I mean things like 'Badges' or 'Achievements'.
From psychological point of view they give us great tool for attracting attention of players and even teaching
about game itself.
Here is the source code -> https://gist.github.com/Demagogue/216e89435d2550108f6f (https://gist.github.com/Demagogue/216e89435d2550108f6f)
This is already only basic template and lack almost any documentation and code for updating variables.
CMake Error at depends/protobuf/CMakeLists.txt:60 (MESSAGE):
Could not find a working hash map implementation. Please install GCC >=
4.4, and all necessary 32-bit C++ development libraries.
) /usr/bin/c++ -m32 -fvisibility=hidden -m32 -march=i686 -mtune=generic -std=c++0x -O3 -DNDEBUG \
CMakeFiles/protoc-bin.dir/google/protobuf/compiler/main.cc.o -o protoc -rdynamic libprotoc.so /usr/lib/libpthread.so \
libprotobuf.so -lz -Wl,-rpath,/home/bra/source/dfhack/build/depends/protobuf
EDIT: I think I worked around it for now, but I haven't properly tested yet. dfhack starts, but I haven't run any game yet. What I did was move the provided libs/libstdc++.so.6 out of the way and replace it with a symlink to /usr/lib/gcc/i586-linux-gnu/4.9/libstdc++.soThat should work - you might not even need the symlink, if the library is in the correct location.
That should work - you might not even need the symlink, if the library is in the correct location.Indeed. In my case (Ubuntu 12.04 x86_64), simply deleting the offending library in the DF folder enabled it to locate the correct library on my system. (although it would be useful to know if there are distributions on which it won't work without adding a symlink)
enable syndromeTrigger
syndrome-trigger -syndrome "wake gabbro" -command [ tesb-spawn GABBRO \\LOCATION \\UNIT_ID ]
Posting to follow.
The two are not the same, if you select notify you get email spam, if you ptw you get unread notification.Posting to follow.You know, you have option notify.
I'm saying just in case.
If mods will be removing upper post. Please remove this one two.
Possible Problems:
- Developer plugins were accidentally included
in the linux distributionin the Linux and Windows versions. These plugins are used by individual developers for testing purposes. Unless you are certain otherwise, you should assume they are all dangerous, and that there will not be any backwards compatibility guarantees. The safest thing is to delete them from hack/plugins manually after installing. The full list:
- autolabor2
- buildprobe
- counters
- dumpmats
- eventExample
- frozen
- itemhacks
- kittens
- memview
- nestboxes
- notes
- onceExample
- printArgs
- rawdump
- ref-index
- rprobe
- stepBetween
- stockcheck
- stripcaged
- tiles
- tilesieve
- vectors
- vshook
That's the "kittens" plugin.so far the only dangerous thing kitten does is prevent me from quitting the game at all, unless the console is terminatedPossible Problems:
- Developer plugins were accidentally included
in the linux distributionin the Linux and Windows versions. These plugins are used by individual developers for testing purposes. Unless you are certain otherwise, you should assume they are all dangerous, and that there will not be any backwards compatibility guarantees. The safest thing is to delete them from hack/plugins manually after installing. The full list:
- autolabor2
- buildprobe
- counters
- dumpmats
- eventExample
- frozen
- itemhacks
- kittens
- memview
- nestboxes
- notes
- onceExample
- printArgs
- rawdump
- ref-index
- rprobe
- stepBetween
- stockcheck
- stripcaged
- tiles
- tilesieve
- vectors
- vshook
The most common mistake with syndromeTrigger is that you have to explicitly enable it in dfhack.init or manually withIt turns out that it's syndromeTrigger enable rather than enable syndromeTrigger but thanks for the tip on putting it in the init file. Unfortunately, it still doesn't seem to work :(Code: [Select]enable syndromeTrigger
Just glancing at your inorganic, it looks fine to me but I haven't tested it personally. If you still have problems after the above I'll look into it in more detail.
PS: Just so you know, in the next release you'll need to switch over to the new system, which will require this line in onLoad.init:Code: [Select]syndrome-trigger -syndrome "wake gabbro" -command [ tesb-spawn GABBRO \\LOCATION \\UNIT_ID ]
Not sure this is exactly the right place to ask this question, but I can't get syndromeTrigger to work. I have a set of minerals that are supposed to trigger a script when mined, but the script is never getting called (I put an unconditional print in there to make sure). The script runs from the DFHack prompt, but repeated applications of the boil-away stone don't work. Once I found out that syndromeTrigger can be enabled or disabled, I re-genned a world with syndromeTrigger enabled, but got the same (non)results.Spoiler: example boil-away stone (click to show/hide)
The script is a stripped-down version of spawn-unit.lua with an added bit to make an announcement.
I'm probably making a rookie mistake with the syndromeTrigger, but I just can't find it. Any and all help would be greatly appreciated!
syndromeTrigger enable and enable syndromeTrigger should both work.That occurred to me after I quit for the night. Next time I get a crack at it, I'll add a specific effect like a blinking tile or something to make sure. I just find it hard to believe that the dwarf happened to not inhale after so many tests.Not sure this is exactly the right place to ask this question, but I can't get syndromeTrigger to work. I have a set of minerals that are supposed to trigger a script when mined, but the script is never getting called (I put an unconditional print in there to make sure). The script runs from the DFHack prompt, but repeated applications of the boil-away stone don't work. Once I found out that syndromeTrigger can be enabled or disabled, I re-genned a world with syndromeTrigger enabled, but got the same (non)results.Spoiler: example boil-away stone (click to show/hide)
The script is a stripped-down version of spawn-unit.lua with an added bit to make an announcement.
I'm probably making a rookie mistake with the syndromeTrigger, but I just can't find it. Any and all help would be greatly appreciated!
Are you sure that the syndrome is being applied at all? Can you make it happen when the syndrome is applied as part of an interaction?
OK, I'll be the guy who asks. Where can I find info regarding DFHack for the just-released (0.40.0x) version. Please note that this is NOT a when-you-gonna-get-it-done-? post. I just want to know where to check for it when it is finished, or is in beta and needs testers, and thanks for all your very appreciated work so far.
#dfhack on freenode.net is fairly activeOK, I'll be the guy who asks. Where can I find info regarding DFHack for the just-released (0.40.0x) version. Please note that this is NOT a when-you-gonna-get-it-done-? post. I just want to know where to check for it when it is finished, or is in beta and needs testers, and thanks for all your very appreciated work so far.
Probably right here or at least in a new topic in the DF Modding subforum. It wouldn't be anywhere else here. Github is the only other place to look.
its not a when-you-gonna-get-it-done-? post.Oh, but I want to do one. :P
Updating from 0.31.25 to 0.34.02 took 9 days, IIRC. It'll probably be longer this time - maybe 2 weeks? I'm not doing memory analysis myself, so I'm not sure.Quoteits not a when-you-gonna-get-it-done-? post.Oh, but I want to do one. :P
I am in absolutely no hurry with this, but a rough idea (1 week, 1 month, 3 months-after-Toady-did-bugfix-releases-himself), would be nice. Not necessary in any way, but it would allow me to time my own stuff better to be on par with it.
Some amount of time between a week and a month is seems like a safe bet.But does not take into account meteor strikes. I would plan from a week and infinity. :D
my guess is there'll be a wait for bugfix updates first, which is reasonable. That said I'm looking forward to playing the new adventure mode with advfort :D, hopefully now we'll be able to build anywhere now and not just already established lairs *crosses fingers*Actually there was a script that would create a site at current location. Bigger problem was returning to almost any site would duplicate something till it lagged everything to death. Hopefully that is fixed in new df.
Version 0.40.01 is so absolutely broken that I don't think it's even worth updating DFhack for it, yet.Bugfixes usually change very little of df compared to real releases so almost everything will be straightforward to port into bugfix version.
e: typo
So I download the source to DFhack and all the 32-bit libraries it requires and all the ruby nonsense it requires. I finally get it to compile, but: the compiled shared objects don't include stonesense!
There's a syntax error in the source code:
custom_builds/dfhack/plugins/stonesense/Creatures.cpp:578:35: error: ‘InBody’ is not a member of ‘df::unit_inventory_item::T_mode’ itemslot->mode != df::unit_inventory_item::T_mode::InBody) {
So I download the source to DFhack and all the 32-bit libraries it requires and all the ruby nonsense it requires. I finally get it to compile, but: the compiled shared objects don't include stonesense!
You need to change the NO to YES on line 9 of plugins/CMakeLists.txt, then rebuild.QuoteThere's a syntax error in the source code:
custom_builds/dfhack/plugins/stonesense/Creatures.cpp:578:35: error: ‘InBody’ is not a member of ‘df::unit_inventory_item::T_mode’ itemslot->mode != df::unit_inventory_item::T_mode::InBody) {
I believe this means you need to update the dfstructures submodule in library/xml (git submodule init; git submodule update in the main DFHack directory should do this). However, I'm not 100% sure.
Is this on Linux or OS X?
I seem to be having an issue with exterminate, no matter how i select the unit by 'v' or 'k' or unit list, it either tells me i need to select a unit ingame or "Invalid race, use one of...". I've also tried "exterminate pig slaughter/butcher" (yes I have pigs) and get the same result, looking at the code for the script it seems like there should be a list there but it doesn't seem to be printing or finding it.I've run into this same thing, but I assumed it was because I was getting the name for voracious cave crawlers wrong.
I seem to be having an issue with exterminate, no matter how i select the unit by 'v' or 'k' or unit list, it either tells me i need to select a unit ingame or "Invalid race, use one of...". I've also tried "exterminate pig slaughter/butcher" (yes I have pigs) and get the same result, looking at the code for the script it seems like there should be a list there but it doesn't seem to be printing or finding it.I've run into this same thing, but I assumed it was because I was getting the name for voracious cave crawlers wrong.
I seem to be having an issue with exterminate, no matter how i select the unit by 'v' or 'k' or unit list, it either tells me i need to select a unit ingame or "Invalid race, use one of...". I've also tried "exterminate pig slaughter/butcher" (yes I have pigs) and get the same result, looking at the code for the script it seems like there should be a list there but it doesn't seem to be printing or finding it.I've run into this same thing, but I assumed it was because I was getting the name for voracious cave crawlers wrong.
I fixed my problem, seems to have been with the ruby api implementation in the Lazy Noob Pack, I just downloaded dfhack and extracted over the existing version of dfhack in the LNP and it worked. Not sure if that's what you were using salithus.
The Ruby API is part of DFHack, the Lazy Newb Pack doesn't add any functionality to DFHack.I fixed my problem, seems to have been with the ruby api implementation in the Lazy Noob Pack, I just downloaded dfhack and extracted over the existing version of dfhack in the LNP and it worked. Not sure if that's what you were using salithusI seem to be having an issue with exterminate, no matter how i select the unit by 'v' or 'k' or unit list, it either tells me i need to select a unit ingame or "Invalid race, use one of...". I've also tried "exterminate pig slaughter/butcher" (yes I have pigs) and get the same result, looking at the code for the script it seems like there should be a list there but it doesn't seem to be printing or finding it.I've run into this same thing, but I assumed it was because I was getting the name for voracious cave crawlers wrong.
Sweet - I'll try this out later today and let you know if it works for me too.The Ruby API is part of DFHack, the Lazy Newb Pack doesn't add any functionality to DFHack.I fixed my problem, seems to have been with the ruby api implementation in the Lazy Noob Pack, I just downloaded dfhack and extracted over the existing version of dfhack in the LNP and it worked. Not sure if that's what you were using salithusI seem to be having an issue with exterminate, no matter how i select the unit by 'v' or 'k' or unit list, it either tells me i need to select a unit ingame or "Invalid race, use one of...". I've also tried "exterminate pig slaughter/butcher" (yes I have pigs) and get the same result, looking at the code for the script it seems like there should be a list there but it doesn't seem to be printing or finding it.I've run into this same thing, but I assumed it was because I was getting the name for voracious cave crawlers wrong.
Yeah, actually my fault. I sent over some scripts to Peredexiserrant, one of them was /hack/ruby/ruby-autogen.rb which has different line endings on mac, and because of this fails on windows. (btw: is that normal?)
thx for the report.
git clone git://github.com/angavrilov/cl-linux-debug.git
wget https://github.com/downloads/angavrilov/cl-linux-debug/sbcl-runtime.bz2
bzip2 -d sbcl-runtime.bz2
some help:
how open the console and use stonesense?
and my game freeze at the world update......
Yeah, actually my fault. I sent over some scripts to Peredexiserrant, one of them was /hack/ruby/ruby-autogen.rb which has different line endings on mac, and because of this fails on windows. (btw: is that normal?)
thx for the report.
some help:
how open the console and use stonesense?
and my game freeze at the world update......
No DFHack with 40.x yet.
In 34.11, ctrl-shift-P "ssense overlay"
I cannot seem to select a hotkey for df 0.34.11 with dfhack r4. Can someone tell me how to put a hotkey for "digv" step by step?This is from the dfhack.init of LNP:
keybinding add Ctrl-V digv
It's normal if you're using a standard text editor, IIRC. Grab an IDE designed for development and it should allow you to choose which encoding to use. Scite's pretty easy to use and open-source: http://www.scintilla.org/SciTE-OSX.htmlYes, I know how to save them with different encoding, but I didn't edit it, my problem was that it came from the same github repo (afaik) and used different encoding in the mac pack, and in the win pack. BUT it was the only one, there were a few other ruby scripts in the same directory that used windows encoding... so not so straightforward.
It's not included. You need to find the plugin, put it in the folder "/DF/hack/plugins/", and add the activation command to dfhack.init
71% for the rest of my live :-[Are you that ill? :'(
71% for the rest of my live :-[Are you that ill? :'(
Note that the bar will likely never reach 100%.No, I don't want that.
Right now, there's enough for people to start updating plugins.
We just need somebody who knows enough about them to do that.
Right now, there's enough for people to start updating plugins.
We just need somebody who knows enough about them to do that.
That's a known issue (in EventManager, I believe).Right now, there's enough for people to start updating plugins.
We just need somebody who knows enough about them to do that.
I've considered updating the stockflow plugin, but can no longer compile for Windows. I've used Kiryl's Linux offsets to compile a version that lets DF launch, but it crashes whenever I embark or load a fortress, even with all plugins disabled and uninstalled.
Why won't it reach 100%? Are there structures that just aren't there anymore, or are the dfhack people not bothered to do it?
Why won't it reach 100%? Are there structures that just aren't there anymore, or are the dfhack people not bothered to do it?
Some of the structures are part of the economy or similar rare or obsolete things, so finding an instance to verify is hard or requires hacking things to turn disabled stuff on. Also, most of the yellow section of the diagram can be recolored green by now; only the red is completely untouched.
Registered here to ask if there was any information available about how I can help get those obscure structures found. I have a small amount of experience dealing with structures and memory, pointers and such. Enough that I think I know what to look for.Afaik almost everything is done now. We (and i mean they) are working on bringing plugins (and maybe scripts) up to date now.
Is there perhaps a quick guide, or a helpful person who could throw a quick pointer my way to get started?
I've found that without all the scripts, DF seems more convoluted than normal. I need my dfhack back.
If you look at plugins/CMakeLists.txt in DFHack:develop and count how many lines are commented out that should tell you how many plugins need updating.It's in quietust:develop (https://github.com/quietust/dfhack/blob/develop/plugins/CMakeLists.txt) at the moment. edit: reword
If you look at plugins/CMakeLists.txt in DFHack:develop and count how many lines are commented out that should tell you how many plugins need updating.It's in quietust:develop (https://github.com/quietust/dfhack/blob/develop/plugins/CMakeLists.txt) at the moment. edit: reword
Hello everyone.I... It's beautiful. Even if DFHack doesn't put it in (I hope they will), if you have your own threads, I'd like a link so I can subscribe.
I decided that Adventure Mode inventory screen could be improved a lot, so I started writing a DFHack plugin.
I started by reimplementing the default screen to expand to whole window, but later I got a lot of new ideas.
After 5 days of working on it I have pretty much finished the display part.
Here is what I got so far:
Screenshots on Imgur (http://imgur.com/a/413mX/embed#1)
- first screenshot shows DF default inventory screen for comparison.
- second one shows my AdvInventory plugin with items in default order
- Third one shows the plugin with items in sorted order.
If anyone is wondering, the "EIW" flags will show whether the item can be eaten, interacted or worn.
(all screens are from DF 0.34.11 because I am waiting for new DFHack before I move development to DF 0.40)
Hope you like it :)
As I said the display part is practically finished but there is almost no interaction with it yet. Only Sorting, Tab and ESC keys work at the moment, not even scrolling the list does. So there is still much work to do.
And there is even more work to do to support all the actions, because my plan is to eventually allow all actions like Eat, Put, Remove, Throw etc. to be available from this one screen.
I plan to release a version with basic functionality once the new DFHack ready, and then continue work on more advanced fuctions.
Rafal99 / Carabus
I... It's beautiful. Even if DFHack doesn't put it in (I hope they will), if you have your own threads, I'd like a link so I can subscribe.Thank you :)
I've always felt for years that adventure mode could use a UI overhaul.
A much simpler way (instead of creating a separate clone of df-structures) is to change to library/xml and run "git checkout master".If you look at plugins/CMakeLists.txt in DFHack:develop and count how many lines are commented out that should tell you how many plugins need updating.It's in quietust:develop (https://github.com/quietust/dfhack/blob/develop/plugins/CMakeLists.txt) at the moment. edit: reword
woho with that link and some shoehorning,ctrl-c,ctrl-v and one sledgehammer i got dfhack to work with 40.04
And no i wont uppload since my version is probably very unstable but if you whant it and know how it works get quietust dfhack and then the do the usually inti, update and so on but don't build instead pull the df-structures from https://github.com/DFHack/df-structures/ (https://github.com/DFHack/df-structures/) and replace the contents in library/xml with it
Is the plan to have the whole DFhack plugin list migrated to 0.40 at once before you release it?
Or can we get a barebones version with fastdwarf, reveal, autodump, etc before then?
Screenshots on Imgur (http://imgur.com/a/413mX/embed#1)
Screenshots on Imgur (http://imgur.com/a/413mX/embed#1)
I find this very arousing.
Hehe.. yeah, would be nice if it was a checkbox to tick in the DFHack tab of the DF Starter Pack.Screenshots on Imgur (http://imgur.com/a/413mX/embed#1)
I find this very arousing.
Holy crap is that cool!
It's not far now. As much as I'd like to believe that Quietust et al. are holding off the shiny and complete new DFHack suite until then, it'll probably trail behind for a bit longer.
Just noting that the progress bar is now drawing from .40.05's lst file.(http://goo.gl/zTOLc1)
Listening in on #dfhack and keeping an eye on the different Github branches of DFHack depositories are a good place to start, I think.
Can someone clarify where development is on the v40 dfhack. A while ago the bars were at seventy percent, now they seem to be at eight. Also, someone mentioned dfhack might come out soon after 40.05, but I'm unsure if this was a plan or a guess. Thanks for any and all clarification!
The big yellow portion seems to be what has been identified by scripts, with the green portion being what has been verified by actual humans. The yellow+green shot up to about 54% amazingly fast.Can someone clarify where development is on the v40 dfhack. A while ago the bars were at seventy percent, now they seem to be at eight. Also, someone mentioned dfhack might come out soon after 40.05, but I'm unsure if this was a plan or a guess. Thanks for any and all clarification!
It's because the structure verifying needs to be done per release. However, a large part can be done via clever scripting, hence it being fast.
Other than that, plugins need to be updated and verified by their developers.
Uh... what happened to the progress bar? It was on 71% yesterday.
Literally immediately above your post.The big yellow portion seems to be what has been identified by scripts, with the green portion being what has been verified by actual humans. The yellow+green shot up to about 54% amazingly fast.Can someone clarify where development is on the v40 dfhack. A while ago the bars were at seventy percent, now they seem to be at eight. Also, someone mentioned dfhack might come out soon after 40.05, but I'm unsure if this was a plan or a guess. Thanks for any and all clarification!
It's because the structure verifying needs to be done per release. However, a large part can be done via clever scripting, hence it being fast.
Other than that, plugins need to be updated and verified by their developers.
Uh... what happened to the progress bar? It was on 71% yesterday.
Uh... what happened to the progress bar? It was on 71% yesterday.
0.40.05 changed several structures, as well as added a new d_init option, and so things have to be realigned.
If they're Lua scripts, they require DFHack to work - they're not simple raw/binary patches.
They are a plugin (https://github.com/DFHack/dfhack/blob/f5de76e2cce0dd1dd266ed1d6ac79d711bf37c29/plugins/fixpositions.cpp), which also requires DFHack.
It's a matter of simply editing 50 of the files.They are a plugin (https://github.com/DFHack/dfhack/blob/f5de76e2cce0dd1dd266ed1d6ac79d711bf37c29/plugins/fixpositions.cpp), which also requires DFHack.
So that's not something we can attempt manually at all? It's not a matter of simply editing one of the files?
It's a matter of simply editing 50 of the files.They are a plugin (https://github.com/DFHack/dfhack/blob/f5de76e2cce0dd1dd266ed1d6ac79d711bf37c29/plugins/fixpositions.cpp), which also requires DFHack.
So that's not something we can attempt manually at all? It's not a matter of simply editing one of the files?
I know toady fixed the elven diplomat in the new one (but only if you gen a new world) so I wondered about adding it into an existing world like you could before.
I know toady fixed the elven diplomat in the new one (but only if you gen a new world) so I wondered about adding it into an existing world like you could before.
Can you please add the bug number?
Bug for what? Today fixed the elven diplomat, so if you gen a new world he'll work. But an existing save it isn't enabled. I had wanted to use the dfhack script to add him to an existing save.Oh, it's from http://www.bay12games.com/dwarves/ , found it, thanks.
http://dwarffortresswiki.org/index.php/Utility:DFHack/createitem#Body_parts
Does "SHELL CREATURE_MAT:(creature):SHELL" work?
Is there a program out there that will let me see what layer a cavern starts? Similar to reveal.
I can't wait for DF Hack to get updated. I'd like my prospector tool. XDMe too. That and digv. I didn't realize how much I depended on those two commands until now.
3. If so, was it only invasions of races that exist on the map?3. Yes, the civ had to exist.
4. If I use spawnunit to mimick an invasion will the game hate me for creating 20+ units at once?
dfhack.gui.makeAnnouncement(type,flags,pos,text,color[,is_bright]
And what is the "slot"dfhack.gui.addCombatReport(unit,slot,report_index)
mode set <return>
2 <return>
Then assume control of a creature and run:mode set <return>
1 <return>
I'm not sure if doing this will corrupt your save or not if you attempt to save, so be sure to make a backup of your region folder.
in other news I'm working on ghosts and what you can do with them knowing that now they are hellishly bugged.Here, I do, please, Ghost Army coming up?
hopefully assigning them jobs or pointing them to migrants/invaders/who ever would be in the works.
who wants a ghost army?
In the readme I only found showmood and forcing moods on people... is there any way at all to stop a mood from happening, or cancel a mood?No, unless I'm misunderstanding this:
And what exactly are the minimum requirements for moods to happen. Quietust once mentioned a population of 20, but I dont know if there are any others, and if its enough to breach 20 once... if I had 21 dwarves and after that (because of death) under 20, will moods still happen, because the 20 population was reached at some point in time?
In order for a dwarf to be struck with a strange mood, three conditions must be met:
* There is no currently active strange mood,
* The maximum number of artifacts is not met,
* There are at least 20 eligible dwarves (see below), including dwarves who have already created artifacts.
If all three of these conditions are true, the game may trigger a strange mood according to the frequency.
You forgot to do the submodule stuff, I think.You mean ruby and xml stuff? I'm pretty sure I did that.
In git.Can you please explain what this means/how to do that?
If you just want to compile DFHack or work on it by contributing patches, it's quite enough to clone from the read-only address:
git clone git://github.com/peterix/dfhack.git
cd dfhack
git submodule init
git submodule update
https://github.com/DFHack/dfhack/blob/master/Compile.rst#id1QuoteIf you just want to compile DFHack or work on it by contributing patches, it's quite enough to clone from the read-only address:
git clone git://github.com/peterix/dfhack.git
cd dfhack
git submodule init
git submodule update
https://github.com/DFHack/dfhack/blob/master/Compile.rst#id1QuoteIf you just want to compile DFHack or work on it by contributing patches, it's quite enough to clone from the read-only address:
git clone git://github.com/peterix/dfhack.git
cd dfhack
git submodule init
git submodule update
Thanks. I actually did it in the beginning, but doing it again gave me 2 new commits and now it compiled for 2 minutes and 40 seconds instead of 40 seconds and gave me this:
http://puu.sh/aJtfb/ba7c8f167f.png
And yes it's the development branch.
Well, there's install batch file and a script to set df path, but I don't know what they're doing.I don't think it works. I tried running it.
http://puu.sh/aJuQ8/401a76eef7.pngTry building against a repository that's actually been adjusted for version 0.40, such as this one (https://github.com/quietust/dfhack/tree/develop).
http://puu.sh/aJuT6/d05fc2a5b0.png
Hooray! it works.
Reveal works.
In case anyone else wants it.
https://mega.co.nz/#!w903SBbL!tBZNl6bh3mQ02VgsCPTCcdHyB-sxJQPWhyhjQF5Rdm8
I was actually using yours :/http://puu.sh/aJuQ8/401a76eef7.pngTry building against a repository that's actually been adjusted for version 0.40, such as this one (https://github.com/quietust/dfhack/tree/develop).
http://puu.sh/aJuT6/d05fc2a5b0.png
Hooray! it works.
Reveal works.
I think I see what the problem is - DFHack 0.40-r0 currently has a bunch of plugins disabled (they need significant changes to get them working again), but you apparently included old versions of those plugins from 0.34.11-r5 (which you really should delete, since there's no way they'll work as-is).Yeah, I figured that much.
Go through the build instructions using Quietust's repository instead of DFHack's. It works. I even have a script written for it, though I think the structures may have been changed since then (with my research), so it might not work. I'll update it when DFHack does, whatever, heh.uhh most of my adventurers don't have undetermined marked when I checked so it could be used for megabeasts or creatures who don't have a separate sex or atleast going by your Gaydar.
Research, for those interested:
unit_soul.unk1 is actually orientation_flags. The flags are as follows:
undetermined (used for adventurers)
male_lover
male_marry
female_lover
female_marry
Starting program: /home/user/Games/DF/df_linux/libs/Dwarf_Fortress
ERROR: ld.so: object './hack/libdfhack.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Trying to run dfhack for Linux Mint Qiana 17. Building is fine (using gcc 4.8.2) but when I launch the dfhack script it doesn't seem to be recognized by the game and it doesn't look like dfhack is loaded.
Running with gdb outputs this:QuoteStarting program: /home/user/Games/DF/df_linux/libs/Dwarf_Fortress
ERROR: ld.so: object './hack/libdfhack.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Any clue as to why dfhack isn't recognized by the game?
Sound devices available:
OpenAL Soft
Picking OpenAL Soft. If your desired device was missing, make sure you have the appropriate 32-bit libraries installed. If you wanted a different device, configure ~/.openalrc appropriately.
Perfect OpenAL context attributes GET
Loading bindings from data/init/interface.txt
New window size: 640x300
Font size: 8x12
Resizing grid to 80x25
Resizing font to 8x12
Nothing apart from standard DF outputQuoteSound devices available:
OpenAL Soft
Picking OpenAL Soft. If your desired device was missing, make sure you have the appropriate 32-bit libraries installed. If you wanted a different device, configure ~/.openalrc appropriately.
Perfect OpenAL context attributes GET
Loading bindings from data/init/interface.txt
New window size: 640x300
Font size: 8x12
Resizing grid to 80x25
Resizing font to 8x12
/home/user/Games/DF/dfhack/library/LuaApi.cpp:69:25: fatal error: df/identity.h: No such file or directory
#include "df/identity.h"
^
compilation terminated.
make[2]: *** [library/CMakeFiles/dfhack.dir/LuaApi.cpp.o] Error 1
make[1]: *** [library/CMakeFiles/dfhack.dir/all] Error 2
make: *** [all] Error 2
It seems that there is a md5sum mismatch and the symbols.xml file doesn't contain any entry for .40.08. I then tried downloading the develop branch but then build fails at 44% about a missing header file:Quote/home/user/Games/DF/dfhack/library/LuaApi.cpp:69:25: fatal error: df/identity.h: No such file or directory
#include "df/identity.h"
^
compilation terminated.
make[2]: *** [library/CMakeFiles/dfhack.dir/LuaApi.cpp.o] Error 1
make[1]: *** [library/CMakeFiles/dfhack.dir/all] Error 2
make: *** [all] Error 2
Uh, yeah, dfhack isn't updated for .08 yet. Give it time.
Try building against a repository that's actually been adjusted for version 0.40, such as this one (https://github.com/quietust/dfhack/tree/develop).
sudo apt-get install gcc-multilib g++-multilib
sudo apt-get install libxml-libxml-perl --no-install-recommends
# sudo ln -s /usr/include/x86_64-linux-gnu/zconf.h /usr/include # not sure it's necessary
sudo apt-get install lib32z1-dev
sudo apt-get install libxml-libxslt-perl
git clone -b develop https://github.com/DFHack/dfhack.git
cd dfhack
git submodule init
git submodule update
cd build/
cmake .. -DCMAKE_INSTALL_PREFIX=/home/int/games/df/2014/df_linux
make install
It seems that there is a md5sum mismatch and the symbols.xml file doesn't contain any entry for .40.08. I then tried downloading the develop branch but then build fails at 44% about a missing header file:It seems quitesutst's dev branch builds fine but there is a version mismatch.Quote/home/user/Games/DF/dfhack/library/LuaApi.cpp:69:25: fatal error: df/identity.h: No such file or directory
#include "df/identity.h"
^
compilation terminated.
make[2]: *** [library/CMakeFiles/dfhack.dir/LuaApi.cpp.o] Error 1
make[1]: *** [library/CMakeFiles/dfhack.dir/all] Error 2
make: *** [all] Error 2
Tried building Quietut's develop branch at the "Change version to v0.40.08" commit with Visual Studio Express 2010 and using the recommended cmake and perl, but compilation fails. Also, cmake fails to download the ruby library.Same thing(windows). You can download ruby manually from http://cloud.github.com/downloads/jjyg/dfhack/msvcrtruby187.tar.gz and put this *.tar.gz into .....build\VC2010\plugins\ruby\
Somewhat out of left field - the protobuf dependency fails to configure properly if you have clang installed on Linux (it gets selected over the GNU compiler for some reason.)
Since it seems there's no link as yet, here are my DFhack builds based on Quietust's latest pull
GNU/Linux: http://wikisend.com/download/557900/df_linux_40_08_hack.tar.gz
OS X: http://rghost.net/57423137
Note that the links will likely expire in 7 and 30 days respectively, until I find a better file-hosting site. Most stuff works, including most UI plugins and the essentials like reveal or dig-v.
I wonder when DFhack will be available for 40.08? I'd really like to be able to figure out what the heck is going on with the responses and why x is acting y way. It's really confusing atm and vague.Look at the post above yours, tell me if it works.
And also whatever is causing some underground critters to spam path fail errors sometimes. I feel like posting a bug report, but just saying I'm getting craploads of path fail errors isn't really enough.
Is this available for windows?Here is it:
Building stuff for Windows is a pain in the butt. For some reason my Windows partition can't install the SP1 update of Visual Studio Express 2010 (says it can't detect VS). If there's a way to install it as a standalone I'd be grateful (and I could build dfhack I guess).QuoteI wonder when DFhack will be available for 40.08? I'd really like to be able to figure out what the heck is going on with the responses and why x is acting y way. It's really confusing atm and vague.Look at the post above yours, tell me if it works.
And also whatever is causing some underground critters to spam path fail errors sometimes. I feel like posting a bug report, but just saying I'm getting craploads of path fail errors isn't really enough.
Finally, installed vc2010 and sp1 succesfully.
Removed stonesense, rprobe and autolabor2. Because it causes errors and fail while compiling. May be someone more experienced can build with it and post here?
Removed autolabor.plug.dll - because it fails to initialize.
Removed "UI and game logic tweaks", "Apply binary patches at runtime" , "Scripts" and stockflow from dfhack.init. It seems , they are for 34.11. Something of them even causes crash on embarking.
dfhack.init-example left unchangedIs this available for windows?Here is it: http://www.mediafire.com/download/pf9bdyvsyq815np/dfhack-0.40.08-r0-Windows.zip
Reveal, autodump, createitem, liquids, tiletypes, search, manipulator, prospect, exterminate, digl, digv works fine.
It can be very buggy. Use at your own risk. It is recommended to wait official build.
It doesn't like the new SDL. I get this error when I try to start DF: “The program can’t start because protobuf-lite.dll is missing from your computer.”Looks like an error while extracting the archive
Since it seems there's no link as yet, here are my DFhack builds based on Quietust's latest pull
GNU/Linux: http://wikisend.com/download/557900/df_linux_40_08_hack.tar.gz
OS X: http://rghost.net/57423137
Note that the links will likely expire in 7 and 30 days respectively, until I find a better file-hosting site. Most stuff works, including most UI plugins and the essentials like reveal or dig-v.
# /Users/rbrady/df/dfhack: line 15: 69791 Bus error: 10 DYLD_INSERT_LIBRARIES=./hack/libdfhack.dylib ./dwarfort.exe "$@"
logout
There's a repo here: https://github.com/EldrickWT/dfhack that supposedly compiles, "but expect explosions". Testing it on osx. Hopefully it won't crash right off the bat :PUploading Macnewbie with DFhack right now, cherry picked all the commits that'd compile.
dyld: lazy symbol binding failed: Symbol not found: __ZNKSt8__detail20_Prime_rehash_policy11_M_next_bktEm
Referenced from: ./hack/libdfhack.dylib
Expected in: /Users/rbrady/df/libs/libstdc++.6.dylib
I haven't been able to get anything I compile myself to work. Always get some message like:Code: [Select]dyld: lazy symbol binding failed: Symbol not found: __ZNKSt8__detail20_Prime_rehash_policy11_M_next_bktEm
There are no errors in compiling, but plenty of warnings about how variable X is too small to hold all values of Y.
Referenced from: ./hack/libdfhack.dylib
Expected in: /Users/rbrady/df/libs/libstdc++.6.dylib
Obviously, since I was able to use the one compiled earlier by nopenope, this is a problem on my end. Anyone know how to resolve the problems with libstdc++.6.dylib?
I haven't been able to get anything I compile myself to work. Always get some message like:Code: [Select]dyld: lazy symbol binding failed: Symbol not found: __ZNKSt8__detail20_Prime_rehash_policy11_M_next_bktEm
Referenced from: ./hack/libdfhack.dylib
Expected in: /Users/rbrady/df/libs/libstdc++.6.dylib
There are no errors in compiling, but plenty of warnings about how variable X is too small to hold all values of Y.
Obviously, since I was able to use the one compiled earlier by nopenope, this is a problem on my end. Anyone know how to resolve the problems with libstdc++.6.dylib?
Plus the 40.08 osx memory structures are not yet in the official repo, you need to pull them from lethosor's.
gcc 4.8. Brew errors out if I try to install 4.5. Not sure why. I think brew puts stuff in usr/local/lib, so I'll try that. Thanks!
--offtopic below--
That's what I hate git/github for. Before cool-distributed-trendy-git-github people gained write access to a single repo and just working there together. Now they're forking and forking, right now we have at least five more or less active dfhack repose, nobody knows which one to use at a given point in time and when changes going to be merged into the "main" repo.
--offtopic end--
Honestly it doesn't bother me much. If you want to use a system before it is officially released then you need to do the work to make sure all of the parts are correct. If everything was in a single place and working then it would be the official release. Having things in separate repos allows people to make changes for one specific thing (like making it OSX compatible, or Linux compatible, or whatever) and then when they have that aspect working, they can merge it back into the main repo for all to use.
--offtopic below--
That's what I hate git/github for. Before cool-distributed-trendy-git-github people gained write access to a single repo and just working there together. Now they're forking and forking, right now we have at least five more or less active dfhack repose, nobody knows which one to use at a given point in time and when changes going to be merged into the "main" repo.
--offtopic end--
This. I don't think I'm the only one wanting to be bleeding-edge and it's just silly to have to fetch stuff from unofficial repos because of all these forks. Hardly anyone knows which one will compile, which one will run, which one is Linux/OS X compatible (since these are usually given less priority), etc. Even the AUR contains outdated versions.
eh, I still prefer the centralized repo with branching/tagging used liberally. that way you can have tags for official releases, branches for people doing whatever they feel like, and a trunk that will always at least compile (or someone pays dearly) even if it isn't 100% functional. actually had a discussion about this today at work and how we will never ever use git for future projects because of the kind of fragmentation I'm seeing on DF projects.Honestly it doesn't bother me much. If you want to use a system before it is officially released then you need to do the work to make sure all of the parts are correct. If everything was in a single place and working then it would be the official release. Having things in separate repos allows people to make changes for one specific thing (like making it OSX compatible, or Linux compatible, or whatever) and then when they have that aspect working, they can merge it back into the main repo for all to use.
--offtopic below--
That's what I hate git/github for. Before cool-distributed-trendy-git-github people gained write access to a single repo and just working there together. Now they're forking and forking, right now we have at least five more or less active dfhack repose, nobody knows which one to use at a given point in time and when changes going to be merged into the "main" repo.
--offtopic end--
This. I don't think I'm the only one wanting to be bleeding-edge and it's just silly to have to fetch stuff from unofficial repos because of all these forks. Hardly anyone knows which one will compile, which one will run, which one is Linux/OS X compatible (since these are usually given less priority), etc. Even the AUR contains outdated versions.
eh, I still prefer the centralized repo with branching/tagging used liberally. that way you can have tags for official releases, branches for people doing whatever they feel like, and a trunk that will always at least compile (or someone pays dearly) even if it isn't 100% functional. actually had a discussion about this today at work and how we will never ever use git for future projects because of the kind of fragmentation I'm seeing on DF projects.Honestly it doesn't bother me much. If you want to use a system before it is officially released then you need to do the work to make sure all of the parts are correct. If everything was in a single place and working then it would be the official release. Having things in separate repos allows people to make changes for one specific thing (like making it OSX compatible, or Linux compatible, or whatever) and then when they have that aspect working, they can merge it back into the main repo for all to use.
--offtopic below--
That's what I hate git/github for. Before cool-distributed-trendy-git-github people gained write access to a single repo and just working there together. Now they're forking and forking, right now we have at least five more or less active dfhack repose, nobody knows which one to use at a given point in time and when changes going to be merged into the "main" repo.
--offtopic end--
This. I don't think I'm the only one wanting to be bleeding-edge and it's just silly to have to fetch stuff from unofficial repos because of all these forks. Hardly anyone knows which one will compile, which one will run, which one is Linux/OS X compatible (since these are usually given less priority), etc. Even the AUR contains outdated versions.
Yep.Heh, it's funny since I recently told myself I should be writing a script that automatically updates and builds dfhack until I got stuck with the same issue.
Also, for example, I was going to add dfhack to my build server to automatically build it for 0.40 as development goes until the official release, but it's just not possible - I can't build and publish 5 repos.
Depends on what you want: bleeding edge- pull _Q and ag develop branches into your own (maybe few other you want) and merge and build. Want something more sane: use DFHack develop branch (usually updated 0.5 times a day). Want stable/releases build DFHack master.Yep.Heh, it's funny since I recently told myself I should be writing a script that automatically updates and builds dfhack until I got stuck with the same issue.
Also, for example, I was going to add dfhack to my build server to automatically build it for 0.40 as development goes until the official release, but it's just not possible - I can't build and publish 5 repos.
Yeah um, careful with those experimental builds people. Given how dfhack toys with DF's memory, if some obsolete plugin change the wrong things you're likely to end up with crashes and saves corruption... so only use those for fooling around with a fortress you don't care about much.
Also, some people should educate themselves on what OSX, Windows and Linux are. No excuse, you've got Wikipedia and the intertubes at your disposal.
--offtopic below--
That's what I hate git/github for. Before cool-distributed-trendy-git-github people gained write access to a single repo and just worked there together. Now they're forking and forking, right now we have at least five more or less active dfhack repos, nobody knows which one to use at a given point in time and when changes going to be merged into the "main" repo.
--offtopic end--
Isitanos, I don't get the impression that the folks ITT cloning the repos will have unrealistic expectations. They probably comprehend what it means to be an unstable/incomplete version. I just see it as enthusiastic beta testing. :PActually I was thinking about other folks downloading the experimental binaries from this thread, not those cloning the repos. The latter indeed know what they're getting into (hopefully :P ).
To be fair, nopenope didn't say which one of his downloads was windows compatible.To be fair, someone with the slightest knowledge of OS's instantly knows that a download is not for windows if it's for OSX or Linux. Hence my encouragement to learn about those. No offense meant.
First post before everything explodes.
Thanks for your everything, everyone involved. I've missed this.
e: dang, this thing just doesn't stop crashing
First post before everything explodes.
Thanks for your everything, everyone involved. I've missed this.
e: dang, this thing just doesn't stop crashing
in dfhack init disable: tweak craft-age-wear
It's there. Look harder.
When you do, add a # in front of it to comment it out.
Attention: Do NOT use either of these versions, as they were built against outdated structures data where the virtual method table for the "item" class is misaligned, which will cause various plugins to crash Dwarf Fortress if they try to manipulate items in certain ways.
A new version will be available shortly.
Basically everything will crash in r1. r2 should be mostly ok, but still be careful with it.
-- Allows for script-based wishing.
function getGenderString(gender)
local genderStr
if gender==0 then
genderStr=string.char(12)
elseif gender==1 then
genderStr=string.char(11)
else
return ""
end
return string.char(40)..genderStr..string.char(41)
end
function getCreatureList()
local crList={}
for k,cr in ipairs(df.global.world.raws.creatures.alphabetic) do
for kk,ca in ipairs(cr.caste) do
local str=ca.caste_name[0]
str=str..' '..getGenderString(ca.gender)
table.insert(crList,{str,nil,ca})
end
end
return crList
end
function getMatFilter(itemtype)
local itemTypes={
SEEDS=function(mat,parent,typ,idx)
return mat.flags.SEED_MAT
end,
PLANT=function(mat,parent,typ,idx)
return mat.flags.STRUCTURAL_PLANT_MAT
end,
LEAVES=function(mat,parent,typ,idx)
return mat.flags.LEAF_MAT
end,
MEAT=function(mat,parent,typ,idx)
return mat.flags.MEAT
end,
CHEESE=function(mat,parent,typ,idx)
return (mat.flags.CHEESE_PLANT or mat.flags.CHEESE_CREATURE)
end,
LIQUID_MISC=function(mat,parent,typ,idx)
return (mat.flags.LIQUID_MISC_PLANT or mat.flags.LIQUID_MISC_CREATURE or mat.flags.LIQUID_MISC_OTHER)
end,
POWDER_MISC=function(mat,parent,typ,idx)
return (mat.flags.POWDER_MISC_PLANT or mat.flags.POWDER_MISC_CREATURE)
end,
DRINK=function(mat,parent,typ,idx)
return (mat.flags.ALCOHOL_PLANT or mat.flags.ALCOHOL_CREATURE)
end,
GLOB=function(mat,parent,typ,idx)
return (mat.flags.STOCKPILE_GLOB)
end,
WOOD=function(mat,parent,typ,idx)
return (mat.flags.WOOD)
end,
THREAD=function(mat,parent,typ,idx)
return (mat.flags.THREAD_PLANT)
end,
LEATHER=function(mat,parent,typ,idx)
return (mat.flags.LEATHER)
end
}
return itemTypes[df.item_type[itemtype]] or getRestrictiveMatFilter(itemtype)
end
function getRestrictiveMatFilter(itemType)
if not args.veryRestrictive then return nil else
local itemTypes={
WEAPON=function(mat,parent,typ,idx)
return (mat.flags.ITEMS_WEAPON or mat.flags.ITEMS_WEAPON_RANGED)
end,
AMMO=function(mat,parent,typ,idx)
return (mat.flags.ITEMS_AMMO)
end,
ARMOR=function(mat,parent,typ,idx)
return (mat.flags.ITEMS_ARMOR)
end,
SHOES,SHIELD,HELM,GLOVES=ARMOR,ARMOR,ARMOR,ARMOR,
INSTRUMENT=function(mat,parent,typ,idx)
return (mat.flags.ITEMS_HARD)
end,
GOBLET,FLASK,TOY,RING,CROWN,SCEPTER,FIGURINE,TOOL=INSTRUMENT,INSTRUMENT,INSTRUMENT,INSTRUMENT,INSTRUMENT,INSTRUMENT,INSTRUMENT,
AMULET=function(mat,parent,typ,idx)
return (mat.flags.ITEMS_SOFT or mat.flags.ITEMS_HARD)
end,
EARRING,BRACELET=AMULET,AMULET,
ROCK=function(mat,parent,typ,idx)
return (mat.flags.IS_STONE)
end,
BOULDER=ROCK,
BAR=function(mat,parent,typ,idx)
return (mat.flags.IS_METAL or mat.flags.SOAP or mat.id==COAL)
end
}
return itemTypes[df.item_type[itemType]]
end
end
function createItem(mat,itemType,quality,creator,description)
dfhack.items.createItem(itemType[1], itemType[2], mat[1], mat[2], creator)
if df.item_type[itemType[1]]=='SLAB' then
item.description=description
end
end
function qualityTable()
return {{'None'},
{'-Well-crafted-'},
{'+Finely-crafted+'},
{'*Superior*'},
{string.char(240)..'Exceptional'..string.char(240)},
{string.char(15)..'Masterwork'..string.char(15)}
}
end
local script=require('gui.script')
function showItemPrompt(text,item_filter,hide_none)
require('gui.materials').ItemTypeDialog{
prompt=text,
item_filter=item_filter,
hide_none=hide_none,
on_select=script.mkresume(true),
on_cancel=script.mkresume(false),
on_close=script.qresume(nil)
}:show()
return script.wait()
end
function showMaterialPrompt(title, prompt, filter, inorganic, creature, plant) --the one included with DFHack doesn't have a filter or the inorganic, creature, plant things available
require('gui.materials').MaterialDialog{
frame_title = title,
prompt = prompt,
mat_filter = filter,
use_inorganic = inorganic,
use_creature = creature,
use_plant = plant,
on_select = script.mkresume(true),
on_cancel = script.mkresume(false),
on_close = script.qresume(nil)
}:show()
return script.wait()
end
function usesCreature(itemtype)
typesThatUseCreatures={REMAINS=true,FISH=true,FISH_RAW=true,VERMIN=true,PET=true,EGG=true,CORPSE=true,CORPSEPIECE=true}
return typesThatUseCreatures[df.item_type[itemtype]]
end
function getCreatureRaceAndCaste(caste)
return df.global.world.raws.creatures.list_creature[caste.index],df.global.world.raws.creatures.list_caste[caste.index]
end
function hackWish(unit)
script.start(function()
local amountok, amount
local matok,mattype,matindex,matFilter
local itemok,itemtype,itemsubtype=showItemPrompt('What item do you want?',function(itype) return df.item_type[itype]~='CORPSE' and df.item_type[itype]~='FOOD' end ,true)
if not args.notRestrictive then
matFilter=getMatFilter(itemtype)
end
if not usesCreature(itemtype) then
matok,mattype,matindex=showMaterialPrompt('Wish','And what material should it be made of?',matFilter)
else
local creatureok,useless,creatureTable=script.showListPrompt('Wish','What creature should it be?',COLOR_LIGHTGREEN,getCreatureList())
mattype,matindex=getCreatureRaceAndCaste(creatureTable[3])
end
local qualityok,quality=script.showListPrompt('Wish','What quality should it be?',COLOR_LIGHTGREEN,qualityTable())
local description
if df.item_type[itemtype]=='SLAB' then
local descriptionok
descriptionok,description=script.showInputPrompt('Slab','What should the slab say?',COLOR_WHITE)
end
if args.multi then
repeat amountok,amount=script.showInputPrompt('Wish','How many do you want? (numbers only!)',COLOR_LIGHTGREEN) until tonumber(amount)
if mattype and itemtype then
for i=1,tonumber(amount) do
createItem({mattype,matindex},{itemtype,itemsubtype},quality,unit,description)
end
end
else
if mattype and itemtype then
createItem({mattype,matindex},{itemtype,itemsubtype},quality,unit,description)
end
end
end)
end
scriptArgs={...}
utils=require('utils')
validArgs = validArgs or utils.invert({
'startup',
'all',
'restrictive',
'unit',
'multi'
})
args = utils.processArgs({...}, validArgs)
eventful=require('plugins.eventful')
if not args.startup then
local unit=args.unit and df.unit.find(args.unit) or dfhack.gui.getSelectedUnit(true)
hackWish(unit)
else
eventful.onReactionComplete.hackWishP=function(reaction,unit,input_items,input_reagents,output_items,call_native)
if not reaction.code:find('DFHACK_WISH') then return nil end
hackWish(unit)
end
end
I get that, but is the only thing I have to replace is one file or is there more? I'm just checking on that.At least the complete /hack directory and the .init.
Most notably, you need to update all of the DLLs - SDL.dll, protobuf-lite.dll, lua.dll, libruby.dll, dfhack-client.dll, and all of the plugins - failing to update any of those can and will cause it to continue crashing.I get that, but is the only thing I have to replace is one file or is there more? I'm just checking on that.At least the complete /hack directory and the .init.
lua (without any parameters)But I can't find any documentation about what do do when IN the interpreter.
This starts an interactive lua interpreter.
Most notably, you need to update all of the DLLs - SDL.dll, protobuf-lite.dll, lua.dll, libruby.dll, dfhack-client.dll, and all of the plugins - failing to update any of those can and will cause it to continue crashing.I get that, but is the only thing I have to replace is one file or is there more? I'm just checking on that.At least the complete /hack directory and the .init.
Just unpack the damn thing into the root folder where Dwarf Fortress.exe is sitting. This isn't hard.
Well, I stayed at a Best Western Inn last night. :PJust unpack the damn thing into the root folder where Dwarf Fortress.exe is sitting. This isn't hard.
This is what I did. I made a backup of my sdl.dll though so I can feel smart. 8)
And I saved a bunch om money on car insurance.
By not owning a car.
You're using an old, unworking version of hackwish. Like, literally doesn't work. Here's one that does:
/snip
[DFHack]# gui/hack-wish
...ons/dfhack_osx_0.40.08-r2/hack/scripts/gui/hack-wish.lua:197: attempt to index global 'utils' (a nil value)
stack traceback:
...ons/dfhack_osx_0.40.08-r2/hack/scripts/gui/hack-wish.lua:197: in main chunk
(...tail calls...)
How do I use rename? It's saying it isn't a recognized commandIt's gui/rename, default keybind: ctrl-shift-n
The heck happened to my requires...same error
EDIT: Fixed.
tweak military-training is still in the readme and floating around in the .init, but is it no longer there? Trying to invoke it just makes tweak fart out a command list like I was typing gibberish at it.
How do I see the cursor coordinates?
enable mousequery
He's asking how to find df.global.cursor.
It's df.global.cursor.
It's a structure. Here's a script:
printall(df.global.cursor)
It's a structure. Here's a script:
printall(df.global.cursor)
Just tried that, not a recognized command.
It's a structure. Here's a script:
printall(df.global.cursor)
Just tried that, not a recognized command.
First, "lua" then "~df.global.cursor"
It's a structure. Here's a script:
printall(df.global.cursor)
Just tried that, not a recognized command.
First, "lua" then "~df.global.cursor"
You're using an old, unworking version of hackwish. Like, literally doesn't work. Here's one that does:
gui/unit-info-viewer
http://es.tinypic.com/view.php?pic=11lpoi0&s=8
for k,v in pairs(tmp_soul.traits) do
local min,mean,max
min=caste.personality.a[k]
mean=caste.personality.b[k]
max=caste.personality.c[k]
tmp_soul.traits[k]=clampedNormal(min,mean,max)
end
local unit_name
if not unit_id then
unit_name = "Something" -- The player activated the script in an interactive window.
else
unit_name = dfhack.TranslateName(dfhack.units.getVisibleName(unit_id))
end
getVisibleName takes a unit, not the unit's ID. You want df.unit.find(unit_id) for that.Thanks.
I didn't have an onLoad.init file in the folder with dfhack.init, so I made one and added the items but it didn't try to run the commands on load.
After doing some research it looks like the LNP has it's own onLoad.init file named LNP_dfhack_onLoad.init. I added the commands to this file and it seems to work fine. I just hope this file doesn't get overwritten by the LNP from time to time.
It will be overwritten by the launcher every time you launch DF or close the launcher. Your onLoad.init needs to go in the /data/save/regionX/raw/ folder.
./libs/Dwarf_Fortress: symbol lookup error: ./hack/libdfhack.so: undefined symbol: _Z10lua_gettopP9lua_State
gui/unit-info-viewer
*with realization* OHhh. Why didn't I think of that, lol. I thought I had to do lua or script or something. Thank you.
Edit: It doesn't do what I thought it would do, just the name, description, and size. I thought there would be a way to view stuff like the reason for them acting in a certain way to stuff, like the conversations? Though maybe that isn't developed yet.
Also, how do I view the adventurer info like reputation/fame?
What's New
- Internals
- Support for per save script folders. DFHack will now look for scripts in raw/scripts before checking for scripts in hack/scripts. This will help portability of savegames between people who have different mods.
If you set more than a link to a stockpile, the linked list of "give: stockpile #1", "take: stockpile #2", ETC/ETC gets overlapped by: "J: No Job Selected" ??, its anybody else having this issue?
EDIT:
and this:
http://es.tinypic.com/view.php?pic=11lpoi0&s=8 (http://es.tinypic.com/view.php?pic=11lpoi0&s=8)
dfhack is failing to start, giving me this:Code: [Select]./libs/Dwarf_Fortress: symbol lookup error: ./hack/libdfhack.so: undefined symbol: _Z10lua_gettopP9lua_State
I was previously getting the usual libstdc++ errors, which I fixed by (as usual) removing the libstdc++ file from "/libs". The above error only appeared after making the fix. Other than that, I've only done some basic changes to "dfhack.init". DF itself is the most recent v.
Workaround? Fix? Please/thanks!
Edit: It doesn't do what I thought it would do, just the name, description, and size. I thought there would be a way to view stuff like the reason for them acting in a certain way to stuff, like the conversations? Though maybe that isn't developed yet.
Also, how do I view the adventurer info like reputation/fame?
Why are you guys not answering my new questions?
dfhack is failing to start, giving me this:This sounds like it's failing to load ./hack/liblua.so for some reason. Has that file been deleted? Do you have another liblua.so on your system?Code: [Select]./libs/Dwarf_Fortress: symbol lookup error: ./hack/libdfhack.so: undefined symbol: _Z10lua_gettopP9lua_State
Well, I'm glad that most of the new structures are added on instead of removed outright. Most of the old scripts should still work.
That being said, has anyone been playing with trees? I've worked out how to change the tiles of a tree provided they are already part of that tree, but how does the game determine the tree's current shape? It doesn't seem to be all tree tiles within a cube, since adding new tree tiles within a tree's cube just creates a species-less 'tree' tile. Stranger still, trees don't seem to have ID numbers. How does the game determine which tiles belong to which tree if the tree has no ID?
Edit: It doesn't do what I thought it would do, just the name, description, and size. I thought there would be a way to view stuff like the reason for them acting in a certain way to stuff, like the conversations? Though maybe that isn't developed yet.
Also, how do I view the adventurer info like reputation/fame?
Why are you guys not answering my new questions?
When we don't know an answer, we tend to stay silent in case someone with more expertise in that particular area can chime in. Unfortunately, there isn't always a good answer, and we can't always tell when that's the case. Frequently, the experts are doing something else, such as playing the game or updating DFHack to the new version, instead of paying close attention to the thread.
In this case, it doesn't sound like there's a good script anywhere that does exactly what you want. However, you could try launching lua and poking around in the memory structures to see if something sounds like what you're looking for. In this case, historical_figure_info.reputation sounds promising.
Hello everyone!https://github.com/DFHack/dfhack/issues/282
I installed DFHack on my debian machine amd64 (df 40.08) but cannot get stonesense to work
I removed libstdc++ to use system one, installed liballegro:i386 but still no luck
now stderr says: df_linux/hack/plugins/stonesense.plug.so: undefined symbol: al_color_rgb_to_hsv
hints?
If you set more than a link to a stockpile, the linked list of "give: stockpile #1", "take: stockpile #2", ETC/ETC gets overlapped by: "J: No Job Selected" ??, its anybody else having this issue?
This one's my fault. I'm open to suggestions on a better place for the stockflow lines. Part of the trickiness is that the position of the links depends on the size of the window, and part is that I was working around Falconne's auto-trade/auto-melt/auto-dump plugin.
now stderr says: df_linux/hack/plugins/stonesense.plug.so: undefined symbol: al_color_rgb_to_hsvhttps://github.com/DFHack/dfhack/issues/282
hints?
https://github.com/DFHack/stonesense/pull/22/files
[ ... ]
For aesthetic reasons, I'm leaning toward overwriting the bottom of the link list. As long as lines are counted from the bottom, any overwritten lines are accessible by changing the window size, or by deleting a few links.
I have a question about this version of dfhack:No, you cannot - it will only work with 0.40.07 and 0.40.08, and the next version will only work with 0.40.09 and later (because of the new POLE worldgen parameter).
Can i use it with 0.40.03 df?
I regularly get into trouble with the link list as I only have a netbook. I know I am sort of in the tails of the curve :/ (oh, and that was already with .34, though it continues with .40). I favor the "overwirte the DONE line" solution, though this might look more messy.
Combining all three plugins would likely be a bit of a nightmare for you and Falconne, since you would create interdependencies between the three plugins. While that would probably result in the shortest (and potentially nicest) result, "you don't want to" [see his identification] (because of trouble).
I regularly get into trouble with the link list as I only have a netbook. I know I am sort of in the tails of the curve :/ (oh, and that was already with .34, though it continues with .40). I favor the "overwirte the DONE line" solution, though this might look more messy.
Dwarf Fortress can be played on a netbook‽
My current pull request (https://github.com/DFHack/dfhack/pull/290) overwrites the last three lines of the list, and sometimes the blank line below them, when all three plugins (stockflow, stocks, and autotrade) are enabled. At the minimum height of 25 lines, that leaves at least five links visible. Given a valid objection as the only response, though, I should consider alternatives.Five links should be ok, if they were visible ...
Would it be okay if I squish the extra lines out of the way only when they would overwrite a link? I should be able to figure out how many links there are to/from the selected stockpile...QuoteCombining all three plugins would likely be a bit of a nightmare for you and Falconne, since you would create interdependencies between the three plugins. While that would probably result in the shortest (and potentially nicest) result, "you don't want to" [see his identification] (because of trouble).
Currently, I'm considering something like "Auto: Trade Dump Melt" where the three word colors indicate their selection status. That way, each of the three plugins could write the "Auto:" part and its own word, leaving blank space where the other two plugins would write theirs.
The point is currently moot, though, unless and until auto-melting (https://github.com/falconne/dfhack/tree/plugin_automelt) and auto-dumping (https://github.com/falconne/dfhack/tree/plugin_autodump) from stockpiles get pulled from Falconne's fork into the main DFHack repository.
My current pull request (https://github.com/DFHack/dfhack/pull/290) overwrites the last three lines of the list, and sometimes the blank line below them, when all three plugins (stockflow, stocks, and autotrade) are enabled. At the minimum height of 25 lines, that leaves at least five links visible. Given a valid objection as the only response, though, I should consider alternatives.Five links should be ok, if they were visible ...
checking, I believe some screen layout changed...
Wait a minute, wasn't the link list at the very bottom or am I confusing stuff? Sorry for causing the confusion, but I was sure (unable to check since the save is inaccessible at the moment) that the links were at the bottom and having more than, dunno, five or so would make the last ones disappear. In .40.09 the links start really at the top. Sorry for ( the confusion caused ) OR ( being confused myself )
I'd like to add a second question to that: Does this r2 release only have ReactiobTrigger using registration, or does it have both this new system abd the old AutoSyndrome and SyndromeTrigger together?
help friends, stonesense overlay command freezes :(Yeah, stonesense is really buggy right nw.
help friends, stonesense overlay command freezes :(Yeah, stonesense is really buggy right nw.
Does it freeze on the first or second ime you open it?
My current pull request (https://github.com/DFHack/dfhack/pull/290) overwrites the last three lines of the list, and sometimes the blank line below them, when all three plugins (stockflow, stocks, and autotrade) are enabled. At the minimum height of 25 lines, that leaves at least five links visible. Given a valid objection as the only response, though, I should consider alternatives.Five links should be ok, if they were visible ...
checking, I believe some screen layout changed...
Wait a minute, wasn't the link list at the very bottom or am I confusing stuff? Sorry for causing the confusion, but I was sure (unable to check since the save is inaccessible at the moment) that the links were at the bottom and having more than, dunno, five or so would make the last ones disappear. In .40.09 the links start really at the top. Sorry for ( the confusion caused ) OR ( being confused myself )
No, you're right, the layout changed. In .34, the Done line was always on line 23, and the links started some number of lines from the bottom and worked their way up. Yes, that means that even the default interface had collisions for certain screen sizes, and stockflow was well positioned up near the main menu.
Now in .40, the Done line is always near the bottom, and the links start just below the main menu and work their way down, paging before they would hit the Done line. Nicer overall, but subtle enough that you don't notice the difference unless something else is being drawn on top.
So, I know it has been said so many times that it can't be done, but I just want to keep banging my head against a wall with this. I really want to explore all options to see what I can do with it.I have a script that restricts reactions, they only work if water is under or next to the workshop. You can still build the building where you like, but the reactions wont work. Would that help you?
I want to invalidate buildings when they aren't where I want them.
This has a very specific purpose for me, I really want to force buildings to be built over water. I thought with DFHack, that maybe if I grabbed building location, used some stuff from tiletypes to see if there is a water source under the building, and then (if I can find the hex) invalidate/validate the building appropriately.
I know, a lot to do, and running it on every building placement might slow things down, but I really want to get this, if it is possible.
At any time, did it ask you if you want to overwrite sdl.dll?
A little question about stockpiles and lua.
As I can see in stockflow.lua - stockpile is a bunch of tiles with special flags.
So, if I want to get all items in selected stockpile - I must flow through all "df.global.world.items.all" and compare their position/on_ground with coords of my stockpile' tiles?
There's no easiest way?
No, you're right, the layout changed. In .34, the Done line was always on line 23, and the links started some number of lines from the bottom and worked their way up. Yes, that means that even the default interface had collisions for certain screen sizes, and stockflow was well positioned up near the main menu.
Now in .40, the Done line is always near the bottom, and the links start just below the main menu and work their way down, paging before they would hit the Done line. Nicer overall, but subtle enough that you don't notice the difference unless something else is being drawn on top.
... which means it is overwritten by dfhack now:
j: no job selected
overwrites the second link
most stockpile applications would be happy with a simple list of stored items.
checking the items vector of each overlapping 16x16 map block, but that requires some calculations
There is an unnamed vmethod in df.buildings.xmlHow to call a numbered vmethod in lua? All vmethods in *.h are protected.
checking the items vector of each overlapping 16x16 map block, but that requires some calculations
function findItemsAtTile2(x, y, z)
local found = {}
local items = dfhack.maps.getTileBlock(x, y, z).items
for _, item_id in ipairs(items) do
local item = df.item.find(item_id)
if item.pos.x == x and item.pos.y == y and
item.pos.z == z and item.flags.on_ground then
found[#found+1] = item
end
end
return found
end
expwnent: Before you do extra work, I will try with registration and see how it goes. You mentioned a script a while ago that automatically reads out raws and creates the correct syntax? That would be fine, no need for you to port stuff before I at least have tested the new system. If you and Roses say its amazing, who am I to not us it. ;)
If vmethods are unnamed, then it means we don't know what they do (and, in some cases, what parameters they take), so attempting to call them could just make DF crash. Experimenting with unnamed vmethods from DFHack is also completely pointless - if you want to figure out what it does and how it's used, you disassemble the entire game (e.g. in IDA Pro) and then analyze the vmethod code directly (and, if possible, track down and identify the places that call it).There is an unnamed vmethod in df.buildings.xmlHow to call a numbered vmethod in lua? All vmethods in *.h are protected.
Meph: Let me know if you have trouble with the conversion script. It's probably a lot easier for me to tweak it than for you to manually do 500 registrations or however many there are.I am on vacation. ;) Beginning next month with it, I'll let you know.
http://pastebin.com/RCqzsd1Z
So I've identified those annoying (to me, anyways) leaf/fruit circles under trees as spatter structures in block_events, but deleting the structures (with erase()) does nothing, they're still quite visible.They aren't defined anywhere else - if you remove them from map_block.block_events[], they should disappear.
Where else might these be defined?
most stockpile applications would be happy with a simple list of stored items.
I'm a newbie in c++, so lua is my way.
For example, need to create "cut gems" jobs in linked workshop according stored rough gems in stockpile.
There is an unnamed vmethod in df.buildings.xmlHow to call a numbered vmethod in lua? All vmethods in *.h are protected.
A little change in hack/lua/plugins/stockflow.lua.
For test, I replaced function findItemsAtTile by this:Spoiler: Code (click to show/hide)
and run check_pile(stockpile, true)
Was: 101 sec.
Now: 1 sec.
If vmethods are unnamed, then it means we don't know what they do (and, in some cases, what parameters they take), so attempting to call them could just make DF crash. Experimenting with unnamed vmethods from DFHack is also completely pointless - if you want to figure out what it does and how it's used, you disassemble the entire game (e.g. in IDA Pro) and then analyze the vmethod code directly (and, if possible, track down and identify the places that call it).
Besides, there's no reason why Toady would put a stockpile-specific operation in a virtual method available within the base class - he'd put it as a non-virtual method directly within stockpile itself (which I'm pretty sure is what he's already doing).
My disassembly skills are rusty enough that just trying it to see what happens sounds much more fun, and potentially more fruitful. I never did get around to determining how the "xx% done" bit on the bookkeeper settings page gets calculated. (I found the viewscreen variable that caches it, but nothing else holds the same value consistently.)In all likelihood, random probing of vmethods will be totally fruitless, since even if they don't crash, they may appear to do nothing at all while instead having some obscure side effect on the game which will ruin any further testing efforts unless you test each one in complete isolation and monitor the entire game's memory for changes, by which point you'd be better off just disassembling it and seeing exactly what it does.
And I'm not opposed to a few crashes. Even if something goes wrong with the save, I can always git reset.
Oh. So there's no way we can call such a method once the symbols have been stripped?
Non-virtual class methods are infeasible to call on Windows due to whole program optimization (http://msdn.microsoft.com/en-us/library/0zza0de8.aspx), which stuffs function parameters (including "this") into random registers rather than putting them on the stack (and ECX), making it impossible to just call them as if they were function pointers (as we can for virtual class methods).
Couple questions:
1. This one may be a silly one, but does addReactionToShop(reaction_name,shop_name) work the way I think it does? Meaning can you add a reaction to a workshop mid-game? And will those reactions stay post-save-quit-reload?
2. Is there a script to allow only one of a particular building to be built? If not I can write one, but I figured I would ask first.
3. Is there an eventful command for triggering every season?
Well, I'm glad that most of the new structures are added on instead of removed outright. Most of the old scripts should still work.
That being said, has anyone been playing with trees? I've worked out how to change the tiles of a tree provided they are already part of that tree, but how does the game determine the tree's current shape? It doesn't seem to be all tree tiles within a cube, since adding new tree tiles within a tree's cube just creates a species-less 'tree' tile. Stranger still, trees don't seem to have ID numbers. How does the game determine which tiles belong to which tree if the tree has no ID?
There's a list of trees in the first map_block_column of the embark square, each of which has a list of all the branches in the tree, and their sizes. You have to modify that if you want to add new tiles to the tree. Keep in mind that the bounding box of the tree is kinda fixed after the tree is made, so you can't easily make ygdrassil, as far as I know.
Now I undertsand how the script works. It simply changes the unit's birth year to twenty years before the current one, which is gets with df.global.cur_year, and that's all well and good, but what I'd really like to do is to make it so that their birthday is tomorrow, so I don't have to wait too long before putting them to work and can still face looking myself in the mirror.
A simpler method: just change their profession. BABY and CHILD are simply professions that automatically change into DEFAULT (adult peasant) when the creature reaches their adult age. You can do this at any age.
In Lua: unit.profession = df.profession.NONESetting profession to NONE (-1) is bound to cause all sorts of problems - if you want to reset it to its default state, you want STANDARD (i.e. Peasant).
In Lua: unit.profession = df.profession.NONE
I am waiting dfhack since 0.40.09.
Important lesson has been learned; just because there’s a new version of DF doesn’t mean you should upgrade straight away!
Ugh... I'm trying to learn how to run DFHack... All I really know is reveal and prospect.
Can someone give me a step by step instruction on how to drop a masterwork steel longsword inside my wagon? I got a dwarf to make a steel long sword, so I'd like to only hack in (at least in that world) what already exists. Thanks!If you already have a steel longsword crafted, you can use dfhack to change its quality to 'masterpiece':
changeitem q 5
createitem BAR STEEL 5
Thanks a lot! I had the create item thing totally wrong, I thought it went
CREATEITEM:Sword_LONG:STEEL
createitem WEAPON:ITEM_WEAPON_SWORD_LONG STEEL
Also, it's still much better than remaining on 40.08.
Because there is a newer version, obviously.Also, it's still much better than remaining on 40.08.
Oh? Why?
There isn't an official release of DFHack for 0.40.09 or 0.40.10 yet.any unofficial for 0.40.10?
I'm not experiencing those problems on 0.40.09 or 0.40.10. What commits (dfhack and df-structures) are you building from?dfhack: https://github.com/quietust/dfhack/tree/eb221e1165ab4bdaebd6da3fccc47d90fdd8aa1d
Because of this change "Made people not so eager to jump in on the side of their relatives and friends if the relative/friend is berserk/etc."Also, it's still much better than remaining on 40.08.
Oh? Why?
Could be a bug with how I built it - I was using Visual Studio 2013, and I had to add includes forI hate tantrum spirals... One dwarf couldn't find a shell for a strange mood, so he freaks out and starts punching a nearby dwarf. Then their friends hopped in. Then the guys hauling equipment by hopped in. Then I sent my military to "handle it" by stationing ten marksdwarves nearby. Then a forgotten beast showed up. Then a thief gets in and steals an artifact adamantine short sword. Then the beast burns down the bedrooms. Then my military goes by the fight from the tantrum. They get involved. I start hitting my head off the table. And every last one of my dwarves get assigned to squads, given spears, and rushed at the beast. But they stop to join the tantrum. A little over one hundred armed dwarves fighting in one large room, a third of them dead already, so I just gave up and let everyone kill each other. Turns out I had a werebeast in the mix. That was a twelve game year old fortress.
Lost two rather progressed fortresses to tantrum spirals because of that in 40.08. Maybe it's my fortress design: all my dwarves tend to stick together in large public areas, so they see a friend going berserk and suddenly the entire fortress is fighting, death is everywhere, and everyone is mad as hell because all their friends died.
Yeah, you'll need Visual Studio 2010 on Windows - that's what DF uses, and using a different compiler version on Windows tends to cause difficult-to-diagnose crashes.I'm not experiencing those problems on 0.40.09 or 0.40.10. What commits (dfhack and df-structures) are you building from?dfhack: https://github.com/quietust/dfhack/tree/eb221e1165ab4bdaebd6da3fccc47d90fdd8aa1d
I used git submodule init/git submodule update to get the df-structures stuff.
Could be a bug with how I built it - I was using Visual Studio 2013, and I had to add includes for <algorithm> and <functional> to different spots and remove a few "using namespace std"s (because dfhack uses a bunch of variables named "count" which conflicted with <algorithm>'s std::count).
Is there a way to trigger a script to only run once on initial world load instead of on every load?
I can't seem to get DFHack to make me dragon bones. I'm trying to test out a reaction, but I don't have the needed dragon bones. I followed the steps from the wiki, create-items BONE CREATURE_MAT:DRAGON:BONE 10, but it'd just come up with another of the incredibly unhelpful how-to's of DFHack. Can I make dragon bones, or are they one of the items you can't make?
Can I turn a creature into a different one?
There is a way to do it with syndrome that has a CE_BODY_TRANSFORMATION tag in it.Can I turn a creature into a different one?
Creatures/units in Dwarf Fortress consist of pretty complex data structures, for example their individual bodyplan based on race/caste definitions and whatnot else. Converting into another race will be quite complicated, if not outright impossible.
Something like this should do ya for testing if df hack isn't being friendly:Next time, try actually testing your sample reaction, since that reaction will not work in any version of Dwarf Fortress - in fact, attempting it in version 0.40.09 caused the game to CRASH.Spoiler (click to show/hide)
I can't seem to get DFHack to make me dragon bones. I'm trying to test out a reaction, but I don't have the needed dragon bones. I followed the steps from the wiki, create-items BONE CREATURE_MAT:DRAGON:BONE 10, but it'd just come up with another of the incredibly unhelpful how-to's of DFHack. Can I make dragon bones, or are they one of the items you can't make?You want createitem - create-items is an entirely different script that only supports bars, boulders, plants, logs, webs, and anvils (from its documentation).
Can I turn a creature into a different one?
Creatures/units in Dwarf Fortress consist of pretty complex data structures, for example their individual bodyplan based on race/caste definitions and whatnot else. Converting into another race will be quite complicated, if not outright impossible.
unit.enemy.normal_race=0
unit.enemy.normal_caste=0
unit.enemy.were_race=0
unit.enemy.were_caste=0
Copy the raws from dragon bones over to cats?The game isn't smart enough to tell if two different items are indistinguishable, it would treat CREATURE_MAT:CAT:BONE and CREATURE_MAT:DRAGON:BONE as completely different. I suppose you try throwing a reaction class onto the material and dispense with the item ID.
Copy the raws from dragon bones over to cats?The game isn't smart enough to tell if two different items are indistinguishable, it would treat CREATURE_MAT:CAT:BONE and CREATURE_MAT:DRAGON:BONE as completely different. I suppose you try throwing a reaction class onto the material and dispense with the item ID.
Asking for ETAs never works.
On the bright side, 40.10 already works... somewhat, just check github forks and compile.
I think PE's looking for something stable to include in the Starter Pack, not a "user beware" version.
In addition, https://github.com/quietust/dfhack/tree/develop contains the change(s) needed to compile DFHack with 0.40.09-10 at the moment.
I just tried building from Quietust's branch (git clone https://github.com/quietust/dfhack.git), and it compiles fine, but when I run dfhack (using df 40.10) I don't get a dfhack console prompt, and when I exit and look at stderr.log, I see that it reports a bunch of dummy symbol entries, then:Did you update the xml submodules? Check the symbols.xml in df/hack to see if it contains the 40.10 structures for linux.Code: [Select]Loaded 6 DF symbol tables.
Unable to retrieve version information.
MD5: 0b7185da37ac3a729f0972c9aff512ca
Not a known DF version.
git clone git://github.com/quietust/dfhack.git
cd dfhack
git submodule init
git submodule update
This is why it's not really sufficient to say "just check github forks and compile." I'm a software engineer with about 25 years of experience, most of that doing build/release engineering, so I'm fairly experienced at building stuff from source. And even I'm having trouble with it. It took me a couple of hours to figure out which 32-bit libs I needed and get them all installed so it would build, plus figuring out that cmake was consistently finding the wrong zlib and figuring out how to override that. Heaven help someone with no experience building stuff.
Edit: Ok, I just discovered that I get the same HTTPS clone URL whether I'm on https://github.com/quietust/dfhack/tree/develop or https://github.com/quietust/dfhack/tree/master. So how do I tell git to grab the develop branch, not the master?
git fetch origin
git checkout develop
or git clone git://github.com/quietust/dfhack.git -b develop
Agreed (just shy of 10 years exp here ;)). If it's stable enough to "just check github forks and compile", why doesn't someone who's successfully done that publish a stable release so there's no guess work?Cough, zero years of experience here, cough. And I do publish, just get a mac. :D
Edit: Ok, I just discovered that I get the same HTTPS clone URL whether I'm on https://github.com/quietust/dfhack/tree/develop or https://github.com/quietust/dfhack/tree/master. So how do I tell git to grab the develop branch, not the master?
git checkout develop
or
git clone git://github.com/quietust/dfhack.git -b develop
Cough, zero years of experience here, cough. And I do publish, just get a mac. :DOP's current Mac release still points to 08.r2 :-P
I think PE's looking for something stable to include in the Starter Pack, not a "user beware" version.
Same thing for MDF. But I will start doing the Raws in the meantime. :)I think PE's looking for something stable to include in the Starter Pack, not a "user beware" version.
Yeah. If I wanted a version for myself, that would probably work, but I'd expect to be dealing with errors caused by my inexperience / incompetence for a while. For the people who use the starter packs, that's not really good enough.
git checkout develop && git pull
Instead of making a separate clone, you can add another remote pointing to Quietust's fork (merging changes from different forks is easier with a single clone):Edit: Ok, I just discovered that I get the same HTTPS clone URL whether I'm on https://github.com/quietust/dfhack/tree/develop or https://github.com/quietust/dfhack/tree/master. So how do I tell git to grab the develop branch, not the master?Code: [Select]git fetch origin
or
git checkout developCode: [Select]git clone git://github.com/quietust/dfhack.git -b develop
git remote add quietust https://github.com/quietust/dfhack
git fetch quietust
git checkout -b newbranch # optional
git merge quietust/develop
Yes it seems that with his latest commit Quietust's develop branch builds and hooks with no needed additional changes.I don't consider them complete enough to include in DFHack officially yet, but you're certainly welcome to test them out. :)
Also lethosor, am I missing something or are your own scripts (load-screen settings-manager etc.) missing from the main repo? They're pretty nifty though.
Because there is a newer version, obviously.Also, it's still much better than remaining on 40.08.
Oh? Why?
The OP only contains official releases and there's hasn't been one for .10 yet, even though you can still easily build your own once you're set up. But yeah, trying to find the one commit from the one tree from the one repo that will build, hook and run is a little bit like playing hide-and-seek. That's part of a decentralized project I guess, it has ups and downs.
Quietust's fork is only necessary when compiling DFHack for a new DF version before Quietust's changes are merged into DFHack/dfhack (which they were approximately 12 hours ago - dfhack:dfhack and quietust:dfhack are now identical (https://github.com/DFHack/dfhack/compare/quietust:develop...dfhack:develop)). DFHack:develop (https://github.com/dfhack/dfhack/tree/develop) should compile for 0.40.10 now.The OP only contains official releases and there's hasn't been one for .10 yet, even though you can still easily build your own once you're set up. But yeah, trying to find the one commit from the one tree from the one repo that will build, hook and run is a little bit like playing hide-and-seek. That's part of a decentralized project I guess, it has ups and downs.
Sorry but if you have to hunt for what repo to pull someone somewhere have done an awful job with keeping things clean.
Hi. I can't get dfhack to work. I am on a fresh install of Debian "Jessie" testing, the upcoming Debian release. My Linux is 64bit but I installed all the libraries I need (I think) in 32bit. Vanilla DF works fine. But when I try to start dfhack I get:
sander@porky:/opt/df_linux$ ./dfhack
./libs/Dwarf_Fortress: /opt/df_linux/libs/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./hack/libdfhack.so)
./libs/Dwarf_Fortress: /opt/df_linux/libs/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by ./hack/libdfhack.so)
./libs/Dwarf_Fortress: /opt/df_linux/libs/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by ./hack/libdfhack.so)
./libs/Dwarf_Fortress: /opt/df_linux/libs/libstdc++.so.6: version `CXXABI_1.3.5' not found (required by ./hack/libdfhack.so)
./libs/Dwarf_Fortress: /opt/df_linux/libs/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ./hack/libdfhack.so)
./libs/Dwarf_Fortress: /opt/df_linux/libs/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by ./hack/libprotobuf-lite.so)
-e
Any help? I have libstdc++6 installed in both 32bit and 64bit versions so I'm not sure what the problem is. Is this a problem with the libstdc++.so.6 file shipped by DF?
EDIT: I think I worked around it for now, but I haven't properly tested yet. dfhack starts, but I haven't run any game yet. What I did was move the provided libs/libstdc++.so.6 out of the way and replace it with a symlink to /usr/lib/gcc/i586-linux-gnu/4.9/libstdc++.so
Did you remove libstdc++ from DF/libs?
Did you remove libstdc++ from DF/libs?
I had not. I just tried removing it, and now DF runs when I run ./dfhack, but DFHack itself is not running. It doesn't throw an error of any kind.
It looks like my dfhack is expecting version 40.07 of DF. The md5sums don't match because I'm running 40.10. stderr.log shows an unknown version of DF. I'm guessing that's why hack quits. :)
Will it be helpful to edit symbols.xml with the correct version and md5sum, or does hack need to re-generate that file itself?
Did you remember to run "git submodule update"?
Not sure if this is an old bug or new or not a DFHack bug at all (DF seems to have some screen resizing issues atm), but the text for the DFHack-added UI functions displays as if the window has never been resized: http://i.imgur.com/A1JxrWk.png
This is not a big problem usually, but on certain screens (trading with merchants) it blocks entire rows of information.
I'm a simple guy with no software experience, would it be [possible] for me to download and compile df hack for 0.40.10 from github? And if so how?
I greatly appreciate all the work you guys put into this tool! Thank you.
That said, since I am just able to understand what you are talking about ... I am in no way able to compile "my own" windows build for 40.10 ... if someone has already done so, could he/she maybe put it up for download somewhere?
I would gladly take a "may crash be careful" build ;)
cheers
Check the dwarf's thoughts (v->z->enter) and you'll probably see that he/she is very unhappy for one reason or another.
Ah, yeah. Bad example pic - the DFHack text should be at the bottom of the screen though because it runs over the lists of 'give' entries: http://i.imgur.com/9AEI6DB.pngNot sure if this is an old bug or new or not a DFHack bug at all (DF seems to have some screen resizing issues atm), but the text for the DFHack-added UI functions displays as if the window has never been resized: http://i.imgur.com/A1JxrWk.png
This is not a big problem usually, but on certain screens (trading with merchants) it blocks entire rows of information.
Don't see a problem on your screenshot though.
You forget that you need cmake and perl as well.Oh right.
As for git, I can't live without tortoisegit.TortoiseGit is the only reason I still use Git at all, but in this case it's probably simpler to explain the command line.
Have you tried asking someone in the mead hall? I haven't played much adventure mode in 40.XX, but there seems to be a vastly greater opportunity to ask questions about nearly everything.
Actually, TortoiseGit is just a front-end for whatever commandline git program is in your PATH. It won't work without one of the other two installed.You forget that you need cmake and perl as well.Oh right.As for git, I can't live without tortoisegit.TortoiseGit is the only reason I still use Git at all, but in this case it's probably simpler to explain the command line.
(And I forget if TortoiseGit adds itself to PATH automatically like Github and mysysgit do.)
Compiling DFHack for Windows is actually really easy if explained, and it doesn't require a zillion programs, just four.
[...]
You need:
[...]
Visual Studio 2010 Express for C# (http://go.microsoft.com/?linkid=9709939)
Compiling DFHack for Windows is actually really easy if explained, and it doesn't require a zillion programs, just four.
You need:
CMake (http://www.cmake.org/cmake/resources/software.html)
Git - I prefer Github (https://windows.github.com/) or mysysgit (http://msysgit.github.io/) for these purposes (simple command line stuff).
Perl - Strawberry Perl (http://strawberryperl.com/) is simplest
Visual Studio 2010 Express for C# (http://go.microsoft.com/?linkid=9709939)
- Install all four of the above programs.
- Hold down Shift and right-click in an empty space on your desktop. Select "Open command window here".
- Type "git clone -b develop git://github.com/dfhack/dfhack.git" and hit Enter. (Remove the "-b develop" part if you don't want the development branch version, but you usually will.)
- Type "cd dfhack" and hit Enter.
- Type "git submodule init" and hit Enter.
- Type "git submodule update" and hit Enter.
- Close the command prompt and open the DFHack folder you just made and then open the Build folder inside of that.
- Double-click on 'generate-MSVC-gui.bat'.
- In the window that pops up, uncheck the box that says "DL_RUBY", then click Configure, and lastly click Generate.
- Close that window and enter the new VC2010 directory that was created and double-click on dfhack.sln.
- Open the "Solution Explorer" tab to the right, scroll down to "PACKAGE", and then right-click on it and hit "Build".
- When it eventually finishes running, open the new folder "_CPack_Packages", then the folder "win32", then the folder "ZIP", and you will have your very own zipped-up DFHack build.
New release!Thank.It is 5 days after df 0.40.10 release.
New release!
*dumps a Finished Goods bin full of golden crafts on the heads of the project members, fracturing the skull and tearing the brain!*
*Shazbot flees in horror!*
You could have just transferred the save back to dfhack 40_08r2. There weren't that many changes that'd break raws(in save games). Besides the one in dinit. Besides you may have to wait a while when you reload with 40_10 for some of the exe changes to bounce back in (morale and all that). It should have been do able anyways.Wrong - once you upgrade a save to a newer version (by loading and saving), you cannot load it in an older version anymore.
keybinding add Ctrl-Shift-Z@dwarfmode/Default "stocks show"
but this one doeskeybinding add Ctrl-Shift-S@dwarfmode/Default "stocks show"
./libs/Dwarf_Fortress: symbol lookup error: ./hack/libdfhack.so: undefined symbol: _Z10lua_gettopP9lua_State
Apart from recognizing some file paths, I don't know what this means or how I might fix/avoid it. Ideas?You should add the line from here (https://github.com/DFHack/df-structures/commit/b259a55e9ee9f1aa162af39757cfacc4bcf88527) for your OS to DF/hack/symbols.xml, under the correct <symbol-table> tag ("0.40.10 SDL" for Windows or "0.40.10 linux" for Linux) instead of editing the script. I'm not sure what the problem is if neither of those work, though.
DFHack errors are logged to stderr.log, not errorlog.txt, although a crash usually won't log anything.
Any idea if it would be feaseable to have some kind of tool to analyze NPCs in adventure mode to better understand what's going on? No idea what such a tool would do exactly though.
Curious why this doesn't workyou might need to set a X/Y/Z coord for where the items go.Spoiler (click to show/hide)
And whats the proper to way to force a building to give up its contents, without actually disassembling the building.
I have no idea what you mean by "analyze" or "what's going on".
hey, i use the current starter pack with dfhack and during my play i saw that red text appears in the dfhack console:It looks like a problem with repeat.lua - can you try replacing it with https://raw.githubusercontent.com/Furcube/dfhack/master/scripts/repeat.lua?
(http://s1.directupload.net/images/140830/temp/6um4y6pl.png) (http://www.directupload.net/file/d/3730/6um4y6pl_png.htm)
are these some errors i should be aware of or are these harmless? thx!
hey, i use the current starter pack with dfhack and during my play i saw that red text appears in the dfhack console:It looks like a problem with repeat.lua - can you try replacing it with https://raw.githubusercontent.com/Furcube/dfhack/master/scripts/repeat.lua?
(http://s1.directupload.net/images/140830/temp/6um4y6pl.png) (http://www.directupload.net/file/d/3730/6um4y6pl_png.htm)
are these some errors i should be aware of or are these harmless? thx!
Replace DF/hack/scripts/repeat.lua with that script, renaming it to repeat.lua if necessary. (It might be a good idea to make a copy of your current hack/scripts/repeat.lua, in case it doesn't work.)
If you change one thing (the repeat.lua script) and suddenly the game starts crashing on launch or when you use repeat, then yeah that would be evidence of it not working. Same thing for red text. Dwarves killing each other is typical tantrum behavior and probably unrelated :)Replace DF/hack/scripts/repeat.lua with that script, renaming it to repeat.lua if necessary. (It might be a good idea to make a copy of your current hack/scripts/repeat.lua, in case it doesn't work.)
thanks, one last question: how can i find out if it doesn't work? crashes? more red text? dwarves starting to kill each other? :D
hey, i use the current starter pack with dfhack and during my play i saw that red text appears in the dfhack console:It looks like a problem with repeat.lua - can you try replacing it with https://raw.githubusercontent.com/Furcube/dfhack/master/scripts/repeat.lua?
(http://s1.directupload.net/images/140830/temp/6um4y6pl.png) (http://www.directupload.net/file/d/3730/6um4y6pl_png.htm)
are these some errors i should be aware of or are these harmless? thx!
I want a pony.
No, its not. Please keep it about dfhack.
Getting this again:If anyone's interested, I went into /usr/lib and renamed liblua.so (it was a link to liblua.so.5.2, itself a link to liblua.so.5.2.3) to hide it and see what happens. DF/dfhack works fine.Code: [Select]./libs/Dwarf_Fortress: symbol lookup error: ./hack/libdfhack.so: undefined symbol: _Z10lua_gettopP9lua_State
Now, back to DFHack. lethosor, was this (http://www.bay12forums.com/smf/index.php?topic=126076.msg5619102) the fix you just tried for Xerberus?The fix for repeat.lua I suggested was from https://github.com/DFHack/dfhack/pull/308, which appears to have worked for Xerberus.
Now, back to DFHack. lethosor, was this (http://www.bay12forums.com/smf/index.php?topic=126076.msg5619102) the fix you just tried for Xerberus?The fix for repeat.lua I suggested was from https://github.com/DFHack/dfhack/pull/308, which appears to have worked for Xerberus.
(Is that supposed to be a forward slash in repeat.lua's path? I know nothing of that stuff, it just sticks out in the sea of red)Yes. The use of forward slashes there is intentional because they will work on all platforms in Lua (and usually C++).
Did you change "1 months" to "1 -timeUnits months"?Now, back to DFHack. lethosor, was this (http://www.bay12forums.com/smf/index.php?topic=126076.msg5619102) the fix you just tried for Xerberus?The fix for repeat.lua I suggested was from https://github.com/DFHack/dfhack/pull/308, which appears to have worked for Xerberus.
Did he PM you? The last I saw from him, he was saying this did not work.
I'm seeing the same issue and can confirm something is still broken after replacing that script.
Now, back to DFHack. lethosor, was this (http://www.bay12forums.com/smf/index.php?topic=126076.msg5619102) the fix you just tried for Xerberus?The fix for repeat.lua I suggested was from https://github.com/DFHack/dfhack/pull/308, which appears to have worked for Xerberus.
sorry for double post but this is another question / topic dfhack related.I believe this is only part of the MDF mod (and another mod), but you may be thinking of other performance improvements - take a look at Readme.rst (https://github.com/DFHack/dfhack/blob/master/Readme.rst#cleanup-and-garbage-disposal).
in my last fort in DF 40.09 i gave up duo to the FPS being kinda creepy slow (22 FPS), i had around 122 dwarves and at the time around 100 undead elves attacking me (which undoubtly was the reason for my lack). i have a intel core i5 4440 (4 x 3.2 ghz), i know DF runs on a single core but i would love to improve the FPS without drastically changing the gameplay experience. i know that in the old dfhack version (and in the masterwork mod) there is the option to simplify materials which seemed to increase the FPS drastically. now my question is if this option is already available in the current version (i just have to enter i command i don't know) or if this is still in developement for the current version.
thanks!
Anyone know of some symbol offsets I can manipulate to emulate nanofortress?Use "embark-tools".
sorry for double post but this is another question / topic dfhack related.
in my last fort in DF 40.09 i gave up duo to the FPS being kinda creepy slow (22 FPS), i had around 122 dwarves and at the time around 100 undead elves attacking me (which undoubtly was the reason for my lack). i have a intel core i5 4440 (4 x 3.2 ghz), i know DF runs on a single core but i would love to improve the FPS without drastically changing the gameplay experience. i know that in the old dfhack version (and in the masterwork mod) there is the option to simplify materials which seemed to increase the FPS drastically. now my question is if this option is already available in the current version (i just have to enter i command i don't know) or if this is still in developement for the current version.
thanks!
Can workflow watch for filled sand bags? And what would the command look like if it can, my guesses led to nothing so far.
Thanks! Never used the gui before, I search for the names in the forum and raws, but this one had me stumped, your system sounds a lot easier.Can workflow watch for filled sand bags? And what would the command look like if it can, my guesses led to nothing so far.
workflow amount POWDER_MISC/SAND 105 10
In the future, you can use the gui to add a limit and then "workflow list-commands" to get the command you'd use in a world-start script
Can workflow watch for filled sand bags? And what would the command look like if it can, my guesses led to nothing so far.
workflow amount POWDER_MISC/SAND 105 10
In the future, you can use the gui to add a limit and then "workflow list-commands" to get the command you'd use in a world-start script
set it into a "LNP_dfhack_onLoad" init
:lua dfhack.onStateChange.onloadscript = function(state) if state == SC_WORLD_LOADED then print(dfhack.run_command('script dfhack_onLoad.init')) end end
set it into a "LNP_dfhack_onLoad" init
As i know, this file overwrites automatically.
I just create dfhack_onLoad.init in df folder and put next line to my dfhack.init:Code: [Select]:lua dfhack.onStateChange.onloadscript = function(state) if state == SC_WORLD_LOADED then print(dfhack.run_command('script dfhack_onLoad.init')) end end
Spoiler (click to show/hide)
Interesting, so you prefer for your dwarves to just continue digging as they find interesting material... do you ever run into issues where they dig new access points to the fortress? Undefended ones?
And do you know why workflow drink doesn't work?
Interesting, so you prefer for your dwarves to just continue digging as they find interesting material... do you ever run into issues where they dig new access points to the fortress? Undefended ones?
And do you know why workflow drink doesn't work?
I'm always can do "digFlood digAll0", and back again with "script digflood.txt"
Maybe you need use "workflow amount DRINK 10000 1" (with caps) because it it raw token?
Taken from my working workflow.txt script loaded from my dfhack_onLoad.init
Do you know of a way to modify the script so it only fires on initial embark?
script my_embark.txt
Do you know of a way to modify the script so it only fires on initial embark?Hmmm, don't understand.
Do you want to load script only one time when you desired?
Create a file named my_embark.txt in df folder, add all your wishes there, like:and just run it in dfhack console after embark, eg:Spoiler (click to show/hide)Code: [Select]script my_embark.txt
PS: And you don't need "load into workflow from the start" - workflow saves all jobs into df save.
Is there a way to trigger a script to only run once on initial world load instead of on every load?In lua'value' could be any true value, it's not actually even saving the boolean 'true', but rather an empty string. Which is a true value.Spoiler (click to show/hide)
Is 3dveins supposed to work? I've run it in the latest Starter Pack and it looks like it's frozen the app (I've let it sit for over an hour at this point).I haven't had any problems with it. Is it displaying any progress? What's your local map size?
Is 3dveins supposed to work? I've run it in the latest Starter Pack and it looks like it's frozen the app (I've let it sit for over an hour at this point).I haven't had any problems with it. Is it displaying any progress? What's your local map size?
[DFHack]# forum-dwarves
<viewscreen_textviewerst: 0x15481930>
child = nil
parent = <viewscreen_itemst: 0x14d2da10>
breakdown_level = 0
option_key_pressed = 0
title = (prepared llama heart [5])
title_colors =
src_text = <vector<string*>: 0x15481978>
outvar_type =
outvar_name =
meeting_context = <meeting_context: 0x154819c0>
help_filename = text_viewer
page_filename =
formatted_text = <vector<viewscreen_textviewerst.T_formatted_text*>: 0x15481a08>
hyperlinks = <vector<char*>: 0x15481a18>
logged_error = 0
scroll_pos = 0
cursor_line = 0
pause_depth = 0
<viewscreen_textviewerst.T_formatted_text: 0x16dd8c60>
text = <char: 0x155ef618>
format = <char: 0x155ef420>
flags = <viewscreen_textviewerst.T_formatted_text.T_flags: 0x16dd8c68>
pause_depth = 0
return_val = -1
indent = 0
<char: 0x155ef618>
value = 84
...Documents\df\df_40_10_win\hack\scripts/forum-dwarves.lua:73: bad argument #1 to 'find' (string ex
pected, got userdata)
stack traceback:
[C]: in function 'find'
...Documents\df\df_40_10_win\hack\scripts/forum-dwarves.lua:73: in function 'format_for_foru
m'
...Documents\df\df_40_10_win\hack\scripts/forum-dwarves.lua:116: in main chunk
(...tail calls...)
That happens regardless of the item being examined; the script just fails.
3dveins had never worked for me in DFHack40.08-r2 or DFHack40.10-r1. I always use a 4x4 embark (I honestly never thought of trying another lol). It output "Collecting statistics" in the dfhack console then 2-5 secs later the windows crash screen came up for Dwarf Fortress.exe. I've tried it on 6 embarks over 2 (medium all the way) worlds, that were genned on 40.08, using PE's starter packs.It could be a world-specific issue - there's no difference between the DFHack build from this thread and the one included in PE's pack.
I've downloaded PE's starter pack 40.10 r4 and genned a new medium world on it. Tried 1 3x3 embark(at the place the cursor starts) 3dveins completes successfully. Tried 1 4x4 embark(same place), completes successfully. Tried 2 more embarks 4x4 at some random places on the 40.10 genned world with no issues too.
I tried copying over my 40.08 genned map, loaded up a just arrived save, same old crash. Maybe it is just a problem with some worlds or something that was fixed in 40.10 either in DF or dfhack or the plugin.
So... has anyone figured out how to add new tiles to a tree yet?I don't think so - the only solution I'm aware of for growing trees is to set a timer to one tick before they should grow. https://github.com/DFHack/df-structures/blob/master/df.plants.xml#L49 seems relevant.
So... has anyone figured out how to add new tiles to a tree yet?df.global.world.map.map_block_columns[c].plants[p].tree_info.body is the right place, but you can't really properly access it in lua, because lua can't really do two dimensional arrays. it's actually tree_info.body[z][x+y*width].bits.whatever
I can change a tile to a branch/twig/trunk tile, but I can't find where the trees themselves store their shape data, so the new tiles are just generic branches/twigs/trunks without a species, not actually a part of any tree.
The most promising spot I've found is df.global.world.map.map_block_columns[c].plants[p].tree_info.body.value, but that's just a list of booleans where it looks like there ought to be arrays...
Anyone able to help? I want to make a tree-manipulating magic system but right now I'm stumped...
3dveins had never worked for me in DFHack40.08-r2 or DFHack40.10-r1. I always use a 4x4 embark (I honestly never thought of trying another lol). It output "Collecting statistics" in the dfhack console then 2-5 secs later the windows crash screen came up for Dwarf Fortress.exe. I've tried it on 6 embarks over 2 (medium all the way) worlds, that were genned on 40.08, using PE's starter packs.
I've downloaded PE's starter pack 40.10 r4 and genned a new medium world on it. Tried 1 3x3 embark(at the place the cursor starts) 3dveins completes successfully. Tried 1 4x4 embark(same place), completes successfully. Tried 2 more embarks 4x4 at some random places on the 40.10 genned world with no issues too.
I tried copying over my 40.08 genned map, loaded up a just arrived save, same old crash. Maybe it is just a problem with some worlds or something that was fixed in 40.10 either in DF or dfhack or the plugin.
3dveins had never worked for me in DFHack40.08-r2 or DFHack40.10-r1. I always use a 4x4 embark (I honestly never thought of trying another lol). It output "Collecting statistics" in the dfhack console then 2-5 secs later the windows crash screen came up for Dwarf Fortress.exe. I've tried it on 6 embarks over 2 (medium all the way) worlds, that were genned on 40.08, using PE's starter packs.
I've downloaded PE's starter pack 40.10 r4 and genned a new medium world on it. Tried 1 3x3 embark(at the place the cursor starts) 3dveins completes successfully. Tried 1 4x4 embark(same place), completes successfully. Tried 2 more embarks 4x4 at some random places on the 40.10 genned world with no issues too.
I tried copying over my 40.08 genned map, loaded up a just arrived save, same old crash. Maybe it is just a problem with some worlds or something that was fixed in 40.10 either in DF or dfhack or the plugin.
Interesting. I'm using r3, so maybe I'll try an increment.
Could anyone explain how I go about using item-trigger in the RAWs? I can't seem to find anything on it other than an explanation of its function. My apologies if I am missing anything.
EDIT: More broadly, are there examples or a how-to-use the modtools (https://github.com/DFHack/dfhack/blob/master/Readme.rst#modtools) mentioned in the readme? Because the readme itself only explains what they do, not how to apply them.
# example syntax
modtools/item-trigger -material INORGANIC:GOLD -command [ devel/printArgs "gold item equipped!" ] -onEquip
modtools/item-trigger -material CREATURE_MAT:DWARF:SKIN -command [ devel/printArgs "dwarf skin item? gross. put it back down." ] -onEquip
modtools/item-trigger -itemType ITEM_WEAPON_SPEAR -onStrike -command [ devel/printArgs "spear strikes target!" ]
Anyone know of some symbol offsets I can manipulate to emulate nanofortress?Use "embark-tools".
Edit: To be specific, "embark-tools enable nano".
embark_site is not a recognized command.
Invalid hotkey command: 'embark_site nano'
keybinding add Alt-N@choose_start_site "embark_site nano"
Basically the only documentation right now is modtools/blah -help and the readme. Do you have any specific questions about how to use them? I'm not sure what you want.Just wanted to know how to use them. Thanks for the help.
Where is onLoad.init located? Checked the dfhack files and couldn't find it. Assuming I have to create it, where does it go?Could anyone explain how I go about using item-trigger in the RAWs? I can't seem to find anything on it other than an explanation of its function. My apologies if I am missing anything.
EDIT: More broadly, are there examples or a how-to-use the modtools (https://github.com/DFHack/dfhack/blob/master/Readme.rst#modtools) mentioned in the readme? Because the readme itself only explains what they do, not how to apply them.
The various modtools were discussed here (http://www.bay12forums.com/smf/index.php?topic=139781.0). I don't believe that there has been much other information about them, but you basically don't modify anything in the raws, you put everything into onLoad.init now, example syntax from expwnent's postCode: [Select]# example syntax
modtools/item-trigger -material INORGANIC:GOLD -command [ devel/printArgs "gold item equipped!" ] -onEquip
modtools/item-trigger -material CREATURE_MAT:DWARF:SKIN -command [ devel/printArgs "dwarf skin item? gross. put it back down." ] -onEquip
modtools/item-trigger -itemType ITEM_WEAPON_SPEAR -onStrike -command [ devel/printArgs "spear strikes target!" ]
But if it only appears after genning a world, how can I, for example, set a specific god to be created for every world with moddable-gods?You could create an onLoad.init in DF/raw, which should be copied to the 'raw' folder of new saves, but this won't apply to existing saves. I'm hoping to implement a global onLoadWorld.init in the next version of DFHack, but something like this should work for now (placed in dfhack.init, which loads onLoad.init in the main DF directory):
:lua dfhack.onStateChange.foo = function(state) if state == SC_WORLD_LOADED then print((dfhack.run_command('script onLoad.init'))) end end
Placing it in dfhack.init will work as a global onLoad.init, placing onLoad.init into the objects/raw/onLoad.init will mean that any world you generate will get a copy of it put into that worlds file.If moddable-gods needs to be run when a world is loaded, it won't work in dfhack.init (I'm not sure if this is the case, though).
The template god is the first god that is found through a linear search of the hist fig vector.The worlds genned to test wheter or not I had used the script correctly had gods, so I guess the latter.
Basically, either your world's got no gods or the flag that determines whether a god is a god has been changed in 0.40.
Yes, but the syndrome has to have a name. See the modtools/add-syndrome script for details.
does anybody know, how to turn off those "urist is now a rusty ..." announcements?I think those announcements are generated by the soundsense script. Open dfhack.init, and deactivate the line with #. Or change it to soundsense-season.
does anybody know, how to turn off those "urist is now a rusty ..." announcements?I think those announcements are generated by the soundsense script. Open dfhack.init, and deactivate the line with #. Or change it to soundsense-season.
Siege forcing doesn't work anymore.
'mapexport' doesn't seem to be recognized in 40.10 any more. Ah well. I guess the venerable 'Overseer 0.7' has to be shelved for good now.That's because it was disabled due to large trees changing the map format significantly - even if you were able to export it, those old programs wouldn't understand the new tiles anyways.
I've done some experimentation and discovered the following (in 40.10):
If a plant is not found on an embark, that is, if the biome doesn't support it, even if you have seeds, you can't plant it.
In particular, if you have Hemp seeds, they don't appear in the list of plants you can sow on a surface field, unless Hemp could grow there "naturally".
I'd like to know if DFHack can adjust/expand the list of available plants that can be sown, currently, or if this would be new functionality? In short, I'd like to be able to plant with the seeds I have.
Specifics:
These crops seem to always be available to be sown, on the surface/above ground, even if you don't have seeds:
Alfalfa
Barley
Blade Weed
Caper bushes
Fisher berries
Hide root
Lentil plants
Longland grass
Potato plants
Prickle berries
Rat weed
Red spinach
Rope reeds
Rye
Sliver barbs
Strawberry plants
Sun Berries
Whip vines
while others (like cotton, hemp, and others) are biome dependent (or have some other key to unlock their availability)
I've done some experimentation and discovered the following (in 40.10):
If a plant is not found on an embark, that is, if the biome doesn't support it, even if you have seeds, you can't plant it.
In particular, if you have Hemp seeds, they don't appear in the list of plants you can sow on a surface field, unless Hemp could grow there "naturally".
I'd like to know if DFHack can adjust/expand the list of available plants that can be sown, currently, or if this would be new functionality? In short, I'd like to be able to plant with the seeds I have.
Specifics:
These crops seem to always be available to be sown, on the surface/above ground, even if you don't have seeds:
Alfalfa
Barley
Blade Weed
Caper bushes
Fisher berries
Hide root
Lentil plants
Longland grass
Potato plants
Prickle berries
Rat weed
Red spinach
Rope reeds
Rye
Sliver barbs
Strawberry plants
Sun Berries
Whip vines
while others (like cotton, hemp, and others) are biome dependent (or have some other key to unlock their availability)
Thats how it has always been, there is the [BIOME] token in the plant_standard.txt raws. Changing those will allow you to plant in different biomes.
I believe I now have reasonably working builds of DFHack both with and without Stonesense for 0.40.11.Can't load plugin. :(
I think I've chased down and squashed all the bugs that were plaguing the OS X build of Stonesense previously. However, I would appreciate some feedback on it, whether it works or not.
I believe I now have reasonably working builds of DFHack both with and without Stonesense for 0.40.11.Can't load plugin. :(
I think I've chased down and squashed all the bugs that were plaguing the OS X build of Stonesense previously. However, I would appreciate some feedback on it, whether it works or not.
Anything in stderr.log? Do you have libfreetype accessible?I believe I now have reasonably working builds of DFHack both with and without Stonesense for 0.40.11.Can't load plugin. :(
I think I've chased down and squashed all the bugs that were plaguing the OS X build of Stonesense previously. However, I would appreciate some feedback on it, whether it works or not.
otool -L stonesense.plug.so:
libdfhack.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
@executable_path/hack/libs/liballegro.5.0.dylib (compatibility version 5.0.0, current version 5.0.9)
@executable_path/hack/libs/liballegro_primitives.5.0.dylib (compatibility version 5.0.0, current version 5.0.9)
@executable_path/hack/libs/liballegro_font.5.0.dylib (compatibility version 5.0.0, current version 5.0.9)
@executable_path/hack/libs/liballegro_color.5.0.dylib (compatibility version 5.0.0, current version 5.0.9)
@executable_path/hack/libs/liballegro_image.5.0.dylib (compatibility version 5.0.0, current version 5.0.9)
@executable_path/hack/libs/liballegro_ttf.5.0.dylib (compatibility version 5.0.0, current version 5.0.9)
libprotobuf-lite.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
/opt/local/lib/libgcc/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.20.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 2577.0.0)
/opt/local/lib/libgcc/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
Nemesis is probably the animal itself; not sure exactly why it's called that, but it is called that by DF itself.In Dwarf Fortress, a "nemesis" record is what binds a Unit and a Historical Figure together and keeps track of where the unit can be found (namely, which unit-*.dat file contains it). If a unit-*.dat file gets corrupted or deleted, then when the game tries to load a particular unit from it (and fails) it terminates with a "Nemesis Unit Load Failed" error message.
Nemesis is probably the animal itself; not sure exactly why it's called that, but it is called that by DF itself.In Dwarf Fortress, a "nemesis" record is what binds a Unit and a Historical Figure together and keeps track of where the unit can be found (namely, which unit-*.dat file contains it). If a unit-*.dat file gets corrupted or deleted, then when the game tries to load a particular unit from it (and fails) it terminates with a "Nemesis Unit Load Failed" error message.
When I pared down a spawn-unit script to make just animals, I just removed the entire nemesis portion because I didn't think an unintelligent creature could consciously decide that someone is an enemy (Jaws and Moby Dick notwithstanding).If you're going to remove the Nemesis portion, then you must also remove the Historical Figure information with it, since the game will likely get very confused if it finds a historical figure with no nemesis record, potentially by crashing outright. Once your animal kills a historical figure, the game will automatically make it into one (and create a Nemesis record for it as well).
Thanks for the help, crashing makes for a poor player experience. I'm fine with these guys being simple non-historical animals, so I'll wade through the script and see if I can prune out all of the historical figure parts.When I pared down a spawn-unit script to make just animals, I just removed the entire nemesis portion because I didn't think an unintelligent creature could consciously decide that someone is an enemy (Jaws and Moby Dick notwithstanding).If you're going to remove the Nemesis portion, then you must also remove the Historical Figure information with it, since the game will likely get very confused if it finds a historical figure with no nemesis record, potentially by crashing outright. Once your animal kills a historical figure, the game will automatically make it into one (and create a Nemesis record for it as well).
When I pared down a spawn-unit script to make just animals, I just removed the entire nemesis portion because I didn't think an unintelligent creature could consciously decide that someone is an enemy (Jaws and Moby Dick notwithstanding).If you're going to remove the Nemesis portion, then you must also remove the Historical Figure information with it, since the game will likely get very confused if it finds a historical figure with no nemesis record, potentially by crashing outright. Once your animal kills a historical figure, the game will automatically make it into one (and create a Nemesis record for it as well).
FWIW, the animal I was referring too is not a historical figure. In fact, it was a wild boar piglet, which was born on the map and is guaranteed to not have killed anything, much less anything historical. However, the wild boar does in fact have a hist_figure_id setIf a creature's hist_figure_id is not equal to -1, then by definition it is a historical figure. It's possible that the act of training it makes it into a hist figure, perhaps in order to assign entity/site membership to it.
Yeah, not sure where people get this idea that hist figures have to be legendary in some way (I.E flashing or having killed something important). It's certainly not the case--all of your fortress citizens are hist figures, every single person your adventurer talks to becomes a hist figure right then and there if they weren't already, among other things.also the whole historical figure nemesis bit is there in case you want to jump into their bodies for adventure mode and not having the game horribly bug out doing so.
Yeah, not sure where people get this idea that hist figures have to be legendary in some way (I.E flashing or having killed something important). It's certainly not the case--all of your fortress citizens are hist figures, every single person your adventurer talks to becomes a hist figure right then and there if they weren't already, among other things.also the whole historical figure nemesis bit is there in case you want to jump into their bodies for adventure mode and not having the game horribly bug out doing so.
oh and I thought I already fix spawn units?
Yeah, not sure where people get this idea that hist figures have to be legendary in some way (I.E flashing or having killed something important). It's certainly not the case--all of your fortress citizens are hist figures, every single person your adventurer talks to becomes a hist figure right then and there if they weren't already, among other things.So these creatures might be spawned as wild animals (civ -1) or already tame (members of the player's civ). If I understand you and Quietust correctly, they should spawn historical with nemesis data. Having a few wild animals in there won't crash Legends.
yes (https://gist.github.com/Rumrusher/f4d0ba18ba6868d38221)Yeah, not sure where people get this idea that hist figures have to be legendary in some way (I.E flashing or having killed something important). It's certainly not the case--all of your fortress citizens are hist figures, every single person your adventurer talks to becomes a hist figure right then and there if they weren't already, among other things.also the whole historical figure nemesis bit is there in case you want to jump into their bodies for adventure mode and not having the game horribly bug out doing so.
oh and I thought I already fix spawn units?
That is entirely possible. I was working off an old 34.11r3 script that I then pruned (incorrectly it turns out) and then tacked on a couple bits specific to the mod I'm working on.
Is there a unit spawning script for 40?
Couple questions...
1. Is it possible to pause world generation and run a script in the middle of it? Namely in between when civilizations are placed and history starts running.
2. Has anyone played with adding noble positions using DFHack? It seems like all the pertinent information is there, but I am unsure how it would effect gameplay and if the position would be used by the computer or would even be usable by the players.
3. Similarly, Ethics, is there any effect on gameplay, changing them in game?
4. I know there is a quick way to find material id and index using df.mat_find (or whatever the function is, not at my DF computer right now), is there a similar way to find a creatures id and caste id? How about for things like leathers? (I am looking to be able to add and remove all the different types of items and materials from an entity using DFHack, and to do that I need to be able to find the correct indices for the things to add/remove).
yes (https://gist.github.com/Rumrusher/f4d0ba18ba6868d38221)
Couple questions...
1. Is it possible to pause world generation and run a script in the middle of it? Namely in between when civilizations are placed and history starts running.
2. Has anyone played with adding noble positions using DFHack? It seems like all the pertinent information is there, but I am unsure how it would effect gameplay and if the position would be used by the computer or would even be usable by the players.
3. Similarly, Ethics, is there any effect on gameplay, changing them in game?
4. I know there is a quick way to find material id and index using df.mat_find (or whatever the function is, not at my DF computer right now), is there a similar way to find a creatures id and caste id? How about for things like leathers? (I am looking to be able to add and remove all the different types of items and materials from an entity using DFHack, and to do that I need to be able to find the correct indices for the things to add/remove).
for question 2: The Dwarven Higher learning mod does this, although I don't think the librarian position has any actual duties. The mod was created for 34.x but if you manually apply the raw file changes it appears to work in 40.x (I only use the medical ward part of the mod - I don't like the thought of subjecting patients to a surgeon with rusty skills).
For some reason I can't fathom falconne's hotkeys plugin has been wiped out from the latest reposAs far as I can tell, it has never been in DFHack/dfhack (at least, not in 0.34.11-r1, 0.34.11-r3, 0.34.11-r5, 0.40.08-r1, or 0.40.11-r1).
can't remember where, but Falconne posted within the last week or so saying life's been hectic and/or (s)he's been waiting on the DF updates to slow down before tackling upgrading the plugins to .40.For some reason I can't fathom falconne's hotkeys plugin has been wiped out from the latest reposAs far as I can tell, it has never been in DFHack/dfhack (at least, not in 0.34.11-r1, 0.34.11-r3, 0.34.11-r5, 0.40.08-r1, or 0.40.11-r1).
Edit: Falconne's plugins are in this thread (http://www.bay12forums.com/smf/index.php?topic=119575.0), although they were last updated for 0.34.11-r5 - only some of them are included in the official DFHack repo (and I'm not sure if the ones in Falconne's thread contain unmerged changes).
As far as I can tell, it has never been in DFHack/dfhack (at least, not in 0.34.11-r1, 0.34.11-r3, 0.34.11-r5, 0.40.08-r1, or 0.40.11-r1).
Edit: Falconne's plugins are in this thread (http://www.bay12forums.com/smf/index.php?topic=119575.0), although they were last updated for 0.34.11-r5 - only some of them are included in the official DFHack repo (and I'm not sure if the ones in Falconne's thread contain unmerged changes).
I think just because no one is aware they work, officially or otherwise.As far as I can tell, it has never been in DFHack/dfhack (at least, not in 0.34.11-r1, 0.34.11-r3, 0.34.11-r5, 0.40.08-r1, or 0.40.11-r1).
Edit: Falconne's plugins are in this thread (http://www.bay12forums.com/smf/index.php?topic=119575.0), although they were last updated for 0.34.11-r5 - only some of them are included in the official DFHack repo (and I'm not sure if the ones in Falconne's thread contain unmerged changes).
Oh. Is there any reason as to why some plugins were included and not the other ones (namely hotkeys and automelt)? Because they build and run fine on .40.11 for me, I could provide binaries for various OSes if people are interested.
Sorry about the lack of updates, I've been busy on some other projects. Will try to get on it soon. I was hoping to wait till the DF updates slowed down.
Unless I'm missing something this plugin is absent in the latest repo for .40.x. Is the source available so we can at least build it ourselves? I find this hotkey plugin very useful and very much miss it in the latest version.
That, and the fact that nobody has merged them into the official DFHack repo yet - feel free to submit a pull request (https://github.com/dfhack/dfhack/pulls).I think just because no one is aware they work, officially or otherwise.As far as I can tell, it has never been in DFHack/dfhack (at least, not in 0.34.11-r1, 0.34.11-r3, 0.34.11-r5, 0.40.08-r1, or 0.40.11-r1).
Edit: Falconne's plugins are in this thread (http://www.bay12forums.com/smf/index.php?topic=119575.0), although they were last updated for 0.34.11-r5 - only some of them are included in the official DFHack repo (and I'm not sure if the ones in Falconne's thread contain unmerged changes).
Oh. Is there any reason as to why some plugins were included and not the other ones (namely hotkeys and automelt)? Because they build and run fine on .40.11 for me, I could provide binaries for various OSes if people are interested.
Here's....you?....asking where to get the source for hotkey (and not getting an answer that I saw):I looked further and the source was actually buried in falconne's repos. So since no one knew what happened to the missing plugins I just built them myself.
And by "feel free" he means "dear god hurry up and do one" because I'd really like to see those plugins too... :ohdear:Huh I don't have a github account but here are binaries:
009B6D10: 4B 30
009B6D11: 00 4B
5. does not persist. Need to run each load (also just had an idea to extend this to run some code and check some prerequisites). No need for permissions (iirc)
6. removes native reactions. To be used for disabling hardcoded workshops or replacing (with 5.) their reactions
7. no. it needs a bit more tweaking after creation. I'm a bit rusty on this front... and still haven't finished "THE IMPLEMENTATION THAT WILL BE USED FOR EVERYTHING" of this (i.e. more stable, more features, other plugins could use it, etc...)
8. yes (i think) there is tame level, also there is civ id and a few flags (hopefully somebody has more info)
2. it's possible (have been doing that) but never with any intention of real use.
3. i'm pretty sure they don't have any effect on game
1 might be possible, but you'd have to be careful to catch worldgen fast enough and use a CoreSuspend object in C++.Thanks for all the responses, two more slightly specific questions
However, I cannot actually achieve patching. I try to use following line in dfhack.init:
binpatch apply pressureplate_04011.dif
I also tried explicitly targeting the executable, but there's no difference:
binpatch apply "Dwarf Fortress.exe" pressureplate_04011.dif
It says patch applied, but I see no change.
pressureplate_04011.dif itself looks like this:Code: [Select]009B6D10: 4B 30
009B6D11: 00 4B
Isn't that supposed to work?
fix-armory hasn't been updated to 0.40.xx yet, as far as I can tell - its line in CMakeLists.txt is currently commented out (https://github.com/DFHack/dfhack/blob/master/plugins/CMakeLists.txt#L118), so it's not included in any 0.40.xx builds of DFHack.
However, I cannot actually achieve patching. I try to use following line in dfhack.init:
binpatch apply pressureplate_04011.dif
I also tried explicitly targeting the executable, but there's no difference:
binpatch apply "Dwarf Fortress.exe" pressureplate_04011.dif
It says patch applied, but I see no change.
pressureplate_04011.dif itself looks like this:Code: [Select]009B6D10: 4B 30
009B6D11: 00 4B
Isn't that supposed to work?
It works for me. I did this:I concluded that the patch does change the weight strings.
- Extracted df_40_11_win_s.zip to a new test directory,
- Extracted dfhack-0.40.11-r1-Windows.7z there,
- Created a subdirectory named hack\patches\v0.40.11 SDL ,
- In that subdirectory, created a file named pressureplate_04011.dif ,
- Pasted your patch content into that file,
- And started DF to the main menu.
- At the DFHack commandline,
- binpatch check pressureplate_04011
- Note that I did not append the .dif extension.
- binpatch apply pressureplate_04011
- binpatch remove pressureplate_04011
- DFHack did not complain about any of that, which surprised me a bit.
- Then I created a pocket world and started a new embark, crafted a few mechanisms,
- And began to construct a creature-triggered pressure plate. I noted the min weight of 5K.
- I backed out of all the menus, and again did:
- binpatch apply pressureplate_04011
- And constructed a pressure plate. I noted the min weight of 50K.
I suggest checking your patch file. Are you using the right command? Is the file in the right place? Do you have multiple copies scattered around, with different contents? Do you have a file named pressureplate_04011.dif.dif ? (Note the doubled extension.)
binpatch apply pressureplate_04011
the prompt says that the patch was applied (if it doesn't find the file it clearly states in red that it can't find the patch). But when I check for changes like thisbinpatch check pressureplate_04011
it always says that the patch is removed, which means that no changes were actually made. Thank you for answers and suggestion. I have no idea why it doesn't work for me, I even tried the steps you describe, starting with downloading df_40_11_win_s.zip. Could you please tell what "check" function of binpatch returns after successfully applying the patch?
When I apply the patch, like thisCode: [Select]binpatch apply pressureplate_04011
the prompt says that the patch was applied (if it doesn't find the file it clearly states in red that it can't find the patch). But when I check for changes like thisCode: [Select]binpatch check pressureplate_04011
it always says that the patch is removed, which means that no changes were actually made.
What worries me is if I deliberately put a wrong value in the patch file, like changing expected original value of 4B to 4A for example, then applying the patch also says that it was applied. Which means the function returned success even though it shouldn't/couldn't, instead it that example it should write something like "conflict at address" I think.
5. does not persist. Need to run each load (also just had an idea to extend this to run some code and check some prerequisites). No need for permissions (iirc)
6. removes native reactions. To be used for disabling hardcoded workshops or replacing (with 5.) their reactions
7. no. it needs a bit more tweaking after creation. I'm a bit rusty on this front... and still haven't finished "THE IMPLEMENTATION THAT WILL BE USED FOR EVERYTHING" of this (i.e. more stable, more features, other plugins could use it, etc...)
8. yes (i think) there is tame level, also there is civ id and a few flags (hopefully somebody has more info)
2. it's possible (have been doing that) but never with any intention of real use.
3. i'm pretty sure they don't have any effect on game1 might be possible, but you'd have to be careful to catch worldgen fast enough and use a CoreSuspend object in C++.Thanks for all the responses, two more slightly specific questions
9. If I have two scripts that enable the same eventful event type (e.g. events.enableEvent(events.eventType.UNIT_DEATH,100)) will both get run, or will one be overwritten/ignored?
10. Is there any way to make tile temperature changes more permanent? It seems like every time I change the tiles temperature (both temperature1 and temperature2) it just reverts back to the surrounding, even if I set temperature update to false.
EDIT: Heres another one just for expwnent;
11. The old LUA_HOOK system allowed us access to the items used in a reaction, have you given any thought to trying the same functionality in the new reaction-trigger system?
The one that registers the event to be checked more frequently is the one that counts.
There really isn't a way to make temperature updates permanent other than turning temperature off and reimplementing it yourself.
I would have to rejigger EventManager. It's on the list of things to do.
[spoiler]Thank you for answers and suggestion. I have no idea why it doesn't work for me, I even tried the steps you describe, starting with downloading df_40_11_win_s.zip. Could you please tell what "check" function of binpatch returns after successfully applying the patch?[
When I apply the patch, like thisCode: [Select]binpatch apply pressureplate_04011
the prompt says that the patch was applied (if it doesn't find the file it clearly states in red that it can't find the patch). But when I check for changes like thisCode: [Select]binpatch check pressureplate_04011
it always says that the patch is removed, which means that no changes were actually made.
What worries me is if I deliberately put a wrong value in the patch file, like changing expected original value of 4B to 4A for example, then applying the patch also says that it was applied. Which means the function returned success even though it shouldn't/couldn't, instead it that example it should write something like "conflict at address" I think.
/spoiler]
Luckily, I didn't delete that install yet.
[DFHack]# binpatch check pressureplate_04011
pressureplate_04011: patch is removed
[DFHack]# binpatch apply pressureplate_04011
pressureplate_04011: applied the patch
[DFHack]# binpatch check pressureplate_04011
pressureplate_04011: patch is applied
[DFHack]# binpatch remove pressureplate_04011
pressureplate_04011: removed the patch
[DFHack]# binpatch check pressureplate_04011
pressureplate_04011: patch is removed
[DFHack]#
No errors.
Editing the original 4B to 4A:
[DFHack]# binpatch check pressureplate_04011
pressureplate_04011: conflict at address db8310
[DFHack]#
Let's see... you apply the patch, no complaints, but check says it's removed. Same thing when you deliberately corrupt the patch.
The file is being treated as garbage.
Lines in a patch file that don't have three hexnumbers, with a colon between the first and the second, are silently ignored.
And binpatch doesn't give a warning if no valid patch lines are found.
Check that the contents are exactly as you posted, and check that it's an ASCII text file instead of Unicode or word-processor formatted. Open it inNotepadWordpad, then Save-As and make sure the Encoding is ANSI or UTF-8.
Another thing I just noticed: you can't edit the patch file while Dwarf Fortress is still running. You have to stop and restart DF every time. (Or use an editor that can overwrite a locked file.) That's due to a bug in binpatch.lua. EDIT: I've reported the bug on the Github tracker.
So your tests may be invalid.
So if one is checked every 100 and another every 1000, the one that gets checked every 1000 will never be checked? Or will it instead be checked every 100?
You could use the F9 to F12 keys, as far as I know they're not taken by the game.
It might be possible to reset modifier keys when the window focus changes through DFHack, but it would require interposing additional SDL functions (and would only be necessary on Windows, and possibly some Linux distributions).
I just assumed I was doing something incompetent until it got brought up in this thread. D:It might be possible to reset modifier keys when the window focus changes through DFHack, but it would require interposing additional SDL functions (and would only be necessary on Windows, and possibly some Linux distributions).
That would definitely be worth doing if it's possible, since this is one of the most common problems new players have with dfhack.
Wait, is this only a DFHack-specific bug? I was under the impression that this occurs with any key combinations that use 'Alt' on Windows.It might be possible to reset modifier keys when the window focus changes through DFHack, but it would require interposing additional SDL functions (and would only be necessary on Windows, and possibly some Linux distributions).
That would definitely be worth doing if it's possible, since this is one of the most common problems new players have with dfhack.
Wait, is this only a DFHack-specific bug? I was under the impression that this occurs with any key combinations that use 'Alt' on Windows.It might be possible to reset modifier keys when the window focus changes through DFHack, but it would require interposing additional SDL functions (and would only be necessary on Windows, and possibly some Linux distributions).
That would definitely be worth doing if it's possible, since this is one of the most common problems new players have with dfhack.
It might be possible to reset modifier keys when the window focus changes through DFHack, but it would require interposing additional SDL functions (and would only be necessary on Windows, and possibly some Linux distributions).
diff --git a/library/Core.cpp b/library/Core.cpp
index 0196413..fc63fc1 100644
--- a/library/Core.cpp
+++ b/library/Core.cpp
@@ -1605,6 +1605,15 @@ int Core::DFH_SDL_Event(SDL::Event* ev)
hotkey_states[ke->ksym.sym] = false;
}
}
+ else if (ev->type == SDL::ET_ACTIVEEVENT && ev->active.state == 2)
+ {
+ // There's probably a good enum or macro for that state value somewhere.
+ // Basically, state == 1 means mouse moved in or out of the window,
+ // state == 2 means the window gained or lost focus.
+ // At least on Linux, anyway...
+ fprintf(stderr, "Window Focus Event.\n");
+ fflush(stderr);
+ }
return true;
// do stuff with the events...
}
Wait, is this only a DFHack-specific bug? I was under the impression that this occurs with any key combinations that use 'Alt' on Windows.It might be possible to reset modifier keys when the window focus changes through DFHack, but it would require interposing additional SDL functions (and would only be necessary on Windows, and possibly some Linux distributions).
That would definitely be worth doing if it's possible, since this is one of the most common problems new players have with dfhack.
It's not strictly limited to DFHack, but almost all cases I see are people confused when, for example, trying to make a job repeat brings up the rooms menu. Between the Starter Pack and all the people who use dfhack, a fix would be widely appreciated - even if it's not always dfhack causing the problem!
It counts (under linux, with some terminals) as an intended behaviour. It is all a matter of which keys are caught by which program first. Ticks me off, many utilities designed for terminals have hotkeys F1 or F10 in use, that get caught by (I believe) e.g. gnome-terminal (probably gnome, which passes it on to gnome-terminal, which then brings up some config menu or help or somesuch). This is not a dfhack bug (unless you would count "using keys that the OS is likely to catch and not pass down to the program" as a bug).
Do we have the memory layouts for .12 yet?Zohan just posted this (http://www.bay12forums.com/smf/index.php?topic=143632.0) under General Discussion. Not sure if this is a big or small fraction of the layouts needed for DFHack, but it's a start.
Do we have the memory layouts for .12 yet?Yes: https://github.com/dfhack/df-structures. In fact, DT offsets are often generated from df-structures. Official DFHack releases simply take longer to put together.
Still no Windows symbols for 40.12 ?Last I checked, df-structures has all of them...
The \windows folder says the last change was 9 days ago, vs \linux and \osx being 2 days ago and saying "Update version to v0.40.12".Still no Windows symbols for 40.12 ?Last I checked, df-structures has all of them...
Compiling DFHack for Windows is actually really easy if explained, and it doesn't require a zillion programs, just four.also I just tried this and it worked, but no idea how I'd make it even try to generate something for 40.12 ("96> CPack: - package: C:/Users/salithus/Desktop/dfhack/build/VC2010/dfhack-0.40.11-r1-Windows.zip generated.")
You need:
CMake (http://www.cmake.org/cmake/resources/software.html)
Git - I prefer Github (https://windows.github.com/) or mysysgit (http://msysgit.github.io/) for these purposes (simple command line stuff).
Perl - Strawberry Perl (http://strawberryperl.com/) is simplest
Visual Studio 2010 Express for C# (http://go.microsoft.com/?linkid=9709939)
- Install all four of the above programs.
- Hold down Shift and right-click in an empty space on your desktop. Select "Open command window here".
- Type "git clone -b develop git://github.com/dfhack/dfhack.git" and hit Enter. (Remove the "-b develop" part if you don't want the development branch version, but you usually will.)
- Type "cd dfhack" and hit Enter.
- Type "git submodule init" and hit Enter.
- Type "git submodule update" and hit Enter.
- Close the command prompt and open the DFHack folder you just made and then open the Build folder inside of that.
- Double-click on 'generate-MSVC-gui.bat'.
- In the window that pops up, uncheck the box that says "DL_RUBY", then click Configure, and lastly click Generate.
- Close that window and enter the new VC2010 directory that was created and double-click on dfhack.sln.
- Open the "Solution Explorer" tab to the right, scroll down to "PACKAGE", and then right-click on it and hit "Build".
- When it eventually finishes running, open the new folder "_CPack_Packages", then the folder "win32", then the folder "ZIP", and you will have your very own zipped-up DFHack build.
Those folders only contain generated files (e.g. DT layouts and CSV files). The changes in the rest of the repo include globals for all platforms (see symbols.xml (https://github.com/DFHack/df-structures/blob/master/symbols.xml)).The \windows folder says the last change was 9 days ago, vs \linux and \osx being 2 days ago and saying "Update version to v0.40.12".Still no Windows symbols for 40.12 ?Last I checked, df-structures has all of them...
Note: I have no idea what that means.
yeah - what confused me is that it still says .40.11 in itThose folders only contain generated files (e.g. DT layouts and CSV files). The changes in the rest of the repo include globals for all platforms (see symbols.xml (https://github.com/DFHack/df-structures/blob/master/symbols.xml)).The \windows folder says the last change was 9 days ago, vs \linux and \osx being 2 days ago and saying "Update version to v0.40.12".Still no Windows symbols for 40.12 ?Last I checked, df-structures has all of them...
Note: I have no idea what that means.
The develop (https://github.com/dfhack/dfhack/tree/develop) branch of DFHack/dfhack still points to the df-structures commit used in 0.40.11-r1. If you want to use the latest df-structures commit, you'll have to run the following commands in <DFHack directory>/library/xml before building:Compiling DFHack for Windows is actually really easy if explained, and it doesn't require a zillion programs, just four.also I just tried this and it worked, but no idea how I'd make it even try to generate something for 40.12 ("96> CPack: - package: C:/Users/salithus/Desktop/dfhack/build/VC2010/dfhack-0.40.11-r1-Windows.zip generated.")
You need:
CMake (http://www.cmake.org/cmake/resources/software.html)
Git - I prefer Github (https://windows.github.com/) or mysysgit (http://msysgit.github.io/) for these purposes (simple command line stuff).
Perl - Strawberry Perl (http://strawberryperl.com/) is simplest
Visual Studio 2010 Express for C# (http://go.microsoft.com/?linkid=9709939)
- Install all four of the above programs.
- Hold down Shift and right-click in an empty space on your desktop. Select "Open command window here".
- Type "git clone -b develop git://github.com/dfhack/dfhack.git" and hit Enter. (Remove the "-b develop" part if you don't want the development branch version, but you usually will.)
- Type "cd dfhack" and hit Enter.
- Type "git submodule init" and hit Enter.
- Type "git submodule update" and hit Enter.
- Close the command prompt and open the DFHack folder you just made and then open the Build folder inside of that.
- Double-click on 'generate-MSVC-gui.bat'.
- In the window that pops up, uncheck the box that says "DL_RUBY", then click Configure, and lastly click Generate.
- Close that window and enter the new VC2010 directory that was created and double-click on dfhack.sln.
- Open the "Solution Explorer" tab to the right, scroll down to "PACKAGE", and then right-click on it and hit "Build".
- When it eventually finishes running, open the new folder "_CPack_Packages", then the folder "win32", then the folder "ZIP", and you will have your very own zipped-up DFHack build.
E: figured it out - dunno if it matters but symbols.xml on github shows "<symbol-table name='v0.40.11 SDL' os-type='windows'>", but I replaced the file the above generated with the github one and it fired up just fine on .40.12
git fetch origin
git checkout origin/master
Plugin twbt was not built for this version of DFHack.
Plugin: 0.40.12-r1, DFHack: 0.40.11-r1
That error is pretty much self-explanatory...except, I'm running DF .40.12...
If you want to know why, I'm not entirely sure; I assume it's so that the thing doesn't crash every time you start up DF with the plugin activated.
And twbt was built for 0.40.11-r1, just like the error says.?
Just change .11 to .12 in cmakelist.txt in dfhack root folder.
I just discovered that this is only an issue for me when I have QuickFort running - as soon as I close out of that, the Alt key works just fine. Windows 8.1 x64 w/ .40.12It counts (under linux, with some terminals) as an intended behaviour. It is all a matter of which keys are caught by which program first. Ticks me off, many utilities designed for terminals have hotkeys F1 or F10 in use, that get caught by (I believe) e.g. gnome-terminal (probably gnome, which passes it on to gnome-terminal, which then brings up some config menu or help or somesuch). This is not a dfhack bug (unless you would count "using keys that the OS is likely to catch and not pass down to the program" as a bug).
We're not talking about Fx keys or the dfhack terminal window (or at least I'm not). I'm referring to the vanilla DF bug which has been traced to an old version of the SDL library, where if you alt-tab away the game thinks alt is still held when it comes back into focus. Which results in pressing "r" being interpreted as "alt-r", which brings up something confusing and unexpected.
In short, fixing this bug (http://www.bay12games.com/dwarves/mantisbt/view.php?id=6455), since dfhack arguably makes it worse.
A moody dwarf is demanding silk and yarn, two things I wont be getting for an entire year probably. I tried using the createitem page on the wiki, but it's not really working.
createitem CLOTH CREATURE_MAT:GIANT_CAVE_SPIDER:SILK
And
createitem CLOTH CREATURE_MAT:GOAT_MOUNTAIN:HAIR
They both just bring up
Unrecognized material!
Could somebody who already compiled this *unofficial 40.12* build be so kind as to upload it? I can't for the life of me compile it on my own.
./libs/Dwarf_Fortress: /home/dkm/Documents/df/df2014/df_linux/libs/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./hack/libdfhack.so)
./libs/Dwarf_Fortress: /home/dkm/Documents/df/df2014/df_linux/libs/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by ./hack/libdfhack.so)
./libs/Dwarf_Fortress: /home/dkm/Documents/df/df2014/df_linux/libs/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by ./hack/libdfhack.so)
./libs/Dwarf_Fortress: /home/dkm/Documents/df/df2014/df_linux/libs/libstdc++.so.6: version `CXXABI_1.3.5' not found (required by ./hack/libdfhack.so)
./libs/Dwarf_Fortress: /home/dkm/Documents/df/df2014/df_linux/libs/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ./hack/libdfhack.so)
./libs/Dwarf_Fortress: /home/dkm/Documents/df/df2014/df_linux/libs/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by ./hack/libprotobuf-lite.so)
-e
wat do?
Could somebody who already compiled this *unofficial 40.12* build be so kind as to upload it? I can't for the life of me compile it on my own.
here's what I built for Windows: http://1drv.ms/XeJL4V
e: or magnet link if you prefer: magnet:?xt=urn:btih:ABE54CAC04119D46A77450475876A347D0894DCD
so far it works pretty well - only thing missing from your dfhack.init is lethosor's scripts, I think. I haven't tested your custom onload scripts yet.Could somebody who already compiled this *unofficial 40.12* build be so kind as to upload it? I can't for the life of me compile it on my own.
here's what I built for Windows: http://1drv.ms/XeJL4V
e: or magnet link if you prefer: magnet:?xt=urn:btih:ABE54CAC04119D46A77450475876A347D0894DCD
Neat. I've got this working for myself, but I'd prefer an official release for the Starter Pack. Is there an ETA for dfhack 40.12-r1? If it's not going to be out in the next day or two I'll just use the unofficial version.
Neat. I've got this working for myself, but I'd prefer an official release for the Starter Pack. Is there an ETA for dfhack 40.12-r1? If it's not going to be out in the next day or two I'll just use the unofficial version.so far it works pretty well - only thing missing from your dfhack.init is lethosor's scripts, I think. I haven't tested your custom onload scripts yet.
I've also got some weirdness going on with workflow - nothing completely broken, but I'm getting errors showing up about something missing in a table - I'll post details tomorrow (just closed out everything). I don't know where to start troubleshooting, so I haven't worried too much about it.
Neat. I've got this working for myself, but I'd prefer an official release for the Starter Pack. Is there an ETA for dfhack 40.12-r1? If it's not going to be out in the next day or two I'll just use the unofficial version.so far it works pretty well - only thing missing from your dfhack.init is lethosor's scripts, I think. I haven't tested your custom onload scripts yet.
I've also got some weirdness going on with workflow - nothing completely broken, but I'm getting errors showing up about something missing in a table - I'll post details tomorrow (just closed out everything). I don't know where to start troubleshooting, so I haven't worried too much about it.
Right, I'll wait on the official version if that kind of thing is showing up. ;) My dfhack.init makes a few changes - adding Lethosor's scripts (which are amazing), adding some keybindings that I think should be default (https://github.com/DFHack/dfhack/pull/325), and de-commenting the UI plugins (seriously, why were those ever disabled?). All but the last are in a single section:Spoiler: start of init (click to show/hide)
Also, here's my dfhack.init - I basically went through the StarterPack one and tweaked it to my preferences, but the key thing is that the title-version and load-screen plugins won't load on .40.12 (at least when I first built that package above): http://pastebin.com/mM6TgBjCThey appear to be working just fine on 0.40.11 and 0.40.12 for me. Are there errors that show up in the console, or do those scripts just fail silently? What platform and DFHack version are you using?
The "table index is nil" error is a simple fix (https://github.com/DFHack/dfhack/pull/332/files) (make that change to <DF>/hack/lua/plugins/workflow.lua).Worked like a charm. I've updated my build (r1a): http://1drv.ms/1pfAakN
In dfhack:QuoteAlso, here's my dfhack.init - I basically went through the StarterPack one and tweaked it to my preferences, but the key thing is that the title-version and load-screen plugins won't load on .40.12 (at least when I first built that package above): http://pastebin.com/mM6TgBjCThey appear to be working just fine on 0.40.11 and 0.40.12 for me. Are there errors that show up in the console, or do those scripts just fail silently? What platform and DFHack version are you using?
You need to obtain those scripts from here (https://github.com/lethosor/dfhack-scripts) - they're not included in DFHack by default.will do as soon as I'm back at my computer (out running errands now)
Also, it would be nice if you could use "r0" for pre-releases to avoid confusion (and possible incompatibilities) with the official r1 release.
You need to obtain those scripts from here (https://github.com/lethosor/dfhack-scripts) - they're not included in DFHack by default.Understood, and I usually do this, however mifki's plugins were complied with 40.12-r1 string, so they won't work r0 unless you recompile or hexedit them. And I couldn't locate the sources of his forked dfhack plugins.
Also, it would be nice if you could use "r0" for pre-releases to avoid confusion (and possible incompatibilities) with the official r1 release.
this is my excuse also <_<You need to obtain those scripts from here (https://github.com/lethosor/dfhack-scripts) - they're not included in DFHack by default.Understood, and I usually do this, however mifki's plugins were complied with 40.12-r1 string, so they won't work r0 unless you recompile or hexedit them. And I couldn't locate the sources of his forked dfhack plugins.
Also, it would be nice if you could use "r0" for pre-releases to avoid confusion (and possible incompatibilities) with the official r1 release.
I just built it to work with the .40.12 release I have (it's actually r0, but I had to build as r1 for compatibility with TwbT):
https://github.com/Falconne/dfhack/blob/f7640811990f5d8c0638fff960fa977019d161ed/plugins/hotkeys.cpp is where I got the source.
dll: http://1drv.ms/1D82Y99
Unofficial releases should always use a different release string to avoid incompatibilities and so that if people have problems they can accurately report what version they have, which is impossible if they have the same name as an official release.If I understand the build/load process correctly, we'd need less stringent version checking for loaded modules. fricy and I have to compile DFHack as a .40.12r1 release because the latest .40.12 TwbT was compiled as that release. If I compile as r0, TwbT won't load.
Extra plugins can just be recompiled for different releases.Not if we don't have the source, like fricy mentioned.
The compatibility check is essential - if there are any structure changes between pre-release builds and r1, plugins built with the older structures could crash when using the official r1 structures. It would be safer to recompile TwbT (changing the release number of an existing binary might work, assuming it was built for the same version of DF, since I don't think TwbT relies on specific structures).Unofficial releases should always use a different release string to avoid incompatibilities and so that if people have problems they can accurately report what version they have, which is impossible if they have the same name as an official release.If I understand the build/load process correctly, we'd need less stringent version checking for loaded modules. fricy and I have to compile DFHack as a .40.12r1 release because the latest .40.12 TwbT was compiled as that release. If I compile as r0, TwbT won't load.
The compatibility check is essential - if there are any structure changes between pre-release builds and r1, plugins built with the older structures could crash when using the official r1 structures. It would be safer to recompile TwbT (changing the release number of an existing binary might work, assuming it was built for the same version of DF, since I don't think TwbT relies on specific structures).Unofficial releases should always use a different release string to avoid incompatibilities and so that if people have problems they can accurately report what version they have, which is impossible if they have the same name as an official release.If I understand the build/load process correctly, we'd need less stringent version checking for loaded modules. fricy and I have to compile DFHack as a .40.12r1 release because the latest .40.12 TwbT was compiled as that release. If I compile as r0, TwbT won't load.
Edit: Ninja'd
It would be better than to version the structure/API changes and check plugins against that (yes I realize that would be a large undertaking). The upside would be that you wouldn't have to have a separate compiled DLL for each DFHack release, which would I hope mean troubleshooting plugins would be easier.Isn't this what the existing system accomplishes?
No? The existing system assumes nothing can be forwards compatible, ever, as illustrated by the issue with TwbT. Despite the code being exactly the same, I have to have a version # that matches the build of DFHack. If I understood what I did above correctly, I'm using the exact same structures/API as .40.11 but with symbols.xml for .40.12 and building from source with a .40.12.r1 version number.It would be better than to version the structure/API changes and check plugins against that (yes I realize that would be a large undertaking). The upside would be that you wouldn't have to have a separate compiled DLL for each DFHack release, which would I hope mean troubleshooting plugins would be easier.Isn't this what the existing system accomplishes?
e2: I got the Hotkeys plugin working with this release too (literally did nothing except figure out where the source was and how to add a plugin to the cmake jaunts):
e3: I also got automelt working HOWEVER - there's got to be a better way to find spots to add text than what I did.
I think Fricy is referring to Mifki's modifications to other plugins (e.g. mousequery) to make them work better with TwbT.Either way, there's no good reason (other than, as I conceded earlier, the effort required to make the change now), for plugins to have to be compiled against a specific version of DFHack as a whole. Without that requirement, the same exact twbt.plugin.dll could load against .40.11r1 or .40.12r0 without any work by anyone, which in turn means that people compiling starter packs and whatnot won't have to wait for as many updates with each release of anything.
e2: I got the Hotkeys plugin working with this release too (literally did nothing except figure out where the source was and how to add a plugin to the cmake jaunts):
e3: I also got automelt working HOWEVER - there's got to be a better way to find spots to add text than what I did.
It appears that we have duplicated (https://github.com/DFHack/dfhack/pull/323) effort (https://github.com/DFHack/dfhack/pull/326); sorry for not being more vocal about the latter progress. (At least this provides more evidence of their desirability.) For automelt, I rearranged the lines again to put it and autotrade together, and made the two merge at the bottom when there isn't enough room for the stockpile links.
Sometimes there can be changes that break compatibility, there was such between 0.34.11r3 and r5 not so long ago.Yeah I don't expect it will change either, but I'm still right that my way is better ;)
However of course I'd prefer not to recompile twbt for each minor dfhack update.
So in general version check is good but probably it should include only major changes.
That said, all other plugins are included in dfhack source tree and built together with it, so it's a problem for twbt only, so I don't expect anything to change here.
Sometimes there can be changes that break compatibility, there was such between 0.34.11r3 and r5 not so long ago.Yeah I don't expect it will change either, but I'm still right that my way is better ;)
However of course I'd prefer not to recompile twbt for each minor dfhack update.
So in general version check is good but probably it should include only major changes.
That said, all other plugins are included in dfhack source tree and built together with it, so it's a problem for twbt only, so I don't expect anything to change here.
Actually, I wonder how big of a change it would to just change DFHack's version to be separate from DF itself. That way you could do regular major/minor/revision versioning for DFHack (I'd call it 6.whatever at this point and consider 0.34.11r5 5.0) and then the DF version check would go against the contents of symbols.xml.
Things like the Hotkeys plugin, though, wouldn't - source I used for that was from before DF 0.40 so there's really no reason the dll from before shouldn't work, other than the version check that fails.Sometimes there can be changes that break compatibility, there was such between 0.34.11r3 and r5 not so long ago.Yeah I don't expect it will change either, but I'm still right that my way is better ;)
However of course I'd prefer not to recompile twbt for each minor dfhack update.
So in general version check is good but probably it should include only major changes.
That said, all other plugins are included in dfhack source tree and built together with it, so it's a problem for twbt only, so I don't expect anything to change here.
Actually, I wonder how big of a change it would to just change DFHack's version to be separate from DF itself. That way you could do regular major/minor/revision versioning for DFHack (I'd call it 6.whatever at this point and consider 0.34.11r5 5.0) and then the DF version check would go against the contents of symbols.xml.
I will have to update twbt for each df version anyway (but not dfhack release).
Using the same source doesn't guarantee compatibility - if a structure used by a plugin changes at all, that plugin will have to be recompiled, even if it doesn't need to be updated. For example, here (https://www.diffchecker.com/e5zvlv3j) is a diff of the viewscreen_loadgamest.h changes between 0.34.11 and 0.40.12. Note the addition of the "unk_v40_1a" and "unk_v40_1b" fields - any plugin compiled before these fields were introduced will almost certainly crash when attempting to access other fields (e.g. "saves").Things like the Hotkeys plugin, though, wouldn't - source I used for that was from before DF 0.40 so there's really no reason the dll from before shouldn't work, other than the version check that fails.Sometimes there can be changes that break compatibility, there was such between 0.34.11r3 and r5 not so long ago.Yeah I don't expect it will change either, but I'm still right that my way is better ;)
However of course I'd prefer not to recompile twbt for each minor dfhack update.
So in general version check is good but probably it should include only major changes.
That said, all other plugins are included in dfhack source tree and built together with it, so it's a problem for twbt only, so I don't expect anything to change here.
Actually, I wonder how big of a change it would to just change DFHack's version to be separate from DF itself. That way you could do regular major/minor/revision versioning for DFHack (I'd call it 6.whatever at this point and consider 0.34.11r5 5.0) and then the DF version check would go against the contents of symbols.xml.
I will have to update twbt for each df version anyway (but not dfhack release).
So if one is checked every 100 and another every 1000, the one that gets checked every 1000 will never be checked? Or will it instead be checked every 100?
It will check for events every 100 ticks. When that happens, all listeners will be notified, regardless of how often or rarely they requested EventManager to check for events.
As for the rest, I don't know.
I'm not sure what you're saying by this. I see the first type of change as just bad design and the whole reason we're having this discussion in the first place - yes I know it would take a lot of work to fix and there are ~reasons~ it evolved the way it did, but it doesn't change the fact that it's bad practice when designing an API. Additive changes shouldn't break compatibility and plugins that don't use changed functionality shouldn't need to recompile just to get a new version number.Using the same source doesn't guarantee compatibility - if a structure used by a plugin changes at all, that plugin will have to be recompiled, even if it doesn't need to be updated. For example, here (https://www.diffchecker.com/e5zvlv3j) is a diff of the viewscreen_loadgamest.h changes between 0.34.11 and 0.40.12. Note the addition of the "unk_v40_1a" and "unk_v40_1b" fields - any plugin compiled before these fields were introduced will almost certainly crash when attempting to access other fields (e.g. "saves").Things like the Hotkeys plugin, though, wouldn't - source I used for that was from before DF 0.40 so there's really no reason the dll from before shouldn't work, other than the version check that fails.Sometimes there can be changes that break compatibility, there was such between 0.34.11r3 and r5 not so long ago.Yeah I don't expect it will change either, but I'm still right that my way is better ;)
However of course I'd prefer not to recompile twbt for each minor dfhack update.
So in general version check is good but probably it should include only major changes.
That said, all other plugins are included in dfhack source tree and built together with it, so it's a problem for twbt only, so I don't expect anything to change here.
Actually, I wonder how big of a change it would to just change DFHack's version to be separate from DF itself. That way you could do regular major/minor/revision versioning for DFHack (I'd call it 6.whatever at this point and consider 0.34.11r5 5.0) and then the DF version check would go against the contents of symbols.xml.
I will have to update twbt for each df version anyway (but not dfhack release).
Edit: In addition to structure changes, DFHack changes can break compatibility - for example, this change (https://github.com/dfhack/dfhack/commit/896cd11fe92c5a069c0cdf14bdda17c7e286f0b0) broke compatibility with all plugins that interpose vmethods.
It's working for me. What platform are you using? Is Ruby available?
It looks like the exterminate script may be broke for 0.40.12, assuming it's not something I am doing. Works fine on a clean install in 0.40.11 (Dwarf Fortress and DFHack only), but does nothing in a clean install of 0.40.12. Running the script gives nothing for output, and the same for any switches you try with it. Just FYI.
It's working for me. What platform are you using? Is Ruby available?
It looks like the exterminate script may be broke for 0.40.12, assuming it's not something I am doing. Works fine on a clean install in 0.40.11 (Dwarf Fortress and DFHack only), but does nothing in a clean install of 0.40.12. Running the script gives nothing for output, and the same for any switches you try with it. Just FYI.
I'm not sure what you're saying by this. I see the first type of change as just bad design and the whole reason we're having this discussion in the first place - yes I know it would take a lot of work to fix and there are ~reasons~ it evolved the way it did, but it doesn't change the fact that it's bad practice when designing an API. Additive changes shouldn't break compatibility and plugins that don't use changed functionality shouldn't need to recompile just to get a new version number.
Not sure this is the right place to ask this - is the 0.34.11-r5 source, with all the submodules, still available? I'm trying to compile a MDF version for linux, and it's still using the old dfhack.
It helps to realize that there is effectively no abstraction between DFHack plugins and DF itself - memory addresses for globals are determined on program startup (based on data inside symbols.xml), but structure layouts are defined in C++ header files (which are generated by a Perl script prior to compiling DFHack itself) so that plugins are able to directly access DF's internals as if they were part of DF itself (which, for all intents and purposes, they are). Once a plugin is compiled, an access to "viewscreen_loadgamest.loading" simply becomes "BYTE PTR [ecx+10h]", so if a new int32 field named "unk_v40_1a" gets added, it will end up reading the wrong data.I'm not sure what you're saying by this. I see the first type of change as just bad design and the whole reason we're having this discussion in the first place - yes I know it would take a lot of work to fix and there are ~reasons~ it evolved the way it did, but it doesn't change the fact that it's bad practice when designing an API. Additive changes shouldn't break compatibility and plugins that don't use changed functionality shouldn't need to recompile just to get a new version number.
Sorry, but if there was an actual modding API for DF, this would be valid, but unfortunately, there isn't one. If something changes in the DF memory stuctures, there's no way for a plugin to necessarily know that.
Not sure this is the right place to ask this - is the 0.34.11-r5 source, with all the submodules, still available? I'm trying to compile a MDF version for linux, and it's still using the old dfhack.
https://github.com/DFHack/dfhack/tree/0.34.11-r5
Just do a git checkout 0.34.11-r5 and it should work hopefully. git submodule update also to use the old df-structures.
Are you referring to the "binpatch" external executable or the "binpatch" Lua script (included in DFHack)? It sounds like what you're describing is already covered by the latter.
Also, it appears that the DF OSX image has two entire versions of DF in it, what's up with that? Something about OS version, or maybe old 680x0/new x86 architectures?
$ file dwarfort.exe
dwarfort.exe: Mach-O executable i386
$ file /usr/lib/libz.dylib
/usr/lib/libz.dylib: Mach-O universal binary with 2 architectures
/usr/lib/libz.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
/usr/lib/libz.dylib (for architecture i386): Mach-O dynamically linked shared library i386
Ah, that makes more sense. DFHack contains some memory-scanning tools available to Lua, which may be useful (see devel/find-offsets.lua for an example).Thank you very much; I'll take a close look at that.
Also, it appears that the DF OSX image has two entire versions of DF in it, what's up with that? Something about OS version, or maybe old 680x0/new x86 architectures?
It doesn't appear to contain multiple architectures:Code: [Select]$ file dwarfort.exe
dwarfort.exe: Mach-O executable i386
$ file /usr/lib/libz.dylib
/usr/lib/libz.dylib: Mach-O universal binary with 2 architectures
/usr/lib/libz.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
/usr/lib/libz.dylib (for architecture i386): Mach-O dynamically linked shared library i386
The first bolded statement is my whole point, and like I mentioned above - depending on a end-user configured version string to determine compatibility isn't giving much assurance of actual compatibility.It helps to realize that there is effectively no abstraction between DFHack plugins and DF itself - memory addresses for globals are determined on program startup (based on data inside symbols.xml), but structure layouts are defined in C++ header files (which are generated by a Perl script prior to compiling DFHack itself) so that plugins are able to directly access DF's internals as if they were part of DF itself (which, for all intents and purposes, they are). Once a plugin is compiled, an access to "viewscreen_loadgamest.loading" simply becomes "BYTE PTR [ecx+10h]", so if a new int32 field named "unk_v40_1a" gets added, it will end up reading the wrong data.I'm not sure what you're saying by this. I see the first type of change as just bad design and the whole reason we're having this discussion in the first place - yes I know it would take a lot of work to fix and there are ~reasons~ it evolved the way it did, but it doesn't change the fact that it's bad practice when designing an API. Additive changes shouldn't break compatibility and plugins that don't use changed functionality shouldn't need to recompile just to get a new version number.
Sorry, but if there was an actual modding API for DF, this would be valid, but unfortunately, there isn't one. If something changes in the DF memory stuctures, there's no way for a plugin to necessarily know that.
If you want something you don't need to recompile between releases, you need to use scripts, since those are effectively recompiled every time you run them and will thus know where to get that new field since they can ask DFHack where it is, and while DFHack has the same issue described above, recompiling it for new versions of DF is acceptable and expected by most people. Of course, scripts are also slower, but that's the cost you pay for increased flexibility.
What would I have to put in to DHPFHack to force a strange mood to happen? Can I control what type of mood?"strangemood"
It's working for me. What platform are you using? Is Ruby available?
It looks like the exterminate script may be broke for 0.40.12, assuming it's not something I am doing. Works fine on a clean install in 0.40.11 (Dwarf Fortress and DFHack only), but does nothing in a clean install of 0.40.12. Running the script gives nothing for output, and the same for any switches you try with it. Just FYI.
Windows 7 64. Have ruby installed. I tried running someone else's compilation of DFHack (0.40.12) for comparison and have the same issue.
OS X build (0.40.12-r1) (http://dffd.wimbli.com/file.php?id=9719)
Dammit... I can only seem to get "strangemood -force" to work. Could someone give me the exact words to force a secretive armour smith mood going? I want to have my king be a steel artifact-covered killing machine. I already have a giant lion leather, ruby and faint yellow diamond spiked cloak that he wears. I may give him the steel studded thong too.
That's strange - it sounds like you're not using DF 0.40.12 (or 0.40.11). If that's not the case, have you made any patches to dwarfort.exe?OS X build (0.40.12-r1) (http://dffd.wimbli.com/file.php?id=9719)
I'm not able to issue any commands in this version. It says "resetting textures" and gives notices if I resize the window or zoom in, but no commands are working, and hotkeys appear to not be working either.
That's strange - it sounds like you're not using DF 0.40.12 (or 0.40.11). If that's not the case, have you made any patches to dwarfort.exe?OS X build (0.40.12-r1) (http://dffd.wimbli.com/file.php?id=9719)
I'm not able to issue any commands in this version. It says "resetting textures" and gives notices if I resize the window or zoom in, but no commands are working, and hotkeys appear to not be working either.
That's strange - it sounds like you're not using DF 0.40.12 (or 0.40.11). If that's not the case, have you made any patches to dwarfort.exe?OS X build (0.40.12-r1) (http://dffd.wimbli.com/file.php?id=9719)
I'm not able to issue any commands in this version. It says "resetting textures" and gives notices if I resize the window or zoom in, but no commands are working, and hotkeys appear to not be working either.
Anyone want to take on the challenge of adding script triggers for the following to modtools? I have visions of modding in various things, from a whoopee cushion all the way to a dragonfire trap.Note: lever pull can be already be done through the job complete event, but I included it in the list for the purposes of a consistent interface.
- lever pull
- pressure plate activation
- gear/shaft/roller power status change
- door status change
- bridge/hatch/floor bars/vertical bars/floodgate status change
- trap status change
- minecart friction (from stop) applied; minecart dump activation
depending on a end-user configured version string to determine compatibility isn't giving much assurance of actual compatibility.There is a version string, but it isn't "end-user configured" - it's set inside the project makefiles (by the DFHack developers).
And I'd say "acceptable and expected" is not quite the same as "accepted because they're not given any other options". Like I've already mentioned repeatedly, I appreciate that putting in that layer of abstraction now that should have been there all along to prevent the issue you described is a significant undertaking. This doesn't change the fact that the state of DF is very different now than it was 6 months ago when it had been 18 months since the last update and that dependence on DFHack, especially in starter packs and the like, is significant enough to warrant finding better ways to do things.Long ago, there was an "abstraction layer" with that level of detail. It was called "memory.xml", and it contained individual addresses and offsets for the small handful of variables that DFHack commands wanted to use. It was also very messy to deal with.
I'll add it to the list.
Long ago, there was an "abstraction layer" with that level of detail. It was called "memory.xml", and it contained individual addresses and offsets for the small handful of variables that DFHack commands wanted to use. It was also very messy to deal with.Man, I remember when DFHack used memory.xml, so few people used it because there were only a handful of things, and hardly any modders had it in their mods. The df-structures method is so much nicer. I shudder to think of those days.
I'm an end user - I set it to get DFHack to recognize mifki's build of the TwbT plugin, which is what brought up this whole discussion in the first place. If I want to compile just a plugin, I can set that version string to whatever I feel like, and DFHack will think the DLL was compiled for that version of DFHack, regardless of what is actually happening in the source.depending on a end-user configured version string to determine compatibility isn't giving much assurance of actual compatibility.There is a version string, but it isn't "end-user configured" - it's set inside the project makefiles (by the DFHack developers).
That doesn't make any sense in the context of the discussion so far. My whole reason for thinking that there's got to be a better way of doing things is that I used:And I'd say "acceptable and expected" is not quite the same as "accepted because they're not given any other options". Like I've already mentioned repeatedly, I appreciate that putting in that layer of abstraction now that should have been there all along to prevent the issue you described is a significant undertaking. This doesn't change the fact that the state of DF is very different now than it was 6 months ago when it had been 18 months since the last update and that dependence on DFHack, especially in starter packs and the like, is significant enough to warrant finding better ways to do things.Long ago, there was an "abstraction layer" with that level of detail. It was called "symbols.xml", and it contained individual addresses and offsets for the small handful of variables that DFHack commands wanted to use. It was also very messy to deal with.
When we switched to df-structures and loading into DF itself (instead of acting like a debugger and using ReadProcessMemory/WriteProcessMemory), we did away with that because the new system was much simpler to code for - rather than having to call special functions inside DFHack to fetch an object of a particular type (from one of the specific lists it knew about at the time) and then lookup the offset of each individual field within the object it wanted to access, it could offload all of that to the C++ compiler.
And like I already said, Lua scripts do have the "layer of abstraction" you're so insistent on having - you can access fields by name, and as long as those field names don't change then you can run the script in whatever version of DF you want. Hell, I've run some DFHack Lua scripts written for 0.34.11 in 0.28.181.40d and even 0.23.130.23a, and they worked just fine as long as they weren't trying to access things that didn't exist.
If you think you can do better, then by all means do so.
If you set the DFHack version when compiling DFHack, that's not what Quietust is referring to by "end user". If you want a plugin to be compatible with a specific version of DFHack, it's safer to compile DFHack and that plugin with an accurate version (or ask the plugin's author to build for that DFHack version), rather than changing the DFHack version to match a plugin. The version check is in place to prevent problems resulting from incompatibilities between DFHack versions - it may have been safe to bypass in this case (by changing the DFHack version), but that doesn't guarantee that it will be safe in the future.I'm an end user - I set it to get DFHack to recognize mifki's build of the TwbT plugin, which is what brought up this whole discussion in the first place. If I want to compile just a plugin, I can set that version string to whatever I feel like, and DFHack will think the DLL was compiled for that version of DFHack, regardless of what is actually happening in the source.depending on a end-user configured version string to determine compatibility isn't giving much assurance of actual compatibility.There is a version string, but it isn't "end-user configured" - it's set inside the project makefiles (by the DFHack developers).
When you built your version of "0.40.12-r1", there hadn't been any DFHack changes made to the main repo since 0.40.11-r1 - the only changes were made to df-structures. Expwnent merged in around a dozen pull requests an hour or so before making an official release. This brings up another point: there are now multiple "0.40.12-r1" builds floating around that have different behaviors and features. Among other things, "hack-wish" no longer crashes in certain cases, "search" has been updated for 0.40.12, and workflow no longer produces repeating error messages. However, since builds built before these changes identify themselves as "0.40.12-r1", there's no easy way to tell which build of "0.40.12-r1" that specific bug reports apply to, for example....That doesn't make any sense in the context of the discussion so far. My whole reason for thinking that there's got to be a better way of doing things is that I used:
DFHack source from .40.11r1
symbols.xml for DF .40.12
DF .40.12
And everything worked fine. If symbols.xml isn't that abstraction layer anymore, why was updating it enough to get everything working? Why was it needed at all? Those are the questions that kickstarted this whole thing. Waiting on the DFHack team to put together for a release when there are bug fixes or breaking changes makes sense. Waiting on them when all that was required to get DF .40.12 up and running, which has a critical fix for dwarves getting stuck unconscious, doesn't make sense if the only two things required were updating symbols.xml and making DFHack and the plugins all think they had been changed to work with .40.12.
As a result, an update to DF .04.12 for the Starter Pack PE maintains could not be released until the DFHack developers put together a release. For whatever reason, this took 6 days to do. Considering that the DF update from .10->.11 took 7 days and Toady's notes say a .13 release could be today or tomorrow, continuing this cycle makes starter packs effectively worthless. We have gone from a system where, 6 months ago, the starter pack was constantly at the latest version of DF to now, where it never can be.Why exactly do starter packs "require" DFHack? If playing the latest version is necessary, it's entirely possible to play the latest version without DFHack (or any other utilities, for that matter) for a few days. An alternative is to build DFHack independently, as Fricy did for his pack (and Beautato attempted to). (Admittedly, doing so brings up DFHack versioning issues again, but my point is that the delays in updating some packs are primarily due to the authors of those packs choosing not to update until certain utilities are updated.)
I don't particularly care how we get that gap closed, what's important to that me is we figure out a way to do it. Yours is the first post since this conversation began that wasn't completely "well we've always done it this way so get over it" and actually started discussing why the roadblocks exist and what it would take to overcome them. With that in mind, unless the DFHack team intends to completely obsolete non-Lua plugins, that's not an effective approach as things like the Starter Pack depend on a ton of existing plugins - TwbT, Falconne's jaunts, etc.
that doesn't guarantee that it will be safe in the future.
When you built your version of "0.40.12-r1", there hadn't been any DFHack changes made to the main repo since 0.40.11-r1 - the only changes were made to df-structures. Expwnent merged in around a dozen pull requests an hour or so before making an official release. This brings up another point: there are now multiple "0.40.12-r1" builds floating around that have different behaviors and features. Among other things, "hack-wish" no longer crashes in certain cases, "search" has been updated for 0.40.12, and workflow no longer produces repeating error messages. However, since builds built before these changes identify themselves as "0.40.12-r1", there's no easy way to tell which build of "0.40.12-r1" that specific bug reports apply to, for example.
Why exactly do starter packs "require" DFHack? If playing the latest version is necessary, it's entirely possible to play the latest version without DFHack (or any other utilities, for that matter) for a few days. An alternative is to build DFHack independently, as Fricy did for his pack (and Beautato attempted to). (Admittedly, doing so brings up DFHack versioning issues again, but my point is that the delays in updating some packs are primarily due to the authors of those packs choosing not to update until certain utilities are updated.)It's asinine to think that starter packs, which are specifically geared towards new/inexperienced DF players, aren't dependent on the functionality that DFHack and commonly used plugins bring. Saying it's entirely up to the pack author's choice is like blaming the restaurant industry for people getting hungry.
From what I've heard on IRC, Expwnent plans to release 0.40.13-r1 within a day of df-structures being updated. (If you take a look at the old DFHack thread, updates were often available a day or so after a release, except for major/new-feature releases).What I mean is that, per Quietust's posts, Lua scripts are currently the only way to have a layer of abstraction in that would have prevented needing DFHack plugins recompiled between .40.11 and .40.12. Unless you plan to make that the only option for plugins (which we all realize is not the right way to fix this gap), we need to consider other options.
I'm not sure what you mean by obsoleting non-Lua plugins - Lua plugins don't necessarily work with new DFHack releases without modification (they don't need to be recompiled, but that leads to problems being encountered at runtime instead).
[...] This brings up another point: there are now multiple "0.40.12-r1" builds floating around that have different behaviors and features. Among other things, "hack-wish" no longer crashes in certain cases, "search" has been updated for 0.40.12, and workflow no longer produces repeating error messages. However, since builds built before these changes identify themselves as "0.40.12-r1", there's no easy way to tell which build of "0.40.12-r1" that specific bug reports apply to, for example.
[...]
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
[...]
Maybe the actual repo master branch should always have a DFHACK_RELEASE string with "-unofficial" appended to it?To clarify in case it matters:
And to make an official release, branch the master and change only that one string?
How about it, Peterix, expwnent, lethosor ?
Also, can we please quit approaching this with the "it won't fix this every time" mentality? I know that there are going to be times between versions that compatibility will break. My point is that it is not every release as evidenced by being able to use .40.11-r1 source with .40.12 symbols, so there is clearly an opportunity to improve the process.
I find it absurd that lethosor keeps insisting that since we can't guarantee non-breaking changes every time a new DF is released, we can't improve the DFHack versioning approach. If you find that curious...ok?Also, can we please quit approaching this with the "it won't fix this every time" mentality? I know that there are going to be times between versions that compatibility will break. My point is that it is not every release as evidenced by being able to use .40.11-r1 source with .40.12 symbols, so there is clearly an opportunity to improve the process.The intensity with which you are approaching this almost suggests you see some kind of moral or ethical failing, which I find curious.
Consequently, there's absolutely no way to set useful expectations for actual end users. This is not a problem to be dismissed lightly; providing a mechanism will to most users imply a promise, and if that promise is not kept, people react in silly ways. From a social standpoint, it's often easier to not imply that promise.
As Peterix noted, if you want to try to improve things in the way you feel they should be improved, there's no real barrier to doing so, beyond you needing to choose to be responsible for it.That's disingenuous. There is a very real barrier to changing, fundamentally, how DFHack versioning works. It's got to be accepted by both the core DFHack team and the people developing plugins as both an improvement to the existing system and easier to use. No point in me wasting time writing anything in code if the current viewpoint of the DFHack team doesn't change to accept both the possibility and necessity of making this kind of improvement.
You act as though some moral wrong has been perpetrated. The dfhack team has opted not to take responsibility for a thing they CANNOT take responsibility for, and for you it's some kind of crime against release policies or something. That's what I find curious.The intensity with which you are approaching this almost suggests you see some kind of moral or ethical failing, which I find curious.I find it absurd that lethosor keeps insisting that since we can't guarantee non-breaking changes every time a new DF is released, we can't improve the DFHack versioning approach. If you find that curious...ok?
You built it yourself, you got what you wanted, and you have a viable pattern for doing so again in the future, so as far as I can tell, your actual technical problem has been solved, and now you're attacking a social problem. This leads to...Consequently, there's absolutely no way to set useful expectations for actual end users. This is not a problem to be dismissed lightly; providing a mechanism will to most users imply a promise, and if that promise is not kept, people react in silly ways. From a social standpoint, it's often easier to not imply that promise.
That's a poor argument for not trying to improve the release cycle, especially considering the attitude prior to this discussion was largely "well if the DFHack team isn't going fast enough for you, build it yourself". Which I did. Which caused this discussion.
As Peterix noted, if you want to try to improve things in the way you feel they should be improved, there's no real barrier to doing so, beyond you needing to choose to be responsible for it.That's disingenuous. There is a very real barrier to changing, fundamentally, how DFHack versioning works. It's got to be accepted by both the core DFHack team and the people developing plugins as both an improvement to the existing system and easier to use. No point in me wasting time writing anything in code if the current viewpoint of the DFHack team doesn't change to accept both the possibility and necessity of making this kind of improvement.
You act as though some moral wrong has been perpetrated. The dfhack team has opted not to take responsibility for a thing they CANNOT take responsibility for, and for you it's some kind of crime against release policies or something. That's what I find curious.That is not an accurate description of what has happened and you know that. You sound sillier each time you try and act like this is a morality crusade, though, which is amusing at least, so keep it up I guess?
You built it yourself, you got what you wanted, and you have a viable pattern for doing so again in the future, so as far as I can tell, your actual technical problem has been solved, and now you're attacking a social problem. This leads to...No I have not - Starter Pack still depends on an official DFHack release only because that's what it currently takes to get a release that is considered stable and works with the latest DF version. There is, based on the discussions so far, an opportunity to change that since both 11->12 and 12->13 only required a symbols.xml update, but due to the way DFHack is currently maintained this requires everything to be recompiled by the DFHack team to make the versions aligned and it to be considered stable, which is what is required for inclusion in the Starter Pack. What I want is to separate DF versioning from DFHack versioning from plugin versioning so that when DF makes non-breaking changes in an upgrade, the's no need for an unsupported "at your own risk" build in order to update.
Disingenuous? How? The team, at present, doesn't consider the benefits worth the effort, but is open to contributions. You've provided steps for solving the problem locally. If you want the problem solved on a larger scope, then put in the legwork to solve it on a larger scope. If it's good work, and it does what you think it will do, it's likely to get merged.I described it already, but given your other posts it's not surprising that you'll ignore both that and the implications of a core change like this, given your above approach to replying to me. This isn't creating a new plugin - it would require DFHack and all the plugins to be updated to use a new system - that's not something that just gets done off on a branch and suddenly everyone becomes accepting of it.
[...] This brings up another point: there are now multiple "0.40.12-r1" builds floating around that have different behaviors and features. Among other things, "hack-wish" no longer crashes in certain cases, "search" has been updated for 0.40.12, and workflow no longer produces repeating error messages. However, since builds built before these changes identify themselves as "0.40.12-r1", there's no easy way to tell which build of "0.40.12-r1" that specific bug reports apply to, for example.
That. That's been a persistent problem for the past month, month and a half.
Not only is it causing confusion, it's also against the DFHack license.Quote from: the license boilerplate[...]
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
[...]
Now in the current mess, salithus didn't exactly alter the source; he mixed-and-matched code from the official repo, part of it at a time when the repo was between official releases. As I understand it.
It's still a problem.
Maybe the actual repo master branch should always have a DFHACK_RELEASE string with "-unofficial" appended to it? (EDIT: in the file CMakeLists.txt)
And to make an official release, branch the master and change only that one string?
How about it, Peterix, expwnent, lethosor ?
Eh, 0x517A5D's suggestion makes sense for the current process at least - if you were to download and build a bleeding edge release now, it'd have the same DFHack version as the latest stable release. That's what causes the DFHack devs to have to worry about unofficial builds in the first place.[...] This brings up another point: there are now multiple "0.40.12-r1" builds floating around that have different behaviors and features. Among other things, "hack-wish" no longer crashes in certain cases, "search" has been updated for 0.40.12, and workflow no longer produces repeating error messages. However, since builds built before these changes identify themselves as "0.40.12-r1", there's no easy way to tell which build of "0.40.12-r1" that specific bug reports apply to, for example.
That. That's been a persistent problem for the past month, month and a half.
Not only is it causing confusion, it's also against the DFHack license.Quote from: the license boilerplate[...]
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
[...]
Now in the current mess, salithus didn't exactly alter the source; he mixed-and-matched code from the official repo, part of it at a time when the repo was between official releases. As I understand it.
It's still a problem.
Maybe the actual repo master branch should always have a DFHACK_RELEASE string with "-unofficial" appended to it? (EDIT: in the file CMakeLists.txt)
And to make an official release, branch the master and change only that one string?
How about it, Peterix, expwnent, lethosor ?
I'd rather the DFHack developers not worry about unofficial builds. And I think those willing to build DFHack on their own should be hesitant to provide those builds to others -- do we really want to encourage others to download and run unknown executable's?
But I can see the need to provide bleeding edge builds forlazyeager die-hards who want to run Toady's latest and have their DFHack too. Here's my solution: If someone wants to post a link or reference to an unofficial build, just do so in a separate message thread. Anyone wanting the official build can come here (or the latest thread), which is identified by the current version.
For those working on starter and mod packs, put whatever *you* want in those packs; just understand that users expect some level of testing on your part to identify any major issues or problems (and aren't likely to care at all about version identifiers).
No I have not - Starter Pack still depends on an official DFHack release only because that's what it currently takes to get a release that is considered stable and works with the latest DF version. There is, based on the discussions so far, an opportunity to change that since both 11->12 and 12->13 only required a symbols.xml update, but due to the way DFHack is currently maintained this requires everything to be recompiled by the DFHack team to make the versions aligned and it to be considered stable, which is what is required for inclusion in the Starter Pack. What I want is to separate DF versioning from DFHack versioning from plugin versioning so that when DF makes non-breaking changes in an upgrade, the's no need for an unsupported "at your own risk" build in order to update.DF 0.40.13 does require structure changes, due to this commit (https://github.com/DFHack/df-structures/commit/3217bab75753c71b4393155cf6f062f01f6fc997).
$ git describe --tags --always
0.34.11-r5-338-g856a146
Unfortunately, defining this as a constant will require rebuilding everything DFHack-specific (DFHack core and plugins) after every commit, which is impractical. Using a reference to a df-structures commit instead will require rebuilding less often, but is still more inconvenient than the current method, which only rebuilds plugins (and core modules) that use structures that have changed since the last build. The problem, of course, is that there is no easy way to tell which df-structures commit a compiled plugin was built with without introducing some kind of unique identifier, and I'm not aware of a way to do this without causing CMake to unnecessarily rebuild all plugins.Maybe the actual repo master branch should always have a DFHACK_RELEASE string with "-unofficial" appended to it? (EDIT: in the file CMakeLists.txt)Expwnent mentioned doing this after making a release, although it doesn't appear to have been changed yet. Generally, the master branch points to the latest release, but it would be easy to change the version string on the develop branch after making a release.
And to make an official release, branch the master and change only that one string?
No I have not - Starter Pack still depends on an official DFHack release only because that's what it currently takes to get a release that is considered stable and works with the latest DF version. There is, based on the discussions so far, an opportunity to change that since both 11->12 and 12->13 only required a symbols.xml update, but due to the way DFHack is currently maintained this requires everything to be recompiled by the DFHack team to make the versions aligned and it to be considered stable, which is what is required for inclusion in the Starter Pack. What I want is to separate DF versioning from DFHack versioning from plugin versioning so that when DF makes non-breaking changes in an upgrade, the's no need for an unsupported "at your own risk" build in order to update.There is an opportunity, yes. There is also an opportunity cost, which the team is not comfortable with at this time. That might change, particularly with a demonstration of implementation.
I described it already, but given your other posts it's not surprising that you'll ignore both that and the implications of a core change like this, given your above approach to replying to me. This isn't creating a new plugin - it would require DFHack and all the plugins to be updated to use a new system - that's not something that just gets done off on a branch and suddenly everyone becomes accepting of it.
DF 0.40.13 does require structure changes, due to this commit (https://github.com/DFHack/df-structures/commit/3217bab75753c71b4393155cf6f062f01f6fc997).So, if I understand things right, that means the build I made above did processing of the structures during compile time that, if I included that commit (I think I did based on your instructions for the /library/xml folder), it "safely" updated all the DFHack-included plugins, but, despite being the same original source (master branch of DFHack), previous DLLs would not work (aside from the version string issue), due to those changes?
Anyway, I'm not opposed to changes in DFHack's versioning system; I'm just not sure how best to implement them. There was a discussion about this earlier on IRC where replacing the DFHack version string with a reference to a Git commit was brought up:That makes sense - let me think on it. If I were doing this with SVN, I'd just reference an svn:externals and do some pre-build scripting based on that, but I'm not sure how that concept works in git. I can google my way around it, but any pointers on how you guys are doing it would be appreciated.Code: [Select]$ git describe --tags --always
Unfortunately, defining this as a constant will require rebuilding everything DFHack-specific (DFHack core and plugins) after every commit, which is impractical. Using a reference to a df-structures commit instead will require rebuilding less often, but is still more inconvenient than the current method, which only rebuilds plugins (and core modules) that use structures that have changed since the last build.
0.34.11-r5-338-g856a146
It really comes down to how you want people who are compiling themselves to do it. When I did it with .40.12, I just followed the step by step instructions because it was my first time. With .40.13, I did the master branch thinking it'd prove more of a point about how close the DF code was across the 3 releases and I didn't want to unknowingly include active development that might address an issue I wasn't aware of. Whichever I should be compiling against, that's the one I recommend not have an official version string as the default. (Might even be worth taking those lines out of source control entirely somehow [addmittedly no idea how CMake works], so that it always has to be specified by whoever is doing the compiling to make sure it's done correctly.)Quote from: 0x517A5DMaybe the actual repo master branch should always have a DFHACK_RELEASE string with "-unofficial" appended to it? (EDIT: in the file CMakeLists.txt)Expwnent mentioned doing this after making a release, although it doesn't appear to have been changed yet. Generally, the master branch points to the latest release, but it would be easy to change the version string on the develop branch after making a release.
And to make an official release, branch the master and change only that one string?
You're demanding someone else do it for you.You gave yourself away here. Go troll someone else - I've never demanded or even asked anyone to undertake any work because of the reasons I already outlined for needing acceptance of the concept and direction from the DFHack team first.
It really comes down to how you want people who are compiling themselves to do it. When I did it with .40.12, I just followed the step by step instructions because it was my first time. With .40.13, I did the master branch thinking it'd prove more of a point about how close the DF code was across the 3 releases and I didn't want to unknowingly include active development that might address an issue I wasn't aware of. Whichever I should be compiling against, that's the one I recommend not have an official version string as the default. (Might even be worth taking those lines out of source control entirely somehow [addmittedly no idea how CMake works], so that it always has to be specified by whoever is doing the compiling to make sure it's done correctly.)
throw in some Zolgar and count me in.It really comes down to how you want people who are compiling themselves to do it. When I did it with .40.12, I just followed the step by step instructions because it was my first time. With .40.13, I did the master branch thinking it'd prove more of a point about how close the DF code was across the 3 releases and I didn't want to unknowingly include active development that might address an issue I wasn't aware of. Whichever I should be compiling against, that's the one I recommend not have an official version string as the default. (Might even be worth taking those lines out of source control entirely somehow [addmittedly no idea how CMake works], so that it always has to be specified by whoever is doing the compiling to make sure it's done correctly.)
uhh through IRC? kinda find the idea that if anyone willingly set on building dfhack and compiling a (dev/branch/copy/early access) build should hang out with the devs and listen to them discuss builds and plugins.
like you cross the step from being a user of dfhack to being a developer and drank the darkspawn blood and finally become a Git Warden, now shall wait out your continuous life in Freenode dusting the giant ruins of DF to unearth more stuff for the wizards of the camp to craft wonderful spells or trinkets of either entertainment or ease of use. This quest is a long and repeating one that has it's ups and downs, but's thats the life of a git warden. jokes aside that sounds like alot of effort to do in the middle of a dev cycle that updates around in weeks and that whole dfhack shouldn't cause people to wait out for the new update of DFH to play the new update of DF.
then again this is a opinion from a guy who writes scripts(lua) all day and too lazy or/and incompetent to write a solution that doesn't end with rewriting everything. Take with a grain of salt.
despite being the same original source (master branch of DFHack), previous DLLs would not work (aside from the version string issue), due to those changes?
Sanity check - if I understand what you said:despite being the same original source (master branch of DFHack), previous DLLs would not work (aside from the version string issue), due to those changes?
Most of them will because they don't use changed structures.
I have an idea:
Anybody that does an unofficial DFHack build that intends to release it should change the version number to reflect that.
So instead of being DFHack 40.12.r1, which is only for official builds, or 40.12.r0, which is ambiguous, it should be something like 40.12.whiny-and-impatient-noobs-version, to avoid confusion with the official releases.
I have an idea:That doesn't really solve the problem presented though does it? The idea is to make the default that would be grabbed by anyone not paying close enough attention be something that's easily distinguishable from a supported build, given the advice when waiting for official releases is and has been:
Anybody that does an unofficial DFHack build that intends to release it should change the version number to reflect that.
So instead of being DFHack 40.12.r1, which is only for official builds, or 40.12.r0, which is ambiguous, it should be something like 40.12.whiny-and-impatient-noobs-version, to avoid confusion with the official releases.
you'll have to wait or compile it on your own
Toady's gone a bit farther than that; he provides the guarantee of a complete absence of guarantee. He's said before that he doesn't want to have to keep 3rd party programs in mind when he writes Dwarf Fortress; it's pretty much the same problem as a UI API.This is interesting; the way he releases a new version in a matter of hours after each dfhack release and focuses on dfhack-fixable bugs first makes me wonder if he doesn't want people to get used too much to dfhack magic.
I have an idea:That's unfair, there are many legitimate reasons one would wish to compile from source, if one wants to add a port to Gentoo or a bleeding-edge package to the AUR. Maybe the version should be .40.12r1u2 (second unofficial build from the first dfhack release from the .40.12 version), .40.13r0u1 (first unofficial build from the .40.13 version) or even .34.11r5e1u1 for experimental builds expwnent has been known to release.
Anybody that does an unofficial DFHack build that intends to release it should change the version number to reflect that.
So instead of being DFHack 40.12.r1, which is only for official builds, or 40.12.r0, which is ambiguous, it should be something like 40.12.whiny-and-impatient-noobs-version, to avoid confusion with the official releases.
Forgive me if it's obvious, but it seems the problem at hand is the necessity to recompile every plugin every time the version number changes. However there doesn't seem to be this problem with scripts; is there any dfhack magic involved (save for that of laziness which I understand perfectly, mind you) that would prevent people from rewriting said plugins into lua/ruby scripts?
Plus as I understand it, there's a noticeable performance hit from running it as a Lua script instead of a compiled plugin, because it's compiled each time it's run + the abstraction to the memory addresses.Forgive me if it's obvious, but it seems the problem at hand is the necessity to recompile every plugin every time the version number changes. However there doesn't seem to be this problem with scripts; is there any dfhack magic involved (save for that of laziness which I understand perfectly, mind you) that would prevent people from rewriting said plugins into lua/ruby scripts?
Can't interpose vmethods in Lua; you need C++ to access events related to those.
Can't interpose vmethods in Lua; you need C++ to access events related to those.
Plus as I understand it, there's a noticeable performance hit from running it as a Lua script instead of a compiled plugin, because it's compiled each time it's run + the abstraction to the memory addresses.I don't know if it's "noticeable", and I don't know whether performance is paramount when dealing with a script that will only be punctually used (such as a gui or various hack magic). There's only that much stuff that runs continuously along the game (like emigration, rendermax or twbt).
I don't have any first-hand knowledge here, just relaying what I took away from Quietust's posts.Can't interpose vmethods in Lua; you need C++ to access events related to those.
From what I understand some events (the onSomething thingies) have been exported to lua, making it possible to use them in scripts, isn't that right?Plus as I understand it, there's a noticeable performance hit from running it as a Lua script instead of a compiled plugin, because it's compiled each time it's run + the abstraction to the memory addresses.I don't know if it's "noticeable", and I don't know whether performance is paramount when dealing with a script that will only be punctually used (such as a gui or various hack magic). There's only that much stuff that runs continuously along the game (like emigration, rendermax or twbt).
This is interesting; the way he releases a new version in a matter of hours after each dfhack release and focuses on dfhack-fixable bugs first makes me wonder if he doesn't want people to get used too much to dfhack magic.
Actually it's even more impresive than that. Some bug had code snippets (e.g. "i think you did for(int x=0;x<t;t++)... where you meant for(int x=0;x<t;x++)) with approximate location where to find it.This is interesting; the way he releases a new version in a matter of hours after each dfhack release and focuses on dfhack-fixable bugs first makes me wonder if he doesn't want people to get used too much to dfhack magic.
I'm pretty sure the main reason Toady's fixed so many of the dfhack-fixable bugs in this cycle is because Quietust and ag have done a yeoman's job of figuring out exactly what those bugs are, where they are located, and what would be necessary to fix them, and provided that information in the bug notes.
Some bugs had code snippets (e.g. "i think you did for(int x=0;x<t;t++)... where you meant for(int x=0;x<t;x++)) with approximate location where to find it.:o
I actually did a test about 2 years ago to see how much slower it would be to implement reveal as a script instead of a plugin. The script version took almost an entire minute to run, compared to the plugin which was pretty much instantaneous. It's made even worse by the fact that the script wasn't doing the extra work of saving unreveal information or avoiding revealing HFS - adding that would have made it even slower.Plus as I understand it, there's a noticeable performance hit from running it as a Lua script instead of a compiled plugin, because it's compiled each time it's run + the abstraction to the memory addresses.I don't know if it's "noticeable", and I don't know whether performance is paramount when dealing with a script that will only be punctually used (such as a gui or various hack magic). There's only that much stuff that runs continuously along the game (like emigration, rendermax or twbt).
I have recently downloaded the LNP for 40.12 and it of course comes with DFHack. Previously I started using DFHack on my last few 34.11 games and I don't use it for much. I like digx, cleanowned, fix/dead-units(?), and a few of the UI things (filters and cursor sticking).
Anyways, I started a new game with this latest version, and there is a new thing going on. I am getting some kind of intermediate display while I'm queueing work from workshops. This has happened in my kitchen, still, masonry, and carpentry workshops. If I recall correctly, it says something about the workshop not being assigned to a dwarf, and has an arrow on it pointing to the item I'm trying to build.
Again, it's not in front of me right now, so XXdescriptionXX and xaccuracyx, sorry. But if anyone could point me in the direction of a mod/fix/UI piece this might be, I'd appreciate it.
DFHack has this issue when you alt-tab out of the game, it still thinks you pressed alt and alt-r brings out a room gui. You probably set a workshop order to [r]epeat and it brought out this menu. Simply press alt again to resolve it.Yes, I am having this problem. I found it through google-fu on why I couldn't access my (m)ilitary screen.
Regarding 0.40.12-r1 'forum-dwarves' script included with the release version, in vanilla df 0.40.12:That's just from trying to use it to output the details of any object (in this case, cave spider silk trousers).Spoiler (click to show/hide)
I don't know how to fix the problem, or I would. :(
Seems like the stockflow is bugged. Had a hard lockup when my recordkeeper went to update his records. Crash does not occur if I insure there are no stockpiles with stockflow settings. Nothing is printed to stdout or stderr.
I have recently downloaded the LNP for 40.12 and it of course comes with DFHack. Previously I started using DFHack on my last few 34.11 games and I don't use it for much. I like digx, cleanowned, fix/dead-units(?), and a few of the UI things (filters and cursor sticking).
Anyways, I started a new game with this latest version, and there is a new thing going on. I am getting some kind of intermediate display while I'm queueing work from workshops. This has happened in my kitchen, still, masonry, and carpentry workshops. If I recall correctly, it says something about the workshop not being assigned to a dwarf, and has an arrow on it pointing to the item I'm trying to build.
Again, it's not in front of me right now, so XXdescriptionXX and xaccuracyx, sorry. But if anyone could point me in the direction of a mod/fix/UI piece this might be, I'd appreciate it.
The project could go to a 30-component version numbering scheme, but that seems stupid. Maybe some meta-structure that holds version numbers for the DF structures, and use that to register dependencies.Sanity check - if I understand what you said:despite being the same original source (master branch of DFHack), previous DLLs would not work (aside from the version string issue), due to those changes?
Most of them will because they don't use changed structures.
Let's say there are 30 structures total and that 2 of them changed. Most of the DLLs could work, because those 2 structures aren't ones "typically" used?
So phase 1 would be: if 0 of the structures changed, we're ok to use all the same plugins from before. Versioning would need to be based off identifying a specific changeset used from the symbols project.
Phase 2 would be figuring out a registration system, or some other method to see what specific structures are used, and identify the specific changeset AND structure used, which would require stricter handling on the plugin side, but looser coupling on the DFHack side.
Does that make sense?
As a counter argument I would provide an example of rendermax lighting mod. First implementation was in lua yes verrrrryyyy slow, but I had something almost nice in matter of minutes. The c++ engine ( though to be fair a lot more complex) took way longer and with help from other people.I actually did a test about 2 years ago to see how much slower it would be to implement reveal as a script instead of a plugin. The script version took almost an entire minute to run, compared to the plugin which was pretty much instantaneous. It's made even worse by the fact that the script wasn't doing the extra work of saving unreveal information or avoiding revealing HFS - adding that would have made it even slower.Plus as I understand it, there's a noticeable performance hit from running it as a Lua script instead of a compiled plugin, because it's compiled each time it's run + the abstraction to the memory addresses.I don't know if it's "noticeable", and I don't know whether performance is paramount when dealing with a script that will only be punctually used (such as a gui or various hack magic). There's only that much stuff that runs continuously along the game (like emigration, rendermax or twbt).
Most of the "fix" scripts also take a noticeable amount of time to run, and rewriting them as plugins would probably drop their execution times down to a few hundred milliseconds.
*peep*
A much more ambitious path is to include a plugin wrapper for experimental builds. It would check the version string and throw up an obvious console warning in the event of a mis-match.
********************************************************************
WARNING!
The plugin twbt.dll was compiled for DFHack version 0.40.12.r1
You are running DFHack version 0.40.13.i-cant-live-without-digv
********************************************************************
How do you want to proceed?
1. Do not load the plug-in (as if the DLL did not exist)
2. Load the plug-in this time
3. Load the plug-in and remember this decision (affects onLoad.init)
In any case, there are absolutely no guarantees about the behavior of a plug-in not designed specifically for that version. It turns out that .12 stuff would run fine under .11, but some .13 stuff would cause magma to ooze out of your USB ports. If someone is mucking around the sourcecode to make this compile, they should be aware of the risks.
That and the goal isn't to make plugins work with unofficial builds, but:*peep*
A much more ambitious path is to include a plugin wrapper for experimental builds. It would check the version string and throw up an obvious console warning in the event of a mis-match.
********************************************************************
WARNING!
The plugin twbt.dll was compiled for DFHack version 0.40.12.r1
You are running DFHack version 0.40.13.i-cant-live-without-digv
********************************************************************
How do you want to proceed?
1. Do not load the plug-in (as if the DLL did not exist)
2. Load the plug-in this time
3. Load the plug-in and remember this decision (affects onLoad.init)
In any case, there are absolutely no guarantees about the behavior of a plug-in not designed specifically for that version. It turns out that .12 stuff would run fine under .11, but some .13 stuff would cause magma to ooze out of your USB ports. If someone is mucking around the sourcecode to make this compile, they should be aware of the risks.
Just an end user on this project, though I am aware of the difficulties which can arise from doing stuff like that, but those sort of "just making sure you're informed before you bone everything up anyways" alerts are too often overlooked, and mostly appreciated by people who already know what they're getting into, sadly.
@Dirst: Twbt is a bad example, as it doesn't (only?) depend on symbols.xml, but uses hard-coded memory adresses. So that's one that needs to be recompiled for every df version.Indeed - if you tried editing the version string on TWBT to run it in a newer version than whatever it was compiled for, it would either refuse to run or crash the game entirely, neither of which are in any way useful. It also appears to contain a bunch of hardcoded binary patches, all of which were likely designed solely for version 0.34.11 and are thus nonfunctional in the current version anyways.
Seems like the stockflow is bugged. Had a hard lockup when my recordkeeper went to update his records. Crash does not occur if I insure there are no stockpiles with stockflow settings. Nothing is printed to stdout or stderr.
*peep*The compile-time macros would allow bleeding-edge DFHacks to be tested with not-yet-updated plug-ins. And yes TWBT would most likely crash the game and possibly take the region folder with it. That console prompt is not intended as an end-user feature in an official release, just a way for people to figure out what needs to be updated and what doesn't.
Just an end user on this project, though I am aware of the difficulties which can arise from doing stuff like that, but those sort of "just making sure you're informed before you bone everything up anyways" alerts are too often overlooked, and mostly appreciated by people who already know what they're getting into, sadly.
@Warmist: speaking of rendermax: any plans to update to 40.x?Rendermax doesn't work with 0.40.xx because (if I understand correctly), the script that automatically locates <vtable-address> entries in symbols.xml doesn't check for 'renderer', which rendermax requires. Warmist has made changes that make rendermax compile with 0.40.xx, but I've been unable to test them without the required offsets.
Actually it "should" locate it automatically (in windows) but for some reason does not. Though it's probably one of the easiest things to do (finding vtables that is) i am a very lazy (read: busy) person. Also everybody is sad because new version has low fps, so rendermax (which takes away yet more fps) are not on top of people list of things they like :P@Warmist: speaking of rendermax: any plans to update to 40.x?Rendermax doesn't work with 0.40.xx because (if I understand correctly), the script that automatically locates <vtable-address> entries in symbols.xml doesn't check for 'renderer', which rendermax requires. Warmist has made changes that make rendermax compile with 0.40.xx, but I've been unable to test them without the required offsets.
Also everybody is sad because new version has low fps, so rendermax (which takes away yet more fps) are not on top of people list of things they like :PBut it's soooooo preeeety! ;D
Actually it "should" locate it automatically (in windows) but for some reason does not. Though it's probably one of the easiest things to do (finding vtables that is) i am a very lazy (read: busy) person. Also everybody is sad because new version has low fps, so rendermax (which takes away yet more fps) are not on top of people list of things they like :PActually rendermax is what got me into that whole dfhack business, along with falconne's plugins. It's really nifty. Plus I think the few people who are aware that dfhack is a thing also know how to use rendermax options.
stonesense.plug.so: undefined symbol: al_color_rgb_to_hsv
Can't load plugin stonesense.plug.so
The compilation was successful, the linking process failed. You need to modify dfhack/plugins/isoworld/CMakeLists.txt file and add agui to linker. Here is my patch:Where libagui_allegro5.a and libagui.a are 32-bit .a files that are absent from the main repo and had to be compiled manually.Code: [Select]--- plugins/isoworld/CMakeLists.txt 2014-09-11 19:32:10.998717669 +0200
+++ plugins/isoworld/CMakeLists.txt 2014-08-28 01:18:09.000000000 +0200
@@ -91,6 +92,11 @@
allegro_image
allegro_ttf
${PROJECT_LIBS}
+ /home/majiin/repos/Agui/build/libagui_allegro5.a
+ /home/majiin/repos/Agui/build/libagui.a
+ )
+ include_directories (
+ /home/majiin/repos/Agui/include
)
ENDIF()
ENDIF()
Of course you need to change /home/majiin/repos/Agui/build/ and /home/majiin/repos/Agui/include to the location where you have those files. Maybe there is a simpler way to do this but this worked for me.
--- plugins/isoworld/MapSection.h 2014-09-11 17:47:18.331186059 +0200
+++ plugins/isoworld/MapSection.h 2014-09-09 12:12:36.000000000 +0200
@@ -32,7 +32,7 @@
void pointToSprite(float *inx, float *iny, int inz);
void load_heights(ALLEGRO_BITMAP * heightmap);
void load_water_level(ALLEGRO_BITMAP * watermap);
- void MapSection::load_colors(s_maplist * map_list);
+ void load_colors(s_maplist * map_list);
void load_level(ALLEGRO_BITMAP * levelmap, int level);
void load_biome_tiles(s_maplist * maplist);
void load_structure_tiles(ALLEGRO_BITMAP * structuremap);
It's working for me. What platform are you using? Is Ruby available?
It looks like the exterminate script may be broke for 0.40.12, assuming it's not something I am doing. Works fine on a clean install in 0.40.11 (Dwarf Fortress and DFHack only), but does nothing in a clean install of 0.40.12. Running the script gives nothing for output, and the same for any switches you try with it. Just FYI.
Windows 7 64. Have ruby installed. I tried running someone else's compilation of DFHack (0.40.12) for comparison and have the same issue.
Just to follow up my post. Works fine in the new release. Must have been something I did compiling it (be nice to know what but alas). And thanks for the new release! Appreciate all the work you all do!
Let's see, lately when building Isoworld I usually run into various issues, most of which have been solved by maijin:If you have to change something in isoworld to make it compile, a github fork is probably easier to find than some patches in a forum thread.The compilation was successful, the linking process failed. You need to modify dfhack/plugins/isoworld/CMakeLists.txt file and add agui to linker. Here is my patch:Where libagui_allegro5.a and libagui.a are 32-bit .a files that are absent from the main repo and had to be compiled manually.Code: [Select]--- plugins/isoworld/CMakeLists.txt 2014-09-11 19:32:10.998717669 +0200
+++ plugins/isoworld/CMakeLists.txt 2014-08-28 01:18:09.000000000 +0200
@@ -91,6 +92,11 @@
allegro_image
allegro_ttf
${PROJECT_LIBS}
+ /home/majiin/repos/Agui/build/libagui_allegro5.a
+ /home/majiin/repos/Agui/build/libagui.a
+ )
+ include_directories (
+ /home/majiin/repos/Agui/include
)
ENDIF()
ENDIF()
Of course you need to change /home/majiin/repos/Agui/build/ and /home/majiin/repos/Agui/include to the location where you have those files. Maybe there is a simpler way to do this but this worked for me.
Also, MapSection.h seems to have a weird line:Code: [Select]--- plugins/isoworld/MapSection.h 2014-09-11 17:47:18.331186059 +0200
+++ plugins/isoworld/MapSection.h 2014-09-09 12:12:36.000000000 +0200
@@ -32,7 +32,7 @@
void pointToSprite(float *inx, float *iny, int inz);
void load_heights(ALLEGRO_BITMAP * heightmap);
void load_water_level(ALLEGRO_BITMAP * watermap);
- void MapSection::load_colors(s_maplist * map_list);
+ void load_colors(s_maplist * map_list);
void load_level(ALLEGRO_BITMAP * levelmap, int level);
void load_biome_tiles(s_maplist * maplist);
void load_structure_tiles(ALLEGRO_BITMAP * structuremap);
Will post more as I recall along.
Is there a DFHack 0.34.11 r5-compatible script which makes injured but conscious dwarves take care of themselves?
There's fix/feeding-timers.
New release!
Is there a script which sets how many skill points dwarves have for skills at the start? like startdwarf.rb adds dwarves and points.rb adds points.Pretty sure this can be set in the worldgen.txt file.
https://github.com/DFHack/dfhack/blob/master/scripts/fix/feeding-timers.lua
Yeah I was just wondering as with points it's pretty easy to "change" when you at the "embark screen" but a bit more difficult since there isn't a script for it (yet) and you'd probably have to set it for x many dwarves which brings a bit more difficulty. Not as useful as the other 2 scripts that exist though.
:lua for _, dwf in ipairs(dfhack.gui.getCurViewscreen().dwarf_info) do dwf.levels_remaining = 11 end
Yeah I was just wondering as with points it's pretty easy to "change" when you at the "embark screen" but a bit more difficult since there isn't a script for it (yet) and you'd probably have to set it for x many dwarves which brings a bit more difficulty. Not as useful as the other 2 scripts that exist though.Code: [Select]:lua for _, dwf in ipairs(dfhack.gui.getCurViewscreen().dwarf_info) do dwf.levels_remaining = 11 end
Edit: Here's a script (https://github.com/lethosor/dfhack-scripts/blob/master/embark-skills.lua)
Is the superdwarf add command not working? I went to toggle it on earlier and there was no effect.
Is it possible to get dfhack working with stonesense under linux? Stonesense doesn't seem to be included in the linux build, so I tried to compile it myself, but I don't get further than "Could NOT find Threads (missing: Threads_FOUND)".
If you're trying to compile it you might need pthreads. I don't really know the details about stonesense so I'm not sure.
When compiling dfhack, make sure to run "ccmake .." before running make install, so you can toggle what you want to build, you'll see there's a stonesense include option.
Oh, and delete all the CMake things like CMakeCache if you've been installing things. I couldn't figure out why it wasn't recognizing a prerequisite for hours my first time because the CMakeCache had wrong things in it from the first compile attempt. This is very rarely the problem but it might fix it I guess.
The [M]ark all feature is implemented in autotrade (a DFHack plugin), so the problem can't occur without DFHack.I can put up a save if needed too - I noticed this but forgot to follow up on it.
Euius, could you upload a save for testing purposes?
0 = userdata: 00000002
1 = userdata: 00000003
2 = userdata: 00000004
3 = userdata: 00000005
4 = userdata: 00000006
5 = userdata: 00000007
6 = userdata: 00000008
7 = userdata: 00000009
8 = userdata: 0000000A
9 = userdata: 0000000B
10 = userdata: 0000000C
11 = userdata: 0000000D
12 = userdata: 0000000E
13 = userdata: 0000000F
14 = userdata: 00000010
15 = userdata: 00000011
16 = userdata: 00000012
for i=1,#vs.sites do
gui.simulateInput(vs, 'LEGENDS_EXPORT_MAP')
--I don't know what "down" is, so just put that here
end
function export_site_maps()
vs = dfhack.gui.getCurViewscreen()
print(' Attempting to export site maps...')
-- get to sites screen before the next bit
for i=1,#vs.sites do
gui.simulateInput(vs, 'LEGENDS_EXPORT_MAP')
gui.simulateInput(vs, 'STANDARDSCROLL_DOWN')
end
end
You might want to make vs local ("local vs =" instead of just "vs =") there, since it's in a function and all. Just good practice in programming.
Not sure if this is the problem, but "(CDI:INTERACTION:CONJURE)" is not the same as "[CDI:INTERACTION:CONJURE]".Code: (In my Wizard Creature's raws) [Select][CAN_DO_INTERACTION:CONJURE]
[CDI:ADV_NAME:Conjure Bound Dagger]
(CDI:INTERACTION:CONJURE)
[CDI:TARGET:A:SELF_ONLY]
[CDI:MAX_TARGET_NUMBER:A:1]
[CDI:VERB:conjure a bound dagger:conjures a bound dagger:NA]
[CDI:WAIT_PERIOD:86400]
Not sure if this is the problem, but "(CDI:INTERACTION:CONJURE)" is not the same as "[CDI:INTERACTION:CONJURE]".Code: (In my Wizard Creature's raws) [Select][CAN_DO_INTERACTION:CONJURE]
[CDI:ADV_NAME:Conjure Bound Dagger]
(CDI:INTERACTION:CONJURE)
[CDI:TARGET:A:SELF_ONLY]
[CDI:MAX_TARGET_NUMBER:A:1]
[CDI:VERB:conjure a bound dagger:conjures a bound dagger:NA]
[CDI:WAIT_PERIOD:86400]
I'm pretty sure I've got bad syntax in my onLoad.init, or I've put the onLoad.init in the wrong place or something like that.What happens if you load the game and then manually copy/paste the contents of onLoad.init into the DFHack console window?
You can also invoke devel/print-args (e.g. "devel/print-args test") in onLoad.init to display a message if/when onLoad.init is run.
Also, have you verified that the file was saved as "onLoad.init" and not "onLoad.init.txt"?
[CDI:VERB:conjure a bound dagger:conjures a bound dagger:NA]
modtools/interaction-trigger -onAttackStr "conjure a bound dagger" -command [ item/create -unit \\ATTACKER_ID -item WEAPON:ITEM_WEAPON_DAGGER_BOUND -mat SOUL_BOUND -inventory -dur 86400 ]
[CDI:VERB:summons a steel sword:summons a steel sword:summons a steel sword]
modtools/interaction-trigger -onAttackStr "summons a steel sword" -command [ item/create -unit \\ATTACKER_ID -item WEAPON:ITEM_WEAPON_SWORD -mat STEEL -inventory ]
which is code given to me by roses, but I can't get that to work either. :s
Too few actors is something EventManager prints when it can figure out either the attacker or the defender but not both. Can you figure out what makes that happen?
Heh. I might have been silly and not tested self-interactions. Does it work if you cast it on someone else?
Too few actors is something EventManager prints when it can figure out either the attacker or the defender but not both. Can you figure out what makes that happen?
Heh. I might have been silly and not tested self-interactions. Does it work if you cast it on someone else?
I forget but I might have set it up so it only prints the message once per run of DF, which makes it really awkward to test.
Good thing VERBAL_SPEECH points to a text file and takes lines from it at random.
Try out, say, Fortbent, where there are a few creatures (ebubbles) that have hundreds of lines in their verbal_speech files for their interactions.
Good thing VERBAL_SPEECH points to a text file and takes lines from it at random.
Try out, say, Fortbent, where there are a few creatures (ebubbles) that have hundreds of lines in their verbal_speech files for their interactions.
Not sure if this was aimed at me
Are you unpausing? 'exterminate' takes 1-2 in-game ticks to take effect.
Are you unpausing? 'exterminate' takes 1-2 in-game ticks to take effect.
Yep. That yak was wandering happily around much longer than that.
I attacked him with three dwarves. He killed all three.
Can you use DFHack to add a syndrome to the selected dwarf?
i.e. to turn a dwarf into a vampire
Yes, but the syndrome has to have a name. See the modtools/add-syndrome script for details.
Thanks, I'm assuming the name given in the LegendsViewer would work.
Also, it was called add-syndrome?!
I ctrl-f'd all over the place, well sorry for having missed it with so obvious a name.
Superdwarf report (https://github.com/DFHack/dfhack/issues/337)
What's the error message? Does this commit (https://github.com/jjyg/dfhack/commit/eed684a8dfba80c04964a5b5ada1621fde3caaa5) work?
I took some time to fix forum-dwarves script (if you don't know what's this: here's a sample of what it does)Nicely done! Thank you very much, Mchl.
...
Anyone else have issues with the copy savegame option? It does not seem to do anything at all?Fixdiplomats can indeed be removed since Toady readded Elven diplomats, but he hasn't readded Human Guild Representatives so Fixmerchants is still useful.
(using .13 starter pack r3)
Additionally can't "fixdiplomats and fixmerchants" be removed? the issue seem to be fixed.
modtools/interaction-trigger -onAttackStr "summons a steel sword" -command [ devel/print-args "Steel sword summoned" ]
modtools/interaction-trigger -onAttackStr "summons a steel sword" -command [ rendermax ]
Doesn't do anything at all though. Now, I'm not sure if using devel/print-args like this should work, but simply writing the command "rendermax" into the console generally throws an error. This doesn't though, and nothing happens.
interaction-trigger does not work in the arena AFAIK, probably for the same reason most tick-based repeating loops don't.
turn on showing file extensions in windows. If you see a .txt at the end of the file, get rid of it.
I have a question about customizing the spawn (https://gist.github.com/Rumrusher/f4d0ba18ba6868d38221) script: How can you tell "what time it is" to set the spawned creature's birth time exactly? In my case, the creature comes into being the moment the script is called (no backdated birthdays), so unit.relations.birth_year=df.global.cur_year gets the year right. Is it unit.relations.birth_time=df.global.curr_year_ticks to set the birth time? The historical figure data seems to want hf.born_seconds and I'm not sure how "ticks" relate to "seconds" here.
If I understand my search results correctly, this screen is from stackflow, right?No, this is the "gui/room-list" script, accessible (by default) by pressing Alt-R when viewing a building. If you're using Windows and meant to press "R", it's possible that the "Alt" key is stuck - pressing and releasing it should fix the problem.Spoiler (click to show/hide)
Does anyone know whether the stockpile "autodump" portion of Falconne's "UI Improvement Plugins" ever got updated for DF2014?
interaction-trigger does not work in the arena AFAIK, probably for the same reason most tick-based repeating loops don't.
I'm testing it in adventure mode though. Should the commands that I posted work, or are they completely wrong?
Also, how would I go about launching scripts every time a new region is loaded? I'm writing a script that should log the beliefs of any historical figures the player meets, but I have no idea how to automate the launching of the script. I'm not sure if "region" is the right term, but I need to the script to run whenever a new historical figure might be loaded.
interaction-trigger does not work in the arena AFAIK, probably for the same reason most tick-based repeating loops don't.
I'm testing it in adventure mode though. Should the commands that I posted work, or are they completely wrong?
Also, how would I go about launching scripts every time a new region is loaded? I'm writing a script that should log the beliefs of any historical figures the player meets, but I have no idea how to automate the launching of the script. I'm not sure if "region" is the right term, but I need to the script to run whenever a new historical figure might be loaded.
Actually I think it has trouble in just adventure mode. It does things by searching through combat logs so unless your name is "you" it doesn't find the adventurer. I'll fix it when I can.
Does anyone know whether the stockpile "autodump" portion of Falconne's "UI Improvement Plugins" ever got updated for DF2014?
No, it hasn't. It can be compiled in its current state, but would need a bit of work, just like stockflow, autotrade, and automelt did, to play nicely with the new behavior of the stockpile links. I haven't done that, out of apathy, though I have found Falconne's source code for it. I'm curious; what would an auto-dumping stockpile provide for you that minecarts don't?
Is there a protocol to get a script/tool added to the main install? I've got a couple ideas I'd like to try out (and learn myself some lua or ruby) and it would be nice to get them included in future versions (assuming I ever get them to that point and they would be useful). I don't really see any documentation on "so you want to help develop for dfHack"...Most people make a PR (once a script is ready for inclusion), although this thread and #dfhack on irc.freenode.net also work. In order to make a PR, you'd need to fork DFHack/dfhack (https://github.com/dfhack/dfhack) on Github, create a new branch from the "develop" branch, add your script to it and create a PR based on "DFHack:develop" (i.e. the develop branch of DFHack/dfhack).
How do I view my adventurers reputation while in an adventure game? Or rather, can I?
Is there a protocol to get a script/tool added to the main install? I've got a couple ideas I'd like to try out (and learn myself some lua or ruby) and it would be nice to get them included in future versions (assuming I ever get them to that point and they would be useful). I don't really see any documentation on "so you want to help develop for dfHack"...Most people make a PR (once a script is ready for inclusion), although this thread and #dfhack on irc.freenode.net also work. In order to make a PR, you'd need to fork DFHack/dfhack (https://github.com/dfhack/dfhack) on Github, create a new branch from the "develop" branch, add your script to it and create a PR based on "DFHack:develop" (i.e. the develop branch of DFHack/dfhack).
Mostly the ability to automagically dump everything from my indoors refuse pile down the garbage chute (80z's down straight into the magma bath with all of those useless goblin clothes!) ... without having to learn how to use mine carts. :D
I suppose this would probably be a good time for me to learn how to use minecarts, eh? :P
Also: was it you that recompiled and updated the other plugins like automelt for the new version? If so, or if you've done any other work on dfhack at all -- thank you so much! dfhack makes my entire Dwarf Fortress experience much more enjoyable, and I really appreciate it.
Mostly the ability to automagically dump everything from my indoors refuse pile down the garbage chute (80z's down straight into the magma bath with all of those useless goblin clothes!) ... without having to learn how to use mine carts. :D
I suppose this would probably be a good time for me to learn how to use minecarts, eh? :P
This seems like a perfect application for them, yes. They're really not that bad, though setting up tracks can be a bit finicky.
Can you use DFHack to add a syndrome to the selected dwarf?
i.e. to turn a dwarf into a vampireYes, but the syndrome has to have a name. See the modtools/add-syndrome script for details.
Thanks, I'm assuming the name given in the LegendsViewer would work.
Also, it was called add-syndrome?!
I ctrl-f'd all over the place, well sorry for having missed it with so obvious a name.
I tried a bunch of things with this and could not figure out how to make it work. Can anyone tell me the command you'd use to make a vampire.
-snip
If none say vampire, then none are named vampire and your script as written won't work.
The DFFD links seem to be dead, and the DFHACK/dfhack site only seems to have source doe downloads. Is there a mirror where I can get the Windows release?
The DFFD links seem to be dead, and the DFHACK/dfhack site only seems to have source doe downloads. Is there a mirror where I can get the Windows release?
DFFD isn't dead right now...
The INVENTORY_CHANGE event currently crashes the game whenever it runs regardless of listeners.
The INVENTORY_CHANGE event currently crashes the game whenever it runs regardless of listeners.
That's bad. I'll take a look. Out of curiosity what mode did you test it in?
[lua]# for k,v in pairs(miner_unit.syndromes.active[0]) do print(k,v) end
type 1
year 125
year_time 18832
ticks 3
wounds <vector<int32_t>: 0x35ff2840>
wound_id -1
symptoms <vector<unit_syndrome.T_symptoms*>: 0x35ff2854>
reinfection_count 1
flags <unit_syndrome.T_flags: 0x35ff2868>
unk4 <vector<int32_t>: 0x35ff286c>
df.syndrome.find(type)Thank you Putnam. That .find method didn't show up when I iterated over the df.syndrome object (my guess is that no methods would). Is there some way in lua to interrogate all of the attributes and methods of an object? Or better yet, an object model somewhere? I tried searching in symbols.xml, but that doesn't have everything.
df.syndrome.find(type)Thank you Putnam. That .find method didn't show up when I iterated over the df.syndrome object (my guess is that no methods would). Is there some way in lua to interrogate all of the attributes and methods of an object? Or better yet, an object model somewhere? I tried searching in symbols.xml, but that doesn't have everything.
digFlood doesn't like me. Per the man page I added a command to my dfhack.init but every time I launch it fails.Do you see an equivalent error with "Cassiterite" when deleting BISMUTHINITE? (It should be CASSITERITE, not CASSERITE, by the way.) If so, you'll probably need to run that command with a world loaded - you can do this automatically by adding it to the "onLoadWorld.init" file (creating it if necessary) in the same folder as dfhack.init.
digFlood BISMUTHINITE CASSERITE GALENA GARNIERITE HEMATITE LIMONITE MAGNETITE MALACHITE SPHALERITE TETRAHEDRITE LIGNITE
this kicks back: Could not find material "BISMUTHINITE"
I'm spelling it correctly per the wiki and the raws, so what am I doing wrong?
digFlood doesn't like me. Per the man page I added a command to my dfhack.init but every time I launch it fails.
digFlood BISMUTHINITE CASSERITE GALENA GARNIERITE HEMATITE LIMONITE MAGNETITE MALACHITE SPHALERITE TETRAHEDRITE LIGNITE
this kicks back: Could not find material "BISMUTHINITE"
I'm spelling it correctly per the wiki and the raws, so what am I doing wrong?
digFlood 1 [materials]
I found a small bug in modtools/add-syndrome.lua
On line 122, it should read
local affectedCaste = syndrome.syn_affected_caste[caste].value
instead of
local affectedCaste = syndrome.syn_affectedCaste[caste].value
Fixing that made it a couple orders of magnitude easier for me to troubleshoot my scripts.
Thanks for all the awesomeness that is DFHack! Now I'm off to stumble my way through art assets...
I thought it'd be handy if some of the functions were grouped under some user-friendly headers.. An example would be a "Interacting with liquids" section that'd list any and all dfhack functions that deal with liquid interactions or usage.. Some other sections/groups could be 'Workflow controls", "Patches and repairs", "Commands that can kill", "Cleaning and framerate", "Item manipulation", stuff like that..
Basically it'd provide shorter and more focused lists of dfhack features in help-file format and give new users a cleaner way to explore available functions without scanning the gigantic/daunting 'ls' list :>
Also, enabling the 'liquids' command to place blood and venom, or extracts/dusts/illnesses in liquid form, if possible, would be insane.. Purposefully dumping sadness on my dwarves for science..
/home/drokles/DFML-1-11/df/df_linux_0_40_13/hack/plugins/stonesense.plug.so: undefined symbol: al_color_rgb_to_hsvI have understood that some clever folks made stonesense work by building it in such a way that allegro is included properly in the build, but is it really necessary to build Stonesense from scratch in order to make it work?
Can't load plugin /home/drokles/DFML-1-11/df/df_linux_0_40_13/hack/plugins/stonesense.plug.so
Well there does seem to be something as opposed to past versions, this is interesting:Code: [Select]stonesense.plug.so: undefined symbol: al_color_rgb_to_hsv
Can't load plugin stonesense.plug.so
https://github.com/DFHack/dfhack/issues/282
I'll try to rebuild my Linux build (GCC 4.5.4) with Eswald's change when I get a chance.
Just out of curiousity, is it possible to replace all stone with adamantine ore? If so, how? I want to play a fort like this for fun.http://dwarffortresswiki.org/index.php/DF2014:Cheating#Skill_Practice_Workshops
[REACTION:PRACTICE_ARMORSMITHING]
[NAME:practice armorsmithing]
[BUILDING:PRACTICE_WORKSHOP:NONE]
[REAGENT:B:1:BOULDER:NO_SUBTYPE:NONE:NONE][PRESERVE_REAGENT]
[PRODUCT:100:1:BAR:NO_SUBTYPE:METAL:ADAMANTINE][PRODUCT_DIMENSION:150]
[SKILL:FORGE_ARMOR]
digFlood doesn't like me. Per the man page I added a command to my dfhack.init but every time I launch it fails.Do you see an equivalent error with "Cassiterite" when deleting BISMUTHINITE? (It should be CASSITERITE, not CASSERITE, by the way.) If so, you'll probably need to run that command with a world loaded - you can do this automatically by adding it to the "onLoadWorld.init" file (creating it if necessary) in the same folder as dfhack.init.
digFlood BISMUTHINITE CASSERITE GALENA GARNIERITE HEMATITE LIMONITE MAGNETITE MALACHITE SPHALERITE TETRAHEDRITE LIGNITE
this kicks back: Could not find material "BISMUTHINITE"
I'm spelling it correctly per the wiki and the raws, so what am I doing wrong?
Yeah, but is there a way to replace stone with adamantium? I saw someone else do it, and thought it was interesting.Just out of curiousity, is it possible to replace all stone with adamantine ore? If so, how? I want to play a fort like this for fun.http://dwarffortresswiki.org/index.php/DF2014:Cheating#Skill_Practice_Workshops
Is your goal to have a lot of adamantine around? Just add in the production of adamantine to one of the above reactions. For example:Code: [Select][REACTION:PRACTICE_ARMORSMITHING]
[NAME:practice armorsmithing]
[BUILDING:PRACTICE_WORKSHOP:NONE]
[REAGENT:B:1:BOULDER:NO_SUBTYPE:NONE:NONE][PRESERVE_REAGENT]
[PRODUCT:100:1:BAR:NO_SUBTYPE:METAL:ADAMANTINE][PRODUCT_DIMENSION:150]
[SKILL:FORGE_ARMOR]
Or any reaction, for that matter.
Which file are you referring to?digFlood doesn't like me. Per the man page I added a command to my dfhack.init but every time I launch it fails.Do you see an equivalent error with "Cassiterite" when deleting BISMUTHINITE? (It should be CASSITERITE, not CASSERITE, by the way.) If so, you'll probably need to run that command with a world loaded - you can do this automatically by adding it to the "onLoadWorld.init" file (creating it if necessary) in the same folder as dfhack.init.
digFlood BISMUTHINITE CASSERITE GALENA GARNIERITE HEMATITE LIMONITE MAGNETITE MALACHITE SPHALERITE TETRAHEDRITE LIGNITE
this kicks back: Could not find material "BISMUTHINITE"
I'm spelling it correctly per the wiki and the raws, so what am I doing wrong?
I did it manually with a world loaded and it worked much better. The man file should be updated to put the commands into onLoadWorld.init
Which file are you referring to?
I did it manually with a world loaded and it worked much better. The man file should be updated to put the commands into onLoadWorld.init
DFHack is not a mod.
Also check thisWell there does seem to be something as opposed to past versions, this is interesting:Code: [Select]stonesense.plug.so: undefined symbol: al_color_rgb_to_hsv
Can't load plugin stonesense.plug.sohttps://github.com/DFHack/dfhack/issues/282
I'll try to rebuild my Linux build (GCC 4.5.4) with Eswald's change when I get a chance.
EDIT: Didn't quite read your post correctly, sorry. For the inconvenience I can upload a build of stonesense that works on my machine, if you're interested.
/usr/lib/i386-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /home/jbabcock/df_linux/hack/plugins/twbt.plug.so) Can't load plugin /home/jbabcock/df_linux/hack/plugins/twbt.plug.so world: 2432492 ui: 28440 b_stock: 1272 d_init: 372
/usr/lib/i386-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /home/jbabcock/df_linux/hack/plugins/stonesense.plug.so) Can't load plugin /home/jbabcock/df_linux/hack/plugins/stonesense.plug.so
Yeah, but is there a way to replace stone with adamantium? I saw someone else do it, and thought it was interesting.Assuming you mean "adamantine", there is a "changelayer" command which does exactly that.
"GLIBCXX_3.4.20" corresponds to GCC 4.9.0 (see this page (https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html) for a complete list). It appears that those two plugins were compiled with GCC 4.9, so they won't work unless you have GCC 4.9 libraries available.DFHack is not a mod.
Also check thisWell there does seem to be something as opposed to past versions, this is interesting:Code: [Select]stonesense.plug.so: undefined symbol: al_color_rgb_to_hsv
Can't load plugin stonesense.plug.sohttps://github.com/DFHack/dfhack/issues/282
I'll try to rebuild my Linux build (GCC 4.5.4) with Eswald's change when I get a chance.
EDIT: Didn't quite read your post correctly, sorry. For the inconvenience I can upload a build of stonesense that works on my machine, if you're interested.
I'm also having this problem. I substituted the stonesense liib that Nopenope provided (thanks) but something is still wrong. It looks like it is looking for version 3.4.20, but you are compiling it with 4.5.4. Also, I have replaced df_linux/libs/libsdtc++.so.6 with the gcc-snapshot version. Maybe I have a LD_LIBRARY_PATH problem? Everything else seems to load and run properly.Code: [Select]/usr/lib/i386-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /home/jbabcock/df_linux/hack/plugins/twbt.plug.so) Can't load plugin /home/jbabcock/df_linux/hack/plugins/twbt.plug.so world: 2432492 ui: 28440 b_stock: 1272 d_init: 372
/usr/lib/i386-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /home/jbabcock/df_linux/hack/plugins/stonesense.plug.so) Can't load plugin /home/jbabcock/df_linux/hack/plugins/stonesense.plug.so
It is also fun and a great way to break things, but just turning stone into adamantine isn't so bad, be careful doing it with soil layers though, that gets a bit weird.Yeah, but is there a way to replace stone with adamantium? I saw someone else do it, and thought it was interesting.Assuming you mean "adamantine", there is a "changelayer" command which does exactly that.
I know DFHack has drainaquifer. Is the reverse possible? Could a layer be turned into an aquifer layer?
Yes - I've had small sections of an aquifer remain after running drainaquifer.I know DFHack has drainaquifer. Is the reverse possible? Could a layer be turned into an aquifer layer?It also appears that the drainaquifer script might be slightly wrong; it can miss aquifers that happen to miss the two tiles it checks, and it ignores the two block-level flags. Is that a problem in practice?
A quick question. I've pored over the DFHack readme multiple times but I can't seem to for the life of me figure out how to get the mod manager GUI to work without throwing up an error
Hi all,
I've been experiencing some strange behaviour with the digtype plugin. When I invoke the plugin, any constructed walls built in previously mined veins of that type are marked for removal. Is this intended behaviour? It seems strange if it is.
I'm using the Starter Pack 40_13 r4
If this is not the best place to report this please direct me to a more appropriate place.
Cheers
It also appears that the drainaquifer script might be slightly wrong; it can miss aquifers that happen to miss the two tiles it checks, and it ignores the two block-level flags. Is that a problem in practice?Yes - I've had small sections of an aquifer remain after running drainaquifer.
This is the error I usually get when inputting the command:A quick question. I've pored over the DFHack readme multiple times but I can't seem to for the life of me figure out how to get the mod manager GUI to work without throwing up an errorWhich error is very important.
...\Dwarf Fortress 0.40.13\hack\scripts/gui/mod-manager.lua:247: attempt to index local 'choice' (a nil value)
stack traceback:
...\Dwarf Fortress 0.40.13\hack\scripts/gui/mod-manager.lua:247: in function <...\Dwarf Fortress 0.40.13\hack\scripts/gui/mod-manager.lua:246>
[C]: in function 'on_select'
... 0.40.13\Dwarf Fortress 0.40.13\hack\lua\gui\widgets.lua:491: in function 'moveCursor'
... 0.40.13\Dwarf Fortress 0.40.13\hack\lua\gui\widgets.lua:447: in function 'setSelected'
... 0.40.13\Dwarf Fortress 0.40.13\hack\lua\gui\widgets.lua:442: in function 'setChoices'
... 0.40.13\Dwarf Fortress 0.40.13\hack\lua\gui\widgets.lua:423: in function 'fun'
...rtress 0.40.13\Dwarf Fortress 0.40.13\hack\lua\class.lua:98: in function 'invoke_after_rec'
...rtress 0.40.13\Dwarf Fortress 0.40.13\hack\lua\class.lua:127: in function 'List'
...\Dwarf Fortress 0.40.13\hack\scripts/gui/mod-manager.lua:207: in function 'fun'
...rtress 0.40.13\Dwarf Fortress 0.40.13\hack\lua\class.lua:98: in function 'invoke_after_rec'
...rtress 0.40.13\Dwarf Fortress 0.40.13\hack\lua\class.lua:127: in function 'manager'
...\Dwarf Fortress 0.40.13\hack\scripts/gui/mod-manager.lua:347: in main chunk
(...tail calls...)
I know DFHack has drainaquifer. Is the reverse possible? Could a layer be turned into an aquifer layer?
Yes. On the map block level, there are three flags to set: flags.has_aquifer, flags.check_aquifer, and designation[x%16][y%16].water_table for each tile you want to turn into a water source. In addition, df.global.world.raws.inorganics[???].flags.AQUIFER for that tile's rock/soil type needs to be true. (Or perhaps the tile's layer type; I haven't experimented with veins and inclusions.)
Even after all four flags are set, it might take a few steps for the new aquifer to start leaking.
It also appears that the drainaquifer script might be slightly wrong; it can miss aquifers that happen to miss the two tiles it checks, and it ignores the two block-level flags. Is that a problem in practice?
Does the mod have an init.lua?They do.
there is no longer a script to force sieges.Just to expand that a bit... siege armies now actually move across the map to your fort. They no longer appear out of thin air.
there is no longer a script to force sieges.However, it is still possible to force megabeasts to arrive. Just take the script "devel/migrants-now" and change "Migrants" to "Megabeast" and replace the entity line with "entity = nil".
there is no longer a script to force sieges.Just to expand that a bit... siege armies now actually move across the map to your fort. They no longer appear out of thin air.
You can use spawn-unit to create 10 hostile bronze colossi, but that's not quite the same thing as a megabeast attack.
there is no longer a script to force sieges.However, it is still possible to force megabeasts to arrive. Just take the script "devel/migrants-now" and change "Migrants" to "Megabeast" and replace the entity line with "entity = nil".
:o Yeah, not messing with files.
If you look at modtools/force that should give you what you want.
General unit creation is still being researched, and there's currently no way to spawn sieges because they're more complicated now.
I've no idea if this works because nothing is coming when I put Megabeasts. Maybe I would need to have met the requirements for them to come?It does indeed respect the megabeast population/wealth/export requirements.
-civ player refers to the civ where the event comes from, not where it's going to. NightCreature doesn't work, no.
Pausing has that effect...
Is there any way to execute a script when world gen starts?
Also, how would I go about freezing DF, doing some stuff, and then resuming the game? Does dfhack.with_suspend(f[,args...]) do anything like this? How would I go about using this? :)
Is there any way to execute a script when world gen starts?
Also, how would I go about freezing DF, doing some stuff, and then resuming the game? Does dfhack.with_suspend(f[,args...]) do anything like this? How would I go about using this? :)
Currently there is no way of doing that.
DF is already frozen during Lua script execution.
r4 wasn't exactly an official release, but here's (http://dffd.wimbli.com/file.php?id=8474) an OS X build.Thanks, that seems to have taken a step in the right direction as twbt is working correctly now, yet there's still strange segfaults whenever worldgen starts to create caves; from this I assume this means that somehow dfhack is going all weird when creating certain civs.
You should probably post masterwork problems in the masterwork area of the forums, meph added things to dfhack that would cause df to crash at some point if you used the wrong version of dfhack.Huh, I didn't know that. Do you know what things specifically, and if they're not in the source code/can be fixed manually? I only posted this here because dfhack is a big part of mdf and it seems odd that it would only crash upon using masterwork RAWS... which is strange, as the raws are not code but rather a large compilation of various tags. If I wanted to present this problem on the mdf forums, where should I put it? It's not race- or gui- specific, and the mac version thread is old, so I don't really know whether or not to create a new thread.
You should probably post masterwork problems in the masterwork area of the forums, meph added things to dfhack that would cause df to crash at some point if you used the wrong version of dfhack.Huh, I didn't know that. Do you know what things specifically, and if they're not in the source code/can be fixed manually? I only posted this here because dfhack is a big part of mdf and it seems odd that it would only crash upon using masterwork RAWS... which is strange, as the raws are not code but rather a large compilation of various tags. If I wanted to present this problem on the mdf forums, where should I put it? It's not race- or gui- specific, and the mac version thread is old, so I don't really know whether or not to create a new thread.
The cavegrasses grow once you've broke through to a cave then you can seal it up and the grasses will still continue to grow.You can also use "feature" to trigger a cavern discovery (allowing grass to grow) without actually breaching a cavern.
revflood seems to work for me. What exactly is the problem?The cavegrasses grow once you've broke through to a cave then you can seal it up and the grasses will still continue to grow.You can also use "feature" to trigger a cavern discovery (allowing grass to grow) without actually breaching a cavern.
I'm pretty sure that's expected behavior, since there's no way to make an underground room with constructed walls without revealing the adjacent natural walls (assuming they exist).revflood seems to work for me. What exactly is the problem?The cavegrasses grow once you've broke through to a cave then you can seal it up and the grasses will still continue to grow.You can also use "feature" to trigger a cavern discovery (allowing grass to grow) without actually breaching a cavern.
It just doesn't hide any tiles. I did a failproof test by building a wall behind a natural wall and nothing got hidden. Like this: http://i.imgur.com/L8mm2.jpg
How would one go about expanding the embark tools plugin?I'm not sure if samanato ever got an answer, but I was hoping to make a variation of the sand indicator for my mod as well, to indicate the presence of "living stone" (a set of several minerals added by the mod). Ideally, I'd like the player to be able to filter locations by its presence, but that's probably beyond my limited coding capabilities.
In my major mod, smelter reactions are all custom reactions with additional reagents to the ore itself. For example, tetrahedrite smelting needs a flux in rough green glass which you can get in several ways, lead and tin ores need another coal bar to reduce the oxide, and ironworking is done entirely outside of the smelter. This means, metal ores are no longer considered as such by the vanilla game, so that they no longer appear on the embark screen as "Shallow Metal" and "Deep Metal".
I want to restore something like that to the embark screen, which I think would work in a similar way to the sand indicator. As groundwork I've prefixed all the ore names with METAL_ORE_ (so, METAL_ORE_HEMATITE and so on). How would such a script work, so that for example, the string to search would be "METAL_ORE_"? Ideally I would like for it to work like vanilla (with plurals and depth and all) though that is too much wizardry for me (I can't into DFHack programming :()
How do I get prospect to work before embarkation?
At both the embark selection and points allocation stages, if I Ctrl-Shift-p and type prospect (or prospect all, etc.), all I get is, "Map is not available!" in red text. Is there something I need to do beforehand to make the map open to dfhack?
I'm running dfhack 0.40.13 (though this has happened in previous 0.40 releases as well) in Ubuntu 14.04 / Linux Mint 17.
You need to run "prospect all" in the DFHack console (i.e. not the in-game command prompt). "prospect" expects the top viewscreen to be the embark selection screen, and the command-prompt plugin creates its own viewscreen above the current viewscreen.
I know this isn't the right version of dfhack, but the previous dwarfhack forums are locked so I have to post my question here.
I seem to be having a problem using the plugin syndrome triggerSpoiler: MY INTERACTION (click to show/hide)
It looks correct so I have no idea whats wrong (I did enable syndrometriger in the init file). I'm using the r4 version of 34.xx
http://i.imgur.com/tH4HQgG.png
The little area I walled off to the left doesn't get filled in by revflood.
I dont know whats wrong.
My best guess is that constructed walls aren't treated as terrain that blocks visibility.
I cannot see why slayrace wouldn't work with syndrometrigger.
there is no longer a script to horse sieges.Just to expand that a bit... siege armies now actually move across the map to your fort. They no longer appear out of thin air.
You can use spawn-unit to create 10 hostile bronze colossi, but that's not quite the same thing as a megabeast attack.
there is no longer a script to force sieges.Just to expand that a bit... siege armies now actually move across the map to your fort. They no longer appear out of thin air.
I have a bit of a request for the pros here, I'm running into a town related crash (http://www.bay12games.com/dwarves/mantisbt/view.php?id=8290) in adventure mode, though specifically I want to see if I can save this savegame (http://dffd.wimbli.com/file.php?id=9936), especially since that adventurer is underground and thus, kind of stuck.
Basically, I'm just wondering if you guys can somehow salvage that specific savegame, but providing some insight into what's causing the crash would be of help to Toady One.
I might be able to get out by saving every ten steps or something.
I'm using Peridexis's starter pack r1.
Edit: Okay, I got out by saving every ten steps. Seems that once the trouble spot got offloaded, it stopped crashing, I think.
You know, instead of ignoring my posts, you guys (including the pros) could just say 'no idea' if you have no idea how to look into it.
I am really disliking the fact that it looks like you people are ignoring my posts. :<
You know, instead of ignoring my posts, you guys (including the pros) could just say 'no idea' if you have no idea how to look into it.
I am really disliking the fact that it looks like you people are ignoring my posts. :<
The problem with that is, if nobody really knew how to deal with it, then what you'd get would be about a dozen posts saying, "No idea." For every single post that they didn't know about—not to mention the half-dozen or so saying "No idea" for every post that some of them knew the answers to. Because there isn't some central repository of knowledge, and the "pros", as you call them, aren't this close-knit group of hotshot developers that consult behind the scenes about every single post on the thread; they're really just a bunch of guys, and it's pretty much expected that if anyone knows how to answer the question, they simply will.
So I'm afraid you're just going to have to deal with the fact that if you ask questions nobody knows the answer to, the response is going to be a resounding silence.
1. You try just sorta moving it off-map?
2. I've added historical figures after worldgen successfully, and full entities can be made by the player in adventure mode; I'm not sure all of what that entails, but it may be possible.
You know, instead of ignoring my posts, you guys (including the pros) could just say 'no idea' if you have no idea how to look into it.
I am really disliking the fact that it looks like you people are ignoring my posts. :<
So, can I get access to a socket from a lua script? I can tell that I can use clsocket from a native plugin, but I want to write an IRC chatbot and I'd rather not have to build/manage binaries every time I want to make a dumb change.Warmist's work in this branch (https://github.com/warmist/dfhack/tree/luasocket) may be helpful, although I'm not sure how usable it is in its current state.
Warmist's work in this branch (https://github.com/warmist/dfhack/tree/luasocket) may be helpful, although I'm not sure how usable it is in its current state.Alright, I'll ping him to see what he remembers about it. On the off chance that I hack it into something halfway usable, you think upstream would be interested in a PR for it? Giving arbitrary scripts socket access might be a bit dicey.
Looking at the source code in embark-tools.cpp, it doesn't look too hard to hack the sand indicator to check for a specific pattern of mineral names. Before I get started, I have a couple more generic questions about DFHack plugins.How would one go about expanding the embark tools plugin?I'm not sure if samanato ever got an answer, but I was hoping to make a variation of the sand indicator for my mod as well, to indicate the presence of "living stone" (a set of several minerals added by the mod). Ideally, I'd like the player to be able to filter locations by its presence, but that's probably beyond my limited coding capabilities.
In my major mod, smelter reactions are all custom reactions with additional reagents to the ore itself. For example, tetrahedrite smelting needs a flux in rough green glass which you can get in several ways, lead and tin ores need another coal bar to reduce the oxide, and ironworking is done entirely outside of the smelter. This means, metal ores are no longer considered as such by the vanilla game, so that they no longer appear on the embark screen as "Shallow Metal" and "Deep Metal".
I want to restore something like that to the embark screen, which I think would work in a similar way to the sand indicator. As groundwork I've prefixed all the ore names with METAL_ORE_ (so, METAL_ORE_HEMATITE and so on). How would such a script work, so that for example, the string to search would be "METAL_ORE_"? Ideally I would like for it to work like vanilla (with plurals and depth and all) though that is too much wizardry for me (I can't into DFHack programming :()
1. It was mentioned how to compile dfhack multiple times in the last 2 months a quick search will let you find that information.Thanks! Visual Studio Express would work fine for me because I don't know enough about the different compilers to have a strong preference, so I can use those instructions directly.
http://www.bay12forums.com/smf/index.php?topic=139553.msg5667803#msg5667803 May help you or do a search for compile dfhack.
you specifically need 2010 - I haven't dared to find out why yet but everyone who is "in the know" says that horrible things happen to your friends and loved ones if you use any other version.1. It was mentioned how to compile dfhack multiple times in the last 2 months a quick search will let you find that information.Thanks! Visual Studio Express would work fine for me because I don't know enough about the different compilers to have a strong preference, so I can use those instructions directly.
http://www.bay12forums.com/smf/index.php?topic=139553.msg5667803#msg5667803 May help you or do a search for compile dfhack.
The INVENTORY_CHANGE event currently crashes the game whenever it runs regardless of listeners.
1. It was mentioned how to compile dfhack multiple times in the last 2 months a quick search will let you find that information.Here (https://github.com/DFHack/dfhack/blob/master/Compile.rst#windows) is the documentation on Github.
http://www.bay12forums.com/smf/index.php?topic=139553.msg5667803#msg5667803 May help you or do a search for compile dfhack.
1. Replace "COMPILE.rst" with "Compile.rst"Looking at the source code in embark-tools.cpp, it doesn't look too hard to hack the sand indicator to check for a specific pattern of mineral names. Before I get started, I have a couple more generic questions about DFHack plugins.How would one go about expanding the embark tools plugin?I'm not sure if samanato ever got an answer, but I was hoping to make a variation of the sand indicator for my mod as well, to indicate the presence of "living stone" (a set of several minerals added by the mod). Ideally, I'd like the player to be able to filter locations by its presence, but that's probably beyond my limited coding capabilities.
In my major mod, smelter reactions are all custom reactions with additional reagents to the ore itself. For example, tetrahedrite smelting needs a flux in rough green glass which you can get in several ways, lead and tin ores need another coal bar to reduce the oxide, and ironworking is done entirely outside of the smelter. This means, metal ores are no longer considered as such by the vanilla game, so that they no longer appear on the embark screen as "Shallow Metal" and "Deep Metal".
I want to restore something like that to the embark screen, which I think would work in a similar way to the sand indicator. As groundwork I've prefixed all the ore names with METAL_ORE_ (so, METAL_ORE_HEMATITE and so on). How would such a script work, so that for example, the string to search would be "METAL_ORE_"? Ideally I would like for it to work like vanilla (with plurals and depth and all) though that is too much wizardry for me (I can't into DFHack programming :()
1. The "compile document" in this thread's OP is a broken link. A pointer to real compiling instructions would be invaluable. My limited experience with compilers was several years ago, and my experience with Git is non-existent.
2. Could embark-tools and a separate plug-in interposing at the same point coexist peacefully? Can I guarantee that embark-tools would run first?
3. Would the embedded space in Core::getInstance().runCommand(out, "prospect all"); cause any problems?
4. This thing is going to be a stripped-down version of embark-tools, and I would really like to give attribution to the original author(s).
5. Is there a way to read what DF wrote on the screen? That would let me put my indicator at the bottom of the site attributes. Otherwise I need to print on top, and commingle my tool with the sand indicator.
Screen::Pen pen = Screen::readTile(x,y);
if (pen.valid())
{
// pen.ch, pen.fg, pen.bg, pen.bold, etc.
}
I'm not sure if this is the best solution, though - with the smallest window size (80x25), there are only a few extra rows available. If you're interested in all metals available, I'd recommend a script which duplicates some of prospect's functionality instead.
I'll make sure I find a copy of VSE 2010. Somehow.You don't have to look very hard - it's right here (http://www.visualstudio.com/downloads/download-visual-studio-vs#DownloadFamilies_4).
Pleasantly surprised that prior versions are still available. Was not my experience with Microsoft the last time I was looking for old stuff (though that was years ago).I'll make sure I find a copy of VSE 2010. Somehow.You don't have to look very hard - it's right here (http://www.visualstudio.com/downloads/download-visual-studio-vs#DownloadFamilies_4).
The INVENTORY_CHANGE event currently crashes the game whenever it runs regardless of listeners.
just repeating this since it's a gigantic showstopper that prevents the release of numerous mods for the current version of DF
fix digType
fix interaction-trigger
do conversion script for old syndromeTrigger system
fix INVENTORY_CHANGE
merge stuff
do release
function getTargetInteractions(tar)
ints = {}
t_ints = {}
for i,x in pairs(df.global.world.raws.creatures.all[tonumber(tar.race)].caste[tonumber(tar.caste)].body_info.interactions) do
s = -1
check = false
name = false
for j,y in pairs(df.global.world.raws.creatures.all[tonumber(tar.race)].raws) do
if split(y.value,':')[1] == '[CAN_DO_INTERACTION' then
s = s + 1
if s == i then
check = true
elseif s > i then
break
end
end
if check then
if split(y.value,':')[2] == 'ADV_NAME' then
ints[i+1] = split(split(y.value,':')[3],']')[1]
name = true
end
end
end
if not name then
ints[i+1] = 'Unknown'
end
end
if #ints == 0 then
ints[1] = {'NONE'}
end
for i,x in pairs(tar.syndromes.active) do
for j,y in pairs(df.global.world.raws.syndromes.all[tonumber(x.type)].ce) do
if y._type == df['creature_interaction_effect_can_do_interactionst'] then
t_ints[i+1] == y.name
end
end
end
return ints, t_ints
end
Hi, I've got a question about DFhack v34.11 (I've still got a Fort left in 0.34)You can copy text from the DFHack console on Windows by accessing the window's menu (either by clicking in the upper left or upper right corner of the window).
I've tried activating the gui/assign-rack script but it told me to activate the weaponrack-UNassign binpatch first, when I did it gave me this error.
Now I have to admit that computers, programming etc. are by no means my domain so I wager I'm doing something wrong. However I was unable to find any kind of solution on the internet.
Thanks in advance and apologies if I'm posting this in the wrong place, if this post doesn't belong here then just tell me where to post and I'll delete it.
(http://i15.photobucket.com/albums/a361/project404/Whatdoesthismean_zps9e0b0b12.png)
I saw that DFHack generates a few files relating to ghosts:Certainly, although I don't know exactly how much you'd be able to accomplish. Take a look at the tweak plugin (the "clear-ghostly" tweak to be specific) for an example.Can these somehow be used to modify ghosts and their behavior? I was thinking of making a mod that added friendlier and productive ghosts, but I've read that ghosts are hard-coded and can't be found on the Raws. Is DFHack powerful enough for me to make a ghost mod?
- unit_ghost_info.h
- ghost_goal.h
- ghost_type.h
For those interested, I have written a little function to get the ADV_NAME of each interaction that a unit can do (both via creature/caste interactions, and those granted through syndromes). It will be going in my new unitViewer script, but I seem to remember someone asking for something like this in the past
-snip-
For those interested, I have written a little function to get the ADV_NAME of each interaction that a unit can do (both via creature/caste interactions, and those granted through syndromes). It will be going in my new unitViewer script, but I seem to remember someone asking for something like this in the past
-snip-
Wow that's cool!
...
You really need to work on variable names, though, heh. I can't read that at all.
There is a way to fix unclear variable names. CTRL-H.For those interested, I have written a little function to get the ADV_NAME of each interaction that a unit can do (both via creature/caste interactions, and those granted through syndromes). It will be going in my new unitViewer script, but I seem to remember someone asking for something like this in the past
-snip-
Wow that's cool!
...
You really need to work on variable names, though, heh. I can't read that at all.
NEVAR!
But yes, on a serious note, I really do. I get yelled at about it all the time for work, don't know what my problem with proper variable naming is... This code is actually pretty good compared to some of my others (like the one you saw with ddtot and such). ints = interactions, t_ints = temporary_interactions
This is a dumb question but what does ctrl-H do?
What does it do?It's the standard shortcut key for search-and-replace.
Is it an autocomplete hotkey or summat?
Custom scripts are treated as DFHack commands exactly like normal scripts, so do it the same way you see other keybindings done in the init.Thank you so much! :D
I ain't posting the whole documentation on the topic here, so search "simulateInput" here (https://github.com/DFHack/dfhack/blob/master/Lua%20API.rst)
So I'm trying to work with the gui and have some questions.
I can create screens and frames and all that, and I can put text in them, with columns and rows and overall it looks nice, but my issue is that some of the lists I want to put in are variable in length, and the only examples I have seen of organization is either all in a single list (e.g. room-list) or set columns and rows (e.g. autobutcher). I've been trying to look over the API documentation about the gui, but am still very much a novice when it comes to anything gui related (my only work with guis has been in python) and am having a hard time understanding everything.
So, long story short, my question is, does anyone have any knowledge they can impart about creating a gui that would, ideally, look something like thisWhere the VARIABLE LENGTH parts can be 0-whatever rows in length.Spoiler (click to show/hide)
classes = {
--code to obtain classes from unit
}
list:setChoices(classes)
So I'm trying to work with the gui and have some questions.I'm not sure exactly what you're asking. TheDorf addressed getting the data; this is about the formatting.
I can create screens and frames and all that, and I can put text in them, with columns and rows and overall it looks nice, but my issue is that some of the lists I want to put in are variable in length, and the only examples I have seen of organization is either all in a single list (e.g. room-list) or set columns and rows (e.g. autobutcher). I've been trying to look over the API documentation about the gui, but am still very much a novice when it comes to anything gui related (my only work with guis has been in python) and am having a hard time understanding everything.
So, long story short, my question is, does anyone have any knowledge they can impart about creating a gui that would, ideally, look something like thisWhere the VARIABLE LENGTH parts can be 0-whatever rows in length.Spoiler (click to show/hide)
It's the standard shortcut key for search-and-replace.
Seems like the easiest way to handle a variable number of rows is to start at the top and write one row at a time. When you run out of items, skip a line or three and start the next section.
Of course, then you need to figure out what to do if there isn't enough room on the screen. DF mostly uses paging, but there are interfaces that scroll instead, with up and down arrows at the side to indicate that there's more to see.
for i in ipairs(df.job_skill) do print(i, df.job_skill[i], df.job_skill.attrs[i].caption, df.job_skill.attrs[i].caption_noun) end
Sound devices available:
OpenAL Soft
Picking OpenAL Soft. If your desired device was missing, make sure you have the appropriate 32-bit libraries installed. If you wanted a different device, configure ~/.openalrc appropriately.
Perfect OpenAL context attributes GET
Loading bindings from data/init/interface.txt
Unknown binding: CIVZONE_GATHER
Unknown binding: CIVZONE_GATHER_OPTIONS
Unknown binding: CIVZONE_GATHER_OPTIONS_PICK_TREES
Unknown binding: CIVZONE_GATHER_OPTIONS_PICK_SHRUBS
Unknown binding: CIVZONE_GATHER_OPTIONS_GATHER_FALLEN
Ahhh, that explains the keybinds, good to know, I'll poke around with it in a bit, and try the mdf5 fix, thanks!It sounds like the problem is with the DFHack build you're using, not libgraphics. What GCC versions do you have available? If you don't have GCC 4.9, you should be using the GCC 4.5 build of DFHack (which uses the libraries that come with DF).
Hmmm, switching to the libgraphics.so that came with it breaks it, just spams me with the libstdc++.s0.6:version 'GLIBCXX_3.4.20' not found (required by ./hack/libdfhack.so) messages and then the canberra-gtk-module, but it did try to load the right bindings, though they weren't actually right in the save I loaded, but that's not unexpected given how sloppily I put everything together atm.
When I get back on I'll try it with a fresh df, fresh dfhack, and put the right md5 in there, and then update the keybinds by hand.
This too, which was new to me, looks like the fruit gathering stuff keybinds, but the openal thing I've never seen before.Code: [Select]Sound devices available:
OpenAL Soft
Picking OpenAL Soft. If your desired device was missing, make sure you have the appropriate 32-bit libraries installed. If you wanted a different device, configure ~/.openalrc appropriately.
Perfect OpenAL context attributes GET
Loading bindings from data/init/interface.txt
Unknown binding: CIVZONE_GATHER
Unknown binding: CIVZONE_GATHER_OPTIONS
Unknown binding: CIVZONE_GATHER_OPTIONS_PICK_TREES
Unknown binding: CIVZONE_GATHER_OPTIONS_PICK_SHRUBS
Unknown binding: CIVZONE_GATHER_OPTIONS_GATHER_FALLEN
Thanks. What would I have to do to make it go back to normal?"fastdwarf 0 0"
Perfect! Exactly what I was looking for. Just wasted 20 minutes trying to figure it out myself. Completely passed over the .attrs oh well, always good to learn :)
EDIT: Had a little more time to work on this today, here is what it's looking like nowSpoiler (click to show/hide)
Perfect! Exactly what I was looking for. Just wasted 20 minutes trying to figure it out myself. Completely passed over the .attrs oh well, always good to learn :)
EDIT: Had a little more time to work on this today, here is what it's looking like nowSpoiler (click to show/hide)
Looks great! It's up to you but I'd put the numerical skill level in addition to the word (master / dabbler / etc). Just in case people forget what the order is.
TWBT: version 5.27
TWBT: no display patch
ARGH, SO CLOSE....
I gave symbols.xml the right md5 in a new symbols table and it got that far, I've got gcc 4.9.1 already, but I haven't had more luck than getting twbt to start trying to load like that and segfaulting out.
Is there anything else people would like to see on there?
[thefunk@archenstein df_linux]$ ./dfhack
Gtk-Message: Failed to load module "canberra-gtk-module"
Loading bindings from data/init/interface.txt
Resetting textures
TWBT: version 5.27
TWBT: no display patch
./dfhack: line 43: 22368 Segmentation fault (core dumped) setarch i386 -R env LD_PRELOAD=$PRELOAD_LIB ./libs/Dwarf_Fortress "$@"
[thefunk@archenstein df_linux]$ ./dfhack
Gtk-Message: Failed to load module "canberra-gtk-module"
ARGH, SO CLOSE....
I gave symbols.xml the right md5 in a new symbols table and it got that far, I've got gcc 4.9.1 already, but I haven't had more luck than getting twbt to start trying to load like that and segfaulting out.
That's a pretty good suggestion, do we know the amount of rust_counter that describes each level of rustiness?Is there anything else people would like to see on there?
Skills that are rusty, or very rusty, in a different color?
Thanks for your help with the syndrome thing expwnent, got that working right, and got the class system working correctly as well (before it was just a place holder label, not it is a proper list). I also added a flag so if you aren't using my class system, you can just turn the display off and get that extra space back (instead it would just say 'None' and give you a lot of zeroes).
Here is the updated lookSpoiler (click to show/hide)
I may exchange the word Permanent for just a P or something since it is adding extra space that doesn't really need to be there. As always if anyone has any thoughts I am open to suggestions. I think I want to put some basic health information in the upper right corner (age, happiness level, health condition, maybe put up the sleepiness/hungry timers).That's a pretty good suggestion, do we know the amount of rust_counter that describes each level of rustiness?Is there anything else people would like to see on there?
Skills that are rusty, or very rusty, in a different color?
Other than that I am pretty content with where it is and where it is going, so I will probably release it to the public soon. Keep up the good suggestions!
Loving this so far. That's the kind of plug-in i would definitely use. A suggestion, is it possible to sort the skills, so the highest level skills are at the top. And maybe seperate them by 3 category, one for the work related skills, one for the combats skill and the other one for skills like negociator, comedian etc..
Is DFHack available for 40.14 yet?No.
Aren't they categorized already?Thanks for your help with the syndrome thing expwnent, got that working right, and got the class system working correctly as well (before it was just a place holder label, not it is a proper list). I also added a flag so if you aren't using my class system, you can just turn the display off and get that extra space back (instead it would just say 'None' and give you a lot of zeroes).
Here is the updated lookSpoiler (click to show/hide)
I may exchange the word Permanent for just a P or something since it is adding extra space that doesn't really need to be there. As always if anyone has any thoughts I am open to suggestions. I think I want to put some basic health information in the upper right corner (age, happiness level, health condition, maybe put up the sleepiness/hungry timers).That's a pretty good suggestion, do we know the amount of rust_counter that describes each level of rustiness?Is there anything else people would like to see on there?
Skills that are rusty, or very rusty, in a different color?
Other than that I am pretty content with where it is and where it is going, so I will probably release it to the public soon. Keep up the good suggestions!
Loving this so far. That's the kind of plug-in i would definitely use. A suggestion, is it possible to sort the skills, so the highest level skills are at the top. And maybe seperate them by 3 category, one for the work related skills, one for the combats skill and the other one for skills like negociator, comedian etc..
They aren't really categorized (as far as I know). There is a loose categorization on the wiki, but that's by no means rigid.
The question I have for categories is about the outiers, for example, where should Building Designer or Record Keeper go? Should there be a medical skills category? I was thinking the break down would be;
Labor (all the hard labor stuff)
Administrative (things like Record Keeper, Organizer, etc...)
Social (things like Negotiation)
Medical (all medical skills)
Military (all military skills)
But is that too many categories? And what about strange ones like Alchemy, Swimming, etc... Thoughts?
Another suggestion, well maybe a lillte bit weird but i thought for the health status adding a kind of stick figure representing the dwarf, maybe like that:That's a good idea except for two things: First, you can't guarantee that the screen font's punctuation isn't all screwy and Second, I'm not sure if DF is very helpful about telling you that a bruised pancreas is inside the lowerbody in order to color-code nicely.
O
_/|\_
|
/ \
- -
When all part is green it mean hes in good shape, and add color to body part when they are missing or bruised etc..
Edit2: If a skill is not activated on a dwarf and have experience on it, is it gonna be shown on the list?Currently it takes all of the skills of the Dwarf, active or not, as long as they have some experience in the skill.
I though about something like that at some point a few years back and made some mockups.
It would certainly make recognizing health issues at a quick glance easier, but at the very least you would have to separate mannequins for blood vessels, nervous tissue, skeletal structure, and organs plus skin to keep it reasonably clear.
Blinking could be used to denote injuries.Spoiler: old mockups (click to show/hide)
As it has been mentioned though, this would be quite the work to do. I'd reckon you'd need 4 (as per separation mentioned above) generic mannequins for vertebrates (skull, 4 extremities, tail), several for arthropods with various # of extremities and some more for mollusks and similarly diverse animals. That's 20-30 compound images that have to be created, every one with all possible wound "overlays".
...
Similarly, the reason DFHack doesn't use TrueType is because it doesn't support it, and the reason we don't support it is because it's too damn buggy.
yes TWBT help, but I need ttf outputWhy do you need ttf?
TTF is useful because we can intercept text passed to SDL_ttf.dll and change it as we need, in order to polish the translation.There's a separate thread (http://www.bay12forums.com/smf/index.php?topic=145179) going on in the General Discussion area about attaching a screen reader to Dwarf Fortress (or more likely, the DFHack console as an interface to Dwarf Fortress). It seems like any solution to "intercepting text sent to the screen" would be equally applicable to both situations.
You could certainly use DFHack for things like that if you manually keep track of what viewscreen is which and where they write things to the screen. It'd be a pain but you could do it. If you do it the naive way you'd end up with garbled text for elves and dogs and humans wandering around.The map is quite definitely the biggest issue, since "reading it aloud" it is not feasible.
Depending on how hard you want to work, it is technically possible to export the entire fortress once every few seconds without too much slowdown
So, after some effort, I managed to successfully follow instructions and compile DFHack 0.40.13-r1 from source for Windows.
Is there any way to compile an unofficial version that will work with Dwarf Fortress 0.40.14?
I would dearly love to be able to use autodump - I don't need anything else really.
git remote add quietust https://github.com/quietust/dfhack
git fetch quietust
git checkout quietust/develop
cd library/xml
git remote add quietust https://github.com/quietust/df-structures
git fetch quietust
git checkout quietust/master
cd ../..
git submodule update
Both of Quietust's forks (dfhack and df-structures) appear to be up-to-date for 0.40.14. This should work from the command line (in the dfhack folder):Brilliant. It's compiling now (fingers crossed).
Did you remember to update the library/xml submodule? What does "git status" display?
<symbol-table name='v0.40.14 linux' os-type='linux'>
<md5-hash value='8ab84807a405a7fa697847e6b3ecb00f'/>
</symbol-table>
Got my git discovery set wrong though, need to figure out what is going on there, I'm too used to relying on pacman I guess.
The symbols bit isn't too hard, as an example I added this to my symbols.xml a while back and it started to load up but crashed due to it still being too early:It crashed because, while you had a <symbol-table> entry in symbols.xml, every offset was missing. Like I said earlier, you'd need to check out a branch of dfhack and df-structures that are up-to-date for 0.40.14 (which both of Quietust's forks are) and compile DFHack from source for it to work with 0.40.14. There were significant structure changes between 0.40.13 and 0.40.14, so using an old build of DFHack will almost certainly crash when it tries to access changed structures (although the crash in your case was probably due to the missing addresses in symbols.xml).Code: [Select]<symbol-table name='v0.40.14 linux' os-type='linux'>
Got my git discovery set wrong though, need to figure out what is going on there, I'm too used to relying on pacman I guess.
<md5-hash value='8ab84807a405a7fa697847e6b3ecb00f'/>
</symbol-table>
Just the data. You would need to have a plugin that reads the map data and sends it over the network, and a client app that renders it.Depending on how hard you want to work, it is technically possible to export the entire fortress once every few seconds without too much slowdown
Do you mean data, or data and Fort images?
I'm willing to spend a few hours each day learning. Do you have a place you recommend I start?
createitem BAR COAL:COKEAhhhh, well, that's probably why I'm grateful for you all having the more arcane aspects handled, I suspected that nothing at all would happen, so the way it started to do the red and yellow twbt loading was a surprise. I'll have to check the git repo and see if I can smush something working together, though I'm not in a big rush due to the "oh god I miss my cousin, I'M GONNA GO PUNCH A BABY" state currently, as I'm anticipating a .15 update might not be too far away.
(INORGANIC is usually not necessary, and is incorrect in this case.)The symbols bit isn't too hard, as an example I added this to my symbols.xml a while back and it started to load up but crashed due to it still being too early:It crashed because, while you had a <symbol-table> entry in symbols.xml, every offset was missing. Like I said earlier, you'd need to check out a branch of dfhack and df-structures that are up-to-date for 0.40.14 (which both of Quietust's forks are) and compile DFHack from source for it to work with 0.40.14. There were significant structure changes between 0.40.13 and 0.40.14, so using an old build of DFHack will almost certainly crash when it tries to access changed structures (although the crash in your case was probably due to the missing addresses in symbols.xml).Code: [Select]<symbol-table name='v0.40.14 linux' os-type='linux'>
Got my git discovery set wrong though, need to figure out what is going on there, I'm too used to relying on pacman I guess.
<md5-hash value='8ab84807a405a7fa697847e6b3ecb00f'/>
</symbol-table>
dwarves.rb - type "dwarves #" at the embark selector/map before you embark. It will raise your starting dwarves to the number you entered.Code: [Select]# patch start dwarf count
nr = $script_args[0].to_i
raise 'too low' if nr < 7
addr = df.get_global_address('start_dwarf_count')
df.memory_patch(addr, [nr].pack('L'))
points.lua - type "points #" at the embark selector/map before you embark. It will raise your embark points to that number.Code: [Select]df.global.world.worldgen.worldgen_parms.embark_points=tonumber(...)
Add embark points in the advanced worldgen options of vanilla DF.I don't think that's what StagnantSoul is looking for:
How would I add embark points with dfhack? I need more than 10k
If you had to remove manipulator and strangemood, you're doing something wrong - those plugins should work if you use the develop branch of DFHack/dfhack (since all 0.40.14 development has now been merged into it). Quietust's develop branch appears to include the changes necessary for these plugins to compile as well (although DFHack:develop is more up-to-date).
I hope this is ok, I managed to get a .14 version compiled by removing the manipulator and strangemood plugins, and following Lethosor's instructions. I didnt even try to compile other stuff like stonesense or isoworld.
Its for windows, and I am running an i5 if that matters, I am so ignorant on the specifics of who this may work for, i figured i would better mention it.
If this upsets anyone, I will happily take down the link, just let me know!
But reveal (and cleanall) seems to work, and thats what i need to save my dying thirsty colony, so I thought i would share it. Thanks to the DFHack team and Quietust branch, they did the hard work, I just(barely) managed to compile something that is probably buggy and will wipe you fort, so test with a backup first people......
http://www.mediafire.com/download/nj5bd7l24efges5/dfhack-0.40.14-r0-Windows.zip
That "dwarves" script is exactly the same as the "startdwarf" script included with DFHack since at least 0.34.11-r3, which certainly works (assuming you have the start_dwarf_count offset in symbols.xml).dwarves.rb - type "dwarves #" at the embark selector/map before you embark. It will raise your starting dwarves to the number you entered.Code: [Select]# patch start dwarf count
nr = $script_args[0].to_i
raise 'too low' if nr < 7
addr = df.get_global_address('start_dwarf_count')
df.memory_patch(addr, [nr].pack('L'))
points.lua - type "points #" at the embark selector/map before you embark. It will raise your embark points to that number.Code: [Select]df.global.world.worldgen.worldgen_parms.embark_points=tonumber(...)
The dwarf count one is outdated though, but I do know of a working one. For 40.13 anyways. Or you can use cheat engine to modify any of the points in that menu.
If you had to remove manipulator and strangemood, you're doing something wrongIt was 'stress_level' errors. Yesterday I tried to compile and had these errors too:
Using 40.13 with the latest version of DFHack, I'm getting error messages with adventure mode commands. It won't let me bodyswap or use advtools. I get the message that it's not a recognized command. Are these commands broken? Is there anything I can do?Those commands were disabled in version 0.40 because they use variables whose locations are no longer known, and we didn't have time to fix them.
If you had to remove manipulator and strangemood, you're doing something wrongIt was 'stress_level' errors. Yesterday I tried to compile and had these errors too:
..\..\..\plugins\strangemood.cpp(637): error C2039: 'stress_level' : is not a member of 'df::unit_personality'
__
Today I compiled it without errors(stonesense disabled). And many tools seems to work fine.
It might be very buggy. Use at your own risk for testing and fooling around with a fortress you don't care about much:
http://www.mediafire.com/download/c1mntxtnq06vzk1/dfhack-0.40.14-r0-Windows-3.11.zip (http://www.mediafire.com/download/c1mntxtnq06vzk1/dfhack-0.40.14-r0-Windows-3.11.zip)
Oh, you need to update the library/xml submodule with "git submodule update". Git doesn't automatically check out new versions of submodules, even when the parent repo (dfhack) points to them (although it will often fetch new submodule commits to make it easier to check them out later). This is useful for developers, since it allows us to work on df-structures and dfhack separately (without the risk of losing submodule content when the dfhack repo is updated), but it can be confusing if you're only trying to compile a branch that requires different submodule commits. You should always run "git status" after changing branches, then "git submodule update" if any submodules are listed.If you had to remove manipulator and strangemood, you're doing something wrongIt was 'stress_level' errors. Yesterday I tried to compile and had these errors too:
..\..\..\plugins\strangemood.cpp(637): error C2039: 'stress_level' : is not a member of 'df::unit_personality'
__
Today I compiled it without errors(stonesense disabled). And many tools seems to work fine.
It might be very buggy. Use at your own risk for testing and fooling around with a fortress you don't care about much:
http://www.mediafire.com/download/c1mntxtnq06vzk1/dfhack-0.40.14-r0-Windows-3.11.zip (http://www.mediafire.com/download/c1mntxtnq06vzk1/dfhack-0.40.14-r0-Windows-3.11.zip)
There are some temperature update flags you could look at to avoid checking most map tile blocks. You could also keep track of dig job completions to find mined tiles.The temperature update might help, but since I don't want to run this every tick, maybe check the actual temperature instead? "Warm stone" is 10075, so if the temperature is >= 10075 then that's pretty good evidence of magma.
I have a DFHack API question: what's the difference between Maps::getBlock and Maps::getTileBlock? The only change I can see is that getTileBlock right-shifts its x and y indices by 4...Going by that information, getTileBlock takes the coordinates of an individual tile, while getBlock takes the position of a (16x16 tile) map block.
I would guess something like that, except they both return a df::map_block*, and index into the same array. And each map_block seems to have a 16x16 array of tiles in it?I have a DFHack API question: what's the difference between Maps::getBlock and Maps::getTileBlock? The only change I can see is that getTileBlock right-shifts its x and y indices by 4...Going by that information, getTileBlock takes the coordinates of an individual tile, while getBlock takes the position of a (16x16 tile) map block.
Quiver base value should be 20 instead of 10 in getItemBaseValue(), isn't it?No, because the base item value actually is 10...
A map block consists of a 16x16(x1) array of tiles. getTileBlock() returns the map block that contains a specific tile, while getBlock() returns a specific block.Ohhh, okay. Duh. Thank you!
Edit:getTileBlock(1,1) returns the block containing the red tile, while getBlock(1,1) returns the blue block.Spoiler: Example (click to show/hide)
Quiver base value should be 20 instead of 10 in getItemBaseValue(), isn't it?No, because the base item value actually is 10...
modtools/interaction-trigger -onAttackStr "casts burn" -command [ add-syndrome -unit \\DEFENDER_ID -syndrome BURN ]
modtools/interaction-trigger -onAttachStr "casts burn" -command [ add-syndrome -unit \\ATTACKER_ID -syndrome SPELL_CAST ]
in onLoad.init, and a unit uses an interaction with the "casts burn" CDI:VERB, will both effects be triggered?
That is the intended usage, yes. It may or may not be broken. I forget if that was one of the broken things or not.
Could not connect to localhost: 5000
#!/bin/bash
#workflow.sh
cd ~/PATH/TO/DF
#Reset stuff
./dfhack-run workflow enable
./dfhack-run workflow enable drybuckets
./dfhack-run workflow enable auto-melt
./dfhack-run workflow unlimit-all
./dfhack-run autobutcher stop
./dfhack-run autobutcher forget all
#Autobutcher 10 f kids, 10 m kids, 4 f adults, 2 m adults
./dfhack-run autobutcher target 6 3 3 1 all
./dfhack-run autobutcher autowatch
./dfhack-run autobutcher start
#OTHER COMMANDS
./dfhack-run autolabor 1
./dfhack-run seedwatch all 30
./dfhack-run getplants HEMP REED_ROPE
./dfhack-run getplants BERRY_SUN BERRIES_FISHER BERRIES_PRICKLE
./dfhack-run getplants BEET POTATO RADISH TURNIP KANIWA QUINOA FINGER_MILLET WILD_CARROT
#FOOD
./dfhack-run workflow amount DRINK 1000 500
./dfhack-run workflow amount FOOD 1000 500
############
## Farmer ##
############
./dfhack-run workflow amount THREAD 1000 500
./dfhack-run workflow amount LIQUID_MISC/MILK 1000 500
./dfhack-run workflow amount CHEESE 1000 500
###########
## Quern ##
###########
./dfhack-run workflow amount POWDER_MISC//MUSHROOM_CUP_DIMPLE:MILL 2 1
./dfhack-run workflow amount POWDER_MISC//GRASS_WHEAT_CAVE:MILL 2 1
./dfhack-run workflow amount GLOB 10 5
## Tools, Furniture, and Construction ##
./dfhack-run workflow amount BLOCKS/WOOD 2 1
./dfhack-run workflow amount BLOCKS/STONE,METAL 200 100
./dfhack-run workflow amount BOX/CLOTH,YARN,SILK,LEATHER 2 1
./dfhack-run workflow amount BOX/WOOD,STONE,METAL 2 1
./dfhack-run workflow amount ANIMALTRAP 2 1
./dfhack-run workflow amount BARREL 2 1
./dfhack-run workflow amount BIN 2 1
./dfhack-run workflow amount BUCKET 2 1
## Furniture and Construction ##
./dfhack-run workflow amount ANVIL 2 1
./dfhack-run workflow amount ARMORSTAND 2 1
./dfhack-run workflow amount BED 2 1
./dfhack-run workflow amount CABINET 2 1
./dfhack-run workflow amount CHAIN 2 1
./dfhack-run workflow amount CHAIR 2 1
./dfhack-run workflow amount COFFIN 2 1
./dfhack-run workflow amount DOOR 2 1
./dfhack-run workflow amount FLOODGATE 2 1
./dfhack-run workflow amount HATCH_COVER 2 1
./dfhack-run workflow amount GRATE 2 1
./dfhack-run workflow amount MILLSTONE 2 1
./dfhack-run workflow amount QUERN 2 1
./dfhack-run workflow amount SLAB 2 1
./dfhack-run workflow amount STATUE 2 1
./dfhack-run workflow amount TABLE 2 1
./dfhack-run workflow amount WEAPONRACK 2 1
./dfhack-run workflow amount TRAPPARTS 2 1
./dfhack-run workflow amount CAGE 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_ENORMOUSCORKSCREW 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_GIANTAXEBLADE 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_LARGESERRATEDDISC 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_MENACINGSPIKE 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_SPIKEDBALL 2 1
./dfhack-run workflow amount PIPE_SECTION 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_MINECART 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_WHEELBARROW 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_NEST_BOX 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_JUG 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_LARGE_POT 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_HIVE 2 1
./dfhack-run workflow amount CRUTCH 2 1
./dfhack-run workflow amount SPLINT 2 1
./dfhack-run workflow amount TRACTION_BENCH 2 1
## Trade Goods ##
./dfhack-run workflow amount COIN 1000 500
./dfhack-run workflow amount CRAFTS 1000 500
./dfhack-run workflow amount GOBLET 1000 500
./dfhack-run workflow amount INSTRUMENT 1000 500
./dfhack-run workflow amount TOTEM 1000 500
./dfhack-run workflow amount TOY 1000 500
./dfhack-run workflow amount THREAD 1000 500
#./dfhack-run workflow amount THREAD//INORGANIC:ADAMANTINE 2 1
./dfhack-run workflow amount CLOTH/PLANT 2 1
./dfhack-run workflow amount CLOTH/SILK 2 1
./dfhack-run workflow amount CLOTH/YARN 2 1
./dfhack-run workflow amount CLOTH//INORGANIC 2 1
## Armor ##
./dfhack-run workflow amount SHIELD:ITEM_SHIELD_SHIELD 2 1
./dfhack-run workflow amount SHIELD:ITEM_SHIELD_BUCKLER 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_DRESS 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_SHIRT 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_COAT 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_VEST 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_ROBE 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_CLOAK 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_LEATHER 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_MAIL_SHIRT 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_BREASTPLATE 2 1
./dfhack-run workflow amount PANTS:ITEM_PANTS_PANTS 2 1
./dfhack-run workflow amount PANTS:ITEM_PANTS_LEGGINGS 2 1
./dfhack-run workflow amount PANTS:ITEM_PANTS_GREAVES 2 1
./dfhack-run workflow amount SHOES:ITEM_SHOES_BOOTS 4 2
./dfhack-run workflow amount SHOES:ITEM_SHOES_BOOTS_LOW 4 2
./dfhack-run workflow amount SHOES:ITEM_SHOES_SOCKS 4 2
./dfhack-run workflow amount SHOES:ITEM_SHOES_SHOES 4 2
./dfhack-run workflow amount HELM:ITEM_HELM_CAP 2 1
./dfhack-run workflow amount HELM:ITEM_HELM_HELM 2 1
./dfhack-run workflow amount HELM:ITEM_HELM_HOOD 2 1
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_GLOVES 4 2
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_MITTENS 4 2
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_GAUNTLETS 4 2
## Weapons ##
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_PICK 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_SPEAR_TRAINING 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_SWORD_SHORT_TRAINING 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_AXE_TRAINING 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_SWORD_SHORT/STONE 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_MACE 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_SPEAR 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_SWORD_SHORT 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_HAMMER_WAR 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_AXE_BATTLE 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_CROSSBOW 2 1
./dfhack-run workflow amount AMMO:ITEM_AMMO_BOLTS/WOOD,BONE 200 100
./dfhack-run workflow amount AMMO:ITEM_AMMO_BOLTS/METAL 200 100
## Military Misc ##
./dfhack-run workflow amount FLASK 2 1
./dfhack-run workflow amount BACKPACK 2 1
./dfhack-run workflow amount QUIVER 2 1
## Other ##
./dfhack-run workflow amount SMALLGEM 2 1
./dfhack-run workflow amount BALLISTAARROWHEAD 2 1
###########
## GLASS ##
###########
./dfhack-run workflow amount POWDER_MISC/SAND 100 50
./dfhack-run workflow amount BLOCKS/GLASS 200 100
##################
## Wood Furnace ##
##################
./dfhack-run workflow amount BAR//ASH 4 2
./dfhack-run workflow amount BAR//COAL 8 4
#############
## Smelter ##
#############
./dfhack-run workflow amount BAR//INORGANIC:COPPER 4 2
./dfhack-run workflow amount BAR//INORGANIC:SILVER 4 2
./dfhack-run workflow amount BAR//INORGANIC:BRONZE 4 2
./dfhack-run workflow amount BAR//INORGANIC:BISMUTH 4 2
./dfhack-run workflow amount BAR//INORGANIC:BISMUTH_BRONZE 4 2
./dfhack-run workflow amount BAR//INORGANIC:IRON 4 2
./dfhack-run workflow amount BAR//INORGANIC:PIG_IRON 4 2
./dfhack-run workflow amount BAR//INORGANIC:STEEL 4 2
./dfhack-run workflow amount BAR//INORGANIC:PLATINUM 4 2
./dfhack-run workflow amount BAR//INORGANIC:GOLD 4 2
./dfhack-run workflow amount BAR//INORGANIC:NICKEL 4 2
./dfhack-run workflow amount BAR//INORGANIC:ZINC 4 2
./dfhack-run workflow amount BAR//INORGANIC:BRASS 4 2
./dfhack-run workflow amount BAR//INORGANIC:ELECTRUM 4 2
./dfhack-run workflow amount BAR//INORGANIC:TIN 4 2
./dfhack-run workflow amount BAR//INORGANIC:PEWTER_FINE 4 2
./dfhack-run workflow amount BAR//INORGANIC:PEWTER_TRIFLE 4 2
./dfhack-run workflow amount BAR//INORGANIC:PEWTER_LAY 4 2
./dfhack-run workflow amount BAR//INORGANIC:ALUMINUM 4 2
./dfhack-run workflow amount BAR//INORGANIC:LEAD 4 2
./dfhack-run workflow amount BAR//INORGANIC:NICKEL_SILVER 4 2
./dfhack-run workflow amount BAR//INORGANIC:BILLON 4 2
./dfhack-run workflow amount BAR//INORGANIC:STERLING_SILVER 4 2
./dfhack-run workflow amount BAR//INORGANIC:BLACK_BRONZE 4 2
./dfhack-run workflow amount BAR//INORGANIC:ROSE_GOLD 4 2
#Containers
./dfhack-run workflow amount BARREL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_LARGE_POT 2 1
./dfhack-run workflow amount BIN 2 1
./dfhack-run workflow amount BOX/CLOTH 20 10
./dfhack-run workflow amount TOOL:ITEM_TOOL_JUG 2 1
#Furniture
./dfhack-run workflow amount BED///LOCAL,EXCEPTIONAL 2 1
./dfhack-run workflow amount DOOR///LOCAL,EXCEPTIONAL 2 1
./dfhack-run workflow amount TABLE///LOCAL,EXCEPTIONAL 2 1
./dfhack-run workflow amount CHAIR///LOCAL,EXCEPTIONAL 2 1
./dfhack-run workflow amount ARMORSTAND///LOCAL,EXCEPTIONAL 2 1
./dfhack-run workflow amount WEAPONRACK///LOCAL,EXCEPTIONAL 2 1
./dfhack-run workflow amount CABINET///LOCAL,EXCEPTIONAL 2 1
./dfhack-run workflow amount BOX/STONE//LOCAL,EXCEPTIONAL 2 1
./dfhack-run workflow amount COFFIN 2 1
./dfhack-run workflow amount SLAB 2 1
./dfhack-run workflow amount STATUE 2 1
./dfhack-run workflow amount WINDOW 2 1
./dfhack-run workflow amount GRATE 2 1
./dfhack-run workflow amount HATCH_COVER 2 1
./dfhack-run workflow amount FLOODGATE 2 1
./dfhack-run workflow amount CHAIN 2 1
#Workshop Carpenter
./dfhack-run workflow amount BED/WOOD 2 1
./dfhack-run workflow amount DOOR/WOOD 2 1
./dfhack-run workflow amount TABLE/WOOD 2 1
./dfhack-run workflow amount CHAIR/WOOD 2 1
./dfhack-run workflow amount ARMORSTAND/WOOD 2 1
./dfhack-run workflow amount WEAPONRACK/WOOD 2 1
./dfhack-run workflow amount CABINET/WOOD 2 1
./dfhack-run workflow amount BOX/WOOD 2 1
./dfhack-run workflow amount COFFIN/WOOD 2 1
#Tools
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_PICK 2 1
./dfhack-run workflow amount BUCKET 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_MINECART 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_WHEELBARROW 2 1
#Traps
./dfhack-run workflow amount CAGE 10 5
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_ENORMOUSCORKSCREW 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_SPIKEDBALL 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_MENACINGSPIKE 2 1
#Consumables
./dfhack-run workflow amount THREAD 1000 500
./dfhack-run workflow amount CLOTH/PLANT 1000 500
./dfhack-run workflow amount CORPSEPIECE/YARN 1000 500
./dfhack-run workflow amount CLOTH/YARN 1000 500
#Construction
./dfhack-run workflow amount BLOCKS 1000 500
./dfhack-run workflow amount TRAPPARTS 20 10
./dfhack-run workflow amount PIPE_SECTION 2 1
./dfhack-run workflow amount QUERN 2 1
./dfhack-run workflow amount MILLSTONE 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_NEST_BOX 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_HIVE 2 1
#Construction Wood
./dfhack-run workflow amount BLOCKS/WOOD 2 1
#Gear
./dfhack-run workflow amount FLASK 10 5
./dfhack-run workflow amount BACKPACK 10 5
./dfhack-run workflow amount QUIVER 10 5
#Weapons Copper
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_AXE_BATTLE//INORGANIC:COPPER 2 1
#Weapons Ranged
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_CROSSBOW 10 5
./dfhack-run workflow amount AMMO:ITEM_AMMO_BOLTS/METAL 1000 500
./dfhack-run workflow amount AMMO:ITEM_AMMO_BOLTS/WOOD,BONE 200 100
#Trade Goods
./dfhack-run workflow amount TOTEM 1000 500
./dfhack-run workflow amount TOY 1000 500
./dfhack-run workflow amount CRAFTS 1000 500
./dfhack-run workflow amount GOBLET 1000 500
./dfhack-run workflow amount INSTRUMENT 1000 500
#Jewels
./dfhack-run workflow amount ROUGH 1000 500
#Hospital
./dfhack-run workflow amount CRUTCH 4 2
./dfhack-run workflow amount SPLINT 4 2
./dfhack-run workflow amount TRACTION_BENCH 2 1
#Soap
./dfhack-run workflow amount BAR//ASH 10 5
./dfhack-run workflow amount LIQUID_MISC//LYE 10 5
./dfhack-run workflow amount BAR/SOAP 4 2
#Farming
./dfhack-run workflow amount BAR//POTASH 20 10
#Glass
./dfhack-run workflow amount POWDER_MISC/SAND 100 50
./dfhack-run workflow amount SMALLGEM 1000 500
#Clay Pottery
./dfhack-run workflow amount BOULDER/CLAY 20 10
#Dye
./dfhack-run workflow amount POWDER_MISC//MUSHROOM_CUP_DIMPLE:MILL 1000 500
#Fuel
./dfhack-run workflow amount BAR//COAL 40 20
#Smithing
./dfhack-run workflow amount BAR//INORGANIC:COPPER 4 2
./dfhack-run workflow amount BAR//INORGANIC:SILVER 4 2
./dfhack-run workflow amount BAR//INORGANIC:IRON 4 2
./dfhack-run workflow amount BAR//INORGANIC:STEEL 4 2
./dfhack-run workflow amount BAR//INORGANIC:BRONZE 4 2
#Forge
#Weapons Bronze
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_AXE_BATTLE//INORGANIC:BRONZE/LOCAL,MASTERFUL 2 1
#Weapons Steel
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_AXE_BATTLE//INORGANIC:STEEL/LOCAL,MASTERFUL 2 1
#Trap Parts Steel
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_MENACINGSPIKE//INORGANIC:STEEL/LOCAL,MASTERFUL 2 1
## Furniture Iron ##
./dfhack-run workflow amount CAGE//INORGANIC:IRON 2 1
./dfhack-run workflow amount CHAIN//INORGANIC:IRON 2 1
./dfhack-run workflow amount ANIMALTRAP//INORGANIC:IRON 2 1
./dfhack-run workflow amount BUCKET//INORGANIC:IRON 2 1
./dfhack-run workflow amount BARREL//INORGANIC:IRON 2 1
./dfhack-run workflow amount ARMORSTAND//INORGANIC:IRON 2 1
./dfhack-run workflow amount BLOCKS//INORGANIC:IRON 16 8
./dfhack-run workflow amount DOOR//INORGANIC:IRON 2 1
./dfhack-run workflow amount FLOODGATE//INORGANIC:IRON 2 1
./dfhack-run workflow amount HATCH_COVER//INORGANIC:IRON 2 1
./dfhack-run workflow amount GRATE//INORGANIC:IRON 2 1
./dfhack-run workflow amount STATUE//INORGANIC:IRON 2 1
./dfhack-run workflow amount CABINET//INORGANIC:IRON 2 1
./dfhack-run workflow amount BOX//INORGANIC:IRON 2 1
./dfhack-run workflow amount CHAIR//INORGANIC:IRON 2 1
./dfhack-run workflow amount COFFIN//INORGANIC:IRON 2 1
./dfhack-run workflow amount TABLE//INORGANIC:IRON 2 1
./dfhack-run workflow amount WEAPONRACK//INORGANIC:IRON 2 1
./dfhack-run workflow amount BIN//INORGANIC:IRON 2 1
./dfhack-run workflow amount PIPE_SECTION//INORGANIC:IRON 2 1
./dfhack-run workflow amount SPLINT//INORGANIC:IRON 2 1
./dfhack-run workflow amount CRUTCH//INORGANIC:IRON 2 1
## Furniture GOLD ##
./dfhack-run workflow amount CAGE//INORGANIC:GOLD 2 1
./dfhack-run workflow amount CHAIN//INORGANIC:GOLD 2 1
./dfhack-run workflow amount ANIMALTRAP//INORGANIC:GOLD 2 1
./dfhack-run workflow amount BUCKET//INORGANIC:GOLD 2 1
./dfhack-run workflow amount BARREL//INORGANIC:GOLD 2 1
./dfhack-run workflow amount ARMORSTAND//INORGANIC:GOLD 2 1
./dfhack-run workflow amount BLOCKS//INORGANIC:GOLD 16 8
./dfhack-run workflow amount DOOR//INORGANIC:GOLD 2 1
./dfhack-run workflow amount FLOODGATE//INORGANIC:GOLD 2 1
./dfhack-run workflow amount HATCH_COVER//INORGANIC:GOLD 2 1
./dfhack-run workflow amount GRATE//INORGANIC:GOLD 2 1
./dfhack-run workflow amount STATUE//INORGANIC:GOLD 2 1
./dfhack-run workflow amount CABINET//INORGANIC:GOLD 2 1
./dfhack-run workflow amount BOX//INORGANIC:GOLD 2 1
./dfhack-run workflow amount CHAIR//INORGANIC:GOLD 2 1
./dfhack-run workflow amount COFFIN//INORGANIC:GOLD 2 1
./dfhack-run workflow amount TABLE//INORGANIC:GOLD 2 1
./dfhack-run workflow amount WEAPONRACK//INORGANIC:GOLD 2 1
./dfhack-run workflow amount BIN//INORGANIC:GOLD 2 1
./dfhack-run workflow amount PIPE_SECTION//INORGANIC:GOLD 2 1
./dfhack-run workflow amount SPLINT//INORGANIC:GOLD 2 1
./dfhack-run workflow amount CRUTCH//INORGANIC:GOLD 2 1
## Furniture SILVER ##
./dfhack-run workflow amount CAGE//INORGANIC:SILVER 2 1
./dfhack-run workflow amount CHAIN//INORGANIC:SILVER 2 1
./dfhack-run workflow amount ANIMALTRAP//INORGANIC:SILVER 2 1
./dfhack-run workflow amount BUCKET//INORGANIC:SILVER 2 1
./dfhack-run workflow amount BARREL//INORGANIC:SILVER 2 1
./dfhack-run workflow amount ARMORSTAND//INORGANIC:SILVER 2 1
./dfhack-run workflow amount BLOCKS//INORGANIC:SILVER 16 8
./dfhack-run workflow amount DOOR//INORGANIC:SILVER 2 1
./dfhack-run workflow amount FLOODGATE//INORGANIC:SILVER 2 1
./dfhack-run workflow amount HATCH_COVER//INORGANIC:SILVER 2 1
./dfhack-run workflow amount GRATE//INORGANIC:SILVER 2 1
./dfhack-run workflow amount STATUE//INORGANIC:SILVER 2 1
./dfhack-run workflow amount CABINET//INORGANIC:SILVER 2 1
./dfhack-run workflow amount BOX//INORGANIC:SILVER 2 1
./dfhack-run workflow amount CHAIR//INORGANIC:SILVER 2 1
./dfhack-run workflow amount COFFIN//INORGANIC:SILVER 2 1
./dfhack-run workflow amount TABLE//INORGANIC:SILVER 2 1
./dfhack-run workflow amount WEAPONRACK//INORGANIC:SILVER 2 1
./dfhack-run workflow amount BIN//INORGANIC:SILVER 2 1
./dfhack-run workflow amount PIPE_SECTION//INORGANIC:SILVER 2 1
./dfhack-run workflow amount SPLINT//INORGANIC:SILVER 2 1
./dfhack-run workflow amount CRUTCH//INORGANIC:SILVER 2 1
## Furniture COPPER ##
./dfhack-run workflow amount CAGE//INORGANIC:COPPER 2 1
./dfhack-run workflow amount CHAIN//INORGANIC:COPPER 2 1
./dfhack-run workflow amount ANIMALTRAP//INORGANIC:COPPER 2 1
./dfhack-run workflow amount BUCKET//INORGANIC:COPPER 2 1
./dfhack-run workflow amount BARREL//INORGANIC:COPPER 2 1
./dfhack-run workflow amount ARMORSTAND//INORGANIC:COPPER 2 1
./dfhack-run workflow amount BLOCKS//INORGANIC:COPPER 16 8
./dfhack-run workflow amount DOOR//INORGANIC:COPPER 2 1
./dfhack-run workflow amount FLOODGATE//INORGANIC:COPPER 2 1
./dfhack-run workflow amount HATCH_COVER//INORGANIC:COPPER 2 1
./dfhack-run workflow amount GRATE//INORGANIC:COPPER 2 1
./dfhack-run workflow amount STATUE//INORGANIC:COPPER 2 1
./dfhack-run workflow amount CABINET//INORGANIC:COPPER 2 1
./dfhack-run workflow amount BOX//INORGANIC:COPPER 2 1
./dfhack-run workflow amount CHAIR//INORGANIC:COPPER 2 1
./dfhack-run workflow amount COFFIN//INORGANIC:COPPER 2 1
./dfhack-run workflow amount TABLE//INORGANIC:COPPER 2 1
./dfhack-run workflow amount WEAPONRACK//INORGANIC:COPPER 2 1
./dfhack-run workflow amount BIN//INORGANIC:COPPER 2 1
./dfhack-run workflow amount PIPE_SECTION//INORGANIC:COPPER 2 1
./dfhack-run workflow amount SPLINT//INORGANIC:COPPER 2 1
./dfhack-run workflow amount CRUTCH//INORGANIC:COPPER 2 1
## Furniture STEEL ##
./dfhack-run workflow amount CAGE//INORGANIC:STEEL 2 1
./dfhack-run workflow amount CHAIN//INORGANIC:STEEL 2 1
./dfhack-run workflow amount ANIMALTRAP//INORGANIC:STEEL 2 1
./dfhack-run workflow amount BUCKET//INORGANIC:STEEL 2 1
./dfhack-run workflow amount BARREL//INORGANIC:STEEL 2 1
./dfhack-run workflow amount ARMORSTAND//INORGANIC:STEEL 2 1
./dfhack-run workflow amount BLOCKS//INORGANIC:STEEL 16 8
./dfhack-run workflow amount DOOR//INORGANIC:STEEL 2 1
./dfhack-run workflow amount FLOODGATE//INORGANIC:STEEL 2 1
./dfhack-run workflow amount HATCH_COVER//INORGANIC:STEEL 2 1
./dfhack-run workflow amount GRATE//INORGANIC:STEEL 2 1
./dfhack-run workflow amount STATUE//INORGANIC:STEEL 2 1
./dfhack-run workflow amount CABINET//INORGANIC:STEEL 2 1
./dfhack-run workflow amount BOX//INORGANIC:STEEL 2 1
./dfhack-run workflow amount CHAIR//INORGANIC:STEEL 2 1
./dfhack-run workflow amount COFFIN//INORGANIC:STEEL 2 1
./dfhack-run workflow amount TABLE//INORGANIC:STEEL 2 1
./dfhack-run workflow amount WEAPONRACK//INORGANIC:STEEL 2 1
./dfhack-run workflow amount BIN//INORGANIC:STEEL 2 1
./dfhack-run workflow amount PIPE_SECTION//INORGANIC:STEEL 2 1
./dfhack-run workflow amount SPLINT//INORGANIC:STEEL 2 1
./dfhack-run workflow amount CRUTCH//INORGANIC:STEEL 2 1
#ETC
#Gold
#Silver
#Copper
#Nickel
#Zinc
#Bronze
#Brass
#Steel
#Platinum
#Electrum
#Tin
#Fine_Pewter
#Trifle_Pewter
#Lay_Pewter
#ALUMINUM
#Nickel SIlver
#Billon
#Sterling Silver
#Black Bronze
#Rose Gold
#Bismuth Bronze
#Adamantine
## Siege Equipment Metal ##
./dfhack-run workflow amount BALLISTAARROWHEAD/METAL 10 5
#IRON
#SILVER
#COPPER
#BRONZE
#STEEL
#BISMUTH BRONZE
#ADAMANTINE
## Trap Components Metal ##
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_GIANTAXEBLADE//METAL 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_ENORMOUSCORKSCREW//METAL 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_SPIKEDBALL//METAL 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_LARGESERRATEDDISC//METAL 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_MENACINGSPIKE//METAL 2 1
./dfhack-run workflow amount TRAPPARTS//METAL 2 1
#IRON
#SILVER
#COPPER
#BRONZE
#STEEL
#BISMUTH BRONZE
#ADAMANTINE
## Other Objects Metal ##
./dfhack-run workflow amount ANVIL/METAL 2 1
./dfhack-run workflow amount CRAFTS/METAL 2 1
./dfhack-run workflow amount GOBLET/METAL 2 1
./dfhack-run workflow amount TOY/METAL 2 1
./dfhack-run workflow amount INSTRUMENT/METAL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_NEST_BOX/METAL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_JUG/METAL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_LARGE_POT/METAL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_HIVE/METAL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_MINECART/METAL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_WHEELBARROW/METAL 2 1
./dfhack-run workflow amount FLASK/METAL 2 1
./dfhack-run workflow amount COIN/METAL 2 1
## Other Objects STEEL ##
./dfhack-run workflow amount ANVIL//INORGANIC:STEEL 2 1
./dfhack-run workflow amount CRAFTS//INORGANIC:STEEL 2 1
./dfhack-run workflow amount GOBLET//INORGANIC:STEEL 2 1
./dfhack-run workflow amount TOY//INORGANIC:STEEL 2 1
./dfhack-run workflow amount INSTRUMENT//INORGANIC:STEEL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_NEST_BOX//INORGANIC:STEEL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_JUG//INORGANIC:STEEL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_LARGE_POT//INORGANIC:STEEL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_HIVE//INORGANIC:STEEL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_MINECART//INORGANIC:STEEL 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_WHEELBARROW//INORGANIC:STEEL 2 1
./dfhack-run workflow amount FLASK//INORGANIC:STEEL 2 1
./dfhack-run workflow amount COIN//INORGANIC:STEEL 2 1
#Reset stuff
./dfhack-run workflow enable
./dfhack-run workflow enable drybuckets
./dfhack-run workflow enable auto-melt
./dfhack-run workflow unlimit-all
./dfhack-run autobutcher stop
./dfhack-run autobutcher forget all
#Autobutcher 10 f kids, 10 m kids, 4 f adults, 2 m adults
./dfhack-run autobutcher target 4 4 2 1 all
./dfhack-run autobutcher autowatch
./dfhack-run autobutcher start
#OTHER COMMANDS
./dfhack-run autolabor 1
./dfhack-run seedwatch all 30
./dfhack-run getplants REED_ROPE BERRY_SUN BERRIES_FISHER BERRIES_PRICKLE HEMP
# Beet, Wild Carrot, Potato, Radish, Turnip, Kaniwa, Quinoa, Finger Millet, Hemp
#FOOD
./dfhack-run workflow amount DRINK 3000 1500
./dfhack-run workflow amount FOOD:ITEM_FOOD_ROAST 3000 1500
############
## Farmer ##
############
./dfhack-run workflow amount THREAD 1000 500
./dfhack-run workflow amount LIQUID_MISC/MILK 100 50
./dfhack-run workflow amount CHEESE 3000 1500
###########
## Quern ##
###########
./dfhack-run workflow amount POWDER_MISC//MUSHROOM_CUP_DIMPLE:MILL 2 1
./dfhack-run workflow amount POWDER_MISC//GRASS_WHEAT_CAVE:MILL 2 1
./dfhack-run workflow amount GLOB 10 5
###############
## Carpenter ##
###############
#Tasks=31
#Workshops=4
./dfhack-run workflow amount SHIELD:ITEM_SHIELD_SHIELD/WOOD 2 1
./dfhack-run workflow amount SHIELD:ITEM_SHIELD_BUCKLER/WOOD 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_SPEAR_TRAINING/WOOD 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_SWORD_SHORT_TRAINING/WOOD 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_AXE_TRAINING/WOOD 2 1
./dfhack-run workflow amount BARREL/WOOD 2 1
./dfhack-run workflow amount BLOCKS/WOOD 2 1
./dfhack-run workflow amount BUCKET/WOOD 2 1
./dfhack-run workflow amount ANIMALTRAP/WOOD 2 1
./dfhack-run workflow amount CAGE/WOOD 2 1
./dfhack-run workflow amount ARMORSTAND/WOOD 2 1
./dfhack-run workflow amount BED/WOOD 2 1
./dfhack-run workflow amount CHAIR/WOOD 2 1
./dfhack-run workflow amount COFFIN/WOOD 2 1
./dfhack-run workflow amount DOOR/WOOD 2 1
./dfhack-run workflow amount FLOODGATE/WOOD 2 1
./dfhack-run workflow amount HATCH_COVER/WOOD 2 1
./dfhack-run workflow amount GRATE/WOOD 2 1
./dfhack-run workflow amount CABINET/WOOD 2 1
./dfhack-run workflow amount BIN/WOOD 2 1
./dfhack-run workflow amount BOX/WOOD 2 1
./dfhack-run workflow amount WEAPONRACK/WOOD 2 1
./dfhack-run workflow amount TABLE/WOOD 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_ENORMOUSCORKSCREW/WOOD 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_SPIKEDBALL/WOOD 2 1
./dfhack-run workflow amount TRAPCOMP:ITEM_TRAPCOMP_MENACINGSPIKE/WOOD 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_MINECART/WOOD 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_WHEELBARROW/WOOD 2 1
./dfhack-run workflow amount PIPE_SECTION/WOOD 2 1
./dfhack-run workflow amount SPLINT/WOOD 2 1
./dfhack-run workflow amount CRUTCH/WOOD 2 1
###########
## Mason ##
###########
./dfhack-run workflow amount ARMORSTAND//INORGANIC 2 1
./dfhack-run workflow amount BLOCKS//INORGANIC 16 8
./dfhack-run workflow amount CHAIR//INORGANIC 2 1
./dfhack-run workflow amount COFFIN//INORGANIC 2 1
./dfhack-run workflow amount DOOR//INORGANIC 2 1
./dfhack-run workflow amount FLOODGATE//INORGANIC 2 1
./dfhack-run workflow amount HATCH_COVER//INORGANIC 2 1
./dfhack-run workflow amount GRATE//INORGANIC 2 1
./dfhack-run workflow amount CABINET//INORGANIC 2 1
./dfhack-run workflow amount BOX//INORGANIC 2 1
./dfhack-run workflow amount STATUE//INORGANIC 2 1
./dfhack-run workflow amount SLAB//INORGANIC 2 1
./dfhack-run workflow amount TABLE//INORGANIC 2 1
./dfhack-run workflow amount WEAPONRACK//INORGANIC 2 1
./dfhack-run workflow amount QUERN//INORGANIC 2 1
./dfhack-run workflow amount MILLSTONE//INORGANIC 2 1
#################
## Craftsdwarf ##
#################
## Rock ##
./dfhack-run workflow amount CRAFTS//INORGANIC 2 1
./dfhack-run workflow amount GOBLET//INORGANIC 2 1
./dfhack-run workflow amount INSTRUMENT//INORGANIC 2 1
./dfhack-run workflow amount WEAPON:ITEM_WEAPON_SWORD_SHORT//INORGANIC 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_NEST_BOX//INORGANIC 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_JUG//INORGANIC 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_LARGE_POT//INORGANIC 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_HIVE//INORGANIC 2 1
./dfhack-run workflow amount TOY//INORGANIC 2 1
## Wood ##
./dfhack-run workflow amount CRAFTS/WOOD 2 1
./dfhack-run workflow amount AMMO:ITEM_AMMO_BOLTS/WOOD 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_NEST_BOX/WOOD 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_JUG/WOOD 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_LARGE_POT/WOOD 2 1
./dfhack-run workflow amount TOOL:ITEM_TOOL_HIVE/WOOD 2 1
## Bone ##
./dfhack-run workflow amount AMMO:ITEM_AMMO_BOLTS/BONE 2 1
./dfhack-run workflow amount CRAFTS/BONE 2 1
./dfhack-run workflow amount PANTS:ITEM_PANTS_LEGGINGS/BONE 2 1
./dfhack-run workflow amount PANTS:ITEM_PANTS_GREAVES/BONE 2 1
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_GAUNTLETS/BONE 4 2
./dfhack-run workflow amount HELM:ITEM_HELM_HELM/BONE 2 1
## Shell ##
./dfhack-run workflow amount CRAFTS/SHELL 2 1
./dfhack-run workflow amount PANTS:ITEM_PANTS_LEGGINGS/SHELL 2 1
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_GAUNTLETS/SHELL 4 2
./dfhack-run workflow amount HELM:ITEM_HELM_HELM/SHELL 2 1
## Misc ##
./dfhack-run workflow amount TOTEM 2 1
./dfhack-run workflow amount CRAFTS/CLOTH 2 1
./dfhack-run workflow amount CRAFTS/SILK 2 1
./dfhack-run workflow amount CRAFTS/YARN 2 1
./dfhack-run workflow amount CRAFTS/TOOTH 2 1
./dfhack-run workflow amount CRAFTS/HORN 2 1
./dfhack-run workflow amount CRAFTS/PEARL 2 1
./dfhack-run workflow amount CRAFTS/LEATHER 2 1
./dfhack-run workflow amount THREAD//INORGANIC:ADAMANTINE 2 1
##############
## Mechanic ##
##############
./dfhack-run workflow amount TRAPPARTS//INORGANIC 2 1
./dfhack-run workflow amount TRACTION_BENCH 2 1
##########
## Loom ##
##########
#Tasks=5
#Workshops=1
./dfhack-run workflow amount THREAD/SILK 1000 500
./dfhack-run workflow amount CLOTH/PLANT 2 1
./dfhack-run workflow amount CLOTH/SILK 2 1
./dfhack-run workflow amount CLOTH/YARN 2 1
./dfhack-run workflow amount CLOTH//INORGANIC 2 1
##############
## Clothier ##
##############
#Tasks=39
#Workshops=4
##CLOTH##
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_DRESS/CLOTH 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_SHIRT/CLOTH 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_COAT/CLOTH 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_VEST/CLOTH 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_ROBE/CLOTH 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_CLOAK/CLOTH 2 1
./dfhack-run workflow amount PANTS:ITEM_PANTS_PANTS/CLOTH 2 1
./dfhack-run workflow amount HELM:ITEM_HELM_CAP/CLOTH 2 1
./dfhack-run workflow amount HELM:ITEM_HELM_HOOD/CLOTH 2 1
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_GLOVES/CLOTH 4 2
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_MITTENS/CLOTH 4 2
./dfhack-run workflow amount SHOES:ITEM_SHOES_SOCKS/CLOTH 4 2
./dfhack-run workflow amount SHOES:ITEM_SHOES_SHOES/CLOTH 4 2
./dfhack-run workflow amount BOX/CLOTH 2 1
./dfhack-run workflow amount CHAIN/CLOTH 2 1
##SILK##
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_DRESS/SILK 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_SHIRT/SILK 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_ROBE/SILK 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_CLOAK/SILK 2 1
./dfhack-run workflow amount PANTS:ITEM_PANTS_PANTS/SILK 2 1
./dfhack-run workflow amount HELM:ITEM_HELM_CAP/SILK 2 1
./dfhack-run workflow amount HELM:ITEM_HELM_HOOD/SILK 2 1
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_GLOVES/SILK 4 2
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_MITTENS/SILK 4 2
./dfhack-run workflow amount SHOES:ITEM_SHOES_SOCKS/SILK 4 2
./dfhack-run workflow amount SHOES:ITEM_SHOES_SHOES/SILK 4 2
./dfhack-run workflow amount BOX/SILK 2 1
./dfhack-run workflow amount CHAIN/SILK 2 1
##YARN##
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_DRESS/YARN 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_SHIRT/YARN 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_ROBE/YARN 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_CLOAK/YARN 2 1
./dfhack-run workflow amount PANTS:ITEM_PANTS_PANTS/YARN 2 1
./dfhack-run workflow amount HELM:ITEM_HELM_CAP/YARN 2 1
./dfhack-run workflow amount HELM:ITEM_HELM_HOOD/YARN 2 1
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_GLOVES/YARN 4 2
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_MITTENS/YARN 4 2
./dfhack-run workflow amount SHOES:ITEM_SHOES_SOCKS/YARN 4 2
./dfhack-run workflow amount SHOES:ITEM_SHOES_SHOES/YARN 4 2
./dfhack-run workflow amount BOX/YARN 2 1
./dfhack-run workflow amount CHAIN/YARN 2 1
#############
## Leather ##
#############
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_LEATHER/LEATHER 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_DRESS/LEATHER 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_SHIRT/LEATHER 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_COAT/LEATHER 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_VEST/LEATHER 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_ROBE/LEATHER 2 1
./dfhack-run workflow amount ARMOR:ITEM_ARMOR_CLOAK/LEATHER 2 1
./dfhack-run workflow amount PANTS:ITEM_PANTS_LEGGINGS/LEATHER 2 1
./dfhack-run workflow amount PANTS:ITEM_PANTS_PANTS/LEATHER 2 1
./dfhack-run workflow amount HELM:ITEM_HELM_CAP/LEATHER 2 1
./dfhack-run workflow amount HELM:ITEM_HELM_HELM/LEATHER 2 1
./dfhack-run workflow amount HELM:ITEM_HELM_HOOD/LEATHER 2 1
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_GLOVES/LEATHER 4 2
./dfhack-run workflow amount GLOVES:ITEM_GLOVES_MITTENS/LEATHER 4 2
./dfhack-run workflow amount SHOES:ITEM_SHOES_BOOTS_LOW/LEATHER 4 2
./dfhack-run workflow amount SHOES:ITEM_SHOES_BOOTS/LEATHER 4 2
./dfhack-run workflow amount SHOES:ITEM_SHOES_SHOES/LEATHER 4 2
./dfhack-run workflow amount SHIELD:ITEM_SHIELD_SHIELD/LEATHER 2 1
./dfhack-run workflow amount SHIELD:ITEM_SHIELD_BUCKLER/LEATHER 2 1
./dfhack-run workflow amount BOX/LEATHER 2 1
./dfhack-run workflow amount FLASK/LEATHER 2 1
./dfhack-run workflow amount BACKPACK/LEATHER 2 1
./dfhack-run workflow amount QUIVER/LEATHER 2 1
cd ~/bin
That is the intended usage, yes. It may or may not be broken. I forget if that was one of the broken things or not.
Second Bug: I also notice in the autolabor plugin that woodcutting is snubbed completely if dwarves have any experience in mining. If you embark with seven picks and assign all your dwarves the "Mining" labor having all your dwarves dig and become dabblers, if you then enable the autolabor plugin and then assign some trees to be cut down your dwarves will refuse. Forcing one to disable autolabor and assign the woodcutting profession manually.Just a quick thought, both the miner and the woodcutter have an invisible "uniform" that goes along with their labors (edit: Hunting does too). Turning on both in Dwarf Therapist or the vanilla interface would also lead to problems. These invisible "uniforms" also conflict with real military uniforms.
I run dwarf fortress and dfhack on a min install of debian linux jessie. If you need any other information just ask and I'll try to get the information to you as clearly as possible.
First off, I love dfhack and I don't know what I would do without it. It is a powerful and awesome tool. Thank you so much!It's possible that that's a problem with dfhack-run, not workflow. Does the problem still occur if you place the commands in a file (without "./dfhack-run") and run "script (filename)" in the DFHack console?
Second off, I have run into some bugs and I am hoping this is the right place to report them. If not, kindly point me in the right direction.
First Bug: I've noticed that the workflow plugin seems to have a limited number of entries that it can take before hanging? You can duplicate this error by running a bash script with multiple (~320) entries of "./dfhack-run workflow amount X 2 1" Where X # # is a new and different item to be produced. Exiting the game with the "die" command or the conventional way results with repetitions of the following error for each workflow command that didn't execute:Code: [Select]Could not connect to localhost: 5000
Second off, I have run into some bugs and I am hoping this is the right place to report them. If not, kindly point me in the right direction.
Second Bug: I also notice in the autolabor plugin that woodcutting is snubbed completely if dwarves have any experience in mining.
autolabor MINE 2 6
autolabor CUTWOOD 1 2
autolabor HUNT 0 1
First off, I love dfhack and I don't know what I would do without it. It is a powerful and awesome tool. Thank you so much!It's possible that that's a problem with dfhack-run, not workflow. Does the problem still occur if you place the commands in a file (without "./dfhack-run") and run "script (filename)" in the DFHack console?
Second off, I have run into some bugs and I am hoping this is the right place to report them. If not, kindly point me in the right direction.
First Bug: I've noticed that the workflow plugin seems to have a limited number of entries that it can take before hanging? You can duplicate this error by running a bash script with multiple (~320) entries of "./dfhack-run workflow amount X 2 1" Where X # # is a new and different item to be produced. Exiting the game with the "die" command or the conventional way results with repetitions of the following error for each workflow command that didn't execute:Code: [Select]Could not connect to localhost: 5000
That is the intended usage, yes. It may or may not be broken. I forget if that was one of the broken things or not.
It's not.
modtools/interaction-trigger -onAttackStr "casts burn" -command [ wrapper -unitSource \\ATTACKER_ID -unitTarget \\DEFENDER_ID -script [ modtools/add-syndrome -unit !TARGET -syndrome BURN ] -reflect [ REFELECT_ALL REFLECT_ELEMENTAL REFLECT_FIRE ] -silence [ SILENCE_ALL SILENCE_ELEMENTAL SILENCE_FIRE ] -iclass [ FIRE_1 FIRE_2 FIRE_3 FIRE_4 MAGIC_IMMUNE MAGIC_RESIST ] -isyndrome [ FIRE_WARD RESIST_MAGIC IMMUNE_MAGIC ] ]
modtools/interaction-trigger -onAttackStr "casts burn" -command [ wrapper -unitSource \\ATTACKER_ID -unitTarget \\DEFENDER_ID -script [ unit/attribute-change -unit !TARGET -physical [ ENDURANCE TOUGHNESS ] -fixed [ !VALUE !VALUE ] -dur 1000 ] -value self:willpower:-10:100 -reflect [ REFELECT_ALL REFLECT_ELEMENTAL REFLECT_FIRE ] -silence [ SILENCE_ALL SILENCE_ELEMENTAL SILENCE_FIRE ] -iclass [ FIRE_1 FIRE_2 FIRE_3 FIRE_4 MAGIC_IMMUNE MAGIC_RESIST ] -isyndrome [ FIRE_WARD RESIST_MAGIC IMMUNE_MAGIC ] -aclass [ ICE_1 ICE_2 ICE_3 ICE_4 ] ]
modtools/interaction-trigger -onAttackStr "casts burn" -command [ wrapper -unitSource \\ATTACKER_ID -unitTarget \\DEFENDER_ID -script [ modtools/add-syndrome -unit !TARGET -syndrome ICE_WARD -eraseAll ] -reflect [ REFELECT_ALL REFLECT_ELEMENTAL REFLECT_FIRE ] -silence [ SILENCE_ALL SILENCE_ELEMENTAL SILENCE_FIRE ] -iclass [ FIRE_1 FIRE_2 FIRE_3 FIRE_4 MAGIC_IMMUNE MAGIC_RESIST ] -isyndrome [ FIRE_WARD RESIST_MAGIC IMMUNE_MAGIC ] -asyndrome [ ICE_WARD ] ]
modtools/interaction-trigger -onAttackStr "casts burn" -command [ wrapper -unitSource \\ATTACKER_ID -unitTarget \\DEFENDER_ID -script [ modtools/add-syndrome -unit !TARGET -syndrome SOAKED -eraseAll ] -reflect [ REFELECT_ALL REFLECT_ELEMENTAL REFLECT_FIRE ] -silence [ SILENCE_ALL SILENCE_ELEMENTAL SILENCE_FIRE ] -iclass [ FIRE_1 FIRE_2 FIRE_3 FIRE_4 MAGIC_IMMUNE MAGIC_RESIST ] -isyndrome [ FIRE_WARD RESIST_MAGIC IMMUNE_MAGIC ] -asyndrome [ SOAKED ] ]
That's only useful if you want the commands to be run when a specific world loads (or any world, in the case of onLoadWorld.init). Some plugins save their state, so commands involving them only need to be run once per world.First off, I love dfhack and I don't know what I would do without it. It is a powerful and awesome tool. Thank you so much!It's possible that that's a problem with dfhack-run, not workflow. Does the problem still occur if you place the commands in a file (without "./dfhack-run") and run "script (filename)" in the DFHack console?
Second off, I have run into some bugs and I am hoping this is the right place to report them. If not, kindly point me in the right direction.
First Bug: I've noticed that the workflow plugin seems to have a limited number of entries that it can take before hanging? You can duplicate this error by running a bash script with multiple (~320) entries of "./dfhack-run workflow amount X 2 1" Where X # # is a new and different item to be produced. Exiting the game with the "die" command or the conventional way results with repetitions of the following error for each workflow command that didn't execute:Code: [Select]Could not connect to localhost: 5000
Or better yet, put them in an appropriately placed onLoad.init file...
I'm planning on a release very soon. It will be missing most of the things on my todo list. I'll do an r2 later for those.
I'm planning on a release very soon. It will be missing most of the things on my todo list. I'll do an r2 later for those.
Aaand.. 0.40.15 is here:)
I hate to complain, but I just downloaded the new version and I found several issues. First off, it says that 'plugin dwarfmoniter not built for this version of DF hack', as well as the dfhack.int config file is missing. Care to fix/Find out what is with that, please?Dwarf monitor has not yet been updated to the new thought system in 40.14. Rename the dfhack.init-example config, this how dfhack is always built. Dfhack.init is configured by the pack authors/users.
It's possible that that's a problem with dfhack-run, not workflow. Does the problem still occur if you place the commands in a file (without "./dfhack-run") and run "script (filename)" in the DFHack console?
Quote from: Rogue YunSecond Bug: I also notice in the autolabor plugin that woodcutting is snubbed completely if dwarves have any experience in mining.
Yeah, autolabor tries to deal with the three uniformed professions (mining, woodcutting, and hunting), but isn't exactly optimal for them. It helps to reduce their maximum numbers to less than the number of civilians in your fort. For this case:Code: [Select]autolabor MINE 2 6
autolabor CUTWOOD 1 2
autolabor HUNT 0 1
That will probably give you six miners and one woodcutter, but might switch them to five and two.
Dragonfire can hurt things normally immune to fire, I believe. In fact it used to be true (and might still be) that it's possible to be immune to dragonfire and not regular fire. I don't know whether that's the only difference or not.
#Kill dfhack
keybinding add Ctrl-Z die
autolabor HERBALIST 1 2
Pretty serious bug report: mousequery is broken. Clicking anywhere brings up stockpile or military menus, depending (I think) on whether you click on a unit. Edge scrolling doesn't work. Box select mode in the designations menu does work, luckily. This is particularly bad for new players with my pack :(Does this occur with the default mousequery plugin or only with the one that comes with TwbT? Mousequery appears to be working for me.
You can assign min and max to specific labors? That is AWESOME! Is there a more detailed documentation for this somewhere? I always hated it when my whole fort started engraving or felt they had the right to use wood to make cruddy beds because they were a skilled cheesemaker.
Also it seems the following command still allows all the dwarves to go plant gathering merrily without restraint.Code: [Select]autolabor HERBALIST 1 2
Mousequery seems to work for me on Windows. Edge scrolling works if you click. Hovering and clicking on dwarves seems to work. Clicking on dwarves in the military screen seems to work. I don't use it myself regularly so I'm not sure what all of the features are but I found it intuitive and functional.
edit ... and I can't replicate this in a fresh install of DF+DFHack. NVM.
New release!Github oddities aside, we plebeians who don't know our ass from a compiler thank you and the entire DFHack team.
we plebeians who don't know our ass from a compiler thank you and the entire DFHack team.As do we lazy bastards who've never bothered to set up a proper development environment since last installing Windows. :D
<global-address name='keydisplay' value='0x181C170'/>
It's a known bug in the Windows version (and it's not just manipulator). Find the "<symbol-table name='v0.40.15 SDL' os-type='windows'>" line in <DF>/hack/symbols.xml and add this line under it:Code: [Select]<global-address name='keydisplay' value='0x181C170'/>
Can somebody hook me up with a link to the 40.14 OSX release? I can't seem to find it anymore, and DT hasn't caught up with 40.15 yethttps://github.com/splintermind/Dwarf-Therapist/blob/DF2014/share/memory_layouts/osx/v0.40.15_osx.ini
Can somebody hook me up with a link to the 40.14 OSX release? I can't seem to find it anymore, and DT hasn't caught up with 40.15 yethttp://dffd.wimbli.com/file.php?id=10033
one last thing, I don't see .34.11-r5 in the dfhack archive either, which I need for webfortress
Happiness.enable/disable dwarfmonitor, actually. ("enable" and "disable" are built-in commands that control most UI plugins, except for tweak and a couple others.)
I think it's dwarfmonitor enable/disable to toggle it, might be dwarf-monitor enable/disable, I don't use it myself so I'm not sure off the top of my head.
It's a known bug in the Windows version (and it's not just manipulator). Find the "<symbol-table name='v0.40.15 SDL' os-type='windows'>" line in <DF>/hack/symbols.xml and add this line under it:Code: [Select]<global-address name='keydisplay' value='0x181C170'/>
When I use tiletypes to paint out some floor onto previously solid stone, the surrounding tiles aren't revealed like they would be if a dwarf dug them out.There is a better way than revflood.
(https://i.imgur.com/85zNkSX.png)
- How can I reveal those areas?
- Is there a better way to dig out sections (without using dwarves)?
Did the workflow problems occur before you added the line to symbols.xml? I don't think a symbols change would cause those types of errors.It's a known bug in the Windows version (and it's not just manipulator). Find the "<symbol-table name='v0.40.15 SDL' os-type='windows'>" line in <DF>/hack/symbols.xml and add this line under it:Code: [Select]<global-address name='keydisplay' value='0x181C170'/>
So, I had this problem and tried this and it worked for the most part, except now I can't see the values in ranges in workflow's GUI, (go to a workshop, open the workflow gui, add a constraint, try to edit the range)
Additionally I'm getting this error spammed into stderr.log:Spoiler (click to show/hide)
Lastly I'm getting crashes frequently, I'm using the starter pack and the version of DFHack packed with it, I can play at most for half an hour before something crashes, each time the action I last took before the crash was different, last time opening the building menu and trying to select building a carpenters workshop crashed the game, is there some way I can figure out what is causing the crashes? Are there any options I should avoid because they could be causing them? I'm not using any utilities but I have Workflow, Autolabor, and Mouse tweaks enabled as well as the bugfixes and performance tweaks options enabled. Graphics are all default options on pure install of the starter pack except I changed the pallet and installed spacefox, so I am using TwbT. The world and map were all generated in this version of DF and I imported no settings. The map is 4x4 and I have the calculation FPS cap at 300, I'm noticing no lag. Let me know if I should provide any other details.
A small suggestion (or two):This is intentional - in fact, DF used to disable access to unavailable labors in 40d (bug report (http://www.bay12games.com/dwarves/mantisbt/view.php?id=6511)).
The manipulator plugin only allows you to toggle labors that are enabled in the entity, can this be changed? (I would like to use the alchemy labor without needing to mod the entity)
The manipulator plugin needs a "clear all labors, this dwarf" key. This would allow making custom professions via a macro (just like Therapist's custom professions).What key would you suggest? (Custom professions should be possible as well, although coming up with a working configuration format could take some work.)
Did the workflow problems occur before you added the line to symbols.xml? I don't think a symbols change would cause those types of errors.
Regarding the random crashes, I'd try disabling TwbT first.
Is there a script or plugin for exporting and importing stockpile settings?There are a Falconne plugin that enables you to copy the settings of a stockpile, no import/export however, and I am not sure if it has been migrated to 40.xx.
##################################
# food stockpile adjustments
##################################
seeds: s{Down}deb{Right}{Down 9}p^
noseeds: s{Down}dea{Right}{Down 9}f^
booze: s{Down}deb{Right}{Down 5}p{Down}p^
food: s{Down}dea{Right}{Down 5}f{Down}f{Down 3}f^
plants: s{Down}deb{Right}{Down 4}p^
PreparedFoods: s{down}debu^
plantsandseeds: s{Down}deb{Right}{Down 4}p{Down 5}p^
cookableSolids: s{Down}debu{Right}p{Down}p{Down 2}p{Down 5}p{Down}p{Down}p{Down}f{Right}&{Down}&{Down 2}&{Down 5}&{left}{Down 4}p{Right}{up}&{left}{Down 2}{Right}sroy&&{Down}&^
#place Place a food stockpile
` ` ` ` #
` ` ` ` #
` f(2x1)#
` ` ` ` #
# # # # #
This illustration may be a little hard to understand. The f(2x1) is in column 2, row 3. All the other cells are empty. QF considers both ` and ~ characters within cells to be empty cells; this can help with multilayer or fortresswide blueprint layouts as 'chalk lines'.#place Place a food stockpile
` ` ` ` #
` ` ` ` #
` f f ` #
` ` ` ` #
# # # # #
#query
` ` ` ` #
` r+` ` #
` booze #
` ` ` ` #
# # # # #
I've never used the workflow plugin, so maybe I'm looking in wrong place, but I can edit ranges without problems:
(http://i.imgur.com/4AGDVFil.png) (http://imgur.com/4AGDVFi)
However your main issue is crashes, right? Here are the instructions how to enable crash dumps that would help me to fix it.
http://www.bay12forums.com/smf/index.php?topic=138754.msg5624349#msg5624349
Not too sure if this is the correct place to mention this, but when I use item-trigger in DFHack 0.40.13-r1 like this:
modtools/item-trigger -itemType ITEM_SHOES_PIPBUCK -onEquip -command [ modtools/add-syndrome -syndrome "PipBuck" -target \\UNIT_ID ]
DFHack will crash upon unpausing in Fortress Mode. Is this is a known thing? If you want, here is the crash dump (http://dffd.wimbli.com/file.php?id=10063)
Does DFHack work with the newest version of DF or what?
Does DFHack work with the newest version of DF or what?I was going to ask that a few minutes after the update posted, just because I like the sound of Quietust saying "No."
Does DFHack work with the newest version of DF or what?I was going to ask that a few minutes after the update posted, just because I like the sound of Quietust saying "No."
But I don't want to distract the memory mapping guys.
It sounds like there were few if any changes to data structures, so I'd imaging this round of mapping would be relatively quick. The automated detection might already be done with a bunch of testing now to make sure that DFHack 0.40.16-r1 doesn't set your computer on fire.
Well I don't know WHAT the hell most of that means but I'll just wait a while.DFHack is a hack: it inserts itself into the DF game by replacing one of the DLL files. If this DLL was compiled by Toady alongside the rest of DF, it would Just Work. The reality is that the DFHack team has to poke around inside each new version of DF and find out where everything is stored, a task made a bit more difficult by the security features of Windows, OSX and Linux. When you hear references to the SYMBOLS table, that is the list of memory locations for game data (the in-game date, the raws, the name of a creature, etc., etc., etc.).
This is only true on Windows, where DFHack is implemented by replacing SDL.dll. Toady doesn't compile this, but it can safely be replaced (assuming the replacement is built correctly), since it's linked to DF dynamically (i.e. DF doesn't rely on a specific copy of SDL.dll).Well I don't know WHAT the hell most of that means but I'll just wait a while.DFHack is a hack: it inserts itself into the DF game by replacing one of the DLL files. If this DLL was compiled by Toady alongside the rest of DF, it would Just Work.
The reality is that the DFHack team has to poke around inside each new version of DF and find out where everything is stored, a task made a bit more difficult by the security features of Windows, OSX and Linux. When you hear references to the SYMBOLS table, that is the list of memory locations for game data (the in-game date, the raws, the name of a creature, etc., etc., etc.).There aren't really security problems, since DFHack and DF run in the same address space (and can access the same memory).
I know that Dwarf Therapist also uses the SYMBOLS table, and a lot of 3rd-party tools (TWBT, Stonesense, Embark Tools, etc.) are DFHack plugins that can't operate without DFHack.Dwarf Therapist actually uses a separate configuration format (not symbols.xml) which contains some different data, so there isn't really a single "symbols table". However, a lot of this data comes from the df-structures (https://github.com/DFHack/df-structures) repo, which is what DFHack uses as well. (It's also possible to generate a DT ini file using DFHack, which I did for 0.40.15.)
Thanks for the clarification. The security feature I meant was the address space randomization, which affects how the memory mapping needs to be set up initially but probably doesn't affect version-to-version updates. And sorry about the brain-fart conflating df-structures, symbols.xml, and Dwarf Therapist's .ini files.Spoiler: Detailed explanation (click to show/hide)
local utils = require 'utils'
validArgs = validArgs or utils.invert({
'unit',
'amount',
'adjust'
})
local args = utils.processArgs({...}, validArgs)
local unit = args.unit and df.unit.find(args.unit) or dfhack.gui.getSelectedUnit(true)
if not unit then qerror('No unit was selected or specified.') end
if args.amount then
if args.adjust then
unit.status.current_soul.personality.stress_level=unit.status.current_soul.personality.stress_level+args.amount
else
unit.status.current_soul.personality.stress_level=args.amount
end
else
print(unit.status.current_soul.personality.stress_level)
end
Is there some reason dfhack gui plugins and keybindings wouldn't play well with vanilla macros?Just curious, but is this in response to something you've experienced?
Is there some reason dfhack gui plugins and keybindings wouldn't play well with vanilla macros?Just curious, but is this in response to something you've experienced?
Is there some reason dfhack gui plugins and keybindings wouldn't play well with vanilla macros?Just curious, but is this in response to something you've experienced?
Yea, whenever I record a basic macro (digging designations, placing furniture, hauling route assignment) then play it, crazy things happen. In particular I noticed a small dfhack prompt appearing in the upper left (where the FPS counter goes) and keys being entered there which is quite strange.
Can you verify that you're using Ctrl-P and not Ctrl-Shift-P?Is there some reason dfhack gui plugins and keybindings wouldn't play well with vanilla macros?Just curious, but is this in response to something you've experienced?
Yea, whenever I record a basic macro (digging designations, placing furniture, hauling route assignment) then play it, crazy things happen. In particular I noticed a small dfhack prompt appearing in the upper left (where the FPS counter goes) and keys being entered there which is quite strange.
Huh, you can edit stress directly and it'll stick now.
When can we expect DFHack for 40.16? The dwarf pus is gone, but somehow I got my aquifer full of otter blood! Yuck.
When can we expect DFHack for 40.16? The dwarf pus is gone, but somehow I got my aquifer full of otter blood! Yuck.
I believe that if the layer+biome is sandy, m SOIL will result in a sand tile
I believe that if the layer+biome is sandy, m SOIL will result in a sand tile
Hmm. I may be doing something wrong, or my biome isn't sandy. (Incidentally, if it isn't, is there any way to force a sandy tile? As you all know, I only need one. :P )
(http://i.gyazo.com/4ba7a80b7c101e7bc54820186a4f6991.png)
Here's what I'm trying. Activating it outside and inside my fortress didn't change anything.
Not wanting to sound impatient, but is there any progress on the crash related to item-trigger I posted previously?
Am I the only one having issues with siren? It apparently can't read field unit.T_status.recent_events.Might be something to do with the emotion/thought rewrite, it seems df.unit_thought_type.Tired doesn't exist any more. No idea about recent_events, possibly that changed too.
Not wanting to sound impatient, but is there any progress on the crash related to item-trigger I posted previously?
I fixed a lot of related things lately. What specifically was the problem?
Not too sure if this is the correct place to mention this, but when I use item-trigger in DFHack 0.40.13-r1 like this:
modtools/item-trigger -itemType ITEM_SHOES_PIPBUCK -onEquip -command [ modtools/add-syndrome -syndrome "PipBuck" -target \\UNIT_ID ]
DFHack will crash upon unpausing in Fortress Mode. Is this is a known thing? If you want, here is the crash dump (http://dffd.wimbli.com/file.php?id=10063)
Is there any way to get dwarves to like certain things? I want to get a dwarf to like cloaks, and another to like morningstars.Only way I know of for sure is kinda fiddly, but you can go into gm-editor > status > current soul > preferences, usually the fourth or fifth entry will be a pre-existing likes item preference, which I've found are a bit safer to edit than trying to manually add one or edit a totally different preference.
Roses: All I know is that I tried very hard to figure that out and I failed. I believe there is a type that hasn't yet been mapped out for innate interactions a caste can do.
Just because it compiles doesn't mean it works yet.I didn't explicitly say it in the previous post but I obviously ran it, otherwise I wouldn't have posted at all. Even rendermax works.
Roses: All I know is that I tried very hard to figure that out and I failed. I believe there is a type that hasn't yet been mapped out for innate interactions a caste can do.
Alright, that's pretty much what I thought.
Roses: All I know is that I tried very hard to figure that out and I failed. I believe there is a type that hasn't yet been mapped out for innate interactions a caste can do.
Alright, that's pretty much what I thought.
Actually Quietust just found that struct yesterday so it might be doable soon.
Will the current version more-or-less work with 40.16?To clarify, the current version (0.40.15-r1) will only work with 0.40.15 (possibly 0.40.14 as well), but it's fairly easy to compile from source for 0.40.16.
Will the current version more-or-less work with 40.16?To clarify, the current version (0.40.15-r1) will only work with 0.40.15 (possibly 0.40.14 as well), but it's fairly easy to compile from source for 0.40.16.
We should be able to have an actual release up soon.
git clone -b develop git://github.com/DFHack/dfhack.git
Keep in mind that this will create a fresh clone of the repo - it's faster to simply use "git checkout develop" if you've already cloned DFHack.git clone -b develop git://github.com/DFHack/dfhack.git
Git veteran here, I never knew about the -b switch to clone. You never go to bed without having learned at least one new thing, eh?
Since 40.16 isn't here yet, is there a way to use 40.15 df hack with 40.16?No. It won't recognize DF versions other than 0.40.14 or 0.40.15, and it could crash if you try to update symbols.xml with 0.40.16 symbols. (It's unlikely in this case, since the only changes I can see are naming changes, but it's generally not safe to use DFHack with an unsupported DF version.)
There are a few remaining globals left to be found. Give it a day or two.
Oh good I didn't update twbt for 40.16 :) Or will you still release it for some reason?
It sounded like .16 was just about finished, so I hope all that work doesn't go to waste.Oh good I didn't update twbt for 40.16 :) Or will you still release it for some reason?
I don't really care whether it's 40.16 or 40.17 at this point, I just hope it's soon :D
if ... then
for k,v in ipairs(df.global.world.units.active) do
v.status.current_soul.personality.stress_level=-1000000
end
else
dfhack.gui.getSelectedUnit().status.current_soul.personality.stress_level=-1000000
end
-- remove stress from a unit
-- With unit selected, affects that unit. Use "remove-stress all" to affect all units.
--By Putnam; http://www.bay12forums.com/smf/index.php?topic=139553.msg5820486#msg5820486
if ... then
for k,v in ipairs(df.global.world.units.active) do
v.status.current_soul.personality.stress_level=-1000000
end
else
dfhack.gui.getSelectedUnit().status.current_soul.personality.stress_level=-1000000
end
I'm sorry, but DFHack still seems to crash when item-trigger is used like this: modtools/item-trigger -itemType ITEM_SHOES_PIPBUCK -onEquip -command [ modtools/add-syndrome -syndrome "PipBuck" -target \\UNIT_ID ]what if you use one slash instead of two
If you wish, here (http://dffd.wimbli.com/file.php?id=10063) is a crash dump.
OSX | DFHack 0.40.16-r1 (https://www.dropbox.com/s/1ynh6y2nw0dryce/dfhack_osx_0.40.16-r1.bz2?dl=0) with StonesenseHow did you compile Stonesense? I haven't been able to compile it on any platform since the emotion changes in 0.40.14.
Naive happiness patch. (https://github.com/DFHack/stonesense/pull/25) It runs, and feels as stable as usual on osx, but that's not too much. :)OSX | DFHack 0.40.16-r1 (https://www.dropbox.com/s/1ynh6y2nw0dryce/dfhack_osx_0.40.16-r1.bz2?dl=0) with StonesenseHow did you compile Stonesense? I haven't been able to compile it on any platform since the emotion changes in 0.40.14.
I'm sorry, but DFHack still seems to crash when item-trigger is used like this: modtools/item-trigger -itemType ITEM_SHOES_PIPBUCK -onEquip -command [ modtools/add-syndrome -syndrome "PipBuck" -target \\UNIT_ID ]
If you wish, here (http://dffd.wimbli.com/file.php?id=10063) is a crash dump.
When does it crash? Immediately after calling it or when they equip it or unequip it? Arena or fort mode?Immediately after unpausing in Fortress Mode.
Apparently I wasn't watching that repo, so I never noticed that PR. Thanks!Naive happiness patch. (https://github.com/DFHack/stonesense/pull/25) It runs, and feels as stable as usual on osx, but that's not too much. :)OSX | DFHack 0.40.16-r1 (https://www.dropbox.com/s/1ynh6y2nw0dryce/dfhack_osx_0.40.16-r1.bz2?dl=0) with StonesenseHow did you compile Stonesense? I haven't been able to compile it on any platform since the emotion changes in 0.40.14.
I put up a build of 0.40.16-r1 at https://github.com/lethosor/dfhack/releases, which uses GCC 4.5. GCC 4.9 builds don't work on systems that don't have GCC 4.9 available (which includes a number of Ubuntu distros).
I made it "by hand", (tar -jcvf), didn't know there's a make command for that. live and learn.Apparently I wasn't watching that repo, so I never noticed that PR. Thanks!Naive happiness patch. (https://github.com/DFHack/stonesense/pull/25) It runs, and feels as stable as usual on osx, but that's not too much. :)OSX | DFHack 0.40.16-r1 (https://www.dropbox.com/s/1ynh6y2nw0dryce/dfhack_osx_0.40.16-r1.bz2?dl=0) with StonesenseHow did you compile Stonesense? I haven't been able to compile it on any platform since the emotion changes in 0.40.14.
Edit: Also, how did you create that package? It appears from the filename that you used something other than "make package".
https://github.com/DFHack/dfhack/blob/master/Lua%20API.rst#eventfulThanks! This will take a bit of research, but it sounds like exactly what I needed. Hopefully I can figure out how to make an inorganic "rotten" or "disturbed" without breaking the in-game text too much.
item chosen by K and placing cursor over it (a log lying on a stockpile) or T over a building results in "No item selected in the UI" "No Item selected"Could this be the cause? (https://github.com/quietust/df-structures/commit/74e9d4ca5f327ba6b58dff80b22ebdd1fd4a992e)
Are you using the DFHack console or the command-prompt plugin (Ctrl-Shift-P)?not the promt in Df, the console. (its the window that looks like good old MS-Dos..
It seems to be that for the changeitem, I on a gamble, replaced my symbols.xml whit that one (after spending 10 min to figure out where it was).. and now changeitem info worked.. (not tried rest yet).item chosen by K and placing cursor over it (a log lying on a stockpile) or T over a building results in "No item selected in the UI" "No Item selected"Could this be the cause? (https://github.com/quietust/df-structures/commit/74e9d4ca5f327ba6b58dff80b22ebdd1fd4a992e)
I'm sorry, but DFHack still seems to crash when item-trigger is used like this: modtools/item-trigger -itemType ITEM_SHOES_PIPBUCK -onEquip -command [ modtools/add-syndrome -syndrome "PipBuck" -target \\UNIT_ID ]
If you wish, here (http://dffd.wimbli.com/file.php?id=10063) is a crash dump.
Not wanting to sound impatient, but is there any progress on this bug?When does it crash? Immediately after calling it or when they equip it or unequip it? Arena or fort mode?Immediately after unpausing in Fortress Mode.
First thanks for all the good work.
Second, I have probably scewed something up, so ill ask here for help.
changeitem no mather what command and whit a item chosen by K and placing cursor over it (a log lying on a stockpile) or T over a building results in "No item selected in the UI" "No Item selected"
Running Dwarf fortress 0.40.16 whit DF-Hack 0.40.16-r1 and Phobeus graphics, OS Win7 Pro (Norwegian). Fort is from the release whit stepladders.
Second, is there a way in df-hack to make a dwarf no longer like harps, or change its like of harps to robes? that royal is getting rather pissed and I rather get mandates for usefull stuff.. ;) (heard of something called gui\gm-editor but it just gives a errormessage about no valid target when using K button over dwarf.
Any info i can give that can help whit for the changeitem problem?
The problem mentioned is that changeitem can't locate items, not that it can't modify them.The root of the problem is that you can't specify what craft / instrument / toy to create. A hack should not be needed to do so.
The problem mentioned is that changeitem can't locate items, not that it can't modify them.The root of the problem is that you can't specify what craft / instrument / toy to create. A hack should not be needed to do so.
May I suggest some sort of escape key from the enhanced view of the stocks screen, or a way to keep it from automatically putting input into the search space? It, by default, locks key commands into the search bar, ignoring shift/ctrl keystrokes, etc. I'm assuming you escape the menu by pushing the leavescreen button, but since I've bound mine to space instead of esc (a habit formed of 40d), I was unable to leave the page and lost a season's worth of game progress, being forced to kill DF with no way to save.being the same type to do that, I just bound both Space and Esc to the same leave screen/leave all screens function, wonder if quicksave still functions in different screens and save you a season worth of game progress?
I know it's an improbable way to run into problems with DFhack, but I might not be the only person to have re-bound the leavescreen key.
// Original code will check screentexpos et al. for changes but we don't want that
// because map is not rendered this way now. But we can't completely disable graphics
// because it's used on status screen to show professions at least.
// To find this address, look for a function with two SDL_GetTicks calls inside,
// there will be two calls with the same argument right before an increment between
I'm sorry, but DFHack still seems to crash when item-trigger is used like this: modtools/item-trigger -itemType ITEM_SHOES_PIPBUCK -onEquip -command [ modtools/add-syndrome -syndrome "PipBuck" -target \\UNIT_ID ]
If you wish, here (http://dffd.wimbli.com/file.php?id=10063) is a crash dump.Not wanting to sound impatient, but is there any progress on this bug?When does it crash? Immediately after calling it or when they equip it or unequip it? Arena or fort mode?Immediately after unpausing in Fortress Mode.
Are you using TwbT? If so, try disabling it.Indeed! Thank you. I didn't knew the plugin allowed for "mortar" like shots with the catapults, nice. Edit: no, it doesn't, lol.
hey, is spawn-unit up to date?spawn.lua works though... (https://gist.github.com/Rumrusher/f4d0ba18ba6868d38221) so that could be used as a substitute until spawn-unit gets patch up correctly.
You want modtools/reaction-trigger for that.
I'm sorry, but DFHack still seems to crash when item-trigger is used like this: modtools/item-trigger -itemType ITEM_SHOES_PIPBUCK -onEquip -command [ modtools/add-syndrome -syndrome "PipBuck" -target \\UNIT_ID ]
If you wish, here (http://dffd.wimbli.com/file.php?id=10063) is a crash dump.
When does it crash? Immediately after calling it or when they equip it or unequip it? Arena or fort mode?Immediately after unpausing in Fortress Mode.
Parameters?
a) 100% bruised/burned/frostbite/melt/necrosis/blister/boil/freeze/condense (i.e. 10000+ in layer_effect_fraction)The bolded ones, specifically.
b) 250% dented (i.e. 25000+ in layer_dent_fraction)
c) 100% cut (i.e. 10000+ in layer_cut_fraction) (cut in this case is synonymous with fracture)
That's only true on Windows (which I think Mister Always is using, but I don't believe DFHack is distributed as a .rar on any platforms).
If you're downloading it from here (https://github.com/DFHack/dfhack/releases/tag/0.40.16-r1), it's a .7z file.That's only true on Windows (which I think Mister Always is using, but I don't believe DFHack is distributed as a .rar on any platforms).
Nope, I've most certainly got a WinRar archive of DFhack downloaded from the front page.
Okay, so only copy the folder's contents, not the whole thing... Got ya. But before I do that, what's this thing I need to overwrite and how do I do that?If you copy everything from the DFHack archive folder to the DF folder, you should receive some sort of prompt asking you if you want to overwrite "SDL.dll", which you should confirm. (If you don't overwrite SDL.dll, DFHack won't load at all.)
Roses: All I know is that I tried very hard to figure that out and I failed. I believe there is a type that hasn't yet been mapped out for innate interactions a caste can do.
Alright, that's pretty much what I thought.
Actually Quietust just found that struct yesterday so it might be doable soon.
Is there a version for 0.40.18?
Is there a version for 0.40.18?Just so you know, you can compile DFHack for .40.19. If you're using Linux I can upload a build if you like.
OSX is missing a few globals. Soon.Yaaay!
Actually, it was only start_dwarf_count that needed to be found (on all three platforms), and it's been located now. Most of the remaining work is merging the 10-something open pull requests.
In other news, Danaris's Stonesense changes have been merged, so Stonesense should work again on OS X (although it's still buggy in general):
(http://i.imgur.com/wZBhjMT.png)
Does this mean that 40.19-r1 will include Stonesense?Does this mean that 40.19-r1 will include overlay?
Does this mean that 40.19-r1 will include Stonesense?Does this mean that 40.19-r1 will include overlay?
New release!Thank you so much! I'm sure my voice is the voice of thousands when I say. "We sure appreciate all you do!"
Does this mean that 40.19-r1 will include Stonesense?Does this mean that 40.19-r1 will include overlay?
If it has Stonesense at all, it'll have the overlay - it's a built-in feature now (if unpolished).
(http://media.giphy.com/media/vGbL469j4pBJK/giphy.gif)
New release!
New release!
I'm uploading an OS X build now and starting a build on Linux.Uhmm: https://www.dropbox.com/s/jl2wlb8832o13bg/dfhack-0.40.19-r1-Darwin.zip
Hi sorry for Newb question, but something in DFHack is replacing some of the standard menu keyboard commands, any advise on how to switch them off?
Hi sorry for Newb question, but something in DFHack is replacing some of the standard menu keyboard commands, any advise on how to switch them off?
Because DF uses an old SDL version, the 'alt' key gets stuck occasionally. Press and release the 'alt' key so it gets the keyup signal, and it should be fine.
Thanks! Expwnent has uploaded that to Github (https://github.com/dfhack/dfhack/releases/tag/0.40.19-r1).I'm uploading an OS X build now and starting a build on Linux.Uhmm: https://www.dropbox.com/s/jl2wlb8832o13bg/dfhack-0.40.19-r1-Darwin.zip
Forgot to post it earlier.
I don't believe this has anything to do with the SDL version, although you could try upgrading to 1.2.15. It may be a conflict with other utilities, a problem with how DFHack handles keybindings, or a problem with DF itself. Speaking of this, could you (or anyone else on Windows) try to reproduce it without any utilities and post your findings in the report (http://www.bay12games.com/dwarves/mantisbt/view.php?id=6455)?Hi sorry for Newb question, but something in DFHack is replacing some of the standard menu keyboard commands, any advise on how to switch them off?
Because DF uses an old SDL version, the 'alt' key gets stuck occasionally. Press and release the 'alt' key so it gets the keyup signal, and it should be fine.
-- Allows ectobiology.
-- where doing it man
-- where MAKING THIS HAPEN
local function getCitizenList(lovers_only)
local citizenTable={}
if lovers_only then
for k,u in ipairs(df.global.world.units.active) do
if dfhack.units.isCitizen(u) and (u.relations.spouse_id~=-1 or u.relations.lover_id~=-1) then
table.insert(citizenTable,{dfhack.TranslateName(dfhack.units.getVisibleName(u)),nil,u})
end
end
else
for k,u in ipairs(df.global.world.units.active) do
if dfhack.units.isCitizen(u) then
table.insert(citizenTable,{dfhack.TranslateName(dfhack.units.getVisibleName(u)),nil,u})
end
end
end
return citizenTable
end
local function getSpouseOrLover(unit)
local lover_unit=df.unit.find(unit.relations.lover_id) or df.unit.find(unit.relations.spouse_id)
if lover_unit then
return lover_unit.hist_figure_id
else
local hist_fig=df.historical_figure.find(unit.hist_figure_id)
for k,v in ipairs(hist_fig.histfig_links) do
if df.histfig_hf_link_spousest:is_instance(v) or df.histfig_hf_link_loverst:is_instance(v) then
return v.target_hf
end
end
end
end
local function getFemaleCasteWithSameMaxAge(unit)
local curCaste=df.creature_raw.find(unit.race).caste[unit.caste]
for k,caste in ipairs(df.creature_raw.find(unit.race).caste) do
if caste.gender==0 and caste.misc.maxage_min==curCaste.misc.maxage_min and caste.misc.maxage_max==curCaste.misc.maxage_max then return k end
end
end
local function ectobiologize(freeform)
local script=require('gui.script')
script.start(function()
local citizens=getCitizenList(not freeform)
if #citizens==0 then script.showMessage('Ectobiology',"Nobody is in a relationship! Best use freeform ectobiology.",COLOR_WHITE) return end
if freeform then
local ok1,name1,unit1_t=script.showListPrompt("Ectobiology","Choose first paradox ghost slime target.",COLOR_WHITE,citizens)
local ok2,name2,unit2_t=script.showListPrompt("Ectobiology","Choose second paradox ghost slime target.",COLOR_WHITE,citizens)
local unit1=unit1_t[3]
local unit2=unit2_t[3]
unit1.relations.pregnancy_timer=1
unit1.relations.pregnancy_genes=unit1.appearance.genes:new()
unit1.relations.pregnancy_spouse=unit2.hist_figure_id
unit1.relations.pregnancy_caste=unit2.caste
dfhack.run_script('modtools/add-syndrome','-syndrome','temp desterilize','-target',unit1.id)
if unit1.sex==1 then
local normal_caste=unit1.enemy.normal_caste
unit1.enemy.normal_caste=getFemaleCasteWithSameMaxAge(unit1)
script.sleep(1,'ticks')
unit1.enemy.normal_caste=normal_caste
end
else
local ok,name,unit_t=script.showListPrompt("Ectobiology","Choose first genetic material giver.",COLOR_WHITE,citizens)
local unit=unit_t[3]
local lover=getSpouseOrLover(unit)
unit.relations.pregnancy_timer=1
unit.relations.pregnancy_genes=unit.appearance.genes:new()
unit.relations.pregnancy_spouse=lover
unit.relations.pregnancy_caste=df.historical_figure.find(lover).caste
dfhack.run_script('modtools/add-syndrome','-syndrome','temp desterilize','-target',unit.id)
if unit.sex==1 then
local normal_caste=unit.enemy.normal_caste
unit.enemy.normal_caste=getFemaleCasteWithSameMaxAge(unit)
script.sleep(1,'ticks')
unit.enemy.normal_caste=normal_caste
end
end
end)
end
local utils=require('utils')
validArgs = validArgs or utils.invert({
'freeform'
})
local args = utils.processArgs({...}, validArgs)
ectobiologize(args.freeform)
Is elevate-physical gone in the new version?That's never been included in the DFHack repo - it's one of Vjek's scripts (http://dwarffortresswiki.org/index.php/User:Vjek).
You still want some kind of reaction product, otherwise the reaction takes no time and generates no experience.
libpng12.so.0: wrong ELF class: ELFCLASS64
Can't load plugin /path/to/df19/hack/plugins/stonesense.plug.so
Press the button to actually go into the item's screen, it's only selected if you do that.so when i have it highlighted and go to the menu where you can see it's weight and etc. Already tried it not working
I don't believe this has anything to do with the SDL version, although you could try upgrading to 1.2.15. It may be a conflict with other utilities, a problem with how DFHack handles keybindings, or a problem with DF itself. Speaking of this, could you (or anyone else on Windows) try to reproduce it without any utilities and post your findings in the report (http://www.bay12games.com/dwarves/mantisbt/view.php?id=6455)?
Are you sure this is caused by DFHack? I know it's noticeable with DFHack keybindings, but could you see if it occurs with vanilla DF?
Is elevate-physical gone in the new version?I'm going to be testing all my scripts with the current (40.19) df/dfhack this week, and updating the wiki page to reflect any changes. They might work perfectly at the moment, they might burn down your house, not sure yet. :)
-- lets babies be adopted by couples with no infants.
local function getSpouseOrLover(unit)
local lover_unit=df.unit.find(unit.relations.lover_id) or df.unit.find(unit.relations.spouse_id)
if lover_unit then
return lover_unit.hist_figure_id
else
local hist_fig=df.historical_figure.find(unit.hist_figure_id)
for k,v in ipairs(hist_fig.histfig_links) do
if df.histfig_hf_link_spousest:is_instance(v) or df.histfig_hf_link_loverst:is_instance(v) then
return v.target_hf
end
end
end
return false
end
local function getNumberOfChildren(unit)
local children=0
for k,v in ipairs(df.historical_figure.find(unit.hist_figure_id).histfig_links) do
if df.histfig_hf_link_childst:is_instance(v) then children=children+1 end
end
return children
end
local function figureIsAlive(hist_figure)
return hist_figure.died_year==-1
end
local function unitIsChild(unit)
return df.global.cur_year-unit.relations.birth_year<12
end
local function unitIsOrphan(unit)
if unitIsChild(unit) then
local fatherIsAlive,motherIsAlive=false,false
for k,v in ipairs(df.historical_figure.find(unit.hist_figure_id).histfig_links) do
if df.histfig_hf_link_motherst:is_instance(v) then
if figureIsAlive(df.historical_figure.find(v.hist_figure_id)) then motherIsAlive=true end
elseif df.histfig_hf_link_fatherst:is_instance(v) then
if figureIsAlive(df.historical_figure.find(v.hist_figure_id)) then fatherIsAlive=true end
end
end
return (fatherIsAlive or motherIsAlive)
end
return false
end
local function adopt(baby,couple)
local mother,father=false,false
if df.historical_figure.find(couple.unit).sex==0 then
mother=couple.unit
father=couple.lover --yeah, the "father" will be female if the unit's lover is female, but the game will correctly display both as "mother"
else
father=couple.unit
mother=couple.lover --similar to the above, the "mother" will be male if the unit's lover is male, but they'll both be "father" pretty elegantly.
end
local mother_fig=df.historical_figure.find(mother)
local father_fig=df.historical_figure.find(father)
local baby_hist_fig=df.historical_figure.find(baby.hist_figure_id)
for k,v in ipairs(baby_hist_fig.histfig_links) do
if df.histfig_hf_link_motherst:is_instance(v) then
v.target_hf=mother --yeah, adoption will remove any relation other than genetics between biological parents and children.
elseif df.histfig_hf_link_fatherst:is_instance(v) then
v.target_hf=father
end
end
mother_fig.histfig_links:insert('#',{new=df.histfig_hf_link_childst,target_hf=baby.hist_figure_id,link_strength=100})
father_fig.histfig_links:insert('#',{new=df.histfig_hf_link_childst,target_hf=baby.hist_figure_id,link_strength=100})
baby.relations.mother_id=mother_fig.unit_id
baby.relations.father_id=father_fig.unit_id
local message = dfhack.TranslateName(mother_fig.name) .. ' and ' .. dfhack.TranslateName(father_fig.name) .. ' have adopted ' .. dfhack.TranslateName(dfhack.units.getVisibleName(baby)) .. '.'
dfhack.gui.showAnnouncement(message)
dfhack.gui.writeToGamelog(message) --too lazy to use makeAnnouncement right now
end
local function findBabiesWithNoParents()
local couples_histfig={}
local orphans={}
for k,unit in ipairs(df.global.world.units.active) do
if dfhack.units.isCitizen(unit) then
local spouseOrLover=getSpouseOrLover(unit)
if spouseOrLover then
couples_histfig[unit.hist_figure_id]=couples_histfig[unit.hist_figure_id] or {children=getNumberOfChildren(unit),lover=spouseOrLover,unit=unit.hist_figure_id}
couples_histfig[spouseOrLover]=true --this weird sequence of crap makes it so that 1. I can easily cull redundant units and 2. I can still sort the table
elseif unitIsOrphan(unit) then
table.insert(orphans,unit)
end
end
end
local couples={}
for k in pairs(couples_histfig) do
if couples[k]==true then couples[k]=nil end --not doing this will make an error show up when sorting the couples table due to true.children being nonsense
end
for k,v in pairs(couples_histfig) do
table.insert(couples,v) --makes the keys of the couples table be 1,2,3 etc. instead of being all over the place as histfigs
end
table.sort(couples,function(a,b) return a.children<b.children end)
if #orphans>1 then
for k,orphan in ipairs(orphans) do
adopt(orphan,math.ceil(couples[k]/2))
end
end
end
require('repeat-util').scheduleUnlessAlreadyScheduled('Orphan Adoption Service',1,'days',findBabiesWithNoParents)
libjpeg.so.62: cannot open shared object file: No such file or directory
Adoption! It takes childless parents and gives them parents from couples.Putnam, this is extremely cool, but could you be a sweetheart and make a gist out of it or upload it on wimbli or do a pull request or do anything that will prevent this cool script from getting buried in the massive thread? We've already had these issues in the .34.11r5 thread. This way you'd have an easier time maintaining it, too.
I'm not sure if this is possible, but I've seen a LOT of people get confused by the stuck-Alt-key issue and complain in the Starter Pack thread.
Are you sure this is caused by DFHack? I know it's noticeable with DFHack keybindings, but could you see if it occurs with vanilla DF?
Uh, yes. What I meant is that there should be a subforum specifically dedicated to DFHack so all questions related to it aren't contained within one giant thread. There was a poll about it some time ago, and most people were favourable to the idea.Japa means that UA3PA forum is kinda the DFhack(and other utilities) subforum after it got separated from DFmodding. I don't think another subforum would be needed for a Post in a thread, that's like making a new planet for one person in a country. you're better off just making a [Dfhack question] thread and hope someone could answer it(we usually don't so it's bound to be empty). Though you're best bet for questions to not get swallowed up is to hit us on IRC.
Uh, yes. What I meant is that there should be a subforum specifically dedicated to DFHack so all questions related to it aren't contained within one giant thread. There was a poll about it some time ago, and most people were favourable to the idea.I don't think another subforum would be needed for a Post in a thread, that's like making a new planet for one person in a country.
My two cents: there is enough DFHack content to merit its own forum but there isn't enough 3rd party stuff that isn't DFHack to merit its own forum so it may as well all get lumped together.Actually there's plenty, it just tends to be buried by all the dfhack stuff since dfhack development is much more active and needs constant updating. I think a separation could benefit both sides. Other third party utilities would have greater visibility and user support for DFHack (since it's lacking somewhat in documentation) would be easier.
QuoteMy two cents: there is enough DFHack content to merit its own forum but there isn't enough 3rd party stuff that isn't DFHack to merit its own forum so it may as well all get lumped together.Actually there's plenty, it just tends to be buried by all the dfhack stuff since dfhack development is much more active and needs constant updating. I think a separation could benefit both sides. Other third party utilities would have greater visibility and user support for DFHack (since it's lacking somewhat in documentation) would be easier.
@expwnent - Could you please edit the first post to remove the line "This must be downloaded separately for technical reasons." from the stonesense line. Stonesense hasn't had its own release since 2010 (https://github.com/DFHack/stonesense/releases), and its been bundled with DFHack releases for awhile (except of course the recent non-availability due to bugs).
Elsewhere (Reddit and StackExchange) people are confused about how to get stonesense because of that line ([snide_comment]apparently some people read user docs![/snide_comment]).
https://github.com/JapaMala/armok-vision
This is a little something I threw together to read DF map data into Unity.
The way it works is that there's a DFHack plugin that accepts RPC calls over sockets, and returns data to the client. Right now it's just basic map reading, but it can be extended to anything. The important part is that the RPC language used is independent of DFHack version, so even if DFHack adds or removes features, the RPC protocol either is unchanged, or changes more intelligently, to maintain compatibility (This has already happened at least once so far)
Then the unity side does what it wants with everything.
My goal with this was to have a 3d visualizer that worked with multiple versions of DF at the same time. (In comparison to stonesense, which is locked to one DF version, so if you want to view older forts, you have to use an older stonesense, and all that implies)
Only reason that wasn't realtime is because I was more working on making sure things were connecting right and rendering. There's no reason why it couldn't do updates more often. The communication is pretty quick, in any case.
Regarding events, something clever could be done with them, maybe, but I think it'd be simplest just to poll for changed values of stuff.
Things like dwarf positions would change far more often than terrain data, after all.
Only reason that wasn't realtime is because I was more working on making sure things were connecting right and rendering. There's no reason why it couldn't do updates more often. The communication is pretty quick, in any case.
Regarding events, something clever could be done with them, maybe, but I think it'd be simplest just to poll for changed values of stuff.
Things like dwarf positions would change far more often than terrain data, after all.
Well I'm home from work now, so it's time to start experimenting! Great work with this Japa. Reduces a lot of the framework I was thinking I was needing to write to get the RPC connection working. :)
Or better yet, stay away from C#.
Only reason that wasn't realtime is because I was more working on making sure things were connecting right and rendering. There's no reason why it couldn't do updates more often. The communication is pretty quick, in any case.
Regarding events, something clever could be done with them, maybe, but I think it'd be simplest just to poll for changed values of stuff.
Things like dwarf positions would change far more often than terrain data, after all.
Well I'm home from work now, so it's time to start experimenting! Great work with this Japa. Reduces a lot of the framework I was thinking I was needing to write to get the RPC connection working. :)
A request from a fellow dev and non-windows user: whatever you're creating for DFHack, if you plan to mass release it, please keep it compatible with the Mono libraries so non-windows users can use it.
whyC# is an unwieldy language for non-Windows OSes.
whyC# is an unwieldy language for non-Windows OSes.
interaction-trigger -suppressDefend doesn't seem to work.
In lua how do I get the type of a tile?
The Documentation seem a bit sparse, I found the dfhack.maps.getTileType(coords) function which returns a number, however it seems to return the same for eg openSpace and Lava?
My end goal is check if there is a Liquid and which one at a given position. Any hints/examples are appreciated.
block = dfhack.maps.getTileBlock(x, y, z)
flow_size = block.designation[x%16][y%16].flow_size
liquid_type = block.designation[x%16][y%16].liquid_type
How would I make someone hostile with DFHack?depends on what range of hostilities
My dfhack comes up with a ton of red text when I try that... Ohwell. I'll try again some other time. Thanks for telling me!
[DFHack]# digFlood CLEAR
Could not find material "CLEAR".
Usage:
Example:
digFlood 0
disable plugin
digFlood 1
enable plugin
digFlood 0 MICROCLINE COAL_BITUMINOUS 1
disable plugin and remove microcline and bituminous coal from being monitored, then re-enable plugin digFlood 1 MICROCLINE 0 COAL_BITUMINOUS 1
do monitor microcline, don't monitor COAL_BITUMINOUS, then enable plugin
digFlood CLEAR
remove all inorganics from monitoring
digFlood digAll1
enable digAll mode: dig any vein, regardless of the monitor list
digFlood digAll0
disable digAll mode
[DFHack]#
DigFlood failure?[DFHack]# digFlood CLEAR
Could not find material "CLEAR".
Usage:
Example:
digFlood 0
disable plugin
digFlood 1
enable plugin
digFlood 0 MICROCLINE COAL_BITUMINOUS 1
disable plugin and remove microcline and bituminous coal from being monitored, then re-enable plugin digFlood 1 MICROCLINE 0 COAL_BITUMINOUS 1
do monitor microcline, don't monitor COAL_BITUMINOUS, then enable plugin
digFlood CLEAR
remove all inorganics from monitoring
digFlood digAll1
enable digAll mode: dig any vein, regardless of the monitor list
digFlood digAll0
disable digAll mode
[DFHack]#
Pretty much nothing, except when I kill Dwarf Fortress (either manually or by means of Ctrl-Shift-P and "die"):Does it matter if you invoke the command with "Ctrl-Shift-P" or in console?Spoiler (click to show/hide)
I should mention it also uses up a whole core on itself (DF running on another core) if I leave it hanging.
No, pretty much the same thing happens. The prompt hangs and I even lose control of the game, so I have to kill it with the actual console.Does the console hang before or after displaying the DFHack prompt again?
When I try to use the Embark comand it just says;Try typing embark-tools enable.
Offset for embark patch not found!
I haven't changed any of the settings, its all default. Should I have? Do I need to redownload?
1. Well, it tells you what causes them to be horrified pretty explicitly, say, "watching x die".
2. Easily, if unit.relations.pregnancy_timer>0 then unit is pregnant.
end
2. Yes, that's because it's a structure. Press enter on it.Woo! Dunno why I didn't think of that. That's got me wanting to figure out how to make a script for a Pregnancy GUI. It will be a nice and relevant project to learn, as I'm about to pop out an actual baby sometime this week ;) Thanks for the help!
So I'm not sure if I have asked this before. It crossed my mind awhile ago and just again now. I have been playing with the in game gui capabilities a bit and it made me realize that we could put better descriptions and information about creatures and items. Now I can do this already by having a separate button for checking this "enhanced" description, but I was wondering if it is possible to set it up so that instead of opening the standard description page when viewing a unit, it instead opens my custom page?
To be more clear, I am thinking about being able to display the descriptions properly formatted, where putting something like NEWLINE means that you will get a new line. And possibly even allowing descriptions on items through an external file.
Could it be possible to force the game to display more colors than the 16 included?
Could it be possible to force the game to display more colors than the 16 included?
Could it be possible to force the game to display more colors than the 16 included?Do you mean something like rendermax? If you mean using arbitrary colors for interface elements (particularly DFHack-generated ones), that should be possible using a similar strategy (subclassing df::renderer). Unfortunately, there's currently no safe way to use multiple custom renderers, so it wouldn't be possible to combine this with rendermax. I'm thinking of implementing a more centralized way to add custom renderers, which could make this and additional colors easier to implement (possibly from Lua as well).
1. I just tried, it's difficult at the very best. Imma keep trying.
2. There's the SC_VIEWSCREEN_CHANGED state change that can be used with dfhack.onStateChange.
EDIT: Oh, formatted_text.text seems to be a char[]. That makes it easier.
Inconvenient is that the junk values it's giving me when I put in high z for text[z] later suggest that I can get up to some serious trouble if I flub this. Oof.
But yeah, you can definitely edit the text in the text viewer.
(http://imgur.com/UNVTt4Z.png)
I can't figure that blank space in the word "is", though. I can't change it to anything, either.
The GUI lua interface is pretty damn powerful.It depends on what you mean. As for getting more than 16 colors on the screen, tileset graphics can already use arbitrary colors and TWBT/Rendermax both shade standard tiles.
Also, darn. Oh well, it was just a minor idea.
You can specify RGB values in the raws...Yes, but the question seemed to be about getting beyond a 16-display-color palette. It'd be nice if tiles were shaded by their named colors, but that's beyond the reach of raw modding and not yet a feature or TWBT or Rendermax. It is part of Stonesense, but that's not quite a game interface.
http://dwarffortresswiki.org/index.php/DF2014:Color#Color_tokens
You can make more of those arbitrarily.
As for coloring things by their named colors, that seems to be a lot more complicated. Expanding the color palette in the raws (for example, specifying RGB values) might be impossible and is certainly infeasible.
What's the exact path of the missing file? As far as I can tell, advfort requires "dfhack.buildings" and "gui.buildings", which correspond to <DF>/hack/lua/dfhack/buildings.lua and <DF>/hack/lua/gui/buildings.lua, both of which are included. As far as I can tell, there is no "building.lua" included with DFHack.
Should be <df folder>/stocksettings
ptb: none of those buildings listed are workshopsEr, yes, yes some of them are. Everything from Carpenters down are. In any case that doesn't really change the point of my questions. Namely, 'Advfort - does it work? And can I build workshops with it?'
Putting aside the problems I've had with the version of advfort altered by Warmist (http://www.bay12forums.com/smf/index.php?topic=123944.0), how usuable is the default version included with dfhack?Not usable at all. Included in dfhack version has two major bugs: does not list any workshops (due to me commiting a version with experimenting on list filtration for deon) and not having new "action" mechanic that is used in new df (due to me not knowing enough about it to implement).
Er, yes, yes some of them are. Everything from Carpenters down are. In any case that doesn't really change the point of my questions. Namely, 'Advfort - does it work? And can I build workshops with it?'Oh and yes old version prints out all possible buildings (again for filter development). It's really strange how it does not work for you. I'll have to look into it more closely. Maybe something todo with locale, but it's really unlikely...
It's really strange how it does not work for you. I'll have to look into it more closely. Maybe something todo with locale, but it's really unlikely...
Is it possible to get the exact material of a tile from a lua script?
Is it possible to get the exact material of a tile from a lua script?
Anyone? I asked before elsewhere and was ignored there too (a long time ago), could I at least get a yes or no?
function findMineralEv(block,inorganic) -- Taken from Warmist's constructor.lua
for k,v in pairs(block.block_events) do
if df.block_square_event_mineralst:is_instance(v) and v.inorganic_mat==inorganic then
return v
end
end
end
function set_vein(x,y,z,mat) -- Taken from Warmist's constructor.lua
local b=dfhack.maps.ensureTileBlock(x,y,z)
local ev=findMineralEv(b,mat.index)
if ev==nil then
ev=df.block_square_event_mineralst:new()
ev.inorganic_mat=mat.index
ev.flags.vein=true
b.block_events:insert("#",ev)
end
dfhack.maps.setTileAssignment(ev.tile_bitmask,math.fmod(x,16),math.fmod(y,16),true)
end
function changeType(x,y,z,material,dur)
local mat
if material ~= 'clear' then
mat = dfhack.matinfo.find(material)
set_vein(x,y,z,mat)
else
clear_vein(x,y,z)
end
end
You'll notice that the heart of it comes from Warmist, so he would probably be a better person to ask than me.
No. Using symbols.xml from here (https://github.com/lethosor/df-structures/blob/0.40.22-osx-offsets/symbols.xml) might make DFHack recognize the DF version, but most useful offsets will be missing unless you're using OS X. (You could try copying the 0.40.20 offsets into the 0.40.22 section for your platform, although I have no idea if this is safe on other platforms.)
Has the Brainwash script been removed from dfhack per default?It's never been included in DFHack - it's one of Vjek's scripts (http://dwarffortresswiki.org/index.php/User:Vjek#brainwash).
Does anyone know if the spawnunit script still works/was fixed? I see it when I list the commands, but I don't want to destroy my save file in case it's just a holdover.don't know if they updated it with my patched findings but here's a working spawn something script. (https://gist.github.com/Rumrusher/f4d0ba18ba6868d38221)
I'm wondering if it is possible to get a siege-trigger and trade-trigger, basically a script that runs anytime a siege or traders arrive, possibly ambushers too? I saw the onInvasion in eventful, so I assume that is basically my siege-trigger. Is there a similar thing for traders and ambushers? (Would also be interesting if there was such a thing for megabeasts)
EDIT: @expwnent, has the onLoad.init been modified to accept multi-line commands?
I'm wondering if it is possible to get a siege-trigger and trade-trigger, basically a script that runs anytime a siege or traders arrive, possibly ambushers too? I saw the onInvasion in eventful, so I assume that is basically my siege-trigger. Is there a similar thing for traders and ambushers? (Would also be interesting if there was such a thing for megabeasts)
EDIT: @expwnent, has the onLoad.init been modified to accept multi-line commands?
Those would be neat. There is currently no things for traders. On invasion should trigger for ambushes but not megabeasts (probably). onLoad.init does not yet support multiline commands, sadly.
I'm not sure what language (if any) that uses, but assuming you receive a report ID in Lua, a match can be determined with df.report.find(id).text:match('text to search for').Actually, from https://github.com/warmist/df-structures/blob/master/df.announcements.xml (https://github.com/warmist/df-structures/blob/master/df.announcements.xml) it looks like an announcement event has a lot of useful information embedded in it. Just have no idea how to turn that into an actual announce-trigger.
Exactly, df.report.find(id) returns an announcement object (or nil). What exactly is "announce-trigger"? I can't find anything in DFHack that refers to it.There isn't one, I was suggesting one if its feasible. It would incorporate the features that Roses requested with a lot of additional flexibility for modders to react to announcements. Might even pave the way for folding Soundsense into DFHack (if there would be any advantage to doing that).
You can use the onReport event - here (https://github.com/lethosor/dfhack-scripts/blob/master/annc-monitor.lua) is an example.Oh, that looks like exactly what Roses needed. Just stick the event handling logic inside the annc_handler function.
(the same way you can suppress an interaction verb)
That's unfortunate. I hadn't noticed because I managed to build my mod out of syndrome-triggers and reaction-triggers instead of interaction-triggers.(the same way you can suppress an interaction verb)
This doesn't seem to actually work as of the most recent version.
Does anyone know if there exists a GUI for "createitem" command? The command itself is not very easy or forgiving for people like me who have not dabbled with raws, so helpful filterable/searchable GUI would be very much appreciated.gui/hack-wish
Thank you.Does anyone know if there exists a GUI for "createitem" command? The command itself is not very easy or forgiving for people like me who have not dabbled with raws, so helpful filterable/searchable GUI would be very much appreciated.gui/hack-wish
Okay, added very basic unit loading to Armok Vision, and RemoteFortressReader. All it does is get a list of the coordinates of all units in play over the network.
Yeah, the map is divided into blocks of 16x16 tiles.
cd library/xml
git fetch origin
git checkout origin/master
I just tested it, works perfectly for 40.23 Linux. It does exactly what I wanted.
If you're using OS X or Linux, you would still need a copy of DFHack from at least 0.40.20 (of which there are none) in order to make it work with 0.40.23 by copying over symbols.xml, due to structure changes made in 0.40.20.
Yeah, compiled from Lethosor's 0.40.23-dev (https://github.com/lethosor/dfhack/tree/0.40.23-dev) branch. It's already quite stable, most things work. You need to use latest df-structures.I've tried that a few times before. Never quite managed it. If a kind person decided to upload an unofficial dev compiles for Window, Linux and/or OS X I'm sure many would be very grateful.
I as well.Yeah, compiled from Lethosor's 0.40.23-dev (https://github.com/lethosor/dfhack/tree/0.40.23-dev) branch. It's already quite stable, most things work. You need to use latest df-structures.I've tried that a few times before. Never quite managed it. If a kind person decided to upload an unofficial dev compiles for Window, Linux and/or OS X I'm sure many would be very grateful.
There were some missing symbols for Windows, so that's why you aren't seeing any unofficial windows DFHack floating around. The only one in reddit is very buggy, it crashes on dig* commands, manager doesn't work, not even embark tools work. I think the only thing that works is reveal.Ohh. my favourite function for a new fort, and I just started one.. Makes planning a bit easier, and lets me avoid the mess I made in the last one.. hmm, where can I get that reddit version?
Gtk-Message: Failed to load module "canberra-gtk-module"
Loading bindings from data/init/interface.txt
New window size: 1920x1080
Font size: 24x24
Resizing grid to 80x45
Resizing font to 24x24
Resetting textures
TWBT: version 5.36
TWBT: set PRINT_MODE to TWBT or TWBT_LEGACY in data/init/init.txt to activate the plugin
Ohh. my favourite function for a new fort, and I just started one.. Makes planning a bit easier, and lets me avoid the mess I made in the last one.. hmm, where can I get that reddit version?
TwbT shouldn't be loaded unless you've compiled it for 0.40.23 or forgot to change the DFHack version. (For example, if DFHack is built as "0.40.19-r1", it'll load any plugins built with "0.40.19-r1", which can cause crashes if they're not actually compatible with the DF/DFHack version being used.) I'm not sure if TwbT is the problem in this case, but you could try removing it from the hack/plugins folder.Yup, realized that I had forgot to swap over the new plugins folder which doesn't have it in there, checking to see if I've got it fixed.
Thank you wery much. :)Ohh. my favourite function for a new fort, and I just started one.. Makes planning a bit easier, and lets me avoid the mess I made in the last one.. hmm, where can I get that reddit version?
Here (https://www.reddit.com/r/dwarffortress/comments/2r0koe/df_hack_for_last_df_release/). A new build was just posted that fixes a lot of the problems the old one had.
So what about dfhack for 0.40.23? Will it be ready anytime soon?
Toady has an unnerving ability to time his releases to coincide with either the DFHack update or the Lazy New Pack update that follows quickly thereafter.So what about dfhack for 0.40.23? Will it be ready anytime soon?
So many fixes recently, I have a feeling that .24 will be released soon.
So what about dfhack for 0.40.23? Will it be ready anytime soon?Expwnent's been busy recently:
I'm going to work on it this weekend. I've been busy with family stuff.I'm not sure exactly when we'll get around to a release, but DFHack is sufficiently updated for one. (There are a number of pull requests that fix problems with plugins that would need to be merged first, however.)
New release. It took a long time because I was away for Christmas stuff. Sorry for the delay everyone!
Edit: I've merged every open PR and updated a few things, so this branch should compile and work with 0.40.23 (at least, it does on OS X): https://github.com/lethosor/dfhack/tree/0.40.23-r1-rcUmm... Thanks but... Am I supposed to compile it somehow? I don't even use *nix, you know. Where can I get compiled Windows version?
Edit: I've merged every open PR and updated a few things, so this branch should compile and work with 0.40.23 (at least, it does on OS X): https://github.com/lethosor/dfhack/tree/0.40.23-r1-rcUmm... Thanks but... Am I supposed to compile it somehow? I don't even use *nix, you know. Where can I get compiled Windows version?
-- prints info on assigned hotkeys to the console
local hotkeys = {'F1 ', 'F2 ', 'F3 ', 'F4 ', 'F5 ', 'F6 ',
'F7 ', 'F8 ', 'F9 ', 'F10', 'F11', 'F12'}
for i=1, #hotkeys do
local hk = hotkeys[i]
hk = {id=hk}
-- PLACEHOLDER PROPERTIES ONLY!
hk.name = '_name'
hk.x = df.global.window_x
hk.y = df.global.window_y
hk.z = df.global.window_z
print(hk.id..' '..hk.name..' X= '..hk.x..', Y= '..hk.y..', Z= '..hk.z)
end
print(('%i %i X=%i Y=%i Z=%i'):format(hk.id, hk.name, hk.x, hk.y, hk.z))
(The parentheses around the string are only necessary for string literals.)
Take a look at df.global.ui.main.hotkeys
Also, there is no "F9" hotkey by default - the default keybindings use F1-F8 and Shift+F1-F8.
I've forgotten how to install DFHack on OSX. Can someone please give me a quick run-down?Same as other platforms - copy all files/folders from the archive into your DF folder.
I've forgotten how to install DFHack on OSX. Can someone please give me a quick run-down?
******************************************************
Auxiliary file changes for 0.40.23:
creature_small_riverlake and creature_standard
breath -> breathe a few places (Gorobay)
******************************************************
Auxiliary file changes for 0.40.22:
Just the usual.
******************************************************
Auxiliary file changes for 0.40.21:
Just the usual.
******************************************************
Auxiliary file changes for 0.40.20:
new keys
DESIGNATE_STANDARD_MARKER:m
DESIGNATE_MINE_MODE:a
DESIGNATE_TOGGLE_MARKER:M
BUILDJOB_NOW:n
changed key
DESIGNATE_FORTIFY a -> F
Try deleting hack/libstdc++.6.dylib. That's there to fix a bunch of Lua-related crashes that occur with DF's libstdc++ (in libs/), but I doubt it works on 10.6. I could try adjusting some more GCC build flags, I suppose.
Lua error messages crash the game.Try deleting hack/libstdc++.6.dylib. That's there to fix a bunch of Lua-related crashes that occur with DF's libstdc++ (in libs/), but I doubt it works on 10.6. I could try adjusting some more GCC build flags, I suppose.
What were the crashes, by the way? I'm doing a lot of Lua coding recently and never seen any crashes (well, except for the ones I believe caused by C++ part of my code).
Will it be safe to just copy and paste my domestic creature raws from 40.19 into 40.23? If not, I honestly don't know what I'm going to do.Yeah, sure, .19 and .23 is almost identical.
Lua error messages crash the game.Try deleting hack/libstdc++.6.dylib. That's there to fix a bunch of Lua-related crashes that occur with DF's libstdc++ (in libs/), but I doubt it works on 10.6. I could try adjusting some more GCC build flags, I suppose.
What were the crashes, by the way? I'm doing a lot of Lua coding recently and never seen any crashes (well, except for the ones I believe caused by C++ part of my code).
https://github.com/DFHack/dfhack/issues/437
More specifically, Lua errors triggered from C++ would crash (and only in some cases).Lua error messages crash the game.Try deleting hack/libstdc++.6.dylib. That's there to fix a bunch of Lua-related crashes that occur with DF's libstdc++ (in libs/), but I doubt it works on 10.6. I could try adjusting some more GCC build flags, I suppose.
What were the crashes, by the way? I'm doing a lot of Lua coding recently and never seen any crashes (well, except for the ones I believe caused by C++ part of my code).
https://github.com/DFHack/dfhack/issues/437
Oh so it's not something you can do from Lua code. Thanks.That depends on what you mean - something as simple as "dfhack.gui.showAnnouncement()" crashed reliably.
When I try to gen a new world, this white rectangle appears on screen and it covers over whatever else is on the screen in that area, and the game straight-up freezes.That happens when you used modded raws with the saves and not everything is in the right place.
[CREATURE:AQUILOUP]
[DESCRIPTION:A wolf-like creature with an eagle's broad wings and razor-sharp talons instead of paws. It can be seen flying high above the virtuous temperate lands.]
[NAME:aquiloup:aquiloups:aquiloup]
[CASTE_NAME:aquiloup:aquiloups:aquiloups]
[CHILD:2][GENERAL_CHILD_NAME:aquiloup pup:aquiloup pups]
[CREATURE_TILE:'A'][COLOR:6:0:0]
[LARGE_PREDATOR]
[LARGE_ROAMING][FREQUENCY:50]
[BIOME:TUNDRA]
[BIOME:FOREST_TAIGA]
[BIOME:ANY_TEMPERATE_FOREST]
[BIOME:SHRUBLAND_TEMPERATE]
[BIOME:MOUNTAIN]
[POPULATION_NUMBER:15:30]
[CLUSTER_NUMBER:3:7]
[GRASSTRAMPLE:0][NATURAL]
[PETVALUE:1000]
[PET_EXOTIC]
[TRAINABLE]
[GOOD]
[FLIER]
[GRASSTRAMPLE:0]
[MOUNT_EXOTIC]
[FANCIFUL]
[BONECARN]
[PREFSTRING:elaborate courtship flights]
[PREFSTRING:noble features]
[PREFSTRING:devoted parenting]
[BODY:QUADRUPED_NECK:2WINGS:TAIL:2EYES:2EARS:NOSE:2LUNGS:HEART:GUTS:ORGANS:THROAT:NECK:SPINE:BRAIN:SKULL:4TOES_FQ_REG:4TOES_RQ_REG:MOUTH:TONGUE:GENERIC_TEETH_WITH_LARGE_EYE_TEETH:RIBCAGE]
[BODYGLOSS:TALON]
[BODY_DETAIL_PLAN:STANDARD_MATERIALS]
[BODY_DETAIL_PLAN:STANDARD_TISSUES]
[SELECT_TISSUE:HAIR]
[INSULATION:200]
[BODY_DETAIL_PLAN:VERTEBRATE_TISSUE_LAYERS:SKIN:FAT:MUSCLE:BONE:CARTILAGE]
[BODY_DETAIL_PLAN:BODY_HAIR_TISSUE_LAYERS:HAIR]
[USE_MATERIAL_TEMPLATE:FEATHER_FEATHER_TEMPLATE]
[USE_TISSUE_TEMPLATE:FEATHER:FEATHER_TEMPLATE]
[TISSUE_LAYER:BY_CATEGORY:WING]
[USE_MATERIAL_TEMPLATE:TALON:NAIL_TEMPLATE]
[USE_TISSUE_TEMPLATE:TALON:NAIL_TEMPLATE]
[TISSUE_LAYER:BY_CATEGORY:TOE:TALON:FRONT]
[SELECT_TISSUE_LAYER:HEART:BY_CATEGORY:HEART]
[PLUS_TISSUE_LAYER:SKIN:BY_CATEGORY:THROAT]
[TL_MAJOR_ARTERIES]
[BODY_DETAIL_PLAN:STANDARD_HEAD_POSITIONS]
[BODY_DETAIL_PLAN:HUMANOID_RIBCAGE_POSITIONS]
[USE_MATERIAL_TEMPLATE:SINEW:SINEW_TEMPLATE]
[TENDONS:LOCAL_CREATURE_MAT:SINEW:200]
[LIGAMENTS:LOCAL_CREATURE_MAT:SINEW:200]
[HAS_NERVES]
[USE_MATERIAL_TEMPLATE:BLOOD:BLOOD_TEMPLATE]
[BLOOD:LOCAL_CREATURE_MAT:BLOOD:LIQUID]
[CREATURE_CLASS:GENERAL_POISON]
[GETS_WOUND_INFECTIONS]
[GETS_INFECTIONS_FROM_ROT]
[USE_MATERIAL_TEMPLATE:PUS:PUS_TEMPLATE]
[PUS:LOCAL_CREATURE_MAT:PUS:LIQUID]
[BODY_SIZE:0:0:20000]
[BODY_SIZE:1:0:100000]
[BODY_SIZE:2:0:200000]
[BODY_APPEARANCE_MODIFIER:LENGTH:90:95:98:100:102:105:110]
[BODY_APPEARANCE_MODIFIER:HEIGHT:90:95:98:100:102:105:110]
[BODY_APPEARANCE_MODIFIER:BROADNESS:90:95:98:100:102:105:110]
[MAXAGE:20:40]
[ATTACK:BITE:CHILD_BODYPART_GROUP:BY_CATEGORY:HEAD:BY_CATEGORY:TOOTH]
[ATTACK_SKILL:BITE]
[ATTACK_VERB:bite:bites]
[ATTACK_CONTACT_PERC:100]
[ATTACK_PENETRATION_PERC:100]
[ATTACK_FLAG_EDGE]
[ATTACK_PREPARE_AND_RECOVER:3:3]
[ATTACK_PRIORITY:MAIN]
[ATTACK_FLAG_CANLATCH]
[ATTACK:SCRATCH:CHILD_TISSUE_LAYER_GROUP:BY_TYPE:STANCE:BY_CATEGORY:ALL:NAIL]
[ATTACK_SKILL:GRASP_STRIKE]
[ATTACK_VERB:claw:claws]
[ATTACK_CONTACT_PERC:100]
[ATTACK_PENETRATION_PERC:100]
[ATTACK_FLAG_EDGE]
[ATTACK_PREPARE_AND_RECOVER:3:3]
[ATTACK_PRIORITY:SECOND]
[DIURNAL]
[HOMEOTHERM:10070]
[APPLY_CREATURE_VARIATION:STANDARD_QUADRUPED_GAITS:900:447:298:149:1900:2900] 59 kph
[APPLY_CREATURE_VARIATION:STANDARD_SWIMMING_GAITS:6561:6115:5683:1755:7456:8567] 5 kph
[APPLY_CREATURE_VARIATION:STANDARD_CRAWLING_GAITS:6561:6115:5683:1755:7456:8567] 5 kph
[SWIMS_INNATE]
[MUNDANE]
[CASTE:FEMALE]
[FEMALE]
[CASTE:MALE]
[MALE]
[SET_BP_GROUP:BY_TYPE:LOWERBODY][BP_ADD_TYPE:GELDABLE]
[SELECT_CASTE:ALL]
[SET_TL_GROUP:BY_CATEGORY:ALL:HAIR]
[TL_COLOR_MODIFIER:WHITE:1:SILVER:1:PEARL:1]
[TLCM_NOUN:hair and feathers:PLURAL]
[SET_TL_GROUP:BY_CATEGORY:ALL:SKIN]
[TL_COLOR_MODIFIER:BROWN:1:BURNT_UMBER:1:CINNAMON:1:COPPER:1:DARK_BROWN:1:DARK_PEACH:1:DARK_TAN:1:ECRU:1:PALE_BROWN:1:PALE_CHESTNUT:1:PALE_PINK:1:PEACH:1:PINK:1:RAW_UMBER:1:SEPIA:1:TAN:1:TAUPE_PALE:1:TAUPE_SANDY:1]
[TLCM_NOUN:skin:SINGULAR]
[SET_TL_GROUP:BY_CATEGORY:EYE:EYE]
[TL_COLOR_MODIFIER:IRIS_EYE_AMBER:1:ORANGE:1:GOLD:1]
[TLCM_NOUN:eyes:PLURAL]
[SELECT_MATERIAL:ALL]
[MULTIPLY_VALUE:4]
[CREATURE:BONGO]
[DESCRIPTION: A large, heavy-bodied antelope with large, curving horns and striking white markings.]
[NAME:bongo:bongos:bongo]
[CASTE_NAME:bongo:bongos:bongo]
[CHILD:1][GENERAL_CHILD_NAME:bongo calf:bongo calves]
[CREATURE_TILE:'B'][COLOR:7:0:1]
[PETVALUE:50]
[PET_EXOTIC]
[MOUNT_EXOTIC]
[STANDARD_GRAZER]
[VISION_ARC:50:310]
[PREFSTRING:attractive markings]
[PREFSTRING:graceful horns]
[GRASSTRAMPLE:0]
[LARGE_ROAMING]
[POPULATION_NUMBER:15:30]
[CLUSTER_NUMBER:4:8]
[BIOME:SHRUBLAND_TROPICAL]
[BIOME:FOREST_TROPICAL_MOIST_BROADLEAF]
[BENIGN][MEANDERER][NATURAL]
[BODY:QUADRUPED_NECK_HOOF:TAIL:2EYES:2EARS:NOSE:2LUNGS:HEART:GUTS:ORGANS:THROAT:NECK:SPINE:BRAIN:SKULL:MOUTH:GENERIC_TEETH:RIBCAGE]
[BODY_DETAIL_PLAN:STANDARD_MATERIALS]
[USE_MATERIAL_TEMPLATE:HOOF:HOOF_TEMPLATE]
[BODY_DETAIL_PLAN:STANDARD_TISSUES]
[USE_TISSUE_TEMPLATE:HOOF:HOOF_TEMPLATE]
[BODY_DETAIL_PLAN:VERTEBRATE_TISSUE_LAYERS:SKIN:FAT:MUSCLE:BONE:CARTILAGE]
[BODY_DETAIL_PLAN:BODY_HAIR_TISSUE_LAYERS:HAIR]
[SELECT_TISSUE_LAYER:HEART:BY_CATEGORY:HEART]
[PLUS_TISSUE_LAYER:SKIN:BY_CATEGORY:THROAT]
[TL_MAJOR_ARTERIES]
[BODY_DETAIL_PLAN:STANDARD_HEAD_POSITIONS]
[BODY_DETAIL_PLAN:HUMANOID_RIBCAGE_POSITIONS]
[USE_MATERIAL_TEMPLATE:SINEW:SINEW_TEMPLATE]
[TENDONS:LOCAL_CREATURE_MAT:SINEW:200]
[LIGAMENTS:LOCAL_CREATURE_MAT:SINEW:200]
[HAS_NERVES]
[USE_MATERIAL_TEMPLATE:BLOOD:BLOOD_TEMPLATE]
[BLOOD:LOCAL_CREATURE_MAT:BLOOD:LIQUID]
[CREATURE_CLASS:GENERAL_POISON]
[GETS_WOUND_INFECTIONS]
[GETS_INFECTIONS_FROM_ROT]
[USE_MATERIAL_TEMPLATE:PUS:PUS_TEMPLATE]
[PUS:LOCAL_CREATURE_MAT:PUS:LIQUID]
[BODY_APPEARANCE_MODIFIER:LENGTH:90:95:98:100:102:105:110]
[BODY_APPEARANCE_MODIFIER:HEIGHT:90:95:98:100:102:105:110]
[BODY_APPEARANCE_MODIFIER:BROADNESS:90:95:98:100:102:105:110]
[MAXAGE:10:20]
[ATTACK:KICK:BODYPART:BY_CATEGORY:HOOF_FRONT]
[ATTACK_SKILL:STANCE_STRIKE]
[ATTACK_VERB:kick:kicks]
[ATTACK_CONTACT_PERC:100]
[ATTACK_PREPARE_AND_RECOVER:4:4]
[ATTACK_PRIORITY:MAIN]
[ATTACK_FLAG_WITH]
[ATTACK_FLAG_BAD_MULTIATTACK]
[ATTACK:KICK:BODYPART:BY_CATEGORY:HOOF_REAR]
[ATTACK_SKILL:STANCE_STRIKE]
[ATTACK_VERB:kick:kicks]
[ATTACK_CONTACT_PERC:100]
[ATTACK_PREPARE_AND_RECOVER:4:4]
[ATTACK_PRIORITY:MAIN]
[ATTACK_FLAG_WITH]
[ATTACK_FLAG_BAD_MULTIATTACK]
[ATTACK:BITE:CHILD_BODYPART_GROUP:BY_CATEGORY:HEAD:BY_CATEGORY:TOOTH]
[ATTACK_SKILL:BITE]
[ATTACK_VERB:bite:bites]
[ATTACK_CONTACT_PERC:100]
[ATTACK_PENETRATION_PERC:100]
[ATTACK_FLAG_EDGE]
[ATTACK_PREPARE_AND_RECOVER:3:3]
[ATTACK_PRIORITY:SECOND]
[ATTACK_FLAG_CANLATCH][ATTACK:HGORE:BODYPART:BY_CATEGORY:HORN]
[ATTACK_SKILL:BITE]
[ATTACK_VERB:gore:gores]
[ATTACK_CONTACT_PERC:100]
[ATTACK_PREPARE_AND_RECOVER:3:3]
[ATTACK_FLAG_WITH]
[ATTACK_PRIORITY:MAIN]
[CREPUSCULAR]
[HOMEOTHERM:10067]
[APPLY_CREATURE_VARIATION:STANDARD_QUADRUPED_GAITS:900:438:292:146:1900:2900] 60 kph
[APPLY_CREATURE_VARIATION:STANDARD_SWIMMING_GAITS:9000:8900:8825:8775:9500:9900] 1 kph, NO DATA
[APPLY_CREATURE_VARIATION:STANDARD_CRAWLING_GAITS:9000:8900:8825:8775:9500:9900] 1 kph, NO DATA
[SWIMS_INNATE]
[MUNDANE]
[CASTE:FEMALE]
[FEMALE]
[MULTIPLE_LITTER_RARE]
[BODY_SIZE:0:0:19000]
[BODY_SIZE:1:0:75000]
[BODY_SIZE:2:0:220000]
[CASTE:MALE]
[MALE]
[BODY_SIZE:0:0:19000]
[BODY_SIZE:1:0:100000]
[BODY_SIZE:2:0:300000]
[SET_BP_GROUP:BY_TYPE:LOWERBODY][BP_ADD_TYPE:GELDABLE]
[SELECT_CASTE:ALL]
[[SET_TL_GROUP:BY_CATEGORY:ALL:HAIR]
[TL_COLOR_MODIFIER:CHESTNUT:1]
[TLCM_NOUN:hair:SINGULAR]
[SET_TL_GROUP:BY_CATEGORY:ALL:SKIN]
[TL_COLOR_MODIFIER:BROWN:1:BURNT_UMBER:1:CINNAMON:1:COPPER:1:DARK_BROWN:1:DARK_PEACH:1:DARK_TAN:1:ECRU:1:PALE_BROWN:1:PALE_CHESTNUT:1:PALE_PINK:1:PEACH:1:PINK:1:RAW_UMBER:1:SEPIA:1:TAN:1:TAUPE_PALE:1:TAUPE_SANDY:1]
[TLCM_NOUN:skin:SINGULAR]
[SET_TL_GROUP:BY_CATEGORY:EYE:EYE]
[TL_COLOR_MODIFIER:IRIS_EYE_BROWN:1]
[TLCM_NOUN:eyes:PLURAL]
[SELECT_MATERIAL:ALL]
[MULTIPLY_VALUE:3]
It's most likely a result of some structure that changed in 0.40.20 (in other words, a DFHack/df-structures problem).
cd library/xml
git checkout -b <descriptive branch name>
git add df.refs.xml
git commit -m 'Identify entity_site_link.civ_id, etc.'
git remote add <username (or another descriptive remote name)> https://github.com/<username>/df-structures # if you haven't already
git push <username (or remote name)> <branch name>
* Make a pull requeststartdwarf is not working for me, anybody else having this? I have some basic objects.txt edits, but in dfhack0.40.19 it worked fine,Right. start_dwarf_count has to be located in symbols.xml, and nobody did that for this release. There were a couple releases in the past where this was also the case. I'll try to make sure it's located in the next version (which'll probably be 0.40.24).
however there were times this happened before, and then fixed itself in the next release.
The plugin is disabled.
Autonestbox stopped.
Watches the numbers of seeds available and enables/disables seed and plant cooking.
Each plant type can be assigned a limit. If their number falls below,
the plants and seeds of that type will be excluded from cookery.
If the number rises above the limit + 20, then cooking will be allowed.
The plugin needs a fortress to be loaded and will deactivate automatically otherwise.
You have to reactivate with 'seedwatch start' after you load the game.
Options:
seedwatch all - Adds all plants from the abbreviation list to the watch list.
seedwatch start - Start watching.
seedwatch stop - Stop watching.
seedwatch info - Display whether seedwatch is watching, and the watch list.
seedwatch clear - Clears the watch list.
You can use these abbreviations for the plant tokens:
bs -> SLIVER_BARB
bt -> TUBER_BLOATED
bw -> WEED_BLADE
cw -> GRASS_WHEAT_CAVE
dc -> MUSHROOM_CUP_DIMPLE
fb -> BERRIES_FISHER
hr -> ROOT_HIDE
kb -> BULB_KOBOLD
lg -> GRASS_LONGLAND
mr -> ROOT_MUCK
pb -> BERRIES_PRICKLE
ph -> MUSHROOM_HELMET_PLUMP
pt -> GRASS_TAIL_PIG
qb -> BUSH_QUARRY
rr -> REED_ROPE
rw -> WEED_RAT
sb -> BERRY_SUN
sp -> POD_SWEET
vh -> HERB_VALLEY
ws -> BERRIES_STRAW_WILD
wv -> VINE_WHIP
Examples:
seedwatch MUSHROOM_HELMET_PLUMP 30
add MUSHROOM_HELMET_PLUMP to the watch list, limit = 30
seedwatch MUSHROOM_HELMET_PLUMP
removes MUSHROOM_HELMET_PLUMP from the watch list.
seedwatch ph 30
is the same as 'seedwatch MUSHROOM_HELMET_PLUMP 30'
seedwatch all 30
adds all plants from the abbreviation list to the watch list, the limit being 30.
Loading script at PyLNP_dfhack_onLoad.init
Enabling the plugin.
The plugin is enabled.
Option drybuckets is enabled.
Option auto-melt is enabled.
Fixed feeding timers for 0 citizens.
unstuck 0 doors
[DFHack]#
Why are you reporting a crash here when you're not using DFHack? A white box (which should be a readable error message) is almost certainly a raw problem, if DF starts up normally, so that should be reported in the thread of the graphics pack you're using. Also, what bugs are you referring to? I haven't noticed an unusual number of new bugs in 0.40.23, unless you're referring to the DFHack libstdc++ problem.Phoebus doesn't do OSX releases (he doesn't have the OS, I presume) so he wasn't able to do anything about it when I did report to him. I've noticed the complete absence of shellfish and vermin despite there being nothing wrong with their raws, crashing upon generating coin information, and this issue, and those are just the ones I can remember right now.
Tell me more about the libstdc++ problem. I have that file in my DF libs, and when I open it I get:Er, libstdc++ is a library, meaning that it's used by other programs (DF in this case) but does effectively nothing on its own. In fact, it's not even a valid executable. The libstdc++ in the DF/hack folder takes priority, but apparently isn't compatible with 10.6, so deleting it causes DF to use the older one (with the same name) in DF/libs.
Last login: Sat Jan 10 17:26:05 on ttys000
/Applications/df_osx/libs/libstdc++.6.dylib ; exit;
computer:~ emans002$ /Applications/df_osx/libs/libstdc++.6.dylib ; exit;
-bash: /Applications/df_osx/libs/libstdc++.6.dylib: cannot execute binary file
logout
[Process completed]
Try "gaydar".
You could always have just modified the orientation, you know.
[DFHack]# tiletypes
tiletypes> paint sh EMPTY
tiletypes> paint mat AIR
tiletypes>
Alternatively, "filter sh STAIR_UPDOWN" should apply to select up/down stairs, allowing you to use a larger brush.
Sheesh Meph, helping me all over the place XD Yes, that helps a lot. Thanks.There you go. :) All solved?
Edit: Quotes work! Two names are a go.
Sheesh Meph, helping me all over the place XD Yes, that helps a lot. Thanks.There you go. :) All solved?
Edit: Quotes work! Two names are a go.
So I've been trying to get two dwarves to marry via dfhack because they're taking too long, and I found a script to do so here (https://github.com/EldrickWT/My-Crazy-Dwarf-Fortress-Mods/blob/master/dfhack.40.06/scripts/marry.lua), which does exactly what I want to do. But there's a slight snag.
It keeps asking for a unit ID, and I have absolutely no idea what that is, and extensive googling has led me nowhere. I had a feeling it might have been the unit name (nada), the unit nickname (nope), the unit's memory address via dwarf therapist (again, nope), but nothing I've tried has worked.
Anyone know what a unit ID is? :p It's probably something extremely obvious that I'm missing out on, but I don't even know where to start on finding that thing.
EDIT : Tried using the names inside quotes, that didn't work either :(
./dfhack: line 43: 9279 Segmentation fault (core dumped) setarch i386 -R env LD_PRELOAD=$PRELOAD_LIB ./libs/Dwarf_Fortress "$@"
Unit ID is a name. It's unit.id in the structure. "teleport -showunitid" will show you the unit's Id.Tried that, but wierdly enough teleport gave me errors :o Dunno why, I was probably doing it wrong somehow, but...
Also, the way that scripts gets units from IDs is... awful. I mean, not as bad as my first tries, but still, awful. df.unit.find, come on :P
Hmmm, you should be able to see it with gm-editor, just be wary of changing things in there.This worked perfectly! :D
I don't have the means to get metal bars for a mooded dwarf, so I have createitem set to put items on the floor via createitem floor. Then when I run the actual createitem to spawn in the bars, it refuses to work saying "No unit selected" what do I do?Select a unit (then run createitem).
I don't have the means to get metal bars for a mooded dwarf, so I have createitem set to put items on the floor via createitem floor. Then when I run the actual createitem to spawn in the bars, it refuses to work saying "No unit selected" what do I do?There's also a create-items command that handles bars (and a few other things). I find it easier to use for the items it works for.
Yup, and is way easier than memorizing createitem stuff, though once you get used to doing it that way it feels weird scrolling through the hack-wish gui.
Seedwatch appears to not be working for a lot of the new plants, specifically the ones without edible seeds, I believe. Has anyone else had this issue?
Seedwatch appears to not be working for a lot of the new plants, specifically the ones without edible seeds, I believe. Has anyone else had this issue?
Correct me if I'm wrong, but isn't the main function of seedwatch to toggle cooking of a seed type based on how many of that seed type you have? Doesn't seem like it could reasonably apply to plants which lack edible seeds.
Seedwatch appears to not be working for a lot of the new plants, specifically the ones without edible seeds, I believe. Has anyone else had this issue?
Correct me if I'm wrong, but isn't the main function of seedwatch to toggle cooking of a seed type based on how many of that seed type you have? Doesn't seem like it could reasonably apply to plants which lack edible seeds.
What is the code to spawn in cloth? Specifically Cave Spider silk cloth. I need it for a mooded dwarf -3-I'm not sure what you mean by "code" or "spawn in" - if you're referring to the createitem command, there's a page on the wiki (http://dwarffortresswiki.org/index.php/Utility:DFHack/createitem#Cloth.2Fleather) that gives some examples. (Note that all of them need to be preceded with "createitem ".)
Do SDL.dll and SDLreal.dll both exist in the DF folder (and are they different)? You need to copy over both of those files from the DFHack package on Windows in order for DFHack to work.
Size.
What are you trying to avoid about reinstalling? Do you have custom scripts? It shouldn't overwrite them unless they have the same name as scripts in DFHack.
Well, you have to replace DF's copy of SDL.dll with the one distributed by DFHack. If you've already downloaded DFHack, it should only be a matter of copying over the file.
I can't replace just that because I can't open .7z files the same way I can open .zip files. It's not a folder or a pseudo-folder; the files are inaccessible. I have no choice but to extract it all at once, picking and choosing files is not an option.If the DFHack window is opening at all, replacing the DLL won't fix it. But maybe that was a console window from dfhack-run or something, so it's worth trying a re-install.
Thanks for the help everyone.
I can't replace just that because I can't open .7z files the same way I can open .zip files. It's not a folder or a pseudo-folder; the files are inaccessible. I have no choice but to extract it all at once, picking and choosing files is not an option.If the DFHack window is opening at all, replacing the DLL won't fix it. But maybe that was a console window from dfhack-run or something, so it's worth trying a re-install.
Thanks for the help everyone.
You should be able to extract everything on top of the current install, which won't use up any additional space (once the tempfiles clear). You can rename the two SDL files to ensure that they're out of the way. Once things are running properly, go ahead and delete the renamed files.
Question about DFHack:
What does it mean when a creature will marry one sex but "likes" the other? Does "like" refer to a lovers' relationship that never progresses?
I'm not really sure how your archive manager works, but the one I'm used to extracts to a new folder by default (i.e. not "over" an existing folder). Could you try this and copy over the two .dll files? (Replacing SDL.dll, as well as copying any other files/folders you haven't already.)Well, you have to replace DF's copy of SDL.dll with the one distributed by DFHack. If you've already downloaded DFHack, it should only be a matter of copying over the file.
I can't replace just that because I can't open .7z files the same way I can open .zip files. It's not a folder or a pseudo-folder; the files are inaccessible. I have no choice but to extract it all at once, picking and choosing files is not an option.
Thanks for the help everyone.
Hi to every one, I tried to use latest df hack version (40.23) with df 40.24 but it crashes every time I start the game, how did you solve the issue in order to play df 40.24 with df hack?Don't.
Hi to every one, I tried to use latest df hack version (40.23) with df 40.24 but it crashes every time I start the game, how did you solve the issue in order to play df 40.24 with df hack?Don't.
Use version that is supported (e.g. if it's called dfhack 0.40.23-r1 it should be used with df 0.40.23)
Can i use createitem to create a CAGE with a specificed animal/creature inside?
OMG SO CLOSE, EXCITE TIME IS NEAR, it actually starts up and everything properly, still missing some globals though:Spoiler (click to show/hide)
Still, the fact that it didn't just crash or load df without dfhack is good right?
Compiled and built the dev branch, arch linux, df 40.24, updated the symbols.xml with the one on newer commit, I think the globals was already the most up to date one but still damn close, awesome work!
Hi to every one, I tried to use latest df hack version (40.23) with df 40.24 but it crashes every time I start the game, how did you solve the issue in order to play df 40.24 with df hack?
Hmmm, I have no idea how buggy it could be, but there is a name entry accessible with gm-editor.
Well, good news is, the first name can be edited really easily...
The bad news is, the rest of the name requires you to know the numbers corresponding to the words used in game.
(http://i.imgur.com/2AXgzNA.png)
Ebsas (Candy) is her first name, but then Adoredeath, and her title, are represented under the words/parts of speech tags and it's like 7 entries that just list the numbers, I think it was like 1768 for "Adore" as a guess...
I don't know if DFHack is the right place to make the requestion, but I'm wondering if anybody has done any sort of family tree helper?
I often like to at least give married couples the same nickname so I can give them the same job roles and help manage bedrooms and such. In my latest fort it seems like all my migrants are brothers/sisters/aunts/uncles/cousins or something and I can't hope to keep track of it all with the DF interface.
Does anybody know of something that helps address this problem statement?
Seedwatch appears to not be working for a lot of the new plants, specifically the ones without edible seeds, I believe.
DFHack should deactivate, not crash, if it doesn't recognize the DF version (that's how it works on OS X and Linux, at least).
Anyway, here (https://github.com/lethosor/df-structures/blob/0.40.24-linux-offsets/symbols.xml) is a copy of symbols.xml with Linux offsets for 0.40.24. You'll want to compile with the latest commit in dfhack/df-structures (2f1a0f8455814aa844e2461f834e4e9faf5f8831), since there were a number of structure changes made (or noticed) since 0.40.23.
,d88b.d88b,
88888888888
`Y8888888Y'
`Y888Y'
`Y'
So is the dev version stable on linux 40_24? If yes any reason not to upload it?
So is the dev version stable on linux 40_24? If yes any reason not to upload it?There are still several Windows offsets missing.
"libprotoc.so: undefined reference to pthread_once"
collect2: error: ld returned 1 exit status
make[2]: *** [depends/protobuf/protoc] Fehler 1
make[1]: *** [depends/protobuf/CMakeFiles/protoc-bin.dir/all] Fehler 2
(Fehler = error)It was actually txtsd who found those offsets - I just added them to the right places in symbols.xml.
Edit: Solved it. I deleted everything in /build and compiled again, which worked out fine. A million warnings but no errors.If you're using a newer version of GCC, the "struct is too small"-type warnings are expected.
Are you using a graphics set?Nope, just a tileset with minor d_init.txt edits for trees and Pillar tile.
Yes it builds and run but almost all plugins won't load due to missing offsets, if that counts as an issue.
I've been testing Lethosor df-structures update and it works well, haven't found any issue.
Yes it builds and run but almost all plugins won't load due to missing offsets, if that counts as an issue.
I've been testing Lethosor df-structures update and it works well, haven't found any issue.
cannot open ~/df_40_24/data/save/region1/raw/init.lua: file or folder not found
error/warning? I get it with all DFHack releases iirc even in 34.11. I think putting an empty file there helps but what's the reason of this warning?
What platform are you using? I've only located offsets for OS X and Linux (they're on different branches at the moment), and there aren't any missing besides debug flags and start_dwarf_count (which is on another branch, also for OS X and Linux only as the script to find it isn't working with the Windows version).Yes it builds and run but almost all plugins won't load due to missing offsets, if that counts as an issue.
I've been testing Lethosor df-structures update and it works well, haven't found any issue.
Yes, the plugins except twbt load.Never seen it. What platform are you using?
On another note, am i the only one who gets theCode: [Select]cannot open ~/df_40_24/data/save/region1/raw/init.lua: file or folder not found
error/warning? I get it with all DFHack releases iirc even in 34.11. I think putting an empty file there helps but what's the reason of this warning?
Any plans for multiple onLoad.init files?What do you mean, exactly? You can already use per-save onLoad.init files, as well as a global onLoadWorld.init. If you want to load another file from within those, you can use the "script" command.
Any plans for multiple onLoad.init files?What do you mean, exactly? You can already use per-save onLoad.init files, as well as a global onLoadWorld.init. If you want to load another file from within those, you can use the "script" command.
I think there's a command to read in a blah.init file and execute it but I forget how.
Yes, the plugins except twbt load.Never seen it. What platform are you using?
On another note, am i the only one who gets theCode: [Select]cannot open ~/df_40_24/data/save/region1/raw/init.lua: file or folder not found
error/warning? I get it with all DFHack releases iirc even in 34.11. I think putting an empty file there helps but what's the reason of this warning?
Edit: It looks like that message is only suppressed if the error message contains "No such file or directory", which isn't a very portable way of handling it.
cannot open /home/solis/Spiele/df_40_24/data/save/region3/raw/init.lua: Datei oder Verzeichnis nicht gefunden
I had this message on Windows and now on GNU/Linux. Since it hasn't been progressing, I've attempted to find some offsets myself, but I can't figure out how to translate the offsets in symbols.xml to addresses. When I take the base address of "Dwarf Fortress.exe" + offset, I just end up in empty memory or something else that obviously isn't right. I'm using Cheat Engine.IIRC the offsets in symbols.xml might be for binary file so they could be offset by 0x400000. In cheat engine that might look like "Dwarf Fortress.exe" + offset-0x400000
Since it hasn't been progressing, I've attempted to find some offsets myself, but I can't figure out how to translate the offsets in symbols.xml to addresses. When I take the base address of "Dwarf Fortress.exe" + offset, I just end up in empty memory or something else that obviously isn't right. I'm using Cheat Engine.
No, they're memory offsets. You might want to try +0x400000 (on Windows) if cheat engine is using file offsets.Since it hasn't been progressing, I've attempted to find some offsets myself, but I can't figure out how to translate the offsets in symbols.xml to addresses. When I take the base address of "Dwarf Fortress.exe" + offset, I just end up in empty memory or something else that obviously isn't right. I'm using Cheat Engine.IIRC the offsets in symbols.xml might be for binary file so they could be offset by 0x400000. In cheat engine that might look like "Dwarf Fortress.exe" + offset-0x400000
It does, but some offsets that are found with df_misc scripts on OS X and Linux have to be found manually on Windows (such as created_item_type, IIRC).Since it hasn't been progressing, I've attempted to find some offsets myself, but I can't figure out how to translate the offsets in symbols.xml to addresses. When I take the base address of "Dwarf Fortress.exe" + offset, I just end up in empty memory or something else that obviously isn't right. I'm using Cheat Engine.
Does the Windows version of dfhack not have `devel/find-offsets`?
I think the request was some way to automatically hoover up on-load scripts that come with mods, so the player doesn't need to stitch them together manually. This might simplify mod merging.Any plans for multiple onLoad.init files?What do you mean, exactly? You can already use per-save onLoad.init files, as well as a global onLoadWorld.init. If you want to load another file from within those, you can use the "script" command.I think there's a command to read in a blah.init file and execute it but I forget how.
What he said. It's the "script" command.
df.global.world.entities.all:insert(0, {new=true, type=1, id=df.global.entity_next_id})
DF crashes when saving the world. When I addentity_raw=another_entity.entity_raw
to the new entity, it saves, but DF crashes when gets to the "Loading civilized populations" part of loading the world.
I think the request was some way to automatically hoover up on-load scripts that come with mods, so the player doesn't need to stitch them together manually. This might simplify mod merging.
I'm picturing this as a standard bit in DFHack's onload script that runs every file in the raw/scripts folder that matches a specific filename pattern, maybe onload_*.lua|onload_*.rb. It should be deterministically before or after the onload.init script at the root of raw. Or put it in the raw/onload.init file, but I think the feature would be more user-proof if it functioned with the main file missing.
How can I create a new entity in DFHack? When I tryCode: [Select]df.global.world.entities.all:insert(0, {new=true, type=1, id=df.global.entity_next_id})
DF crashes when saving the world. When I addCode: [Select]entity_raw=another_entity.entity_raw
to the new entity, it saves, but DF crashes when gets to the "Loading civilized populations" part of loading the world.
A starter pack's mod manager could in principle merge the scripts together, so yes this would be aimed at players throwing random and/or homebrewed mods together. But it would also make the mod manager's job easier.I think the request was some way to automatically hoover up on-load scripts that come with mods, so the player doesn't need to stitch them together manually. This might simplify mod merging.
I'm picturing this as a standard bit in DFHack's onload script that runs every file in the raw/scripts folder that matches a specific filename pattern, maybe onload_*.lua|onload_*.rb. It should be deterministically before or after the onload.init script at the root of raw. Or put it in the raw/onload.init file, but I think the feature would be more user-proof if it functioned with the main file missing.
I'll add it to the list.
Is the goal to make it easier for homebrewed combinations of mods?
One problem is it looks like you aren't updating entity_next_id.Now I do update df.global.entity_next_id, but it still has the same problem. I tried making a new population and adding its id to the new entity’s populations, but that didn’t work either.
[...]
edit: Never mind. entity_raw is probably the one you can't create more of and making new entities is fine.
dfhack.gui.makeAnnouncement(type,flags,pos,text,color[,is_bright])
anddfhack.gui.addCombatReport(unit,slot,report_index)
dfhack.run_script('unit/body-change -unit 3399 -temperature fire -all')
Is not working, it saysC:\Users\Miles\Desktop\My_DF2\hack\lua\dfhack.lua:410: Could not find script uni
t/body-change -unit 3399 -temperature fire -all
stack traceback:
[C]: in function 'error'
C:\Users\Miles\Desktop\My_DF2\hack\lua\dfhack.lua:410: in function 'run_
script'
(interactive):1: in main chunk
[C]: in function 'safecall'
C:\Users\Miles\Desktop\My_DF2\hack\lua\dfhack.lua:366: in function 'inte
rpreter'
C:\Users\Miles\Desktop\My_DF2\hack\scripts/lua.lua:47: in main chunk
(...tail calls...)
Note that putting that exact string into the command line works fine.old = df.global.world.entities.all[0]
new = old:new()
new.id = entity_next_id
new.type = 1
blah
blah
blah
I'm trying to add announcements and combat log text to my scripts, I looked through the API and foundCode: [Select]dfhack.gui.makeAnnouncement(type,flags,pos,text,color[,is_bright])
andCode: [Select]dfhack.gui.addCombatReport(unit,slot,report_index)
But I am unsure what the type, flags, and slot should all be for a given announcement (also pos?). Anyone have any examples or a list of what the valid entries are?
I think the request was some way to automatically hoover up on-load scripts that come with mods, so the player doesn't need to stitch them together manually. This might simplify mod merging.
I'm picturing this as a standard bit in DFHack's onload script that runs every file in the raw/scripts folder that matches a specific filename pattern, maybe onload_*.lua|onload_*.rb. It should be deterministically before or after the onload.init script at the root of raw. Or put it in the raw/onload.init file, but I think the feature would be more user-proof if it functioned with the main file missing.
I'll add it to the list.
Is the goal to make it easier for homebrewed combinations of mods?
dfhack.run_command('script',SAVE_PATH..'/raw/fortbent_onload.init')
EDIT2: @Gorobay, I'm pretty sure its because you have a lot of fields that are left undefined if you just make a new one with type and id.I wrote the following script as a test:
local old = df.global.world.entities.all[0]
local new = old:new()
new.id = df.global.entity_next_id
new.type = 1
df.global.world.entities.all:insert('#', new)
The game crashes when I exit the current mode and offload the world.Is there any simple way of getting the products of a reaction that is linked to a LUA_HOOK function? The example function includes output_items as a parameter, but as far as I can tell it is always empty
function upgradeitem(reaction,unit,input_items,input_reagents,output_items,call_native)
local ptype = reaction.products[0].mat_type
local pindx = reaction.products[0].mat_index
local product = dfhack.matinfo.decode(ptype,pindx)
local args = {}
for i,x in ipairs(product.material.syndrome[0].syn_class) do
args[i] = x.value
end
local dur = 0
if #args == 2 then dur = tonumber(args[2]) end
local sitems = {}
if args[0] == 'this' then
-- Upgrade only the input items with preserve reagent
for i,x in ipairs(input_reagents) do
if x.flags.PRESERVE_REAGENT then sitems[i] = input_items[i] end
end
elseif args[0] == 'all' then
-- Upgrade all items of the same type as input
local itemList = df.global.world.items.all
local k = 1
for j,y in ipairs(input_reagents) do
if y.flags.PRESERVE_REAGENT then
for i,x in ipairs(itemList) do
if itemSubtypes(x) then
if x.subtype.id == y.subtype.id then
sitems[k] = itemList[i]
k = k + 1
end
end
end
end
end
else
-- Randomly upgrade one specific item
local itemList = df.global.world.items.all
local k = 1
for j,y in ipairs(input_reagents) do
if y.flags.PRESERVE_REAGENT then
for i,x in ipairs(itemList) do
if itemSubtypes(x) then
if x.subtype.id == y.subtype.id then
sitems[k] = itemList[i]
k = k + 1
end
end
end
end
end
local rando = dfhack.random.new()
sitems = {sitems[rando:random(#sitems)]}
end
if args[1] == 'upgrade' then
-- Increase items number by one
for _,x in ipairs(sitems) do
local name = x.subtype.id
if dur > 0 then sid = x.subtype.subtype end
local namea = split(name,'_')
local num = tonumber(namea[#namea])
num = num + 1
namea[#namea] = tostring(num)
name = table.concat(namea,'_')
item_index = itemSubtypes(x)
for i=0,dfhack.items.getSubtypeCount(item_index)-1,1 do
item_sub = dfhack.items.getSubtypeDef(item_index,i)
if item_sub.id == name then x:setSubtype(item_sub.subtype) end
end
if dur > 0 then dfhack.timeout(dur,'ticks',createcallback(x,sid)) end
end
elseif args[1] == 'downgrade' then
-- Decrease items number by one
for _,x in ipairs(sitems) do
local name = x.subtype.id
if dur > 0 then sid = x.subtype.subtype end
local namea = split(name,'_')
local num = tonumber(namea[#namea])
num = num - 1
if num > 0 then namea[#namea] = tostring(num) end
name = table.concat(namea,'_')
item_index = itemSubtypes(x)
for i=0,dfhack.items.getSubtypeCount(item_index)-1,1 do
item_sub = dfhack.items.getSubtypeDef(item_index,i)
if item_sub.id == name then x:setSubtype(item_sub.subtype) end
end
if dur > 0 then dfhack.timeout(dur,'ticks',createcallback(x,sid)) end
end
else
-- Change item to new item
for _,x in ipairs(sitems) do
if dur > 0 then sid = x.subtype.subtype end
item_index = itemSubtypes(x)
for i=0,dfhack.items.getSubtypeCount(item_index)-1,1 do
item_sub = dfhack.items.getSubtypeDef(item_index,i)
if item_sub.id == args[1] then x:setSubtype(item_sub.subtype) end
end
if dur > 0 then dfhack.timeout(dur,'ticks',createcallback(x,sid)) end
end
end
end
-- START Taken from hire-guard.lua
local eventful = require 'plugins.eventful'
local utils = require 'utils'
function string.starts(String,Start)
return string.sub(String,1,string.len(Start))==Start
end
dfhack.onStateChange.loadUpgradeItem = function(code)
local registered_reactions
if code==SC_MAP_LOADED then
--registered_reactions = {}
for i,reaction in ipairs(df.global.world.raws.reactions) do
-- register each applicable reaction (to avoid doing string check
-- for every lua hook reaction (not just ours), this way uses identity check
if string.starts(reaction.code,'LUA_HOOK_UPGRADE_ITEM') then
-- register reaction.code
eventful.registerReaction(reaction.code,upgradeitem)
-- save reaction.code
--table.insert(registered_reactions,reaction.code)
registered_reactions = true
end
end
--if #registered_reactions > 0 then print('HireGuard: Loaded') end
if registered_reactions then print('Upgradable Items: Loaded') end
elseif code==SC_MAP_UNLOADED then
--[[ doesn't seem to be working, and probably not needed
registered_reactions = registered_reactions or {}
if #registered_reactions > 0 then print('HireGuard: Unloaded') end
for i,reaction in ipairs(registered_reactions) do
-- un register each registered reaction (to prevent persistance between
-- differing worlds (probably irrelavant, but doesn't hurt)
-- un register reaction.code
eventful.registerReaction(reaction.code,nil)
end
registered_reactions = nil -- clear registered_reactions
--]]
end
end
-- if dfhack.init has already been run, force it to think SC_WORLD_LOADED to that reactions get refreshed
if dfhack.isMapLoaded() then dfhack.onStateChange.loadUpgradeItem(SC_MAP_LOADED) end
-- END Taken from hire-guard.lua
EDIT2: @Gorobay, I'm pretty sure its because you have a lot of fields that are left undefined if you just make a new one with type and id.I wrote the following script as a test:Code: [Select]local old = df.global.world.entities.all[0]
The game crashes when I exit the current mode and offload the world.
local new = old:new()
new.id = df.global.entity_next_id
new.type = 1
df.global.world.entities.all:insert('#', new)
I have found reading the source code (https://github.com/DFHack/dfhack/blob/master/library/modules/Gui.cpp) helpful for determining what the GUI functions do. The slot parameter of addCombatReport must be 0, 1, or 2 for combat, hunting, or sparring.
Is there any simple way of getting the products of a reaction that is linked to a LUA_HOOK function? The example function includes output_items as a parameter, but as far as I can tell it is always empty
reaction.products
Is there any simple way of getting the products of a reaction that is linked to a LUA_HOOK function? The example function includes output_items as a parameter, but as far as I can tell it is always empty
reaction.products
Not that, that's the data from the reaction's object. I want the actual items produced from the reaction.
I'm trying to make a function that runs after a particular reaction that produces a tool. I want the function to run some script and then set the 'maker' field of the tool to a certain number based on that script. How would I go about doing that?
Code: [Select]dfhack.run_script('unit/body-change -unit 3399 -temperature fire -all')
Is not working, it saysCode: [Select]C:\Users\Miles\Desktop\My_DF2\hack\lua\dfhack.lua:410: Could not find script uni
Note that putting that exact string into the command line works fine.
t/body-change -unit 3399 -temperature fire -all
stack traceback:
[C]: in function 'error'
C:\Users\Miles\Desktop\My_DF2\hack\lua\dfhack.lua:410: in function 'run_
script'
(interactive):1: in main chunk
[C]: in function 'safecall'
C:\Users\Miles\Desktop\My_DF2\hack\lua\dfhack.lua:366: in function 'inte
rpreter'
C:\Users\Miles\Desktop\My_DF2\hack\scripts/lua.lua:47: in main chunk
(...tail calls...)
Is there any simple way of getting the products of a reaction that is linked to a LUA_HOOK function? The example function includes output_items as a parameter, but as far as I can tell it is always empty
reaction.products
Not that, that's the data from the reaction's object. I want the actual items produced from the reaction.
I'm trying to make a function that runs after a particular reaction that produces a tool. I want the function to run some script and then set the 'maker' field of the tool to a certain number based on that script. How would I go about doing that?
Ah, I see what you mean. I misunderstood. As far as I know output_items should be what you want. If it isn't then I am of no help.
You might also have to change the value of save_file_id. Also I'm not sure if its going to freak out over having duplicate events and such.Looks like it still freaks out: setting the save_file_id to 1 + the maximum of all other save_file_ids didn’t fix it. Maybe I can work around this using dfhack.persistent.
You might also have to change the value of save_file_id. Also I'm not sure if its going to freak out over having duplicate events and such.Looks like it still freaks out: setting the save_file_id to 1 + the maximum of all other save_file_ids didn’t fix it. Maybe I can work around this using dfhack.persistent.
A starter pack's mod manager could in principle merge the scripts together, so yes this would be aimed at players throwing random and/or homebrewed mods together. But it would also make the mod manager's job easier.I think the request was some way to automatically hoover up on-load scripts that come with mods, so the player doesn't need to stitch them together manually. This might simplify mod merging.
I'm picturing this as a standard bit in DFHack's onload script that runs every file in the raw/scripts folder that matches a specific filename pattern, maybe onload_*.lua|onload_*.rb. It should be deterministically before or after the onload.init script at the root of raw. Or put it in the raw/onload.init file, but I think the feature would be more user-proof if it functioned with the main file missing.
I'll add it to the list.
Is the goal to make it easier for homebrewed combinations of mods?
Yeah I am not sure about adding an entity. But what are you trying to do? There may be other ways to handle it.I am trying to add proper linguistics to the game. I was representing languages as entities, so that historical figures could have links to languages they knew, and civilizations could have links to their default languages. It worked perfectly, except for the crashing. Anything that allows such links would work; I think I might try sites next.
No, they're memory offsets. You might want to try +0x400000 (on Windows) if cheat engine is using file offsets.
IIRC the offsets in symbols.xml might be for binary file so they could be offset by 0x400000. In cheat engine that might look like "Dwarf Fortress.exe" + offset-0x400000
A starter pack's mod manager could in principle merge the scripts together, so yes this would be aimed at players throwing random and/or homebrewed mods together. But it would also make the mod manager's job easier.I think the request was some way to automatically hoover up on-load scripts that come with mods, so the player doesn't need to stitch them together manually. This might simplify mod merging.
I'm picturing this as a standard bit in DFHack's onload script that runs every file in the raw/scripts folder that matches a specific filename pattern, maybe onload_*.lua|onload_*.rb. It should be deterministically before or after the onload.init script at the root of raw. Or put it in the raw/onload.init file, but I think the feature would be more user-proof if it functioned with the main file missing.
I'll add it to the list.
Is the goal to make it easier for homebrewed combinations of mods?
Regardless, I'll need to add some special-casing to the mod merger, since it currently skips anything not ending in '.txt'.
The easiest way will simply be to test for file ending '.init', '.lua', or '.rb' and spoof an empty file as the vanilla text; and the usual merge logic can then combine the files. Multiple files will be combined, per the usual merge logic, with no change if they're identical.
I might be reading that wrong, but isn't that already done with an init.d subfolder loading all lua files there on save load?
It is worth extending that to rb and init files so you can add reaction triggers easily.
Good point, what I originally proposed was Lua/Ruby scripts, but what I really meant was init files with DFHack commands. Each mod can have its own init file that registers reactions, etc. Since an init file can call scripts easily, it's probably best to process only init files automatically.
I might be reading that wrong, but isn't that already done with an init.d subfolder loading all lua files there on save load?
It is worth extending that to rb and init files so you can add reaction triggers easily.
Right now that only works for Lua and Ruby scripts, not for dfhack commands like dfhack.init.
No, there are good reasons to have an init.d/*.lua or init.lua file. The onUnload() function is necessary for me to avoid a crash upon starting a second new game in Fortbent, for example.Sheesh I'm unclear today. No good would come from removing the existing feature to auto-run Lua. I was trying to clarify that a way to auto-run .init files would be helpful if mods could seamlessly add to the onload queue without physically merging the onload.init file at the root of raw. So kind of what I said above, except that it runs each ./scripts/*.init either just before or just after the ./onload.init file.
I used reveal, saved while reveal was on, loaded the save, and now cannot unreveal. Is this intended, or is there a workaround?I don't remember if it's a known bug/feature, but the workaround is to use revflood.
Thanks friend! Worked as desired.I used reveal, saved while reveal was on, loaded the save, and now cannot unreveal. Is this intended, or is there a workaround?I don't remember if it's a known bug/feature, but the workaround is to use revflood.
Why r0?
New release!Post #2000! Nice!
New release!Yessss! Thank you!
I'm testing on Windows, seems to work well enough. Plugins "search", "sort", "strangemood" and "zone" have missing globals.Are you sure those are the only ones with missing globals (not just the only ones visible in the console)?
nanoforts are now an astonishing and full featuredWhat do you mean? Toady is the only one that had anything to do with the addition of that option in vanilla DF.
possibility, many thanks to everyone involved!
Those are the ones visible in the console. I didn't test anything except what gets loaded by default.I'm testing on Windows, seems to work well enough. Plugins "search", "sort", "strangemood" and "zone" have missing globals.Are you sure those are the only ones with missing globals (not just the only ones visible in the console)?
why wasnt there communication with Toady prior to release of .24? to prevent month long delays in the releasing of utilities..are you guys not on speaking terms anymore?
Have you tried scrolling up?Those are the ones visible in the console. I didn't test anything except what gets loaded by default.I'm testing on Windows, seems to work well enough. Plugins "search", "sort", "strangemood" and "zone" have missing globals.Are you sure those are the only ones with missing globals (not just the only ones visible in the console)?
why wasnt there communication with Toady prior to release of .24? to prevent month long delays in the releasing of utilities..are you guys not on speaking terms anymore?I found addresses for OS X and Linux a few weeks or so ago. We were waiting for some Windows offsets, which I don't know how to find and have no way to test.
Have you tried scrolling up?Yes, those are the ones visible when the dfhack window is scrolled to the top. Did you expect more plugins to have problems?
Yeah, there was never communication with Toady prior to any release.
I found addresses for OS X and Linux a few weeks or so ago. We were waiting for some Windows offsets, which I don't know how to find and have no way to test.
Also, I sometimes hear about releases before they happen from Toady (or when he's planning another long release cycle). That doesn't help memory research at all, as it requires an actual executable.
Yeah, there was never communication with Toady prior to any release.I found addresses for OS X and Linux a few weeks or so ago. We were waiting for some Windows offsets, which I don't know how to find and have no way to test.
Also, I sometimes hear about releases before they happen from Toady (or when he's planning another long release cycle). That doesn't help memory research at all, as it requires an actual executable.
Would it even help to have Toady export some debugging report from his compiler to catalog the offsets? At some level, Toady's compiler already knows where everything is. Obviously he's under no obligation to help, but it's a much much simpler thing than the API idea that keeps coming up from time to time.
Toady's been burned by things like this before (though not really with any real effects, AFAIK).Can't wade through 23 pages of posts, but since DFHack is still here I'm assuming Toady is okay with it.
It was a long time ago, but the topic's still around (http://www.bay12forums.com/smf/index.php?topic=58796.0), so I figure it shouldn't be too odd to link to it. You may understand why Toady is wary of releasing too much.
Toady's been burned by things like this before (though not really with any real effects, AFAIK).Can't wade through 23 pages of posts, but since DFHack is still here I'm assuming Toady is okay with it.
It was a long time ago, but the topic's still around (http://www.bay12forums.com/smf/index.php?topic=58796.0), so I figure it shouldn't be too odd to link to it. You may understand why Toady is wary of releasing too much.
There are two distinct questions: (1) Is it simple for Toady to generate the dubug info at compile-time, and (2) Would this be helpful to the DFHack folks? You need a "Hell yes!" to both of those before even broaching the subject with him. Whatever the report is, it will almost certainly be shared privately with hand-picked people.
Full debug info would make reverse-engineering very easy - something that Toady doesn't want (and we don't need). We need only data structures, and I don't know how to export them alone.That answers my question... so it's hard to export something useful without giving away everything. That's a shame.
Has start_dwarf_count not been located yet for 40.24-r0? I know it never was on 40.23. It's not working for me on Windows.It's been located on OS X and Linux. I tried to locate it on Windows, but the script to do so seems to break when analyzing the 0.40.24 Windows (SDL) executable.
Has start_dwarf_count not been located yet for 40.24-r0? I know it never was on 40.23. It's not working for me on Windows.It's been located on OS X and Linux. I tried to locate it on Windows, but the script to do so seems to break when analyzing the 0.40.24 Windows (SDL) executable.
Good news! Quietust found the remaining offsets, now we just need expwnent to update the main repo with them.
Quietust has located the remaining offsets, so that should work in r1.
r1 is up for Windows.Praise the DFHackers for their incredibly useful way of praising the Toad!
I have a furniture stockpile set to Automelt and the two Copperchests
OSX | DFHack 0.40.24-r1 (https://www.dropbox.com/s/h9j25bfdinqxbua/dfhack-0.40.24-r1-OSX.zip?dl=0)I've been marking chests for melting manually on and off for a while now. Since there are non in my smelters (and also not in the Stockpile) it seems to be working.I have a furniture stockpile set to Automelt and the two CopperchestsI'm pretty sure chests cannot be melted at all. Long time DF bug. (http://dwarffortresswiki.org/index.php/23a:Known_bugs_and_issues#Unmeltable_Chests) This link is from 23a, but the bug was still in 34.11 and haven't heard from it being fixed since.
Nope. Supposed to be fixed in 40.05 (http://www.bay12games.com/dwarves/mantisbt/view.php?id=2493). Can you test chest melting without automelt?
If you're selecting the units with [k], that is to be expected. The reason that this release is named r0 is because several offsets are missing on Windows, causing many things (such as that) to fail to work properly. Quietust has located the remaining offsets, so that should work in r1.Yupp, fixed whit the new version.
diff --git a/scripts/hfs-pit.lua b/scripts/hfs-pit.lua
index 9592d0a..b9e4760 100644
--- a/scripts/hfs-pit.lua
+++ b/scripts/hfs-pit.lua
@@ -20,7 +20,7 @@ wallOff = tonumber(args[2])
stairs = tonumber(args[3])
--Get the layer of the underworld
-for index,value in ipairs(df.global.world.cur_savegame.map_features) do
+for index,value in ipairs(df.global.world.features.map_features) do
local featureType=value:getType()
if featureType==9 then --Underworld
underworldLayer = value.layer
On the same note...
How do we track an adventurer's position in the world?
Also is it possible to teleport the adventurer to arbitary locations?
hfs-pit.lua wasn't working, this fixes it.Code: [Select]diff --git a/scripts/hfs-pit.lua b/scripts/hfs-pit.lua
index 9592d0a..b9e4760 100644
--- a/scripts/hfs-pit.lua
+++ b/scripts/hfs-pit.lua
@@ -20,7 +20,7 @@ wallOff = tonumber(args[2])
stairs = tonumber(args[3])
--Get the layer of the underworld
-for index,value in ipairs(df.global.world.cur_savegame.map_features) do
+for index,value in ipairs(df.global.world.features.map_features) do
local featureType=value:getType()
if featureType==9 then --Underworld
underworldLayer = value.layer
The short answer: It don't work no more and I have no idea how I could make it work. Armies are weird.
The long answer: ARMIES ARE WEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEIRD
On the same note...
How do we track an adventurer's position in the world?
Also is it possible to teleport the adventurer to arbitary locations?
Yes, yes it is. army.unk_pos1 actually seems to represent a proper world position.
EDIT: But the adventurer apparently ceases to be a proper army the instant they leave city limits. Still, my poor adventurer ended up in a jungle halfway to the western border of a large world.
dfhack.onStateChange.whatever=function(code)
if code==SC_MAP_LOADED then
dfhack.run_command('deramp') --you can replace 'deramp' with whatever
end
end
the idea of armies moving around while your in fort mode means there's a chance for fort mode to go borderless, and allow the player to 'scroll' from one site to another.
Is it possible to get the exact material of a tile from a lua script?
Anyone? I asked before elsewhere and was ignored there too (a long time ago), could I at least get a yes or no?
I'm not sure if it is possible to get exact material (it should be, but I'm not aware how to do it). I do have a script that changes a tile to a specific inorganic (but it has some issues recognizing ramps and open grass and etc...)
The relevant code isCode: [Select]function findMineralEv(block,inorganic) -- Taken from Warmist's constructor.lua
You'll notice that the heart of it comes from Warmist, so he would probably be a better person to ask than me.
for k,v in pairs(block.block_events) do
if df.block_square_event_mineralst:is_instance(v) and v.inorganic_mat==inorganic then
return v
end
end
end
function set_vein(x,y,z,mat) -- Taken from Warmist's constructor.lua
local b=dfhack.maps.ensureTileBlock(x,y,z)
local ev=findMineralEv(b,mat.index)
if ev==nil then
ev=df.block_square_event_mineralst:new()
ev.inorganic_mat=mat.index
ev.flags.vein=true
b.block_events:insert("#",ev)
end
dfhack.maps.setTileAssignment(ev.tile_bitmask,math.fmod(x,16),math.fmod(y,16),true)
end
function changeType(x,y,z,material,dur)
local mat
if material ~= 'clear' then
mat = dfhack.matinfo.find(material)
set_vein(x,y,z,mat)
else
clear_vein(x,y,z)
end
end
I am trying to bring back summoning using spawnunit, finding a 0.40x version from Rumrusher. It's all fine when I run it, the creature even appear in the animal screen, sometimes. (I need to locate this screen but nvm).When I converted the inhabitants of a reclaim (due to being stupid and forgetting to check under tweak for makeown) I had to toggle flags2 > resident to false, they became friendly at that point, and after doing the civ id/cultural id/pop id to the same as my dorfs they were fully controllable.
However if I save and reload, the creature becomes hostile despite belonging to the civilization. I tried comparing it with a normal pet using gm-editor but I could not figure what's different. The civ_id is right, population is set to -1 as expected.
Here's the script, it's pretty much the same that Rumrusher posted:
https://gist.github.com/Devduweb/9299841e7169445f8cce
I tried commenting the nemesis creation call but the result is the same. Any idea of how I can make sure that df remember the creature being friendly? Thanks.
I am trying to bring back summoning using spawnunit, finding a 0.40x version from Rumrusher. It's all fine when I run it, the creature even appear in the animal screen, sometimes. (I need to locate this screen but nvm).When I converted the inhabitants of a reclaim (due to being stupid and forgetting to check under tweak for makeown) I had to toggle flags2 > resident to false, they became friendly at that point, and after doing the civ id/cultural id/pop id to the same as my dorfs they were fully controllable.
However if I save and reload, the creature becomes hostile despite belonging to the civilization. I tried comparing it with a normal pet using gm-editor but I could not figure what's different. The civ_id is right, population is set to -1 as expected.
Here's the script, it's pretty much the same that Rumrusher posted:
https://gist.github.com/Devduweb/9299841e7169445f8cce
I tried commenting the nemesis creation call but the result is the same. Any idea of how I can make sure that df remember the creature being friendly? Thanks.
spawnunit still has a few issues, like the one you said. Thank you for testing it, but it may take a while to fix. I'll include it in the main library once it's fully functional.
Hmmm, it's fascinating that it resists the makeown script actually...
# patch start dwarf count
nr = $script_args[0].to_i
raise 'too low' if nr < 7
addr = df.get_global_address('start_dwarf_count')
df.memory_patch(addr, [nr].pack('L'))
df.global.world.worldgen.worldgen_parms.embark_points=tonumber(...)
Testing shows that my FPS go from solid 150FPS to impressive 5-8FPS when I enable it though... maybe thats my netbook? I ran it simultaniously with TWBT.
startdwarf works for me in 0.40.24. Make sure you're using a version of DFHack that has the necessary offset (i.e. not r0).
[DFHack]# tile/material-change -floor -unit 3387 -plan 5x5_X -material GOLD
C:\Users\Miles\Desktop\My_DF2\hack\lua\utils.lua:595: error: invalid arg: 1: flo
or
stack traceback:
[C]: in function 'error'
C:\Users\Miles\Desktop\My_DF2\hack\lua\utils.lua:595: in function 'proce
ssArgs'
...les\Desktop\My_DF2\hack\scripts/tile/material-change.lua:95: in main
chunk
(...tail calls...)
validArgs = validArgs or utils.invert({
'help',
'plan',
'location',
'material',
'dur',
'unit',
'floor',
'remove'
})
local args = utils.processArgs({...}, validArgs)
In my code.
I'm pretty sure it's missing from Windows.
Any idea why this is happening?Code: [Select][DFHack]# tile/material-change -floor -unit 3387 -plan 5x5_X -material GOLD
C:\Users\Miles\Desktop\My_DF2\hack\lua\utils.lua:595: error: invalid arg: 1: flo
or
stack traceback:
[C]: in function 'error'
C:\Users\Miles\Desktop\My_DF2\hack\lua\utils.lua:595: in function 'proce
ssArgs'
...les\Desktop\My_DF2\hack\scripts/tile/material-change.lua:95: in main
chunk
(...tail calls...)
I think I know what it is saying, but it doesn't make sense, since I haveCode: [Select]validArgs = validArgs or utils.invert({
In my code.
'help',
'plan',
'location',
'material',
'dur',
'unit',
'floor',
'remove'
})
local args = utils.processArgs({...}, validArgs)
Quietust found it for 0.40.24 on Windows but apparently nobody added it to symbols.xml. Should be 0xB4C833.startdwarf works for me in 0.40.24. Make sure you're using a version of DFHack that has the necessary offset (i.e. not r0).
I thought it was only found on mac/linux?
<vtable-address name='start_dwarf_count' value='0xB4C833'/>
<global-address name='start_dwarf_count' value='0xB4C833'/>
...
<global-address name='save_on_exit' value='0x1839D92'/>
code
<global-address name='start_dwarf_count' value='0xB4C833'/>
generated standingorders
<global-address name='standing_orders_gather_minerals' value='0x00e80e64'/>
...
Ah, found my mistake. There are 4 entries of start_dwarf_count, while I only changed one of them. Fixed now, works. Thanks for the help and the patience.Well, you need to change only one of them, but it needs to be the correct one. The others are for Linux and Mac.
There's also one in the commented-out section at the start of the file.Ah, found my mistake. There are 4 entries of start_dwarf_count, while I only changed one of them. Fixed now, works. Thanks for the help and the patience.Well, you need to change only one of them, but it needs to be the correct one. The others are for Linux and Mac.
Please, Meph. This isn't hard!By the way, what's displaying the "reshape_graphics" line in that screenshot? (TwbT?)Spoiler (click to show/hide)
Given a unit, how can I determine what site they live in?
Is rendermax compatible with twbt as of .40.24r1? Ils it normal that the dfhack console should hang whenever I attempt to enable rendermax?
Is rendermax compatible with twbt as of .40.24r1? Ils it normal that the dfhack console should hang whenever I attempt to enable rendermax?No, they're not compatible (since both replace the renderer). I don't know what "normal" behavior might be, but I'd expect hanging or crashes.
Some units have a hist_figure_id of -1. I guess for those I can assume they live in the currently loaded site, but how can I determine what site is currently loaded?Given a unit, how can I determine what site they live in?
Such information is stored inside historical figure object, not unit (unit has a reference to HF). But I am not sure if there is real data there, because when I check my dwarves they all have no site_links. Maybe its all about sites themselves, not HFs
I'm not sure how it's determined from UNIT side but from site side there are two ways: either it's in list of historical figure or it's in population. Population is non-important unit list, usually race, caste and num of units (e.g. number of crows in site).Some units have a hist_figure_id of -1. I guess for those I can assume they live in the currently loaded site, but how can I determine what site is currently loaded?Given a unit, how can I determine what site they live in?
Such information is stored inside historical figure object, not unit (unit has a reference to HF). But I am not sure if there is real data there, because when I check my dwarves they all have no site_links. Maybe its all about sites themselves, not HFs
All of your dwarves should be histfigs. Invaders and merchants might not be, unless there was a recent change to that.I should have specified: I am dealing with adventurer mode.
I'm not sure how it's determined from UNIT side but from site side there are two ways: either it's in list of historical figure or it's in population. Population is non-important unit list, usually race, caste and num of units (e.g. number of crows in site).How can I determine the currently loaded site, so I know what site to get all that information from?
Is there a way to disable the happiness counter in the bottom right? In older versions it was usefull, but now I feel it kind of cheating given the obscurity of dwarf's "stress" levels in 0.40.Are you saying that you think using the happiness monitor is cheating, or that the happiness monitor is "cheating" to display its values? Also, stress levels are in no way more obscure than the previous happiness values - neither of them are directly accessible in vanilla DF, while both are accessible with utilities. (It's easier to determine a range of possible happiness values in vanilla DF, but the thoughts and preferences screen also provides information about stress, albeit less straightforward.)
dfhack.script_environment('add-thought')
.setTought(x)
.setSeverity(10)
.addEmotionToUnit(u)
dfhack.script_environment('add-thought'){ thought=x, severity=10, unit=u}
seriously why add some strange state-object that has no clear use?dfhack.script_environment['add-thought']{ thought=x, severity=10, unit=u}
of for names without "-" and other non-programmer friendly symbols:dfhack.script_environment.thoughts{ thought=x, severity=10, unit=u}
wouldn't it be better to use named arguments?Code: [Select]dfhack.script_environment('add-thought'){ thought=x, severity=10, unit=u}
seriously why add some strange state-object that has no clear use?
Edit: also this could be simplified to:Code: [Select]dfhack.script_environment['add-thought']{ thought=x, severity=10, unit=u}
of for names without "-" and other non-programmer friendly symbols:Code: [Select]dfhack.script_environment.thoughts{ thought=x, severity=10, unit=u}
Question about items.1. Stack is one item. I.e. all items have quantity (or amount) field. Except bodyparts, those are tricky...
1. If an item is part of a stack, is each part of the stack its own item, or is the stack itself just a single item? For example, if a unit is carrying 25 arrows, is it 25 distinct items (in terms of df.global.world.item.all) or is it one item that when a unit fires generates another item?
2. When using dfhack.items.moveToGround(), are the correct flags turned true/false? What I mean is if an item is in a container in a units inventory and I use that dfhack command will it be removed from the container and the inventory correctly?
1. Hmm, that makes it a little more difficult. I am trying to update my projectile script with the option of using held items instead of creating them from scratch. I suppose I will have to check if the item is in a stack, generate a new item of the same type if it is, and lower the stack count by one. Would have been so much easier if they were all single items.1. yeah a lot of my ideas would be easier if it was split items. Maybe somebody should add split/combine functions in the items module now that we can sort-of create items...
2. I did have a small issue with moving an item out of a building, but I just set the flag to false manually and it solved the issue. As long as it takes the item out of containers/inventory correctly, thats all I need for now.
1. yeah a lot of my ideas would be easier if it was split items. Maybe somebody should add split/combine functions in the items module now that we can sort-of create items...1. I'll see what I can put together, but it will probably just start out as a hack for my script that can be expanded to something more robust.
2. It's better to remove and move then to mess with flags. Sometimes they are cached in strange places and either it will crash later or just leave parts of it somewhere thus growing each time it's used. For exactly what happens you should see the source code though.
2. i would try using it and if any moveToXXXX() returns false then consider first doing dfhack.items.remove(item,true)1. yeah a lot of my ideas would be easier if it was split items. Maybe somebody should add split/combine functions in the items module now that we can sort-of create items...1. I'll see what I can put together, but it will probably just start out as a hack for my script that can be expanded to something more robust.
2. It's better to remove and move then to mess with flags. Sometimes they are cached in strange places and either it will crash later or just leave parts of it somewhere thus growing each time it's used. For exactly what happens you should see the source code though.
2. So you are saying use dfhack.items.remove(item, no_uncat) and then use dfhack.items.moveToGround()?
New Question!
3. How does dfhack.items.createItem() work? Specifically, does it put the item on the map or does dfhack.items.moveToGround() need to be called after to actually get the item into the game world?
1. yeah a lot of my ideas would be easier if it was split items. Maybe somebody should add split/combine functions in the items module now that we can sort-of create items...1. I'll see what I can put together, but it will probably just start out as a hack for my script that can be expanded to something more robust.
if item.stack_size == 1 then
dfhack.items.moveToGround(item,{locSource.x,locSource.y,locSource.z+height})
else
item.stack_size = item.stack_size - 1
item = dfhack.items.createItem(itemType,itemSubtype,item.mat_type,item.mat_index,dfhack.items.getHolderUnit(item))
dfhack.items.moveToGround(item,{locSource.x,locSource.y,locSource.z+height})
end
end
I think I identified what the vector "world_unk_90" does.
It's a big pile of coordinates, each describing a 12x12 square somewhere on the map. Each one is set perfectly over a murky pool. These squares can overlap. I can see at least one square having willows grow outside it, so it's probably not a straight "plants with [WET] can grow in these zones" listing caused by the presence of pools.
<..>
Have you tried INORGANIC:BLACK_SAND?
Examples:
changelayer GRANITE
Convert layer at cursor position into granite.
changelayer SILTY_CLAY force
Convert layer at cursor position into clay even if it's stone.
changelayer MARBLE all_biomes all_layers
Convert all layers of all biomes which are not soil into marble.
Have you tried INORGANIC:BLACK_SAND?
Neither that nor INORGANIC:SAND_BLACK yield any result, nor should they given that the examples given in the writeup on GitHub all use the material name without the preface of INORGANIC; e.g., quoting directly from said writeup:QuoteExamples:
changelayer GRANITE
Convert layer at cursor position into granite.
changelayer SILTY_CLAY force
Convert layer at cursor position into clay even if it's stone.
changelayer MARBLE all_biomes all_layers
Convert all layers of all biomes which are not soil into marble.
So what is the argument for sand?
Have you tried INORGANIC:BLACK_SAND?
Neither that nor INORGANIC:SAND_BLACK yield any result, nor should they given that the examples given in the writeup on GitHub all use the material name without the preface of INORGANIC; e.g., quoting directly from said writeup:QuoteExamples:
changelayer GRANITE
Convert layer at cursor position into granite.
changelayer SILTY_CLAY force
Convert layer at cursor position into clay even if it's stone.
changelayer MARBLE all_biomes all_layers
Convert all layers of all biomes which are not soil into marble.
So what is the argument for sand?
I just tested it and changelayer SAND_BLACK works so either you didn't actually use that command like you said on the last page or 40.24 doesn't have it working? I don't want to redownload 40.24 to test that, so see if it works.. You will find the soil/ stone types in inorganic_stone_Name.txt
For a reference I clicked on the soil then alt tabbed to dfhack and used that command, maybe you did it differently? By mousing over it? Which may work, I'm already done testing it so...
So I just installed DFHack 0.40.24-r2, and I keep crashing when I Create New World, Design New World w/ Adv Parameters, or start Object Testing Arena. It Quits cleanly. Both df and dfhack directories are vanilla and for OSX. I'm running OSX 10.9.5, and have installed XQuartz 2.7.7 (xorg-server 1.15.2)Hmm, could be the add-spatter crash that lethosor mentioned earlier, I'm not sure it's been fixed in the upload. You could try Macnewbie, I used my own build.
DFHack 0.40.24-r1 runs fine w/ this same setup.
I think I managed to resuscitate the fix-armory plugin. Substituting the deprecated "StoreItemInCabinet/Chest" jobs for StoreOwnedItem and StoreItemInHospital seem to work, targeting cabinets and chests correctly. Weapon racks and armor stands work as well as they ever did.Could you make a pull request for this?
The next problem is with the armor stand capacity patch. I'm not confident about reclaiming some other region of CC CC CC CC padding for directions, since the old "empty lots" just aren't there anymore.If it's possible, it would be nice to implement this as a tweak instead. Binary patches can be difficult to maintain across DF versions (not to mention not portable between platforms). What exactly does that patch do?
basically:
+ int allowed_count = 1; // to mean 2
...
- if (type(item) == new_type)
+ if (type(item) == new_type && --allowed_count < 0)
return false;
to allow up to two items of the same type at the same time
Hmm, could be the add-spatter crash that lethosor mentioned earlier, I'm not sure it's been fixed in the upload. You could try Macnewbie, I used my own build.That fixed it!(the plugin) ...guess I should of read through the thread... Thanx a bunch fricy!
EDIT: easier changing the fixed plugin: https://github.com/DFHack/dfhack/releases/download/0.40.24-r2/add-spatter.plug.dylib
I'll look up what that means, first. I don't have a github account seeing as how I can't code in any significant manner.Does this (https://github.com/DFHack/dfhack/pull/543/files) look right?
I've been having a lot of trouble trying to get multiple retired adventurers to migrate to a fortress in a reasonable time.oh yeah adventurers if they don't rest at the site first will move to their first resting place. the game tends to move around people frequently and if you say play any of your dwarves in adventure mode do expect them to bug off to some local site when you unretire the fort.
As an alternative, is it possible to do some sort of bodyswap thing to switch one unremarkable fortress-embark dwarf with one retired (non-migrant) adventurer dwarf? Or is there any way to influence which dwarves arrive in a migration wave?
Hmm, the retired adventurers I used 'tweak makeown' on can't be selected for any jobs in the noble screen.yeah that's the major problem with the current discovery is that it's pretty hard to figure out how to make those guys pop up in nobles, though I do remember warmist making a script called tofort which slaps the adventurer as a mayor of the site then also switches to fort mode.
Have you made any modifications to the raws? Is there any sand listed by "prospect all"?I hadn't changed anything other than what the LNP launcher can do. I didn't think to try prospect to check for sand; I wish I hadn't deleted the save now so I could help debug. :(
According to the source code, embark-tools watches for any material tokens that started with "SAND_", and the underscore should have excluded sandy loam.Have you made any modifications to the raws? Is there any sand listed by "prospect all"?I hadn't changed anything other than what the LNP launcher can do. I didn't think to try prospect to check for sand; I wish I hadn't deleted the save now so I could help debug. :(
For some reason I can no longer search worn out items in trading menu. Typing x has no effect.Has this ever worked? Are you referring to the search plugin?
Some more basic structure stuff that's unlabeled for some reason.The reason it's unlabeled is because nobody has identified it. (As a side note, you should never use anon_* names in scripts - these are fields that don't actually have a name at all, but are assigned that name in order to compile and be visible. Any changes a structure can change the names of its anon_* fields.)
I don't know what anon2 means yet exactly, but each one of the above types seems to have its own series of 32-bit integers, identical to the letter. My dwarves have the longest one at 1008 entries, followed by humans at 491, elves and goblins at 292 & 235 and finished by kobolds and cave tribals at 112 and 97 respectively. Divine guardians are the shortest with only 27 integers, but each one seems to have its own specific unique contents despite the identical length.Do you mean pointers (e.g. 0x86414ba6) instead of integers? DF is probably storing the raw text of the raws (similar to many other raw structures) as pointers to character arrays.
e: well, duh. My LAYER_LINKED entity raws are exactly 97 lines long discounting the ENTITY:xyz headline and Toady's comments. Each integer corresponds to a line of text in the raws.
I don't recall.For some reason I can no longer search worn out items in trading menu. Typing x has no effect.Has this ever worked? Are you referring to the search plugin?
Do you mean pointers (e.g. 0x86414ba6) instead of integers? DF is probably storing the raw text of the raws (similar to many other raw structures) as pointers to character arrays.
...adopt?I think it's ties to prisoner rescue option
Aye, one of the prisoner rescue choices available until you get the adorable "soandso embraces soandso" bit when talking with a friendly unit.invokeServiceBounding option.
More to the point, how did you turn them into companions?
df.global.ui_advmode.conversation.choices[15].choice.type=163
df.global.ui_advmode.conversation.choices[14].choice.type=162
df.global.ui_advmode.conversation.choices[15].title="Invoke obediance By using The True Name"
df.global.ui_advmode.conversation.choices[14].title="Banish By using The True Name"
just pick a option then rewrite it to include this. though if I was more Dfhackfu I would just make this an insert choice option. Is it possible to enter arena mode from fortress mode and spawn creatures in 40.24? I'm using DF 40.24 with Phoebus's tileset and this is what I getwe got a script to spawn creatures with out needing to switch to arena mode(you can do this by using Modeset but it's not a tile set issue more so doing so kinda doesn't fill out the creature list for arena and you need another script.), but Fiddling with arena mode will end up with everyone set to independent and hostile to everyone because their unit.combat_side is set to 0 in every other mode.Also, is it possible to "hire" human caravan guards or take some goblin "slaves" in 40.24? How exactly?Spoiler (click to show/hide)And also can I mass-edit tiles using DFHack? For example, turn all tiles designated for mining into open space.Spoiler (click to show/hide)
function FillArena()
--add races to the arena spawn list
local arena_spawn=df.global.world.arena_spawn
arena_spawn.race:resize(0)
arena_spawn.caste:resize(0)
for num,race in pairs(df.global.world.raws.creatures.all) do
for caste_id,caste in pairs(race.caste) do
arena_spawn.race:insert("#",num)
arena_spawn.caste:insert("#",caste_id)
end
end
makeown script will hire those folks but god we don't have a good script/plugin for editing those guys into the fort. we don't have a good script/plugin for editing those guys into the fortI don't understand this part. Do you mean that they wouldn't get involved in the fortress activities and given any jobs?
yeah pretty much unless their the same civ from the same group from the same culture or what ever they won't work, also you need to remove the resident flag from them so they could pop up.we don't have a good script/plugin for editing those guys into the fortI don't understand this part. Do you mean that they wouldn't get involved in the fortress activities and given any jobs?
stockpiles_save ./stocksettings/Material SP Feeder ./hack/lua/plugins/stockpiles.lua:142: Cannot invoke field (global).stockpiles.stockpiles_save(): C++ exception: CHECK failed: (bytes_produced_by_serialization) == (byte_size_before_serialization): Byte size calculation and serialization were inconsistent. This may indicate a bug in protocol buffers or it may be caused by concurrent modification of the message..
stack traceback:
[C]: in function 'stockpiles_save'
./hack/lua/plugins/stockpiles.lua:142: in function <./hack/lua/plugins/stockpiles.lua:130>
I made an album with some of the screenshots that seemed relevant to this:...I think I'll just train them up until they're not encumbered by their regular gear. Then the DT-identical speeds will be accurate for my purposes.
[snipped for brevity]
Hmm. I can't really think of a proper scientific way to determine army stuff. There are too many unknown variables at this point. Any advice?I know a few fields...
unk_48[0] -> is_player (or sth like that)
unk_pos1 -> position
some array i forgot, has first id as nemesis id of traveling unit. (will look when i get home)
You can save commands in a text file and run them with the "script" command. I believe workflow data is saved in each world that uses it, so you shouldn't need to do this more than once per world.
Is it possible to load a script while loading a save?
I want to load a simple list of workflow orders, but I don't know how to do it
You can save commands in a text file and run them with the "script" command. I believe workflow data is saved in each world that uses it, so you shouldn't need to do this more than once per world.Yes I know, but I want to be able to replicate the orders in another fort.
same civ from the same group from the same culture or what everWhat defines that? Unit's "civ_id"? What else?
also you need to remove the resident flag from them so they could pop up.You mean set it to "false"? If so, they're showing up in the units list, but their status is "tame" and no labours can be given to them.
and even then you need to do more fancy dfhackin to get them into the noble screen and the militaryWhat exactly? I was looking through various scripts (none of which worked supposedly because they were written for older versions of DF or maybe they shouldn't work with other races at all?) like Warmist's "addToFort" and dfhack sources, but since I know neither LUA (though it looks very simple by itself I'm not familiar with the DFHack's LUA API and some pieces of code which people use in their scripts aren't documented), nor C++ or ruby I have troubles understanding it.
same civ from the same group from the same culture or what everWhat defines that? Unit's "civ_id"? What else?also you need to remove the resident flag from them so they could pop up.You mean set it to "false"? If so, they're showing up in the units list, but their status is "tame" and no labours can be given to them.and even then you need to do more fancy dfhackin to get them into the noble screen and the militaryWhat exactly? I was looking through various scripts (none of which worked supposedly because they were written for older versions of DF or maybe they shouldn't work with other races at all?) like Warmist's "addToFort" and dfhack sources, but since I know neither LUA (though it looks very simple by itself I'm not familiar with the DFHack's LUA API and some pieces of code which people use in their scripts aren't documented), nor C++ or ruby I have troubles understanding it.
I'm currently trying to understand how Warmist's script works step by step by putting single lines of it into my "example" script and seeing what it gives in console but maybe his script should work only for dwarven caravan guards and animals in the first place?
well the thing is dwarf fortress is pretty anti-multi-race forts, warmist found a way via Raw hacking the game to get around this way back in 40d era, that method is kinda lost in time, what's left is well the ability to alter the mainfort's Race id which chances who's the playable civ's race site is, like changing the fort from dwarves to goblins will set all the 'tame' goblins to peasant and all the dwarves to 'tame', though you might want to makesure the site has citizen goblins first before attempting dfusion set current race.Well, there's certainly a way to do to it through RAW edit, as "Succubus Dungeon" mod uses it and this was the first thing I'm looked into. But when I tried to do that myself I got dwarf civs full to the brim of "slave" goblins, probably due to their non-eating, non-drinking and biological immortality. And whether the sizes of clothes and armor will be suitable for such "slaves" is a big question.
Well, there's certainly a way to do to it through RAW edit, as "Succubus Dungeon" mod uses it and this was the first thing I'm looked into. But when I tried to do that myself I got dwarf civs full to the brim of "slave" goblins, probably due to their non-eating, non-drinking and biological immortality. And whether the sizes of clothes and armor will be suitable for such "slaves" is a big question.
Is there a reliable way to add reactions from the raws into buildings after genning a world? I accidentally forgot one until I was quite a ways into a fort. I could also have sworn there used to be a way to get DFHack to reparse the reactions and add them for you somehow, but I might just be imagining things.There is one way: "devel\inject-raws.lua"
I found the addReactionToShop function in the eventful Lua plugin, but when I run it I only see "Reaction" added to the building, not the real reaction. Said reaction is always red and can't be added.
I'm guessing this is because the game hasn't even loaded the reaction I added. Does that plugin only let you add reactions that were part of the world when you genned it, or those created dynamically in a Lua script?
Maybe I can just change an existing reaction I don't want and use it to add that to the building...
Is there a reliable way to add reactions from the raws into buildings after genning a world? I accidentally forgot one until I was quite a ways into a fort. I could also have sworn there used to be a way to get DFHack to reparse the reactions and add them for you somehow, but I might just be imagining things.There is one way: "devel\inject-raws.lua"
I found the addReactionToShop function in the eventful Lua plugin, but when I run it I only see "Reaction" added to the building, not the real reaction. Said reaction is always red and can't be added.
I'm guessing this is because the game hasn't even loaded the reaction I added. Does that plugin only let you add reactions that were part of the world when you genned it, or those created dynamically in a Lua script?
Maybe I can just change an existing reaction I don't want and use it to add that to the building...
First backup everything! Then do "devel\inject-wars reaction REACTION_NAME". Then edit raws (i.e. add it do reactions.txt or other.txt and to civ and to building). Then save and reload.
DFHack previously used Shift-Enter, which now selects all items (this is a feature in vanilla DF, introduced at some point in the 0.40.xx series). You can now use Shift-Down (or Shift-Up) to accomplish the same thing.
DFHack previously used Shift-Enter, which now selects all items (this is a feature in vanilla DF, introduced at some point in the 0.40.xx series). You can now use Shift-Down (or Shift-Up) to accomplish the same thing.
[DFHack]# teleport showpos
./hack/lua/dfhack.lua:436: /home/thefunk/.df24/hack/scripts/teleport.lua:15: syntax error near '=='
stack traceback:
[C]: in function 'error'
./hack/lua/dfhack.lua:436: in function <./hack/lua/dfhack.lua:418>
(...tail calls...)
Does anyone have experience with adding wounds to units with DFHack? Every time I try to add a wound using gm-editor or just the command line it reverts back after a few ticks.It might just heal... Wounds are complicated to say the least.
putnam doesn't pop up with a fixed teleport.lua beforehand.
[DFHack]# teleport showpos
./hack/lua/dfhack.lua:436: /home/thefunk/.df24/hack/scripts/teleport.lua:15: syntax error near '=='
stack traceback:
[C]: in function 'error'
./hack/lua/dfhack.lua:436: in function <./hack/lua/dfhack.lua:418>
(...tail calls...)
Does anyone have experience with adding wounds to units with DFHack? Every time I try to add a wound using gm-editor or just the command line it reverts back after a few ticks.It might just heal... Wounds are complicated to say the least.
Let's see... I had a script that adds a wound... A heart ripping out script. here (https://gist.github.com/warmist/8450238)
The wound just removes the heart and adds a HUGE amount of bleed per tick (without the bleeding ripping out a heart does nothing... dwarves can be heartless strangely). So more complicated stuff like damaging tissues and breaking bones or even figureing out how much bleeding to add for heart removal (also it would be fun to add a hole through to the heart :) ) is left as an exercise to the reader ;)
Thank you! I needed an actual error to know what to fix.Yeah, it is kinda a way to encourage me to not use it too much though, find different ways to do things instead of porting around.
...There is no == in all of that file. That's odd. I can't find what that error is.
Also, you really shouldn't teleport using gm-editor. It causes unit occupancy units. See teleport to see how to properly do it.
Did you check out dfhack.lua lines 418-436? It looks like the actual error is occurring there, not necessarily in teleport.lua. I think.No, the trackback lists the most recent function call first. The syntax error is occurring when attempting to load the actual script (which does occur in dfhack.lua, but the error message also mentions the problem in teleport.lua).
I was able to use teleport.lua as long as I filled out both unitID and position. If I omitted one, I got errors. Here's a screenshot.You could just copy the text from the console.
Tiny Pic because my internet is shit right now. (http://oi60.tinypic.com/hv9ibt.jpg)
I was able to use teleport.lua as long as I filled out both unitID and position. If I omitted one, I got errors. Here's a screenshot.
Tiny Pic because my internet is shit right now. (http://oi60.tinypic.com/hv9ibt.jpg)
Does anyone have experience with adding wounds to units with DFHack? Every time I try to add a wound using gm-editor or just the command line it reverts back after a few ticks.It might just heal... Wounds are complicated to say the least.
Let's see... I had a script that adds a wound... A heart ripping out script. here (https://gist.github.com/warmist/8450238)
The wound just removes the heart and adds a HUGE amount of bleed per tick (without the bleeding ripping out a heart does nothing... dwarves can be heartless strangely). So more complicated stuff like damaging tissues and breaking bones or even figureing out how much bleeding to add for heart removal (also it would be fun to add a hole through to the heart :) ) is left as an exercise to the reader ;)
Hmm, I may be able to use that to achieve what I am thinking, but I will have to investigate wounds a bit more in arena first I think. Get a good bench mark for numbers and such.
[lua]# ~unit.body.wounds[0]
<unit_wound: 0x1606de90>
id = 1
parts = <vector<unit_wound.T_parts*>: 0x1606de94>
age = 343
attacker_unit_id = 3
attacker_hist_figure_id = -1
flags = <unit_wound.T_flags: 0x1606deb0>
syndrome_id = -1
pain = 0
nausea = 0
dizziness = 0
paralysis = 0
numbness = 0
fever = 0
curse = nil
Then you have to add the parts that the wound affects. Each wound can have more than one body part affected, although it usually appears to be the same body part with different layers.[lua]# ~unit.body.wounds[0].parts[0]
<unit_wound.T_parts: 0x13da0dc0>
global_layer_idx = 64
body_part_id = 15
layer_idx = 0
contact_area = 24
surface_perc = 100
strain = 49900
effect_perc1 = <vector<int16_t>: 0x13da0dd4>
effect_perc2 = <vector<int16_t>: 0x13da0de4>
effect_type = <vector<wound_effect_type>: 0x13da0df4>
edged_curve_perc = 29
flags1 = <wound_damage_flags1: 0x13da0e08>
flags2 = <wound_damage_flags2: 0x13da0e0c>
bleeding = 0
pain = 5
nausea = 0
dizziness = 0
paralysis = 0
numbness = 0
swelling = 0
impaired = 0
cur_penetration_perc = 99
max_penetration_perc = 100
jammed_layer_idx = -1
unk_v406_1 = 0
Lastly, the corresponding body part AND layer must have the correct values and flags set.[lua]# ~unit.body.components
<body_component_info: 0x15ff4c98>
body_part_status = <vector<body_part_status>: 0x15ff4c98>
numbered_masks = <vector<uint32_t>: 0x15ff4ca8>
nonsolid_remaining = <vector<uint32_t>: 0x15ff4cb8>
layer_status = <vector<body_layer_status>: 0x15ff4cc8>
layer_wound_area = <vector<uint32_t>: 0x15ff4cd8>
layer_cut_fraction = <vector<uint32_t>: 0x15ff4ce8>
layer_dent_fraction = <vector<uint32_t>: 0x15ff4cf8>
layer_effect_fraction = <vector<uint32_t>: 0x15ff4d08>
With all three of these things I have managed to add persistent wounds (although in about 10% of my trials the damage was undone and the wound removed, but that may have been because the wound healed, or there is another check somewhere that I am unaware of for certain wounds).No, I had my cursor set.
Jeeze, you try and be helpful, and people call you an idiot...
if df.global.T_cursor:is_instance(pos) then
postemp = {x=0,y=0,z=0}
postemp.x = pos.x
postemp.y = pos.y
postemp.z = pos.z
pos = postemp
end
For those of you wondering, it appears the getTileBlock function will not accept an global.T_cursor type. Hence it won't work when using the cursor.
No, I had my cursor set.
Jeeze, you try and be helpful, and people call you an idiot...
Oh I see the problem. (I really didn't mean to suggest you were an idiot, its my fault for not reading your error log carefully enough). One sec for a fix.
EDIT: I am sure there is a more elegant way to do this, but I just threw it together, just copy and paste this in between the 'local pos =' and 'teleport()' (at the end of the file)Code: [Select]if df.global.T_cursor:is_instance(pos) then
For those of you wondering, it appears the getTileBlock function will not accept an global.T_cursor type. Hence it won't work when using the cursor.
postemp = {x=0,y=0,z=0}
postemp.x = pos.x
postemp.y = pos.y
postemp.z = pos.z
pos = postemp
end
thing_that_needs_pos(copyall(df.global.pos))
...d\Desktop\Mashup Fortress\hack\lua\plugins\stockflow.lua:390: attempt to index local 'entity' (a nil value)
stack traceback:
...d\Desktop\Mashup Fortress\hack\lua\plugins\stockflow.lua:390: in function 'collect_reactions'
...d\Desktop\Mashup Fortress\hack\lua\plugins\stockflow.lua:34: in function <...d\Desktop\Mashup Fortress\hack\lua\plugins\stockflow.lua:33>
Could not load stockflow world data!
DFHack previously used Shift-Enter, which now selects all items (this is a feature in vanilla DF, introduced at some point in the 0.40.xx series). You can now use Shift-Down (or Shift-Up) to accomplish the same thing.
...any chance of getting a related shortcut to buy a container and move past the items inside the container?
That's a problem with arena mode. Stockflow tries to look up things about civilizations, but since there's no actual world out there to collect from, it throws a fit in red text.
With all three of these things I have managed to add persistent wounds (although in about 10% of my trials the damage was undone and the wound removed, but that may have been because the wound healed, or there is another check somewhere that I am unaware of for certain wounds).Silly question, but did you check the has_breaks under flags2?
So it seems adding wounds to units is at least possible, now the issue is getting correct values for everything. I could definitely use some help in that department. What would be awesome is if anytime you are playing and one of your units gets a cool wound you could post all the values. Or if you have a fort that has lived through a bunch of different sieges and monster attacks I can go through the units (both alive and dead) and get a set of wounds, ranging from stubbed toes to torn in half. My hope is to build a, sort of, wound database, that I can use in modding and scripts to simulate an adventuring system inside of fortress mode.
very short neatly combed sideburns
very long double braided moustache
very long neatly combed beard
long double braided hair
tissue_style tissue_style_id tissue_style_type tissue_length
1 2 39 150
1 2 39 150
2 0 37 156
2 1 38 246
-1 -1 -1 -300000
-1 -1 -1 -300000
2 3 36 137
2 3 36 137
-1 -1 -1 -300000
-1 -1 -1 -300000
-1 -1 -1 -300000
-1 -1 -1 -300000
With all three of these things I have managed to add persistent wounds (although in about 10% of my trials the damage was undone and the wound removed, but that may have been because the wound healed, or there is another check somewhere that I am unaware of for certain wounds).Silly question, but did you check the has_breaks under flags2?
I ask because I've done basically the reverse of what you're talking about and until I flip the non-body flags I either keep flashing the wounded tile indicator, can't hold things, or can't stand up (even if you lose a limb and revert the wound totally, until you put stance/grasp count back to 2 you don't get the use returned), oh and the vision/breathing flags, but I forget if those are flags2 or flags3.
stuffStonesense reads and supports all of the hair styles, and displays them. I've forgotten how we did it, but a read through the source should prove helpful.
Oh lord yeah they are, the order you flip mos twounds doesn't matter much, but doing stance/grasp before wounds reverts every time.With all three of these things I have managed to add persistent wounds (although in about 10% of my trials the damage was undone and the wound removed, but that may have been because the wound healed, or there is another check somewhere that I am unaware of for certain wounds).Silly question, but did you check the has_breaks under flags2?
I ask because I've done basically the reverse of what you're talking about and until I flip the non-body flags I either keep flashing the wounded tile indicator, can't hold things, or can't stand up (even if you lose a limb and revert the wound totally, until you put stance/grasp count back to 2 you don't get the use returned), oh and the vision/breathing flags, but I forget if those are flags2 or flags3.
Yes, there are a couple other flags and other things that need to be changed for more serious wounds. Interestingly enough the logic for the stance/grasp tags are kind of weird.
Wait, I wasn't here at the time, you also helped make stonesense?stuffStonesense reads and supports all of the hair styles, and displays them. I've forgotten how we did it, but a read through the source should prove helpful.
Wait, I wasn't here at the time, you also helped make stonesense?Japa is... impressive.
Nah, I used to be an adventurer like you, until I took an arrow to the knee.so.... you got married? Good on ya.
Considering the way things reload layout/connections when you zone in/out of say, a dorf fort, perhaps you could find something useful at the boundary of the changing portion?Nah, I used to be an adventurer like you, until I took an arrow to the knee.so.... you got married? Good on ya.
though back to DFhack news. I have no idea how buildings pop up on site, though I can sure as hell manipulate the current site buildings.
1) item-trigger constantly spams the console with errors (something about a nil value), at least it doesn't crash anymore.
After seeing about the 700th person make this mistake (with myself earlier on that list), would it be possible for someone with better coding skills than mine to make a quick error-checker for raws? Just scan the files on launch and when a world is generated to make sure each raw has a file name, internal name, and OBJECT: tag that match.Should be simple enough. What exactly should the OBJECT: check involve? Most vanilla files appear to be named according to the objects they contain (e.g. inorganic_other.txt contains [OBJECT:INORGANIC]), but I'm not sure if this holds true for mods.
Thanks. Off the top of my head, I'm pretty sure that the matching should be:After seeing about the 700th person make this mistake (with myself earlier on that list), would it be possible for someone with better coding skills than mine to make a quick error-checker for raws? Just scan the files on launch and when a world is generated to make sure each raw has a file name, internal name, and OBJECT: tag that match.Should be simple enough. What exactly should the OBJECT: check involve? Most vanilla files appear to be named according to the objects they contain (e.g. inorganic_other.txt contains [OBJECT:INORGANIC]), but I'm not sure if this holds true for mods.
Edit: Here (https://github.com/lethosor/dfhack-scripts/blob/master/raw-lint.lua) is something. It doesn't work in the arena yet, unfortunately.
I followed the instructions but It wont work, can you upload a DF install with DFhack already in it?http://lazynewbpack.com/
what about adding scripts to it? I know it comes with a few but I was hoping to get some more.There's not all that much to add, since the default ships with a lot of scripts. You can find others around in various places, but they're generally either mod-specific or unfinished/untested/unstable - there's a reason they're not in by default.
I followed the instructions but It wont work, can you upload a DF install with DFhack already in it?What platform are you using? Are there any errors displayed? There's no need to download an entire pack if you'd rather not, particularly on a slow connection.
what about spawning creatures
forcing migrant waves?
creating sieges
Well, Putnam linked me to the lua API: https://github.com/DFHack/dfhack/blob/master/Lua%20API.rst but I'm not sure how useful that is for C++ as I am not a wizard myself.you could end up with vamperism or werewolfism doing this so bewarned you could end up a vampire with no way to drinking blood.
As for necromancers Rumrusher found a trick for necros if you have control of them: createitem a slab, gm-editor the slab, subtype 6 should be secrets, change the secrets type and if you have no modded secrets added then one of the first five or six should be life and death.
Note that adding reading to a unit under your control won't work, but if you add the skill to an npc and then assume control it works fine.
1) item-trigger constantly spams the console with errors (something about a nil value), at least it doesn't crash anymore.
What exactly does it say and what inputs did you give it?
Hmmm, does tiletypes have a designation flag?
I'd suggest fastdwarf 1 1 unless you REALLY need it dug out now because you can get weird behaviors from tiletypes if you aren't really careful about making sure all the right stuff is in place.
There's this (https://github.com/lethosor/dfhack-scripts/blob/master/settings-manager.lua), or you could just edit d_init.txt. (If you mean changing it in-game, that should be possible with the former, although I'm not sure if I've implemented it yet.)Oh my god where has this been and why did I not even consider that you could do this?
Edit: Should be implemented now.
1) item-trigger constantly spams the console with errors (something about a nil value), at least it doesn't crash anymore.
What exactly does it say and what inputs did you give it?
I am away from a computer that has DF right now, so I'll just try to give all I can remember.
The input I gave it didn't seem to make any difference in testing, if you want the exact information download Rubble and look at "addons/User/Speluncaphobia/DFHack".
The error is something about attempting to index a nil value, I checked and it was the "equip handler" function, forgot its exact name.
The value it was trying to index was named "table" if I remember correctly.
The error came up continuously while DF was unpaused.
local persist = require('persist-table')
persist.GlobalTable.foo.bar = 'asdf' %error: foo does not exist yet
--instead do this
persist.GlobalTable.foo = persist.GlobalTable.foo or {}
persist.GlobalTable.foo.bar = 'asdf' %foo definitely exists here
this is going to be a stupid question, but how do you run a dfhack script?Type its name in the console and press Enter.
spawn-unit DWARF 0 dwarfy
I get this error yeah that whole lua.txt thing messed me up, I am trying to run the spawn unit script (https://gist.github.com/warmist/8563110)As a quick-and-dirty fix, try replacing anon_4 with own_interaction and anon_5 with own_interaction_delay
but when I runCode: [Select]spawn-unit DWARF 0 dwarfy
I get this errorSpoiler (click to show/hide)
Can anyone confirm that eventful adding a reaction to a hardcoded building does not work (correctly)?It only works with custom workshops. Intended use is that you add reactions based on something (e.g. only if you have important person X or you mined X of Y etc...). Adding reactions to hardcoded workshops is um... a lot of work (for anyone who wants to do it: interpose ALL the workshop types).
I know that was the plan until I found out about the spawn-unit script, do we have any idea when it will be fixed?
I know that was the plan until I found out about the spawn-unit script, do we have any idea when it will be fixed?
I am not sure what you mean, this script (https://gist.github.com/Devduweb/9299841e7169445f8cce) keeps throwing up this error when ever I do spawn-unit humanSpoiler (click to show/hide)
wow, thanks.
Edit: now dfhack pauses for a second, and then when I look in dwarf fortress there is nothing new.
I know that was the plan until I found out about the spawn-unit script, do we have any idea when it will be fixed?
Warmist is supposed to be working on it I think.
To answer my question, yes you can add {'TWBT', 'TWBT'}, to the print_mode list and it will activate/deactivate it as expected on restarting df which is incredibly handy since it is still a bit buggy in adventure mode.There's this (https://github.com/lethosor/dfhack-scripts/blob/master/settings-manager.lua), or you could just edit d_init.txt. (If you mean changing it in-game, that should be possible with the former, although I'm not sure if I've implemented it yet.)Oh my god where has this been and why did I not even consider that you could do this?
Edit: Should be implemented now.
I assume the way twbt switches the display method means it couldn't be hotswapped, but could it be toggled to enable/disable on reboot through the manager?
modtools/reaction-trigger -reactionName CREATE_AUTOMATON -command [ spawn-unit -race AUTOMANTON ]
but it asks me to point my pointy thing somewhere, how do I make it spawn the creature at the workshop where the reaction happened?
I am having trouble with modtools/reaction-trigger I put this into onLoad.INITCode: [Select]modtools/reaction-trigger -reactionName CREATE_AUTOMATON -command [ spawn-unit -race AUTOMANTON ]
but it asks me to point my pointy thing somewhere, how do I make it spawn the creature at the workshop where the reaction happened?
modtools/reaction-trigger -reactionName CREATE_AUTOMATON -command [ spawn-unit -race AUTOMANTON -position \LOCATION]
modtools/reaction-trigger -reactionName CREATE_AUTOMATON -command [ spawn-unit -race AUTOMATON -position [ \\LOCATION ] ]
modtools/reaction-trigger -reactionName CREATE_AUTOMATON -command [ spawn-unit -race AUTOMATON -position [ \\LOCATION ] ]
because it still says to point my pointy thing somewhere.
is this rightThe new script is checking location differently than the old script I had duct-taped together, so I'm not sure exactly what's going on. The \\LOCATION is actually a list of three numbers, thus the square brackets around it, and that doesn't seem to be getting slotted into spawn-unit's arguments properly. With a "blank" position, it is defaulting to the cursor location. If that gives an X-coordinate of -3000, it means the "pointy thing" isn't displayed currently.Code: [Select]modtools/reaction-trigger -reactionName CREATE_AUTOMATON -command [ spawn-unit -race AUTOMATON -position [ \\LOCATION ] ]
because it still says to point my pointy thing somewhere.
modtools/reaction-trigger -reactionName CREATE_AUTOMATON -command [ devel/print-args -race AUTOMATON -position [ \\LOCATION ] ]
I must have broken the parameter, that'll be fixed in a day or two.Is this going to find its way into DFHack r3, or would I need to package this inside a mod that uses it? Would you prefer me to direct people to download it separately?
Hopefully that would be in a future version of dfhack once its bugs are taken care of, there is also a few things missing with orientation flags and probably the noble screen too.Thanks.
same thing
where am I supposed to put modtools/reaction-trigger -reactionName CREATE_AUTOMATON -command [ devel/print-args -race AUTOMATON -position [ \\LOCATION ] ] I put it in onLoad.INITThat is the right place, but make sure it is the ONLY reaction-trigger tied to that reaction. Only one will trigger.
Invoking: modtools/reaction-trigger -reactionName CREATE_AUTOMATON -command [ spawn-unit -race AUTOMATON -position [ \\LOCATION ] ]
Cannot write field coord.1: not found.
stack traceback:
[C]: in ?
[C]: in function 'assign'
...\Desktop\df_40_24_win_modded/hack/scripts/spawn-unit.lua:359: in function 'place'
...\Desktop\df_40_24_win_modded/hack/scripts/spawn-unit.lua:425: in function 'f'
...rs\Aidan\Desktop\df_40_24_win_modded\hack\lua\dfhack.lua:434: in function <...rs\Aidan\Desktop\df_40_24_win_modded\hack\lua\dfhack.lua:418>
(...tail calls...)
[C]: in function 'runCommand'
...rs\Aidan\Desktop\df_40_24_win_modded\hack\lua\dfhack.lua:454: in function '_run_command'
...rs\Aidan\Desktop\df_40_24_win_modded\hack\lua\dfhack.lua:469: in function 'run_command'
...24_win_modded/hack/scripts/modtools/reaction-trigger.lua:106: in function 'doAction'
...24_win_modded/hack/scripts/modtools/reaction-trigger.lua:146: in function <...24_win_modded/hack/scripts/modtools/reaction-trigger.lua:75>
alright I put the hole devlog thing in onLoad.INIT created the workshop tried to make an automaton, and nothing dfhack says nothing.It should be onLoad.init (if your filesystem is case-sensitive).
-race
AUTOMATON
-position
[
103
100
84
]
after many tries I put modtools/reaction-trigger -reactionName CREATE_AUTOMATON -command [ devel/print-args -race AUTOMATON -position [ \\LOCATION ] ] in onLoad.init and it printed thisCode: [Select]-race
AUTOMATON
-position
[
103
100
84
]
E: NoMethodError: undefined method `unk_6c' for #<DFHack::CreatureInteractionEffectBodyTransformationst:0xa9d14454>
./hack/scripts/ShowUnitSyndromes.rb:761
./hack/scripts/ShowUnitSyndromes.rb:863
./hack/scripts/ShowUnitSyndromes.rb:1013:in `collect'
./hack/ruby/ruby-autogen-defs.rb:391:in `each'
./hack/ruby/ruby-autogen-defs.rb:391:in `each'
./hack/scripts/ShowUnitSyndromes.rb:863:in `collect'
./hack/scripts/ShowUnitSyndromes.rb:863
./hack/scripts/ShowUnitSyndromes.rb:924:in `[]'
--create unit at pointer or given location and with given civ (usefull to pass -1 for enemy). Usage e.g. "spawn-unit -race DWARF -caste 0 -name Dwarfy"
--[=[
arguments
-help
print this help message
-race <RACE_ID>
The raw id of the creature's race, mandatory
-caste <number>
The caste's number, optional
-name <doggy>
The unit's name, optional
-position [ x y z ]
The unit's position, will try to use the cursor if ommited
-civ_id
The unit's civilisation or -1 for hostile, will be the player's if ommited
Example : spawn-unit -race HUMAN -caste 0 -name Bob
Made by warmist, but edited by Putnam for the dragon ball mod to be used in reactions
Hotfix by Dirst to repair location parameter
TODO:
throw a proper error if the user attempt to run it from the console, without good args
orientation
chosing a caste based on ratios
birth time
death time
real body size
blood max
check if soulless and skip make soul
set weapon body part
nemesis/histfig : add an 'arrived on site' event
generate name
--]=]
local utils=require 'utils'
-- Picking a caste or gender at random
local function getRandomCasteId(race_id)
local cr = df.creature_raw.find(race_id)
local caste_id, casteMax
casteMax = #cr.caste - 1
if casteMax > 0 then
return math.random(0, casteMax)
end
return 0
end
local function getCaste(race_id,caste_id)
local cr=df.creature_raw.find(race_id)
return cr.caste[caste_id+0]
end
local function genBodyModifier(body_app_mod)
local a=math.random(0,#body_app_mod.ranges-2)
return math.random(body_app_mod.ranges[a],body_app_mod.ranges[a+1])
end
local function getBodySize(caste,time)
--TODO: real body size...
return caste.body_size_1[#caste.body_size_1-1] --returns last body size
end
local function genAttribute(array)
local a=math.random(0,#array-2)
return math.random(array[a],array[a+1])
end
local function norm()
return math.sqrt((-2)*math.log(math.random()))*math.cos(2*math.pi*math.random())
end
local function normalDistributed(mean,sigma)
return mean+sigma*norm()
end
local function clampedNormal(min,median,max)
local val=normalDistributed(median,math.sqrt(max-min))
if val<min then return min end
if val>max then return max end
return val
end
local function makeSoul(unit,caste)
local tmp_soul=df.unit_soul:new()
tmp_soul.unit_id=unit.id
tmp_soul.name:assign(unit.name)
tmp_soul.race=unit.race
tmp_soul.sex=unit.sex
tmp_soul.caste=unit.caste
--todo: preferences,traits.
local attrs=caste.attributes
for k,v in pairs(attrs.ment_att_range) do
local max_percent=attrs.ment_att_cap_perc[k]/100
local cvalue=genAttribute(v)
tmp_soul.mental_attrs[k]={value=cvalue,max_value=cvalue*max_percent}
end
for k,v in pairs(tmp_soul.personality.traits) do
local min,mean,max
min=caste.personality.a[k]
mean=caste.personality.b[k]
max=caste.personality.c[k]
tmp_soul.personality.traits[k]=clampedNormal(min,mean,max)
end
--[[natural skill fix]]
for k, skill in ipairs(caste.natural_skill_id) do
local rating = caste.natural_skill_lvl[k]
utils.insert_or_update(tmp_soul.skills,
{new=true,id=skill,experience=caste.natural_skill_exp[k],rating=rating}, 'id')
end
unit.status.souls:insert("#",tmp_soul)
unit.status.current_soul=tmp_soul
end
local function CreateUnit(race_id,caste_id)
local race=df.creature_raw.find(race_id)
if race==nil then error("Invalid race_id") end
local caste
local unit=df.unit:new()
-- Pick a random caste is none are set
if nil == caste_id then
caste_id = getRandomCasteId(race_id)
end
caste = getCaste(race_id,caste_id)
unit:assign{
race=race_id,
caste=caste_id,
sex=caste.gender,
}
unit.relations.birth_year=df.global.cur_year-15 --AGE is set here
if caste.misc.maxage_max==-1 then
unit.relations.old_year=-1
else
unit.relations.old_year=df.global.cur_year+math.random(caste.misc.maxage_min,caste.misc.maxage_max)
end
--unit.relations.birth_time=??
--unit.relations.old_time=?? --TODO add normal age
--[[ interataction stuff, probably timers ]]--
local num_inter=#caste.body_info.interactions -- new for interactions
unit.curse.own_interaction:resize(num_inter) -- new for interactions
unit.curse.own_interaction_delay:resize(num_inter) -- new for interactions
--[[ body stuff ]]
local body=unit.body
body.body_plan=caste.body_info
local body_part_count=#body.body_plan.body_parts
local layer_count=#body.body_plan.layer_part
--[[ body components ]]
local cp=body.components
cp.body_part_status:resize(body_part_count)
cp.numbered_masks:resize(#body.body_plan.numbered_masks)
for num,v in ipairs(body.body_plan.numbered_masks) do
cp.numbered_masks[num]=v
end
cp.layer_status:resize(layer_count)
cp.layer_wound_area:resize(layer_count)
cp.layer_cut_fraction:resize(layer_count)
cp.layer_dent_fraction:resize(layer_count)
cp.layer_effect_fraction:resize(layer_count)
local attrs=caste.attributes
for k,v in pairs(attrs.phys_att_range) do
local max_percent=attrs.phys_att_cap_perc[k]/100
local cvalue=genAttribute(v)
unit.body.physical_attrs[k]={value=cvalue,max_value=cvalue*max_percent}
end
body.blood_max=getBodySize(caste,0) --TODO normal values
body.blood_count=body.blood_max
body.infection_level=0
unit.status2.body_part_temperature:resize(body_part_count)
for k,v in pairs(unit.status2.body_part_temperature) do
unit.status2.body_part_temperature[k]={new=true,whole=10067,fraction=0}
end
--[[ largely unknown stuff ]]
local stuff=unit.enemy
stuff.body_part_878:resize(body_part_count) -- all = 3
stuff.body_part_888:resize(body_part_count) -- all = 3
stuff.body_part_relsize:resize(body_part_count) -- all =0
stuff.were_race=race_id
stuff.were_caste=caste_id
stuff.normal_race=race_id
stuff.normal_caste=caste_id
stuff.body_part_8a8:resize(body_part_count) -- all = 1
stuff.body_part_base_ins:resize(body_part_count)
stuff.body_part_clothing_ins:resize(body_part_count)
stuff.body_part_8d8:resize(body_part_count)
--TODO add correct sizes. (calculate from age)
local size=caste.body_size_2[#caste.body_size_2-1]
body.size_info.size_cur=size
body.size_info.size_base=size
body.size_info.area_cur=math.pow(size,0.666)
body.size_info.area_base=math.pow(size,0.666)
body.size_info.area_cur=math.pow(size*10000,0.333)
body.size_info.area_base=math.pow(size*10000,0.333)
unit.recuperation.healing_rate:resize(layer_count)
--appearance
local app=unit.appearance
app.body_modifiers:resize(#caste.body_appearance_modifiers) --3
for k,v in pairs(app.body_modifiers) do
app.body_modifiers[k]=genBodyModifier(caste.body_appearance_modifiers[k])
end
app.bp_modifiers:resize(#caste.bp_appearance.modifier_idx) --0
for k,v in pairs(app.bp_modifiers) do
app.bp_modifiers[k]=genBodyModifier(caste.bp_appearance.modifiers[caste.bp_appearance.modifier_idx[k]])
end
--app.unk_4c8:resize(33)--33
app.tissue_style:resize(#caste.bp_appearance.style_part_idx)
app.tissue_style_civ_id:resize(#caste.bp_appearance.style_part_idx)
app.tissue_style_id:resize(#caste.bp_appearance.style_part_idx)
app.tissue_style_type:resize(#caste.bp_appearance.style_part_idx)
app.tissue_length:resize(#caste.bp_appearance.style_part_idx)
app.genes.appearance:resize(#caste.body_appearance_modifiers+#caste.bp_appearance.modifiers) --3
app.genes.colors:resize(#caste.color_modifiers*2) --???
app.colors:resize(#caste.color_modifiers)--3
makeSoul(unit,caste)
--finally set the id
unit.id=df.global.unit_next_id
df.global.unit_next_id=df.global.unit_next_id+1
df.global.world.units.all:insert("#",unit)
df.global.world.units.active:insert("#",unit)
return unit
end
local function findRace(name)
for k,v in pairs(df.global.world.raws.creatures.all) do
if v.creature_id==name then
return k
end
end
qerror("Race:"..name.." not found!")
end
local function createFigure(trgunit,he,he_group)
local hf=df.historical_figure:new()
hf.id=df.global.hist_figure_next_id
hf.race=trgunit.race
hf.caste=trgunit.caste
hf.profession = trgunit.profession
hf.sex = trgunit.sex
df.global.hist_figure_next_id=df.global.hist_figure_next_id+1
hf.appeared_year = df.global.cur_year
hf.born_year = trgunit.relations.birth_year
hf.born_seconds = trgunit.relations.birth_time
hf.curse_year = trgunit.relations.curse_year
hf.curse_seconds = trgunit.relations.curse_time
hf.birth_year_bias = trgunit.relations.birth_year_bias
hf.birth_time_bias = trgunit.relations.birth_time_bias
hf.old_year = trgunit.relations.old_year
hf.old_seconds = trgunit.relations.old_time
hf.died_year = -1
hf.died_seconds = -1
hf.name:assign(trgunit.name)
hf.civ_id = trgunit.civ_id
hf.population_id = trgunit.population_id
hf.breed_id = -1
hf.unit_id = trgunit.id
df.global.world.history.figures:insert("#",hf)
hf.info = df.historical_figure_info:new()
hf.info.unk_14 = df.historical_figure_info.T_unk_14:new() -- hf state?
--unk_14.region_id = -1; unk_14.beast_id = -1; unk_14.unk_14 = 0
hf.info.unk_14.unk_18 = -1; hf.info.unk_14.unk_1c = -1
-- set values that seem related to state and do event
--change_state(hf, dfg.ui.site_id, region_pos)
--lets skip skills for now
--local skills = df.historical_figure_info.T_skills:new() -- skills snap shot
-- ...
hf.info.skills = {new=true}
he.histfig_ids:insert('#', hf.id)
he.hist_figures:insert('#', hf)
if he_group then
he_group.histfig_ids:insert('#', hf.id)
he_group.hist_figures:insert('#', hf)
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=he_group.id,link_strength=100})
end
trgunit.flags1.important_historical_figure = true
trgunit.flags2.important_historical_figure = true
trgunit.hist_figure_id = hf.id
trgunit.hist_figure_id2 = hf.id
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=trgunit.civ_id,link_strength=100})
--add entity event
local hf_event_id=df.global.hist_event_next_id
df.global.hist_event_next_id=df.global.hist_event_next_id+1
df.global.world.history.events:insert("#",{new=df.history_event_add_hf_entity_linkst,year=trgunit.relations.birth_year,
seconds=trgunit.relations.birth_time,id=hf_event_id,civ=hf.civ_id,histfig=hf.id,link_type=0})
return hf
end
local function allocateNewChunk(hist_entity)
hist_entity.save_file_id=df.global.unit_chunk_next_id
df.global.unit_chunk_next_id=df.global.unit_chunk_next_id+1
hist_entity.next_member_idx=0
print("allocating chunk:",hist_entity.save_file_id)
end
local function allocateIds(nemesis_record,hist_entity)
if hist_entity.next_member_idx==100 then
allocateNewChunk(hist_entity)
end
nemesis_record.save_file_id=hist_entity.save_file_id
nemesis_record.member_idx=hist_entity.next_member_idx
hist_entity.next_member_idx=hist_entity.next_member_idx+1
end
local function createNemesis(trgunit,civ_id,group_id)
local id=df.global.nemesis_next_id
local nem=df.nemesis_record:new()
nem.id=id
nem.unit_id=trgunit.id
nem.unit=trgunit
nem.flags:resize(4)
--not sure about these flags...
-- [[
nem.flags[4]=true
nem.flags[5]=true
nem.flags[6]=true
nem.flags[7]=true
nem.flags[8]=true
nem.flags[9]=true
--]]
--[[for k=4,8 do
nem.flags[k]=true
end]]
nem.unk10=-1
nem.unk11=-1
nem.unk12=-1
df.global.world.nemesis.all:insert("#",nem)
df.global.nemesis_next_id=id+1
trgunit.general_refs:insert("#",{new=df.general_ref_is_nemesisst,nemesis_id=id})
trgunit.flags1.important_historical_figure=true
nem.save_file_id=-1
local he=df.historical_entity.find(civ_id)
he.nemesis_ids:insert("#",id)
he.nemesis:insert("#",nem)
local he_group
if group_id~=-1 then
he_group=df.historical_entity.find(group_id)
end
if he_group then
he_group.nemesis_ids:insert("#",id)
he_group.nemesis:insert("#",nem)
end
allocateIds(nem,he)
nem.figure=createFigure(trgunit,he,he_group)
end
-- Do the placement, returns the freshly spawned unit
function place(args)
if not args.race then
qerror("Please provide a race")
end
local pos = {}
if args.position then
pos.x=args.position[1]
pos.y=args.position[2]
pos.z=args.position[3]
else
pos = copyall(df.global.cursor)
end
if pos.x == -30000 then
qerror("Point your pointy thing somewhere")
end
local i
local race_id = findRace(args.race)
local u = CreateUnit(race_id,args.caste)
u.pos:assign(pos)
if args.name then
u.name.first_name = args.name
u.name.has_name = true
end
local group_id
if df.global.gamemode == df.game_mode.ADVENTURE then
u.civ_id = args.civ_id or df.global.world.units.active[0].civ_id
group_id = -1
else
u.civ_id = args.civ_id or df.global.ui.civ_id
end
if args.civ_id == -1 then
group_id = group_id or -1
else
group_id = group_id or df.global.ui.group_id
end
local desig,ocupan = dfhack.maps.getTileFlags(pos)
if ocupan.unit then
ocupan.unit_grounded = true
u.flags1.on_ground = true
else
ocupan.unit = true
end
if df.historical_entity.find(u.civ_id) ~= nil then
createNemesis(u, u.civ_id,group_id)
end
return u
end
validArgs = validArgs or utils.invert({
'help',
'race',
'caste',
'name',
'position',
'civ_id',
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print([[scripts/spawn-unit.lua
arguments
-help
print this help message
-race <RACE_ID>
The raw id of the creature's race, mandatory
-caste <number>
The caste's number, optional
-name <doggy>
The unit's name, optional
-position [ x y z ]
The unit's position, will try to use the cursor if ommited
-civ_id
The unit's civilisation or -1 for hostile, will be the player's if ommited
]])
return
end
if args.race then
place(args) --Creature (ID), caste (number), name, x,y,z , civ_id(-1 for enemy, optional) for spawn.
end
--create unit at pointer or given location and with given civ (usefull to pass -1 for enemy). Usage e.g. "spawn-unit -race DWARF -caste 0 -name Dwarfy"
--[=[
arguments
-help
print this help message
-race <RACE_ID>
The raw id of the creature's race, mandatory
-caste <number>
The caste's number, optional
-age <number>
The unit's age in years, defaults to 15 if omitted
-name <doggy>
The unit's name, optional
-position [ x y z ]
The unit's position, will try to use the cursor if omitted
-civ_id
The unit's civilisation, will be the player's if omitted
-hostile
Overrides the civ_id to -1
Example : spawn-unit -race HUMAN -caste 0 -name Bob
Made by warmist, but edited by Putnam for the dragon ball mod to be used in reactions
Modified by Dirst for use in The Earth Strikes Back mod
TODO:
throw a proper error if the user attempt to run it from the console, without good args
orientation
chosing a caste based on ratios
birth time
death time
real body size
blood max
check if soulless and skip make soul
set weapon body part
nemesis/histfig : add an 'arrived on site' event
generate name
--]=]
local utils=require 'utils'
-- Picking a caste or gender at random
local function getRandomCasteId(race_id)
local cr = df.creature_raw.find(race_id)
local caste_id, casteMax
casteMax = #cr.caste - 1
if casteMax > 0 then
return math.random(0, casteMax)
end
return 0
end
local function getCaste(race_id,caste_id)
local cr=df.creature_raw.find(race_id)
return cr.caste[tonumber(caste_id)]
end
local function genBodyModifier(body_app_mod)
local a=math.random(0,#body_app_mod.ranges-2)
return math.random(body_app_mod.ranges[a],body_app_mod.ranges[a+1])
end
local function getBodySize(caste,time)
--TODO: real body size...
return caste.body_size_1[#caste.body_size_1-1] --returns last body size
end
local function genAttribute(array)
local a=math.random(0,#array-2)
return math.random(array[a],array[a+1])
end
local function norm()
return math.sqrt((-2)*math.log(math.random()))*math.cos(2*math.pi*math.random())
end
local function normalDistributed(mean,sigma)
return mean+sigma*norm()
end
local function clampedNormal(min,median,max)
local val=normalDistributed(median,math.sqrt(max-min))
if val<min then return min end
if val>max then return max end
return val
end
local function makeSoul(unit,caste)
local tmp_soul=df.unit_soul:new()
tmp_soul.unit_id=unit.id
tmp_soul.name:assign(unit.name)
tmp_soul.race=unit.race
tmp_soul.sex=unit.sex
tmp_soul.caste=unit.caste
--todo: preferences,traits.
local attrs=caste.attributes
for k,v in pairs(attrs.ment_att_range) do
local max_percent=attrs.ment_att_cap_perc[k]/100
local cvalue=genAttribute(v)
tmp_soul.mental_attrs[k]={value=cvalue,max_value=cvalue*max_percent}
end
for k,v in pairs(tmp_soul.personality.traits) do
local min,mean,max
min=caste.personality.a[k]
mean=caste.personality.b[k]
max=caste.personality.c[k]
tmp_soul.personality.traits[k]=clampedNormal(min,mean,max)
end
--[[natural skill fix]]
for k, skill in ipairs(caste.natural_skill_id) do
local rating = caste.natural_skill_lvl[k]
utils.insert_or_update(tmp_soul.skills,
{new=true,id=skill,experience=caste.natural_skill_exp[k],rating=rating}, 'id')
end
unit.status.souls:insert("#",tmp_soul)
unit.status.current_soul=tmp_soul
end
local function CreateUnit(race_id,caste_id,unit_age)
local race=df.creature_raw.find(race_id)
if race==nil then error("Invalid race_id") end
unit_age = unit_age or 15
local caste
local unit=df.unit:new()
-- Pick a random caste is none are set
if nil == caste_id then
caste_id = getRandomCasteId(race_id)
end
caste = getCaste(race_id,caste_id)
unit:assign{
race=race_id,
caste=caste_id,
sex=caste.gender,
}
unit.relations.birth_year=df.global.cur_year-unit_age --AGE is set here
if caste.misc.maxage_max==-1 then
unit.relations.old_year=-1
else
unit.relations.old_year=df.global.cur_year+math.random(caste.misc.maxage_min,caste.misc.maxage_max)
end
unit.relations.birth_time=df.global.cur_year_tick
--unit.relations.old_time=?? --TODO add normal age
--[[ interataction stuff, probably timers ]]--
local num_inter=#caste.body_info.interactions -- new for interactions
unit.curse.own_interaction:resize(num_inter) -- new for interactions
unit.curse.own_interaction_delay:resize(num_inter) -- new for interactions
--[[ body stuff ]]
local body=unit.body
body.body_plan=caste.body_info
local body_part_count=#body.body_plan.body_parts
local layer_count=#body.body_plan.layer_part
--[[ body components ]]
local cp=body.components
cp.body_part_status:resize(body_part_count)
cp.numbered_masks:resize(#body.body_plan.numbered_masks)
for num,v in ipairs(body.body_plan.numbered_masks) do
cp.numbered_masks[num]=v
end
cp.layer_status:resize(layer_count)
cp.layer_wound_area:resize(layer_count)
cp.layer_cut_fraction:resize(layer_count)
cp.layer_dent_fraction:resize(layer_count)
cp.layer_effect_fraction:resize(layer_count)
local attrs=caste.attributes
for k,v in pairs(attrs.phys_att_range) do
local max_percent=attrs.phys_att_cap_perc[k]/100
local cvalue=genAttribute(v)
unit.body.physical_attrs[k]={value=cvalue,max_value=cvalue*max_percent}
end
body.blood_max=getBodySize(caste,0) --TODO normal values
body.blood_count=body.blood_max
body.infection_level=0
unit.status2.body_part_temperature:resize(body_part_count)
for k,v in pairs(unit.status2.body_part_temperature) do
unit.status2.body_part_temperature[k]={new=true,whole=10067,fraction=0}
end
--[[ largely unknown stuff ]]
local stuff=unit.enemy
stuff.body_part_878:resize(body_part_count) -- all = 3
stuff.body_part_888:resize(body_part_count) -- all = 3
stuff.body_part_relsize:resize(body_part_count) -- all =0
stuff.were_race=race_id
stuff.were_caste=caste_id
stuff.normal_race=race_id
stuff.normal_caste=caste_id
stuff.body_part_8a8:resize(body_part_count) -- all = 1
stuff.body_part_base_ins:resize(body_part_count)
stuff.body_part_clothing_ins:resize(body_part_count)
stuff.body_part_8d8:resize(body_part_count)
--TODO add correct sizes. (calculate from age)
local size=caste.body_size_2[#caste.body_size_2-1]
body.size_info.size_cur=size
body.size_info.size_base=size
body.size_info.area_cur=math.pow(size,0.666)
body.size_info.area_base=math.pow(size,0.666)
body.size_info.area_cur=math.pow(size*10000,0.333)
body.size_info.area_base=math.pow(size*10000,0.333)
unit.recuperation.healing_rate:resize(layer_count)
--appearance
local app=unit.appearance
app.body_modifiers:resize(#caste.body_appearance_modifiers) --3
for k,v in pairs(app.body_modifiers) do
app.body_modifiers[k]=genBodyModifier(caste.body_appearance_modifiers[k])
end
app.bp_modifiers:resize(#caste.bp_appearance.modifier_idx) --0
for k,v in pairs(app.bp_modifiers) do
app.bp_modifiers[k]=genBodyModifier(caste.bp_appearance.modifiers[caste.bp_appearance.modifier_idx[k]])
end
--app.unk_4c8:resize(33)--33
app.tissue_style:resize(#caste.bp_appearance.style_part_idx)
app.tissue_style_civ_id:resize(#caste.bp_appearance.style_part_idx)
app.tissue_style_id:resize(#caste.bp_appearance.style_part_idx)
app.tissue_style_type:resize(#caste.bp_appearance.style_part_idx)
app.tissue_length:resize(#caste.bp_appearance.style_part_idx)
app.genes.appearance:resize(#caste.body_appearance_modifiers+#caste.bp_appearance.modifiers) --3
app.genes.colors:resize(#caste.color_modifiers*2) --???
app.colors:resize(#caste.color_modifiers)--3
makeSoul(unit,caste)
--finally set the id
unit.id=df.global.unit_next_id
df.global.unit_next_id=df.global.unit_next_id+1
df.global.world.units.all:insert("#",unit)
df.global.world.units.active:insert("#",unit)
return unit
end
local function findRace(name)
for k,v in pairs(df.global.world.raws.creatures.all) do
if v.creature_id==name then
return k
end
end
qerror("Race:"..name.." not found!")
end
local function createFigure(trgunit,he,he_group)
local hf=df.historical_figure:new()
hf.id=df.global.hist_figure_next_id
hf.race=trgunit.race
hf.caste=trgunit.caste
hf.profession = trgunit.profession
hf.sex = trgunit.sex
df.global.hist_figure_next_id=df.global.hist_figure_next_id+1
hf.appeared_year = df.global.cur_year
hf.born_year = trgunit.relations.birth_year
hf.born_seconds = trgunit.relations.birth_time
hf.curse_year = trgunit.relations.curse_year
hf.curse_seconds = trgunit.relations.curse_time
hf.birth_year_bias = trgunit.relations.birth_year_bias
hf.birth_time_bias = trgunit.relations.birth_time_bias
hf.old_year = trgunit.relations.old_year
hf.old_seconds = trgunit.relations.old_time
hf.died_year = -1
hf.died_seconds = -1
hf.name:assign(trgunit.name)
hf.civ_id = trgunit.civ_id
hf.population_id = trgunit.population_id
hf.breed_id = -1
hf.unit_id = trgunit.id
df.global.world.history.figures:insert("#",hf)
hf.info = df.historical_figure_info:new()
hf.info.unk_14 = df.historical_figure_info.T_unk_14:new() -- hf state?
--unk_14.region_id = -1; unk_14.beast_id = -1; unk_14.unk_14 = 0
hf.info.unk_14.unk_18 = -1; hf.info.unk_14.unk_1c = -1
-- set values that seem related to state and do event
--change_state(hf, dfg.ui.site_id, region_pos)
--lets skip skills for now
--local skills = df.historical_figure_info.T_skills:new() -- skills snap shot
-- ...
hf.info.skills = {new=true}
he.histfig_ids:insert('#', hf.id)
he.hist_figures:insert('#', hf)
if he_group then
he_group.histfig_ids:insert('#', hf.id)
he_group.hist_figures:insert('#', hf)
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=he_group.id,link_strength=100})
end
trgunit.flags1.important_historical_figure = true
trgunit.flags2.important_historical_figure = true
trgunit.hist_figure_id = hf.id
trgunit.hist_figure_id2 = hf.id
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=trgunit.civ_id,link_strength=100})
--add entity event
local hf_event_id=df.global.hist_event_next_id
df.global.hist_event_next_id=df.global.hist_event_next_id+1
df.global.world.history.events:insert("#",{new=df.history_event_add_hf_entity_linkst,year=trgunit.relations.birth_year,
seconds=trgunit.relations.birth_time,id=hf_event_id,civ=hf.civ_id,histfig=hf.id,link_type=0})
return hf
end
local function allocateNewChunk(hist_entity)
hist_entity.save_file_id=df.global.unit_chunk_next_id
df.global.unit_chunk_next_id=df.global.unit_chunk_next_id+1
hist_entity.next_member_idx=0
print("allocating chunk:",hist_entity.save_file_id)
end
local function allocateIds(nemesis_record,hist_entity)
if hist_entity.next_member_idx==100 then
allocateNewChunk(hist_entity)
end
nemesis_record.save_file_id=hist_entity.save_file_id
nemesis_record.member_idx=hist_entity.next_member_idx
hist_entity.next_member_idx=hist_entity.next_member_idx+1
end
local function createNemesis(trgunit,civ_id,group_id)
local id=df.global.nemesis_next_id
local nem=df.nemesis_record:new()
nem.id=id
nem.unit_id=trgunit.id
nem.unit=trgunit
nem.flags:resize(4)
--not sure about these flags...
-- [[
nem.flags[4]=true
nem.flags[5]=true
nem.flags[6]=true
nem.flags[7]=true
nem.flags[8]=true
nem.flags[9]=true
--]]
--[[for k=4,8 do
nem.flags[k]=true
end]]
nem.unk10=-1
nem.unk11=-1
nem.unk12=-1
df.global.world.nemesis.all:insert("#",nem)
df.global.nemesis_next_id=id+1
trgunit.general_refs:insert("#",{new=df.general_ref_is_nemesisst,nemesis_id=id})
trgunit.flags1.important_historical_figure=true
nem.save_file_id=-1
local he=df.historical_entity.find(civ_id)
he.nemesis_ids:insert("#",id)
he.nemesis:insert("#",nem)
local he_group
if group_id~=-1 then
he_group=df.historical_entity.find(group_id)
end
if he_group then
he_group.nemesis_ids:insert("#",id)
he_group.nemesis:insert("#",nem)
end
allocateIds(nem,he)
nem.figure=createFigure(trgunit,he,he_group)
end
-- Do the placement, returns the freshly spawned unit
function place(args)
if not args.race then
qerror("Please provide a race")
end
local pos = {}
if args.position then
pos.x=args.position[1]
pos.y=args.position[2]
pos.z=args.position[3]
else
pos = copyall(df.global.cursor)
end
if pos.x == -30000 then
qerror("Point your pointy thing somewhere")
end
local i
local race_id = findRace(args.race)
local u = CreateUnit(race_id,args.caste,args.age)
u.pos:assign(pos)
if args.name then
u.name.first_name = args.name
u.name.has_name = true
end
if args.hostile then
args.civ_id = -1
end
local group_id
if df.global.gamemode == df.game_mode.ADVENTURE then
u.civ_id = args.civ_id or df.global.world.units.active[0].civ_id
group_id = -1
else
u.civ_id = args.civ_id or df.global.ui.civ_id
end
if args.civ_id == -1 then
group_id = group_id or -1
else
group_id = group_id or df.global.ui.group_id
end
local desig,ocupan = dfhack.maps.getTileFlags(pos)
if ocupan.unit then
ocupan.unit_grounded = true
u.flags1.on_ground = true
else
ocupan.unit = true
end
if df.historical_entity.find(u.civ_id) ~= nil then
createNemesis(u, u.civ_id,group_id)
end
return u
end
validArgs = validArgs or utils.invert({
'help',
'race',
'caste',
'age',
'name',
'position',
'civ_id',
'hostile',
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print([[scripts/spawn-unit.lua
arguments
-help
print this help message
-race <RACE_ID>
The raw id of the creature's race, mandatory
-caste <number>
The caste's number, optional
-age <number>
The unit's age in years, defaults to 15 if omitted
-name <doggy>
The unit's name, optional
-position [ x y z ]
The unit's position, will try to use the cursor if ommited
-civ_id
The unit's civilisation, will be the player's if ommited
-hostile
Overrides the civ_id to -1
]])
return
end
if args.race then
place(args) --Creature (ID), caste (number), age, name, x,y,z , civ_id(-1 for enemy, optional) for spawn.
end
Use \-1
Question about syndromes. This is kind of complicated to I'll just skip right to an example;
If I use add-syndrome to add a syndrome with an END I am guessing it will behave just as normal and finish at the appropriate time. But what if, instead, I used add-syndrome to add a syndrome with no END and instead removed said syndrome at a later time? Would that function the same way? Or is there something special that the game does when it ends a syndrome naturally, versus getting removed with a script?
It didn't like -civ_id \-1 either ("inavlid escape sequence"). For now I'll add a -hostile flag to override the civ to -1 if it's present, but if there is a general solution I'd rather go with what's going to be in the spawn-unit.lua that everyone else is using.Code: (tesb-spawn-unit.lua) [Select]--create unit at pointer or given location and with given civ (usefull to pass -1 for enemy). Usage e.g. "spawn-unit -race DWARF -caste 0 -name Dwarfy"
--[=[
arguments
-help
print this help message
-race <RACE_ID>
The raw id of the creature's race, mandatory
-caste <number>
The caste's number, optional
-age <number>
The unit's age in years, defaults to 15 if omitted
-name <doggy>
The unit's name, optional
-position [ x y z ]
The unit's position, will try to use the cursor if omitted
-civ_id
The unit's civilisation, will be the player's if omitted
-hostile
Overrides the civ_id to -1
Example : spawn-unit -race HUMAN -caste 0 -name Bob
Made by warmist, but edited by Putnam for the dragon ball mod to be used in reactions
Modified by Dirst for use in The Earth Strikes Back mod
TODO:
throw a proper error if the user attempt to run it from the console, without good args
orientation
chosing a caste based on ratios
birth time
death time
real body size
blood max
check if soulless and skip make soul
set weapon body part
nemesis/histfig : add an 'arrived on site' event
generate name
--]=]
local utils=require 'utils'
-- Picking a caste or gender at random
local function getRandomCasteId(race_id)
local cr = df.creature_raw.find(race_id)
local caste_id, casteMax
casteMax = #cr.caste - 1
if casteMax > 0 then
return math.random(0, casteMax)
end
return 0
end
local function getCaste(race_id,caste_id)
local cr=df.creature_raw.find(race_id)
return cr.caste[tonumber(caste_id)]
end
local function genBodyModifier(body_app_mod)
local a=math.random(0,#body_app_mod.ranges-2)
return math.random(body_app_mod.ranges[a],body_app_mod.ranges[a+1])
end
local function getBodySize(caste,time)
--TODO: real body size...
return caste.body_size_1[#caste.body_size_1-1] --returns last body size
end
local function genAttribute(array)
local a=math.random(0,#array-2)
return math.random(array[a],array[a+1])
end
local function norm()
return math.sqrt((-2)*math.log(math.random()))*math.cos(2*math.pi*math.random())
end
local function normalDistributed(mean,sigma)
return mean+sigma*norm()
end
local function clampedNormal(min,median,max)
local val=normalDistributed(median,math.sqrt(max-min))
if val<min then return min end
if val>max then return max end
return val
end
local function makeSoul(unit,caste)
local tmp_soul=df.unit_soul:new()
tmp_soul.unit_id=unit.id
tmp_soul.name:assign(unit.name)
tmp_soul.race=unit.race
tmp_soul.sex=unit.sex
tmp_soul.caste=unit.caste
--todo: preferences,traits.
local attrs=caste.attributes
for k,v in pairs(attrs.ment_att_range) do
local max_percent=attrs.ment_att_cap_perc[k]/100
local cvalue=genAttribute(v)
tmp_soul.mental_attrs[k]={value=cvalue,max_value=cvalue*max_percent}
end
for k,v in pairs(tmp_soul.personality.traits) do
local min,mean,max
min=caste.personality.a[k]
mean=caste.personality.b[k]
max=caste.personality.c[k]
tmp_soul.personality.traits[k]=clampedNormal(min,mean,max)
end
--[[natural skill fix]]
for k, skill in ipairs(caste.natural_skill_id) do
local rating = caste.natural_skill_lvl[k]
utils.insert_or_update(tmp_soul.skills,
{new=true,id=skill,experience=caste.natural_skill_exp[k],rating=rating}, 'id')
end
unit.status.souls:insert("#",tmp_soul)
unit.status.current_soul=tmp_soul
end
local function CreateUnit(race_id,caste_id,unit_age)
local race=df.creature_raw.find(race_id)
if race==nil then error("Invalid race_id") end
unit_age = unit_age or 15
local caste
local unit=df.unit:new()
-- Pick a random caste is none are set
if nil == caste_id then
caste_id = getRandomCasteId(race_id)
end
caste = getCaste(race_id,caste_id)
unit:assign{
race=race_id,
caste=caste_id,
sex=caste.gender,
}
unit.relations.birth_year=df.global.cur_year-unit_age --AGE is set here
if caste.misc.maxage_max==-1 then
unit.relations.old_year=-1
else
unit.relations.old_year=df.global.cur_year+math.random(caste.misc.maxage_min,caste.misc.maxage_max)
end
unit.relations.birth_time=df.global.cur_year_tick
--unit.relations.old_time=?? --TODO add normal age
--[[ interataction stuff, probably timers ]]--
local num_inter=#caste.body_info.interactions -- new for interactions
unit.curse.own_interaction:resize(num_inter) -- new for interactions
unit.curse.own_interaction_delay:resize(num_inter) -- new for interactions
--[[ body stuff ]]
local body=unit.body
body.body_plan=caste.body_info
local body_part_count=#body.body_plan.body_parts
local layer_count=#body.body_plan.layer_part
--[[ body components ]]
local cp=body.components
cp.body_part_status:resize(body_part_count)
cp.numbered_masks:resize(#body.body_plan.numbered_masks)
for num,v in ipairs(body.body_plan.numbered_masks) do
cp.numbered_masks[num]=v
end
cp.layer_status:resize(layer_count)
cp.layer_wound_area:resize(layer_count)
cp.layer_cut_fraction:resize(layer_count)
cp.layer_dent_fraction:resize(layer_count)
cp.layer_effect_fraction:resize(layer_count)
local attrs=caste.attributes
for k,v in pairs(attrs.phys_att_range) do
local max_percent=attrs.phys_att_cap_perc[k]/100
local cvalue=genAttribute(v)
unit.body.physical_attrs[k]={value=cvalue,max_value=cvalue*max_percent}
end
body.blood_max=getBodySize(caste,0) --TODO normal values
body.blood_count=body.blood_max
body.infection_level=0
unit.status2.body_part_temperature:resize(body_part_count)
for k,v in pairs(unit.status2.body_part_temperature) do
unit.status2.body_part_temperature[k]={new=true,whole=10067,fraction=0}
end
--[[ largely unknown stuff ]]
local stuff=unit.enemy
stuff.body_part_878:resize(body_part_count) -- all = 3
stuff.body_part_888:resize(body_part_count) -- all = 3
stuff.body_part_relsize:resize(body_part_count) -- all =0
stuff.were_race=race_id
stuff.were_caste=caste_id
stuff.normal_race=race_id
stuff.normal_caste=caste_id
stuff.body_part_8a8:resize(body_part_count) -- all = 1
stuff.body_part_base_ins:resize(body_part_count)
stuff.body_part_clothing_ins:resize(body_part_count)
stuff.body_part_8d8:resize(body_part_count)
--TODO add correct sizes. (calculate from age)
local size=caste.body_size_2[#caste.body_size_2-1]
body.size_info.size_cur=size
body.size_info.size_base=size
body.size_info.area_cur=math.pow(size,0.666)
body.size_info.area_base=math.pow(size,0.666)
body.size_info.area_cur=math.pow(size*10000,0.333)
body.size_info.area_base=math.pow(size*10000,0.333)
unit.recuperation.healing_rate:resize(layer_count)
--appearance
local app=unit.appearance
app.body_modifiers:resize(#caste.body_appearance_modifiers) --3
for k,v in pairs(app.body_modifiers) do
app.body_modifiers[k]=genBodyModifier(caste.body_appearance_modifiers[k])
end
app.bp_modifiers:resize(#caste.bp_appearance.modifier_idx) --0
for k,v in pairs(app.bp_modifiers) do
app.bp_modifiers[k]=genBodyModifier(caste.bp_appearance.modifiers[caste.bp_appearance.modifier_idx[k]])
end
--app.unk_4c8:resize(33)--33
app.tissue_style:resize(#caste.bp_appearance.style_part_idx)
app.tissue_style_civ_id:resize(#caste.bp_appearance.style_part_idx)
app.tissue_style_id:resize(#caste.bp_appearance.style_part_idx)
app.tissue_style_type:resize(#caste.bp_appearance.style_part_idx)
app.tissue_length:resize(#caste.bp_appearance.style_part_idx)
app.genes.appearance:resize(#caste.body_appearance_modifiers+#caste.bp_appearance.modifiers) --3
app.genes.colors:resize(#caste.color_modifiers*2) --???
app.colors:resize(#caste.color_modifiers)--3
makeSoul(unit,caste)
--finally set the id
unit.id=df.global.unit_next_id
df.global.unit_next_id=df.global.unit_next_id+1
df.global.world.units.all:insert("#",unit)
df.global.world.units.active:insert("#",unit)
return unit
end
local function findRace(name)
for k,v in pairs(df.global.world.raws.creatures.all) do
if v.creature_id==name then
return k
end
end
qerror("Race:"..name.." not found!")
end
local function createFigure(trgunit,he,he_group)
local hf=df.historical_figure:new()
hf.id=df.global.hist_figure_next_id
hf.race=trgunit.race
hf.caste=trgunit.caste
hf.profession = trgunit.profession
hf.sex = trgunit.sex
df.global.hist_figure_next_id=df.global.hist_figure_next_id+1
hf.appeared_year = df.global.cur_year
hf.born_year = trgunit.relations.birth_year
hf.born_seconds = trgunit.relations.birth_time
hf.curse_year = trgunit.relations.curse_year
hf.curse_seconds = trgunit.relations.curse_time
hf.birth_year_bias = trgunit.relations.birth_year_bias
hf.birth_time_bias = trgunit.relations.birth_time_bias
hf.old_year = trgunit.relations.old_year
hf.old_seconds = trgunit.relations.old_time
hf.died_year = -1
hf.died_seconds = -1
hf.name:assign(trgunit.name)
hf.civ_id = trgunit.civ_id
hf.population_id = trgunit.population_id
hf.breed_id = -1
hf.unit_id = trgunit.id
df.global.world.history.figures:insert("#",hf)
hf.info = df.historical_figure_info:new()
hf.info.unk_14 = df.historical_figure_info.T_unk_14:new() -- hf state?
--unk_14.region_id = -1; unk_14.beast_id = -1; unk_14.unk_14 = 0
hf.info.unk_14.unk_18 = -1; hf.info.unk_14.unk_1c = -1
-- set values that seem related to state and do event
--change_state(hf, dfg.ui.site_id, region_pos)
--lets skip skills for now
--local skills = df.historical_figure_info.T_skills:new() -- skills snap shot
-- ...
hf.info.skills = {new=true}
he.histfig_ids:insert('#', hf.id)
he.hist_figures:insert('#', hf)
if he_group then
he_group.histfig_ids:insert('#', hf.id)
he_group.hist_figures:insert('#', hf)
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=he_group.id,link_strength=100})
end
trgunit.flags1.important_historical_figure = true
trgunit.flags2.important_historical_figure = true
trgunit.hist_figure_id = hf.id
trgunit.hist_figure_id2 = hf.id
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=trgunit.civ_id,link_strength=100})
--add entity event
local hf_event_id=df.global.hist_event_next_id
df.global.hist_event_next_id=df.global.hist_event_next_id+1
df.global.world.history.events:insert("#",{new=df.history_event_add_hf_entity_linkst,year=trgunit.relations.birth_year,
seconds=trgunit.relations.birth_time,id=hf_event_id,civ=hf.civ_id,histfig=hf.id,link_type=0})
return hf
end
local function allocateNewChunk(hist_entity)
hist_entity.save_file_id=df.global.unit_chunk_next_id
df.global.unit_chunk_next_id=df.global.unit_chunk_next_id+1
hist_entity.next_member_idx=0
print("allocating chunk:",hist_entity.save_file_id)
end
local function allocateIds(nemesis_record,hist_entity)
if hist_entity.next_member_idx==100 then
allocateNewChunk(hist_entity)
end
nemesis_record.save_file_id=hist_entity.save_file_id
nemesis_record.member_idx=hist_entity.next_member_idx
hist_entity.next_member_idx=hist_entity.next_member_idx+1
end
local function createNemesis(trgunit,civ_id,group_id)
local id=df.global.nemesis_next_id
local nem=df.nemesis_record:new()
nem.id=id
nem.unit_id=trgunit.id
nem.unit=trgunit
nem.flags:resize(4)
--not sure about these flags...
-- [[
nem.flags[4]=true
nem.flags[5]=true
nem.flags[6]=true
nem.flags[7]=true
nem.flags[8]=true
nem.flags[9]=true
--]]
--[[for k=4,8 do
nem.flags[k]=true
end]]
nem.unk10=-1
nem.unk11=-1
nem.unk12=-1
df.global.world.nemesis.all:insert("#",nem)
df.global.nemesis_next_id=id+1
trgunit.general_refs:insert("#",{new=df.general_ref_is_nemesisst,nemesis_id=id})
trgunit.flags1.important_historical_figure=true
nem.save_file_id=-1
local he=df.historical_entity.find(civ_id)
he.nemesis_ids:insert("#",id)
he.nemesis:insert("#",nem)
local he_group
if group_id~=-1 then
he_group=df.historical_entity.find(group_id)
end
if he_group then
he_group.nemesis_ids:insert("#",id)
he_group.nemesis:insert("#",nem)
end
allocateIds(nem,he)
nem.figure=createFigure(trgunit,he,he_group)
end
-- Do the placement, returns the freshly spawned unit
function place(args)
if not args.race then
qerror("Please provide a race")
end
local pos = {}
if args.position then
pos.x=args.position[1]
pos.y=args.position[2]
pos.z=args.position[3]
else
pos = copyall(df.global.cursor)
end
if pos.x == -30000 then
qerror("Point your pointy thing somewhere")
end
local i
local race_id = findRace(args.race)
local u = CreateUnit(race_id,args.caste,args.age)
u.pos:assign(pos)
if args.name then
u.name.first_name = args.name
u.name.has_name = true
end
if args.hostile then
args.civ_id = -1
end
local group_id
if df.global.gamemode == df.game_mode.ADVENTURE then
u.civ_id = args.civ_id or df.global.world.units.active[0].civ_id
group_id = -1
else
u.civ_id = args.civ_id or df.global.ui.civ_id
end
if args.civ_id == -1 then
group_id = group_id or -1
else
group_id = group_id or df.global.ui.group_id
end
local desig,ocupan = dfhack.maps.getTileFlags(pos)
if ocupan.unit then
ocupan.unit_grounded = true
u.flags1.on_ground = true
else
ocupan.unit = true
end
if df.historical_entity.find(u.civ_id) ~= nil then
createNemesis(u, u.civ_id,group_id)
end
return u
end
validArgs = validArgs or utils.invert({
'help',
'race',
'caste',
'age',
'name',
'position',
'civ_id',
'hostile',
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print([[scripts/spawn-unit.lua
arguments
-help
print this help message
-race <RACE_ID>
The raw id of the creature's race, mandatory
-caste <number>
The caste's number, optional
-age <number>
The unit's age in years, defaults to 15 if omitted
-name <doggy>
The unit's name, optional
-position [ x y z ]
The unit's position, will try to use the cursor if ommited
-civ_id
The unit's civilisation, will be the player's if ommited
-hostile
Overrides the civ_id to -1
]])
return
end
if args.race then
place(args) --Creature (ID), caste (number), age, name, x,y,z , civ_id(-1 for enemy, optional) for spawn.
end
Use \-1
Question about syndromes. This is kind of complicated to I'll just skip right to an example;
If I use add-syndrome to add a syndrome with an END I am guessing it will behave just as normal and finish at the appropriate time. But what if, instead, I used add-syndrome to add a syndrome with no END and instead removed said syndrome at a later time? Would that function the same way? Or is there something special that the game does when it ends a syndrome naturally, versus getting removed with a script?
Not completely sure but I think it's fine except for transformations. It might even be fine for transformations. I haven't tested it thoroughly. Let me know how it goes. That ought to be documented.
Sorry if I missed it, but do you have an exact example of \-1 failing? What does devel/print-args output? If it doesn't work then that's a bug in processArgs.Other than my "invalid escape sequence" quote, you didn't miss anything. It might be a bit before I have time to replicate under controlled conditions, but the first version of spawn-unit.lua I posted ought to exhibit the error. If it makes a difference, -civ_id was the last argument on the command line.
Sorry if I missed it, but do you have an exact example of \-1 failing? What does devel/print-args output? If it doesn't work then that's a bug in processArgs.Other than my "invalid escape sequence" quote, you didn't miss anything. It might be a bit before I have time to replicate under controlled conditions, but the first version of spawn-unit.lua I posted ought to exhibit the error. If it makes a difference, -civ_id was the last argument on the command line.
modtools/force -eventType \-1
#[...]modtools/force.lua:58: Invalid eventType: -1
dfhack.maps.getRegionBiome()
I can get the following, but don't know how to interpret the output to get the info as in the first image above. (http://i.imgur.com/QhEvh0d.png)Elevation, rainfall, drainage, and temperature are the main factors that go into determining biome...
Also, try running your query somewhere with a lake and somewhere else with a river to see if the structure changes. Don't want the tool to have unrealistic expectations of data stability.Elevation, rainfall, drainage, and temperature are the main factors that go into determining biome...
I think I can deal with that, but is there a function which provides that information for the local window? Right now I can only find info for the region, but I'd like it to go down to the local scale.
Sorry if I missed it, but do you have an exact example of \-1 failing? What does devel/print-args output? If it doesn't work then that's a bug in processArgs.
Outsiders start with a weird civ that I think is hardcoded (or if there is any way to alter it I haven't heard of it being found so I simply assume it is hardcoded) and it only has access to a few things.you mean no civ? they start with no Civ at all which is why they don't get the chance to claim rights as those who start with one.
Just a question: Is spawnunit working properly now? As in, creatures don't become hostile when loading a saved file?
...You know, there's an add-thought script included with DFHack.
I wrote it myself, and yeah, I had to manually add the stress change associated with the emotion. I'm not sure if there's some specific threshold for extreme emotion reactions or if perhaps it's determined by personality.
https://github.com/DFHack/df-structures/blob/master/df.unit-thoughts.xml
With the script, you can actually get the emotion by name, too.
Roses admired a fine script lately.https://github.com/DFHack/df-structures/blob/master/df.unit-thoughts.xml
With the script, you can actually get the emotion by name, too.
Didn't even notice the gui, fantastic good sir!
Can you move in travel mode at all?I've tried everything; the answer is no. This question wouldn't be here if I could. The character's coordinates should be accessible somewhere, shouldn't it? I can browse armies, but none of the coords there match the format I expected.
for k,v in pairs(df.global.world.armies.all) do
if v.unk_48[0]== true then
print(k)
end
end
I have used DFhack with every version of DF since 31.25, and you guys have done incredible work on it, that said, I have several problems with the latest iterations of the toolset.
1) What the hell is the init example file written in, I can read it in notepad but it becomes a horrific unformatted mess that is nearly impossible to understand.
2) I do NOT like having DFhack automatically utilize the init example on startup, there are more than a few plugins I simply don't want running AT ALL in DF, as for why this is a problem see #1
I do not want the effing thing to run AT ALL unless I'm telling it what to do, what part of that is hard to comprehend? And so I take issue with DFhack automatically running something I can't even read.
Thank you lethosor, I appreciate your help. Have a nice day Putnam.When saving something with Notepad on Windows, Notepad automatically appends ".txt" to the filename unless you tell it not to. Check that the name of the file actually is exactly "dfhack.init" and not "dfhack.init.txt".
Edit: new though related problem; I copied the Init example from the git repository, edited it and renamed it dfhack.init, now dfhack doesn't recognize it even existing and wants to use dfhack.init-example, but that file no longer exists. Now what?
Thank you lethosor, I appreciate your help. Have a nice day Putnam.When saving something with Notepad on Windows, Notepad automatically appends ".txt" to the filename unless you tell it not to. Check that the name of the file actually is exactly "dfhack.init" and not "dfhack.init.txt".
Edit: new though related problem; I copied the Init example from the git repository, edited it and renamed it dfhack.init, now dfhack doesn't recognize it even existing and wants to use dfhack.init-example, but that file no longer exists. Now what?
If you are not seeing the file extensions of other files you normally use, you need to switch showing these on somewhere in your options. As I don't use Windows I don't know where to look for that.
I cannot see the first picture.Thank you lethosor, I appreciate your help. Have a nice day Putnam.When saving something with Notepad on Windows, Notepad automatically appends ".txt" to the filename unless you tell it not to. Check that the name of the file actually is exactly "dfhack.init" and not "dfhack.init.txt".
Edit: new though related problem; I copied the Init example from the git repository, edited it and renamed it dfhack.init, now dfhack doesn't recognize it even existing and wants to use dfhack.init-example, but that file no longer exists. Now what?
If you are not seeing the file extensions of other files you normally use, you need to switch showing these on somewhere in your options. As I don't use Windows I don't know where to look for that.Spoiler: Quite clearly detected not a text file (click to show/hide)
Regarding the stockflow plugin, perhaps it would be easier to make it work more like workflow that's tied to a stockpile (having read a separate thread about the difficulty of having stockpile generate jobs in connected workshops)?
Instead of using job manager, stockpile will suspend/resume relevant job in the "Take from" workshops. Then each stockpile can "borrow" the workflow's interface to set up a set number/stacks of items to maintain in the stockpile.
Instead of having stockpile "create" the job, require user to create a job on repeat in the linked workshop. The stockflow UI can indicate if it can detect a relevant job it can control in the linked workshops.
function isGoblinEntity(entity_id)
return df.historical_entity.find(entity_id).entity_raw.code=='EVIL'
end
function forceIt()
for k,v in ipairs(df.global.world.armies.all) do
if v.controller and v.controller.entity_id~=-1 and isGoblinEntity(v.controller.entity_id) then
local fortress=df.world_site.find(df.global.ui.site_id)
local entry_position={x=(fortress.global_min_x*3),y=math.floor((fortress.global_min_y+fortress.global_max_y)*1.5)} --x*1.5 more properly x*3/2, but same thing
v.unk_pos1.x=entry_position.x-1
v.unk_pos2.x=entry_position.x+1
v.unk_pos1.y=entry_position.y
v.unk_pos2.y=entry_position.y
v.controller.pos_x=v.unk_pos1.x
v.controller.pos_y=v.unk_pos1.y
if #v.unk_pos_x>0 then
v.unk_pos_x[0]=v.unk_pos2.x
v.unk_pos_y[0]=v.unk_pos2.y
else
v.unk_pos_x:insert('#',v.unk_pos2.x)
v.unk_pos_y:insert('#',v.unk_pos2.y)
end
print('Diverted Army #'..v.id..' to fortress')
return true
end
end
return false
end
forceIt()
the first entry
Oh, sorry, uh, this:
(http://i.imgur.com/slkZi1K.png)
474 is the dorf race in the mod I'm using, 477 being goblins, unk_0 gave me the number of units, one army I moved near me had two sleeping gobs in it with two entries under unk_2c so I put the unk_0 to 50 in each and ended up with a 3x3 tent that had 100 sleeping gobs in it. Couldn't get them to react normally so I grabbed an army that was about to move and did the same thing, ended up with ~50 gobs sieging my fort in adventurer mode.
Couldn't get the same trick to work in fortress mode though.
function deep_diff(struct1,struct2,prefix)
prefix=prefix or tostring(struct1):sub(2,-14)
for k,v in pairs(struct1) do
if pcall(function() pairs(v) end) then
if type(k)=='number' then
deep_diff(struct1[k],struct2[k],prefix..'['..k..']')
else
deep_diff(struct1[k],struct2[k],prefix..'.'..k)
end
else
if struct1[k]~=struct2[k] then
print(prefix..'.'..k,struct1[k],struct2[k])
end
end
end
end
function removeNative(shop_name,name)
_registeredStuff.shopNonNative=_registeredStuff.shopNonNative or {}
local shops=_registeredStuff.shopNonNative
shops[shop_name]=shops[shop_name] or {}
if name~=nil then
table.insert(shops[shop_name],name)
else
shops[shop_name].all=true
end
postWorkshopFillSidebarMenu._library=onPostSidebar
dfhack.onStateChange.eventful=unregall
end
have you guys found a way to teleport the current adventurer consistently?uhh yeah you need to find the adventurer first in the sea of armies which is done with a search function then alter the position of the army.
have you guys found a way to teleport the current adventurer consistently?Well, you need a script that will check df.global.world.armies.all for the first entry under unk_48 to be true, that will be the player army.
local armies=df.global.world.armies.all
function find_player_army()
for k,v in ipairs(armies) do
if v.unk_48[0] then
return v
end
end
end
"x" will always evaluate as true if "x==true" evaluates as true in Lua.
local armies=df.global.world.armies.all
function find_player_army()
for k,v in ipairs(armies) do
if v.unk_48[0] then
return v
end
end
end
local armies=df.global.world.armies.all
function find_player_army()
for k,v in ipairs(armies) do
if v.unk_48[0] then
return k
end
end
end
print(find_player_army())
Which spits out 80 for my army just now, and I can put that in gui/gm-editor df.global.world.armies.all[80] and open it up... could that be done in the script itself?
roof = proj.target_pos.z - proj.cur_pos.z
if roof==0 then
proj.speed_x=0
proj.speed_y=0
proj.speed_z=0
proj.flags.parabolic=false
proj.flags.has_hit_ground=true
unitSource.flags1.projectile=false
end
Because those are the flags/speed changes that caused me to drop from like 15 z up with no damage.onUnitAction=dfhack.event.new()
local actions_already_checked=actions_already_checked or {}
local function action_already_checked(unit_id,action_id)
local unit_action_checked=actions_already_checked[unit_id]
if unit_action_checked then
return unit_action_checked[action_id]
end
end
onUnitAction.print=function(unit,action)
print('Unit #'..unit.id..' is using action of type '..df.unit_action_type[action.type])
end
function checkForActions()
for k,v in ipairs(df.global.world.units.active) do
for _,action in ipairs(v.actions) do
if not action_already_checked(v.id,action.id) then
onUnitAction(v,action)
actions_already_checked[v.id]=actions_already_checked[v.id] or {}
actions_already_checked[v.id][action.id]=true
end
end
end
end
require('repeat-util').scheduleEvery('onAction',1,'ticks',checkForActions)
Oh man Lua is fast.
Like, way faster than I thought. This code is causing 0 FPS hit (70 before, 70 after) in a fortress of 103:Code: [Select]onUnitAction=dfhack.event.new()
local actions_already_checked=actions_already_checked or {}
local function action_already_checked(unit_id,action_id)
local unit_action_checked=actions_already_checked[unit_id]
if unit_action_checked then
return unit_action_checked[action_id]
end
end
onUnitAction.print=function(unit,action)
print('Unit #'..unit.id..' is using action of type '..df.unit_action_type[action.type])
end
function checkForActions()
for k,v in ipairs(df.global.world.units.active) do
for _,action in ipairs(v.actions) do
if not action_already_checked(v.id,action.id) then
onUnitAction(v,action)
actions_already_checked[v.id]=actions_already_checked[v.id] or {}
actions_already_checked[v.id][action.id]=true
end
end
end
end
require('repeat-util').scheduleEvery('onAction',1,'ticks',checkForActions)
It's going through the entire active units vector every tick. I'm impressed.
And I'm going to exploit this so hard.
Hmm, I wonder if it would be possible make "mines" where you store a location in a persistent variable, and every tick you check if anyone is on that location. Then if there is you trigger a script and remove the location from persistent storage (or not, depending on if you want the mine to trigger more than once)I had a similar idea that I wanted to watch all of the unmined bits of specific stones (should be manageable since they're single-tile-clusters). The backstory of the mod implies that interesting things ought to happen if one of those tiles comes in contact with magma. My thinking was that I'd need a plug-in for this, setting up a data structure for each type of stone-of-interest with a linked list of coordinates, and checking them every hundred ticks or so (spacing out the different types of tiles to prevent FPS stutters).
Note that that is going through every unit, which is still, oh, an order of magnitude smaller than every tile. I wouldn't recommend pushing it, but you could always try.The idea was to scan the tiles on load and build the lists to check periodically. Essentially running prospect all every tick isn't the path to high FPS! My whole concept depends on what kind of persistent data is available to Lua. I could encode the "linked list" in a string, but a real Lua list would be much better.
Yeah, except for exactly what I want to do, heh (which is modify attacks and movement before they actually go through)
Yeah, except for exactly what I want to do, heh (which is modify attacks and movement before they actually go through)
Hmm...there should probably be an event for that. There isn't but there should be. Action initiated or something.
modtools/interaction-trigger -suppressAttack -onAttackStr "test for super saiyan" -command [ dragonball/super_saiyan_trigger -unit \\ATTACKER_ID ]
Anyone know why this isn't working?Code: [Select]modtools/interaction-trigger -suppressAttack -onAttackStr "test for super saiyan" -command [ dragonball/super_saiyan_trigger -unit \\ATTACKER_ID ]
It's suppressing the attack perfectly, but the command isn't going at all.
Anyone know why this isn't working?Code: [Select]modtools/interaction-trigger -suppressAttack -onAttackStr "test for super saiyan" -command [ dragonball/super_saiyan_trigger -unit \\ATTACKER_ID ]
It's suppressing the attack perfectly, but the command isn't going at all.
That looks like the right syntax. I'm not sure. Have you tried testing with devel/print-args?
During all of this current_soul searching, has anyone happened upon the values required to make a creature into a functioning member of the fort? When I use warmist's spawn-unit script to make an animal, it's fine for hostile ones but unreliable for friendly ones. Giving it the player's civ_id will make it appear "Tame" on the units list (and keep it from attacking) but "Not Tame" on the z/Animals list (which prevents it from being a pet) even if I gm-editor its training level. I recall reading that the creature can revert to hostile when the game is saved and re-loaded, but I haven't witnessed this personally.
Comparing the gm-editor screens for a natural specimen and a spawned specimen hasn't gotten me anywhere, but that's because I'm not familiar with the object model. If someone can point me to the proper attributes and values, I think I can make the Lua code changes necessary.
The immediate use of proper fort membership would be to enable war-training and such for spawned animals, and I have plans for assigning specific creatures as pets of specific dwarves in a later expansion.
And, it doesn't get said nearly often enough that DFHack and the other third-party tools are awesome and invaluable additions to the DF game and community.
modtools/reaction-trigger -reactionName WISH_DB_ADV -command [ dragonball/wish -unit \\WORKER_ID ]
I couldn't find a civ_id attribute under unit.status.current_soul, but I did find two attributes that fix the is-it-tame-or-not dilemma:During all of this current_soul searching, has anyone happened upon the values required to make a creature into a functioning member of the fort? When I use warmist's spawn-unit script to make an animal, it's fine for hostile ones but unreliable for friendly ones. Giving it the player's civ_id will make it appear "Tame" on the units list (and keep it from attacking) but "Not Tame" on the z/Animals list (which prevents it from being a pet) even if I gm-editor its training level. I recall reading that the creature can revert to hostile when the game is saved and re-loaded, but I haven't witnessed this personally.
Comparing the gm-editor screens for a natural specimen and a spawned specimen hasn't gotten me anywhere, but that's because I'm not familiar with the object model. If someone can point me to the proper attributes and values, I think I can make the Lua code changes necessary.
The immediate use of proper fort membership would be to enable war-training and such for spawned animals, and I have plans for assigning specific creatures as pets of specific dwarves in a later expansion.
And, it doesn't get said nearly often enough that DFHack and the other third-party tools are awesome and invaluable additions to the DF game and community.
Did you give it the civ_id for both unit.civ_id and unit.status.current_soul.civ_id? I was able to turn animals into tame members that appear as tame both in the units screen and the z/animals. Although this was with already existing animals, and not those spawned by the script. (I also changed all of the unit.animal tokens to -1, not sure what effect that actually has though)
Is there a way to spotcheck a creature for being an intelligent race/caste before I set these flags? It could be hacked by checking if the species matches the player's civ, but that won't be robust to multi-species forts that are just around the corner.
local caste=df.creature_raw.find(unit.race).caste[unit.caste]
if caste.flags.CAN_SPEAK and caste.flags.CAN_LEARN then
--stuff
end
Of course, the minute I decide that it'd be a lot of work for little practical benefit, you go ahead and build it. Must be part dwarven ;)Is there a way to spotcheck a creature for being an intelligent race/caste before I set these flags? It could be hacked by checking if the species matches the player's civ, but that won't be robust to multi-species forts that are just around the corner.Code: [Select]local caste=df.creature_raw.find(unit.race).caste[unit.caste]
if caste.flags.CAN_SPEAK and caste.flags.CAN_LEARN then
--stuff
end
I would remove (or rename) the "hack" folder (and "stonesense" if it exists) first, assuming you don't have anything important in them.Thanks
It works entirely, except for sieges. I've been working on siege spawning, but that seems to rely on some variables that I cannot modify at all.
EDIT: This isn't working either:Code: [Select]modtools/reaction-trigger -reactionName WISH_DB_ADV -command [ dragonball/wish -unit \\WORKER_ID ]
I tested that with print-args and it printed nothing.
modtools/force -eventType CivAttack -civ EVIL // Invalid eventType, line 58
modtools/force -eventType FeatureAttack -civ EVIL // nothing happens, FeatureAttack is an enum from eventType, probably replacement for CivAttack
modtools/force -eventType Caravan -civ PLAINS // a random (maybe the first?) human civilization sends a caravan
modtools/force -eventType Caravan -civ 5034(entity-id) //cannot write field time_event.entity:incompatible pointer type, line 76
modtools/force -eventType Migrants // works regardless of -civ
modtools/force -eventType Caravan(or Diplomat) //game crash, probably need error catch for the second arg?
modtools/force -eventType (AnyOtherType) // nothing happens
modtools/force -eventType (InvalidEventType) //often throws an error, occasionally crashes the game. probably an error check would be better?
It works entirely, except for sieges. I've been working on siege spawning, but that seems to rely on some variables that I cannot modify at all.
EDIT: This isn't working either:Code: [Select]modtools/reaction-trigger -reactionName WISH_DB_ADV -command [ dragonball/wish -unit \\WORKER_ID ]
I tested that with print-args and it printed nothing.
It works entirely, except for sieges. I've been working on siege spawning, but that seems to rely on some variables that I cannot modify at all.
EDIT: This isn't working either:Code: [Select]modtools/reaction-trigger -reactionName WISH_DB_ADV -command [ dragonball/wish -unit \\WORKER_ID ]
I tested that with print-args and it printed nothing.
Ok, it must be broken. I'll take a look.
EDIT: My previous problems with my onload.init file was mainly a problem with the way I was calling it using the script command from a lua init, making it so that, if done in adventure mode, it would load in a context where events wouldn't properly run.
Will interaction-trigger fire when a regional interaction affects a creature, maybe using the HIST string as if were the verb?
I'm trying to run this script on each instance of a specific species of vermin that appears.
I have a work-around, but it doesn't do quite what I want.
Edit: typing on a phone sucks.
unit.flags2.resident = false;
unit.flags3.body_temp_in_range = true;
unit.population_id = -1
unit.status.current_soul.unit_id = unit.id -- Was not set when creating the soul
unit.animal.population.region_x = -1
unit.animal.population.region_y = -1
unit.animal.population.unk_28 = -1
unit.animal.population.population_idx = -1
unit.animal.population.depth = -1
unit.counters.soldier_mood_countdown = -1
unit.counters.death_cause = -1
unit.enemy.anon_4 = -1
unit.enemy.anon_5 = -1
unit.enemy.anon_6 = -1
qerror("No valid target found")
line with my_trg=df.global
--create unit at pointer or given location and with given civ (usefull to pass -1 for enemy). Usage e.g. "spawn-unit -race DWARF -caste 0 -name Dwarfy"
--[=[
arguments
-help
print this help message
-race <RACE_ID>
The raw id of the creature's race, mandatory
-caste <number>
The caste's number, optional
-age <number>
The unit's age in years, defaults to 15 if omitted
-name <doggy>
The unit's name, optional
-position [ x y z ]
The unit's position, will try to use the cursor if omitted
-civ_id
The unit's civilisation, will be the player's if omitted
Example : spawn-unit -race HUMAN -caste 0 -name Bob
Made by warmist, but edited by Putnam for the dragon ball mod to be used in reactions
Modified by Dirst for use in The Earth Strikes Back mod, incorporating fixes discovered
by Boltgun
TODO:
throw a proper error if the user attempt to run it from the console, without good args
orientation
chosing a caste based on ratios
birth time
death time
real body size
blood max
check if soulless and skip make soul
set weapon body part
nemesis/histfig : add an 'arrived on site' event
generate name
--]=]
local utils=require 'utils'
-- Picking a caste or gender at random
local function getRandomCasteId(race_id)
local cr = df.creature_raw.find(race_id)
local caste_id, casteMax
casteMax = #cr.caste - 1
if casteMax > 0 then
return math.random(0, casteMax)
end
return 0
end
local function getCaste(race_id,caste_id)
local cr=df.creature_raw.find(race_id)
return cr.caste[tonumber(caste_id)]
end
local function genBodyModifier(body_app_mod)
local a=math.random(0,#body_app_mod.ranges-2)
return math.random(body_app_mod.ranges[a],body_app_mod.ranges[a+1])
end
local function getBodySize(caste,time)
--TODO: real body size...
return caste.body_size_1[#caste.body_size_1-1] --returns last body size
end
local function genAttribute(array)
local a=math.random(0,#array-2)
return math.random(array[a],array[a+1])
end
local function norm()
return math.sqrt((-2)*math.log(math.random()))*math.cos(2*math.pi*math.random())
end
local function normalDistributed(mean,sigma)
return mean+sigma*norm()
end
local function clampedNormal(min,median,max)
local val=normalDistributed(median,math.sqrt(max-min))
if val<min then return min end
if val>max then return max end
return val
end
local function makeSoul(unit,caste)
local tmp_soul=df.unit_soul:new()
tmp_soul.unit_id=unit.id
tmp_soul.name:assign(unit.name)
tmp_soul.race=unit.race
tmp_soul.sex=unit.sex
tmp_soul.caste=unit.caste
--todo: preferences,traits.
local attrs=caste.attributes
for k,v in pairs(attrs.ment_att_range) do
local max_percent=attrs.ment_att_cap_perc[k]/100
local cvalue=genAttribute(v)
tmp_soul.mental_attrs[k]={value=cvalue,max_value=cvalue*max_percent}
end
for k,v in pairs(tmp_soul.personality.traits) do
local min,mean,max
min=caste.personality.a[k]
mean=caste.personality.b[k]
max=caste.personality.c[k]
tmp_soul.personality.traits[k]=clampedNormal(min,mean,max)
end
--[[natural skill fix]]
for k, skill in ipairs(caste.natural_skill_id) do
local rating = caste.natural_skill_lvl[k]
utils.insert_or_update(tmp_soul.skills,
{new=true,id=skill,experience=caste.natural_skill_exp[k],rating=rating}, 'id')
end
unit.status.souls:insert("#",tmp_soul)
unit.status.current_soul=tmp_soul
end
local function CreateUnit(race_id,caste_id,unit_age)
local race=df.creature_raw.find(race_id)
if race==nil then error("Invalid race_id") end
unit_age = unit_age or 15
local caste
local unit=df.unit:new()
-- Pick a random caste is none are set
if nil == caste_id then
caste_id = getRandomCasteId(race_id)
end
caste = getCaste(race_id,caste_id)
unit:assign{
race=race_id,
caste=caste_id,
sex=caste.gender,
}
unit.relations.birth_year=df.global.cur_year-unit_age --AGE is set here
if caste.misc.maxage_max==-1 then
unit.relations.old_year=-1
else
unit.relations.old_year=df.global.cur_year+math.random(caste.misc.maxage_min,caste.misc.maxage_max)
end
unit.relations.birth_time=df.global.cur_year_tick
--unit.relations.old_time=?? --TODO add normal age
--[[ interataction stuff, probably timers ]]--
local num_inter=#caste.body_info.interactions -- new for interactions
unit.curse.own_interaction:resize(num_inter) -- new for interactions
unit.curse.own_interaction_delay:resize(num_inter) -- new for interactions
--[[ body stuff ]]
local body=unit.body
body.body_plan=caste.body_info
local body_part_count=#body.body_plan.body_parts
local layer_count=#body.body_plan.layer_part
--[[ body components ]]
local cp=body.components
cp.body_part_status:resize(body_part_count)
cp.numbered_masks:resize(#body.body_plan.numbered_masks)
for num,v in ipairs(body.body_plan.numbered_masks) do
cp.numbered_masks[num]=v
end
cp.layer_status:resize(layer_count)
cp.layer_wound_area:resize(layer_count)
cp.layer_cut_fraction:resize(layer_count)
cp.layer_dent_fraction:resize(layer_count)
cp.layer_effect_fraction:resize(layer_count)
local attrs=caste.attributes
for k,v in pairs(attrs.phys_att_range) do
local max_percent=attrs.phys_att_cap_perc[k]/100
local cvalue=genAttribute(v)
unit.body.physical_attrs[k]={value=cvalue,max_value=cvalue*max_percent}
end
body.blood_max=getBodySize(caste,0) --TODO normal values
body.blood_count=body.blood_max
body.infection_level=0
unit.status2.body_part_temperature:resize(body_part_count)
for k,v in pairs(unit.status2.body_part_temperature) do
unit.status2.body_part_temperature[k]={new=true,whole=10067,fraction=0}
end
--[[ largely unknown stuff ]]
local stuff=unit.enemy
stuff.body_part_878:resize(body_part_count) -- all = 3
stuff.body_part_888:resize(body_part_count) -- all = 3
stuff.body_part_relsize:resize(body_part_count) -- all =0
stuff.were_race=race_id
stuff.were_caste=caste_id
stuff.normal_race=race_id
stuff.normal_caste=caste_id
stuff.body_part_8a8:resize(body_part_count) -- all = 1
stuff.body_part_base_ins:resize(body_part_count)
stuff.body_part_clothing_ins:resize(body_part_count)
stuff.body_part_8d8:resize(body_part_count)
--TODO add correct sizes. (calculate from age)
local size=caste.body_size_2[#caste.body_size_2-1]
body.size_info.size_cur=size
body.size_info.size_base=size
body.size_info.area_cur=math.pow(size,0.666)
body.size_info.area_base=math.pow(size,0.666)
body.size_info.area_cur=math.pow(size*10000,0.333)
body.size_info.area_base=math.pow(size*10000,0.333)
unit.recuperation.healing_rate:resize(layer_count)
--appearance
local app=unit.appearance
app.body_modifiers:resize(#caste.body_appearance_modifiers) --3
for k,v in pairs(app.body_modifiers) do
app.body_modifiers[k]=genBodyModifier(caste.body_appearance_modifiers[k])
end
app.bp_modifiers:resize(#caste.bp_appearance.modifier_idx) --0
for k,v in pairs(app.bp_modifiers) do
app.bp_modifiers[k]=genBodyModifier(caste.bp_appearance.modifiers[caste.bp_appearance.modifier_idx[k]])
end
--app.unk_4c8:resize(33)--33
app.tissue_style:resize(#caste.bp_appearance.style_part_idx)
app.tissue_style_civ_id:resize(#caste.bp_appearance.style_part_idx)
app.tissue_style_id:resize(#caste.bp_appearance.style_part_idx)
app.tissue_style_type:resize(#caste.bp_appearance.style_part_idx)
app.tissue_length:resize(#caste.bp_appearance.style_part_idx)
app.genes.appearance:resize(#caste.body_appearance_modifiers+#caste.bp_appearance.modifiers) --3
app.genes.colors:resize(#caste.color_modifiers*2) --???
app.colors:resize(#caste.color_modifiers)--3
makeSoul(unit,caste)
--finally set the id
unit.id=df.global.unit_next_id
df.global.unit_next_id=df.global.unit_next_id+1
df.global.world.units.all:insert("#",unit)
df.global.world.units.active:insert("#",unit)
return unit
end
local function findRace(name)
for k,v in pairs(df.global.world.raws.creatures.all) do
if v.creature_id==name then
return k
end
end
qerror("Race:"..name.." not found!")
end
local function createFigure(trgunit,he,he_group)
local hf=df.historical_figure:new()
hf.id=df.global.hist_figure_next_id
hf.race=trgunit.race
hf.caste=trgunit.caste
hf.profession = trgunit.profession
hf.sex = trgunit.sex
df.global.hist_figure_next_id=df.global.hist_figure_next_id+1
hf.appeared_year = df.global.cur_year
hf.born_year = trgunit.relations.birth_year
hf.born_seconds = trgunit.relations.birth_time
hf.curse_year = trgunit.relations.curse_year
hf.curse_seconds = trgunit.relations.curse_time
hf.birth_year_bias = trgunit.relations.birth_year_bias
hf.birth_time_bias = trgunit.relations.birth_time_bias
hf.old_year = trgunit.relations.old_year
hf.old_seconds = trgunit.relations.old_time
hf.died_year = -1
hf.died_seconds = -1
hf.name:assign(trgunit.name)
hf.civ_id = trgunit.civ_id
hf.population_id = trgunit.population_id
hf.breed_id = -1
hf.unit_id = trgunit.id
df.global.world.history.figures:insert("#",hf)
hf.info = df.historical_figure_info:new()
hf.info.unk_14 = df.historical_figure_info.T_unk_14:new() -- hf state?
--unk_14.region_id = -1; unk_14.beast_id = -1; unk_14.unk_14 = 0
hf.info.unk_14.unk_18 = -1; hf.info.unk_14.unk_1c = -1
-- set values that seem related to state and do event
--change_state(hf, dfg.ui.site_id, region_pos)
--lets skip skills for now
--local skills = df.historical_figure_info.T_skills:new() -- skills snap shot
-- ...
hf.info.skills = {new=true}
he.histfig_ids:insert('#', hf.id)
he.hist_figures:insert('#', hf)
if he_group then
he_group.histfig_ids:insert('#', hf.id)
he_group.hist_figures:insert('#', hf)
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=he_group.id,link_strength=100})
end
trgunit.flags1.important_historical_figure = true
trgunit.flags2.important_historical_figure = true
trgunit.hist_figure_id = hf.id
trgunit.hist_figure_id2 = hf.id
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=trgunit.civ_id,link_strength=100})
--add entity event
local hf_event_id=df.global.hist_event_next_id
df.global.hist_event_next_id=df.global.hist_event_next_id+1
df.global.world.history.events:insert("#",{new=df.history_event_add_hf_entity_linkst,year=trgunit.relations.birth_year,
seconds=trgunit.relations.birth_time,id=hf_event_id,civ=hf.civ_id,histfig=hf.id,link_type=0})
return hf
end
local function allocateNewChunk(hist_entity)
hist_entity.save_file_id=df.global.unit_chunk_next_id
df.global.unit_chunk_next_id=df.global.unit_chunk_next_id+1
hist_entity.next_member_idx=0
print("allocating chunk:",hist_entity.save_file_id)
end
local function allocateIds(nemesis_record,hist_entity)
if hist_entity.next_member_idx==100 then
allocateNewChunk(hist_entity)
end
nemesis_record.save_file_id=hist_entity.save_file_id
nemesis_record.member_idx=hist_entity.next_member_idx
hist_entity.next_member_idx=hist_entity.next_member_idx+1
end
local function createNemesis(trgunit,civ_id,group_id)
local id=df.global.nemesis_next_id
local nem=df.nemesis_record:new()
nem.id=id
nem.unit_id=trgunit.id
nem.unit=trgunit
nem.flags:resize(4)
--not sure about these flags...
-- [[
nem.flags[4]=true
nem.flags[5]=true
nem.flags[6]=true
nem.flags[7]=true
nem.flags[8]=true
nem.flags[9]=true
--]]
--[[for k=4,8 do
nem.flags[k]=true
end]]
nem.unk10=-1
nem.unk11=-1
nem.unk12=-1
df.global.world.nemesis.all:insert("#",nem)
df.global.nemesis_next_id=id+1
trgunit.general_refs:insert("#",{new=df.general_ref_is_nemesisst,nemesis_id=id})
trgunit.flags1.important_historical_figure=true
nem.save_file_id=-1
local he=df.historical_entity.find(civ_id)
he.nemesis_ids:insert("#",id)
he.nemesis:insert("#",nem)
local he_group
if group_id~=-1 then
he_group=df.historical_entity.find(group_id)
end
if he_group then
he_group.nemesis_ids:insert("#",id)
he_group.nemesis:insert("#",nem)
end
allocateIds(nem,he)
nem.figure=createFigure(trgunit,he,he_group)
end
-- Do the placement, returns the freshly spawned unit
function place(args)
if not args.race then
qerror("Please provide a race")
end
local pos = {}
if args.position then
pos.x=args.position[1]
pos.y=args.position[2]
pos.z=args.position[3]
else
pos = copyall(df.global.cursor)
end
if pos.x == -30000 then
qerror("Point your pointy thing somewhere")
end
local i
local race_id = findRace(args.race)
local u = CreateUnit(race_id,args.caste,args.age)
u.pos:assign(pos)
if args.name then
u.name.first_name = args.name
u.name.has_name = true
end
if args.cid_id then args.civ_id = tonumber(args.civ_id) end
local group_id
if df.global.gamemode == df.game_mode.ADVENTURE then
u.civ_id = args.civ_id or df.global.world.units.active[0].civ_id
group_id = -1
else
u.civ_id = args.civ_id or df.global.ui.civ_id
end
if args.civ_id == -1 then
group_id = group_id or -1
else
group_id = group_id or df.global.ui.group_id
-- If a friendly animal, make it domesticated. From Boltgun & Dirst
local caste=df.creature_raw.find(u.race).caste[u.caste]
if not(caste.flags.CAN_SPEAK and caste.flags.CAN_LEARN) then
-- Fix friendly animals (from Boltgun)
u.flags2.resident = false;
u.flags3.body_temp_in_range = true;
u.population_id = -1
u.status.current_soul.unit_id = u.id
u.animal.population.region_x = -1
u.animal.population.region_y = -1
u.animal.population.unk_28 = -1
u.animal.population.population_idx = -1
u.animal.population.depth = -1
u.counters.soldier_mood_countdown = -1
u.counters.death_cause = -1
u.enemy.anon_4 = -1
u.enemy.anon_5 = -1
u.enemy.anon_6 = -1
-- And make them tame (from Dirst)
u.flags1.tame = true
u.training_level = 7
end
end
local desig,ocupan = dfhack.maps.getTileFlags(pos)
if ocupan.unit then
ocupan.unit_grounded = true
u.flags1.on_ground = true
else
ocupan.unit = true
end
if df.historical_entity.find(u.civ_id) ~= nil then
createNemesis(u, u.civ_id,group_id)
end
return u
end
validArgs = validArgs or utils.invert({
'help',
'race',
'caste',
'age',
'name',
'position',
'civ_id',
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print([[scripts/spawn-unit.lua
arguments
-help
print this help message
-race <RACE_ID>
The raw id of the creature's race, mandatory
-caste <number>
The caste's number, optional
-age <number>
The unit's age in years, defaults to 15 if omitted
-name <doggy>
The unit's name, optional
-position [ x y z ]
The unit's position, will try to use the cursor if ommited
-civ_id
The unit's civilisation, will be the player's if ommited
]])
return
end
if args.race then
place(args) --Creature (ID), caste (number), age, name, x,y,z , civ_id(-1 for enemy, optional) for spawn.
end
Sorry, I have only been able to loosely follow what has been going on with the spawn unit script, so these questions may have already been answered.1. Yes. Give the animal a civ_id of -1 to make it hostile. You'll need to escape it as \-1 on the command line.
1. Does it allow for spawning of both friendly and hostile animals?
2. Does it allow for spawning of hostile entity creatures (they don't have to be entity members, but just CAN_SPEAK or CAN_LEARN invaders?)
3. Does it allow for spawning of friendly civ members? (from what I have read this is still a no)
4. Does the friendly and hostile animals extend to semi and megabeasts?
Nice cleanup Dirst, I'll use that one.
I also added orientation in my local. Creatures spawn asexual so animals will have the 'marry' flag for the opposite sex as true and intelligent creatures will be based on raws. I think we are getting to the stability of the 0.34 version of this script.
Second, syndrome-trigger doesn't seem to be able to find named syndromes defined in regional interactions. I don't know how to use a regional interaction to apply a syndrome defined in a material. Is there an event I could hook into instead that would fire when a creature (preferably a certain type) appears on the map?I was looking around the Lua API, and it sounds like Eventful's onSyndrome callback might be able to hear stuff done by regional interactions. Anyone happen to know if it's just the same interface that syndrome-trigger uses?
I was just thinking of creating a trade helper but stuck on finding a function that returns an item's trade value. So long I just found a function that returns an item's base value, and two functions that returns an item's improvements value and dye value in trade respectively. And a struct that seemingly contains a caravan's trade value modifiers, but which I can't fathom its meaning. Am I missing anything here?The various skills involved in assessing value and negotiating for said value, the mental attributes associated with said skills/involved directly,
Come to think of it, is there a command or something to change a regional interaction?Oh dear, that's a hell of an idea, though I think that stuff is a pain to hack that directly, much less permanently.
Say an evil biome has thralling clouds, could you change the clouds into say.....skin necroses? Maybe healing for good biomes?
I was just thinking of creating a trade helper but stuck on finding a function that returns an item's trade value. So long I just found a function that returns an item's base value, and two functions that returns an item's improvements value and dye value in trade respectively. And a struct that seemingly contains a caravan's trade value modifiers, but which I can't fathom its meaning. Am I missing anything here?The various skills involved in assessing value and negotiating for said value, the mental attributes associated with said skills/involved directly,the presence of an accidentally activated pressure washing system, uh, I assume the trade value modifiers are the stuff requested for next year right?
I was looking around the Lua API, and it sounds like Eventful's onSyndrome callback might be able to hear stuff done by regional interactions. Anyone happen to know if it's just the same interface that syndrome-trigger uses?
Thanks!
I was just thinking of creating a trade helper but stuck on finding a function that returns an item's trade value. So long I just found a function that returns an item's base value, and two functions that returns an item's improvements value and dye value in trade respectively. And a struct that seemingly contains a caravan's trade value modifiers, but which I can't fathom its meaning. Am I missing anything here?The various skills involved in assessing value and negotiating for said value, the mental attributes associated with said skills/involved directly,the presence of an accidentally activated pressure washing system, uh, I assume the trade value modifiers are the stuff requested for next year right?
Ughhh... I think I'll just shelve it until I've got time to do !!SCIENCE!! with that. And thanks.
On another note, do anyone knows how to do binary search on a sorted vector? (namely, df.global.world.plants.* vectors). There is a binary search function in utils.lua but it only supports lua functions as comparators and the vectors are sorted by address. My current workaroud is to use tostring(element) to get a string containing the elements' addresses but I fear such a filthy workaround could break at any time.
I was just thinking of creating a trade helper but stuck on finding a function that returns an item's trade value. So long I just found a function that returns an item's base value, and two functions that returns an item's improvements value and dye value in trade respectively. And a struct that seemingly contains a caravan's trade value modifiers, but which I can't fathom its meaning. Am I missing anything here?The various skills involved in assessing value and negotiating for said value, the mental attributes associated with said skills/involved directly,the presence of an accidentally activated pressure washing system, uh, I assume the trade value modifiers are the stuff requested for next year right?
Ughhh... I think I'll just shelve it until I've got time to do !!SCIENCE!! with that. And thanks.
On another note, do anyone knows how to do binary search on a sorted vector? (namely, df.global.world.plants.* vectors). There is a binary search function in utils.lua but it only supports lua functions as comparators and the vectors are sorted by address. My current workaroud is to use tostring(element) to get a string containing the elements' addresses but I fear such a filthy workaround could break at any time.
df.(type).find(id)
to lethosor: Yes, df.plant.find() treats the parameter as the index of an object in df.global.world.plants.all, and df.plant.find(ind) is equivalent to df.global.world.plants.all[ind] (iterated through the vector and it's true for every object inside it on game load)
to lethosor: Yes, df.plant.find() treats the parameter as the index of an object in df.global.world.plants.all, and df.plant.find(ind) is equivalent to df.global.world.plants.all[ind] (iterated through the vector and it's true for every object inside it on game load)
No, it's plant id, not index in .all. The two are are important to distinguish, at least in most cases.
Hi. Long time lurker. I thought I'd post a little Windows - 0.40.24-r3 only plugin/hack for Adventure Mode Region Teleportation.
-snip-
Questions:
1. If I give a unit several interactions is it possible to tell them not to use them all right away? Can I give them any logic behind using them? (besides the USAGE_HINT) Or staggering their usage?
2. Is there a function for computing the weight of a unit? I know there is the dfhack.units functions for figuring out speed and age and such, wondering if there is one for weight.
3. If I use add a syndrome with add-syndrome command with modtools/item-trigger -onEquip is it smart enough to know to remove the syndrome when the item is unequiped or do I need to add an -onUnequip version?
4. Similarly, does -onEquip only work if the actual inventory changes? What happens if I use another script to change one of the items material or subtype? Will it still run -onEquip or -onUnequip?
5. Does -onStrike only run if the target is wounded? What about if the attack is blocked/parried/dodged?
6. With the decoupling of movement and attack speeds, does CE_SPEED_CHANGE still affect both or just movement?
7. I am planning on either making a seperate plugin or an addition to the item-trigger script by allowing for -onParry and -onBlock. Currently the only way I see to do that is by using the eventful onReport and parsing the report for the required information. Is there another way to do it? Possibly an onAction event? I suppose if I make it a seperate plugin I could make it something like action-trigger and allow for dodging and such too?
I have no choice but to load from the seasonal autosave backup folders.What do you mean? What's wrong with your original save folder (the one without a date appended)?
when I load the initial save that is not in a backup folder it still saves(vanilla quit/dfhack quicksave) to the last backup folder listed if it saves.Are you saying that DF is saving to a different folder than the one you loaded from? To make sure you're loading the correct world, what's displayed if you run ":lua print(dfhack.getSavePath())" ?
also when I check the details view of my save folder the current folder's date modified is the time I performed the quit save(haven't checked with the quicksave) and no other save folder would have a matching time.If the original folder (without a date) is being updated, I'm not sure what the issue is.
Are you saying that DF is saving to a different folder than the one you loaded from? To make sure you're loading the correct world, what's displayed if you run ":lua print(dfhack.getSavePath())" ?sorry I misspoke, I haven't tried quicksave on the inital save.
What do you mean? What's wrong with your original save folder (the one without a date appended)?the inital save folder still has the inital save from embark, it does not update this folder. I got the first save folder and then the backups from the begining from each season.
modtools/item-trigger -checkInventoryEvery 1 -material CREATURE_MAT:GREAT_GREY_WOLF:COVENANT -command [ modtools/add-syndrome -syndrome abysswalker -target \\UNIT_ID ] -onEquip
[USE_MATERIAL_TEMPLATE:COVENANT:METAL_TEMPLATE]
[STATE_NAME_ADJ:ALL_SOLID:abysswalker]
[STATE_NAME_ADJ:LIQUID:abysswalker]
[STATE_NAME_ADJ:GAS:abysswalker]
[PREFIX:ancient]
in the proper filesand dfhack keep saying 'attempted to index a nil value'
... Fortress 0.40.24/hack/scripts/modtools/item-trigger.lua:62: attempt to index
a nil value
stack traceback:
... Fortress 0.40.24/hack/scripts/modtools/item-trigger.lua:62: in funct
ion 'handler'
... Fortress 0.40.24/hack/scripts/modtools/item-trigger.lua:102: in func
tion 'equipHandler'
... Fortress 0.40.24/hack/scripts/modtools/item-trigger.lua:111: in func
tion <... Fortress 0.40.24/hack/scripts/modtools/item-trigger.lua:105>
--modifies a specific unit to make it domesticated (and available for pet adoption)
--[=[
argument
<UNIT_ID> The creature to be domesticated, mandatory
Made by Dirst for use in The Earth Strikes Back mod
Intended use is to automatically domesticate all new instances of specific species.
TO DO:
Find a method to apply this script to all new members of the target species.
--]=]
args = {...}
local critter = df.unit.find(tonumber(args[1]))
if critter.civ_id == -1 then
if df.global.gamemode == df.game_mode.ADVENTURE then
critter.civ_id = df.global.world.units.active[0].civ_id
else
critter.civ_id = df.global.ui.civ_id
critter.flags2.resident = false;
critter.flags3.body_temp_in_range = true;
critter.population_id = -1
critter.status.current_soul.unit_id = critter.id
critter.animal.population.region_x = -1
critter.animal.population.region_y = -1
critter.animal.population.unk_28 = -1
critter.animal.population.population_idx = -1
critter.animal.population.depth = -1
critter.counters.soldier_mood_countdown = -1
critter.counters.death_cause = -1
critter.enemy.anon_4 = -1
critter.enemy.anon_5 = -1
critter.enemy.anon_6 = -1
end
critter.flags1.tame = true
critter.training_level = 7
-- Verbose for troubleshooting purposes.
print("Critter (unit# "..args[1]..") has been domesticated.")
else
print("Critter (unit# "..args[1]..") is not wild.")
end
-- Automatically tames any wild specimens of a specific species
--[=[
argument
<CREATURE_TOKEN> The creature type to be domesticated, mandatory
Made by Dirst originally for use in The Earth Strikes Back mod
--]=]
args = {...}
local function findRace(name)
for k,v in pairs(df.global.world.raws.creatures.all) do
if v.creature_id==name then
return k
end
end
qerror("Race:"..name.." not found!")
end
critter = findRace(args[1])
function checkForCritter()
for k,v in ipairs(df.global.world.units.active) do
if v.race == critter then
if v.civ_id == -1 then
if df.global.gamemode == df.game_mode.ADVENTURE then
v.civ_id = df.global.world.units.active[0].civ_id
else
v.civ_id = df.global.ui.civ_id
v.flags2.resident = false;
v.flags3.body_temp_in_range = true;
v.population_id = -1
v.status.current_soul.unit_id = v.id
v.animal.population.region_x = -1
v.animal.population.region_y = -1
v.animal.population.unk_28 = -1
v.animal.population.population_idx = -1
v.animal.population.depth = -1
v.counters.soldier_mood_countdown = -1
v.counters.death_cause = -1
v.enemy.anon_4 = -1
v.enemy.anon_5 = -1
v.enemy.anon_6 = -1
end
v.flags1.tame = true
v.training_level = 7
end
end
end
end
require('repeat-util').scheduleEvery('onAction',1,'ticks',checkForCritter)
Boltgun and Meph, I'm pretty sure the problem was the self-targeting interaction rather than catching the syndrome. I've never had much luck with self-targeting interactions for whatever reason. What surprised me was that a probability 100 regional interaction didn't appear when it was the only option for that biome. Interactions just hate me. At least the Lua code works.
plant
A tool for creating shrubs, growing, or getting rid of them.
Subcommands:
create: Create a new shrub/sapling.
grow: Make saplings grow into trees.
extirpate: Kills trees and shrubs, turning them into ashes instantly.
immolate: Similar to extirpate, but sets the plants on fire instead. The fires can and will spread ;)
It's sort of a moot point now, though I'd like to know if I just plain did the interactions wrong. These are the two interactions, though they wouldn't both be active at the same time.Boltgun and Meph, I'm pretty sure the problem was the self-targeting interaction rather than catching the syndrome. I've never had much luck with self-targeting interactions for whatever reason. What surprised me was that a probability 100 regional interaction didn't appear when it was the only option for that biome. Interactions just hate me. At least the Lua code works.
Can you post your interaction?
interaction_tesb
[OBJECT:INTERACTION]
This interaction serves as a hook for a syndrome-trigger.
[INTERACTION:DOMESTICATE PET ROCK]
[I_SOURCE:REGION]
[IS_REGION:ANY]
[IS_FREQUENCY:100]
[I_TARGET:A:CREATURE]
[IT_LOCATION:CONTEXT_CREATURE]
[IT_AFFECTED_CREATURE:PET_ROCK:ALL]
[IT_CANNOT_TARGET_IF_ALREADY_AFFECTED]
[I_EFFECT:ADD_SYNDROME]
[IE_TARGET:A]
[IE_INTERMITTENT:WEEKLY]
[SYNDROME]
[SYN_NAME:Adorable pet rock]
[CE_MENT_ATTR_CHANGE:PATIENCE:200:1000:START:0]
[INTERACTION:GO_DOMESTIC]
[I_SOURCE:CREATURE_ACTION]
[I_TARGET:ME:CREATURE]
[IT_LOCATION:CONTEXT_CREATURE]
[IT_CANNOT_TARGET_IF_ALREADY_AFFECTED]
[I_EFFECT:ADD_SYNDROME]
[IE_TARGET:ME]
[SYNDROME]
[SYN_CLASS:TESB_DOMESTICATE]
[SYN_NAME:Adorable Pet Rock]
[CE_MENT_ATTR_CHANGE:PATIENCE:200:1000:START:0]
I never did have much luck getting those ones to work either.
So uh, I was trying to figure out for a while how the heck the reaction "imbue with material" I recall having at one point worked only to realize it was done through a script, apparently it was folded at least partially into another script but I can't figure out how to get one that makes something "Vaci Sunaclotho's skull helm" like the reaction one did, is that the only way to make it keep the name/body part stuff?
I recall playing with it some time back and accidentally making a roc feather dagger and such, was that broken by one of the more recent updates or am I just not looking in the right spot?
It's sort of a moot point now, though I'd like to know if I just plain did the interactions wrong. These are the two interactions, though they wouldn't both be active at the same time.Boltgun and Meph, I'm pretty sure the problem was the self-targeting interaction rather than catching the syndrome. I've never had much luck with self-targeting interactions for whatever reason. What surprised me was that a probability 100 regional interaction didn't appear when it was the only option for that biome. Interactions just hate me. At least the Lua code works.
Can you post your interaction?Code: (interaction_tesb.txt) [Select]interaction_tesb
[OBJECT:INTERACTION]
This interaction serves as a hook for a syndrome-trigger.
[INTERACTION:DOMESTICATE PET ROCK]
[I_SOURCE:REGION]
[IS_REGION:ANY]
[IS_FREQUENCY:100]
[I_TARGET:A:CREATURE]
[IT_LOCATION:CONTEXT_CREATURE]
[IT_AFFECTED_CREATURE:PET_ROCK:ALL]
[IT_CANNOT_TARGET_IF_ALREADY_AFFECTED]
[I_EFFECT:ADD_SYNDROME]
[IE_TARGET:A]
[IE_INTERMITTENT:WEEKLY]
[SYNDROME]
[SYN_NAME:Adorable pet rock]
[CE_MENT_ATTR_CHANGE:PATIENCE:200:1000:START:0]
[INTERACTION:GO_DOMESTIC]
[I_SOURCE:CREATURE_ACTION]
[I_TARGET:ME:CREATURE]
[IT_LOCATION:CONTEXT_CREATURE]
[IT_CANNOT_TARGET_IF_ALREADY_AFFECTED]
[I_EFFECT:ADD_SYNDROME]
[IE_TARGET:ME]
[SYNDROME]
[SYN_CLASS:TESB_DOMESTICATE]
[SYN_NAME:Adorable Pet Rock]
[CE_MENT_ATTR_CHANGE:PATIENCE:200:1000:START:0]
And in onload.init:
modtools/syndrome-trigger -syndrome "Adorable pet rock" -command [ tesb-domesticate \\UNIT_ID ]
which I know works when run from the console. The regional one might have misfired because regional interactions just don't pop up as often as modders would like them to. The self-interacting one probably misfired because the critter has an [IMMOBILE] tag, which seems to inhibit all interactions.
The whole reason I needed the script in the first place is that immobile wild animals can't get themselves caught in traps, and I really want these guys to be adoptable. There is also a condition under which they'll be spawn-unit'ed, but those start out tame anyway.
Box: What's wrong with teleport.lua? It was working for me the last time I checked (which was at least after v0.40.20, if not v0.40.24).
teleport -x 44 -y 55 -z 167
That might be what was wrong - I tried to get coords with "teleport showpos", but that also just returned tracebacks.You have to include the hyphen: "teleport -showpos"
...sktop\Shortcuts\Dwarf Fortress\40.24\hack\lua\dfhack.lua:454: ...Shortcuts\Dw
arf Fortress\40.24/hack/scripts/teleport.lua:15: syntax error near '=='
stack traceback:
[C]: in function 'error'
...sktop\Shortcuts\Dwarf Fortress\40.24\hack\lua\dfhack.lua:454: in func
tion <...sktop\Shortcuts\Dwarf Fortress\40.24\hack\lua\dfhack.lua:425>
(...tail calls...)
[REACTION:LUA_HOOK_IMBUE_MAT]
[NAME:imbue with material]
[ADVENTURE_MODE_ENABLED]
[REAGENT:material source:1:NONE:NONE:NONE:NONE]
[REAGENT:item:1:NONE:NONE:NONE:NONE][PRESERVE_REAGENT]
[PRODUCT:100:1:ROCK:NONE:GET_MATERIAL_FROM_REAGENT:material source:NONE]
/home/thefunk/.dfwl/hack/scripts/base_imbueitem.lua:53: attempt to index local 'product' (a nil value)
stack traceback:
/home/thefunk/.dfwl/hack/scripts/base_imbueitem.lua:53: in function '?'
./hack/lua/plugins/eventful.lua:49: in function <./hack/lua/plugins/eventful.lua:47>
/home/thefunk/.dfwl/hack/scripts/base_imbueitem.lua:53: attempt to index local 'product' (a nil value)
It looks like you've made modifications to teleport.lua - the script in the most recent release (https://github.com/DFHack/dfhack/blob/master/scripts/teleport.lua#L15) doesn't have "==" anywhere on that line. Try replacing the script with that version (clicking the "Raw" button will allow you to save it more easily).
That's item base value; the material value of all cheeses in-game is 5, AFAIK, so that seems right.
Oh. It's not counting stack size.
For what it's worth, you can simplify that by using dfhack.gui.getSelectedItem().
I cannot see how that could possibly happen from changing the subtype of a single item. What exactly did you do for the short sword?
Is it possible to use dfhack when running df in text mode?Technically speaking, that is using DFHack.
It runs, but the only way to run commands is with dfhack-run, which is annoying.
Thanks.Is it possible to use dfhack when running df in text mode?Technically speaking, that is using DFHack.
It runs, but the only way to run commands is with dfhack-run, which is annoying.
The command-prompt plugin should work, but you'd have to invoke it with dfhack-run as well since DFHack keybindings (bound with the "keybinding" command) rely on SDL. It would be possible to modify the plugin to add a keybinding to the main fortress mode menu (or other screens, although they'd have to be implemented individually) - I'll look at including this in the next release.
I'm interested in retrieving a dwarf's hairstyles and facial features using dfhack. After looking at the source code of stonesense I am under the impression these values are stored in "unit.appearance.tissue_style". At first I thought the values are in the same order as they appear in the white segment of the character description, but the values of dwarves that have the same styles do not match up. Could someone tell me how these values are matched to what you can read on the character description screen?It's weird, I grant you. The values of the properties themselves are visible in the string dump, in order:Spoiler: Dwarf 1 (click to show/hide)Spoiler: Dwarf 2 (click to show/hide)
unk_4cc - tissue style
unk_4dc - civ_id
unk_4ec -??
unk_4fc -??
unk_50c - lenght?
bp_modifiers->caste.bp_appearance.modifiers[caste.bp_appearance.modifier_idx[k]]
And a script called "find_hair.lua"local race=465
local modifiers={}
local modifiers_idx={}
local caste=df.creature_raw.find(race).caste[1]
local bp=caste.bp_appearance
local unit=dfhack.gui.getSelectedUnit()
for k,v in pairs(bp.modifiers) do
if v.noun=='hair' then
print(k,df.appearance_modifier_type[v.type])
modifiers_idx[k]=true
table.insert(modifiers,v)
end
end
for k,v in pairs(bp.modifier_idx) do
if modifiers_idx[v] then
print(k,v)
end
end
for anyone who cares :Pgui/gm-editor is the go-to for quick tweaks, especially when you're an illiterate dong who can't operate lua from the command line like me. K-cursor a dwarf and punch it in, it'll jump straight to the unit vector.
e: Oh and just plain deduction. One's 3 is double-braided and the other's is combed, find the 2 in one and 0 in the other.
Second, thanks to your pointing out what I was missing I've just about got a perfected script to allow a createitem type script to make artifacts with proper records and names and decorations and all that noise but I'm tired so I'll work out the last few bits later.
spawn something while controlling a creature
It's a shame it can't spawn plant growths
I'm interested in retrieving a dwarf's hairstyles and facial features using dfhack. After looking at the source code of stonesense I am under the impression these values are stored in "unit.appearance.tissue_style". At first I thought the values are in the same order as they appear in the white segment of the character description, but the values of dwarves that have the same styles do not match up. Could someone tell me how these values are matched to what you can read on the character description screen?Spoiler: Dwarf 1 (click to show/hide)Spoiler: Dwarf 2 (click to show/hide)
Spawning something while controlling a creature...
If I go into arena mode, spawn a creature and put my cursor over it, I can spawn an item with createitem. If I assume control of that creature, createitem will still work and it will spawn an item at my feet.
On the other hand, it seems I can't do this with gui/hack-wish. If I try spawning an item while I'm a creature it says "A unit needs to be selected to use hackwish".
df::unit *unit = Gui::getSelectedUnit(out, true);
if (!unit)
{
if (*gametype == game_type::ADVENTURE_ARENA || World::isAdventureMode())
{
// Use the adventurer unit
unit = world->units.active[0];
}
local utils = require 'utils'
validArgs = validArgs or utils.invert({
'help',
'material',
'item',
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print(
[[artifuckery.lua
arguments:
-help
print this help message
-material matstring
specify the material of the item to be created
examples:
INORGANIC:IRON
CREATURE_MAT:DWARF:BRAIN
PLANT_MAT:MUSHROOM_HELMET_PLUMP:DRINK
-item itemstr
specify the itemdef of the item to be created
examples:
WEAPON:ITEM_WEAPON_PICK
]])
return
end
args.creator = df.global.world.units.active[0]
if not args.item then
error 'Invalid item.'
end
local itemType = dfhack.items.findType(args.item)
if itemType == -1 then
error 'Invalid item.'
end
local itemSubtype = dfhack.items.findSubtype(args.item)
args.material = dfhack.matinfo.find(args.material)
if not args.material then
error 'Invalid material.'
end
local item = dfhack.items.createItem(itemType, itemSubtype, args.material['type'], args.mate
rial.index, args.creator)
local base=df.global.world.items.all[2015] --I know there's a way to pick up the item made by the function above
df.global.world.artifacts.all:new()
df.global.world.artifacts.all:insert('#',{new=df.artifact_record})
local facts = df.global.world.artifacts.all
for _,k in ipairs(facts) do
if k.id==0 then
local fake=k
fake.id=df.global.artifact_next_id
--fake.name = --I bet I can get these randomly generated huh
--fake.flags = {new=df.bitarray} --still not sure how to get these to populate but they're all false anyways...
fake.item = {new=base}
fake.anon_1 = -1000000
fake.anon_2 = -1000000
fake.anon_3 = -1000000
fake.item.flags.artifact=true
base.flags.artifact=true
if fake.item == 'WEAPON' then item:setSharpness(1,0) end
if base == 'WEAPON' then item:setSharpness(1,0) end
fake.item:setQuality(5)
base:setQuality(5)
--fake.item.itemdecoration or something needs to be added but they randomize on first viewing happily
--base.itemdecoration there's also gotta be a way to have base copy over fully to fake instead of just portions
df.global.artifact_next_id=df.global.artifact_next_id+1
end
end
function weapon()
df.global.world.units.active[0].flags1.has_mood=true
df.global.world.units.active[0].mood=0
df.global.world.units.active[0].job.current_job.job_type=57
df.global.world.units.active[0].job.mood_skill=27
df.global.world.units.active[0].job.current_job.job_items[0].mat_type=0 --went with a cheap solution
df.global.world.units.active[0].job.current_job.job_items[0].mat_index=8 --my first success was a coal battle axe >.<
end
-- ---------------------------------------------------------------------------
function armor()
df.global.world.units.active[0].flags1.has_mood=true
df.global.world.units.active[0].mood=0
df.global.world.units.active[0].job.current_job.job_type=57
df.global.world.units.active[0].job.mood_skill=28
df.global.world.units.active[0].job.current_job.job_items[0].mat_type=0
df.global.world.units.active[0].job.current_job.job_items[0].mat_index=8
I've got worlds which are generated with the exact same seeds and such, same raws, all that jazz for region8, 9, etc but none of them get past the screen where the job timer would count down after selecting the materials/using the artifake script. Keep having to devel/pop-screen out of it. Yet I go back to the first folder I tried it on and it just cranks em out all day long.
...maybeMeh... not over 9 thousAND!
(https://i.imgur.com/MtP3GTv.png)
Wait... What is that power level?I think it's a reference to Dragonball Z.
I understood that, but how it's calculated (size+hash_of_name? :D)Wait... What is that power level?I think it's a reference to Dragonball Z.
if args.name then do
fake.name.first_name = args.name
fake.name.language = 0
fake.name.has_name = true
end
end
Made a weapon named Buttscratcher and a shield named Armybreaker as expected, I was gonna see about having it parse and split up the string but then I realized I was being derpy and I can just have it call up a prompt and populate that with the name options can't I?
Didn't notice the name-making code in sparking.lua, eh?It doesn't look like that would do what I was thinking of though, which was trying to do a similar trick you did with hack-wish except populate the prompt with say, word, forms, racechoice, translated word, move to next part of name or something along those lines.
Can you use modtools/item-trigger with the hardcoded jewelry, or only with items that have subtypes?
Haha, yeah, quick check of that tells me you may want a proper viewscreen with a proper searchable list for that. 2172 words means paging through is killer. It shouldn't be hard at all to get a list of every valid part of speech for a word, though, since word.flags[part_of_speech_num] tells you whether it's valid.Yup, I was looking to see how to pull up the viewscreen_layer_choose_language_namest, my first try did get a new screen pulled up but my naive attempts at populating it by just copying the entries and whatnot from the adventurer name choice screen didn't quite work.
a = df.new(df.viewscreen_setupadventurest) ; a.subscreen = 3 ; gui = require 'gui' ; gui.simulateInput(a, 'A_RANDOM_NAME') ; gui.simulateInput(a, 'A_CUST_NAME')
If I correctly understood what you're talking about here, there's a trick, try this one-liner:OMFG YOU ARE A GODDAMN WIZARDNINJA!Code: [Select]a = df.new(df.viewscreen_setupadventurest) ; a.subscreen = 3 ; gui = require 'gui' ; gui.simulateInput(a, 'A_RANDOM_NAME') ; gui.simulateInput(a, 'A_CUST_NAME')
local gui = require 'gui'
function getTargetFromScreens()
local my_trg
if dfhack.gui.getCurFocus() == 'item' then
my_trg=dfhack.gui.getCurViewscreen().item
elseif dfhack.gui.getCurFocus() == 'dwarfmode/LookAround/Flow' then
local t_look=df.global.ui_look_list.items[df.global.ui_look_cursor]
my_trg=t_look.flow
elseif dfhack.gui.getSelectedUnit(true) then
my_trg=dfhack.gui.getSelectedUnit(true)
elseif dfhack.gui.getSelectedItem(true) then
my_trg=dfhack.gui.getSelectedItem(true)
end
return my_trg
end
function getNameFromTrg(my_trg)
local trg = my_trg
if trg == 'item' then
if general_refs[0].artifact_id then
local aid = trg.general_refs[0].artifact_id
local nname = df.global.world.artifacts.all[aid].name
elseif trg == 'unit' then
local nname = trg.name
end
end
return nname
end
a = df.new(df.viewscreen_setupadventurest) ; a.subscreen = 3 ; gui = require 'gui' ;
gui.simulateInput(a, 'A_RANDOM_NAME') ; gui.simulateInput(a, 'A_CUST_NAME') ; gui.sendInputToParent(a, 'nname')
function getNewName()
local n = dfhack.gui.getCurViewscreen()
if n == df.viewscreen_layer_choose_language_namest then
local nn = n.name
end
return nn
end
nn = nname
I assumed that would take nn (being the name from the choose screen I think) and send it to nname (being the name from the current target) but it ain't doing it yet.
function getNewName()
local n = dfhack.gui.getCurViewscreen()
if n._type == df.viewscreen_layer_choose_language_namest then
return n.name
end
end
There are multiple errors in your code, it should be something likeWell yeah, I'm kinda poking around making up a lot of it from what I've seen on the lua api and in other scripts+what seems like it might work, just realized I had the bit I was trying to have grab the artifact name trying to use the id for the index so I had to rejigger that.Code: [Select]function getNewName()
local n = dfhack.gui.getCurViewscreen()
if n._type == df.viewscreen_layer_choose_language_namest then
return n.name
end
end
In my example, you'll need to add a:delete() because the adventurer screen has been created, even if you don't see it ;)
/home/thefunk/.dfwl/hack/scripts/names.lua:34: ha ha, nope, suck it max
3. Ok *fix those that pop up until the script runs* right, let's get started!local gui = require 'gui'
function getTargetFromScreens()
local old = dfhack.gui.getCurViewscreen()
if old._type == viewscreen_itemst then
if old.item.general_refs[0] then
local aid = old.item.general_refs[0].artifact_id
local facts = df.global.world.artifacts.all
for _,v in facts do
if v.id == aid then
local nold = facts[v].name
elseif old._type == viewscreen_dungeon_monsterstatusst then
local nold = old.unit.name
end
end
end
end
return nold
end
print(nold)
a = df.new(df.viewscreen_setupadventurest) ; a.subscreen = 3 ; gui = require 'gui' ;
gui.simulateInput(a, 'A_RANDOM_NAME') ; gui.simulateInput(a, 'A_CUST_NAME')
function getNewName()
local n = dfhack.gui.getCurViewscreen()
if n._type == df.viewscreen_layer_choose_language_namest then
local new = n.name
nold = new
end
end
print(new)
It's weird because if I do parts of what I think should get the right target it seems right, like gui/gm-editor dfhack.gui.getCurViewscreen().item pulls it up like I expect it to but I'm clearly missing something needed to get it to pass that along to the next part.a = df.new(df.viewscreen_setupadventurest) ; a.subscreen = 3 ; gui = require 'gui' ; gui.simulateInput(a, 'A_RANDOM_NAME') ; gui.simulateInput(a, 'A_CUST_NAME')
function getNewName()
local n = dfhack.gui.getCurViewscreen()
if df.viewscreen_layer_choose_language_namest:is_instance(n) then
local newn = n.name
end
return newn
end
if dfhack.gui.getCurViewscreen().parent == df.viewscreen_itemst then
local trg = dfhack.gui.getCurViewscreen().parent.item.general_refs[0].artifact_id
local fact = df.artifact_record.find(trg)
local oldn = fact.name
elseif dfhack.gui.getCurViewscreen().parent == df.viewscreen_dungeon_monsterstatusst then
local trg = dfhack.gui.getCurViewscreen().parent.unit
local oldn = trg.name
return oldn
end
newn = oldn
name_change = defclass(name_change, choices)
choices = df.new(df.viewscreen_setupadventurest) ; choices.subscreen = 3 ; gui = require 'gui' ; gui.simulateInput(choices, 'A_RANDOM_NAME') ; gui.simulateInput(choices, 'A_CUST_NAME')
function name_change:init()
local n = dfhack.gui.getCurViewscreen()
end
function name_change:postinit()
if df.viewscreen_layer_choose_language_namest:is_instance(n) then
local newn = n.name
end
return newn
end
if dfhack.gui.getCurViewscreen().parent == df.viewscreen_itemst then
local trg = dfhack.gui.getCurViewscreen().parent.item.general_refs[0].artifact_id
local fact = df.artifact_record.find(trg)
local oldn = fact.name
elseif dfhack.gui.getCurViewscreen().parent == df.viewscreen_dungeon_monsterstatusst then
local trg = dfhack.gui.getCurViewscreen().parent.unit
local oldn = trg.name
return oldn
end
function name_change:onInput(keys)
if keys.SELECT then
newn = oldn
elseif keys.LEAVESCREEN then
if newn ~= oldn then
newn = oldn
self:dismiss()
choices:dismiss()
end
end
end
FamilyNode=defclass(FamilyNode)
FamilyNode.ATTRS {
histfig_id = DEFAULT_NIL,
mother = DEFAULT_NIL,
father = DEFAULT_NIL,
spouse = DEFAULT_NIL,
children = {}
}
function FamilyNode:clean()
local remove_table={}
for k,v in pairs(self.children) do
if v.mother~=self and v.father~=self then
remove_table[k]=true
end
end
for k,v in pairs(remove_table) do
self.children[k]=nil
end
self.children_nodes=nil
end
function FamilyNode:getChildrenNum()
local size=0
for k,v in pairs(self.children) do
size=size+1
end
return size
end
function FamilyNode:isVoid()
return (not self.mother and not self.father and self:getChildrenNum()==0)
end
FamilyTree=defclass(FamilyTree)
FamilyTree.ATTRS {
histfig_lookup={}
}
function FamilyTree:insertNode(node)
if self:histfigLookup(node.histfig_id) then
return self:histfigLookup(node.histfig_id)
else
self.histfig_lookup[node.histfig_id]=node
return node
end
end
function FamilyTree:mergeFamily(other_tree)
for k,v in pairs(other_tree.histfig_lookup) do
self.histfig_lookup[k]=self.histfig_lookup[k] or v
end
other_tree=self
end
function FamilyTree:histfigLookup(histfig_id)
self.histfig_lookup=self.histfig_lookup or {}
return self.histfig_lookup[histfig_id]
end
function FamilyTree:getSize()
local size=0
for k,v in pairs(self.histfig_lookup) do
size=size+1
end
return size
end
function FamilyTree:clean()
for k,v in pairs(self.histfig_lookup) do
v:clean()
if v.mother and not self:histfigLookup(v.mother.histfig_id) then
self:insertNode(v.mother)
end
if v.father and not self:histfigLookup(v.father.histfig_id) then
self:insertNode(v.father)
end
for _,child in pairs(v.children) do
if not self:histfigLookup(child.histfig_id) then
self:insertNode(child)
end
end
if v:isVoid() then
self.histfig_lookup[k]=nil
end
end
end
function FamilyTree:giveFamilyName()
local father,mother=self:findProgenitor()
local father_fig,mother_fig=df.historical_figure.find(father.histfig_id),df.historical_figure.find(mother.histfig_id)
local name_words={father_fig.name.words[0],mother_fig.name.words[1]}
local name_parts_of_speech={father_fig.name.parts_of_speech[0],mother_fig.name.parts_of_speech[1]}
for k,v in pairs(self.histfig_lookup) do
local fig=df.historical_figure.find(v.histfig_id)
fig.name.words[1]=name_words[2]
fig.name.parts_of_speech[1]=name_parts_of_speech[2]
end
end
function FamilyTree:findProgenitor()
local father,mother
for k,v in pairs(self.histfig_lookup) do --actually just returns after first one, heh
father=v.father or v
mother=v.mother or v
while father.father do
father=father.father or father
end
while mother.mother do
mother=mother.mother or mother
end
return father,mother
end
end
function getLeadingZeroes(num,numDigits)
local zeroes=numDigits-math.floor(math.log(num)/math.log(10))-1
local str=''
for i=1,zeroes do
str=str..'0'
end
return str..num
end
function getMonthDate(num)
return num~=-1 and getLeadingZeroes(math.ceil(num/33600),2)..getLeadingZeroes(math.ceil((num%33600)/1200),2) or '0000'
end
function FamilyTree:exportToFamilyScript()
local file=""
local counter=1
for k,v in pairs(self.histfig_lookup) do
print('Exporting member #'..counter..'/'..self:getSize()..', hist fig number #'..k)
local fig=df.historical_figure.find(v.histfig_id)
file=file..'i'..v.histfig_id..' g'..(fig.sex==0 and 'f' or 'm')
file=file..' p'..dfhack.TranslateName(fig.name)
file=file..' b'..getLeadingZeroes(fig.born_year,4)..getMonthDate(fig.born_seconds)
if fig.died_year~=-1 then
file=file..' z1 d'..getLeadingZeroes(fig.died_year,4)..getMonthDate(fig.died_seconds)
end
if v.mother then
file=file..' m'..v.mother.histfig_id
end
if v.father then
file=file..' f'..v.father.histfig_id
end
if v.spouse then
file=file..' s'..v.spouse.histfig_id
end
file=file..NEWLINE
counter=counter+1
end
local f=assert(io.open('family_'..self:findProgenitor().histfig_id..'.family',"w"))
f:write(file)
f:close()
end
Families=defclass(Families)
Families.ATTRS {
families={}
}
function Families:getFamilyFromHistFig(histfig_id)
self.families=self.families or {}
self.families_histfig_lookup = self.families_histfig_lookup or {}
local family=self.families_histfig_lookup[histfig_id]
if family then return family:histfigLookup(histfig_id),family end
return nil
end
function Families:insertNode(node,family)
local existingFamily=self:getFamilyFromHistFig(node.histfig_id)
if existingFamily then
return existingFamily:histfigLookup(node.histfig_id)
else
local newFamily=family or FamilyTree{}
if not family then
newFamily.histfig_lookup={}
newFamily:insertNode(node)
self.families_histfig_lookup[node.histfig_id]=newFamily
table.insert(self.families,newFamily)
else
newFamily:insertNode(node)
self.families_histfig_lookup[node.histfig_id]=newFamily
end
return node,newFamily
end
end
function Families:getFamily(hist_fig_id,family,children_only,parent)
local hist_fig=df.historical_figure.find(hist_fig_id)
local oldNode,oldfamily=self:getFamilyFromHistFig(hist_fig_id)
if oldNode then
if parent and (not oldNode.mother or not oldNode.father) then
for _,fig_link in pairs(hist_fig.histfig_links) do
if fig_link.target_hf==parent.histfig_id then
if fig_link._type==df.histfig_hf_link_motherst then
oldNode.mother=parent
elseif fig_link._type==df.histfig_hf_link_fatherst then
oldNode.father=parent
end
end
end
family:insertNode(parent)
end
return oldNode,oldfamily
end
local node,family=self:insertNode(FamilyNode{histfig_id=hist_fig_id},family)
node.children={}
if children_only and parent then
local parent_fig=df.historical_figure.find(parent.histfig_id)
if parent_fig.sex==0 then
node.mother=parent
else
node.father=parent
end
family:insertNode(parent)
end
for _,fig_link in pairs(hist_fig.histfig_links) do
if fig_link._type==df.histfig_hf_link_motherst and not children_only then
node.mother=self:getFamily(fig_link.target_hf,family,children_only)
elseif fig_link._type==df.histfig_hf_link_fatherst and not children_only then
node.father=self:getFamily(fig_link.target_hf,family,children_only)
elseif fig_link._type==df.histfig_hf_link_childst then
local childNode=self:getFamily(fig_link.target_hf,family,children_only,node)
node.children[childNode.histfig_id]=childNode
elseif fig_link._type==df.histfig_hf_link_spousest then
node.spouse=self:getFamily(fig_link.target_hf,family,children_only)
end
end
return node
end
function Families:clean()
local prevAmount=1
for i=#self.families,1,-1 do
local size=self.families[i]:getSize()
if size<2 then table.remove(self.families,i) end
prevAmount=size
end
for k,v in pairs(self.families) do
v:clean()
end
end
function Families:sort()
table.sort(self.families,function(a,b) return a:getSize()>b:getSize() end)
end
function Families:getAllHistFigs(children_only)
print('Gathering all historical figures...')
for k,v in pairs(df.global.world.history.figures) do
if k%100==0 then print('At figure #'..k..'/'..#df.global.world.history.figures) end
self:getFamily(v.id,nil,children_only)
end
self:clean()
self:clean() --two passes actually does something, weirdly enough
self:sort()
end
local utils=require('utils')
validArgs = validArgs or utils.invert({
'all',
'this',
'help',
'heritage',
'export'
})
local args = utils.processArgs({...}, validArgs)
if args.export then
if args.all then
local dlg=require('gui.dialogs')
dlg.showYesNoPrompt('Family lineage','Really export all families? (May take very long time and may cause game to hang!)',COLOR_WHITE,function()
local families=Families()
families:getAllHistFigs()
for k,v in ipairs(families.families) do
print('Exporting family of ' .. dfhack.TranslateName(df.historical_figure.find(v:findProgenitor().histfig_id).name) .. '...')
v:exportToFamilyScript()
end
end
)
end
if args.this then
local families=Families()
families:getFamily(dfhack.gui.getSelectedUnit().hist_figure_id)
families:clean()
families:clean()
for k,v in ipairs(families.families) do
print('Exporting family of ' .. dfhack.TranslateName(df.historical_figure.find(v:findProgenitor().histfig_id).name) .. '...')
v:exportToFamilyScript()
end
end
end
if args.heritage then
if args.all then
local families=Families()
families:getAllHistFigs(true)
families:clean()
for k,v in ipairs(families.families) do
local progenitor1,progenitor2=v:findProgenitor()
print('Naming family of ' .. dfhack.TranslateName(df.historical_figure.find(progenitor1.histfig_id).name) .. ' and ' .. dfhack.TranslateName(df.historical_figure.find(progenitor2.histfig_id).name)..'...')
v:giveFamilyName()
end
end
if args.this then
local families=Families()
families:getFamily(dfhack.gui.getSelectedUnit().hist_figure_id)
families:clean()
families:clean()
for k,v in ipairs(families.families) do
local progenitor1,progenitor2=v:findProgenitor()
print('Naming family of ' .. dfhack.TranslateName(df.historical_figure.find(progenitor1.histfig_id).name) .. ' and ' .. dfhack.TranslateName(df.historical_figure.find(progenitor2.histfig_id).name)..'...')
v:giveFamilyName()
end
end
end
if args.help then
print([[scripts/family.lua
arguments
-help
print this help message
-export
exports specified families to FamilyScript file
-heritage
gives family name to specified families
-all
specifies all the world's families (may crash game)
-this
specifies selected unit's family
]])
return
end
if args.help then
print([[scripts/modtools/syndrome-trigger.lua
arguments
at the end should be familynode or whatever shouldn't it?
Something completely different: Is there a way to read out how many wood/craft/gem/... jobs have been done already (aka when will the fortress become a metropolis)?There is a way, but it's very much non-trivial - all of the information is present in [df.global.]ui.tasks.recent_jobs, but you'll need to parse that information out on your own. Exact details on how the game itself does this are not available at the moment, but I can locate it (later) without too much difficulty.
I think digv is mostly obsolete with the automining features added at the same time as the priorities (there's still a use case for digv x). But I second that adding a priority to digl and digexp would be useful.digv is superior to automining in one respect: It let's me check whether the command would dig into any tiles I want to keep and then unmark those. It's not nice when my dwarves punch holes into the dining halls.
I already asked this once (and I don't remember why it was denied): It would be very useful if the commands for digging had an option to ignore anything smoothed.
function factname()
--if dfhack.gui.getCurViewscreen().parent == df.viewscreen_itemst then
newn = dfhack.gui.getCurViewscreen().name
fact = dfhack.gui.getCurViewscreen().parent.item.general_refs[0].artifact_id
trg = df.artifact_record.find(fact)
local oldn = trg.name
oldn.first_name = newn.first_name
oldn.words[0] = newn.words[0]
oldn.words[1] = newn.words[1]
oldn.words[2] = newn.words[2]
oldn.words[3] = newn.words[3]
oldn.words[4] = newn.words[4]
oldn.words[5] = newn.words[5]
oldn.words[6] = newn.words[6]
oldn.parts_of_speech[0] = newn.parts_of_speech[0]
oldn.parts_of_speech[1] = newn.parts_of_speech[1]
oldn.parts_of_speech[2] = newn.parts_of_speech[2]
oldn.parts_of_speech[3] = newn.parts_of_speech[3]
oldn.parts_of_speech[4] = newn.parts_of_speech[4]
oldn.parts_of_speech[5] = newn.parts_of_speech[5]
oldn.parts_of_speech[6] = newn.parts_of_speech[6]
oldn.language = newn.language
oldn.has_name = newn.has_name
end
function unitname()
--if dfhack.gui.getCurViewscreen().parent == df.viewscreen_dungeon_monsterstatusst then
newn = dfhack.gui.getCurViewscreen().name
oldn = dfhack.gui.getCurViewscree().parent.unit.name
oldn.first_name = newn.first_name
oldn.words[0] = newn.words[0]
oldn.words[1] = newn.words[1]
oldn.words[2] = newn.words[2]
oldn.words[3] = newn.words[3]
oldn.words[4] = newn.words[4]
oldn.words[5] = newn.words[5]
oldn.words[6] = newn.words[6]
oldn.parts_of_speech[0] = newn.parts_of_speech[0]
oldn.parts_of_speech[1] = newn.parts_of_speech[1]
oldn.parts_of_speech[2] = newn.parts_of_speech[2]
oldn.parts_of_speech[3] = newn.parts_of_speech[3]
oldn.parts_of_speech[4] = newn.parts_of_speech[4]
oldn.parts_of_speech[5] = newn.parts_of_speech[5]
oldn.parts_of_speech[6] = newn.parts_of_speech[6]
oldn.language = newn.language
oldn.has_name = newn.has_name
end
if df.viewscreen_layer_choose_language_namest:is_instance(dfhack.gui.getCurViewscreen()) then
factname()
elseif not df.viewscreen_layer_choose_language_namest:is_instance(dfhack.gui.getCurViewscreen()) then
choices = df.new(df.viewscreen_setupadventurest) ; choices.subscreen = 3 ; gui = require 'gui' ; gui.simulateInput(choices, 'A_RANDOM_NAME') ; gui.simulateInput(choices, 'A_CUST_NAME')
end
At the moment it's set to artifacts as you can see, I intend to have it grab a string sent to it for the first name, and I gotta figure out how to make it apply the change before you exit properly but right now you just run it once and it pulls up the choices, then you run it again and it commits the change.Does http://dwarffortresswiki.org/index.php/Utility:DFHack/createitem help?
Use gui/hack-wish, it's easier
No. You'd use the right item token, like HELM, SHOES and PANTS.
Use gui/hack-wish, it's easier
Can you post a link to this?
Well, there's still SHIELD. But that's the gist of it, yeah. Look up "Item tokens" on the wiki to see why.I'd like to point out that this is mentioned on the createitem page on the wiki.
Another suggestion:Roads would be slightly trickier if you want to use materials effectively, since they'd have to be built to cover groups of tiles, but it shouldn't be too hard to do with constructions (although it could be difficult to use DF's material-selection interface).
A build up of the current DF hack Construction menu addon to support the construction of 'polygonal' walls and fortifications, as well as roads.
A player would select points and DFHack automatically creates construction orders to connect them.
It would be a lot faster to check on the C++ side, actually (maybe with eventful?).Another suggestion:Roads would be slightly trickier if you want to use materials effectively, since they'd have to be built to cover groups of tiles, but it shouldn't be too hard to do with constructions (although it could be difficult to use DF's material-selection interface).
A build up of the current DF hack Construction menu addon to support the construction of 'polygonal' walls and fortifications, as well as roads.
A player would select points and DFHack automatically creates construction orders to connect them.
Button=defclass(Button,widgets.Widget)
Button.ATTRS={
on_click = DEFAULT_NIL,
graphic = DEFAULT_NIL, --refers to the name of a tilepage
label = DEFAULT_NIL
}
function Button:preUpdateLayout()
self.frame=self.frame or {}
self.frame.w=self.page.page_dim_x
self.frame.h=self.page.page_dim_y
end
function Button:onRenderBody(dc)
for k,v in ipairs(self.page.texpos) do
dc:seek(k%self.frame.w,math.floor(k/self.frame.w)):tile(32,v)
end
end
function Button:onInput(keys)
if keys._MOUSE_L_DOWN and self:getMousePos() and self.on_click then
self.on_click()
end
end
function Button:init(args)
for k,v in ipairs(df.global.texture.page) do
if v.token==self.graphic then self.page=v break end
end
end
Button{
graphic='MINE',
frame={t=0,l=0},
on_click=function()
self:sendInputToParent('D_DESIGNATE')
self:sendInputToParent('DESIGNATE_DIG')
end,
label='Mining',
view_id='mining_button'
}
local highlighted=false
for _,child in ipairs(self.subviews) do
if child:getMousePos() then self.subviews.highlight_label:setText(child.label) highlighted=true end
if child.visible then
child:render(dc)
end
end
if not highlighted then self.subviews.highlight_label:setText('Highlight a button!') end
end
[SYNDROME]
[SYN_NAME:bad]
[CE_NECROSIS:SEV:5000:PROB:100:START:1:END:300]
[CE_BLISTERS:SEV:5000:PROB:100:START:1:END:300]
[CE_BLEEDING:SEV:5000:PROB:100:START:1:END:300]
2. Yes. A "unit syndrome" is added to the unit at that point. Said "unit syndrome" has a number that links to a syndrome ID, which is a proper raws syndrome. You cannot add creature effects without a syndrome due to the nature of syndromes. Bleeding actually creates a proper wound AFAIK.
I got around the "do things based on attributes without many syndromes" thing by manually programming what I wanted it to do without syndromes.
It's entirely possible only transformation syndromes work with the current add-syndrome stuff.
local utils = require 'utils'
function checkbodycategory(unit,bp)
local parts = {}
local body = unit.body.body_plan.body_parts
for i,x in ipairs(bp) do
local a = 1
for j,y in ipairs(body) do
if y.category == x and not unit.body.components.body_part_status[j].missing then
parts[a] = j
a = a + 1
end
end
end
return parts
end
function checkbodytoken(unit,bp)
local parts = {}
local body = unit.body.body_plan.body_parts
for i,x in ipairs(bp) do
local a = 1
for j,y in ipairs(body) do
if y.token == x and not unit.body.components.body_part_status[j].missing then
parts[a] = j
a = a + 1
end
end
end
return parts
end
function checkbodyflag(unit,bp)
local parts = {}
local body = unit.body.body_plan.body_parts
for i,x in ipairs(bp) do
local a = 1
for j,y in ipairs(body) do
if y.flags[x] and not unit.body.components.body_part_status[j].missing then
parts[a] = j
a = a + 1
end
end
end
return parts
end
function checkbodylayer(unit,parts,layers)
local a = 1
local array = {}
for i,x in pairs(parts) do
local part = unit.body.body_plan.body_parts[x]
for j,y in pairs(layers) do
for k,z in pairs(part.layers) do
if z.layer_name == y or y == 'ALL' then
array[a] = {x,k,z.layer_id}
a = a+1
end
end
end
end
return array
end
function addwound(unit,array)
local body = unit.body
local wound = df.unit_wound:new()
wound.id = body.wound_next_id
body.wound_next_id = body.wound_next_id + 1
for i,x in pairs(array) do
part = df.unit_wound.T_parts:new()
part.global_layer_idx = x[3]
part.layer_idx = x[2]
part.body_part_id = x[1]
wound.parts:insert('#',part)
end
body.wounds:insert('#',wound)
end
validArgs = validArgs or utils.invert({
'help',
'category',
'token',
'flag',
'all',
'layer',
'unit',
})
local args = utils.processArgs({...}, validArgs)
if args.help then -- Help declaration
print([[wound-add.lua
Assign a wound to a specific body part and layer of a unit
arguments:
-help
print this help message
-unit id
REQUIRED
id of the target unit
-all \
target all body parts |
-category TYPE |
examples: |
TENTACLE |
HOOF_REAR |
HEAD |
-token TYPE | Must have at least one of these
examples: |
UB |
LB |
REYE |
-flag FLAG |
examples: |
SIGHT |
LIMB |
SMALL /
-layer TYPE
examples:
SKIN
FAT
MUSCLE
ALL
examples:
unit/wound-add -unit \\UNIT_ID -all -layer SKIN
unit/wound-add -unit \\UNIT_ID -token UB -layer ALL
]])
return
end
if args.unit and tonumber(args.unit) then -- Check for unit declaration !REQUIRED
unit = df.unit.find(tonumber(args.unit))
else
print('No unit selected')
return
end
dur = tonumber(args.dur) or 0 -- Check if there is a duration (default 0)
parts = {}
recall = ''
tokens = args.all or args.category or args.token or args.flag
layers = args.layer or ''
if type(layers) == 'string' then layers = {layers} end
if type(tokens) == 'string' then tokens = {tokens} end
if args.all then -- Check for the all body parts flag. !!RUN EFFECT!!
body = unit.body.body_plan.body_parts
for k,v in ipairs(body) do
parts[k] = k
end
recall = 'all'
elseif args.category then -- Check for category body parts. !!RUN CHECKBODYCATEGORY!!. !!RUN EFFECT!!
parts = checkbodycategory(unit,tokens)
recall = 'category'
elseif args.token then -- Check for token body parts. !!RUN CHECKBODYTOKEN!!. !!RUN EFFECT!!
parts = checkbodytoken(unit,tokens)
recall = 'token'
elseif args.flag then -- Check for flag body parts. !!RUN CHECKBODYFLAG!!. !!RUN EFFECT!!
parts = checkbodyflag(unit,tokens)
recall = 'flag'
end
array = checkbodylayer(unit,parts,layers)
if #array >= 1 then
addwound(unit,array)
end
Would it be possible to create a flag in Autolabor to set a certain type of labor as 'dedicated'? Like say, set "autolabor HAUL_STONE 2 4 d", where D disables all other labors in the dwarves it selects, leaving them as only stone haulers?
A generalized "HAUL" labor would also be useful, and would act as a macro that sets all of the Hauling labors to the set values.
I'd make this but sadly I have zero programming skill.
...Does it just not doing anything with the wound, or am I misunderstanding something?
Does dfhack.burrows.findByName still work?It's possible that burrows have empty names by default and the names DF generates (e.g. "Burrow 1") aren't easily available to DFHack, although I haven't checked.
I tried "Burrow 1" and "burrow 1", but both of them returned nil.
[edit*]
Well, I rename the burrow and it worked...
How often is DFHack updated? Like if I update a plugin, would it be more reasonable to provide a download of just the plugin, or hope that a new DFhack release comes out before the plugin is needed?
How often is DFHack updated? Like if I update a plugin, would it be more reasonable to provide a download of just the plugin, or hope that a new DFhack release comes out before the plugin is needed?
Oh god I just realized this is like the basis for making eye lasers of limbsplosion (via eventful trickery or something similar), targeted flesh searing, plus custom scarification, isn't it?...Does it just not doing anything with the wound, or am I misunderstanding something?
Yeah, that version just adds the wound to the correct body part and layer depending on the inputs you give it. I was just using it as a proof of concept. The version I am playing with now has options for all of the various numbers (bleeding, pain, nausea, dizziness, paralysis, numbness, swelling, impaired, contact_area, surface_area, and strain) along with options for various flags, and if you want it to be a bruise/burn/frostbite/blister/necrosis. I will upload a full version with all the bells and whistles when I get everything working well. I still have a few more ideas to add to it, like the ability to add wounds that simulate getting a body part chopped off.
Oh god I just realized this is like the basis for making eye lasers of limbsplosion (via eventful trickery or something similar), targeted flesh searing, plus custom scarification, isn't it?
local dlg=require 'gui.dialogs'
local utils = require 'utils'
validArgs = validArgs or utils.invert({
'help',
'item',
'unit',
'first'
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print(
[[names.lua
arguments:
-help
print this help message
-item
if currently targeting an item
-unit
if currently targeting a unit
-first
if a first name is desired
]])
return
end
if not df.viewscreen_layer_choose_language_namest:is_instance(dfhack.gui.getCurViewscreen()) then
choices = df.new(df.viewscreen_setupadventurest) ; choices.subscreen = 3 ; gui = require 'gui' ; gui.simulateInput(choices, 'A_RANDOM_NAME') ; gui.simulateInput(choices, 'A_CUST_NAME')
end
if args.item then
fact = dfhack.gui.getCurViewscreen().parent.item.general_refs[0].artifact_id
trg = df.artifact_record.find(fact)
end
if args.unit then
trg = dfhack.gui.getCurViewscreen().parent.unit
end
if args.first then do
trg.name.first_name = args.first
end
function newName()
newn = dfhack.gui.getCurViewscreen().name
oldn = trg.name
oldn.words[0] = newn.words[0]
oldn.words[1] = newn.words[1]
oldn.words[2] = newn.words[2]
oldn.words[3] = newn.words[3]
oldn.words[4] = newn.words[4]
oldn.words[5] = newn.words[5]
oldn.words[6] = newn.words[6]
oldn.parts_of_speech[0] = newn.parts_of_speech[0]
oldn.parts_of_speech[1] = newn.parts_of_speech[1]
oldn.parts_of_speech[2] = newn.parts_of_speech[2]
oldn.parts_of_speech[3] = newn.parts_of_speech[3]
oldn.parts_of_speech[4] = newn.parts_of_speech[4]
oldn.parts_of_speech[5] = newn.parts_of_speech[5]
oldn.parts_of_speech[6] = newn.parts_of_speech[6]
oldn.language = newn.language
oldn.has_name = newn.has_name
end
end
newName()
function firstName()
newn.first_name = args.first
end
dlg.showInputPrompt(
'Rename Target',
'Enter a new name for the target:', COLOR_GREEN,
newn.first_name,
curry(firstName, first)
)
local utils = require 'utils'
function checkbodycategory(unit,bp)
local parts = {}
local body = unit.body.body_plan.body_parts
for i,x in ipairs(bp) do
local a = 1
for j,y in ipairs(body) do
if y.category == x and not unit.body.components.body_part_status[j].missing then
parts[a] = j
a = a + 1
end
end
end
return parts
end
function checkbodytoken(unit,bp)
local parts = {}
local body = unit.body.body_plan.body_parts
for i,x in ipairs(bp) do
local a = 1
for j,y in ipairs(body) do
if y.token == x and not unit.body.components.body_part_status[j].missing then
parts[a] = j
a = a + 1
end
end
end
return parts
end
function checkbodyflag(unit,bp)
local parts = {}
local body = unit.body.body_plan.body_parts
for i,x in ipairs(bp) do
local a = 1
for j,y in ipairs(body) do
if y.flags[x] and not unit.body.components.body_part_status[j].missing then
parts[a] = j
a = a + 1
end
end
end
return parts
end
function checkbodylayer(unit,parts,layers)
local a = 1
local array = {}
for i,x in pairs(parts) do
local part = unit.body.body_plan.body_parts[x]
for j,y in pairs(layers) do
for k,z in pairs(part.layers) do
if z.layer_name == y or y == 'ALL' then
array[a] = {x,k,z.layer_id}
a = a+1
end
end
end
end
return array
end
function addwound(unit,array,numbers,effect,flags,attacker,args)
local body = unit.body
local wound = df.unit_wound:new()
wound.id = body.wound_next_id
body.wound_next_id = body.wound_next_id + 1
if attacker and tonumber(attacker) then wound.attacker_unit_id = tonumber(attacker) end
if args.severed then -- For applying wounds that remove body parts (doesn't produce severed body part)
wound.flags.severed_part = true
for i,x in pairs(array) do
part = df.unit_wound.T_parts:new()
part.global_layer_idx = x[3]
part.layer_idx = x[2]
part.body_part_id = x[1]
for j,y in pairs(numbers) do
if y and tonumber(y) then part[j] = tonumber(y) end
end
part.contact_area = 1
part.surface_perc = 0
part.strain = 0
part.cur_penetration_perc = 0
part.max_penetration_perc = 0
wound.parts:insert('#',part)
body.components.body_part_status[x[1]].missing = true
body.components.body_part_status[x[1]].muscle_damage = true
body.components.body_part_status[x[1]].muscle_loss = true
body.components.body_part_status[x[1]].bone_damage = true
body.components.body_part_status[x[1]].bone_loss = true
body.components.body_part_status[x[1]].skin_damage = true
body.components.body_part_status[x[1]].severed_or_jammed = true
body.components.layer_status[x[3]].gone = true
body.components.layer_cut_fraction[x[3]] = 10000
body.components.layer_dent_fraction[x[3]] = 10000
end
elseif args.mortal then -- For applying wounds that kill unit (not really useful, mortal wounds are all so different)
wound.flags.mortal_wound = true
body.blood_count = 0
else -- For applying all other types of wounds
for i,x in pairs(array) do
part = df.unit_wound.T_parts:new()
part.global_layer_idx = x[3]
part.layer_idx = x[2]
part.body_part_id = x[1]
for j,y in pairs(numbers) do
if y and tonumber(y) then part[j] = tonumber(y) end
end
if effect then
part.effect_type:insert('#',tonumber(df.wound_effect_type[effect[1]]))
part.effect_perc1:insert('#',tonumber(effect[2]))
part.effect_perc2:insert('#',tonumber(effect[3]))
end
if args.surface_perc >= 100 then part.flags2.entire_surface = true end
for j,y in pairs(flags) do
part.flags1[y] = true
end
wound.parts:insert('#',part)
if part.strain >= 50000 then
body.components.layer_dent_fraction[x[3]] = body.components.layer_dent_fraction[x[3]] + part.aurface_perc*part.cur_penetration_perc
body.components.layer_cut_fraction[x[3]] = body.components.layer_cut_fraction[x[3]] + part.aurface_perc*part.cur_penetration_per
elseif part.strain > 0 then
body.components.layer_cut_fraction[x[3]] = body.components.layer_cut_fraction[x[3]] + part.aurface_perc*part.cur_penetration_perc
elseif part.strain == 0 and effect then
body.components.layer_effect_fraction[x[3]] = body.components.layer_effect_fraction[x[3]] + part.aurface_perc*part.effect_perc1[0]
end
if part.strain >= 50000 and part.cur_penetration_per >= 100 then
body.components.layer_wound_area[x[3]] = body.components.layer_wound_area[x[3]] + part.contact_area
end
end
end
body.wounds:insert('#',wound)
end
end
validArgs = validArgs or utils.invert({
'help',
'category',
'token',
'flag',
'all',
'layer',
'unit',
'bleeding',
'pain',
'nausea',
'dizziness',
'paralysis',
'numbness',
'swelling',
'impaired',
'strain',
'contact_area',
'surface_perc',
'penetration',
'effect',
'attacker',
'flags',
'mortal',
'severed',
'infection',
})
local args = utils.processArgs({...}, validArgs)
if args.help then -- Help declaration
print([[wound-add.lua
Assign a wound to a specific body part and layer of a unit
arguments:
-help
print this help message
-unit id
REQUIRED
id of the target unit
-attacker id
-all \
target all body parts |
-category TYPE |
examples: |
TENTACLE |
HOOF_REAR |
HEAD |
-token TYPE | Must have at least one of these
examples: |
UB |
LB |
REYE |
-flag FLAG |
examples: |
SIGHT |
LIMB |
SMALL /
-layer TYPE
examples:
SKIN
FAT
MUSCLE
ALL
-bleeding #
set bleeding amount for all layers
-pain #
set pain amount for all layers
-nausea #
set nausea amount for all layers
-dizziness #
set dizziness amount for all layers
-paralysis #
set paralysis amount for all layers
-numbness #
set numbness amount for all layers
-swelling #
set swelling amount for all layers
-impaired #
set impaired amount for all layers
-strain #
set strain level for all layers
-contact_area #
set contact area of wound for all layers
-surface_perc #
set surface area affected percentage for all layers
-penetration #
set penetration depth percentage for all layers
-effect [ type # # ]
set what type of wound it is, numbers are percentages, unknown their exact affect
valid types
Bruise
Burn
Frostbite
Melting
Boiling
Freezing
Condensation
Necrosis
Blister
-flags [ flags ]
set which flags are toggled for the wound
valid flags
cut
smashed
scar_cut
scar_smashed
tendon_bruised
tendon_strained
tendon_torn
ligament_bruised
ligament_sprained
ligament_torn
motor_nerve_severed
sensory_nerve_severed
edged_damage
smashed_apart
major_artery
guts_spilled
edged_shake1
scar_edged_shake1
edged_shake2
broken
scar_broken
gouged
blunt_shake1
scar_blunt_shake1
blunt_shake2
joint_bend1
scar_joint_bend1
joint_bend2
compound_fracture
overlapping_fracture
artery
-mortal
sets the wound as a mortal wound (kills the unit by lack of blood)
-severed
sets the body part as severed and removes it (severed body part is not created)
examples:
unit/wound-add -unit \\UNIT_ID -all -layer SKIN -pain 20 -surface_perc 100 -effect [ Burn 100 100 ]
unit/wound-add -unit \\UNIT_ID -token UB -layer ALL -bleeding 10 -penetration 100 -contact_area 25 -surface_perc 30 -flags [ cut edged_damage ]
]])
return
end
if args.unit and tonumber(args.unit) then -- Check for unit declaration !REQUIRED
unit = df.unit.find(tonumber(args.unit))
else
print('No unit selected')
return
end
dur = tonumber(args.dur) or 0 -- Check if there is a duration (default 0)
parts = {}
recall = ''
tokens = args.all or args.category or args.token or args.flag
layers = args.layer or ''
if type(layers) == 'string' then layers = {layers} end
if type(tokens) == 'string' then tokens = {tokens} end
if args.all then -- Check for the all body parts flag. !!RUN EFFECT!!
body = unit.body.body_plan.body_parts
for k,v in ipairs(body) do
parts[k] = k
end
recall = 'all'
elseif args.category then -- Check for category body parts. !!RUN CHECKBODYCATEGORY!!. !!RUN EFFECT!!
parts = checkbodycategory(unit,tokens)
recall = 'category'
elseif args.token then -- Check for token body parts. !!RUN CHECKBODYTOKEN!!. !!RUN EFFECT!!
parts = checkbodytoken(unit,tokens)
recall = 'token'
elseif args.flag then -- Check for flag body parts. !!RUN CHECKBODYFLAG!!. !!RUN EFFECT!!
parts = checkbodyflag(unit,tokens)
recall = 'flag'
end
local numbers = {}
numbers.bleeding = args.bleeding
numbers.pain = args.pain
numbers.nausea = args.nausea
numbers.dizziness = args.dizziness
numbers.paralysis = args.paralysis
numbers.numbness = args.numbness
numbers.swelling = args.swelling
numbers.impaired = args.impaired
numbers.strain = args.strain
numbers.contact_area = args.contact_area
numbers.surface_perc = args.surface_perc
numbers.cur_penetration_perc = args.penetration
numbers.max_penetration_perc = args.penetration
if args.severed then layers = {'ALL'} end
parts_and_layers = checkbodylayer(unit,parts,layers)
if #parts_and_layers >= 1 then
addwound(unit,parts_and_layers,numbers,args.effect,args.flags,args.attacker,args)
end
attack -defender id -attacker -id -target RUA -weapon EQUIPPED
And the correct numbers for the wound would get calculated and applied to the defender.
local utils = require 'utils'
function checkconnectedparts(unit,parts)
for i,x in pairs(parts) do
for j,y in pairs(unit.body.body_plan.body_parts) do
if y.con_part_id == x then
table.insert(parts,j)
end
end
end
return parts
end
function checkbodycategory(unit,bp)
local parts = {}
local body = unit.body.body_plan.body_parts
for i,x in ipairs(bp) do
local a = 1
for j,y in ipairs(body) do
if y.category == x and not unit.body.components.body_part_status[j].missing then
parts[a] = j
a = a + 1
end
end
end
return parts
end
function checkbodytoken(unit,bp)
local parts = {}
local body = unit.body.body_plan.body_parts
for i,x in ipairs(bp) do
local a = 1
for j,y in ipairs(body) do
if y.token == x and not unit.body.components.body_part_status[j].missing then
parts[a] = j
a = a + 1
end
end
end
return parts
end
function checkbodyflag(unit,bp)
local parts = {}
local body = unit.body.body_plan.body_parts
for i,x in ipairs(bp) do
local a = 1
for j,y in ipairs(body) do
if y.flags[x] and not unit.body.components.body_part_status[j].missing then
parts[a] = j
a = a + 1
end
end
end
return parts
end
function checkbodylayer(unit,parts,layers)
local a = 1
local array = {}
for i,x in pairs(parts) do
local part = unit.body.body_plan.body_parts[x]
for j,y in pairs(layers) do
for k,z in pairs(part.layers) do
if z.layer_name == y or y == 'ALL' then
array[a] = {x,k,z.layer_id}
a = a+1
end
end
end
end
return array
end
function addwound(unit,array,numbers,effect,flags,attacker,args)
local body = unit.body
local wound = df.unit_wound:new()
wound.id = body.wound_next_id
body.wound_next_id = body.wound_next_id + 1
if attacker and tonumber(attacker) then wound.attacker_unit_id = tonumber(attacker) end
if args.severed then -- For applying wounds that remove body parts (doesn't produce severed body part)
wound.flags.severed_part = true
for i,x in pairs(array) do
part = df.unit_wound.T_parts:new()
part.global_layer_idx = x[3]
part.layer_idx = x[2]
part.body_part_id = x[1]
for j,y in pairs(numbers) do
if y and tonumber(y) then part[j] = tonumber(y) end
end
part.contact_area = 1
part.surface_perc = 0
part.strain = 0
part.cur_penetration_perc = 0
part.max_penetration_perc = 0
wound.parts:insert('#',part)
body.components.body_part_status[x[1]].missing = true
body.components.body_part_status[x[1]].muscle_damage = true
body.components.body_part_status[x[1]].muscle_loss = true
body.components.body_part_status[x[1]].bone_damage = true
body.components.body_part_status[x[1]].bone_loss = true
body.components.body_part_status[x[1]].skin_damage = true
body.components.body_part_status[x[1]].severed_or_jammed = true
body.components.layer_status[x[3]].gone = true
body.components.layer_cut_fraction[x[3]] = 10000
body.components.layer_dent_fraction[x[3]] = 10000
end
elseif args.mortal then -- For applying wounds that kill unit (not really useful, mortal wounds are all so different)
wound.flags.mortal_wound = true
body.blood_count = 0
else -- For applying all other types of wounds
for i,x in pairs(array) do
part = df.unit_wound.T_parts:new()
part.global_layer_idx = x[3]
part.layer_idx = x[2]
part.body_part_id = x[1]
for j,y in pairs(numbers) do
if y and tonumber(y) then part[j] = tonumber(y) end
end
if effect then
part.effect_type:insert('#',tonumber(df.wound_effect_type[effect[1]]))
part.effect_perc1:insert('#',tonumber(effect[2]))
part.effect_perc2:insert('#',tonumber(effect[3]))
end
if args.surface_perc >= 100 then part.flags2.entire_surface = true end
for j,y in pairs(flags) do
part.flags1[y] = true
end
wound.parts:insert('#',part)
if part.strain >= 50000 then
body.components.layer_dent_fraction[x[3]] = body.components.layer_dent_fraction[x[3]] + part.aurface_perc*part.cur_penetration_perc
body.components.layer_cut_fraction[x[3]] = body.components.layer_cut_fraction[x[3]] + part.aurface_perc*part.cur_penetration_per
elseif part.strain > 0 then
body.components.layer_cut_fraction[x[3]] = body.components.layer_cut_fraction[x[3]] + part.aurface_perc*part.cur_penetration_perc
elseif part.strain == 0 and effect then
body.components.layer_effect_fraction[x[3]] = body.components.layer_effect_fraction[x[3]] + part.aurface_perc*part.effect_perc1[0]
end
if part.strain >= 50000 and part.cur_penetration_per >= 100 then
body.components.layer_wound_area[x[3]] = body.components.layer_wound_area[x[3]] + part.contact_area
end
end
body.wounds:insert('#',wound)
end
end
validArgs = validArgs or utils.invert({
'help',
'category',
'token',
'flag',
'all',
'layer',
'unit',
'bleeding',
'pain',
'nausea',
'dizziness',
'paralysis',
'numbness',
'swelling',
'impaired',
'strain',
'contact_area',
'surface_perc',
'penetration',
'effect',
'attacker',
'flags',
'mortal',
'severed',
'infection',
})
local args = utils.processArgs({...}, validArgs)
if args.help then -- Help declaration
print([[wound-add.lua
Assign a wound to a specific body part and layer of a unit
arguments:
-help
print this help message
-unit id
REQUIRED
id of the target unit
-attacker id
-all \
target all body parts |
-category TYPE |
examples: |
TENTACLE |
HOOF_REAR |
HEAD |
-token TYPE | Must have at least one of these
examples: |
UB |
LB |
REYE |
-flag FLAG |
examples: |
SIGHT |
LIMB |
SMALL /
-layer TYPE
examples:
SKIN
FAT
MUSCLE
ALL
-bleeding #
set bleeding amount for all layers
-pain #
set pain amount for all layers
-nausea #
set nausea amount for all layers
-dizziness #
set dizziness amount for all layers
-paralysis #
set paralysis amount for all layers
-numbness #
set numbness amount for all layers
-swelling #
set swelling amount for all layers
-impaired #
set impaired amount for all layers
-strain #
set strain level for all layers
-contact_area #
set contact area of wound for all layers
-surface_perc #
set surface area affected percentage for all layers
-penetration #
set penetration depth percentage for all layers
-effect [ type # # ]
set what type of wound it is, numbers are percentages, unknown their exact affect
valid types
Bruise
Burn
Frostbite
Melting
Boiling
Freezing
Condensation
Necrosis
Blister
-flags [ flags ]
set which flags are toggled for the wound
valid flags
cut
smashed
scar_cut
scar_smashed
tendon_bruised
tendon_strained
tendon_torn
ligament_bruised
ligament_sprained
ligament_torn
motor_nerve_severed
sensory_nerve_severed
edged_damage
smashed_apart
major_artery
guts_spilled
edged_shake1
scar_edged_shake1
edged_shake2
broken
scar_broken
gouged
blunt_shake1
scar_blunt_shake1
blunt_shake2
joint_bend1
scar_joint_bend1
joint_bend2
compound_fracture
overlapping_fracture
artery
-mortal
sets the wound as a mortal wound (kills the unit by lack of blood)
-severed
sets the body part as severed and removes it (severed body part is not created)
examples:
unit/wound-add -unit \\UNIT_ID -all -layer SKIN -pain 20 -surface_perc 100 -effect [ Burn 100 100 ]
unit/wound-add -unit \\UNIT_ID -token UB -layer ALL -bleeding 10 -penetration 100 -contact_area 25 -surface_perc 30 -flags [ cut edged_damage ]
]])
return
end
if args.unit and tonumber(args.unit) then -- Check for unit declaration !REQUIRED
unit = df.unit.find(tonumber(args.unit))
else
print('No unit selected')
return
end
dur = tonumber(args.dur) or 0 -- Check if there is a duration (default 0)
parts = {}
recall = ''
tokens = args.all or args.category or args.token or args.flag
layers = args.layer or ''
if type(layers) == 'string' then layers = {layers} end
if type(tokens) == 'string' then tokens = {tokens} end
if args.all then -- Check for the all body parts flag. !!RUN EFFECT!!
body = unit.body.body_plan.body_parts
for k,v in ipairs(body) do
parts[k] = k
end
recall = 'all'
elseif args.category then -- Check for category body parts. !!RUN CHECKBODYCATEGORY!!. !!RUN EFFECT!!
parts = checkbodycategory(unit,tokens)
recall = 'category'
elseif args.token then -- Check for token body parts. !!RUN CHECKBODYTOKEN!!. !!RUN EFFECT!!
parts = checkbodytoken(unit,tokens)
recall = 'token'
elseif args.flag then -- Check for flag body parts. !!RUN CHECKBODYFLAG!!. !!RUN EFFECT!!
parts = checkbodyflag(unit,tokens)
recall = 'flag'
end
local numbers = {}
numbers.bleeding = args.bleeding
numbers.pain = args.pain
numbers.nausea = args.nausea
numbers.dizziness = args.dizziness
numbers.paralysis = args.paralysis
numbers.numbness = args.numbness
numbers.swelling = args.swelling
numbers.impaired = args.impaired
numbers.strain = args.strain
numbers.contact_area = args.contact_area
numbers.surface_perc = args.surface_perc
numbers.cur_penetration_perc = args.penetration
numbers.max_penetration_perc = args.penetration
if args.severed then parts = checkconnectedparts(unit,parts) end
if args.severed then layers = {'ALL'} end
parts_and_layers = checkbodylayer(unit,parts,layers)
if #parts_and_layers >= 1 then
addwound(unit,parts_and_layers,numbers,args.effect,args.flags,args.attacker,args)
end
local utils = require 'utils'
validArgs = validArgs or utils.invert({
'help',
'material',
'item',
'name',
'r',
'l'
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print(
[[artifake.lua
arguments:
-help
print this help message
-material matstring
specify the material of the item to be created
examples:
INORGANIC:IRON
CREATURE_MAT:DWARF:BRAIN
PLANT_MAT:MUSHROOM_HELMET_PLUMP:DRINK
-item itemstring
specify the itemdef of the item to be created
examples:
WEAPON:ITEM_WEAPON_PICK
-name namestring
specify a first name if desired
-r
for right handed gloves
-l
for left handed gloves
]])
return
end
if dfhack.gui.getSelectedUnit(true) then
args.creator = dfhack.gui.getSelectedUnit()
else args.creator = df.global.world.units.active[0]
end
if not args.item then
error 'Invalid item.'
end
local itemType = dfhack.items.findType(args.item)
if itemType == -1 then
error 'Invalid item.'
end
local itemSubtype = dfhack.items.findSubtype(args.item)
args.material = dfhack.matinfo.find(args.material)
if not args.material then
error 'Invalid material.'
end
local item = dfhack.items.createItem(itemType, itemSubtype, args.material['type'], args.material.index, args.creator)
local base=df.item.find(df.global.item_next_id-1)
df.global.world.artifacts.all:new()
df.global.world.artifacts.all:insert('#',{new=df.artifact_record})
local facts = df.global.world.artifacts.all
for _,k in ipairs(facts) do
if k.id==0 then
local fake=k
fake.id=df.global.artifact_next_id
fake.item = {new=base}
fake.item.flags.artifact = true
fake.item.flags.artifact_mood = true
fake.item.id = base.id
fake.item.general_refs:insert('#',{new = df.general_ref_is_artifactst})
fake.item.general_refs[0].artifact_id = fake.id
fake.item.spec_heat = base.spec_heat
fake.item.ignite_point = base.ignite_point
fake.item.heatdam_point = base.heatdam_point
fake.item.colddam_point = base.colddam_point
fake.item.boiling_point = base.boiling_point
fake.item.fixed_temp = base.fixed_temp
fake.item.weight = base.weight
fake.item.weight_fraction = base.weight_fraction
fake.item.improvements:insert('#',{new = df.itemimprovement_spikesst,mat_type=25,mat_index=474,quality=0,skill_rating=15})
fake.item.improvements:insert('#',{new = df.itemimprovement_spikesst,mat_type=25,mat_index=493,quality=0,skill_rating=15})
fake.item.improvements:insert('#',{new = df.itemimprovement_art_imagest,mat_type=22,mat_index=474,quality=5,skill_rating=15})
fake.item.improvements:insert('#',{new = df.itemimprovement_art_imagest,mat_type=42,mat_index=480,quality=5,skill_rating=15})
fake.item.improvements:insert('#',{new = df.itemimprovement_art_imagest,mat_type=22,mat_index=497,quality=5,skill_rating=15})
fake.anon_1 = -1000000
fake.anon_2 = -1000000
fake.anon_3 = -1000000
base.flags.artifact = true
base.flags.artifact_mood = true
base.general_refs = fake.item.general_refs
base.improvements = fake.item.improvements
fake.item:setQuality(5)
base:setQuality(5)
if fake.item == 'WEAPON' then item:setSharpness(1,0) end
if base == 'WEAPON' then item:setSharpness(1,0) end
df.global.artifact_next_id=df.global.artifact_next_id+1
df.global.world.history.events:new()
df.global.world.history.events:insert('#',{new=df.history_event_artifact_createdst,
year = df.global.cur_year,
seconds = df.global.cur_year_tick_advmode,
id = df.global.hist_event_next_id,
artifact_id = fake.id,
unit_id = args.creator.id,
hfid = args.creator.hist_figure_id,
}
)
df.global.hist_event_next_id = df.global.hist_event_next_id+1
if args.r then
base.handedness[0] = true
fake.item.handedness[0] = true
end
if args.l then
base.handedness[1] = true
fake.item.handedness[1] = true
end
if args.name then do
fake.name.first_name = args.name
fake.name.language = 0
fake.name.has_name = true
end
end
end
end
I remembered I never put in the -r and -l args for gauntlet handedness as well as fixing them so they properly show up in legends mode:O.o
I just realized you could make a flaming weapon which can add burns and burning type wounds to targeted areas with some hackery, but I can't remember if the on_fire tag is under wounds or not...
unit/body-change -unit id -flag GRASP -fire
Will turn a units hands on fire.It only runs some tests; actually building DFHack would take much longer than 20-30 seconds.appveyor supports msvc 2010 and perl
The main concern when this was mentioned before is setting up the build environment - it would be hard to find a free solution that offers CMake, perl/LibXML/LibXSLT, gcc45/MSVC 2010, etc.
for i,x in pairs(defender.inventory) do
if x.mode == 2 then
if checkcoverage(defender,target_part_id,x) then
function checkcoverage(unit,bp_id,inventory_item)
covers = false
item = inventory_item.item
itype = df.item_type[item:getType()]
base_bp_id = inventory_item.body_part_id
if base_bp_id == bp_id then
covers = true
return covers
end
step = 0
connect = {base_bp_id}
if itype == 'ARMOR' then
ubstep = item.subtype.ubstep
while step < ubstep do
temp = {}
for i,x in pairs(unit.body.body_plan.body_parts) do
for j,y in pairs(connect) do
if x.con_part_id == y and not x.flags.LOWERBODY and not x.flags.HEAD and not x.flags.GRASP then
if i == bp_id then
covers = true
return covers
else
table.insert(temp,i)
end
end
end
end
connect = temp
step = step + 1
end
step = 0
for i,x in pairs(unit.body.body_plan.body_parts) do
if x.flags.LOWERBODY then
base_bp_id = i
break
end
end
if base_bp_id == bp_id then
covers = true
return covers
end
connect = {base_bp_id}
lbstep = item.subtype.lbstep
while step < lbstep do
temp = {}
for i,x in pairs(unit.body.body_plan.body_parts) do
for j,y in pairs(connect) do
if x.con_part_id == y and not x.flags.UPPERBODY and not x.flags.STANCE then
if i == bp_id then
covers = true
return covers
else
table.insert(temp,i)
end
end
end
end
connect = temp
step = step + 1
end
elseif itype == 'HELM' then
return covers
elseif itype == 'GLOVES' then
upstep = item.subtype.upstep
while step < upstep do
temp = {}
for i,x in pairs(unit.body.body_plan.body_parts) do
for j,y in pairs(connect) do
if x.con_part_id == y and not x.flags.UPPERBODY and not x.flags.LOWERBODY then
if i == bp_id then
covers = true
return covers
else
table.insert(temp,i)
end
end
end
end
connect = temp
step = step + 1
end
elseif itype == 'SHOES' then
upstep = item.subtype.upstep
while step < upstep do
temp = {}
for i,x in pairs(unit.body.body_plan.body_parts) do
for j,y in pairs(connect) do
if x.con_part_id == y and not x.flags.UPPERBODY and not x.flags.LOWERBODY then
if i == bp_id then
covers = true
return covers
else
table.insert(temp,i)
end
end
end
end
connect = temp
step = step + 1
end
elseif itype == 'PANTS' then
lbstep = item.subtype.lbstep
while step < lbstep do
temp = {}
for i,x in pairs(unit.body.body_plan.body_parts) do
for j,y in pairs(connect) do
if x.con_part_id == y and not x.flags.UPPERBODY and not x.flags.STANCE then
if i == bp_id then
covers = true
return covers
else
table.insert(temp,i)
end
end
end
end
connect = temp
step = step + 1
end
end
return covers
end
In that case, would anyone be willing to educate me on what exactly the ub/up/lbstep values do? I know that, for example, a chest piece with a ubstep of 0 will only protect the upper body, and a chest piece with a ubstep of 1 will protect the upper body and upper arms. Is it just simply, you take the body part that the piece of armor is attached to, and then, for each increase in ubstep you move out one connected body part? So for a creature with just one part arms, their whole arm would be protected by a ubstep of 1, but a dwarf would need a ubstep of 2?
Did anything happen to "adv-bodyswap"have you tried out Dfusion's Body swap script that should still work. Adv-Bodyswap was someone else attempt at that code with mix results.
Can't seem to preform it at it's current v40.24.
Code: [Select]df.global.world.history.events:new()
df.global.world.history.events:insert('#',{new=df.history_event_hf_attacked_sitest,
year = whenever,
seconds = whatever,
id = df.global.hist_event_next_id,
site = you get the idea,
hfid = beast.id,
}
)
df.global.hist_event_next_id = df.global.hist_event_next_id+1
does this actually do anything
Er my bad, where would I get the script?Did anything happen to "adv-bodyswap"have you tried out Dfusion's Body swap script that should still work. Adv-Bodyswap was someone else attempt at that code with mix results.
Can't seem to preform it at it's current v40.24.
This question seems more appropriate here.I slapped in the same basic layout for artifakes and it made them show up in legends properly. As long as those links are intact it should show up right. If you want to double check pull up the location with gui/gm-editor df.global.world.history.events dot whatever entry you're targeting and make sure you didn't miss a field in the entries.Spoiler (click to show/hide)
I'm trying to make a creature that won't spawn naturally show up during worldgen, as if these historical sites were doing the same kinds of things that a player fort could do to get them to show up. (They show up when a boil-away stone is mined, but that's not important for this discussion).
If I spawn a nemesis and figure out how to place it at a historical site during worldgen, will adding a "rampage" event at that time cause the creature to actually cause problems at that site? Or maybe I'm overthinking this, and placing a hostile nemesis onsite will cause a rampage all by itself?
Ideally, I'd like there to be some mention of these beasts in Legends (and artworks) including the Knights In Shining Armor who've slain them. It bothers me right that they appear in a game-y fashion right now that can only occur in a player fort.
Eventually, I'd like to do away with the boil-away stone entirely, and just make a tiny chance of spawning a critter whenever mining a layer stone.
elevate_mental
This script will adjust all the mental attributes of a single dwarf from whatever they currently are to the value 2600. While 2600 is not the maximum, it's very high, and you'll find this is high enough for most common activities. To adjust this value, pass the new value to the script as an argument. For example: 'elevate_mental 2700' This script can also be used to LOWER all the mental attributes of a particular dwarf. Use 'elevate_mental 200' for example. Yes, I know, it's not really "elevating" if you're lowering a value, but meh, the name is the name, change it if you want.
elevate_physical
This script will adjust all the physical attributes of a single dwarf from whatever they currently are to the value 2600. This value can also be changed by passing an argument to the script such as 'elevate_physical 3000' to adjust them all to 3000 instead of 2600. As with the elevate_mental script, this script can also be used to LOWER all the physical attributes of a particular dwarf. . I have had the need to do this, for example, with pesky nobles who insist on beating the hell out of their fellow dwarves. Not so easy to beat someone with a strength of 10, now is it?! Hee hee.
unit.body.physical_attrs
unit.status.current_soul.mental_attrs
use gui/gm-editor to access your unit to find those
that's pretty much it
Easier than that, save these pages as the appropriate .lua in hack/scripts.
https://dl.dropboxusercontent.com/u/1339319/df_scripts/40.08/elevate_physical.lua
https://dl.dropboxusercontent.com/u/1339319/df_scripts/40.08/elevate_mental.luaQuote from: vjekelevate_mental
This script will adjust all the mental attributes of a single dwarf from whatever they currently are to the value 2600. While 2600 is not the maximum, it's very high, and you'll find this is high enough for most common activities. To adjust this value, pass the new value to the script as an argument. For example: 'elevate_mental 2700' This script can also be used to LOWER all the mental attributes of a particular dwarf. Use 'elevate_mental 200' for example. Yes, I know, it's not really "elevating" if you're lowering a value, but meh, the name is the name, change it if you want.
elevate_physical
This script will adjust all the physical attributes of a single dwarf from whatever they currently are to the value 2600. This value can also be changed by passing an argument to the script such as 'elevate_physical 3000' to adjust them all to 3000 instead of 2600. As with the elevate_mental script, this script can also be used to LOWER all the physical attributes of a particular dwarf. . I have had the need to do this, for example, with pesky nobles who insist on beating the hell out of their fellow dwarves. Not so easy to beat someone with a strength of 10, now is it?! Hee hee.
I think the teleport command should do that, but I can't remember if it still needs to be be spoonfed information in this DFHack release.
Also the option of reveal > find area with link to exit > head over there and advfort dig your way out. Traveling might give you access to a road and if you then travel back to the spot with the stairs you can exit.Thanks a lot!
If you look at the JOB_COMPLETED event then you can probably get rid of the boil-away stone and just count dig completed jobs and check the tile for the appropriate type of rock and then trigger the thing that spawns them or increases their population somehow.That's a good idea. Is it possible to see what the mined-out tile was? Everything leaves a layer stone floor now, so that's an unreliable indicator of the original tile. The boil-away stones currently occur in one-tile clusters inside layer stones and specific gem clusters. I'd prefer to limit spawning to those areas because having the creatures are based on the layer stones, and it'd seem odd for one to spawn inside a microcline cluster.
Could anyone kindly explain to me how to insert new values to int32_t vectors in gm-editor?It doesn't look like it's possible at the moment, but you can use "vector:insert('#', number)" in the lua interpreter.
(For instance, if I wanted to add a value for style_strength of a certain written_content).
does the df::global::world.buildings.all vector contain every building ever made, including removed ones?
I'm trying to decide how I will send over constructed buildings to Armok vision. I don't want to send more than I need to, but besides searching through all buildings and picking the ones that are inside a specific map block, I'm not sure how that could be done.
Could anyone kindly explain to me how to insert new values to int32_t vectors in gm-editor?It doesn't look like it's possible at the moment, but you can use "vector:insert('#', number)" in the lua interpreter.
(For instance, if I wanted to add a value for style_strength of a certain written_content).
There's definitely a way but I forget what it is. Try looking at the tileprobe plugin. Or maybe it's just called probe? I forget.The probe command lists three different materials for a tile: layer, base and static. If and only if the tile is part of a vein, it will also have a vein material.
It looks like you'd have to remove them from their containers somehow (the same applies to items in workshops and projectiles, among other things). Most of those Lua functions are direct wrappers around the corresponding C++ functions, so there shouldn't be any difference between them.
"vector" refers to the actual vector you're looking at, yeah. You specify it the same way you navigate to it in gm-editor.Thank you Putnam, that was precisely what I needed to know!
(unit->body.blood_max in gm-editor becomes unit.body.blood_max in lua, for example)
Second, is there a quick way to check if a material matches one of 24 arbitrary materials? Since this will be an eventful call-back, I'll have a chance to pre-populate a persistent list with numeric ids if that will make a difference in performance.Does anyone have a lead on this, either from a Lua angle or a regular expression angle? Otherwise it turns into looping string match tests, which I imagine would be relatively slow. There are 49 tests in a worst case scenario, so it might not be too bad. Would still like a more elegant solution, though.
Second, is there a quick way to check if a material matches one of 24 arbitrary materials? Since this will be an eventful call-back, I'll have a chance to pre-populate a persistent list with numeric ids if that will make a difference in performance.Does anyone have a lead on this, either from a Lua angle or a regular expression angle? Otherwise it turns into looping string match tests, which I imagine would be relatively slow. There are 49 tests in a worst case scenario, so it might not be too bad. Would still like a more elegant solution, though.
if persistTable.GlobalTable.DirstMatTable[mat.id] then
something like that should work
What's the return value of remove()? The item should have a corresponding general_ref, and not removing both could cause issues. I think there's also a specific_ref or general_ref for tasked items, which remove() should refuse to touch.
Removing items while they're displayed in a DF viewscreen probably isn't safe. If you're making a UI to stack items, you could probably implement a simplified list in lua, but it would have the disadvantage of not having the options of the native viewscreen (I'm not sure how necessary you consider that).
Anyway, you ought to be able to remove an item from a viewscreen listing multiple items from lua, as well as the corresponding refs, but I'm not sure how safe that is.
If, internally, it uses reference-counted smart pointers, then as long as it doesn't do anything obscene with them it should be fine.
local unit = df.global.world.units.active[0]
local attks = unit.actions
for k,v in ipairs(attks) do
if attks[k].type==1 and attks[k].data.attack.attack_item_id then
local item = df.item.find(attks[k].data.attack.attack_item_id)
if item.flags.artifact == true then
item.subtype.attacks[0].velocity_mult = 2700000
attks[k].data.attack.unk_30=99999999
end
end
end
Uhhhh...
unit.actions:new()
unit.actions:insert('#',
type = 1,
id = y,
data = faked_attack,
)
unit.next_action_id = y+1
Set up the relevant fields for faked_attack and it should process it next tick I think?
Announcement: if possible, please submit structure/memory research in the issues tracker for df-structures. Direct Link (https://github.com/DFHack/df-structures/issues/)
Yeah, from the few tests I did it doesn't seem like any of the other unk values have anything to do with material or the like (which why would they since that information is stored in the attack_item_id and body_part_id. What I really need to do is find a way to get into what the actual attack action does (i.e. calculate momentum, shear costs, blah, blah, blah, calculate wound), but from my cursory check it doesn't look like we have a way to manipulate that.
So it turns out that getting the layer and vein materials for a tile is non-trivial, but Milo wrote a Lua plugin to extract it. But I'd also like to check if the just-mined-out tile has a boulder in it or not. Spawning an "awakened stone" creature or a rough "hidden gem" will have a low probability per tile, so I might as well avoid the 1-in-4 tiles that mine out a boulder anyway.Second, is there a quick way to check if a material matches one of 24 arbitrary materials? Since this will be an eventful call-back, I'll have a chance to pre-populate a persistent list with numeric ids if that will make a difference in performance.Does anyone have a lead on this, either from a Lua angle or a regular expression angle? Otherwise it turns into looping string match tests, which I imagine would be relatively slow. There are 49 tests in a worst case scenario, so it might not be too bad. Would still like a more elegant solution, though.
Make a persistent table with the id of each of the materials. Then just useCode: [Select]if persistTable.GlobalTable.DirstMatTable[mat.id] then
something like that should work
So it turns out that getting the layer and vein materials for a tile is non-trivial, but Milo wrote a Lua plugin to extract it. But I'd also like to check if the just-mined-out tile has a boulder in it or not. Spawning an "awakened stone" creature or a rough "hidden gem" will have a low probability per tile, so I might as well avoid the 1-in-4 tiles that mine out a boulder anyway.Second, is there a quick way to check if a material matches one of 24 arbitrary materials? Since this will be an eventful call-back, I'll have a chance to pre-populate a persistent list with numeric ids if that will make a difference in performance.Does anyone have a lead on this, either from a Lua angle or a regular expression angle? Otherwise it turns into looping string match tests, which I imagine would be relatively slow. There are 49 tests in a worst case scenario, so it might not be too bad. Would still like a more elegant solution, though.
Make a persistent table with the id of each of the materials. Then just useCode: [Select]if persistTable.GlobalTable.DirstMatTable[mat.id] then
something like that should work
Is there a straightforward check for an object at a given set of XYZ coordinates? Since this will be checked the tick a tile was mined out, the only possible outcomes are empty and boulder. Carved stairs, etc. are terrain features so they shouldn't interfere with the check.
If I get this to work, I won't need to have different versions of the inorganic file for different graphics packs. The next step would be to find a tile that's universally applicable as a plant, and then there'd be no need to adjust for graphics packs at all.
if dhack.maps.getTileBlock(pos).occupancy[pos.x%16][pos.y%16].item then
will tell you if the particular position has an item in it.
Something likeThanks, this improved way of hiding things in the rock is coming along nicely.Code: [Select]if dhack.maps.getTileBlock(pos).occupancy[pos.x%16][pos.y%16].item then
will tell you if the particular position has an item in it.
Hmmm, well, not sure if it would be easier to set up a faked item or try the projectile thing. Need to ask Putnam if he knows what any of those unk values do, who would have guessed that unk_30 was freaking attack velocity?
Yeah, from the few tests I did it doesn't seem like any of the other unk values have anything to do with material or the like (which why would they since that information is stored in the attack_item_id and body_part_id. What I really need to do is find a way to get into what the actual attack action does (i.e. calculate momentum, shear costs, blah, blah, blah, calculate wound), but from my cursory check it doesn't look like we have a way to manipulate that.
Well, I do have an idea for a workaround now, but it might be pretty messy and have unforeseen consequences. Basically it is split into two parts, item attacks and body part attacks.
- Item Attacks
- Create appropriate item of desired material (or use equipped item)
- Add an attack to the item raw with the desired contact/penetration/name/velocity
- Add the attack action with all necessary inputs
- Wait one tick for attack to be applied
- Remove attack from item raw
- Remove item (if not using an equipped item)
- Body Part Attacks
- Pick body part
- Change the creature raw to use the desired material
- Add attack to the creature raw with the desired contact/penetration/name/velocity
- Add the attack action with all necessary inputs
- Wait one tick for the attack to be applied
- Remove attack from the creature raw
- Revert material of creature raw
Now as far as I can see this should work fine, allowing for highly customisable attacks and such. The only downside is that for that one tick (or however long it needs to remain for the attack to be applied) all items/creatures of that type will have the change. Thoughts?
I really wish you could change an individual creatures material!
Awesome! Scriptable attacks are a great tool. I'm slightly concerned what would happen if the game saves during the one tick where things are weird but as long as that doesn't happen it should work fine.
Weirdly enough, a block has accuracy and such under the attack entry but they don't seem to do anything from what I can tell. Can a block miss?
Releases made before we started uploading builds to GitHub are all on DFFD.Thank you.
Edit:
- GCC 4.9 build (http://dffd.bay12games.com/file.php?id=8681)
- GCC 4.8 build (http://dffd.bay12games.com/file.php?id=8693)
attks[k].data.attack.unk_30=99999999
I pancaked a guy with a single punch with this.I posted that in ~august last year IIRC, me cutting my own head off with a swordSo now we can mod in the astoundingly unsuccessful entrepreneur Cut Me Own Throat Dibbler.
good fun
I just love the idea of redirecting attacks and the possible chance to not only avoid an attack but to launch said attack back at the opponent 20 times stronger.
(http://www.truimagz.com/host/fortcrush2/de/stop-hitting-your-self.png)
so yeah it's possible to set the attacking id to the same unit leading to self harm.
haven't seen what happens if you get a unit to charge after someone 3 tiles away, do they instantly warp over to there position or just fall over?
thought with dfhacking it's possible to launch.lua a man then while airborne punch him repeatedly.
to test this I guess someone needs to throw a unit at another unit then dfhack an attack action on the 'ball unit' with the 'batter unit'
Oh yeah, forgot that requirement of an adjacent target... could you initialize the attack targeting yourself and then change it to the appropriate target?
God I can see some funny side effects of that.
Wait wait wait, I'm going to poke at a couple of things later, but I was reminded of something while I was falling asleep.Oh yeah, forgot that requirement of an adjacent target... could you initialize the attack targeting yourself and then change it to the appropriate target?
God I can see some funny side effects of that.
Alas, that won't help. There is some sort of check in the actual mechanics of the attack that looks to see if the target has moved away (most likely to handle dodging properly). If we were able to hack into the attack code itself (not just the action but the full on number crunching code) we could apply long range attacks. But I'm not sure how feasible that is, and it is definitely beyond my capabilities. If one of the DFHack gods would like to look into it though it could be amazing.
Hmmm, no luck, was able to aim the targets just fine but still get the moved out of range problem.
local utils = require 'utils'
validArgs = validArgs or utils.invert({ 'unit' })
local args = utils.processArgs({...}, validArgs)
local unit = nil
if args.unit and tonumber(args.unit) then
unit = df.unit.find(tonumber(args.unit))
else
print('No unit selected')
return
end
if unit == nil then print('Bad unit ID') return end
lastWeights = lastWeights or {}
local previousWeight = lastWeights[tonumber(args.unit)] or nil
local currentWeight = unit.counters2.stored_fat
lastWeights[tonumber(args.unit)] = currentWeight
local output = dfhack.TranslateName(dfhack.units.getVisibleName(unit)) .. ': weight=' .. currentWeight
if previousWeight ~= nil then output = output .. ' (' .. (currentWeight - previousWeight) .. ')' end
output = output .. ' job='
if unit.job.current_job == nil then
output = output .. 'No Job'
else
output = output .. dfhack.job.getName(unit.job.current_job)
end
output = output .. ' content=' .. unit.counters2.stomach_content .. ' food=' .. unit.counters2.stomach_food
print(output)
...So recuperation is somewhat of a metabolism stat? Huh.
It does nothing except cause Site:Ilolum to show up in the top left corner, below the line discussing the job (R CarveFortification T).Are you using TwbT?
Just had a chuckle at one of the snippets in the script I'm forging at the moment. The Rube-Goldbergness of it is positively Dwarven.
df.global.world.raws.inorganics[dfhack.matinfo.find(hiddenGem_list[GetLayerMat(pos)]).index].material.state_name.Solid
It's really that complicated to get the name of a mineral? This game has a Mandelbrot fractal quality to it, that it feel Dwarven at any scale from overview to microscopic.
I guess this is the thread for research? If so, I think I found something that doesn't seem to be mentioned anywhere else. Is the connection between the Recuperation attribute and dwarf obesity widely known?
I was trying to figure out why most of my starting dwarves had gotten severely obese by a couple years into the game, and had assumed it had something to do with all the lavish meals I was feeding them, so I looked around to see if there was any information on how weight gain works in Dwarf Fortress, and couldn't find anything.
I did a bit of research myself with dfhack, and found that the answer is that most of my starting dwarves have poor Recuperation. While mining on a full stomach, a particular dwarf with 800 Recuperation will actually gain around 300 stored_fat every 150 ticks; the exact same dwarf with their Recuperation changed to 2200 will lose 1000 stored_fat every 150 ticks. I strongly suspect that Recuperation determines a Dwarf's target stored_fat, and their weight loss/gain is modified to keep them near that target value.
A dwarf's job doesn't seem to impact this at all. Miners who work flat out for years will still be fat if they have low Recuperation, while completely sedentary nobles will still be thin if they have high Recuperation. And the game doesn't seem to differentiate types of food, either.
In case anyone finds it useful for testing, here's the script I used to monitor changes to dwarves' weight:Code: [Select]local utils = require 'utils'
validArgs = validArgs or utils.invert({ 'unit' })
local args = utils.processArgs({...}, validArgs)
local unit = nil
if args.unit and tonumber(args.unit) then
unit = df.unit.find(tonumber(args.unit))
else
print('No unit selected')
return
end
if unit == nil then print('Bad unit ID') return end
lastWeights = lastWeights or {}
local previousWeight = lastWeights[tonumber(args.unit)] or nil
local currentWeight = unit.counters2.stored_fat
lastWeights[tonumber(args.unit)] = currentWeight
local output = dfhack.TranslateName(dfhack.units.getVisibleName(unit)) .. ': weight=' .. currentWeight
if previousWeight ~= nil then output = output .. ' (' .. (currentWeight - previousWeight) .. ')' end
output = output .. ' job='
if unit.job.current_job == nil then
output = output .. 'No Job'
else
output = output .. dfhack.job.getName(unit.job.current_job)
end
output = output .. ' content=' .. unit.counters2.stomach_content .. ' food=' .. unit.counters2.stomach_food
print(output)
Takes a unit ID and prints their weight, stomach_content, and stomach_food, as well as the weight change since the script was last called for that unit. Works well with the repeat script set to a tick interval.
Pretty sure just dfhack.matinfo.find(hiddenGem_list[GetLayerMat(pos)]).material.state_name.Solid would workI was pretty sure there was a more efficient way to summon the name, but what you saw reflected the path I followed to find it. And it has twice as many dots as your way ;)
How to install DFHack:(The "Linux" instructions apply to OS X too.)
- First, get the archive meant for your system. Extract the contents into your DF folder.
- On Windows, you're ready to use DFHack. An extra command line window should appear when you run DF.
- On Linux, use the 'dfhack' script from a terminal to run DF with DFHack. If you have stonesense problems, you might have to get your own allegro 5 libraries and delete the ones in stonesense/deplibs.
Where can I trigger rage in gm-editor?It depends on your tolerance for meat-and-potatoes interfaces. I get most enraged when dealing with the bits about materials...
Where can I trigger rage in gm-editor?Select the unit, open gm-editor, select "counters".
hmm is it possible to say send an attack to a spawn unit for the purpose of copying that attack and sending that unit to attack to a far away opponent by teleporting it?
if you need to be adjacent to the opponent you want to mega punch then it should be possible to send a dummy unit to do the blow for you then delete the unit after the assault.
I am probably just missing something, but in the 0.34.x DFHack versions, there was, unless I am very mistaken, a script to assign specific pets to specific entities (it was used by Masterwork, I think). Does it still exist in any form (and, if so, what is the current name)?
Many thanks. I'll probably be back with more questions later since I still don't know much about integrating DFHack into mods.I am probably just missing something, but in the 0.34.x DFHack versions, there was, unless I am very mistaken, a script to assign specific pets to specific entities (it was used by Masterwork, I think). Does it still exist in any form (and, if so, what is the current name)?
Yes, pick your choice among the Add*ToCiv :
https://github.com/Devduweb/DF-succubus/tree/master/succubus-prod/raw/scripts
Example of use in an onLoad.init. (https://github.com/Devduweb/DF-succubus/blob/master/succubus-prod/raw/onLoad.init#L23)
There's a rough list here (https://github.com/DFHack/dfhack/milestones/0.40.24-r4) of things I'd like to see finished, and expwnent wants to finish his create-unit script. I'm not aware of any changes that would affect MDF, though, so Meph ought to be able to update MDF's version of DFHack without too much trouble if it's necessary. I'm a bit hesitant to base DFHack releases around the development cycle of one mod.
Also, changelog length isn't a great metric because we only recently started listing all changes and bugfixes (well, "recent" being at some point in the 0.40 series, so 0.40.24-r3/r4 are probably the largest releases since then).
Did you know it's possible to doCode: [Select]w=dfhack.gui.getCurViewscreen() ; w.child=df.viewscreen_legendsst:new() ; dfhack.gui.getCurViewscreen().parent=w
and get a fully functional Legends screen? There was couple question about how to get more info about outer world recently. The only thing you can't use ESC to close the screen, instead, useCode: [Select]dfhack.gui.getCurViewscreen().breakdown_level=2
Someone needs to make a convenient script, if there's no already.
function func(arg1,arg2,arg3)
blah
end
func(X,Y,Z)
function func(options)
name = options.name or 'this is a name'
blah = options.blah or 'this is blah'
end
func{name='foo',blah='bar'}
function func(arg1,arg2,arg3,options)
blah
name = options.name
end
func(X,Y,Z,{name = 'name'})
Thanks. You're a lifesaver. My dwarves were starting to tantrum. It's one thing to lose a beloved fort, but it's another to lose said fort to a stupid bug.
For a completely unrelated feature, is there a way to wink an item out of existence? My vision for the megabeast is to "animate" nearby boulders, which really means destroying the boulder and spawning a creature in the same tile. The creature then has a corpse item of that kind of boulder to keep everything logical.
itm->flags.bits.garbage_collect = true;
For a completely unrelated feature, is there a way to wink an item out of existence? My vision for the megabeast is to "animate" nearby boulders, which really means destroying the boulder and spawning a creature in the same tile. The creature then has a corpse item of that kind of boulder to keep everything logical.
If you look at the autodump plugin you should be able to figure it out. There's a flag you have to set but I forget which one. Hopefully you won't mind waiting one frame for it to disappear.
Code: [Select]itm->flags.bits.garbage_collect = true;
Whenever I force a siege with modtools/force -CivAttack -EVIL, it says this:Forcing a siege doesn't work in DF 40.01+, because army movements were changed by Toady, and nobody nows how to spawn an invading army (yet).
...1.03_\DWARFF~1\Dwarf Fortress 0.40.24\hack\lua\utils.lua:595: error: invalid
Ludicrously fiddly. Last I tried it, I moved every army in the world to my fort and didn't get an invasion.Yeah, it's really freaking tricky, I know I got one to work, as did Putnam, but there is still something missing about the way an army determines if it is invading or not which still needs to be found.
Toady mentioned that armies actively avoid a player's embark site unless invading. For one thing, the time-dilation of fort mode would slow down an army that's just passing through. And for another, it'd absolutely destroy the game's FPS. So even if an army is told its next step is an embark tile, there's probably a check to see if they're invading or not.Ludicrously fiddly. Last I tried it, I moved every army in the world to my fort and didn't get an invasion.Yeah, it's really freaking tricky, I know I got one to work, as did Putnam, but there is still something missing about the way an army determines if it is invading or not which still needs to be found.
For one thing, the time-dilation of fort mode would slow down an army that's just passing through.Ludicrously fiddly. Last I tried it, I moved every army in the world to my fort and didn't get an invasion.Yeah, it's really freaking tricky, I know I got one to work, as did Putnam, but there is still something missing about the way an army determines if it is invading or not which still needs to be found.
Take a look at dfhack.maps.getTileBlock(x, y, z).designation[x%16][y%16]That worked great, thanks!
Take a look at dfhack.maps.getTileBlock(x, y, z).designation[x%16][y%16]
It's worked fine for me. I really can't understand why the prompt would hang when running that command, since it does so little. Does DF still respond? What happens if you run "lua ~df.global.enabler.renderer"?
feat = df.global.world.cur_savegame.map_features[2]
num = #feat.feature.population
feat.feature.population:insert('#', { new = df.world_population, type = df.world_population_type.Tree, plant = dfhack.matinfo.find('PLANT:NETHER_CAP').index });
for i,j in pairs(df.global.world.populations) do if (j.population.cave_id == feat.layer and j.population.population_idx == num - 1) then df.global.world.populations:insert('#', { new = df.local_population, type = df.world_population_type.Tree, plant = dfhack.matinfo.find('PLANT:NETHER_CAP').index, population = {region_x = j.population.region_x, region_y = j.population.region_y, population_idx = num, cave_id = feat.layer, depth = feat.start_depth, unk_28 = -1 } } ) end end
Didn't know this either, thanks!Spoiler (click to show/hide)
At first glance,Spoiler (click to show/hide)
feat = df.global.world.cur_savegame.map_features[2]
is outdated and needs to be changed to feat = df.global.world.features.map_features[2]
I'm looking forward to creating a GUI like dwarf therapist, where should I get started?
Note- there is also dwarf manipulator in dfhack. Two versions even (one C++ and other lua). You can study them too.I'm looking forward to creating a GUI like dwarf therapist, where should I get started?
Study Dwarf Therapist's code and learn how it works, then join the project or begin your own.
By any chance, is there a script or function to fill in all of the ancillary values when you change a creature's size? Something to keep the surface area, blood volume, etc. in sync. Or is there a size adjustment function buried in DF itself that causes all of these to recalculate?Uhhhh.
Anyone know what happens when you try and use the function dfhack.items.createItem() without a creator? Can't run DF right now so can't check myself. If it crashes, is there anyway to make it so that it doesn't crash?Either it crashes or it does not work at all (i.e. emits an error message).
Anyone know what happens when you try and use the function dfhack.items.createItem() without a creator? Can't run DF right now so can't check myself. If it crashes, is there anyway to make it so that it doesn't crash?Either it crashes or it does not work at all (i.e. emits an error message).
This is because it uses df own functions (namely reaction products IIRC) and it needs unit for it to work. You can make your own createItem for subset of items (e.g. I did one for heart tearing out script, just because these reactions do not support body parts). For a general use case it would be lot's of work...
Are you limited to the IDs of creatures actively on the map? Deities have historical figure IDs ;)Anyone know what happens when you try and use the function dfhack.items.createItem() without a creator? Can't run DF right now so can't check myself. If it crashes, is there anyway to make it so that it doesn't crash?Either it crashes or it does not work at all (i.e. emits an error message).
This is because it uses df own functions (namely reaction products IIRC) and it needs unit for it to work. You can make your own createItem for subset of items (e.g. I did one for heart tearing out script, just because these reactions do not support body parts). For a general use case it would be lot's of work...
Good to know. I suppose it would be possible to select a random creator and then set the created_by flag (or whatever it is called) to -1. I actually don't think it is a big deal as I will almost always have a creator, was just wondering what would happen if I didn't.
Anyone know what happens when you try and use the function dfhack.items.createItem() without a creator? Can't run DF right now so can't check myself. If it crashes, is there anyway to make it so that it doesn't crash?Currently, passing a nil unit will crash, but that's fixed in the next release.
Anyone know what happens when you try and use the function dfhack.items.createItem() without a creator? Can't run DF right now so can't check myself. If it crashes, is there anyway to make it so that it doesn't crash?Currently, passing a nil unit will crash, but that's fixed in the next release.
Hey all, I'm trying to get spawned creatures to do something other than wander, and the logical thing seemed to be to induce them to attack the dwarf that triggered the spawn (unless mod logic says the creature should be friendly, of course).Well obvious out of the way first: have you set civ_id to -1? If so then maybe adding an attack action? Also setting the berserk mood (or that other that badgers use?) should also work.
I tried populating
critter.opponent.unit_id=15250
critter.opponent.unit_pos={118,67,178}
critter.anon_1=300
based on what I've seen hunters and prey do. The id and position are for the miner. But the creature still wanders off and the anon_1 was 265 the next time I checked. It stayed at 300 for hunters and prey. It's apparently a count-down for how long a unit stays interested in its opponent, and there must be some other attributes I'm missing to start a fight.
Has anyone scienced this out?
Well obvious out of the way first: have you set civ_id to -1? If so then maybe adding an attack action? Also setting the berserk mood (or that other that badgers use?) should also work.Yes, its was civ -1. Hunter's prey that fought back didn't have an invader ID, so that can't be necessary to fight. Hunters and prey also maintain mood -1, but it's worth checking for berserk or something. (Edit: Some prey don't fight back and their opponent remains -1, so I know I don't need to fiddle with the triggering dwarf's mind.)
The thing about hunting is that it's a job. All the "ai" depends on creature having hunting job and then it depends on ammo/weapon. Also one of main things is that jobs for non dwarves that are your civ might work and might not.Well obvious out of the way first: have you set civ_id to -1? If so then maybe adding an attack action? Also setting the berserk mood (or that other that badgers use?) should also work.Yes, its was civ -1. Hunter's prey that fought back didn't have an invader ID, so that can't be necessary to fight. Hunters and prey also maintain mood -1, but it's worth checking for berserk or something. (Edit: Some prey don't fight back and their opponent remains -1, so I know I don't need to fiddle with the triggering dwarf's mind.)
I don't know how to set an attack action, but I supposed I could watch some fights in the arena then verify with hunting. A direct attack action ought to work: if the mod triggers the spawn then the triggering dwarf and the spawned creature will be 0 or 1 tiles apart. The player could play with the command line and spawn a creature half a map away from the triggering dwarf, but that won't crash the game or anything.
"Missed him by that much."
Well obvious out of the way first: have you set civ_id to -1? If so then maybe adding an attack action? Also setting the berserk mood (or that other that badgers use?) should also work.Yes, its was civ -1. Hunter's prey that fought back didn't have an invader ID, so that can't be necessary to fight. Hunters and prey also maintain mood -1, but it's worth checking for berserk or something. (Edit: Some prey don't fight back and their opponent remains -1, so I know I don't need to fiddle with the triggering dwarf's mind.)
I don't know how to set an attack action, but I supposed I could watch some fights in the arena then verify with hunting. A direct attack action ought to work: if the mod triggers the spawn then the triggering dwarf and the spawned creature will be 0 or 1 tiles apart. The player could play with the command line and spawn a creature half a map away from the triggering dwarf, but that won't crash the game or anything.
"Missed him by that much."
function checkbodytoken(unit,token)
local parts = {}
local body = unit.body.body_plan.body_parts
for i,x in ipairs(token) do
local a = 1
for j,y in ipairs(body) do
if y.token == x and not unit.body.components.body_part_status[j].missing then
parts[a] = j
a = a + 1
end
end
end
return parts[1]
end
validArgs = validArgs or utils.invert({
'help',
'defender',
'attacker',
'target',
'weapon',
'velocity',
})
local args = utils.processArgs({...}, validArgs)
if args.defender and tonumber(args.defender) then -- Check for defender declaration !REQUIRED
defender = df.unit.find(tonumber(args.defender))
else
print('No defender selected')
return
end
if args.attacker and tonumber(args.attacker) then -- Check for attacker declaration !REQUIRED
attacker = df.unit.find(tonumber(args.attacker))
else
print('No attacker selected')
return
end
j = 0
while j < 1 do
action = df.unit_action:new()
action.id = attacker.next_action_id
attacker.next_action_id = attacker.next_action_id + 1
action.type = 1
attack = action.data.attack
attack.target_unit_id = defender.id
attack.attack_item_id = -1
attack.target_body_part_id = checkbodytoken(defender,{args.target})
attack.attack_body_part_id = checkbodytoken(attacker,{args.weapon})
attack.unk_30 = tonumber(args.velocity)
attack.attack_id = 0
attack.flags = 0
attack.unk_28 = 100
attack.unk_2c = 100
attack.unk_38 = 100
attack.unk_3c = 100
attack.timer1 = 1
attack.timer2 = 1
for i,x in pairs(attack.unk_4) do
attack.unk_4[i] = 0
end
attack.unk_4.wrestle_type = -1
attacker.actions:insert('#',action)
j = j + 1
end
unit/attack-add -target UNIT_ID -attacker UNIT_ID -target BODY_TOKEN -weapon BODY_TOKEN -velocity X
Hello anon >.> and you can artifake one into existence. https://github.com/maxthyme/dfstuff/blob/master/artifake.luaI've been fiddling with that for a little while, and I can easily get an artifact slab, but how can I set it to function as a secret/necromancy slab?
I'm having a bit of trouble with the add-syndrome script in modtools. I'll admit I'm a beginner at using dfhack in this way, so if I wanted to add a syndrome to turn my adventurer into a mist thrall/husk, how would I go about doing that?
I don't really care if you just tell me how to do it or give me a direct command to put into the console but I would really appreciate some help on this one.
-- taxidermy.lua
-- by Atomic Chicken
local utils = require 'utils'
validArgs = validArgs or utils.invert({
'corpse_id',
'statue_id',
'record_name',
'help'
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print([[ taxidermy.lua
This script is designed to work with a reaction that takes a corpse and produces one statue of any material.
arguments:
-corpse_id
The item id of the corpse you wish to "stuff".
If used in conjunction with reaction-product-trigger, this takes \\INPUT_ITEMS
-statue_id
The item id of the statue produced in the reaction.
If used in conjunction with reaction-product-trigger, this takes \\OUTPUT_ITEMS
-record_name
If this optional argument is included, the script will check whether the corpse was from a named historical figure,
and if so describes the statues as being "of [creature's name]" rather than "of [creature's race]".
To use:
Create a file called "onLoad.init" in Dwarf Fortress/raw if one does not already exist.
Enter the following:
modtools/reaction-product-trigger -reactionName YOUR_REACTION -command [ taxidermy -corpse_id \\INPUT_ITEMS -statue_id \\OUTPUT_ITEMS -record_name ]
Replace "YOUR_REACTION" with whatever your reaction is called.
]])
return
end
if not args.corpse_id then
error 'ERROR: Corpse id not specified.'
end
if not args.statue_id then
error 'ERROR: Statue id not specified.'
end
corpse = df.item.find(tonumber(args.corpse_id))
statue = df.item.find(tonumber(args.statue_id))
if corpse ~= nil and statue ~= nil then
if args.record_name
and corpse:getType() ~= df.item_type.REMAINS
and corpse.hist_figure_id ~= -1 then
unit_id = corpse.unit_id
unit = df.unit.find(unit_id)
if unit.name.has_name == true then
target_desc_name = dfhack.TranslateName(dfhack.units.getVisibleName(unit))
dfhack.timeout(1,'ticks',function()
statue.description = ''..target_desc_name..''
for _,artchunk in ipairs(df.global.world.art_image_chunks) do
if artchunk.id == statue.image.id then
statue_image = artchunk.images[statue.image.subid]
end
end
while #statue_image.elements > 0 do
statue_image.elements:erase(#statue_image.elements-1)
end
while #statue_image.properties > 0 do
statue_image.properties:erase(#statue_image.properties-1)
end
newart=df.art_image_element_creaturest:new()
statue_image.elements:insert("#",newart)
statue_image.elements[0].histfig = corpse.hist_figure_id
statue_image.mat_type = -1
statue_image.mat_index = -1
end)
end
else
raceindex = corpse.race
casteindex = corpse.caste
target_desc = df.global.world.raws.creatures.all[raceindex].caste[casteindex].caste_name[0]
dfhack.timeout(1,'ticks',function()
statue.description = 'a '..target_desc..''
for _,artchunk in ipairs(df.global.world.art_image_chunks) do
if artchunk.id == statue.image.id then
statue_image = artchunk.images[statue.image.subid]
end
end
while #statue_image.elements > 0 do
statue_image.elements:erase(#statue_image.elements-1)
end
while #statue_image.properties > 0 do
statue_image.properties:erase(#statue_image.properties-1)
end
newart=df.art_image_element_creaturest:new()
statue_image.elements:insert("#",newart)
statue_image.elements[0].race = raceindex
statue_image.elements[0].caste = casteindex
statue_image.elements[0].count = 1
statue_image.mat_type = -1
statue_image.mat_index = -1
end)
end
end
modtools/reaction-product-trigger -reactionName TAXIDERMY -command [ taxidermy -corpse_id \\INPUT_ITEMS -statue_id \\OUTPUT_ITEMS -record_name ]
modtools/reaction-product-trigger -reactionName TAXIDERMY -command [ taxidermy-helper -inputs [ \\INPUT_ITEMS ] -outputs [ \\OUTPUT_ITEMS ] -record_name ]
--taxidermy-helper.lua
local utils = require 'utils'
validArgs = utils.invert({
'inputs',
'outputs',
'record_name'
})
local args = utils.processArgs({...}, validArgs)
--put error checking here
local commandstr = 'taxidermy -corpse_id ' .. args.inputs[1] .. ' -statue_id ' .. args.outputs[1]
if args.record_name then
commandstr = commandstr .. ' -record_name'
end
dfhack.run_command(commandstr)
Is -r4 planned? Need to find time to submit a bunch of df structures patches before that.
Thanks!Spoiler (click to show/hide)
Thanks!Spoiler (click to show/hide)
Target={}
function getxyz() -- this will return pointers x,y and z coordinates.
local x=df.global.cursor.x
local y=df.global.cursor.y
local z=df.global.cursor.z
return x,y,z -- return the coords
end
function getCreatureAtPos(x,y,z) -- gets the creature index @ x,y,z coord
--local x,y,z=getxyz() --get 'X' coords
local vector=df.global.world.units.all -- load all creatures
for i = 0, #vector-1 do -- look into all creatures offsets
local curpos=vector[i].pos --get its coordinates
local cx=curpos.x
local cy=curpos.y
local cz=curpos.z
if cx==x and cy==y and cz==z then --compare them
return vector[i] --return index
end
end
--print("Creature not found!")
return nil
end
if unit==nil then
adv=df.global.world.units.active[0]
for k,v in pairs(df.global.world.units.active) do
if v.relations.group_leader_id==adv.id then
if v== nil then
error("Invalid creature")
end
--entry=dfhack.lineedit()
targ=getCreatureAtPos(getxyz())
v.opponent.unit_id=targ.id
v.opponent.unit_pos.x=getxyz()
v.opponent.unit_pos.y=getxyz()
v.opponent.unit_pos.z=getxyz()
targ.job.hunt_target=v
end
end
end
Yeah, I might have to mod in eggs for male rocs, since what I've been trying to do is make two male rocs have children. This is way more complicated than I thought.Tell that to the Rocs.
DF doesn't have much in the way of sex-specific roles, but what it has is hard-coded. Females give birth and carry babies; males fertilize. Creatures that can marry will only mate with their spouse.tested it nothing happens.
That said, not sure what would happen if you set the pregnancy timer on a male.
tinder=dfhack.gui.getCurViewscreen().item
tinder.flags.on_fire=true
>.> I totally have it hotkeyed, and I'm resisting the urge to expand it to things that I know I can do like, set everything in an inventory on fire, and I'm pretty sure with a bit of fiddling you could set creatures on fire, but I like the straightforward "I want this item to be on fire now" nature of it.
unit/body-change -unit \\UNIT_ID -token UB -temperature fire
^ Sets the upper body of a creature on fire (from my scripts)
Well, adding an opponent.anon_1 counter to Roses' add_attack doesn't seem to change anything. Hard to tell exactly because I keep getting either one-shot knock-out or the bite deflects off of the miner's hood :o
The miner does not retaliate if a single shot deflects harmlessly. Definitely missing an essential element of starting a fight.
Nice, I was sitting in a forest retreat and all the sleeping elves were boring so I pulled up the loincloth of one and flipped the on_fire flag manually then giggled forever at them setting the tree on fire.
>.> I totally have it hotkeyed, and I'm resisting the urge to expand it to things that I know I can do like, set everything in an inventory on fire, and I'm pretty sure with a bit of fiddling you could set creatures on fire, but I like the straightforward "I want this item to be on fire now" nature of it.Code: [Select]unit/body-change -unit \\UNIT_ID -token UB -temperature fire
^ Sets the upper body of a creature on fire (from my scripts)
local tinder
if dfhack.gui.getCurFocus() == 'item' then
tinder=dfhack.gui.getCurViewscreen().item
tinder.flags.on_fire=true
elseif dfhack.gui.getSelectedUnit(true) then
tinder=dfhack.gui.getSelectedUnit(true).inventory
for k,v in ipairs(tinder) do
tinder[k].item.flags.on_fire=true
end
elseif df.global.ui_advmode.menu==1 then
local curpos=df.global.cursor
df.global.world.fires:insert('#',{new=df.fire})
local hot = df.global.world.fires
for _,k in ipairs(hot) do
if k.temperature==0 then
local spot = k
k.pos.x=curpos.x
k.pos.y=curpos.y
k.pos.z=curpos.z
k.timer=1000
k.temperature=60000
end
end
end
Item by item, or entire inventory at once! Weeee!Do we know where the adventurer's location while traveling is stored?Yes. It forms an army. It has first flag equal to true. pull request about all that stuff (https://github.com/DFHack/df-structures/pull/56).
Do we know where the adventurer's location while traveling is stored?Yes. It forms an army. It has first flag equal to true. pull request about all that stuff (https://github.com/DFHack/df-structures/pull/56).
Not sure where it holds the coordinates before traveling... Maybe in map?
Under df.global.world.world_data, adv_region_x, adv_region_y, adv_emb_x, and adv_emb_y are at least part of it.
The values respectively while fresh out of travel mode:
adv_region_x 63
adv_region_y 27
adv_emb_x 8
adv_emb_y 13
Enter travel mode, move around, the values stay the same while I'm traveling.
Teleport my army from 3043 by 1667 to 304 by 1667, the values stay the same.
Exit travel mode at 304 by 1667 and I get:
adv_region_x 6
adv_region_y 27
adv_emb_x 4
adv_emb_y 13
I moved 4 squares west in travel mode, so thats adv_emb_x 8 -> 4
I teleported from 3043 to 304, so that's adv_region_x 63 -> 6
Putnam and I poked at that a bit, and we had varying degrees of success, but nothing consistent.
I did learn one interesting trick though: nameless historical figures in an army are just designated by a race and a count. I've brought armies to my position which started as 2 gobs and loaded in as 30 or something.
...
function add_attack(attacker_id,defender_id,target,weapon)
attacker = df.unit.find(attacker_id)
defender = df.unit.find(defender_id)
j = 0
while j < 1 do -- Not sure why this "loop" is here???
action = df.unit_action:new()
action.id = attacker.next_action_id
attacker.next_action_id = attacker.next_action_id + 1
action.type = 1
attack = action.data.attack
attack.target_unit_id = defender_id
attack.attack_item_id = -1
attack.target_body_part_id = tonumber(target)
attack.attack_body_part_id = tonumber(weapon)
attack.unk_30 = 1
attack.attack_id = 0
attack.flags = 0
attack.unk_28 = 100
attack.unk_2c = 100
attack.unk_38 = 100
attack.unk_3c = 100
attack.timer1 = 1
attack.timer2 = 1
for i,x in pairs(attack.unk_4) do
attack.unk_4[i] = 0
end
attack.unk_4.wrestle_type = -1
attacker.actions:insert('#',action)
j = j + 1
end
end
...
wyrm = df.unit.find(wyrm_id)
miner = df.unit.find(args.miner)
wyrm.opponent.unit_id = args.miner -- who it's supposed to attack
wyrm.opponent.unit_pos.x = miner.pos.x -- where the target is
wyrm.opponent.unit_pos.y = miner.pos.y
wyrm.opponent.unit_pos.z = miner.pos.z
wyrm.opponent.anon_1 = 300 -- how long to stay in combat mode?
wyrm.mood = 7 -- go berserk, the only reliable way to force more than a single attack
add_attack(wyrm_id,args.miner,3,12) -- targets head, but seems to ignore instructions to attack with its tail
...
Looking over the code, what is the bit about it's tail?My understanding of add_attack was that you provided the target bodypart and the bodypart to be used for the attack. Maybe I just misread that completely? The thing's tail is body part index 12.
Looking over the code, what is the bit about it's tail?My understanding of add_attack was that you provided the target bodypart and the bodypart to be used for the attack. Maybe I just misread that completely? The thing's tail is body part index 12.
In any event, what is the normal value for attack velocity? Is it 1, 100, 1000? Having it really dialed down for an initial ambush is fine if the fight continues, but I'm curious what is considered a "normal" attack.
function momentumitem(unit,velocity,item,material)
weight = math.floor(item.size*material.solid_density/100000)
weight_fraction = item.size*material.solid_density*10 - weight*1000000
effweight=unit.body.size_info.size_cur/100+weight*100+weight_fraction/10000
actweight=weight*1000+weight_fraction/1000
vel=unit.body.size_info.size_base * dfhack.units.getPhysicalAttrValue(unit,0) * velocity/1000/effweight/1000
mom=vel*actweight/1000+1
return mom
end
function momentumbodypart(unit,velocity,bp,material)
partsize = math.floor(unit.body.size_info.size_cur * bp.relsize / unit.body.body_plan.total_relsize)
partweight = math.floor(partsize * material.solid_density / 100)
vel = 100 * dfhack.units.getPhysicalAttrValue(unit,0) / 1000 * velocity / 1000
mom = vel * partweight / 1000 + 1
return mom
end
Oh, it's because attack.attack_id = 0. Use 2 for the tail attack and 1 for the claw attack (that should work I think)Oh! That makes sense. Thanks!
Edit: The tail attack might be more like 5 if it can claw attack with all four claws
Oh, it's because attack.attack_id = 0. Use 2 for the tail attack and 1 for the claw attack (that should work I think)Oh! That makes sense. Thanks!
Edit: The tail attack might be more like 5 if it can claw attack with all four claws
Yeah, maybe it was biting... with its tail.Oh, it's because attack.attack_id = 0. Use 2 for the tail attack and 1 for the claw attack (that should work I think)Oh! That makes sense. Thanks!
Edit: The tail attack might be more like 5 if it can claw attack with all four claws
Yeah, the code I provided earlier wasn't the most up to date version, in the new version I actually check which attack number to use for the corresponding body part. It's interesting that the attack_id over rules the attack_body_part_id. I wonder if you mix match if it uses the material and such of the body part but the penetration/contact etc... of the attack. Will have to do some more testing.
Yeah, maybe it was biting... with its tail.
(http://i.imgur.com/GMz2c2u.png)Yeah, maybe it was biting... with its tail.
I love when this sort of thing happens. Now I want to see somebody bite someone's pancreas with their brain.
hmm would dabble more into this but I still haven't gotten a good UI working for the fast travel warp to marker fixed(waypoint is fixed but portal isn't).Hmmm, could you drop into wait/sleep mode for a tic and pull up the warp then?another question is with the wait command can you send personal armies to do base of operations in areas?Spoiler: "warmist portal script I slightly modified to work with the new version" (click to show/hide)
like park a bunch of peasants at a ruin/lair and tell them to settle there?
I want to see someone attacking their own heart with brain (or reverse) :DYeah, maybe it was biting... with its tail.
I love when this sort of thing happens. Now I want to see somebody bite someone's pancreas with their brain.
I want to see someone attacking their own heart with brain (or reverse) :DYeah, maybe it was biting... with its tail.
I love when this sort of thing happens. Now I want to see somebody bite someone's pancreas with their brain.
I want to see someone attacking their own heart with brain (or reverse) :DYeah, maybe it was biting... with its tail.
I love when this sort of thing happens. Now I want to see somebody bite someone's pancreas with their brain.
Actually, that is something I haven't tried... What if the defending unit is the attacking unit?
I want to see someone attacking their own heart with brain (or reverse) :DYeah, maybe it was biting... with its tail.
I love when this sort of thing happens. Now I want to see somebody bite someone's pancreas with their brain.
Actually, that is something I haven't tried... What if the defending unit is the attacking unit?
Oh well, I have to ask, is there a way to make dorfs get happy thoughts from pain then?...ok, look, I made a fort with civilians in squads so I could assign leather armor and get rid of clothing nonsense... I didn't need THIS added to the image dammit.
I want to see someone attacking their own heart with brain (or reverse) :DYeah, maybe it was biting... with its tail.
I love when this sort of thing happens. Now I want to see somebody bite someone's pancreas with their brain.
Actually, that is something I haven't tried... What if the defending unit is the attacking unit?
Hmmm, could you drop into wait/sleep mode for a tic and pull up the warp then?yes usually before the travel mode got swap for army mode, the script is coded to delay warp if you're not in the right menu allowing for sleeping or waiting to pull you out.
When I'm in a mountainous area or dark fortress I'll wait for 2 or 4 hours and hit my gm-editor hotkey which opens my army pos_x and pos_y up. I've gotten pretty good at just dropping myself in a spot with that now.
:lua printall(df.global.world.items.other)
printall(df.global.world.items.other)
Or justCode: [Select]:lua printall(df.global.world.items.other)
directly from the console.
You can also use "~df.global.world.items.other" as a shortcut in the lua interpreter.
Another thing - if you want a list of all types and their numerical equivalents, use "@df.items_other_id" or "printall_ipairs(df.items_other_id)". You can use either the numbers or names as indices into world.items.other, and convert between them by indexing df.items_other_id (e.g. "df.items_other_id[1]" is "ANY_ARTIFACT" and "df.items_other_id.ANY_ARTIFACT" is 1).
How can I reliably tell whether a player should be seeing the embark map, the world map, or neither?Check ui state i guess.
Simply checking the existence of the data gives false positives while saving and loading.
I seem to remember there's a way of doing it even without DFHack but I don't remember how.Pretty sure there is a way to add "magma" item but not "magma" square.
Has anyone created a script/method to spawn magma from a reaction ala the Magma Shrine from v0.34 Masterwork?
--in dfhack.init
modtools/reaction-trigger -reactionName nameOfReactionThatMakesMagmaGoesHere -command [ liquidMaker -location [ \\LOCATION ] -type Magma -amount 7 -offset [ 0 0 \-1 ] ]
--in hack/scripts/liquidMaker.lua
utils = require 'utils'
validArgs = validArgs or utils.invert({
'help',
'location',
'type',
'amount',
'offset'
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print([[scripts/makeLiquids.lua
-help
print this help message
-location [ x y z ]
specify the target location coordinates
-offset [ x y z ]
add this vector to location in order to get the real target location
this argument is optional
-amount n
specify the desired depth of the liquid
-liquidType liquidType
specify whether you want magma or water
liquidType should be Water or Magma
]])
return
end
local pos = {}
pos.x = tonumber(args.location[1])
pos.y = tonumber(args.location[2])
pos.z = tonumber(args.location[3])
if args.offset then
pos.x = pos.x + tonumber(args.offset[1])
pos.y = pos.y + tonumber(args.offset[2])
pos.z = pos.z + tonumber(args.offset[3])
end
local tileBlock = dfhack.maps.ensureTileBlock(pos.x, pos.y, pos.z)
tileBlock.flags.update_temperature = true
tileBlock.flags.update_liquid = true
local xOffset = pos.x - 16*floor(pos.x / 16)
local yOffset = pos.y - 16*floor(pos.y / 16)
tileBlock.designation[xOffset][yOffset].flow_size = tonumber(args.amount)
tileBlock.designation[xOffset][yOffset].liquid_type = df.tile_liquid[args.liquidType]
Has anyone created a script/method to spawn magma from a reaction ala the Magma Shrine from v0.34 Masterwork?
I have not tested this at all, but this should work with a small amount of fiddling:Code: [Select]--in dfhack.init
modtools/reaction-trigger -reactionName nameOfReactionThatMakesMagmaGoesHere -command [ liquidMaker -location [ \\LOCATION ] -type Magma -amount 7 -offset [ 0 0 \-1 ] ]Code: [Select]--in hack/scripts/liquidMaker.lua
utils = require 'utils'
validArgs = validArgs or utils.invert({
'help',
'location',
'type',
'amount',
'offset'
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print([[scripts/makeLiquids.lua
-help
print this help message
-location [ x y z ]
specify the target location coordinates
-offset [ x y z ]
add this vector to location in order to get the real target location
this argument is optional
-amount n
specify the desired depth of the liquid
-liquidType liquidType
specify whether you want magma or water
liquidType should be Water or Magma
]])
return
end
local pos = {}
pos.x = tonumber(args.location[1])
pos.y = tonumber(args.location[2])
pos.z = tonumber(args.location[3])
if args.offset then
pos.x = pos.x + tonumber(args.offset[1])
pos.y = pos.y + tonumber(args.offset[2])
pos.z = pos.z + tonumber(args.offset[3])
end
local tileBlock = dfhack.maps.ensureTileBlock(pos.x, pos.y, pos.z)
tileBlock.flags.update_temperature = true
tileBlock.flags.update_liquid = true
local xOffset = pos.x - 16*floor(pos.x / 16)
local yOffset = pos.y - 16*floor(pos.y / 16)
tileBlock.designation[xOffset][yOffset].flow_size = tonumber(args.amount)
tileBlock.designation[xOffset][yOffset].liquid_type = df.tile_liquid[args.liquidType]
local xOffset = pos.x - 16*math.floor(pos.x / 16)
local yOffset = pos.y - 16*math.floor(pos.y / 16)
utils = require 'utils'
validArgs = validArgs or utils.invert({
'help',
'location',
'type',
'amount',
'offset'
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print([[scripts/liquidMaker.lua
-help
print this help message
-location [ x y z ]
specify the target location coordinates
-offset [ x y z ]
add this vector to location in order to get the real target location
this argument is optional
-amount n
specify the desired depth of the liquid
-liquidType liquidType
specify whether you want magma or water
liquidType should be Water or Magma
]])
return
end
local pos = {}
pos.x = tonumber(args.location[1])
pos.y = tonumber(args.location[2])
pos.z = tonumber(args.location[3])
if args.offset then
pos.x = pos.x + tonumber(args.offset[1])
pos.y = pos.y + tonumber(args.offset[2])
pos.z = pos.z + tonumber(args.offset[3])
end
local tileBlock = dfhack.maps.ensureTileBlock(pos.x, pos.y, pos.z)
tileBlock.flags.update_temperature = true
tileBlock.flags.update_liquid = true
local xOffset = pos.x - 16*math.floor(pos.x / 16)
local yOffset = pos.y - 16*math.floor(pos.y / 16)
tileBlock.designation[xOffset][yOffset].flow_size = tonumber(args.amount)
tileBlock.designation[xOffset][yOffset].liquid_type = true
tileBlock.flags.update_liquid_twice = true
local hid = df.global.world.world_data.sites
for k, v in ipairs(hid) do
hid[k].flags.Undiscovered=false
hid[k].flags[8]=true
end
The liquidType is no ignored (now surprise). Found that out while trying to spawn water. Gonna have to root around the API docs and see if I can figure it out. I think LUA is casting 'true' into the liquidType magma enum is. Lua, y u no strongly typed? :'(
My first minimod will be an Ice Furnace that takes a block of glacial ice, fuel (mebbe magma) and pipes it to the floor below.
tileBlock.designation[xOffset][yOffset].liquid_type = true
if df.tile_liquid[args.liquidType] == 0 then
tileBlock.designation[xOffset][yOffset].liquid_type = false
elseif df.tile_liquid[args.liquidType] == 1 then
tileBlock.designation[xOffset][yOffset].liquid_type = true
end
if args.liquidType == "Magma" then
tileBlock.designation[xOffset][yOffset].liquid_type = 1
else
tileBlock.designation[xOffset][yOffset].liquid_type = 0
end
Are you trying to recreate a doctor who episode?
Water&Magma seems to inconsistently sticking in a 7/7 column. Sometimes it just takes a few DF days and then it'll fall out, sometimes longer. Not sure what the deal is. Should I try setting the flag for liquid updating on adjacent blocks?I know that fluid updates are staggered a bit for FPS concerns, but a few game days seems long. Hopefully setting the update flag on that and the eight neighboring tiles helps. There are only seven units of water, so it won't look too strange even if the water stays inside that box for a while.
Are there any scripts out there that modify the hunger rates for Dwarves?
If not, could someone direct me toward making one?
Thanks Warmist! I will test this out when I get a chance (which unfortunately might not be for several days).You can probably set one to be angry at another and the other be friendly (till he gets hit?)
Do you need to induce a first blow between the units, or can you specify which one throws the first punch?
The context would be a newly spawned unit 0 or 1 tiles away from a fort citizen, and the mod logic determines that the newly spawned unit is supposed to be "hostile" but not berserk.Thanks Warmist! I will test this out when I get a chance (which unfortunately might not be for several days).You can probably set one to be angry at another and the other be friendly (till he gets hit?)
Do you need to induce a first blow between the units, or can you specify which one throws the first punch?
Also found some research on these values: here (https://gist.github.com/warmist/3017dc796a6173c215bb)
Dirst: I think that would require run-time type information, which Toady does not have enabled.Yeah, that's exactly what I wanted. Can't have everything I suppose.
Dirst: I think that would require run-time type information, which Toady does not have enabled.Yeah, that's exactly what I wanted. Can't have everything I suppose.
Thanks for the help guys!
Yeah, that's what I was referring to withDirst: I think that would require run-time type information, which Toady does not have enabled.Yeah, that's exactly what I wanted. Can't have everything I suppose.
Thanks for the help guys!
Don't know why expwnent said that, since game types are known to us. You can use df.is_instance(df.building_workshopst,your_building).
(your_building._type == df.building_workshopst) will work too in your case, but is_instance handles subclasses as well.
Try object._type(This uses dfhack-implemented structure identities, which are similar to vtables for identification purposes, so RTTI isn't required.)
Gotcha. I am confident I know what all of the bp_modifier values do, as well as the values for tissue styles. I'll try to figure out how to add these values correctly...the XML structure is very confusing to me. I'm completely unfamiliar with C++ and Lisp, and I just dived into Lua for this project.Man, it's all pretty raw in there still huh.
<stl-vector name='bp_modifiers' type-name='int32_t'
index-refers-to='$$._global.caste.ref-target.bp_appearance.modifier_idx[$].refers-to'/>
If I'm not mistaken that can have the relevant type-name replaced with a list pulled from somewhere, hmmm, we need to take into account other species though.For anyone interested: I'm working on a pull request to clean up the documentation, and generally make it possible to check whether something is actually documented as it should be.
This is obviously a work in progress, but I'd love any feedback you have at the pull (https://github.com/DFHack/dfhack/pull/693) or here.
For anyone interested: I'm working on a pull request to clean up the documentation, and generally make it possible to check whether something is actually documented as it should be.
This is obviously a work in progress, but I'd love any feedback you have at the pull (https://github.com/DFHack/dfhack/pull/693) or here.
You can now download the pretty, comprehensive html docs on DFFD (http://dffd.bay12games.com/file.php?id=11152), for those interested.
For anyone interested: I'm working on a pull request to clean up the documentation, and generally make it possible to check whether something is actually documented as it should be.
This is obviously a work in progress, but I'd love any feedback you have at the pull (https://github.com/DFHack/dfhack/pull/693) or here.
You can now download the pretty, comprehensive html docs on DFFD (http://dffd.bay12games.com/file.php?id=11152), for those interested.
I usually hate auto-generated docs but this is pretty good.
Dirst: I think that would require run-time type information, which Toady does not have enabled.Yeah, that's exactly what I wanted. Can't have everything I suppose.
Thanks for the help guys!
Don't know why expwnent said that, since game types are known to us. You can use df.is_instance(df.building_workshopst,your_building).
(your_building._type == df.building_workshopst) will work too in your case, but is_instance handles subclasses as well.
For anyone interested: I'm working on a pull request to clean up the documentation, and generally make it possible to check whether something is actually documented as it should be.
This is obviously a work in progress, but I'd love any feedback you have at the pull (https://github.com/DFHack/dfhack/pull/693) or here.
You can now download the pretty, comprehensive html docs on DFFD (http://dffd.bay12games.com/file.php?id=11152), for those interested.
I usually hate auto-generated docs but this is pretty good.
I don't like auto-gen docs too. The idea of readme.rst and "lua api.rst" was that it would be readable both in html and txt format. Currently that is not exactly the case (because imho they are too big).
We'll see how it goes i guess...
Code: [Select]<stl-vector name='bp_modifiers' type-name='int32_t'
If I'm not mistaken that can have the relevant type-name replaced with a list pulled from somewhere, hmmm, we need to take into account other species though.
index-refers-to='$$._global.caste.ref-target.bp_appearance.modifier_idx[$].refers-to'/>
The parts names are the relevant body parts and layers right? Bah, that's frustrating sounding right off the bat, because we can't just have it be skull_height, skull_width, nose_straightness, ear_height, eye_protrusion, teeth_spacing0, teeth_spacing1, and so forth can we?
What I was saying is that in the general case it is not possible. If there's a vector<void*> in df-structures there's no automatic way of determining the type. The reason we can do it for buildings is because of the building::getType() method (or whatever it's called) and because we've already mapped the enum it returns.
For anyone interested: I'm working on a pull request to clean up the documentation, and generally make it possible to check whether something is actually documented as it should be.
This is obviously a work in progress, but I'd love any feedback you have at the pull (https://github.com/DFHack/dfhack/pull/693) or here.
Update on the next release: effectively negative progress because there's more stuff to do. The documentation is overhauled in terms of formatting and presentation but the content is about the same. I'd like to go over the documentation and add stuff and organize a bit more. I'd also like to go through the big pile of third party scripts we're adding and decide what needs to go in and what would be too cluttered and fix indentation and try and extract out common functionality, etc, etc. I'm working on it a little each day but it will take longer than I expected.
I do still intend to do DFHack 0.40.24-r4 before the next DF release.
It would go a lot quicker if I just took all the 3rd party scripts and stuffed them in but that would clutter the scripts folder a lot and when I do eventually go in and standardize everything it would break backwards compatibility. I'm willing to break it if there's a good reason for the long-term health of the project but I try not to.
we're already sitting on the biggest changelog ever (http://peridexiserrant.neocities.org/html/docs/Changelog.html)
we're already sitting on the biggest changelog ever (http://peridexiserrant.neocities.org/html/docs/Changelog.html)
Have you noticed that it's impossible to read because text doesn't wrap inside grey areas?
That's what the BUILD_DOCS option is for - if you disable it, you don't need to have sphinx installed. If it's disabled by default, there's a risk of including no documentation or inaccurate documentation in releases.
I thought the submodule message referred to "git submodule update --init", which does work, but I'll fix it if not.
What are the contents of your dfhack-config directory (in the source tree, not your DF folder)?
That's strange - the 'default' directory shouldn't exist at all (https://github.com/DFHack/dfhack/tree/develop/dfhack-config) in your source tree. Can you check `git status` and make sure you haven't added it somehow (and make sure you're using the latest commit of the develop branch)?
At any rate, you ought to be able to remove it safely if there's nothing important in it.
expanding = true
Are we still troubleshooting problems with spawn-unit, or has all the effort moved over to create-unit?
As long as the new script accepts age 0 (which is an adult) then I can just start using that one. Thanks for all of your work on this.Are we still troubleshooting problems with spawn-unit, or has all the effort moved over to create-unit?
create-unit works differently enough that it's unlikely to have the same bugs, and I never worked much on spawn-unit. The people who did are busy, I think.
I just download DFHack (default settings), started a game, enter Legend mode, and tried to export all and I see this.How could I fix this?Spoiler (click to show/hide)
I'm totally newbie with this utility.
BTW: Save is here (http://dffd.bay12games.com/file.php?id=11198) if you need this.
local thisIdentity = df.global.world.identities.all[v]
Try https://github.com/DFHack/dfhack/blob/develop/scripts/exportlegends.luahttp://i.imgur.com/U7kzA2j.jpg?1
Try https://github.com/DFHack/dfhack/blob/develop/scripts/exportlegends.luahttp://i.imgur.com/U7kzA2j.jpg?1
Is it theoretically possible to allow building constructed walls from any item?With advfort you probably can. I know I removed the "hard surfaces only" restriction so I could engrave the walls I built the faces of armok with.
Update on the next release: effectively negative progress because there's more stuff to do. The documentation is overhauled in terms of formatting and presentation but the content is about the same. I'd like to go over the documentation and add stuff and organize a bit more. I'd also like to go through the big pile of third party scripts we're adding and decide what needs to go in and what would be too cluttered and fix indentation and try and extract out common functionality, etc, etc. I'm working on it a little each day but it will take longer than I expected.
I do still intend to do DFHack 0.40.24-r4 before the next DF release.
It would go a lot quicker if I just took all the 3rd party scripts and stuffed them in but that would clutter the scripts folder a lot and when I do eventually go in and standardize everything it would break backwards compatibility. I'm willing to break it if there's a good reason for the long-term health of the project but I try not to.
Quick question: wondering if there's still a utility included that can reverse madness in dwarves.
Gm-editor can do it, but the interface is a bit complex.Select the unit, enter "gui/gm-editor" in the console, select "mood" and change the value to -1.
Quick question: wondering if there's still a utility included that can reverse madness in dwarves.Gm-editor can do it, but the interface is a bit complex.Select the unit, enter "gui/gm-editor" in the console, select "mood" and change the value to -1.
dfhack.timeout(1,'ticks',callback)Great to know. Problem is that the fix I was trying to apply doesn't fix the problem :(
if you need function arguments in the callback, you can use an anonymous function:
dfhack.timeout(1,'ticks',function() foo(bar,baz) end)
<...>
each author forks the repo, and works in /devel/$name/
<...>
[CE_NECROSIS:SEV:100:PROB:100:RESISTABLE:BP:BY_TYPE:THOUGHT:ALL:BP:BY_TYPE:NERVOUS:ALL:START:30:PEAK:60:END:1200]
the only thing we can really do is apply necrosis to the correct body parts for the correct times. As you have to populate all the values, and there is no easy way to handle SEV or RESISTABLE.Update on the next release: effectively negative progress because there's more stuff to do. The documentation is overhauled in terms of formatting and presentation but the content is about the same. I'd like to go over the documentation and add stuff and organize a bit more. I'd also like to go through the big pile of third party scripts we're adding and decide what needs to go in and what would be too cluttered and fix indentation and try and extract out common functionality, etc, etc. I'm working on it a little each day but it will take longer than I expected.
I do still intend to do DFHack 0.40.24-r4 before the next DF release.
It would go a lot quicker if I just took all the 3rd party scripts and stuffed them in but that would clutter the scripts folder a lot and when I do eventually go in and standardize everything it would break backwards compatibility. I'm willing to break it if there's a good reason for the long-term health of the project but I try not to.
I'm working on cleaning things up for one soon (I was hoping to do it today, but there are a couple more pull requests to get to).Awesome, that's sooner than I was expecting (and sorry for continuing to add more pulls!).
- I can't say I understand the argument for releasing before the next DF release, although I certainly want to.
- There's nothing preventing us from making a DFHack release before adding support for the new DF version after it's released.
- I also don't know how much modders will gain from having a DFHack release before the new DF release, given that many remain with the older DF version for a while.
So modtools/add-syndrome, for lack of a better term, needs some work, I'm just not exactly sure what. First off most syndromes are added correctly, you can give a unit an interaction that it will use correctly, change display name/tile, change attributes, and basically anything that is considered a "Special Effect" on http://dwarffortresswiki.org/index.php/DF2014:Syndrome (http://dwarffortresswiki.org/index.php/DF2014:Syndrome). But any of the base effects will have do nothing. My brief bit of science that I did found the following.
When applying a syndrome via interaction (which is what I figure we should model add-syndrome after, instead of adding a syndrome via attack). There are several additional components that are not correctly set.
1. None of the target_ vectors are populated in the symptoms list.
2. This leads to no wound being generated.
3. If the target_vectors are artificially populated a wound is automatically created, but it's parts vector is empty
4. Filling in the parts vector seems to correctly "apply" the syndrome. Unfortunately using this method means that out of everything in;Code: [Select][CE_NECROSIS:SEV:100:PROB:100:RESISTABLE:BP:BY_TYPE:THOUGHT:ALL:BP:BY_TYPE:NERVOUS:ALL:START:30:PEAK:60:END:1200]
the only thing we can really do is apply necrosis to the correct body parts for the correct times. As you have to populate all the values, and there is no easy way to handle SEV or RESISTABLE.
5. Unfortunatelyx2 in 3 of my 5 tests the game crashed. This may be because I was creating entries by copying another units. I am unsure
I am hoping that someone more knowledgeable about the workings of things can come up with a way to add damaging syndromes via add-syndrome. Otherwise I will move back to just adding wounds directly (this suffers from the same Unfortunately as number 4)
local my_entity=df.historical_entity.find(df.global.ui.civ_id)
local sText=" "
local k=0
local v=1
for x,y in pairs(df.global.world.entities.all) do
my_entity=y
k=0
while k < #my_entity.resources.misc_mat.clay.mat_index do
v=my_entity.resources.misc_mat.clay.mat_type[k]
sText=dfhack.matinfo.decode(v,my_entity.resources.misc_mat.clay.mat_index[k])
if (sText==nil) then
my_entity.resources.misc_mat.clay.mat_type:erase(k)
my_entity.resources.misc_mat.clay.mat_index:erase(k)
k=k-1
else
if(sText.material.id=="CLAY") then
my_entity.resources.misc_mat.clay.mat_type:erase(k)
my_entity.resources.misc_mat.clay.mat_index:erase(k)
k=k-1
end
if(sText.material.id=="SANDY_CLAY") then
my_entity.resources.misc_mat.clay.mat_type:erase(k)
my_entity.resources.misc_mat.clay.mat_index:erase(k)
k=k-1
end
if(sText.material.id=="SILTY_CLAY") then
my_entity.resources.misc_mat.clay.mat_type:erase(k)
my_entity.resources.misc_mat.clay.mat_index:erase(k)
k=k-1
end
if(sText.material.id=="CLAY_LOAM") then
my_entity.resources.misc_mat.clay.mat_type:erase(k)
my_entity.resources.misc_mat.clay.mat_index:erase(k)
k=k-1
end
end
k=k+1
end
end
Is there an easy way to detect whether a unit is hostile, neutral, or a member of your fort?
r4 is up! (https://github.com/DFHack/dfhack/releases/tag/0.40.24-r4)Need to rename the thread don't we!
Front post updated. Special thanks to Lethosor for putting together this release which is what I'm theoretically supposed to do!You also need to change the "compile" and "contributors" links, since those filenames changed ;-)
I went to copy over my scripts and add in my personal use changes to gm-editor and launch/names are already in there. *squee*
Always awesome when the thread title changes! Thanks for all the wizardry you guys cram into these releases!I too love updates, as much for all the fixed bugs as the new features :D
script_environment worked the last time I checked.
[lua]# ~dfhack.script_environment('devel/lua-example')
Arguments:
Command called 1 times.
table: 0x11dcb2f0
dfhack_flags = table: 0x11ce1ed0
moduleMode = true
run_count = 1
[lua]# ~dfhack.script_environment('devel/lua-example')
table: 0x11dcb2f0
dfhack_flags = table: 0x11ce1ed0
moduleMode = true
run_count = 1
("run_count" is a global variable in that script, and it seems to be exported correctly.)Does anyone know how to use dfhack to get rid of an unkillable animated remain? I've got a head rolling around my fortress and it won't die. I've also encountered undead hair before but didn't have dfhack to deal with it."exterminate it" should work.
I know I can spawn magma but I am afraid of setting all the dwarves currently attacking it on fire, or it getting set on fire and then running around lighting everything on fire. Is there not a simple kill or teleport command?
Ah thank you. Unfortunately if any undead are on the map it this will kill all of them, but it's worth it.Does anyone know how to use dfhack to get rid of an unkillable animated remain? I've got a head rolling around my fortress and it won't die. I've also encountered undead hair before but didn't have dfhack to deal with it."exterminate it" should work.
I know I can spawn magma but I am afraid of setting all the dwarves currently attacking it on fire, or it getting set on fire and then running around lighting everything on fire. Is there not a simple kill or teleport command?
If you run "exterminate it" with a unit selected, it should only kill that unit (and running "exterminate it" without a unit selected shouldn't do anything). Did you run "exterminate undead", or is there an issue with that script?
I'm using GCC 4.5 on 10.9 - I know there's a patch needed to compile it on 10.10 (which Homebrew and Macports use), but I'm not sure about 10.11. Danaris has gotten it to work on 10.10, at least. I don't think Xcode should make a difference.
If you use a newer GCC version, you have to have a corresponding 32-bit libstdc++ in the DF/libs folder (which makes distributing code compiled with newer GCC versions harder, and requires actually building GCC from source and specifying -mmacosx-version-min=10.6 for it to be portable).
The next version of Rubble will use Lua for scripting, ...Nice move Milo, Rubble DF modding framework could then reuse the Lua knowledge of the dfhack team and the Dwarf fortress modding community.... I discovered that the Lua VM I was using was riddled with bugs...If you are evaluating lua VMs as candidates for Rubble scripting and your evaluation is not closed, you could have a look to refactored Metalua 0.72 http://lua-users.org/lists/lua-l/2014-01/msg00636.html (http://lua-users.org/lists/lua-l/2014-01/msg00636.html)
Oh, and did I mention that the main reason I chose the VM I did is because the other one has no documentation whatsoever? ...
Metalua http://metalua.luaforge.net/ (http://metalua.luaforge.net/) is used as a Lua code analysis tool in projects like LuaDevelopmentTools https://eclipse.org/ldt/ (https://eclipse.org/ldt/) (the Eclipse-based Lua IDE, so good community support and maybe even some docs...), LuaDocumentor (an LDoc-like tool which retrieves information missing from comments through code analysis), LuaInspect (back-end for SciTE and ZeroBrane) , etc.
If you dont like metalua VM you can also choose another from the list supported by open source ZeroBrane Studio Lua IDE http://studio.zerobrane.com/ (http://studio.zerobrane.com/) supports debugging with an ever increasing number of different Lua VMs as for LÖVE, Moai, Gideros, Marmalade Quick, Corona, and Cocos2d-x. It also supports general Lua debugging for Wireshark, GSL-shell, Adobe Lightroom, OpenResty, Lapis, Moonscript, home automation, and more.
DFhack is almost a Lua VM or not too far of becoming one. Adding support for debugging dfhack lua scripting to one of the lua IDEs cited could reduce the entry barrier. Adding this support in zerobrane is ,maybe, easier as this IDE is developped 100% in Lua.
Can DFhack be converted to a Lua VM for DF modding and debuging?
This would enable us to use some of the open source Lua IDEs that support lua debugging...
Whenever I try to use Exterminate I get the following error:What DFHack version are you using? If you upgraded, did you make sure to replace the entire hack folder (rather than just overwriting its contents)?
(http://i.imgur.com/bK8sI8Z.png)
How can I fix this?
Did you update submodules ("git submodule update")?of course not. so never mind, this update fixed the issue. thx for the reply. seems i will never get into git.
I've been watching quill18 playing dwarf fortress, and noticed that he is somehow setting certain items to be maintained. For example, he selects iron bars and enters "10-20" and he said that the game will automatically queue up production if the quantity get's too low. Now I couldn't find any way to do this on vanilla DF so I assume since he was using DFHack, someone here could tell me how I can do this. If this is not DFHack, sorry, any tips on how I could do this would be welcome.
Might have to dig around in gui/gm-editor df.global.ui I think to find it, plus the references that links to in df.global.world in whichever entries that I am not sure of off the top of my head.
There's a point where you probably want to make a script for it.And if it doesn't, you have yet another way to instantly induce a crash or corrupt a save :)
That is the exact point.
My process for writing scripts is basically that; go into the lua interface (or gm-editor, if you prefer), go through each step of the process to do what you want and write that step down. If it works, you basically already have a script.
How commonly-used is dfusion, by the way? There's a discussion about removing it on Github, but I'm not sure how much would need to be converted to scripts.I use it for easier body-swapping/reincarnation, plus its heal command can bring things back to life where full-heal can't. Impregnate is useful too.
How commonly-used is dfusion, by the way? There's a discussion about removing it on Github, but I'm not sure how much would need to be converted to scripts.plus its heal command can bring things back to life where full-heal can't. Impregnate is useful too.
for i=0,#v-1,1 do
v[i].on_fire = false
v[i].missing = false
v[i].organ_loss = false
v[i].organ_damage = false
v[i].muscle_loss = false
v[i].muscle_damage = false
v[i].bone_loss = false
v[i].bone_damage = false
v[i].skin_damage = false
v[i].motor_nerve_severed = false
v[i].sensory_nerve_severed = false
end
with this: for i=0,#v-1,1 do
v[i].whole = 0
end
No, it just doesn't bring you back to life. Dfusion does. What dfusion doesn't do is heal you properly. It's a bit broken.
Main thing I do with dfusion is change adventurer, which can also be moved to a new script. The sites thing is handy but I like the claim a site reaction hook one more, and though that hooks into dfusion it can also be moved out of it.It does?... oh i forgot :P
Is stonesense displaying correctly for everyone? I've been having some display issues, specifically with creature sprites, and was wondering if anyone else is experiencing this.What kind of issues are these?
The unit class has no appearance_modifier_type. Where do you get that from?I found it here (https://github.com/DFHack/df-structures/blob/master/df.creature-raws.xml).
[lua]# ~df.appearance_modifier_type.HEIGHT
0
[lua]# ~df.appearance_modifier_type[0]
HEIGHT
First you need to look in df.global.world.raws.creatures.all[465].caste[0].body_appearance_modifiers and find the one of type HEIGHT, where 456 is the default creature type of dwarfs, and 0 is male. Replace with the creature type and caste id of the unit in question.printall(df.global.world.raws.creatures.all[467].caste[0]) gives me a bunch of information on dwarves. (I added two new creatures to make 'plain' leather and 'prepared' meat, intestines, liver, etc., and they went at the beginning of the creature file list.)
Requesting programming magic to make DFHack compatible with the new version of DF.
It can't be that hard... Right?
Right?
Requesting programming magic to make DFHack compatible with the new version of DF.
It can't be that hard... Right?
Right?
In all of programming magic, there are few arts deeper or darker. Fortunately, the best practitioners have been making it simpler, and #dfhack is aware of the new release.
We're working on it but we're running out of people asking us to hurry up. ;)
Requesting programming magic to make DFHack compatible with the new version of DF.There's not a lot of new code needed to update to a new version, aside from changes needed to fix things that depend on changed structures. The most work involves figuring out the layouts of changed structures, and maybe new ones too.
It can't be that hard... Right?
Right?
We're working on it but we're running out of people asking us to hurry up. ;)Hurry up!
all i miss is, uhI almost got around to it...
...
actually i mostly want to make a rollercoaster tycoon-esque "most common thoughts, distractions" GUI
I realize that changes take place and that the version he documented in his video is not the same as what exists now. I went to GitHub to look at the commands like he is talking about but the web page does not look like what is in his video. The biggest problem I have is that the GitHub page the wiki points to is one of the most non-beginner-userfriendly pieces of documentation I have ever seen.Yes, the documentation has been undergoing a massive revamp. It was hoped that the new version would be friendlier, but it seems that it can still be improved.
In the video, there on the front page at the 3:45 mark is a big "Commands" section. I cannot find that anywhere (after looking literally for 3 hours). At the bottom of the page currently it says ..and I quoteTwo issues here. First, the "Commands" section has been rearranged into the new "User Manual" section in the online documentation (https://dfhack.readthedocs.org/en/stable/#user-manual). The "DFHack Core", "DFHack Plugins", and "DFHack Scripts" pages each list their set of the commands. It got a bit too unwieldy as a single page, but the new structure is neither searchable nor intuitive unless you already know the distinction.
"The full documentation is available online here, from the README.html page in the DFHack distribution, or as raw text in the ./docs folder. If you're an end-user, modder, or interested in contributing to DFHack - go read those docs."
I clicked on the link but I do not see any "ReadMe" link or the word "Distribution" in any link either. I also do not see anything saying /docs in the linked page. However I do see docs folder on the github page which shows an images and styles folders which again confuses the hell out of me as nothing there has anythnig remotely resembling actual documentation of anything.
Can someone for the love of GOD point me in the right direction? Also.. can someone clean up the github page to be more user friendly and more concise and clear as to where the bloody hell to go to learn about stuff?I've changed the link on the dwarffortresswiki page to go directly to the online documentation (https://dfhack.readthedocs.org/en/stable/#user-manual). Any suggestions on how to be clearer in the GitHub Readme? Would bullet points help?
Any ETA on the dfhack release? It's a pain to build gigantic things without fastdwarf or cleaning out all the blood without clean allfirst world problems... i cant even manage dwarves without dfhack
Ya I actually think just one large page you could do a search on would be a lot easier, but that is purely personal preference as others may like it sectioned off. I thought I would try and get back into the game a little since its been over a year since I played at all. I was also a little interested in learning how to manipulate the map some to customize my embark location. Instead of creating 30+ worlds or more and then searching for a specific set of circumstances in a 4x4 area I was hoping dfhack would allow me to build an embark location. Example: having 4 regions, each being a different type of surrounding so as to increase the number of possible fauna you could encounter and at the same time making sure there was a minimum amount of X and Y resources. Getting lucky on a world creation for something so specific is hard as hell to get right so thought dfhack could help. I just got frustrated as hell just trying to find any kind of tutorial or anything noob friendly at all.
Also.. as to .rst files.. I have no idea what those are, would not have known what I was looking at it if it was waving at me. I just clicked on that folder and said "thats not anything that looks at all what I am looking for" when it opened up and promptly closed it heh
Any ETA on the dfhack release? It's a pain to build gigantic things without fastdwarf or cleaning out all the blood without clean allfirst world problems... i cant even manage dwarves without dfhack
Could someone recommend me a library I could use to display image files in a dfhack plugin?
The images would use transparency and would be layered on top of each other.
local widgets=require('gui.widgets')
local gui=require('gui')
local Button=defclass(Button,widgets.Widget)
Button.ATTRS={
on_click = DEFAULT_NIL,
graphic = DEFAULT_NIL, --refers to the name of a tilepage
label = DEFAULT_NIL
}
function Button:preUpdateLayout()
self.frame=self.frame or {}
if not self.page then self.frame.w=0 self.frame.h=0 return end
self.frame.w=self.page.page_dim_x
self.frame.h=self.page.page_dim_y
end
function Button:onRenderBody(dc)
if not self.page then return end
for k,v in ipairs(self.page.texpos) do
dc:seek(k%self.frame.w,math.floor(k/self.frame.w)):tile(32,v)
end
end
function Button:onInput(keys)
if keys._MOUSE_L_DOWN and self:getMousePos() and self.on_click then
self.on_click()
end
end
function Button:init(args)
if not self.graphic then return end
for k,v in ipairs(df.global.texture.page) do
if v.token==self.graphic then self.page=v return end
end
error('No tilepage found: '..self.graphic)
end
[TILE_PAGE:LEGENDS_BOOK]
[FILE:scp/menu/white-book.png]
[TILE_DIM:16:16]
[PAGE_DIM:4:4]
[TILE_PAGE:BANKNOTE]
[FILE:scp/menu/banknote.png]
[TILE_DIM:16:16]
[PAGE_DIM:4:4]
[TILE_PAGE:SCP_LOGO]
[FILE:scp/menu/scp-logo.png]
[TILE_DIM:16:16]
[PAGE_DIM:8:8]
[TILE_PAGE:SCP_173]
[FILE:scp/SCPs/scp-173.png]
[TILE_DIM:16:16]
[PAGE_DIM:16:13]
[TILE_PAGE:DESCRIPTION_LOGO]
[FILE:scp/menu/tied-scroll.png]
[TILE_DIM:16:16]
[PAGE_DIM:8:8]
[TILE_PAGE:OFFER_TO_CONTAIN_LOGO]
[FILE:scp/menu/exit-door.png]
[TILE_DIM:16:16]
[PAGE_DIM:8:8]
[TILE_PAGE:SCP_S]
[FILE:scp/SCPs/nothin to see here, insect.png]
[TILE_DIM:16:16]
[PAGE_DIM:16:16]
[CREATURE_GRAPHICS:GRAPHICS_CREATURE_SCP]
[DEFAULT:LEGENDS_BOOK:0:0:ADD_COLOR:DEFAULT]
[STANDARD:SCP_LOGO:0:0:ADD_COLOR:DEFAULT]
[MINER:BANKNOTE:0:0:ADD_COLOR:DEFAULT]
[WOODWORKER:SCP_173:0:0:ADD_COLOR:DEFAULT]
[BOWYER:DESCRIPTION_LOGO:0:0:ADD_COLOR:DEFAULT]
[WOODCUTTER:OFFER_TO_CONTAIN_LOGO:0:0:ADD_COLOR:DEFAULT]
[STONEWORKER:SCP_S:0:0:ADD_COLOR:DEFAULT]
I didn't actually intend for it to display within the game window.Depends on what you want.
I had something like stonesense in mind, in which it opens a separate window to display its graphics.
Other way is have dfhack talk to your program through a socket. We use protobuf and basically you write stuff you need from dfhack to your program. This way you have way more control and can even program in any language you want.
local unit=dfhack.gui.getSelectedUnit()
print(printall(unit.appearance.tissue_style))
print(printall(unit.appearance.bp_modifiers))
There's not a lot of new code needed to update to a new version, aside from changes needed to fix things that depend on changed structures. The most work involves figuring out the layouts of changed structures, and maybe new ones too.
It's listening by default, but not everything is supported: stuff for visualizers is supported but it might be strange format (e.g. export EVERYTHING!). And it's not writing a full plugin in c++ just some commands you need (e.g. "GetSelectedUnitId" and "GetUnitAppearance").Other way is have dfhack talk to your program through a socket. We use protobuf and basically you write stuff you need from dfhack to your program. This way you have way more control and can even program in any language you want.
Is dfhack listening for those requests by default or do I need to write a c++ plugin for it?
My goal is to access variables that store a dwarves appearance. One would place the in-game cursor over a unit and have my application display image files based on these values.
Using a lua script I can access the values like this:Code: [Select]local unit=dfhack.gui.getSelectedUnit()
print(printall(unit.appearance.tissue_style))
print(printall(unit.appearance.bp_modifiers))
Angavrilov said he would work on it today, I think, but there are a lot of structures that still haven't been fixed. That script actually crashes at the moment, which is surprising, but probably related to mismatched layouts (apparently creature raws changed significantly). Plugins are typically fixed as structures are fixed, but it's usually faster than figuring out structures.There's not a lot of new code needed to update to a new version, aside from changes needed to fix things that depend on changed structures. The most work involves figuring out the layouts of changed structures, and maybe new ones too.
How's this work going? I've looked at the commit logs on df-structures, but all that told me was that I don't understand it enough to help :-[ Even a confirmed ETA of "no idea" would be nice!
Once structures are updated - but before all the plugin fixes - could someone run the devel/export-dt-ini script? I've got a number of people asking when it'll be ready ;)
DFHack has a server built in that listens for protobuf requests, but you have to implement request handlers (the commands warmist mentioned) in plugins. You could alternatively set up your own server, which could be done with lua, but it's probably easier to use the built-in one if you're able to use protobuf.Other way is have dfhack talk to your program through a socket. We use protobuf and basically you write stuff you need from dfhack to your program. This way you have way more control and can even program in any language you want.
Is dfhack listening for those requests by default or do I need to write a c++ plugin for it?
My goal is to access variables that store a dwarves appearance. One would place the in-game cursor over a unit and have my application display image files based on these values.
Using a lua script I can access the values like this:Code: [Select]local unit=dfhack.gui.getSelectedUnit()
print(printall(unit.appearance.tissue_style))
print(printall(unit.appearance.bp_modifiers))
df_structures for windows seems almost there for 42.02. Can't really test, I don't use windows.Globals are there, but the structures are not. So it would appear to work until crash or corruption.
Globals are there, but the structures are not. So it would appear to work until crash or corruption.
It will be done when all of these: file on github (https://github.com/DFHack/df-structures/blob/master/v0.42.02.lst) will be "VERIFIED" IIRC
So modtools/add-syndrome, for lack of a better term, needs some work, I'm just not exactly sure what. First off most syndromes are added correctly, you can give a unit an interaction that it will use correctly, change display name/tile, change attributes, and basically anything that is considered a "Special Effect" on http://dwarffortresswiki.org/index.php/DF2014:Syndrome (http://dwarffortresswiki.org/index.php/DF2014:Syndrome). But any of the base effects will have do nothing. My brief bit of science that I did found the following.
When applying a syndrome via interaction (which is what I figure we should model add-syndrome after, instead of adding a syndrome via attack). There are several additional components that are not correctly set.
1. None of the target_ vectors are populated in the symptoms list.
2. This leads to no wound being generated.
3. If the target_vectors are artificially populated a wound is automatically created, but it's parts vector is empty
4. Filling in the parts vector seems to correctly "apply" the syndrome. Unfortunately using this method means that out of everything in;Code: [Select][CE_NECROSIS:SEV:100:PROB:100:RESISTABLE:BP:BY_TYPE:THOUGHT:ALL:BP:BY_TYPE:NERVOUS:ALL:START:30:PEAK:60:END:1200]
the only thing we can really do is apply necrosis to the correct body parts for the correct times. As you have to populate all the values, and there is no easy way to handle SEV or RESISTABLE.
5. Unfortunatelyx2 in 3 of my 5 tests the game crashed. This may be because I was creating entries by copying another units. I am unsure
I am hoping that someone more knowledgeable about the workings of things can come up with a way to add damaging syndromes via add-syndrome. Otherwise I will move back to just adding wounds directly (this suffers from the same Unfortunately as number 4)
Posting to remind myself later.
Do you have any recommended resources for learning lua? I have some programming experience, mostly Javascript, with bits of other languages.
We use protobuf and basically you write stuff you need from dfhack to your program. This way you have way more control and can even program in any language you want.Does the latest version of stonesense use protobuf? I'm trying to find a working example and can not get the addressbook one google themselves provide to work.
I learned programming from Stonesense.I learned programming from a before-school TV series on BASIC.
Do you have any recommended resources for learning lua? I have some programming experience, mostly Javascript, with bits of other languages.
... I learned programming from a before-school TV series on BASIC.Right there with ya. (https://upload.wikimedia.org/wikipedia/commons/1/14/Sinclair_ZX81_Setup_PhotoManipped.jpg) ;D 1980, woo hoo!
Get off my lawn :)
... I learned programming from a before-school TV series on BASIC.Right there with ya. (https://upload.wikimedia.org/wikipedia/commons/1/14/Sinclair_ZX81_Setup_PhotoManipped.jpg) ;D 1980, woo hoo!
Get off my lawn :)
Started with a VIC-20, which wasn't around yet when I saw the show on TV... I wrote out programs on paper with no way to run them. But that practice came in handy a few years later when they started putting computers on display at stores... lot's of fun programming them to give advice to customers.... I learned programming from a before-school TV series on BASIC.Right there with ya. (https://upload.wikimedia.org/wikipedia/commons/1/14/Sinclair_ZX81_Setup_PhotoManipped.jpg) ;D 1980, woo hoo!
Get off my lawn :)
If we're going there, I technically learned BASIC from my c64 manual, but I wasn't counting that.I learned programming from Stonesense.I learned programming from a before-school TV series on BASIC.
Get off my lawn :)
I've written a few squad and military tools for Dfhack using C++. I meant more like I could help find the symbols with a debugger and stuff, I just have no idea how the workload is divided or who's even doing what currently.
Just because it compiles doesn't mean it works.You obviously don't work for a AAA videogame studio.
...or nearly any software shop with a dedicated QA department and a relentless focus on billable hours.Just because it compiles doesn't mean it works.You obviously don't work for a AAA videogame studio.
No. Armok Vision does (with the remotefortressreader plugin), and a couple other plugins implement simpler RPC/protobuf commands, like rename.I need to find a client example that interacts with one of the existing dfhack plugins that implement RPC.
About compiling for windows, would it be complicated to allow it to compile with VS 2015 in addition of VS 2010?Unless VS has gotten a lot smarter recently, DFHack needs to be compiled with the same compiler that was used to build the core DF.
So this answer my question. Thanks ! VS2010, back on disk :DYou'd think there could just be a version flag... but there isn't.
Linux, OS X, and Windows should all be equally supported unless someone hasn't found some offsets on Windows yet (I haven't checked).So why isn't my favorite system supported? :'(
Even after checking dev branch, you must checkout libraries/xml folder to master.Every time I hear how complicated this thing is to build, I think there might be room for a DFhack Therapist ;)
Even after checking dev branch, you must checkout libraries/xml folder to master.
Every time I hear how complicated this thing is to build, I think there might be room for a DFhack Therapist ;)
hang on, does someone have a working version for windows?
hang on, does someone have a working version for windows?
ptw
Pwn the weakptw
pay to win?
ptw
pay to win?
See this guy knows whats up.ptw
pay to win?
Posting To Watch
is there a r0 42.03 version for windows available somewhere? i just cant play without managerPatience. It's ready when it's ready. I want my workflow as much as anyone but I also don't want to chance corrupted saves. Until then, keep an eye on the thread with the rest of us! (:
Of course, this is to be taken with the usual grain of salt (i.e. very early experimental build, may crash randomly, may corrupt your saves, your binaries, your hard-drive, your soul, your firstborn, etc.).
is there a r0 42.03 version for windows available somewhere? i just cant play without manager
I can confirm that with the latest xml updates pretty much everything you can expect works on Linux (and by that I mean the UI tools everyone uses like reveal/prospect/workflow/search/etc. still no luck with Rendermax on the other hand).I have absolutely no idea what the problem with rendermax is, since it hasn't changed in a way that should affect anything since 0.34. I did try to troubleshoot it at one point, but adding a print statement to the renderer_light constructor (I think) made the problem go away, at which point I more or less gave up. Which renderers does it happen with, exactly? If it only happens with renderers that use lua in some way, it could be a threading issue of sorts, although I haven't looked at it at all in 0.42.
A warning: Quietust just fixed a nasty crash (and possible corruption issue) that mainly affected workflow, but could theoretically affect anything that interacts with jobs, units, buildings, items, projectiles, and historical figures (in other words, a lot of things). I'd advise against trying to play seriously or save (unless you've made backups) with whatever unofficial builds are floating around, unless they're less than 4 hours old.
Also, a warning: Quietust just fixed a nasty crash (and possible corruption issue) that mainly affected workflow, but could theoretically affect anything that interacts with jobs, units, buildings, items, projectiles, and historical figures (in other words, a lot of things). I'd advise against trying to play seriously or save (unless you've made backups) with whatever unofficial builds are floating around, unless they're less than 4 hours old.
I have absolutely no idea what the problem with rendermax is, since it hasn't changed in a way that should affect anything since 0.34. I did try to troubleshoot it at one point, but adding a print statement to the renderer_light constructor (I think) made the problem go away, at which point I more or less gave up. Which renderers does it happen with, exactly? If it only happens with renderers that use lua in some way, it could be a threading issue of sorts, although I haven't looked at it at all in 0.42.I think it's more specific, as Rendermax has consistently refused to work ever since .34.11 on my Linux machine. I have the same exact problem as described here:
rendermax trippy works.
rendermax light locks the dfhack console, the game keeps running. If I try to exit DwarfFortress, it just locks. It eats 100% CPU as well.
stderr.log shows:Code: [Select]Invoking: rendermax light
Yeah, it happened right after workflow started controlling a job.Also, a warning: Quietust just fixed a nasty crash (and possible corruption issue) that mainly affected workflow, but could theoretically affect anything that interacts with jobs, units, buildings, items, projectiles, and historical figures (in other words, a lot of things). I'd advise against trying to play seriously or save (unless you've made backups) with whatever unofficial builds are floating around, unless they're less than 4 hours old.
Was this the crash that happenned when you put a job on repeat ? By the way, if you need help to test stuff, I may be able to help
I don't see how that's more specific. What other renderers work or hang?I have absolutely no idea what the problem with rendermax is, since it hasn't changed in a way that should affect anything since 0.34. I did try to troubleshoot it at one point, but adding a print statement to the renderer_light constructor (I think) made the problem go away, at which point I more or less gave up. Which renderers does it happen with, exactly? If it only happens with renderers that use lua in some way, it could be a threading issue of sorts, although I haven't looked at it at all in 0.42.I think it's more specific, as Rendermax has consistently refused to work ever since .34.11 on my Linux machine. I have the same exact problem as described here:rendermax trippy works.
rendermax light locks the dfhack console, the game keeps running. If I try to exit DwarfFortress, it just locks. It eats 100% CPU as well.
stderr.log shows:Code: [Select]Invoking: rendermax light
I don't see how that's more specific. What other renderers work or hang?I meant specific as in 'specific to a couple machines like mine', sorry. What do you mean by 'which renderers'? 'Trippy' works and 'light' hangs, for instance.
Yes, which other renderers work/don't work?QuoteI don't see how that's more specific. What other renderers work or hang?I meant specific as in 'specific to a couple machines like mine', sorry. What do you mean by 'which renderers'? 'Trippy' works and 'light' hangs, for instance.
In adventurer mode, how can I detect when the set of units changes, e.g. when moving to a different world tile? I am currently monitoring #df.global.world.units.all, but that doesn’t work if the new tile has the same number of units as the old tile.Monitor the world position of the map.
Regarding DFHack, we (meaning Quietust and Angavrilov) are sorting out some issues with vtables and structures in .02 first, then moving to .03. Hopefully .03 will be stable enough to release soon after that, but I can't make any guarantees.
For anyone interested, I made a progress bar for df-structures, updating daily @0001UTC and whenever I log on and run the script. Green=verified, yellow=aligned, red=unchecked. Currently for 42.02, but I'll try to keep it up to date. Sized for sigs or whatever, so feel free to use/hotlink.
Those are just structures that we've verified are the correct size and/or contain the right fields. It's not completely accurate, and it's usually even less accurate for new minor versions without structure changes (since we don't bother re-checking everything).There's generally no need to double-check everything in a minor release, but is there a way to color it as "previously checked and almost certainly unchanged"? Gray or something would give the
You can also get the current version from version.lisp, I think.
sv-esk already got somewhat working 42.03 offsets, compiles with no issues and most stuff works.Thats what was said about the last unofficial build until it was found that there was a potentially save-corrupting bug. I'll wait.
It would be somewhat difficult to determine because structures can also be partially verified, which creates new/different lines in the .lst file (example (https://github.com/DFHack/df-structures/commit/6e2e8731d2c10a4a5394046ae48cc0cd16e9a049#diff-5f44db9d128278c344bac1c8676ab0ceR1113)).Those are just structures that we've verified are the correct size and/or contain the right fields. It's not completely accurate, and it's usually even less accurate for new minor versions without structure changes (since we don't bother re-checking everything).There's generally no need to double-check everything in a minor release, but is there a way to color it as "previously checked and almost certainly unchanged"? Gray or something would give the
You can also get the current version from version.lisp, I think.cheering sectioninterested parties a sense of scale.
sv-esk already got somewhat working 42.03 offsets, compiles with no issues and most stuff works.Thats what was said about the last unofficial build until it was found that there was a potentially save-corrupting bug. I'll wait.
There are still several broken things, and there may be issues with those offsets that are causing crashes.And keep a fire extinguisher handy. Just in case.
(Also, since the only file DFHack uses that sv-esk touched was symbols.xml, there shouldn't be any recompiling involved, so anything that compiled in .02 should still compile.) I would advise against using it for anything besides testing at the moment.
The only thing we could really figure out automatically would be if DFHack crashes when doing something, and checking a significant number of structures in DF with that technique probably wouldn't be possible (and we can already figure out some size changes without running DF, anyway). DFHack generates its own constructors for all DF objects, so even if the layout for something like "itemst" is completely wrong and would crash if you try to interact with items in DF, items that DFHack creates (df.itemst:new() in Lua, for example) would work just fine, since they'd have the layout DFHack expects.I think PE meant something like a long macro that just exercises standard DFHack stuff and tries to do something with it in the game (spawn a cat then exterminate it, add the first clothing item to a uniform, etc.), though I might be wrong.
Also, even if we did manage to get a pass/crash check implemented for some structures, that wouldn't tell us if their layouts were correct. For example, if Toady changes unit flags, there isn't a way to verify that DFHack's "scuttle" flag corresponds to DF's without manually checking.
Can you guys give me the link to the new symbols file, please?
Thanks
For anyone interested, I made a progress bar for df-structures, updating daily @0001UTC and whenever I log on and run the script. Green=verified, yellow=aligned, red=unchecked. Currently for 42.02, but I'll try to keep it up to date. Sized for sigs or whatever, so feel free to use/hotlink.Maybe add some markers to it so we can actually see it inching forward day by day? Like, one little line every 10 pixels or so, across the top 1/4th of the height.
(http://peridexiserrant.pythonanywhere.com/dfhack-progress.png)
Sadly the necessary skill level for most of the work updating is quite high. Only Quietust and Angavrilov can do the hard stuff.
Yes, which other renderers work/don't work?
Yes, there are others listed by running "rendermax", "rendermax help", or "help rendermax" - try "truecolor" and "lua".Yes, which other renderers work/don't work?
Are there any others than light and trippy? Still not sure what you mean I should test.
So does anyone have a ballpark estimate on how long it will be till dfhack updates? I not looking for a date I just want to have a rough idea if it isn't too much trouble.Going back through the archives to look at the .40 release timeline, I think it took about a month for DFHack to get a mostly-functional release together. OTOH, the release before that was less than a week, as I remember. The holiday season will probably add to the lag, so if I were setting an over/under line, I think I'd go with January 7 or so.
If you are in a hurry and live dangerously, there is an unoficial compiled dfhack for windows 42.03-r0 in reddit's QA thread.
Here's an alpha release - please feel free to test and report issues:
https://github.com/DFHack/dfhack/releases/tag/0.42.03-alpha1
Many things have not been fully tested, so remember to make backups often.
Very minor problems.What kinds of problems?
Very minor problems.What kinds of problems?
Here's an alpha release - please feel free to test and report issues:
https://github.com/DFHack/dfhack/releases/tag/0.42.03-alpha1
Many things have not been fully tested, so remember to make backups often.
Okay, some commands are missing from your dfhack.init. Are you using a pack? The dfhack.init-example file should contain the default commands, so if you can't figure it out, you can add "script dfhack.init-example" on a new line somewhere in dfhack.init.
Very minor problems.What kinds of problems?
Only issue I've seen in adv mode so far is that saving crashes after entering any major settlement. Doesn't matter which type or how long after visiting I save, if a heavily populated site loads, the game won't be able to save. I verified it wasn't just a corrupted save by uninstalling dfhack, and no problem saving.DFHack doesn't really do much with adventure mode. Are you sure you loaded the same site? Were you using specific DFHack tools? If not, a save would be helpful, as I haven't had crashes in adventure mode.
It should load dfhack.init-example if dfhack.init doesn't exist. Did it not do that?Okay, some commands are missing from your dfhack.init. Are you using a pack? The dfhack.init-example file should contain the default commands, so if you can't figure it out, you can add "script dfhack.init-example" on a new line somewhere in dfhack.init.
I am using a pack, but it doesn't ship with DFHack yet. I'll look around for that file. Thanks a bunch! Have a great holiday!
Edit: You are my hero. It turns out I didn't actually HAVE a dfhack.init. I just took the example file, made a copy and renamed.
I'm sure I was using adv-fort, gm-editor, a few dev utils. DFHack does do much in adventure mode. No problem with using those, but if I go into a town+ population, I have to save, switch back to vanilla .dlls, and after leaving a fortress/city/retreat I can relaunch DFHack and use it. But if I have DFHack running when entering any of those, save will always crash, whether it's done there or several region tiles away.Only issue I've seen in adv mode so far is that saving crashes after entering any major settlement. Doesn't matter which type or how long after visiting I save, if a heavily populated site loads, the game won't be able to save. I verified it wasn't just a corrupted save by uninstalling dfhack, and no problem saving.DFHack doesn't really do much with adventure mode. Are you sure you loaded the same site? Were you using specific DFHack tools? If not, a save would be helpful, as I haven't had crashes in adventure mode.
Okay, I'm thinking it's likely to be advfort. What happens if you don't use that?I don't use advfort in settlements, but I use companion-order. But it doesn't appear to make a difference, even if I just stop into a tavern and save there or on the travel map, crash.
[DFHack]# startdwarf 12
E: RuntimeError: ./hack/scripts/startdwarf.rb:18: patch address not available
./hack/scripts/startdwarf.rb:18
(eval):19:in `load'
(eval):19
(eval):19:in `catch'
(eval):19
The keybinds for workflow aren't working. I tried alt-w to set the requirements for a repeating job and got nothing.It works fine for me. A specific job needs to be selected inside a workshop for the command to work.
startdwarf doesn't work on Debian testing, x86.Code: [Select][DFHack]# startdwarf 12
E: RuntimeError: ./hack/scripts/startdwarf.rb:18: patch address not available
./hack/scripts/startdwarf.rb:18
(eval):19:in `load'
(eval):19
(eval):19:in `catch'
(eval):19The keybinds for workflow aren't working. I tried alt-w to set the requirements for a repeating job and got nothing.It works fine for me. A specific job needs to be selected inside a workshop for the command to work.
The general workflow gui seems only to be accessible while in the 'z' overview menu.
If you are having trouble like I was with keybinds not working for dfhack you need to find the dfhack.init example file and rename it dfhack.initDid you have a dfhack.init file? If you didn't, DFHack should have loaded dfhack.init-example and told you.
Thank you reddit lol
If you are having trouble like I was with keybinds not working for dfhack you need to find the dfhack.init example file and rename it dfhack.initDid you have a dfhack.init file? If you didn't, DFHack should have loaded dfhack.init-example and told you.
Thank you reddit lol
231: Storluturvad, "Dimpleseal", town
Owner: The Uncertain Hatchet, dwarves
Parent Civ: The Waxy Pillars, dwarves
lady: Domas Tuskdyes, dwarf
9477 dwarves
523 humans
2425 cats
10 horses
480 blue peafowls
2 alligator outcasts
141 human outcasts
19 dwarf outcasts
1 saltwater crocodile outcast
20 amphibian man outcasts
1 elf outcast
It should load dfhack.init-example if dfhack.init doesn't exist. Did it not do that?Okay, some commands are missing from your dfhack.init. Are you using a pack? The dfhack.init-example file should contain the default commands, so if you can't figure it out, you can add "script dfhack.init-example" on a new line somewhere in dfhack.init.
I am using a pack, but it doesn't ship with DFHack yet. I'll look around for that file. Thanks a bunch! Have a great holiday!
Edit: You are my hero. It turns out I didn't actually HAVE a dfhack.init. I just took the example file, made a copy and renamed.
It should, and multiple DFHack devs on Windows say that it does. Are you sure that you had a dfhack.init-example file and not a dfhack.init file (not even an empty one)?It should load dfhack.init-example if dfhack.init doesn't exist. Did it not do that?
Oh, it indeed did not do that for me.
It should, and multiple DFHack devs on Windows say that it does. Are you sure that you had a dfhack.init-example file and not a dfhack.init file (not even an empty one)?It should load dfhack.init-example if dfhack.init doesn't exist. Did it not do that?
Oh, it indeed did not do that for me.
I absolutely did not have the dfhack.init file. I downloaded dfhack seperately and not part of a pack. Its ok though, its pretty easy to fix once you know how.Oh, did you have a file that had "dfhack" in its name and ended with ".init"?
I absolutely did not have the dfhack.init file. I downloaded dfhack seperately and not part of a pack. Its ok though, its pretty easy to fix once you know how.Oh, did you have a file that had "dfhack" in its name and ended with ".init"?
No, were there files like "dfhack_stuff.init" or "stuff_dfhack.init"? There was an issue where it wouldn't load dfhack.init-example if any files like that existed, which I hopefully just fixed (at least, that's the most likely explanation I can think of).
is there a good way to increase exp gain from socializing with dfhack?
Did you have a dfhack.init file? If you didn't, DFHack should have loaded dfhack.init-example and told you.I don't think so.
Yes, but DFHack is supposed to load dfhack.init-example if it can't find dfhack.init and display a warning, because at one point enough people who installed DFHack didn't read the documentation and were complaining that DFHack tools weren't working.Did you have a dfhack.init file? If you didn't, DFHack should have loaded dfhack.init-example and told you.I don't think so.
That's an old way to provide a config documentation - you name it "something...example" and include every possible configuration option with comments.
User himself copies the file, removes the "example" path and comments out those option he doesn't need.
This "example" file itself is not loaded, it's only acts as more practical version of documentation.
You're right, I just tested this.Yes, but DFHack is supposed to load dfhack.init-example if it can't find dfhack.init and display a warning, because at one point enough people who installed DFHack didn't read the documentation and were complaining that DFHack tools weren't working.Did you have a dfhack.init file? If you didn't, DFHack should have loaded dfhack.init-example and told you.I don't think so.
That's an old way to provide a config documentation - you name it "something...example" and include every possible configuration option with comments.
User himself copies the file, removes the "example" path and comments out those option he doesn't need.
This "example" file itself is not loaded, it's only acts as more practical version of documentation.
(Apparently the problem here was that DFHack would treat any dfhack*.init file as acceptable, and PE's pack was still distributing dfhack_onload_pylnp.init or something similar, so DFHack loaded that and didn't check for dfhack.init.)
I don't think this issue is new to 42.XX, as I feel like I ran into it in one of the masterwork packs, but I am having an intermittent issue with designations. Sometimes, after attempting to use the mouse to designate tiles for digging/channel/ramps, the designate tool will not designate any of the "dig" commands except whichever it happened to break while using. It will then start working later. I apologize for the lack of information on the issue. Its certainly not game breaking, just a little annoying when it happens.
Weird, I guess I just assumed that channel would follow the same "digging" rules. I apologize for my obtuseness.Because channeling designates the tile below to be dug, it doesn't follow the same rules.
local utils=require('utils')
local args = utils.processArgs({...}, validArgs)
local unit = args.unit and df.unit.find(args.unit) or dfhack.gui.getSelectedUnit(true)
if not unit then qerror('A unit must be specified or selected.') end
function satisfyNeeds(unit,needs)
local needs=unit.status.current_soul.personality.unk_v4201_1a
for k,v in ipairs(needs) do
needs[k].unk_8 = 400
end
end
satisfyNeeds(unit,needs)
local validArgs = utils.invert({
'unit',
'someOtherArgument'
})
Having the exact in-game descriptions of the dance forms would probably be best.Oh yeah, forgot that in the middle of breaking down all 12 of those damn moves in the last one.
Here's another alpha release, for 0.42.04 only this time (there was a change to the world layout, among other things, so support for older versions has been dropped):The work you guys pour into these releases is greatly appreciated. We need the modders to rehearse one of Max™'s dances to show the proper level of appreciation...
https://github.com/DFHack/dfhack/releases/tag/0.42.04-alpha1
Are you restarting DF after you add those keybinding commands to dfhack.init? Does running them in the console work? Do you have a job selected in a workshop when you press Alt-W (for the gui/workflow one)?
I think "blocks of rock" means any inorganic material, or maybe stone without a material type (which could end up allowing stone of any material, but then the "blocks of any stone" option wouldn't make sense). I remember generated sites occasionally containing "rock blocks", which I think Quietust said was due to them not having a material ID (or possibly an invalid one?).
Does your dfhack.init have the Alt-W "qui/workflow status" typo your post did?
[DFHack]# startdwarf 20
E: RuntimeError: ./hack/scripts/startdwarf.rb:18: patch address not available
./hack/scripts/startdwarf.rb:18
(eval):19:in `load'
(eval):19
(eval):19:in `catch'
(eval):19
Here's another alpha release, for 0.42.04 only this time (there was a change to the world layout, among other things, so support for older versions has been dropped):
https://github.com/DFHack/dfhack/releases/tag/0.42.04-alpha1
I'm a human spellcheck machine, some call me... The Grammarian?Does your dfhack.init have the Alt-W "qui/workflow status" typo your post did?
Well, damn! LOL, it probably did, I had since deleted anything I added so I can't check. But adding it in there now, it's working correctly! Thanks Max, nice spot!
Although still strange that it wasn't working correctly in the first place, at least it's working correctly now.
Stonsesense keeps crashing when switching between z levels. I'm using 42.04. This bug didn't happen for 42.03.
Why would all unit and nemesis records be listed as 'bad', and what can I do about that to fix my save? What exactly does it mean when it's listed as bad? I know some of them are corrupted, but it couldn't possibly be all of them.Where are they listed as "bad"?
gui/gm-editor df.global.world.units and df.global.world.nemesisWhy would all unit and nemesis records be listed as 'bad', and what can I do about that to fix my save? What exactly does it mean when it's listed as bad? I know some of them are corrupted, but it couldn't possibly be all of them.Where are they listed as "bad"?
gui/gm-editor df.global.world.units and df.global.world.nemesisYour crash is due to something else. units.bad and nemesis.bad are named that because they can contain bad pointers - for example, pointers to unit structures that have been deleted, freed, overwritten, etc.. It's possible that "all" is a subset of "bad" - I've never noticed a save where "all" is larger than "bad", or one where units in "all" aren't in "bad" as well.
Every record listed in 'all' is also listed in 'bad'. I'm at a point where any save I attempt after offloading current site data will crash the game. Without exception.
Yes, the issues were all before installing dfhack to see if they could be fixed. Save crashes occur on unit saving, so that's where I expected to find problems. So dfhack isn't responsible, I'm just trying to use it to repair if possible.gui/gm-editor df.global.world.units and df.global.world.nemesisYour crash is due to something else. units.bad and nemesis.bad are named that because they can contain bad pointers - for example, pointers to unit structures that have been deleted, freed, overwritten, etc.. It's possible that "all" is a subset of "bad" - I've never noticed a save where "all" is larger than "bad", or one where units in "all" aren't in "bad" as well.
Every record listed in 'all' is also listed in 'bad'. I'm at a point where any save I attempt after offloading current site data will crash the game. Without exception.
There are vanilla DF bugs related to offloading sites, or some aspect of site travel at least, in adventure mode. Does the issue occur without DFHack?
<... stuff ...>Most importantly check if the item has in_job flag (if so remove from job and unset flag) and don't forget to call dfhack.items.moveToGround so everything is correctly set (e.g. tile flags that it contains item, item list in map chunk etc...)
edit: Hmm, that dwarf was found dead a couple months later. Might be related? Let's reload and try again!"You can have this here minecart when you pry it from my cold, dead fingers. Oh, wait..."
/home/thefunk/.df/hack/scripts/names.lua:42: Cannot write field viewscreen_setupadventurest.subscreen: not found.
stack traceback:
[C]: in function '__newindex'
/home/thefunk/.df/hack/scripts/names.lua:42: in function 'f'
./hack/lua/dfhack.lua:554: in function <./hack/lua/dfhack.lua:495>
(...tail calls...)
Hmmm.Code: [Select]/home/thefunk/.df/hack/scripts/names.lua:42: Cannot write field viewscreen_setupadventurest.subscreen: not found.
stack traceback:
[C]: in function '__newindex'
/home/thefunk/.df/hack/scripts/names.lua:42: in function 'f'
./hack/lua/dfhack.lua:554: in function <./hack/lua/dfhack.lua:495>
(...tail calls...)
I notice there are pages now in the adventurer setup screens, but none specifically seem to point to the custom name screen.
I tried a more minimal approach, just cleared the item.flags.owned flag, the owned item.general_refs and the unit.owned_items entry, then marked the item for dumping. Eventually the dwarf dropped it. However, that dwarf appears to immediately claim that item (the minecart) as owned any time he picks it up for any reason!<... stuff ...>Most importantly check if the item has in_job flag (if so remove from job and unset flag) and don't forget to call dfhack.items.moveToGround so everything is correctly set (e.g. tile flags that it contains item, item list in map chunk etc...)
I have one other related question... Can Lua manipulate the sidebar while placing a building? This would give the player more immediate feedback if a location is "appropriate". Any single tile can only have one base material, so a single generic Altar would still work even though building materials aren't selected until after the position (for example, if it's a marble tile, the sidebar can report if the location is suitable for an Altar To Marble).You can replace the sidebar entirely (well, technically that involves creating a new screen, rendering the parent/dwarfmode screen, and then drawing over (parts of) the sidebar). The HistScreen class at https://github.com/lethosor/dfhack/blob/designation-history/plugins/lua/designation-history.lua is an example.
The subscreen field was removed (maybe in 0.40, in fact, but we noticed it in 0.42). That'll need to be fixed.The subscreen worked in 0.40 though, but I'll try the way mifki suggested.
The item also appears in units.used_items. My doctor was growing attached to a stack of adamantine coins (and who could blame him.) I tried removing the reference to the item from used_items. Let's see if he stops picking it back up now.I tried a more minimal approach, just cleared the item.flags.owned flag, the owned item.general_refs and the unit.owned_items entry, then marked the item for dumping. Eventually the dwarf dropped it. However, that dwarf appears to immediately claim that item (the minecart) as owned any time he picks it up for any reason!<... stuff ...>Most importantly check if the item has in_job flag (if so remove from job and unset flag) and don't forget to call dfhack.items.moveToGround so everything is correctly set (e.g. tile flags that it contains item, item list in map chunk etc...)
However, the bug is pretty endemic. Several dwarves have claimed ownership of whatever item is in their right hands. I'm trying to create a bug tracker account to document it, but the captcha there appears to be broken.
Thanks, I will take a look at this.I have one other related question... Can Lua manipulate the sidebar while placing a building? This would give the player more immediate feedback if a location is "appropriate". Any single tile can only have one base material, so a single generic Altar would still work even though building materials aren't selected until after the position (for example, if it's a marble tile, the sidebar can report if the location is suitable for an Altar To Marble).You can replace the sidebar entirely (well, technically that involves creating a new screen, rendering the parent/dwarfmode screen, and then drawing over (parts of) the sidebar). The HistScreen class at https://github.com/lethosor/dfhack/blob/designation-history/plugins/lua/designation-history.lua is an example.
The item also appears in units.used_items. My doctor was growing attached to a stack of adamantine coins (and who could blame him.) I tried removing the reference to the item from used_items. Let's see if he stops picking it back up now.I tried a more minimal approach, just cleared the item.flags.owned flag, the owned item.general_refs and the unit.owned_items entry, then marked the item for dumping. Eventually the dwarf dropped it. However, that dwarf appears to immediately claim that item (the minecart) as owned any time he picks it up for any reason!<... stuff ...>Most importantly check if the item has in_job flag (if so remove from job and unset flag) and don't forget to call dfhack.items.moveToGround so everything is correctly set (e.g. tile flags that it contains item, item list in map chunk etc...)
However, the bug is pretty endemic. Several dwarves have claimed ownership of whatever item is in their right hands. I'm trying to create a bug tracker account to document it, but the captcha there appears to be broken.
Oh, look! The doctor left a job to take a drink, and has again claimed ownership of the item he was using for a previous job. This time I saw it happen start to finish. I'm certain he just picked up the item (a steel coin) and was melting it when he left to get a drink, and now that coin is held in his right hand, and he is its new owner.
Looking over my dwarf population, 3 out of 20 have some inappropriate items in their right hand. One has six glass pots of alcohol in his right hand, and is asleep in bed. (Ha, that sounds about right.)
That bug is definitely confirmed for 42.04, I'll try to get a Mantis account to post it.
It's not such a terrible bug, and it's probably related to 0009443: Dwarfs acquire and equip multiple empty goblets (http://www.bay12games.com/dwarves/mantisbt/view.php?id=9443)
Thanks for the heads-up. Guess I'm sticking with 42.03 for now.
Just a thought: does this inappropriate hanging-on happen with anything other than TOOLs? I could easily imagine there's something about the way people carry around books and scrolls that's had an awful side effect on other tools.
The first post still links to that. If you want the alpha release for 0.42, you can search for my post above or just grab it from https://github.com/dfhack/dfhack/releases. Maybe Expwnent could add a link to the alpha release in the first post as well, but it's not considered stable yet as not everything has been tested (although everything is included that was in 0.40.24-r5, so it's possible to test).
I'm getting an error every time I try to launch DFHack, that I'm running an unknown version of DF. I've tried 0.42.04 and 0.42.03, including fresh installs of both, and I tried redownloading the DFHack zip in case there was an error on the first DL. stderr.log reads as follows:
FirstCall()
Initized HOOKS!
DFHack build: v0.40.24-r5-0-g3330225
Identifying DF version.
Loading hack\symbols.xml ... OK
v0.40.24 SDL: PE: 0x54ad7e66
v0.40.24 linux: MD5: c42f55948a448645d6609102ef6439e8
v0.40.24 osx: MD5: c935236736139882b670ed9f1adec52c
Loaded 3 DF symbol tables.
Unable to retrieve version information.
PE timestamp: 0x567ef345
I'm pretty confused because it doesn't seem like anyone else is having this problem. Anyone have any suggestions?
Do you do all your work offline? You don't really need to download that.
To whoever decided to stop including the "include" directory in DFHack releases: You suck.It never should have been there unless someone released a build with the BUILD_DEV setting on by mistake, or maybe in 40d if it was enabled by default then.
The "include" directory is an invaluable and easy to access source of Lua API documentation, and while it is possible to get the data elsewhere, it is more convenient to have it in the main download.
It's not such a terrible bug, and it's probably related to 0009443: Dwarfs acquire and equip multiple empty goblets (http://www.bay12games.com/dwarves/mantisbt/view.php?id=9443)
Thanks for the heads-up. Guess I'm sticking with 42.03 for now.
All of the dwarves who are claiming ownership of items have a preference for the items material.
Removing ownership references and item attachment references seems to fix the items in question. I will try changing the dwarves preferences so they longer like the item materials and see if they stop pathologically claiming items.
I guess if I'm editing preferences, I could make every dwarf prefer potato wine (vodka) and call it Russian Fortress.
Overall, 42.04 is great! I recommend it. Also thanks to the dfhack team for such a continually amazing effort!
local w1
local wN
local d
if oldestFirst then
w1 = 0
wN = #unit.body.wounds-1
d = 1
else
w1 = #unit.body.wounds-1
wN = 0
d = -1
end
local wounds = unit.body.wounds
for w=w1,wN,d do
if wounds[w].syndrome_id == syndromeId then
wounds:erase(w)
return true
end
end
It was for most of the 40.x releases...Do you mean in the Windows packages? Because the headers aren't in any of the OS X or Linux ones that I've downloaded, which include (heh) most of the releases since 0.34.11.
Once upon a time I tried to make a document generator that read the XML, but that XML is nearly impossible to parse without a lowering pass (and Go had no XLST library at the time), so I gave up :(
How's Doxygen? It might be possible to get that working with df-structures's headers.Doxygen is lovely, just requires a lot of good comments in its style to work as well as it might. That being said, it is a good place to get started.
That bug is definitely confirmed for 42.04, I'll try to get a Mantis account to post it.
Thanks for the heads-up. Guess I'm sticking with 42.03 for now.
It's bad enough to impact gameplay and requires preference editing to handle. Pass.
Here's another alpha release: https://github.com/DFHack/dfhack/releases/tag/0.42.04-alpha2Thank you lethosor and DersEvvak!
This one has some new stuff in it, and some fixes since alpha1, although apparently there weren't any awful bugs. The Linux build is using a new cross-compiler now - one consequence of this is that you'll have to delete libs/libstdc++.so.6 if you weren't doing that before, since it's GCC 4.8 (and hopefully your system has GCC 4.8 or newer installed). However, rendermax seems to work perfectly on my Linux machine now - I don't know if this is due to the compiler change or not, since I hadn't tested it in a while, but others should investigate as well. Anyway, please report any issues that are reliably reproducible on Linux with this particular alpha2 build only (that don't occur with a native alpha2 build or alpha1), as well as general issues with alpha2 as usual.
Thanks to DersEvvak for providing a Windows build this time!
The "include" directory is an invaluable and easy to access source of Lua API documentation, and while it is possible to get the data elsewhere, it is more convenient to have it in the main download.
Generally it is good practice to include documentation with a package, since DFHack has no real documentation for it's Lua API (something that really should change, I mean how hard could it be to auto-generate something readable from the XML?) the header files will have to do.
If they're really useful, I can try to package/upload them separately. I don't know if it would be possible/safe to compile anything with them, though, but I don't think they vary across platforms currently.
Regarding documentation, I'm not sure how you could really generate something from just the information in the XML files, aside from boring stuff like "the 5th field in the viewscreen_titlest structure is a 32-bit integer named 'sel_submenu_line'". There are comments and ref-target attributes in a few places, sure, but including them would still result in pretty sparse documentation, and going into detail about what every field is would just clutter up the XML files. Maybe I'm misunderstanding your comments about documentation, though, so do feel free to make suggestions.
There is a file called "Lua API.rst", by the way, which covers most of the DFHack-implemented Lua API (i.e. the parts that don't wrap DF structures).
Clean, easy to read descriptions of the structures (something that looks like C, without the stuff that the compiler needs but the programmer doesn't), preferably with links connecting types to their definitions. Basically something much like what godoc generates (for example (https://godoc.org/golang.org/x/mobile/app#App)). Anything not exported to Lua can be left out.
How's Doxygen? It might be possible to get that working with df-structures's headers.
Depends on how much you have to mark the headers up, too much markup and it's not worth it. If it can be gotten to work, and produces nice, clear, output (that preferably can be linked into the existing DFHack docs), then it is probably worth the effort required.
Once upon a time I tried to make a document generator that read the XML, but that XML is nearly impossible to parse without a lowering pass (and Go had no XLST library at the time), so I gave up :(
./libs/Dwarf_Fortress: symbol lookup error: ./hack/libdfhack.so: undefined symbol: _ZN8rendererD1Evtry doing a fresh, manual rebuild of libgraphics.so (dwarf_fortress_unfuck) and copy it into your DF libs folder (in my case: /opt/df_linux-sf/libs)
Finally I found it in http://dwarffortresswiki.org/index.php/DF2014:Item_tokenAnyone knows the internal identifier of PREPARED_FOOD to use it in reactions?
Meaning gauntlet handedness or unit handedness? For gauntlets, it's apparently just handedness in gauntlets. There's a method to grab it too (gauntlet:getGloveHandedness()).Gauntlet handedness. I want to give some handedness to the gauntlets I just made in adventure mode.
For units: unit.body.weapon_bp is which hand they'll use to hold weapons.
How do you disable the pre-release notice? It often interrupts loading processes that normally don't require user maintenance.Ditto
Right:Meaning gauntlet handedness or unit handedness? For gauntlets, it's apparently just handedness in gauntlets. There's a method to grab it too (gauntlet:getGloveHandedness()).Gauntlet handedness. I want to give some handedness to the gauntlets I just made in adventure mode.
For units: unit.body.weapon_bp is which hand they'll use to hold weapons.
gauntlet.handedness[0]=true
gauntlet.handedness[1]=false
Left:gauntlet.handedness[1]=true
gauntlet.handedness[0]=false
How do you disable the pre-release notice? It often interrupts loading processes that normally don't require user maintenance.Just delete everything in the pre-release warning lua file and save it like that.
Can they both be true for ambidextrous gloves?Right:Meaning gauntlet handedness or unit handedness? For gauntlets, it's apparently just handedness in gauntlets. There's a method to grab it too (gauntlet:getGloveHandedness()).Gauntlet handedness. I want to give some handedness to the gauntlets I just made in adventure mode.
For units: unit.body.weapon_bp is which hand they'll use to hold weapons.Code: [Select]gauntlet.handedness[0]=true
Left:
gauntlet.handedness[1]=falseCode: [Select]gauntlet.handedness[1]=true
gauntlet.handedness[0]=false
You can try it.Would love to be able to run the game here, but can't. Just thought it would be a quick test for someone who is running it right now.
Right:Meaning gauntlet handedness or unit handedness? For gauntlets, it's apparently just handedness in gauntlets. There's a method to grab it too (gauntlet:getGloveHandedness()).Gauntlet handedness. I want to give some handedness to the gauntlets I just made in adventure mode.
For units: unit.body.weapon_bp is which hand they'll use to hold weapons.Code: [Select]gauntlet.handedness[0]=true
Left:
gauntlet.handedness[1]=falseCode: [Select]gauntlet.handedness[1]=true
gauntlet.handedness[0]=false
Would you know the name of that file?How do you disable the pre-release notice? It often interrupts loading processes that normally don't require user maintenance.Just delete everything in the pre-release warning lua file and save it like that.
huh, there's nothing i can do with generated music for now is thereNot terribly much, I dug into them some but it's much like dances, without a full mapping of all the structures in there and what they do it's really hit and miss and I have no clue how the numbers and stuff translate directly into what happens in game consistently.
I've been 99% unavailable for the last several months and that will continue for another week. At that point depending on a real life undecided factor I'll either be a little more active or a lot more active. If there have been any problems with add-syndrome, scripts in modtools, event manager, or the create-unit script I've done my best to make a note of them but I may have missed a few.
EDIT: wait whatNoticed how that and current_soul.personality.unk_v4201_2 are almost identical?
my adventurer's skill count mismatched with the visual in-game, so I was making some assumptions based on that, but when the game crashed as I tried to edit an unknown value (something I 100% expected but had to try anyway) and I reopened it the skill count now matches up with the in-game display
EDIT 2: Nope, still mismatches. Weird weird weird. I doubt "The Great Standard" is being stored in the standard skills vector, so unit_soul.unk_v42_1 is probably new unit skills. My unit only has one, a poetic form called The Great Standard, one notch in the skill, unk_v42_1 was 100110011010110010011100111000 last time I saw it but now it's 100101001000011101000100000000, that's probably not that weird.
EDIT 3: unk_v42_1 is almost surely poetic etc. skills, I just practiced in the grand standard again and it changed from 0x2521D100 to 0x31B3DE88.
EDIT 4: lol i was dumb and forgot the obvious thing to do, just tested by sleeping for 8 hours and it changed even though i didn't practice anything; that could be explainable by skill rust, but that assumes that skills was a good, well-established hypothesis in the first place, which it sorta wasn't
[ 33%] Building CXX object library/CMakeFiles/dfhack.dir/DataStaticsFields.cpp.o
/var/folders/db/pp9mfd491gn92jzm1_1gltmm0000gn/T//ccy0du2C.s:9739:2: error: ambiguous instructions require an explicit suffix (could be 'filds', or 'fildl')
fild (%eax)
^
/var/folders/db/pp9mfd491gn92jzm1_1gltmm0000gn/T//ccy0du2C.s:9757:2: error: ambiguous instructions require an explicit suffix (could be 'fistps', or 'fistpl')
fistp (%eax)
^
/var/folders/db/pp9mfd491gn92jzm1_1gltmm0000gn/T//ccy0du2C.s:9774:2: error: ambiguous instructions require an explicit suffix (could be 'filds', or 'fildl')
fild (%esp)
^
/var/folders/db/pp9mfd491gn92jzm1_1gltmm0000gn/T//ccy0du2C.s:9793:2: error: ambiguous instructions require an explicit suffix (could be 'fistps', or 'fistpl')
fistp (%esp)
^
/var/folders/db/pp9mfd491gn92jzm1_1gltmm0000gn/T//ccy0du2C.s:9813:2: error: ambiguous instructions require an explicit suffix (could be 'filds', or 'fildl')
fild (%esp)
^
/var/folders/db/pp9mfd491gn92jzm1_1gltmm0000gn/T//ccy0du2C.s:9832:2: error: ambiguous instructions require an explicit suffix (could be 'fistps', or 'fistpl')
fistp (%esp)
^
/var/folders/db/pp9mfd491gn92jzm1_1gltmm0000gn/T//ccy0du2C.s:9852:2: error: ambiguous instructions require an explicit suffix (could be 'filds', or 'fildl')
fild (%esp)
^
/var/folders/db/pp9mfd491gn92jzm1_1gltmm0000gn/T//ccy0du2C.s:9871:2: error: ambiguous instructions require an explicit suffix (could be 'fistps', or 'fistpl')
fistp (%esp)
^
make[2]: *** [library/CMakeFiles/dfhack.dir/DataStaticsFields.cpp.o] Error 1
make[1]: *** [library/CMakeFiles/dfhack.dir/all] Error 2
make: *** [all] Error 2
gcc45: This formula either does not compile or function as expected on OS X
versions newer than Yosemite due to an upstream incompatibility.
Karater: I haven't tried it myself, but apparently installing XCode 6 and switching to it on the command line with xcode-select works.got it :)
Has anyone experimented much with diplomacy? Can you make enemy civs hostile/friendly with DFHack?
EDIT: Follow up question, has anyone done much work with changing a units allegiance? I have written a small script that changes a few basic things, but the changed units don't quite behave the way they should. I am wondering if there are flags and such I'm not properly switching. What all goes into determining if two units are hostile/neutral/friendly to eachother?
Has anyone experimented much with diplomacy? Can you make enemy civs hostile/friendly with DFHack?
EDIT: Follow up question, has anyone done much work with changing a units allegiance? I have written a small script that changes a few basic things, but the changed units don't quite behave the way they should. I am wondering if there are flags and such I'm not properly switching. What all goes into determining if two units are hostile/neutral/friendly to eachother?
There's a global "enemy" table that keeps track of sides in a fight but I have no idea how it works.
Diplomacy not so much: probably just mess around with entity (i.e. current site entity vs other one) add appropriate hist-entity links etc...Has anyone experimented much with diplomacy? Can you make enemy civs hostile/friendly with DFHack?
EDIT: Follow up question, has anyone done much work with changing a units allegiance? I have written a small script that changes a few basic things, but the changed units don't quite behave the way they should. I am wondering if there are flags and such I'm not properly switching. What all goes into determining if two units are hostile/neutral/friendly to eachother?
There's a global "enemy" table that keeps track of sides in a fight but I have no idea how it works.
Hmm is this table available for research purposes?
Diplomacy not so much: probably just mess around with entity (i.e. current site entity vs other one) add appropriate hist-entity links etc...Has anyone experimented much with diplomacy? Can you make enemy civs hostile/friendly with DFHack?
EDIT: Follow up question, has anyone done much work with changing a units allegiance? I have written a small script that changes a few basic things, but the changed units don't quite behave the way they should. I am wondering if there are flags and such I'm not properly switching. What all goes into determining if two units are hostile/neutral/friendly to eachother?
There's a global "enemy" table that keeps track of sides in a fight but I have no idea how it works.
Hmm is this table available for research purposes?
As for allegiance: it's controlled by few factors: it's civ_id and there is also it's history (e.g. crimes etc...) that get recalculated ever so often into a cache table (which i guess Roses mentioned) I think it was called df.global.world.enemy_cache, but could be wrong... The research in that table entry values is here:
gist (https://gist.github.com/warmist/3017dc796a6173c215bb) Totally not finished and could be wrong. But the idea is that you might need to change them when you change civ_id so they would not attack wrong unit while it gets recalculated. Or you could change it to force unit to attack (and then the crimes and etc. system takes care of holding them as enemy).
I'm more worried about skills specifically.It would be great to cull out unwanted forms and examples and make the lists less spammy.
Does anyone have a save in 40.24 that has invaders in it? Preferably with merchants at the same time, although not necessary.
Does anyone have a save in 40.24 that has invaders in it? Preferably with merchants at the same time, although not necessary.
I hope that my savegame can be of service. Human siege, no merchants. I saved it the very first moment they spawned on the map.
Haven't unpaused it before the save. This siege did not start with the usual black screen "A vile force of darkness has arrived!" but with a popup "The enemy have come and are laying siege to the fortress."
http://dffd.bay12games.com/file.php?id=11700 (http://dffd.bay12games.com/file.php?id=11700)
anon_6 = 1935455
anon_7 = 570428152
while an earlier one isanon_6 = 1675531
anon_7 = 570414840
Can't seem to find any reason
Does anyone have a save in 40.24 that has invaders in it? Preferably with merchants at the same time, although not necessary.
gui/gm-editor "world.vermin"
=> all. (Or just "world", there is a lot resources for !!SCIENCE!! right there)I tried a quick save during a brain fart and it corrupted the saveWhat does that mean? If quicksave is causing corruption, that's a serious problem.
GOAL: Get a bee (or other colony) on your embark site.
2) My understanding is that DFHack currently can create units and items, but no vermin. So we take an existing vermin and change it into a colony.
I might know... I had a script for that i think...GOAL: Get a bee (or other colony) on your embark site.
2) My understanding is that DFHack currently can create units and items, but no vermin. So we take an existing vermin and change it into a colony.
https://dfhack.readthedocs.org/en/stable/docs/Plugins.html#colonies
There's a plugin for that! (It would be great if we could also spawn colonies, but nobody knows how)
There's a plugin for that! (It would be great if we could also spawn colonies, but nobody knows how)I had a look at the script from the command before I posted, but all it does is scan for existing colonies and change the race value to HONEY_BEE. That´s not really helpful if you embark in a warm temperate forest with river (no colonies there), but want to set up a mead production.
I might know... I had a script for that i think...
So could we in theory make fish farms with hives?This would be specially useful, if the creatures of the new modded colonies were given the TAGs [UBIQUITOUS], [AMPHIBIOUS], [VERMIN_SOIL_COLONY], [VERMIN_FISH], [FISHITEM], [COOKABLE_LIVE], [UNDERGROUND_DEPTH:min:max], [COLONY_EXTERNAL:], [ARTIFICIAL_HIVEABLE], [HIVE_PRODUCT::::::] and then, the hives placed near a well or another source of water.
Finally got around to it!There's a plugin for that! (It would be great if we could also spawn colonies, but nobody knows how)I had a look at the script from the command before I posted, but all it does is scan for existing colonies and change the race value to HONEY_BEE. That´s not really helpful if you embark in a warm temperate forest with river (no colonies there), but want to set up a mead production.
To spawn colonies as far as I know you would have to write a script similar to create-unit.lua from the modtools and even there they are using the "arena_spawn" function if I got that right, so not sure if that would work for vermin.
Thats why I came up with this dirty way of "creating" a vermin colony from a random temporary vermin.
I might know... I had a script for that i think...
Would be great!
-- creates a honey_bee (or other vermin) colony at pointer
local args={...}
local vermin_name=args[1] or "HONEY_BEE"
local vermin_id
function findVermin(name)
for k,v in pairs(df.global.world.raws.creatures.all) do
if v.creature_id==name then
return k
end
end
qerror("No vermin found with name:"..name)
end
vermin_id=findVermin(vermin_name)
local pos=copyall(df.global.cursor)
if pos.x==-30000 then
qerror("Cursor must be pointing somewhere")
end
local verm=df.vermin:new()
verm.race=vermin_id
verm.flags.is_colony=true
verm.caste=-1 -- check for queen bee?
verm.amount=18826
verm.visible=true
verm.pos:assign(pos)
df.global.world.vermin.colonies:insert("#",verm)
df.global.world.vermin.all:insert("#",verm)
Should create colony at cursor.
Should create colony at cursor.It seems really nice warmist!
Should create colony at cursor.It seems really nice warmist!
If you add a colonies list option, could your script substitute the colonies pluging in DFHACK?
Its been a bit since 40.05 came out. Is there a problem with it?I think .06 is expected soon.
Its been a bit since 40.05 came out. Is there a problem with it?It hadn't been tested much, although there don't seem to be many issues.
Are you confident in it enough to release an alpha? Or is it already there and I'm just not looking in the right place?Its been a bit since 40.05 came out. Is there a problem with it?It hadn't been tested much, although there don't seem to be many issues.
As in minutes after PE's Starter Pack ships with DFHack for 42.05? :)Its been a bit since 40.05 came out. Is there a problem with it?I think .06 is expected soon.
Yes. And in order to take advantage of any of the changes and fixes you've been waiting for the most, you must generate a new world.As in minutes after PE's Starter Pack ships with DFHack for 42.05? :)Its been a bit since 40.05 came out. Is there a problem with it?I think .06 is expected soon.
Well, that's always a risk with simultaneous development. It took several months last time to get to the point where updating the packs was a relatively minor thing, and it coincided with Toady tapering off the releases and going back into the long development cycle.Yes. And in order to take advantage of any of the changes and fixes you've been waiting for the most, you must generate a new world.As in minutes after PE's Starter Pack ships with DFHack for 42.05? :)Its been a bit since 40.05 came out. Is there a problem with it?I think .06 is expected soon.
Built the newest commit in the repository but symbols.xml doesn't have an entry for the newest version of Dwarf Fortress, so dfhack deactivates on startup. Are there other changes in the pre-built binary that aren't in the source version?My guess is that you need to use develop branch. That is there all the (hot) action is going :)
My guess is that you need to use develop branch. That is there all the (hot) action is going :)
# get a fresh copy of the repo
git clone https://github.com/DFHack/dfhack.git .
# get (hot) action
git branch develop
git checkout develop
git pull origin develop
# the following step is what you can't do if you just downloaded the zip
git submodule update
Built the newest commit in the repository but symbols.xml doesn't have an entry for the newest version of Dwarf Fortress, so dfhack deactivates on startup. Are there other changes in the pre-built binary that aren't in the source version?Yes. We didn't update the library/xml submodule, so the develop branch doesn't point to a df-structures commit with Windows 0.42.05 support. That should be fixed now (once you run "git pull" and "git submodule update", of course).
Just use a text editor, you big lug.I just now thought of that.
autogems definitely needs to notice that rough gems are forbidden or marked for dumping before creating tasks to cut them, and it also needs to be able to notice that some other task, such as a mood, has taken the gem.
Has anyone identified the event/rumor data for adventurer mode? I thought it would be in the nemesis file, which would explain the lag every time it displays. Is it buried in userdata?it might get digging in history of world. That usually takes ages as it's a VERY big list.
I'm trying to cull out the insignificant ones to make the list fit for purpose. At this stage of play, the rumors dialog is unusable and simply opening the journal takes a few seconds. I predict the journal will get as bad as the rumor list.
I doubt these are in the history of the world, it's full of items too trivial for history. Such as when a wild animal gets spooked by any other creature's presence, and every single occurrence of the performance of every single tale or text. There's scant overlap between what goes into this rumors list and what is retained in legends. Also, none of it transfers to any other character or fortress.It can filter or look up by id. E.g. your adventurer has a list of historical_event ids and then you open menu game looks every one of them up thus binary searching through a HUGE amount of events.
Yes, PE's Starter Pack, I'll start including that in my posts from now on.
==> Graphics - Numerous "anomalies"...dwarves are mostly the same shape, just different colors. (Could be user error)Might be due to TwbT.
==> Unable to name stock piles. :(How are you trying to rename them?
So autocut definitely needs to notice that rough gems are forbidden or marked for dumping before creating tasks to cut them, and it also needs to be able to notice that some other task, such as a mood, has taken the gem.Sorry about that; I now have a potential fix that I'll submit after testing. Meanwhile, as has been noted, you can link one stockpile to the workshop(s), while keeping a few gems in an unlinked stockpile for moods.
Enabling the plugin should not also enable the workshop order IMO, as automatically cutting rough gems is a big change from vanilla behavior with potentially serious downsides for moody dwarves. (I've had a few comments on this in the Starter Pack thread too)It makes sense when the only people enabling it are those who intend to do so. Apparently, that's not the case, so I can also leave it disabled by default. It can be enabled on a per-world basis easily enough.
So am I right in assuming that in regards to gem cutting:I can't speak to #1, but yes, autogems should render such a workflow hack obsolete. Autogems does respect stockpile links, so it only cuts all gems if you have an unlinked workshop.
1. The new Autogem starts enabled with the Starter Pack install of DFHack?
2. I can stop using a workflow setup where I start with cutting any old gem and then while setting up a Workflow changing it from the specific gem I selected to using "gem of any type"?
or
3. Autogems cut all gems, yes? So perhaps I should keep on with my current method as at least I can link up a stock pile and more easily prevent gems I do not want cut from being cut?
What are the current settings for autogem and how are they changes? My mod uses rough gems as reagents, so I'll need to include instructions on turning this off entirely and/or how to systematically exclude several types of rough gems from automatic cutting.Currently, it can be enabled or disabled on two levels:
Thank you, this is helpful. Wishlist items would beWhat are the current settings for autogem and how are they changes? My mod uses rough gems as reagents, so I'll need to include instructions on turning this off entirely and/or how to systematically exclude several types of rough gems from automatic cutting.Currently, it can be enabled or disabled on two levels:
First, the enable and disable commands on the DFHack command line or in a configuration file;
Second, the o-W "Current Workshop Orders" screen.
In addition, stockpile links can be used to limit a workshop to cutting only certain types of gem.
I'm open to ideas for other configuration options, as long as they're easy to use.
As an update, it appears that spawned critters become insubstantial after a save and reload. This particular one has earned a name and is thus a historical figure. After reloading, there are dozens of pages of dwarves' attacks passing through the creature and the creature's attacks deflecting off of clothing. Prior to saving, the creature had the beginnings of an impressive kill list.
Does anyone know if it is possible to change the color scheme (the data loaded from "data/init/colors.txt" on the fly? If so I want to make a script that allows mods to use custom color schemes without needing to install them separately (why? Take a look at this. (http://www.bay12forums.com/smf/index.php?topic=154960.msg6703020#msg6703020))Yes.
I mean I can't find it on the repo.
I don't remember that option, but there's a ctrl-shift-n hotkey in the default configuration that should work.
and if you wanna compile it yourself after they change the cmakelist , know its probably going to corrupt your save cause they just changed that file and nothing else yet, and read the great great great dfhack documentation webpage which you can find if you try, its all in there. there is some more info on compiling in the GitHub repository , but the read the doc page is a lot better and more complete.Neat, thanks.
Also finding a copy of visual studio 2010I have multiple installations of it for some reason so I think I'm good. Is there a reason DFHack still uses 2010 instead of moving to a newer Community edition or whatever?
Yeah, DFHack absolutely has to use whichever compiler was used for Dwarf Fortress, or it won't work.Also finding a copy of visual studio 2010I have multiple installations of it for some reason so I think I'm good. Is there a reason DFHack still uses 2010 instead of moving to a newer Community edition or whatever?
Yeah, compiling DFHack isn't that hard, either. Just follow the instructions step by step.
Yeah, compiling DFHack isn't that hard, either. Just follow the instructions step by step.
The biggest headache is the download time for all the required stuff. Also finding a copy of visual studio 2010, since MS stopped making the express version easy to find.
Wait, that's all I need, Microsoft's Visual Studio 2010?
The cool thing (imo) about compiling your own dfhack is that you never have to ask "is it ready yet/when will it be ready" - you can try it out for yourself and find out without bothering a soul.
Wait, that's all I need, Microsoft's Visual Studio 2010?
http://dfhack.readthedocs.org/en/stable/docs/Compile.htmlThe cool thing (imo) about compiling your own dfhack is that you never have to ask "is it ready yet/when will it be ready" - you can try it out for yourself and find out without bothering a soul.
Be aware that just because it compiles doesn't mean it works.
makeAnnouncement has a pos argumentThanks for the pointer, but I apparently failed to decipher gui.h properly. This is the header line
DFHACK_EXPORT int makeAnnouncement(df::announcement_type type, df::announcement_flags mode, df::coord pos, std::string message, int color = 7, bool bright = true);
but I get errors about a "complex object" in my tests, mostly likely an issue with the announcement_flags. Would you mind giving me the code to announce "This is a test" at position {x=10,y=20,z=30} with no zooming or pausing?
<snip>
but I get errors about a "complex object" in my tests, mostly likely an issue with the announcement_flags. Would you mind giving me the code to announce "This is a test" at position {x=10,y=20,z=30} with no zooming or pausing?
https://github.com/sv-esk/df-structures/commit/dd6dc08faa0a977115c0a48a015eb9768fc06359
While updating structures I've encountered a problem.
I am sure these two compounds ("waypoints" and "burrows" in "df.global.ui") are correct and are in the right place. 6 points, 3 burrows, "In_edit_waypoints_mode" is true when I am editing route. Structures look and behave same as they were in 42.05. But there are "16 bytes of something" between them on windows 0.42.06, and only 12 bytes on linux 0.42.06. How to describe these 16(12)bytes in xml? Or am I doing something wrong?Spoiler (click to show/hide)
After much trial and error, this works:<snip>
but I get errors about a "complex object" in my tests, mostly likely an issue with the announcement_flags. Would you mind giving me the code to announce "This is a test" at position {x=10,y=20,z=30} with no zooming or pausing?
It could also be that it wants a df.coord instance, not an Lua table that happens to have x, y, and z fields. I think the syntax to make one is df.coord:new().
dfhack.gui.makeAnnouncement(5,{false,false,false,true},xyz2pos(10,20,30),"You have struck whatchamacallit!",6,1)
So I want to save the camera's position and zooms it backdf.global.window_x
While we're on the subject of spawning, create-unit move the camera around because it simulate some arena mode input and zooms into whenever the game felt spawning the unit to, even if I teleport is towards its intended location.
So I want to save the camera's position and zooms it back at the end of the script but I cannot find any position for the player's view anywhere. Is this accessible?
I'll try to incorporate restoring the view into any fixed code I come up with. There is definitely something broken about creatures in civ -1 becoming historical. Next step (when I get a chance, maybe Monday) is to see if it affects creatures in a real civ.While we're on the subject of spawning, create-unit move the camera around because it simulate some arena mode input and zooms into whenever the game felt spawning the unit to, even if I teleport is towards its intended location.
So I want to save the camera's position and zooms it back at the end of the script but I cannot find any position for the player's view anywhere. Is this accessible?
Right now you have to do it yourself. I think create-unit has bigger problems at the moment though. It's currently a proof of concept more than a working thing.
Dirst: is this (https://github.com/DFHack/dfhack/blob/develop/scripts/modtools/create-unit.lua) the most recent/functional version of create-unit?That is identical to what shipped with PE Starter Pack for 42.05, which is where I started but that errors out. These changes make it run without errors, but may be the source of the insubstantial historical figure issue:
In other news, I found a bug in modtools/create-unit.lua for DFHack 0.42.05-r1So, there appears to be a really serious loose end here :(
I can only spawn wild animals if I change line 440 from
elseif args.civId and tonumber(args.civId) then
to
elseif args.civId and tonumber(args.civId) and tonumber(args.civId) ~= -1 then
This skips over nemesis creation for creatures in civ -1 and runs without errors, but I'm not sure if all of the loose ends are properly tied up. I can get one of the animals named then save and reload, but not sure how else to test for save consistency.
So I want to save the camera's position and zooms it backdf.global.window_x
df.global.window_y
df.global.window_z
While we're on the subject of spawning, create-unit move the camera around because it simulate some arena mode input and zooms into whenever the game felt spawning the unit to, even if I teleport is towards its intended location.
So I want to save the camera's position and zooms it back at the end of the script but I cannot find any position for the player's view anywhere. Is this accessible?
Right now you have to do it yourself. I think create-unit has bigger problems at the moment though. It's currently a proof of concept more than a working thing.
If you look at the raw data array you should see ascii characters in a string.
One thing that helps is that we can run DF in Windows, OSX, Linux, and WINE. Different ones are useful for discovering different things. I don't know the particulars. Only Quietust and Angavrilov do.
Under GCC, vectors consist of 3 pointers (12 bytes) internally, while strings consist of just 1 pointer (to a buffer with some header information followed by ASCII characters, I think). The layout of these is different under MSVC (heck, it's even different between some MSVC versions) - apparently vectors are 16 bytes with MSVC 2010, but I don't know much else.
OK. That will be in the next version. You said "these changes" but I only saw one. Is that the only one?Sorry, bad phrasing. It was just the one change there. I've made a lot of other changes to a WIP copy but nothing else has been an improvement.
I didn't find anything in the ...2010 folder.generate batch failed to do its work. Run it in console to see its output.
See also "......../build/VC2010/CMakeFiles/CMakeOutput.log".
See also "......../build/VC2010/CMakeFiles/CMakeError.log".
sv-esk has updated some things, which I'll take a look at merging later today. I don't think they've checked everything, though, but if it's usable I'll try to make an alpha release soon after.
The read the docs page is much more detailed if my memory serves...They're exactly the same, assuming you mean https://dfhack.readthedocs.org/en/latest/docs/Compile.html and https://github.com/DFHack/dfhack/blob/develop/docs/Compile.rst. (The copy on ReadTheDocs is generated whenever the GitHub copy is changed.)
I'm debating moving my todo list onto github so people can see and comment on stuff but I'm not sure if it's worth the effort. Right now it's just a text file.Do it halfway: gist :D
startdwarf the lua script that enables embarking with more than 7 dwarves does not work (fails silently), in DF Tool 2.3 that works, so AbdulovHell has found the fix for his utility. As he is also a C++ programmer I have asked him if the transfer of this know-how towards DFHACK could be possible, he is however not fluent in english. Help him please!I'm still amazed he did that by himself before DFHack was updated.
...
Perhaps troubleshooting could be taken to the IRC channel? A forum thread is not the best format...
Why are you bothering me when I am trying to juggle four different prerequisite installations, some of which must be ran as an exe, others which must be copied to a different folder, and even more that I can't even find where it's going, with each of them giving me dozens of options, some of which don't really seem relevant to my efforts, and which I cannot seem to find a way to change after the installation?
Seriously, I am trying to get into this thing. Thank you, everybody who's taking a few seconds to give recommendations, and NO THANK YOU people who are just here to complain about a newbie not completely understanding these programs, and not even adding anything as the person an hour before them just explain how I went wrong.
There is NO DOCUMENTATION REGARDING WHAT TO DO IN THIS SITUATION. I have reinstalled EVERY PROGRAM, making it through the COMPLETE LACK OF UI of many of them, checking off with the readthedocs site as I go.
That was ONE THING. I made it through the sea of prerequisite programs with only one problem, searched through the forums to find a problem not found in the documentation, and it's still not working.
I am helping, its called tough love. its meant to embarrass you so you actually go read every line of available documentation."Tough love" is bullshit and has been shown to be bullshit. It's mostly promoted by people who either don't actually need to teach anyone anything and by people who don't have enough patience to actually teach people properly. The latter then often complain how awful their students are and wonder why others get along better with them.
Any examples of the output?
Nope, each civ keeps its own save file. When a chunk is added it is whatever-anyone-else-used + 1.I think there are two ways unit is saved: either into civ or into site. Though not sure.
So I'll scan backwards until I find the most recent historical figure of civ -1 and increment from that. But where could the game keep its next_member_idx for civ -1???
Went the easier route: creatures spawned in civ -1 are simply not historical figures. If they're dangerous, they'll get a name by themselves fast enough.Spoiler: create-unit.lua (click to show/hide)
This also fixes the cursor-whiplash problem.
EDIT:Note that supposedly hostile creatures still appear as "friendly" on the unit screen, and they act pretty calm unless prodded with berserkness or something. This appears tied to the arena-spawning method.
EDIT EDIT: Dug up an old workaround. It uses handwavium to insert the spawned creature into population 1 of region (1,1) which classifies the critter as a wild animal but might do some damage to the world data. Anyone know how to creature a population entry on the active map block?
Is there a script that can force a civ to only have a predefined pantheon?
I will gladly reshare tomorrow on any other free file site you guys recommend , but I am trying to leave work today and typing this is taking to long already so I am out, good luck, and your credit cards are belong to me if you use this (kidding I promise this is the develop branch of the git for dfhack, but internet, ya know)How about a permalink to the file in your free Dropbox?
It can, it just requires weird frame timing stuff and I haven't actually tried it so it might be crashy as hell.
http://dffd.bay12games.com/I will gladly reshare tomorrow on any other free file site you guys recommend , but I am trying to leave work today and typing this is taking to long already so I am out, good luck, and your credit cards are belong to me if you use this (kidding I promise this is the develop branch of the git for dfhack, but internet, ya know)How about a permalink to the file in your free Dropbox?
It's not really release-ready, but it's getting closer, and I was hoping to fit in an alpha release this weekend, so that build probably won't explode significantly more than alpha1. Anyway, it would be helpful if people using that build could hunt down and report issues, instead of assuming we know about them (we probably don't) and waiting for the next alpha build.I can build it and bugreport for Linux if you tell me what parts you need tested.
It's not really release-ready, but it's getting closer, and I was hoping to fit in an alpha release this weekend, so that build probably won't explode significantly more than alpha1. Anyway, it would be helpful if people using that build could hunt down and report issues, instead of assuming we know about them (we probably don't) and waiting for the next alpha build.I wish I could help. The alpha build has just been so damned stable for me, it's annoying! ;)
Is the alpha build compatible with v42.06? If so, I can git it tonight and bug test everything in Linny Mint and Win 7. :D ( I really need dfhack for something, sooner rather than later. I don't mind if it inflicts !!weird!! on my saves or crashes the game now and again as long as it's >70% stable and does the one thing I need it for. ( Unit and location renaming. ) Besides that having Stonesense and Soundsense again would be very nice.It's not really release-ready, but it's getting closer, and I was hoping to fit in an alpha release this weekend, so that build probably won't explode significantly more than alpha1. Anyway, it would be helpful if people using that build could hunt down and report issues, instead of assuming we know about them (we probably don't) and waiting for the next alpha build.I wish I could help. The alpha build has just been so damned stable for me, it's annoying! ;)
git clone --recursive https://github.com/DFHack/dfhack
cd dfhack
. So after many failed attempts I just managed to compile and build DFhack. Turns out in my previous attempts I made one (probably very silly) mistake. I downloaded the code via the 'Download Zip' instead of using this commandThanks, I was just having the same problem because I was trying to use "remote add" in my git command. >_>Code: [Select]git clone --recursive https://github.com/DFHack/dfhack
.
cd dfhack
Then I followed the instructions and it would always fail.
It might be useful to make a note of this right at the top of the instructions for Windows, because that's where I started reading the page, thinking that was where I should start. I think that might be very helpful for other noobs of Github, like myself.
Anyway, I'm now ready to try it out, thanks for a great tool!
I just updated the develop branch to point to the latest df-structures commit, so ensuring that you have the latest develop branch (of DFHack) and running "git submodule update" should get you a working df-structures. Thanks to sv-esk, the offsets should be complete on all three platforms, so DFHack should at least start up normally, although I haven't tested anything on Linux yet. OS X definitely works, though.
https://drive.google.com/file/d/0ByxHQd6Tsa3nUEJyV3lHdzJQRVE/view?usp=docslist_api (https://drive.google.com/file/d/0ByxHQd6Tsa3nUEJyV3lHdzJQRVE/view?usp=docslist_api)
How about Google? I dropped it in my google drive before I left work and remembered I could share it from there.
But I am not comfortable with this, I am not familiar enough with Google shares to know the world can't see all my stuff now.
So after many failed attempts I just managed to compile and build DFhack. Turns out in my previous attempts I made one (probably very silly) mistake. I downloaded the code via the 'Download Zip' instead of using this commandThanks, I was just having the same problem because I was trying to use "remote add" in my git command. >_>Code: [Select]git clone --recursive https://github.com/DFHack/dfhack
.
cd dfhack
Then I followed the instructions and it would always fail.
It might be useful to make a note of this right at the top of the instructions for Windows, because that's where I started reading the page, thinking that was where I should start. I think that might be very helpful for other noobs of Github, like myself.
Anyway, I'm now ready to try it out, thanks for a great tool!
I just updated the develop branch to point to the latest df-structures commit, so ensuring that you have the latest develop branch (of DFHack) and running "git submodule update" should get you a working df-structures. Thanks to sv-esk, the offsets should be complete on all three platforms, so DFHack should at least start up normally, although I haven't tested anything on Linux yet. OS X definitely works, though.
Confirming, works on Windows :)
Edit. Got it. Thanks Santa! :)
Edit. Got it. Thanks Santa! :)
Sharing is caring ;)
How about helping some other brothers out?
It's not really release-ready, but it's getting closer, and I was hoping to fit in an alpha release this weekend, so that build probably won't explode significantly more than alpha1. Anyway, it would be helpful if people using that build could hunt down and report issues, instead of assuming we know about them (we probably don't) and waiting for the next alpha build.I wish I could help. The alpha build has just been so damned stable for me, it's annoying! ;)
and I was hoping to fit in an alpha release this weekend
I just built the develop branch on ubuntu and it starts up just fine. Haven't done much yet, but it's a good start.
git clone --recursive https://github.com/DFHack/dfhack -b develop
cd dfhack
For a couple of dfhack scripts/plugins (i.e autolabor, workflow) there is some data stored separately for each save file. Where is it stored? Is it possible to copy it from one save to another?Those two store their data as fake historical figures, which means it gets written to world.sav when DF saves (or unit#.sav, or something else). There's not a really easy way to extract that, although those plugins could implement their own export functionality.
For example I have some dwarf labor rules set up in autolabor in game A. I did set it up once and then every time I load that save it's there. Is it possible to copy it to my next games without manually typing everything in dfhack console?
Thanks in advance!
Cheers,
Matt
Ahh, I think I figured it out. I was following old instructions and cloning quietust's develop branch. Yeah, when I build from the regular develop branch it looks like dfhack. I do get some error/warning messages at startup:I'm going to guess that those plugins in red are left over from the older version of DFHack. You can safely remove those. (If you're on Linux, remotefortressreader was renamed to RemoteFortressReader, so I expect you have both in the folder and can get rid of the lowercase one.)
Loading bindings from data/init/interface.txt
Resetting textures
Plugin weather: missing symbol: plugin_name
Can't load plugin misery
Plugin drybuckets: missing symbol: plugin_name
Plugin remotefortressreader: missing symbol: plugin_name
Plugin feature: missing symbol: plugin_name
Plugin initflags: missing symbol: plugin_name
DFHack is ready. Have a nice day!
DFHack version 0.42.06-alpha0 (development build 0.42.05-alpha1-40-g8eb39cc)
But it starts up, gives the usual prerelease warnings, workflow seems to be working. Enhanced stock screen looks good. I've definitely got dfhack running this time.
Something is wrong. All 0.42.06 symbols are known. missing symbol error shoul not be a thing"symbol" in this case is a symbol defined in a plugin (or shared object, returned by dlopen()/dlsym()), not a DF global.
Ahh, I think I figured it out. I was following old instructions and cloning quietust's develop branch. Yeah, when I build from the regular develop branch it looks like dfhack. I do get some error/warning messages at startup:I'm going to guess that those plugins in red are left over from the older version of DFHack. You can safely remove those. (If you're on Linux, remotefortressreader was renamed to RemoteFortressReader, so I expect you have both in the folder and can get rid of the lowercase one.)
Loading bindings from data/init/interface.txt
Resetting textures
Plugin weather: missing symbol: plugin_name
Can't load plugin misery
Plugin drybuckets: missing symbol: plugin_name
Plugin remotefortressreader: missing symbol: plugin_name
Plugin feature: missing symbol: plugin_name
Plugin initflags: missing symbol: plugin_name
DFHack is ready. Have a nice day!
DFHack version 0.42.06-alpha0 (development build 0.42.05-alpha1-40-g8eb39cc)
But it starts up, gives the usual prerelease warnings, workflow seems to be working. Enhanced stock screen looks good. I've definitely got dfhack running this time.
Not sure what command window you're referring to,The only command-line window that opens in conjunction with DF+dfhack. And by configurable I'm talking about letting people assign their own sets aliases in an .init file, so they can use abbreviations convenient to them to refer to longer strings on command line as well as in the interpreter.
This may be a poor time to request a core feature, but could someone consider it on the back burner?https://github.com/DFHack/dfhack/issues/701
Aliases for commonly used command strings, pre-configurable in .init, usable in command window and interactive lua. This would be especially helpful for referencing the df.* heirarchy; ie aliasing 'df.global.world.world_data.sites' to 'SITES' and 'SITES[ # ]'. Could also include the command in the alias.
0.42.06-alpha1 is up: https://github.com/DFHack/dfhack/releases/tag/0.42.06-alpha1Someone posted about it not being updated on /dfg/ literally seconds before I posted the link to it.
It contains some more fixes than the builds from yesterday, but the new stuff could also introduce problems that people didn't find earlier, so back things up, report problems, etc.
sorry for referring to 0.40.26 still but tele-dwarves kinda cause babies to be abandoned, random babies lying around most of the time. either they don't hunger/thirst ormy absolute laziness waiting for the right phase of game to "be normal" on one of my worldskeeping teledwarf on is having dwarves provide... but they're perfectly fine and even grow up.
Considering the way teledwarf works (by checking every unit on every tick to see if they're pathing, then teleporting them to the path destination should there be one), that doesn't surprise me in the slightest. "Teleporting" here refers to a process where all occupancy flags at the beginning and ending locations are set up properly for the new positions, the teleporting unit's laying-down flag is set as appropriate for if there's a standing creature at the destination, and the teleporting creature's position is set to the destination. Note that none of that accounts for babies, which I have no idea how the game keeps track of babies being held (some sort of general ref?)
babies are counted as riding the mothers, I believe.
0.42.06-alpha1 is up: https://github.com/DFHack/dfhack/releases/tag/0.42.06-alpha1
It contains some more fixes than the builds from yesterday, but the new stuff could also introduce problems that people didn't find earlier, so back things up, report problems, etc.
The issue is with gm-editor not being able to create strings, because its type selection dialog only searches for types of DF data (e.g. when given "viewscreen", it uses "df.viewscreen", but "df.string" isn't a valid type). It would be possible to have it fall back to primitive types (like string, as well as int32_t, bool, etc.), although those are a little trickier to validate.Would copy/paste be a simple work-around? That would be useful for transferring other data types to other vectors, or duplicating one with values close to the ones desired and then editing it.
How do I use reaction-product-trigger? I suspect it has something to do with my limited understanding of all programming languages that are not java, but I can't find anything on the arguments part of the file that indicates how to tell it which product to cause it to trigger.
modtools/reaction-product-trigger -reactionName MAKE_CLAY_JUG -command [ devel/print-args "worker id = " \\WORKER_ID ", input items = " \\INPUT_ITEMS ", output items = " \\OUTPUT_ITEMS ]
sorry for referring to 0.40.26 still but tele-dwarves kinda cause babies to be abandoned, random babies lying around most of the time. either they don't hunger/thirst ormy absolute laziness waiting for the right phase of game to "be normal" on one of my worldskeeping teledwarf on is having dwarves provide... but they're perfectly fine and even grow up.Considering the way teledwarf works (by checking every unit on every tick to see if they're pathing, then teleporting them to the path destination should there be one), that doesn't surprise me in the slightest. "Teleporting" here refers to a process where all occupancy flags at the beginning and ending locations are set up properly for the new positions, the teleporting unit's laying-down flag is set as appropriate for if there's a standing creature at the destination, and the teleporting creature's position is set to the destination. Note that none of that accounts for babies, which I have no idea how the game keeps track of babies being held (some sort of general ref?)babies are counted as riding the mothers, I believe.
Quoting for the benefit of a bug report - https://github.com/DFHack/dfhack/issues/835
oh yeah funny thing about carry mechanics you can technically teleport the rider to anyone's backs if you slap the mount flag on the unit and change the rider's mount relationship to that unit with the mount flag on.sorry for referring to 0.40.26 still but tele-dwarves kinda cause babies to be abandoned, random babies lying around most of the time. either they don't hunger/thirst ormy absolute laziness waiting for the right phase of game to "be normal" on one of my worldskeeping teledwarf on is having dwarves provide... but they're perfectly fine and even grow up.Considering the way teledwarf works (by checking every unit on every tick to see if they're pathing, then teleporting them to the path destination should there be one), that doesn't surprise me in the slightest. "Teleporting" here refers to a process where all occupancy flags at the beginning and ending locations are set up properly for the new positions, the teleporting unit's laying-down flag is set as appropriate for if there's a standing creature at the destination, and the teleporting creature's position is set to the destination. Note that none of that accounts for babies, which I have no idea how the game keeps track of babies being held (some sort of general ref?)babies are counted as riding the mothers, I believe.
Quoting for the benefit of a bug report - https://github.com/DFHack/dfhack/issues/835
If someone could upload a small save with a dwarf carrying a baby that would save developer time a bit fixing it.
./dfhack: line 66: 23167 Segmentation fault
(core dumped) setarch i386 -R env LD_PRELOAD="$PRELOAD_LIB" ./libs/Dwarf_Fortress "$@"
Every time I try so far, actually even if I try to do it for a historical figure direct OR for a specify new > historical figure, it crashes. Multiple saves too.-snip-Thanks for the answer. I guess I misunderstood it then. Is there any script that allows for multiple possible results? What I mean is: the reaction is run, with X% chance of effect A, and Y% of effect B.
-snip-Thanks for the answer. I guess I misunderstood it then. Is there any script that allows for multiple possible results? What I mean is: the reaction is run, with X% chance of effect A, and Y% of effect B.
modtools/random-trigger -outcomeListName myOutcomeList -weight 1 -command [ devel/print-args "outcome 1" ]
modtools/random-trigger -outcomeListName myOutcomeList -weight 2 -command [ devel/print-args "outcome 2" ]
modtools/reaction-trigger -reactionName MY_REACTION -command [ modtools/random-trigger -outcomeListName myOutcomeList -trigger -preserveList ]
[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
Dwarf_Fortress: xcb_io.c:179: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.
./df: line 6: 32410 Aborted
(core dumped) ./libs/Dwarf_Fortress "$@"
./dfhack: line 66: 899 Segmentation fault
(core dumped) setarch i386 -R env LD_PRELOAD="$PRELOAD_LIB" ./libs/Dwarf_Fortress "$@"
I think I understand. Thanks.-snip-Thanks for the answer. I guess I misunderstood it then. Is there any script that allows for multiple possible results? What I mean is: the reaction is run, with X% chance of effect A, and Y% of effect B.
If you want a "cumulative probability" where if there's a 10% chance it happens exactly every 10 times then you can use reaction-product-trigger using DF's built-in partial product system. If you want an independent probability each time, you can do something likeCode: [Select]modtools/random-trigger -outcomeListName myOutcomeList -weight 1 -command [ devel/print-args "outcome 1" ]
modtools/random-trigger -outcomeListName myOutcomeList -weight 2 -command [ devel/print-args "outcome 2" ]
modtools/reaction-trigger -reactionName MY_REACTION -command [ modtools/random-trigger -outcomeListName myOutcomeList -trigger -preserveList ]
Every time MY_REACTION completes, it will print "outcome 1" with probability 1/3 and "outcome 2" with probability 2/3, and it will never print both at once.
Yeah bind a hotkey to run "stocks show" and then you just have to type in b a r s and it lists all your different metal bars nicely.
Does not occur without dfhack.
To reproduce, create a pocket world (Default settings). Embark anywhere, doesn't matter. Build a mason's workshop ASAP, and then make a statue in the workshop. Choose details, and choose to change the image. Select 'historical figure'.
Game will crash with dfhack.
So apparently my crashes are related to the vanilla bug, but they aren't consistent across saves. All of the saves in the folder I'm playing were made fresh for 42.06 to use the new reactions. One of them works fine (http://i.imgur.com/zBNZDWU.png) with ./df or ./dfhack, but the others crash.
When I try ./df for the crashing ones I get this instead of the usual segfault message though:Code: [Select][xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
Dwarf_Fortress: xcb_io.c:179: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.
./df: line 6: 32410 Aborted
(core dumped) ./libs/Dwarf_Fortress "$@"
So... that's weird.
Edit: correction!
One of the saves which I can make figurines in with ./df does not work when I launch with ./dfhack:Code: [Select]./dfhack: line 66: 899 Segmentation fault
(core dumped) setarch i386 -R env LD_PRELOAD="$PRELOAD_LIB" ./libs/Dwarf_Fortress "$@"
I took this after launching with ./df:Spoiler (click to show/hide)
I get the above segfault when I try the same thing with ./dfhack.
DFHack saves stuff as historical figures, so that might be it.
...implement persistent data without using historical figures...Could a sqlite database file in the DF game save directory do the thing?
Is there a list of tools that insert fake historical figures? That might be useful for the pack maintainers to know so they can either turn them off by default or at least warn their users.DFHack saves stuff as historical figures, so that might be it.
That could definitely be it. We'll have to check whether they're being created properly.
On the bright side it's an excuse to implement persistent data without using historical figures, something I've been putting off.
local figs = df.global.world.history.figures
for i=0,#figs-1,1 do
local v = figs[i]
if v.id<0 then
print(v.id..' '..v.name.first_name..' '..v.name.language)
v.name.language = 0
end
end
and it stopped crashing on figurine-design historical figure choose screen:invalid (-1) language id causes segfault
I changed it to 0 with this script(it seems to be not unused for datastoring anyway):Code: [Select]local figs = df.global.world.history.figures
and it stopped crashing on figurine-design historical figure choose screen:
for i=0,#figs-1,1 do
local v = figs[i]
if v.id<0 then
print(v.id..' '..v.name.first_name..' '..v.name.language)
v.name.language = 0
end
endSpoiler (click to show/hide)
If you're an idiot who doesn't know how to work the lua interpreter like me, just throw those magic words into a text file, save it as filename.lua in \hack\scripts and then use the command "filename" in the console.
...implement persistent data without using historical figures...Could a sqlite database file in the DF game save directory do the thing?
I'd hazard a guess that autochop and autolabor use histfigs. :)Autochop/config Abbeybrew is real! And so is the Tooth Fairy, and the Great Pumpkin, and a Rational Economic Plan, and ...
--test_figs.lua
local figs = df.global.world.history.figures
for i=0,#figs-1,1 do
local v = figs[i]
if v.id<0 and v.name.language < 0 then
print(v.id..' '..v.name.first_name..' '..v.name.language)
end
end
New alpha release. (https://github.com/DFHack/dfhack/releases/tag/0.42.06-alpha2) This release fixes a few bugs with the old release.
Got a few more questions (my apologies if this is annoying to anyone here) about if there are scrips that enable me to do certain things. I suspect the answer to all might be no, but...
1) Is it possible to make, say, a flamethrower that consumes ammunition? (I know that item-trigger allows me to simulate the flamethrower, but no idea on the ammo)
2) Is it possible to make a custom siege weapon (without making it a workshop that gives material-emission interactions)?
3) Is there a way to assign gods created through moddable-gods to specific entities? (and do those gods even do any actions in worldgen?)
2. What do you want it to do?Just fire projectiles, I suppose.
and a tileset not found error.
[code]++ dirname dfhack
+ DF_DIR=.
+ cd .
+ export SDL_DISABLE_LOCK_KEYS=1
+ SDL_DISABLE_LOCK_KEYS=1
+ RC=.dfhackrc
+ '[' -r /home/hem39212/.dfhackrc ']'
+ '[' -r ./.dfhackrc ']'
+ libcxx_orig=libs/libstdc++.so.6
+ libcxx_backup=libs/libstdc++.so.6.backup
+ '[' -z '' ']'
+ '[' -e libs/libstdc++.so.6 ']'
+ '[' '!' -e libs/libstdc++.so.6.backup ']'
+ mv libs/libstdc++.so.6 libs/libstdc++.so.6.backup
+ cat
NOTICE: libs/libstdc++.so.6 has been moved to libs/libstdc++.so.6.backup
for better compatibility. If you are using an older distro and this breaks,
run "cp libs/libstdc++.so.6.backup libs/libstdc++.so.6", or add this to
/home/hem39212/.dfhackrc to affect future DFHack installations:
export DFHACK_NO_RENAME_LIBSTDCXX=1
++ stty -g
+ old_tty_settings=5500:5:bf:8a3b:3:1c:7f:15:4:0:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
+ DISTROFIXES=distro_fixes.sh
+ '[' -r distro_fixes.sh ']'
+ export LD_LIBRARY_PATH=:./hack/libs:./hack
+ LD_LIBRARY_PATH=:./hack/libs:./hack
+ PRELOAD_LIB=./hack/libdfhack.so
+ case "$1" in
+ setarch i386 -R env LD_PRELOAD=./hack/libdfhack.so ./libs/Dwarf_Fortress
+ ret=1
+ stty 5500:5:bf:8a3b:3:1c:7f:15:4:0:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
+ echo
+ '[' -n '' ']'
+ exit 1
++ dirname dfhack
+ DF_DIR=.
+ cd .
+ export SDL_DISABLE_LOCK_KEYS=1
+ SDL_DISABLE_LOCK_KEYS=1
+ RC=.dfhackrc
+ '[' -r /home/hem39212/.dfhackrc ']'
+ '[' -r ./.dfhackrc ']'
+ libcxx_orig=libs/libstdc++.so.6
+ libcxx_backup=libs/libstdc++.so.6.backup
+ '[' -z '' ']'
+ '[' -e libs/libstdc++.so.6 ']'
++ stty -g
+ old_tty_settings=5500:5:bf:8a3b:3:1c:7f:15:4:0:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
+ DISTROFIXES=distro_fixes.sh
+ '[' -r distro_fixes.sh ']'
+ export LD_LIBRARY_PATH=:./hack/libs:./hack
+ LD_LIBRARY_PATH=:./hack/libs:./hack
+ PRELOAD_LIB=./hack/libdfhack.so
+ case "$1" in
+ setarch i386 -R env LD_PRELOAD=./hack/libdfhack.so ./libs/Dwarf_Fortress
+ ret=1
+ stty 5500:5:bf:8a3b:3:1c:7f:15:4:0:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
+ echo
+ '[' -n '' ']'
+ exit 1
Now that dwarfs socialize as a job instead of going on break, can someone make the "Idlers" count useful in 42?
error in __gc metamethod (bad argument #1 to '?' (FILE* expected, got userdata))
table: 38614F00
table: 37BFE690
(invalid error: error in __gc metamethod (bad argument #1 to '?' (FILE* expected, got userdata)))
table: 37D8A890
table: 38616508
table: 383F5A20
table: 383F1510
The table lines continued for several pages in constant rapid stream before I quit the fort and they stopped.
Quick question: is it possible to change artifact names with DFHack? It looks like they're stored in a separate data structure (artifacts have a ref that gives an artifact ID) but I couldn't find anything in the docs about it.I really gotta update artifake and figure out what happened with names that makes it not wanna work sometimes. I did add in the specific -item flag for artifacts, real or fake, though.
EDIT: Whoop, I'm an idiot, sorry. Guess I should've searched the thread, first: df.artifact_record.find(artifact id) in the lua interface. If I could delete this post I would ;)
Just had an interesting spasm from DFHack. Version is the one from 42.06.01 Win LazyNewbPack. I was just setting up some flooring when I got the following in the DFHack window in red text: (pulled from stderr.log)Wow, that looks pretty serious. What DFHack tools have you been using (particularly any third-party ones)? Did you replace lua.dll or something? Is it reproducible?Code: [Select]error in __gc metamethod (bad argument #1 to '?' (FILE* expected, got userdata))
The table lines continued for several pages in constant rapid stream before I quit the fort and they stopped.
table: 38614F00
table: 37BFE690
(invalid error: error in __gc metamethod (bad argument #1 to '?' (FILE* expected, got userdata)))
table: 37D8A890
table: 38616508
table: 383F5A20
table: 383F1510
What about the difference between the need (when its purple) and just when they're idleing?Now that dwarfs socialize as a job instead of going on break, can someone make the "Idlers" count useful in 42?
That's doable.
What about the difference between the need (when its purple) and just when they're idleing?Now that dwarfs socialize as a job instead of going on break, can someone make the "Idlers" count useful in 42?
That's doable.
Does anyone know if you can put pretty pictures in the in-game gui, or is it limited to just text and simple shapes?Are you just talking about the simple shapes you can build with text or special characters? I'm not aware of anything else you can do, really.
Does anyone know if you can put pretty pictures in the in-game gui, or is it limited to just text and simple shapes?Are you just talking about the simple shapes you can build with text or special characters? I'm not aware of anything else you can do, really.
There is a way to draw more complicated stuff on the screen, like the Stonesense overlay does, but it's really complicated and varies depending on the print mode (I don't think anyone's managed to do it in OpenGL print modes yet, which a lot of people use).
Does anyone know if you can put pretty pictures in the in-game gui, or is it limited to just text and simple shapes?There are few ways to do it. Depends on what you want.
Putnam did something similar to that to create black-and-white buttons for a mod.
local function get_path_hither()
for path, script in pairs(dfhack.internal.scripts) do
if script.env.dfhack_flags == dfhack_flags then
return path
end
end
end
I think he means things like forgotten beasts.Yeah, that's what I meant. Assuming their raws are in world.raws, that would be a way of editing them in-game.
[CREATURE:FORGOTTEN_BEAST_1] [GENERATED] [FEATURE_BEAST] [ATTACK_TRIGGER:0:0:50000]7 [NAME:forgotten beast:forgotten beasts:forgotten beast]= [CASTE_NAME:forgotten beast:forgotten beasts:forgotten beast] [NO_GENDER] [CARNIVORE] [DIFFICULTY:10] [NATURAL_SKILL:WRESTLING:6] [NATURAL_SKILL:BITE:6] [NATURAL_SKILL:GRASP_STRIKE:6] [NATURAL_SKILL:STANCE_STRIKE:6] [NATURAL_SKILL:MELEE_COMBAT:6] [NATURAL_SKILL:DODGING:6]' [NATURAL_SKILL:SITUATIONAL_AWARENESS:6] [AMPHIBIOUS] [BIOME:SUBTERRANEAN_CHASM] [PETVALUE:2000] [GRASSTRAMPLE:20] [BUILDINGDESTROYER:2] [ALL_ACTIVE] [SWIMS_INNATE] [TRAPAVOID] [NOPAIN] [NOSTUN]
[NONAUSEA] [NOFEAR] [NOEXERT] [NO_DIZZINESS] [NO_FEVERS] [LARGE_PREDATOR] [SPHERE:CAVERNS] [SPHERE:DISEASE] [BODY_SIZE:0:0:10000000] [CREATURE_TILE:83]Á [BODY:RCP_CEPHALOTHORAX:RCP_ABDOMEN:RCP_FIRST_SIMPLE_LEGS:RCP_SECOND_SIMPLE_LEGS:RCP_THIRD_SIMPLE_LEGS:RCP_PINCERS:RCP_3_TAILS:RCP_1_EYE:RCP_HEART:RCP_GUTS:RCP_BRAIN:RCP_MOUTH:RCP_TAIL_STINGER]% [BODY_DETAIL_PLAN:STANDARD_MATERIALS] [REMOVE_MATERIAL:HAIR] [REMOVE_MATERIAL:SKIN]. [USE_MATERIAL_TEMPLATE:CHITIN:CHITIN_TEMPLATE]# [BODY_DETAIL_PLAN:STANDARD_TISSUES] [REMOVE_TISSUE:HAIR] [REMOVE_TISSUE:SKIN], [USE_TISSUE_TEMPLATE:CHITIN:CHITIN_TEMPLATE]> [BODY_DETAIL_PLAN:EXOSKELETON_TISSUE_LAYERS:CHITIN:FAT:MUSCLE]* [BODY_DETAIL_PLAN:STANDARD_HEAD_POSITIONS]* [BODY_DETAIL_PLAN:HUMANOID_HEAD_POSITIONS]$ [BODY_DETAIL_PLAN:HUMANOID_RELSIZES], [USE_MATERIAL_TEMPLATE:SINEW:SINEW_TEMPLATE]& [TENDONS:LOCAL_CREATURE_MAT:SINEW:200]( [LIGAMENTS:LOCAL_CREATURE_MAT:SINEW:200] [HAS_NERVES] [HOMEOTHERM:10040] [SELECT_MATERIAL:CHITIN]# [STATE_COLOR:ALL_SOLID:BURNT_UMBER]
[COLOR:6:0:0]- [SELECT_TISSUE_LAYER:HEART:BY_CATEGORY:HEART], [PLUS_TISSUE_LAYER:SCALE:BY_CATEGORY:THROAT] [TL_MAJOR_ARTERIES], [USE_MATERIAL_TEMPLATE:ICHOR:ICHOR_TEMPLATE]' [BLOOD:LOCAL_CREATURE_MAT:ICHOR:LIQUID] [CREATURE_CLASS:GENERAL_POISON]8 [USE_MATERIAL_TEMPLATE:POISON:CREATURE_EXTRACT_TEMPLATE] [ENTERS_BLOOD]
[SYNDROME] [SYN_NAME:beast sickness]# [SYN_AFFECTED_CLASS:GENERAL_POISON]+ [SYN_IMMUNE_CREATURE:FORGOTTEN_BEAST_1:ALL] [SYN_INJECTED]
[SYN_CONTACT]
[SYN_INHALED] [SYN_INGESTED]N [CE_PAIN:SEV:100:PROB:100:START:782:PEAK:1962:END:3858:LOCALIZED:SIZE_DILUTES]g [CE_IMPAIR_FUNCTION:SEV:100:PROB:100:START:551:PEAK:972:END:3508:BP:BY_CATEGORY:ALL:BRAIN:SIZE_DILUTES]+ [ATTACK:PINCER:BODYPART:BY_CATEGORY:PINCER] [ATTACK_SKILL:GRASP_STRIKE] [ATTACK_VERB:snatch:snatches] [ATTACK_CONTACT_PERC:100] [ATTACK_PENETRATION_PERC:100] [ATTACK_PREPARE_AND_RECOVER:2:2] [ATTACK_FLAG_EDGE] [ATTACK_PRIORITY:MAIN] [ATTACK_FLAG_CANLATCH] [ATTACK_FLAG_WITH]% [ATTACK:KICK:BODYPART:BY_TYPE:STANCE] [ATTACK_SKILL:STANCE_STRIKE] [ATTACK_VERB:kick:kicks] [ATTACK_CONTACT_PERC:100] [ATTACK_PREPARE_AND_RECOVER:2:2] [ATTACK_FLAG_WITH] [ATTACK_PRIORITY:MAIN] [ATTACK_FLAG_BAD_MULTIATTACK]+ [ATTACK:STING:BODYPART:BY_CATEGORY:STINGER] [ATTACK_SKILL:STANCE_STRIKE] [ATTACK_VERB:sting:stings] [ATTACK_CONTACT_PERC:5] [ATTACK_PENETRATION_PERC:100] [ATTACK_PREPARE_AND_RECOVER:2:2] [ATTACK_FLAG_EDGE] [ATTACK_PRIORITY:MAIN]G [SPECIALATTACK_INJECT_EXTRACT:LOCAL_CREATURE_MAT:POISON:LIQUID:100:100]( [ATTACK:BITE:BODYPART:BY_CATEGORY:MOUTH] [ATTACK_SKILL:BITE] [ATTACK_VERB:bite:bites] [ATTACK_CONTACT_PERC:100] [ATTACK_PREPARE_AND_RECOVER:2:2] [ATTACK_PRIORITY:MAIN] [ATTACK_FLAG_CANLATCH]] [GAIT:SWIM:Maximum Swim Speed:725:10:3:2175:50:LAYERS_SLOW:STRENGTH:AGILITY:STEALTH_SLOWS:50]V [GAIT:SWIM:Faster Swim:1450:5:3:2175:10:LAYERS_SLOW:STRENGTH:AGILITY:STEALTH_SLOWS:20]V [GAIT:SWIM:Fast Swim:2175:NO_BUILD_UP:5:LAYERS_SLOW:STRENGTH:AGILITY:STEALTH_SLOWS:10]# [GAIT:SWIM:Swim:2900:NO_BUILD_UP:0]( [GAIT:SWIM:Slow Swim:3900:NO_BUILD_UP:0], [GAIT:SWIM:Creeping Swim:5900:NO_BUILD_UP:0]V [GAIT:WALK:Fastest Walk:225:10:3:675:50:LAYERS_SLOW:STRENGTH:AGILITY:STEALTH_SLOWS:50]T [GAIT:WALK:Faster Walk:450:5:3:675:10:LAYERS_SLOW:STRENGTH:AGILITY:STEALTH_SLOWS:20]U [GAIT:WALK:Fast Walk:675:NO_BUILD_UP:5:LAYERS_SLOW:STRENGTH:AGILITY:STEALTH_SLOWS:10]" [GAIT:WALK:Walk:900:NO_BUILD_UP:0]( [GAIT:WALK:Slow Walk:1900:NO_BUILD_UP:0]+ [GAIT:WALK:Slowest Walk:2900:NO_BUILD_UP:0]S [GAIT:CRAWL:Scramble:225:10:3:675:50:LAYERS_SLOW:STRENGTH:AGILITY:STEALTH_SLOWS:50]V [GAIT:CRAWL:Faster Crawl:450:5:3:675:10:LAYERS_SLOW:STRENGTH:AGILITY:STEALTH_SLOWS:20]W [GAIT:CRAWL:Fast Crawl:675:NO_BUILD_UP:5:LAYERS_SLOW:STRENGTH:AGILITY:STEALTH_SLOWS:10]$ [GAIT:CRAWL:Crawl:900:NO_BUILD_UP:0]* [GAIT:CRAWL:Slow Crawl:1900:NO_BUILD_UP:0]% [GAIT:CRAWL:Creep:2900:NO_BUILD_UP:0]S [GAIT:CLIMB:Scramble:225:10:3:675:50:LAYERS_SLOW:STRENGTH:AGILITY:STEALTH_SLOWS:50]V [GAIT:CLIMB:Faster Climb:450:5:3:675:10:LAYERS_SLOW:STRENGTH:AGILITY:STEALTH_SLOWS:20]W [GAIT:CLIMB:Fast Climb:675:NO_BUILD_UP:5:LAYERS_SLOW:STRENGTH:AGILITY:STEALTH_SLOWS:10]$ [GAIT:CLIMB:Climb:900:NO_BUILD_UP:0]* [GAIT:CLIMB:Slow Climb:1900:NO_BUILD_UP:0]% [GAIT:CLIMB:Creep:2900:NO_BUILD_UP:0]ž [DESCRIPTION:A great one-eyed scorpion. It has three short tails and it is slavering. Its burnt umber exoskeleton is leathery. Beware its poisonous sting!]
[lua]# m=df.inorganic_raw.find(300).material
[lua]# ~m.state_name
<string[]: 0x177ce2e8>
Solid = frozen fetid filth
Liquid = fetid filth
Gas = boiling fetid filth
Powder = frozen fetid filth
Paste = frozen fetid filth
Pressed = frozen fetid filth
[lua]# ~m.heat
<material_common.T_heat: 0x177ce2b4>
spec_heat = 4181
heatdam_point = 60001
colddam_point = 60001
ignite_point = 60001
melting_point = 60001
boiling_point = 60001
mat_fixed_temp = 10000
It seems this material has no melting or boiling points, so how does DF know which state_name to use?
It seems this material has no melting or boiling points, so how does DF know which state_name to use?
It has fixed temperature, so.. um.. temperature/state is always the same.Clearly. But which state is it always in?
It has fixed temperature, so.. um.. temperature/state is always the same.Clearly. But which state is it always in?
I know that this example is an evil rain and will always be a liquid, but I want a script to determine this automatically for any material.
How can I find the phase of a generated material at a given temperature? Here is what I have tried:How did you get that information?
-snop-
It seems this material has no melting or boiling points, so how does DF know which state_name to use?
I assume 60001 corresponds to no melting/boiling point.Code: [Select][lua]# m=df.inorganic_raw.find(300).material
[lua]# ~m.state_name
<string[]: 0x177ce2e8>
Solid = frozen fetid filth
Liquid = fetid filth
Gas = boiling fetid filth
Powder = frozen fetid filth
Paste = frozen fetid filth
Pressed = frozen fetid filth
[lua]# ~m.heat
<material_common.T_heat: 0x177ce2b4>
spec_heat = 4181
heatdam_point = 60001
colddam_point = 60001
ignite_point = 60001
melting_point = 60001
boiling_point = 60001
mat_fixed_temp = 10000
I assume 60001 corresponds to no melting/boiling point.That is what it means, according to the wiki (http://dwarffortresswiki.org/index.php/DF2014:Temperature#Temperature_scale).
Could some kind soul perhaps add a feature to prioritize the designations made from digv and friends (digvx, digl etc)? Currently, when I designate some digging with priority 1 and have a designation made from digv (which doesn't seem to have a priority), the miners randomly change between them (which is kinda annoying).
I looked at the github issue tracker, but decided it was better to post it here instead. Last update was november 2015 which is a while ago...Could some kind soul perhaps add a feature to prioritize the designations made from digv and friends (digvx, digl etc)? Currently, when I designate some digging with priority 1 and have a designation made from digv (which doesn't seem to have a priority), the miners randomly change between them (which is kinda annoying).
Known issue, which certainly deserves some attention: https://github.com/DFHack/dfhack/issues/481
(maybe feature requests should move off the issue tracker? they tend to hang around forever and hide the actual bugs)
It's not as straightforward as it might seem. Digging priority is saved differently from the rest of data. You would need to manage that. It's not very hard but a bit annoying.I looked at the github issue tracker, but decided it was better to post it here instead. Last update was november 2015 which is a while ago...Could some kind soul perhaps add a feature to prioritize the designations made from digv and friends (digvx, digl etc)? Currently, when I designate some digging with priority 1 and have a designation made from digv (which doesn't seem to have a priority), the miners randomly change between them (which is kinda annoying).
Known issue, which certainly deserves some attention: https://github.com/DFHack/dfhack/issues/481
(maybe feature requests should move off the issue tracker? they tend to hang around forever and hide the actual bugs)
I'm no expert on stuff like this, but... Wouldn't it be relatively straightforward to implement the feature so one could do digv 2 to dig with a priority of 2.
Just decided to try the newest version of DF (I last played 40.24), and I installed DF Hack, extracted into my df 42.06 folder, and now when I run DF, it says it's not a known release, then DF crashes (which it does not do without DF Hack).What DFHack version are you using? (Regardless of that, DF shouldn't crash if DFHack disables itself, although that seems to happen on Windows for some reason.)
What DFHack version are you using? (Regardless of that, DF shouldn't crash if DFHack disables itself, although that seems to happen on Windows for some reason.)
I get a message saying that DFhack cannot recognize my version of DF. DF then promptly crashes. What's up? I'm using the latest release.Please specify exactly which DFHack release you're using. If it's 0.40.24-r5, that's not the latest release. There are alpha releases for 0.42.06 on Github: https://github.com/DFHack/dfhack/releases/
I'm working on another release in a few weeks that will probably be a "real" release. Hopefully I'll beat Toady to it or it'll be a bit later.
I get a pretty constant crash when placing furniture(doors, beds, armor stands). I can never reproduce it intentionally, but I save now before building every time because it happens enough.Same annoying bug. Really bothers because of randomness: you can build a lot of stuff and suddenly - crash, start over.
What is it about TwbT that makes it so crash-prone that it seems to be the default answer to any crash, anyway?
Are you sure that that's related to DFHack and is not related to TwbT?Not really. Bug is pure random, so I can't say for sure if it will repeat with TWBT turned off and dfhack turned on.
TwbT is not distributed with the alpha.I'll try to test more.
What extra things in particular? buildingplan? automaterial? You could try running "disable buildingplan" or "disable automaterial" to test and see if either of those fix the issue.
choices=df.new(df.viewscreen_layer_choose_language_namest) ; choices.subscreen = 3 ;
Now it spits out:/home/thefunk/.df/hack/scripts/names.lua:43: Cannot write field viewscreen_layer_choose_language_namest.subscreen: not found.
what are you using to extract the archives?7zip.
I suppose it would be possible to recreate the symlinks in the startup script on Linux and OS X, if it's absolutely necessary.
I don't know if there's ever been a subscreen field in viewscreen_layer_choose_language_namest. There was one in viewscreen_setupadventurest, but it was replaced.Hmmm, I've poked around more in the structures and with gm-editor to explore it but I'm still stumped, what would be the equivalent to the old subscreen[3]? It isn't the pages as far as I can tell, since the names field is opened up off of the background page.
What is that supposed to do?
Also, df.viewscreen_layer_choose_language_namest:new() is a shorter alternative to df.new(df.viewscreen_layer_choose_language_namest).
Stonesense screenshots are saved to your DF folder, called "screenshot1.png" (2, 3, 4...).
Make sure you read the feedback in the DFHack prompt, as sometimes you'll need to zoom out and try again.
I tested a bit on two different computers (different LNP installs, different saves). The bug indeed appears only with TWBT turned on, and without TWBT (print mode:2D) all seems to work fine.Are you sure that that's related to DFHack and is not related to TwbT?Not really. Bug is pure random, so I can't say for sure if it will repeat with TWBT turned off and dfhack turned on.TwbT is not distributed with the alpha.I'll try to test more.
What extra things in particular? buildingplan? automaterial? You could try running "disable buildingplan" or "disable automaterial" to test and see if either of those fix the issue.
Here's a beta release: https://github.com/DFHack/dfhack/releases/tag/0.42.06-beta1The devs' efforts are much appreciated!
r1 will probably happen soon unless there's a nasty issue with that that warrants another beta release.
What's the status of support for new 0.42 features/screens in DFHack? Need to make Remote work with .42 but not much point if the actual new stuff won't be accessible.I think everything is just about accessible and even named right.
I went and grabbed the latest dfhack version hoping I'd be able to mark items for trading from the extended stocks screen. It is greyed out and still is in the beta. I really miss that feature. Is it working for anyone else?
Heyyy, you wouldn't happen to know what changed from the df.viewscreen_setupadventurerst.subscreen[3] trick that broke pulling up the name selection screen with the new pages layout would you?
Crash at save in 0.42.06-alpha2. I've just seen that you've released an update, but this might still be helpful.Well, I have no idea what the issue is there. Has it happened more than once? Do you have anything in onUnloadWorld.init-related files? Have you added stuff to onLoadWorld.init, etc.?
Here is the crash log:Spoiler (click to show/hide)
I remember changing the trade option, so maybe it's being disabled incorrectly. I'll take a look.
Was that the entire error message? There might be more details in stderr.log.
Given that it works for me, there could be something weird going on with that caravan, so it would be helpful to have that save.
Crash at save in 0.42.06-alpha2. I've just seen that you've released an update, but this might still be helpful.Well, I have no idea what the issue is there. Has it happened more than once? Do you have anything in onUnloadWorld.init-related files? Have you added stuff to onLoadWorld.init, etc.?
Here is the crash log:Spoiler (click to show/hide)
Hey man, I appreciate the effort, wasn't sure if it was just me not being able to work it out or what. It's confusing because the structures lists the page and such but I can't figure out how to point a script at it the same way as the old subscreen[3] method did.Heyyy, you wouldn't happen to know what changed from the df.viewscreen_setupadventurerst.subscreen[3] trick that broke pulling up the name selection screen with the new pages layout would you?
I tried but couldn't get it to work so far, sorry.
Alright, familiarized myself a little bit with DFHack and did few tests with it.Save this as elevate_attributes.lua:
Point is, I need 'elevate-physical' and 'elevate-mental' plus 'make-legendary' scripts to buff it all up to the very max of 5000 and not 4000 or 2000 something. :-\
EDIT: Erhm.. re-checked the skill max limit and yeah, I just need the very max abilities is all and I suck even more with coding than making/adding reactions and custom creatures in DF.
-- This script will elevate all the attributes of a unit
-- by vjek
--[[=begin
elevate_attributes portion stolen from armoks_blessing
================
=end]]
local utils=require('utils')
local args = utils.processArgs({...}, validArgs)
local unit = args.unit and df.unit.find(args.unit) or dfhack.gui.getSelectedUnit(true)
function elevate_attributes(unit)
if unit==nil then
print ("No unit available! Aborting with extreme prejudice.")
return
end
local ok,f,t,k = pcall(pairs,unit.status.current_soul.mental_attrs)
if ok then
for k,v in f,t,k do
v.value=10000
v.max_value=20000
end
end
local ok,f,t,k = pcall(pairs,unit.body.physical_attrs)
if ok then
for k,v in f,t,k do
v.value=10000
v.max_value=20000
end
end
end
elevate_attributes(unit)
You can change the caps to whatever you want, 5000 is not hard cap, only a "natural from the raws" cap.
Save this as elevate_attributes.lua:You can change the caps to whatever you want, 5000 is not hard cap, only a "natural from the raws" cap.Spoiler (click to show/hide)
Yar, I mostly pulled the bits from armoks_blessing out like that so you could see how it is put together and play with it.
Apparently the Windows build has the wrong version number again. I'm putting up a fixed build now, but the old one will be unavailable for a few minutes.
Edit: Okay, the Windows build should be fixed. I recommend replacing your copy of DFHack 0.42.06-beta1 if you've downloaded it already on Windows.
Here's a beta release: https://github.com/DFHack/dfhack/releases/tag/0.42.06-beta1
r1 will probably happen soon unless there's a nasty issue with that that warrants another beta release.
Here's a beta release: https://github.com/DFHack/dfhack/releases/tag/0.42.06-beta1
r1 will probably happen soon unless there's a nasty issue with that that warrants another beta release.
(The latest one is always at the top of https://github.com/DFHack/dfhack/releases)
I think prospect causes a crash. Latest version (v.0.42.06, latest dfhack version) and all that. Didn't in 42.05.Does it crash when you're running it (i.e.before the DFHack prompt shows up again)? If not, it's highly unlikely, since prospect just reads map data briefly.
EDIT: can't open "gui/gm-editor df.global.history.figures" as I'm met with error about something to do with expressions everytime.Try df.global.world.history.figures.
[string "expression"]:1: Cannot read field global.history: not found.
If you're on an older version of Windows, you won't be able to select text normally, but there should be an option for it if you right-click the title bar. It should also be logged to stderr.log, although it may be slightly delayed.Latest version (v.0.42.06, latest dfhack version) and all that.It's probably not relevant in this case, but please, please, specify the exact DFHack version you're using. It's displayed in the upper-left corner of the title screen and logged to the DFHack console when the game starts. I know you think you're using the latest DFHack version (which is currently 0.42.06-beta1, released 3 days ago), but people sometimes don't notice releases, especially pre-releases, so it's impossible for us to know for sure if that's what you're using.
df.global.world.history.figures[1]
histfig_links I think and it should have entries for worships_deityst
There's not a histfig_hf_link_deityst entry?
Ok, can you pray to anyone when starting a conversation? That's actually the shortcut to becoming a god I used, flip the deity flag under your df.global.history.figures entry then talk to someone and you can get them to worship you, editing your conversation targets via df.global.ui_adv_mode.conversation.targets to make the histfig_id your own lets you address yourself as a deity.
df.global.gps.screenx df.global.gps.screenyThanks, I'll check out that script when I get a chance.
middle tile is average of df.global.window_(var) and df.global.gps.screen(var)
see this script i wrote for positional sound in soundsense (http://www.bay12forums.com/smf/index.php?topic=60287.msg6214010#msg6214010)
No no, in your df.global.world.history.figures[your adventurer] there is a flags entry which has deity under it, and if you worshipped a deity you would find it under the histfig_links as a histfig_hf_link_deityst entry... unless maybe it's a force or something, I never checked.There's not a histfig_hf_link_deityst entry?
Ok, can you pray to anyone when starting a conversation? That's actually the shortcut to becoming a god I used, flip the deity flag under your df.global.history.figures entry then talk to someone and you can get them to worship you, editing your conversation targets via df.global.ui_adv_mode.conversation.targets to make the histfig_id your own lets you address yourself as a deity.
Uhh, I can't find the deity flag to tag in my adventurer's menu and haven't even found histfig_hf_link_deityst anywhere.
No no, in your df.global.world.history.figures[your adventurer] there is a flags entry which has deity under it, and if you worshipped a deity you would find it under the histfig_links as a histfig_hf_link_deityst entry... unless maybe it's a force or something, I never checked.
df.global.gps.screenx df.global.gps.screenyThanks, I'll check out that script when I get a chance.
middle tile is average of df.global.window_(var) and df.global.gps.screen(var)
see this script i wrote for positional sound in soundsense (http://www.bay12forums.com/smf/index.php?topic=60287.msg6214010#msg6214010)
I'm getting zero for df.global.gps.screeny, but since df.global.gps.dimy seems to be the window height in tiles, I might be able to use that instead. The real problem is that none of these values seem to update when I tab the map into a wider setting.
printall(require('gui.dwarfmode').getPanelLayout())
or
dwarfmode = require('gui.dwarfmode')
printall(dwarfmode.getPanelLayout())
or
dm = require('gui.dwarfmode')
printall(dm.getPanelLayout())
etc.
Hey, I have the latest version of DF-
Latest version (v.0.42.06, latest dfhack version) and all that.It's probably not relevant in this case, but please, please, specify the exact DFHack version you're using. It's displayed in the upper-left corner of the title screen and logged to the DFHack console when the game starts. I know you think you're using the latest DFHack version (which is currently 0.42.06-beta1, released 3 days ago), but people sometimes don't notice releases, especially pre-releases, so it's impossible for us to know for sure if that's what you're using.
QuoteWas that the entire error message? There might be more details in stderr.log.
Given that it works for me, there could be something weird going on with that caravan, so it would be helpful to have that save.
No, now I'm just confusing you:
The plugin from the dfhack build loads fine, the error message I was referring to was me building the stable dfhack and copying the new stock plugin dll i built to dfhack's beta1 version. I didn't realize I was building the stable dfhack.
I can't mark items to trade for any caravan that shows up (in the extended stocks UI, can do it from the trade depot), I can upload a save.
Here is the save:
http://dffd.bay12games.com/file.php?id=11948
What's the best way to submit suggestions for structure names?Fork it, make the change, submit a pull request.
The df.global.world.interaction_instances structure is definitely what associates a region interaction (evil weather) with a region.
The anon_1 variable is the index of the interaction in df.global.world.raws.interactions.
The anon_3 variable is the index of the region in df.global.world.world_data.region.
What's the best way to submit suggestions for structure names?Fork it, make the change, submit a pull request.
The df.global.world.interaction_instances structure is definitely what associates a region interaction (evil weather) with a region.
The anon_1 variable is the index of the interaction in df.global.world.raws.interactions.
The anon_3 variable is the index of the region in df.global.world.world_data.region.
Thanks! Done!What's the best way to submit suggestions for structure names?...Fork it, make the change, submit a pull request.
Specifically, this: https://github.com/DFHack/df-structures
Oh geez that's a lot of stuff. I will look into it. If you can find the full error output that would help. It might be in stderr.log, I forget.I modified my copy of item-trigger to fix this error (which has actually been around for ages) a while ago; if I remember correctly, the issue was caused by the script's inability to handle the hardcoded item types, and had a pretty simple solution. However, I never got around to sharing it, primarily because I haven't yet figured out how to use github. Could someone give me a solid explanation regarding how to contribute to dfhack, beyond the simple explanation of "fork, modify, submit pull request"?
Oh geez that's a lot of stuff. I will look into it. If you can find the full error output that would help. It might be in stderr.log, I forget.I modified my copy of item-trigger to fix this error (which has actually been around for ages) a while ago; if I remember correctly, the issue was caused by the script's inability to handle the hardcoded item types, and had a pretty simple solution. However, I never got around to sharing it, primarily because I haven't yet figured out how to use github. Could someone give me a solid explanation regarding how to contribute to dfhack, beyond the simple explanation of "fork, modify, submit pull request"?
Oh geez that's a lot of stuff. I will look into it. If you can find the full error output that would help. It might be in stderr.log, I forget.Sorry that this took a while, but this is the error output. I also cannot seem to make certain reaction-trigger stuff work, though for some reason it didn't appear in the output.
I'm not a developer, just a user. I was just wondering if the latest version of DFHack will eventually be upgraded to full release with the original thread changed. I apologize if this has been asked already, and yes I've seen the pre-release versions that work for the latest version of DF. I'm just curious if they'll ever stop being pre-release versions.Of course they will - the point of prereleases is to make testing easier before making a more stable release. I'm hoping to do a stable release in a few days, but I'll have to see when I have time for it. (I also don't have the ability to edit this forum post, when that happens, so it could be delayed a bit.)
I'm not a developer, just a user. I was just wondering if the latest version of DFHack will eventually be upgraded to full release with the original thread changed. I apologize if this has been asked already, and yes I've seen the pre-release versions that work for the latest version of DF. I'm just curious if they'll ever stop being pre-release versions.If you're sufficiently warned, select the text in pre-release-warning.lua and delete it then save the blank file. It won't break the stuff that looks for it that way.
I also cannot seem to make certain reaction-trigger stuff work, though for some reason it didn't appear in the output.Spoiler: the reaction error as well as relevant stuff (click to show/hide)
Well, nevermind it all. I managed to find a way around that.I also cannot seem to make certain reaction-trigger stuff work, though for some reason it didn't appear in the output.Spoiler: the reaction error as well as relevant stuff (click to show/hide)
I think I managed to find what's wrong, but don't have the knowledge to fix it so I must, again, ask for help here. I am pretty sure that random-trigger cannot read \\WORKER_ID from the instance reaction-trigger that is calling it and, as such, fails. Is there any way for the random events of random-trigger affect whatever unit is running the reaction?
A few questions:
1. If moods are turned to off, can I still trigger strange moods with the dfhack strangemood command?
2. Is it possible to assign burrows with dfhack? For example, if I wanted to create a civilization that automatically made burrows around certain buildings?
3. Has interaction-trigger been updated to include self targeting interactions like would be found with [USAGE_HINT:FLEEING]?
4. If I have a syndrome that transforms a unit (or transform a unit via the script) and they drop their items, will item-trigger trigger?
5. Can addReactionToShop be used to add reactions to custom buildings? And can default reactions (like butcher animal or melt item) be added to different buildings?
6. Does addReactionToShop need to be run each time you load a save?
PS: I think the description here (https://dfhack.readthedocs.org/en/stable/docs/_auto/base.html#hfs-pit) for hfs_pit command has a type. When describing the examples they both say that they have stairs but no walls, I believe one should say walls but no stairs.
You could just select the dead unit in the units list (under the dead/missing tab) and run full-heal without arguments.
If you want the unit ID, there are several ways to get that, including:
- Run ":lua ~dfhack.gui.getSelectedUnit().id" with the unit selected (or ":lua !dfhack.gui.getSelectedUnit().id", or ":lua print(dfhack.gui.getSelectedUnit().id)", etc.). This won't work for dead units unless you select them in the list, which is kind of pointless since full-heal works from that list too.
- Run "gui/gm-editor unit" with the unit selected and look for the "id" field.
If you know the unit's ID, you just punch in the unit's ID.
-unit ID
function getxyz() -- this will return pointers x,y and z coordinates.
local x=df.global.cursor.x
local y=df.global.cursor.y
local z=df.global.cursor.z
return x,y,z -- return the coords
end
function getCreatureAtPos(x,y,z) -- gets the creature index @ x,y,z coord
--local x,y,z=getxyz() --get 'X' coords
local vector=df.global.world.units.all -- load all creatures
for i = 0, #vector-1 do -- look into all creatures offsets
local curpos=vector[i].pos --get its coordinates
local cx=curpos.x
local cy=curpos.y
local cz=curpos.z
if cx==x and cy==y and cz==z then --compare them
return vector[i] --return index
end
end
--print("Creature not found!")
return nil
end
--heal unit from all wounds and damage
function healunit(unit)
if unit==nil then
unit=getCreatureAtPos(getxyz())
end
if unit==nil then
error("Failed to Heal unit. Unit not selected/valid")
end
for i=#unit.body.wounds-1,0,-1 do
unit.body.wounds[i]:delete()
end
unit.body.wounds:resize(0)
unit.body.blood_count=unit.body.blood_max
--set flags for standing and grasping...
unit.status2.limbs_stand_max=4
unit.status2.limbs_stand_count=4
unit.status2.limbs_grasp_max=4
unit.status2.limbs_grasp_count=4
--should also set temperatures, and flags for breath etc...
unit.flags1.dead=false
unit.flags2.calculated_bodyparts=false
unit.flags2.calculated_nerves=false
unit.flags2.circulatory_spray=false
unit.flags2.vision_good=true
unit.flags2.vision_damaged=false
unit.flags2.vision_missing=false
unit.counters.winded=0
unit.counters.unconscious=0
for k,v in pairs(unit.body.components) do
for kk,vv in pairs(v) do
if k == 'body_part_status' or k=='layer_status' then v[kk].whole = 0 else v[kk] = 0 end
end
end
end
Like I said, you can select it in the Dead/Missing tab of the units list (unless it's been cleared somehow).You could just select the dead unit in the units list (under the dead/missing tab) and run full-heal without arguments.
If you want the unit ID, there are several ways to get that, including:
- Run ":lua ~dfhack.gui.getSelectedUnit().id" with the unit selected (or ":lua !dfhack.gui.getSelectedUnit().id", or ":lua print(dfhack.gui.getSelectedUnit().id)", etc.). This won't work for dead units unless you select them in the list, which is kind of pointless since full-heal works from that list too.
- Run "gui/gm-editor unit" with the unit selected and look for the "id" field.
Thanks but I still don't understand how am I supposed to select a dead unit.
Are you making sure to include the -r argument?This only works for some commands. Most commands that are part of plugins use "help command-name" instead, and some also recognize "command-name help", but not "command-name -help".
You can use -help to get argument help. If that doesn't work for any command, make an issue of it.
<enum-attr name='caption'/>
<enum-attr name='shape' type-name='tiletype_shape' default-value='NONE'/>
<enum-attr name='material' type-name='tiletype_material' default-value='NONE'/>
<enum-attr name='variant' type-name='tiletype_variant' default-value='NONE'/>
<enum-attr name='special' type-name='tiletype_special' default-value='NONE'/>
<enum-attr name='direction' default-value='--------'/>
I think the problem with multi-story buildings is that most buildings need to be completely supported by floors.True. Also, floors can't be supported by buildings, so creating floors on demand wouldn't work (unless we could create a wall for support, but it would have to extend outside of the building). It's possible that the building-hacks plugin could help with this, but I don't remember everything it's capable of.
Like I said, you can select it in the Dead/Missing tab of the units list (unless it's been cleared somehow).
What's the stability of the 0.42.06 version like? I've been getting a few crashes and wondering if the beta DFhack version's behind it.Hopefully not. Some crashes in 0.42 have been attributed to TwbT, so try disabling that first and see if it helps. Otherwise, it would help if you could test without DFHack entirely and see if it's reproducible.
Here's r1! https://github.com/DFHack/dfhack/releases/tag/0.42.06-r1A big thank you to everyone on the team! A weapon trap with masterwork silver serrated discs and mechanisms for each of your rooms :)
Thanks to everyone who helped test the pre-releases and reported back.
Here's r1! https://github.com/DFHack/dfhack/releases/tag/0.42.06-r1
Thanks to everyone who helped test the pre-releases and reported back.
A big thank you to everyone on the team! A weapon trap with masterwork silver serrated discs and mechanisms for each of your rooms :)
Ooh, impressive (I normally just use regular mechanisms because I have extra stone lying around and my mechanics don't know what they're doing).Here's r1! https://github.com/DFHack/dfhack/releases/tag/0.42.06-r1A big thank you to everyone on the team! A weapon trap with masterwork silver serrated discs and mechanisms for each of your rooms :)
Thanks to everyone who helped test the pre-releases and reported back.
Here's r1! https://github.com/DFHack/dfhack/releases/tag/0.42.06-r1Thanks for your team effort! :)
Thanks to everyone who helped test the pre-releases and reported back.
<quite good analysis of lua sockets status>One point missed though. We have almost working lua socket replacement that uses csockets(our socket lib) and is mostly compatible. However I lacked the necessary experience at that time to get it as bug free as possible.
1. An Expedition system. <...>
1. An Expedition system. <...>
Yes that would be fun. I think i'll make a widget that allows to see the world map in biggest scale (as i think df generates small scale details on the fly so it's quite hard to make small scale maps). From there on you need there is the small part of "causing changes to the world". This would probably require huge amount of code (e.g. adding historic events by hand, figuring out the details for various historical things, etc...)
I'm not sure how DF handles the map generation, I was poking around in df.global.world.world_data but wasn't really able to piece anything coherent together. Several of the tables have values that aren't present when looking at them, but can still be accessed (e.g. ~df.global.world.world_data.region_areas will only print value as an output but numbers work as well) unfortunately some of those that I tried to access caused crashes, so that slowed things down. Luckily you really don't need small details for an expedition system, you would mainly just want if there are any features (caves, fortresses, hfs, etc...) and the general animal population. More specific information, like if a cave has an artifact or megabeast in it, will be stored in the site/feature information and that is pretty easy to access.
Interesting, I will give that a look.
I've currently had an irc chat with ragundo just about this last 6 month work in this theme. You can see it here: his pull request (https://github.com/DFHack/dfhack/pull/903) so he could be an expert in that regard.
Hopefully not. Some crashes in 0.42 have been attributed to TwbT, so try disabling that first and see if it helps. Otherwise, it would help if you could test without DFHack entirely and see if it's reproducible.
As far as I can tell, none of the plugins or scripts or the Lua API directly allow moving items from units' or buildings' inventories to the ground.
dfhack.items.moveToGround(item,pos)
One point missed though. We have almost working lua socket replacement that uses csockets(our socket lib) and is mostly compatible. However I lacked the necessary experience at that time to get it as bug free as possible.Plain ridiculous, that you try to justify one half backed intellectual creation, that had not worked as you originally intended for years, attacking the people that states the same fact that you just recognize. You are better than that! Or should aspire to be at least... If you do not have the willpower, the competence or the time to finish one project, please free yourself recognizing it!
Oh and generally: you can spam the #dfhack channel in freenode irc and/or open issues on everything. Currently we are not (yet) that big that the issue count would be (pardon the pun) an issue :) Just try searching before posting.If you really think, that anyone in this forum needs or ask your authorization or consent, to freely express his own opinions or state facts as they are perceived, you should pardon yourself for the image that you are giving of your personality. You are being acquiescent and childish there, and you know it. If you act like a scoundrel with other people there are few chances that they could respect you, or even that you should be able to respect yourself.
There are a number of cases where it will refuse to move items, including that. I don't know if there are specific reasons behind all of those cases, or if it was just too much effort to make it handle everything properly.
(The relevant function that moveToGround() calls out to is detachItem() in library/modules/Items.cpp, if you want to take a look.)
So basically you're writing moveToGroundSeriouslyIMeanItThisTime()? :)There are a number of cases where it will refuse to move items, including that. I don't know if there are specific reasons behind all of those cases, or if it was just too much effort to make it handle everything properly.
(The relevant function that moveToGround() calls out to is detachItem() in library/modules/Items.cpp, if you want to take a look.)
I actually did check it, right after posting that, and found out that it doesn't move things that are currently in a job. I hadn't realised they were in a job--because nobody was doing anything, it was one of those jobs that exists in the list but nobody will ever claim, ever, because of burrow restrictions--so that hadn't occured to me. Forbid/unforbid and now they're movable.
Incidentally, the other problem was that it refuses to move things that are listed in a UI viewscreen, which I actually had learned last year when I wrote a script to combine drinks in a stockpile, but had since forgotten. That's the other problem I was having, since I was trying to move things I had selected in the UI.
So, if anyone's having the same problem, make sure the items aren't visible in the UI (meaning, you can't use gui.getSelectedItem(), you have to store them in a variable), and forbid them to kill any jobs pointing to them.
So basically you're writing moveToGroundSeriouslyIMeanItThisTime()? :)
I have an issue in github about just that. It's not very hard to drastically improve the functionality of detach item and in turn to moveTo* functions.So basically you're writing moveToGroundSeriouslyIMeanItThisTime()? :)
I considered writing "goddamnitDoWhatIWantRightNow()" but it seemed like too large a project scope.
(Actually, I'm still having problems, because detachItem() actually does fail out when an item is stored in a building. Fails if there's a BUILDING_HOLDER general ref. Still not sure why, or what the danger is of proceeding in that case.)
I have an issue in github about just that. It's not very hard to drastically improve the functionality of detach item and in turn to moveTo* functions.
Those are all generated at compile time from df-structures.
There aren't any generated copy constructors that I'm aware of, so the problem is likely with however job-duplicate is copying jobs.
df::job *DFHack::Job::cloneJobStruct(df::job *job, bool keepEverything)
{
CHECK_NULL_POINTER(job);
df::job *pnew = new df::job(*job);
for ( size_t a = 0; a < pnew->job_items.size(); a++ )
pnew->job_items[a] = new df::job_item(*pnew->job_items[a]);
And as usual I still don't have an answer to how to I make an item like sword into an artifact with it's own name? Please I need help here. I asked this a few pages ago.
Since then I now also need answers to how do I turn my character into a necromancer with DFhack? As I don't have any necromancer towers whatsoever and I'm missing out a part of the game here because of it.
function findImage(id, subid)
local result = nil
for _,i in ipairs(df.global.world.art_image_chunks) do
if i.id == id then
result = i.images[subid]
end
end
return result
end
local item = dfhack.gui.getSelectedItem()
if not item then
print("No item selected")
else
local already_artifact = false
for i,v in ipairs(item.general_refs) do if df.general_ref_is_artifactst:is_instance(v) then already_artifact = true end end
if already_artifact then
print("Already an artifact")
else
local artifact_record = df.artifact_record:new()
local artifact_ref = df.general_ref_is_artifactst:new()
local history_event = df.history_event_artifact_createdst:new()
artifact_record.id = df.global.artifact_next_id
artifact_record.item = item
artifact_record.anon_1 = -1000000
artifact_record.anon_2 = -1000000
artifact_record.anon_3 = -1000000
artifact_ref.artifact_id = artifact_record.id
item.flags.artifact = true
item.flags.artifact_mood = true
item:setQuality(5)
for _,v in ipairs(item.improvements) do
v.quality = 5
end
if item.masterpiece_event == -1 then
history_event.year = df.global.cur_year
history_event.seconds = df.global.cur_year_tick_advmode
else
local masterpiece_event = df.global.world.history.events[item.masterpiece_event]
history_event.year = masterpiece_event.year
history_event.seconds = masterpiece_event.seconds
end
history_event.id = df.global.hist_event_next_id
history_event.artifact_id = artifact_record.id
history_event.hfid = item.maker
history_event.unit_id = df.historical_figure.find(item.maker).unit_id
history_event.site = df.global.world.world_data.active_site[0].id
item.general_refs:insert('#', artifact_ref)
df.global.world.artifacts.all:insert('#', artifact_record)
df.global.artifact_next_id = artifact_record.id + 1
df.global.world.history.events:insert('#', history_event)
df.global.hist_event_next_id = df.global.hist_event_next_id + 1
-- Look for a name
local named_image = nil
if df.item_figurinest:is_instance(item) then
print("is figurine")
local image = findImage(item.image.id, item.image.subid)
print("found image") print(image)
if image and image.name.has_name then
print("set name")
named_image = image
end
end
if not named_image then
for _,i in ipairs(item.improvements) do
if df.itemimprovement_art_imagest:is_instance(i)
or df.itemimprovement_illustrationst:is_instance(i)
or df.itemimprovement_sewn_imagest:is_instance(i) then
local image = findImage(i.image.id, i.image.subid)
if image and image.name.has_name then
named_image = image
end
end
end
end
if named_image then
for i=0,6 do
artifact_record.name.words[i] = named_image.name.words[i]
artifact_record.name.parts_of_speech[i] = named_image.name.parts_of_speech[i]
end
artifact_record.name.language = named_image.name.language
artifact_record.name.has_name = true
end
end
end
for i,v in ipairs(df.global.world.raws.language.words) do dfhack.printerr(v.word .. ': ' .. i) end
That'll print the words and their IDs out to DFHack's error log. Copy/paste them into a text file, and you'll have a reference for any time you need to look up word IDs.-snip-
I gave up on the artifact/item naming thing for the time being as getting to be a necromancer is more important. Just went over all of the worlds in legends mode I've had adventurers in and NONE of them have necromancers and their towers in them, something to do with 'Age of Myth' and only 5 years in?Individuals can only become Necromancers if they become obsessed with their own mortality. Five years is simply not enough time for a vanilla sapient to worry about death. Complicating matters is the apparent limit of this anxiety to authorities, the delay between the starts of their quests and their completions, and the time needed to amass the fifty zombies required for a tower (until which, they act as bandits, living in camps.)
How old most the world be for them to generate!? Why of why can't I just turn my character into a necromancer!?? I have DFhack and don't know how to use it properly or at all, or barely. FUCK!!! >:(
-snip-
-snip-
If you're already comfortable with gm-editor and want to avoid scripting, this is probably the simplest method:
1) Obtain a (not necessarily blank) slab. If you can't find one/want to avoid the hassle, you can utilise gui/create-item to make a new one.
2) Enter "gui/gm-editor df.global.world.raws.interactions" in the DFHack console.
3) Look through the entries, until you find one named "SECRET_1" or similar (not SECRET_ANIMATE). Assuming you haven't modded in any new secrets, this should relate to necromancy. Otherwise, if you're unsure about its nature, looking through its sources and effects should give you an indication.
4) Now, take note of the interaction's id (listed just below the name).
5) Use gm-editor to modify the slab: set engraving_type to 6 (Secrets) and topic to the secret's id.
And voilà! A fully-functional necromancy-inducing slab. Reading it (of course, this assumes that your unit is not illiterate) should apply the interaction.Spoiler: side-note (click to show/hide)
Anyhow, I did as instructed but for some reason it didn't work, I found the SECRET_1 thing in 4th line, added it's ID to topic, saved the game and re-load the game, read the slab and nothing. Nothing under 'acquired power' menu. I spawned the slab.That's unusual. Did you remember to change the slab's engraving_type?
Anyhow, I did as instructed but for some reason it didn't work, I found the SECRET_1 thing in 4th line, added it's ID to topic, saved the game and re-load the game, read the slab and nothing. Nothing under 'acquired power' menu. I spawned the slab.That's unusual. Did you remember to change the slab's engraving_type?
If that's not the issue, are you playing a modded race? Necromancy secrets are generated with a requirement for [MORTAL], [CAN_SPEAK], [CAN_LEARN] - reading necromancy slabs has no effect on races which lack such tags, so this method would not work.
BTW, for the folks working on df-structures, I've identified a flag for you.
Interesting tricks, I'll have to check over it and see if I can use what you did to streamline https://github.com/maxthyme/dfstuff/blob/master/artifake.lua more. The names script is still broken because I can't figure out how to duplicate the trick mifki used to pull up the old in-game adventurer name selection screen.And as usual I still don't have an answer to how to I make an item like sword into an artifact with it's own name? Please I need help here. I asked this a few pages ago.
Since then I now also need answers to how do I turn my character into a necromancer with DFhack? As I don't have any necromancer towers whatsoever and I'm missing out a part of the game here because of it.
I actually have a partial explanation for this. I recently needed to write a script to turn things into artifacts, and it looks like this:Spoiler (click to show/hide)
Note: this is very sketchy, but should be enough to work off of. The script currently looks for a name on a decoration on the item and, if it finds one, just copies that name into the artifact record. But, you could manually edit the artifact_record::name through the interactive Lua interface. You can find the word IDs (for name::words) at df.global.world.raws.language.words. They're actually just indexed in the order they appear in language_words.txt. The parts_of_speech is the specific variant of the word to use. 0 and 1 are singular and plural noun, for example.
You could also just skip all this, set all the words to -1, and then set the first_name to whatever you want, but that's less fun.
For an artifact weapon, you'll want to manually set the sharpness and such to the correct values for an artifact weapon. Search on Google for a script called "artifake," which I based mine off of. It sets the sharpness, so you can see how to do that from there.
EDIT: BTW, here's a useful thing for getting the word IDs:Code: [Select]for i,v in ipairs(df.global.world.raws.language.words) do dfhack.printerr(v.word .. ': ' .. i) end
That'll print the words and their IDs out to DFHack's error log. Copy/paste them into a text file, and you'll have a reference for any time you need to look up word IDs.
I considered writing a script to parse language_names from plain text, which would actually not be too hard, since everything's there in raws.language.words. The only tricky bit is the first, compound word. You'd have to first search for single words matching it, then try every split position until you find one that gives you two valid words. It ended up being overengineered for what I needed, though, so I've just been doing it manually when I need to.
been thinking about how would one make a shotgun spread in dwarf fortress.
idea on doing so is using minecart physics to launch a collected amount of items out in a direction assign by a cursor.
either that or thinking up a way to rewrite the 'launch/jump' script into telekinesis script for launching objects from one point to another.
modtools/interaction-trigger -onAttackStr "shotgun" -suppressAttack -command [ wrapper -unitSource \\ATTACKER_ID -locTarget \\DEFENDER_ID -locCheck 2r_circle.txt -script [ item/projectile -unitSource \\SOURCE -locationTarget \\LOCATION -item AMMO:ITEM_AMMO_PELLET -mat INORGANIC:IRON ] ]
Interesting tricks, I'll have to check over it and see if I can use what you did to streamline https://github.com/maxthyme/dfstuff/blob/master/artifake.lua more. The names script is still broken because I can't figure out how to duplicate the trick mifki used to pull up the old in-game adventurer name selection screen.
Yeah, already got the history event bit in there since I wanted to make sure they were recorded right in legends mode.
I still can't figure out why the first one you make in a world ends up turning into a slab-duplicate that crashes unless removed.
Does creating items with a the create-item script function the same as a reaction? That is to say, can I mimic the "make rock crafts" reaction or other hard coded reactions?
Quick question: There seems to be a new dfhack plugin that shows information in material/item descriptions. How do I add, remove or alter those?The info is in item-descriptions.lua and view-item-info.lua. And yes it does look into item type only.
I noticed that when I looked at "dog leather", which gave me some random information about animal leathers in DF.
The issue for me is that I also looked at "dragon scales" and "antman chitinplate", which are actually good materials in the game, and I get the same description about "leathers are not terribly good in DF".
I assume its not related to material, but rather an item description for TANNED_SKIN ?
Quick question: There seems to be a new dfhack plugin that shows information in material/item descriptions. How do I add, remove or alter those?
I noticed that when I looked at "dog leather", which gave me some random information about animal leathers in DF.
The issue for me is that I also looked at "dragon scales" and "antman chitinplate", which are actually good materials in the game, and I get the same description about "leathers are not terribly good in DF".
I assume its not related to material, but rather an item description for TANNED_SKIN ?
I'm curious: when you use tiletypes to change a construction to natural stone, what happens to the block or boulder that was used to build it? Blocks used in constructions still appear in the stocks screen, and the count doesn't seem to decrease when you use tiletypes to replace them with natural stone, so is that object just getting orphaned and sitting in the items list forever?If you are curious about constructions in general i had a stab at making moving walls so there is relevant code here (https://github.com/warmist/df-mini-mods/blob/master/mechanicalWorkshops/wall_mover.lua) and there was a tweak that compacted walls by deleting their items and setting them to non-item based walls here (https://github.com/DFHack/dfhack/blob/33302251c343324b0cd17bfb206d16a626093dd7/plugins/cleanconst.cpp)
Ah, shame. I wonder how hard it would be to update tiletypes to just remove the orphaned constructions and blocks if it's turning a construction into not-a-construction. I mean, would it be that easy?Tile type manipulation is full of stuff like this. E.g. if it's part of vein you need to find the vein entry and remove the tile from it's mask. Also tree and shrubs have special logic and so on...
Ah, shame. I wonder how hard it would be to update tiletypes to just remove the orphaned constructions and blocks if it's turning a construction into not-a-construction. I mean, would it be that easy?Tile type manipulation is full of stuff like this. E.g. if it's part of vein you need to find the vein entry and remove the tile from it's mask. Also tree and shrubs have special logic and so on...
Making sure that each one work correctly would take someone ages (and it would probably break a lot) but anyone who wants to do that is welcome :)
There is actually tile attrs for materials. And one of them is "CONSTRUCTION" so you could use that. Also scripts can use those attrs just finde you don't need plugin for that (unless you want to do it often on a whole map).Ah, shame. I wonder how hard it would be to update tiletypes to just remove the orphaned constructions and blocks if it's turning a construction into not-a-construction. I mean, would it be that easy?Tile type manipulation is full of stuff like this. E.g. if it's part of vein you need to find the vein entry and remove the tile from it's mask. Also tree and shrubs have special logic and so on...
Making sure that each one work correctly would take someone ages (and it would probably break a lot) but anyone who wants to do that is welcome :)
Haha, fair enough. Thanks for cleanconst, BTW, that actually does help a lot.
I actually might write a quick little script, just for myself, to clean up orphaned constructions from my tiletypes usage. Shouldn't be too hard to iterate the list of constructions and remove the ones that are located at tiles that aren't constructions anymore. I take it, from skimming the code on github, that the tiletypes enum isn't laid out in a sane way where I can just use a mask to figure out which ones are constructions and which ones aren't. Unless I want to write a full plugin that can use df::enum_attrs, I'll have to just make a list of all the tile types that are constructions, right?
There is actually tile attrs for materials. And one of them is "CONSTRUCTION" so you could use that. Also scripts can use those attrs just finde you don't need plugin for that (unless you want to do it often on a whole map).
Thank you again, even if that is fairly horrible news. Testing invaders will have to be done the hard way, countless hours of play and player feedback.
on the back burner until I finish my thesis (as is everything else in my life) ... until June all I can do is read the forums and add to my to-do list.
until I finish my thesisWhen DF is your sanity break, you know you've made a wise career choice.
until I finish my thesisWhen DF is your sanity break, you know you've made a wise career choice.
Fortunately for me, I didn't discover DF until well after I'd finished my thesis.
okay got throwing to work so I figured why not recreate Golf strangely I kept throwing my musical instrument per stroke
at least now I can scratch off itemshotgun off the Dfhack todo list.
1. it pulls the top most item from the list usually throwing 1 itemuntil I finish my thesisWhen DF is your sanity break, you know you've made a wise career choice.
Fortunately for me, I didn't discover DF until well after I'd finished my thesis.
Not sure Physicist is a wise career choice, but I've been in graduate school for 7 years now so I am just ready to be done.okay got throwing to work so I figured why not recreate Golf strangely I kept throwing my musical instrument per stroke
at least now I can scratch off itemshotgun off the Dfhack todo list.
Two Questions:
1. What happens if there are more than one item at a position?
2. Do you find it faster to check for an item going through the entire item list instead of checking the occupancy? (I may be remembering occupancy wrong, does that just tell you True or False and you would have to look through the list anyway?)
On a side note I did manage to think up a way to get multilevel buildings to work. After a building is built it is possible to change the tile type inside a building to be a pillar (or wall or what have you) that can then support the next floor above it. I am thinking I will try to write a script that will modify a building to change unpassable tiles or something like that to pillars or walls and then build on top of it. The only question that remains is will it cause crashes? Who knows. (Also if I turn a workshop tile into stairs could a dwarf use those stairs? Could we actually allow for different stories that dwarfs can access? I doubt it, but it would be cool)
@roses there is block-local item storage that MUST be up-to-date. It has item ids and you can get items quicker that way.
Butcher a dead animal (maybe a script which enters arena mode and hits the butcher key?)
Extract from dead animal
Capture a live land animal
Milk Creature
Shear Creatue
Capture a live fish
Engrave memorial (not sure about this one)
Melt Item (can be done, but doesn't handle the fractional bars and such, script should be able to replicate)
Prepare meal (not sure about this one)
Collect Sand
Collect Webs
Collect Clay
Are there any other I am missing, or are there any I have that people think could be done with scripts? Obviously I think they could all be "done" with scripts, but I was thinking about replicating the exact features not just, sand bag is created, remove some sand from map.
There isn't a 0.42.04-r1 DFHack release. What are you using? I remember testing that feature at some point in the 0.42 series and seeing it work, though.Oh, silly me. That's the version number of LazyNewb I'm using. So the dfhack it has is 0.42.04-alpha2.
okay got throwing to work so I figured why not recreate Golf strangely I kept throwing my musical instrument per strokeOh good lord.
http://www.truimagz.com/host/rumrusher/folder1/Golf-might-be-doable-now.gif
which then I threw a stone throne around and then notice something wonderful about tagging the same item with projectile prompts
and tested this with a corpse.
http://www.truimagz.com/host/rumrusher/folder1/telekinesis-Corpse-explosion.gif
so uhh telekinesis.lua is set up.
(https://gist.github.com/Rumrusher/a8f1bfefa2fbed450b6d63f6739b2562)
at least now I can scratch off itemshotgun off the Dfhack todo list.
okay got throwing to work so I figured why not recreate Golf strangely I kept throwing my musical instrument per strokeOh good lord.
http://www.truimagz.com/host/rumrusher/folder1/Golf-might-be-doable-now.gif
which then I threw a stone throne around and then notice something wonderful about tagging the same item with projectile prompts
and tested this with a corpse.
http://www.truimagz.com/host/rumrusher/folder1/telekinesis-Corpse-explosion.gif
so uhh telekinesis.lua is set up.
(https://gist.github.com/Rumrusher/a8f1bfefa2fbed450b6d63f6739b2562)
at least now I can scratch off itemshotgun off the Dfhack todo list.Spoiler (click to show/hide)
1. I'm pretty sure no.Thanks!
2. No; in general, world site stuff is basically infeasible to mess with, and custom sites are probably the infeasible of anything.
3. I'm not sure it could be done on the current region if that region doesn't have an interaction already, but I haven't messed around with interaction instances.
I can't reproduce the issue. Are you waiting for some time for the room to be reassigned? (It won't happen instantly, but it should happen within an in-game day or so.)There isn't a 0.42.04-r1 DFHack release. What are you using? I remember testing that feature at some point in the 0.42 series and seeing it work, though.Oh, silly me. That's the version number of LazyNewb I'm using. So the dfhack it has is 0.42.04-alpha2.
So looking at tasks that are hardcoded that can't be done with a custom reaction I haveCode: [Select]Butcher a dead animal (maybe a script which enters arena mode and hits the butcher key?)
Are there any other I am missing, or are there any I have that people think could be done with scripts? Obviously I think they could all be "done" with scripts, but I was thinking about replicating the exact features not just, sand bag is created, remove some sand from map.
Extract from dead animal
Capture a live land animal
Milk Creature
Shear Creatue
Capture a live fish
Engrave memorial (not sure about this one)
Melt Item (can be done, but doesn't handle the fractional bars and such, script should be able to replicate)
Prepare meal (not sure about this one)
Collect Sand
Collect Webs
Collect Clay
to be honest this is my next project attempt figuring out how to copy and paste playerfort details to another site and or designing custom npc sites to replace the pregen ones.1. I'm pretty sure no.Thanks!
2. No; in general, world site stuff is basically infeasible to mess with, and custom sites are probably the infeasible of anything.
3. I'm not sure it could be done on the current region if that region doesn't have an interaction already, but I haven't messed around with interaction instances.
I can't reproduce the issue. Are you waiting for some time for the room to be reassigned? (It won't happen instantly, but it should happen within an in-game day or so.)There isn't a 0.42.04-r1 DFHack release. What are you using? I remember testing that feature at some point in the 0.42 series and seeing it work, though.Oh, silly me. That's the version number of LazyNewb I'm using. So the dfhack it has is 0.42.04-alpha2.
Edit: Also, is the noble in question a citizen?
It's for my mayor position, and yes they are citizens. I am not sure how much time happens between, it's not an announcement I notice.
I can't reproduce the issue. Are you waiting for some time for the room to be reassigned? (It won't happen instantly, but it should happen within an in-game day or so.)There isn't a 0.42.04-r1 DFHack release. What are you using? I remember testing that feature at some point in the 0.42 series and seeing it work, though.Oh, silly me. That's the version number of LazyNewb I'm using. So the dfhack it has is 0.42.04-alpha2.
Edit: Also, is the noble in question a citizen?
It's for my mayor position, and yes they are citizens. I am not sure how much time happens between, it's not an announcement I notice.
I meant to comment on this before, but is there a reason you chose the falling/minecart projectile mechanics over the shooting mechanics? I currently split my projectile scripts allowing you to chose which one you want, but if falling/minecart is always better then I might just remove the choice to simplify the script.Soft landings I think are the main reason. Not having thrown items destroyed automatically.
just realized now you can sink a sword into a person 7 times, and have it visually look like the person got stab by 7 swords at the same time from 7 different directions.I meant to comment on this before, but is there a reason you chose the falling/minecart projectile mechanics over the shooting mechanics? I currently split my projectile scripts allowing you to chose which one you want, but if falling/minecart is always better then I might just remove the choice to simplify the script.Soft landings I think are the main reason. Not having thrown items destroyed automatically.
just realized now you can sink a sword into a person 7 times, and have it visually look like the person got stab by 7 swords at the same time from 7 different directions.
anyone else having difficulty with AutoChop in 42.x? I'm getting a weird thing where the woodcutter seems to get stuck repeatedly trying to chop down a tree that they already chopped down a while ago. This is in alpha1 on Windows, haven't tried alpha2 yet. I'll load that up and run some more tests, see if I can reproduce it in a different fort.I'm getting the same issue Nomad here is, but I'm using the new release, anyone else seeing the same thing?
--nomad_delta
just realized now you can sink a sword into a person 7 times, and have it visually look like the person got stab by 7 swords at the same time from 7 different directions.
you wouldn't happen to have a screencap? it's been a while since we've had a fanart-inducing headscratcher to inflict on the internet
here's a gif of a spider corpse exploding into 7 clonesjust realized now you can sink a sword into a person 7 times, and have it visually look like the person got stab by 7 swords at the same time from 7 different directions.
you wouldn't happen to have a screencap? it's been a while since we've had a fanart-inducing headscratcher to inflict on the internet
It doesn't come back the tick after? That's what it does to vampirism, at least.
Huh, sounds like it's clearing curses. I could add a -keep-curses option or something, probably.
so here's the script I use for healing wounds on my adventurer.It doesn't come back the tick after? That's what it does to vampirism, at least.Huh, sounds like it's clearing curses. I could add a -keep-curses option or something, probably.
From what I remember about a week or more ago when I tested it I intentionally jumped from a tree and broke a few things as a necromancer, I then of course went to 'z' screen/character stat screen to where I initiated the ritual of 'full-heal', alright good, damages healed/removed but minus being a necromancer. I then investigated a bit by walking around with my character a bit to see for real and make sure that my character wasn't a necromancer anymore and nope, she wasn't.
That was then, now I just booted up the game again to check even though my character currently has no injuries and yup, removes necromancy... but after 30-60 ticks in I'm back to being a necromancer so that's a big-arse relief for me.
Still though, wish there was a version of the script that didn't instantly cure necromancy/vampirism/weresomething.
So, how many minutes was DFHack stable before a new major DF version was released? :)
so here's the script I use for healing wounds on my adventurer.
this script doesn't poke into syndromes and remove them.Spoiler: for draggarth (click to show/hide)
EDIT: Now I just need to know how safe it is to use DFhack as it currently is in DF version 0.43.01.https://www.youtube.com/watch?v=FopyRHHlt3M
EDIT: Now I just need to know how safe it is to use DFhack as it currently is in DF version 0.43.01.https://www.youtube.com/watch?v=FopyRHHlt3M
0.43.01 came out yesterday. DFHack typically lags about a month behind. In all likelihood, DFHack is going to skip 0.43.01 and go to whatever stable 0.43.0x version fixes a bunch of the new bugs.
I imagine advfort is due for an overhaul, to see what sort of stuff we can improve from the interface it uses, it would be nice if we could merge it into the building interface for adventurer mode to some extent but that will probably require more capable gui wizardry.I was hoping to drop advfort support, but after playing some df it seems like I can't do it yet. However it's too soon to tell if merging would be possible. I would guess it's unlikely but we'll see.
Things like workflow and stocks will need a full overhaul I assume.
What exactly's it missing? Digging?the fact you don't get lock out of construction because there a hostile in the area... I mean it's for safety reasons but damn it I wanna dig myself an early grave.
What exactly's it missing? Digging?It only has: construction (with only carpenters workshop), tree cutting, item-based buildings (e.g. coffin and coffers etc...)
I think there will still be a spot for advfort on spot stuff, but doing the great big constructions I've done with advfort and doing them like this... yeah, no question new way is best there. Being able to dig until Toady adds it in will be invauable as always, and being able to deconstruct/alter things outside of the current non-site/camp-site limitations will be nice to have back to play with.I imagine advfort is due for an overhaul, to see what sort of stuff we can improve from the interface it uses, it would be nice if we could merge it into the building interface for adventurer mode to some extent but that will probably require more capable gui wizardry.I was hoping to drop advfort support, but after playing some df it seems like I can't do it yet. However it's too soon to tell if merging would be possible. I would guess it's unlikely but we'll see.
Things like workflow and stocks will need a full overhaul I assume.
What does the workflow tool do that seems to be not yet possible with the manager? Would there be value in using the workflow UI to control the manager?
so here's the script I use for healing wounds on my adventurer.
this script doesn't poke into syndromes and remove them.
Speaking of, does anybody know if the severity of alcohol-induced illness is proportional to the value of the alcohol? Because I've had a suspicious number of alcohol-related deaths, and also have a modded booze that's more valuable than sunshine. It occurred to me that, if the "strength" of alcohol is determined by its value, nobody might've noticed before since the normal alcohol values are so close to each other (2, 3, and 5).
What does the workflow tool do that seems to be not yet possible with the manager? Would there be value in using the workflow UI to control the manager?
I think workflow is entirely replaced with the new job controls; the new controls have even more flexibility (eg multiple conditions) than workflow did.
the script was posted for someone who didn't want their interactions removed since they are tied to Syndromes and the default dfhack heal script kinda deletes syndromes completely.
so here's the script I use for healing wounds on my adventurer.
this script doesn't poke into syndromes and remove them.
Hmm, it doesn't remove syndromes, but will it revive people who're dying of alcohol-induced suffocation? I'm not sure if the problem there is just suffocating because of a blocked airway that they can't clear because they're unconscious (which your script definitely fixes) or if the unconsciousness is a symptom of the suffocation.
Speaking of, does anybody know if the severity of alcohol-induced illness is proportional to the value of the alcohol? Because I've had a suspicious number of alcohol-related deaths, and also have a modded booze that's more valuable than sunshine. It occurred to me that, if the "strength" of alcohol is determined by its value, nobody might've noticed before since the normal alcohol values are so close to each other (2, 3, and 5).
You could enforce it by linking the job to a workshop which is limited to the corresponding minimum skill.What does the workflow tool do that seems to be not yet possible with the manager? Would there be value in using the workflow UI to control the manager?
I think workflow is entirely replaced with the new job controls; the new controls have even more flexibility (eg multiple conditions) than workflow did.
One thing I really want though is workflow's (or the stockpile jobs's ability) to do stuff like "Keep making X until you have Y items of Z quality"
The new version doesn't seem to have it, unless I missed something
...Well now I feel like an idiot, thanks for the tip thoughYou could enforce it by linking the job to a workshop which is limited to the corresponding minimum skill.What does the workflow tool do that seems to be not yet possible with the manager? Would there be value in using the workflow UI to control the manager?
I think workflow is entirely replaced with the new job controls; the new controls have even more flexibility (eg multiple conditions) than workflow did.
One thing I really want though is workflow's (or the stockpile jobs's ability) to do stuff like "Keep making X until you have Y items of Z quality"
The new version doesn't seem to have it, unless I missed something
local pos=position or copyall(df.global.cursor)
if pos.x==-30000 then
qerror("Select a location")
end
local x = 0
local y = 0
for x=pos.x-3,pos.x+3,1 do
for y=pos.y-3,pos.y+3,1 do
z=pos.z-1
while true do
local block = dfhack.maps.getTileBlock(x,y,z)
if block then
--print(x..","..y)
block.tiletype[x%16][y%16]=32
--z = z-1
else
--z = z+1
block = dfhack.maps.getTileBlock(x,y,z)
block.tiletype[x%16][y%16]=42
break
end
end
end
end
What are 32 and 42 supposed to be? You should be using df.tiletype.NAME instead, because the raw numbers can change between releases.Would very low-numbered jobs be likely to be in this group? I have a script that watches for job completions from 3 to 7 inclusive (basically digging out a tile), and I was hoping it would just continue working in 0.43. I suppose if jobs have a name attribute I can do it the right way.
They do - look at df.job_type. I don't know if they've changed, though.Thanks! It would have been a pain to chase down that bug if something did change.
How would I get something to go off on autosave? checking for df.global.ui.main.autosave_request every tick doesn't work.
local dlg = require ('gui.dialogs')
local dlg2 = require ('gui.dialogs')
local dlg3 = require ('gui.dialogs')
local dlg4 = require ('gui.dialogs')
local dlg5 = require ('gui.dialogs')
dlg5.showMessage("A chance encounter", msg5, color, nil)
msg5=("You decide to give the dwarves a proper burial; least they haunt you for using their equipment.")
dlg4.showMessage("A chance encounter", msg4, color, nil)
msg4=("The wagon now yours, you claim your price. The dead have no need for it; you on the other hand...")
dlg3.showMessage("A chance encounter", msg3, color, nil)
msg3=("The goods in the wagon seem intact; curiously enough 7 coffins are among the assorted items.")
dlg2.showMessage("A chance encounter", msg2, color, nil)
msg2=("With no attacker in sight and no trail to follow, you carefully decide to have a closer look.")
dlg.showMessage("A chance encounter", msg, color, nil)
msg=("You come upon a group of dead dwarves, horribly mauled, laying next to their abandoned wagon.")
local dlg = require ('gui.dialogs')
msg5=("You decide to give the dwarves a proper burial; least they haunt you for using their equipment.")
msg4=("The wagon now yours, you claim your price. The dead have no need for it; you on the other hand...")
msg3=("The goods in the wagon seem intact; curiously enough 7 coffins are among the assorted items.")
msg2=("With no attacker in sight and no trail to follow, you carefully decide to have a closer look.")
msg=("You come upon a group of dead dwarves, horribly mauled, laying next to their abandoned wagon.")
dlg.showMessage("A chance encounter", msg5, COLOR_WHITE, nil)
dlg.showMessage("A chance encounter", msg4, COLOR_WHITE, nil)
dlg.showMessage("A chance encounter", msg3, COLOR_WHITE, nil)
dlg.showMessage("A chance encounter", msg2, COLOR_WHITE, nil)
dlg.showMessage("A chance encounter", msg, COLOR_WHITE, nil)
Better? (edit: mh, no, that just crashes the game. :/ )local dlg = require ('gui.dialogs')
msg5=("You decide to give the dwarves a proper burial; least they haunt you for using their equipment.")
dlg.showMessage("A chance encounter", msg5, COLOR_WHITE, nil)
msg4=("The wagon now yours, you claim your price. The dead have no need for it; you on the other hand...")
dlg.showMessage("A chance encounter", msg4, COLOR_WHITE, nil)
msg3=("The goods in the wagon seem intact; curiously enough 7 coffins are among the assorted items.")
dlg.showMessage("A chance encounter", msg3, COLOR_WHITE, nil)
msg2=("With no attacker in sight and no trail to follow, you carefully decide to have a closer look.")
dlg.showMessage("A chance encounter", msg2, COLOR_WHITE, nil)
msg1=("You come upon a group of dead dwarves, horribly mauled, laying next to their abandoned wagon.")
dlg.showMessage("A chance encounter", msg1, COLOR_WHITE, nil)
You should probably put 'local ' before each of the msg variables, but it probably won't cause any problems the way it is.Its for the hermit mode.
Pretty grim embark scenario, there.
Well if you are scripting. Maybe it would be easier to have one reaction that shows choice dialog?You should probably put 'local ' before each of the msg variables, but it probably won't cause any problems the way it is.Its for the hermit mode.
Pretty grim embark scenario, there.
I made a workshop that chains three reaction: #1 spawns a unit (your hermit), #2 kills all dwarves and spawns 7 coffins, #3 gives that embark message and clears all stress from the hermit.
Since create-unit works so well, I want to make every intelligent creature a choice for your hermit. That means 200 reactions for all the animal-men. :D
Well if you are scripting. Maybe it would be easier to have one reaction that shows choice dialog?It would, if I could script. Now I have 400+ reactions that are finished, so... too late. Its maybe a bit clumsier, but at least I managed to do it on my own. I already asked for so much help with scripts lately, I thought it would be better if I do it that way.
I think the 42.06 release was consistent enough that unless people use it enough and find a major bug or something gets passed back down from the 43.xx update process it'll remain as it is.Yeah i was annoyed with it too. I would really want to have some sort "put this item to lua interpreter as <variable>" too.
Also like the gm-editor changes in there, looks like it'll let us pick whether to put in stuff like df.something:new() or drop in ints and such? It was frustrating that I couldn't swap in an int with gm-editor and had to whip up a script or bit of lua (though the interpreter is still a bit of arcane wizardry) to insert it just so I could edit it to figure out what it did.
modtools/interaction-trigger -onAttackStr "ORC_ATTACK_A" -onDefenseStr "ORC_DEFEND_D" -suppressAttack -suppressDefend -command [ item/projectile -unit_source \\ATTACKER_ID -unit_target \\DEFENDER_ID -item AMMO:ITEM_AMMO_BOLTS -mat INORGANIC:IRON -number 5 -maxrange 500 -hitchance 100 ]
forceequip
Forceequip moves local items into a unit’s inventory. It is typically used to equip specific clothing/armor items onto a dwarf, but can also be used to put armor onto a war animal or to add unusual items (such as crowns) to any unit.
For more information run forceequip help. See also modtools/equip-item.
Hey guys, I just read about forceequip:Quoteforceequip
Forceequip moves local items into a unit’s inventory. It is typically used to equip specific clothing/armor items onto a dwarf, but can also be used to put armor onto a war animal or to add unusual items (such as crowns) to any unit.
For more information run forceequip help. See also modtools/equip-item.
How could I use this to target a pet pastured on a workshop? As in:
1. Pasture pet on custom workshop.
2. Dwarf runs a reaction; reagent in reaction is the armor that will be put on the pet.
3. Pet now wears said armor.
I knew the syntax in the older dfhack scripts, but I'm not sure how to do this with the Onload.init. Can it even target units in workshops?
modtools/reaction-trigger -reactionName X -allowNonworkerTargets -command [ script here but make sure you use \\TARGET_ID instead of \\WORKER_ID ]
Haven't tested it myself, but if I am reading the script right it should work. Also, unlike reaction-product-trigger reaction-trigger doesn't need to create a product.Thanks... I get as far as "no unit found at cursor", so the script does run, but as always the script is not optimized for use in a workshop. It requires a cursor for the location. :/ I used the plugin forceequip. I couldnt get modtools/equip-items to work this way.
Haven't tested it myself, but if I am reading the script right it should work. Also, unlike reaction-product-trigger reaction-trigger doesn't need to create a product.Thanks... I get as far as "no unit found at cursor", so the script does run, but as always the script is not optimized for use in a workshop. It requires a cursor for the location. :/ I used the plugin forceequip. I couldnt get modtools/equip-items to work this way.
modtools/reaction-product-trigger -reactionName "Equip Animal Armor" -allowNonworkerTargets -command [ modtools/equip-item -unit \\TARGET_ID -item \\INPUT_ITEMS -bodyPart UB -mode Worn ]
I get the error message about "cannot write field: item.find: Number expected".
I tried \\INPUT_ITEMS, \\OUTPUT_ITEMS, both with \\\ and both with []. I also tried an item ID, like ARMOR:ITEM_ARMOR_BREASTPLATE:INORGANIC:STEEL. None of those help, same error message.
modtools/reaction-trigger -reactionName TEST_PET_ARMOR1 -allowNonworkerTargets -command [ modtools/equip-item -unit \\TARGET_ID -item \\\LAST -bodyPart UB -mode Worn ]
local itemId = tonumber(args.item) or ((args.item == '\\LAST') and (df.global.item_next_id-1))
local item = df.item.find(itemId)
if not item then
error('invalid item!', args.item)
end
to include something like ARMOR:ITEM_ARMOR_ANIMAL:INORGANIC:STEEL ?
itemId = tonumber(args.item) or ((args.item == '\\LAST') and (df.global.item_next_id-1))
withitem = 'ARMOR:ITEM_ARMOR_ANIMAL'
mat = 'INORGANIC:STEEL'
itemId = dfhack.items.createItem(dfhack.items.findType(item), dfhack.items.findSubtype(item), dfhack.matinfo.find(mat)['type'], dfhack.matinfo.find(material).index, unit)
Yes you could, you could replaceThe only problem here is that you are creating a new item from whole cloth, so any quality level of the reagent is lost. As long as it's going to be a custom script, it might be easier to customize the \\INPUT_ITEMS to refer specifically to the first item. That will retain quality levels, name, artifact status, etc.Code: [Select]itemId = tonumber(args.item) or ((args.item == '\\LAST') and (df.global.item_next_id-1))
withCode: [Select]item = 'ARMOR:ITEM_ARMOR_ANIMAL'
mat = 'INORGANIC:STEEL'
itemId = dfhack.items.createItem(dfhack.items.findType(item), dfhack.items.findSubtype(item), dfhack.matinfo.find(mat)['type'], dfhack.matinfo.find(material).index, unit)
After you brought it up I decided that I wanted to expand that system so that you could give units special jewelry, armor to pets, various tools like smoke bombs and grappling hooks, etc... So I am planning on making it more robust, including auto forbidding items so dwarfs won't just take the items off, possibly also including adding ownership of items.
I'm having trouble getting interaction-trigger to trigger anything at all in both arena mode and adventure mode.
It doesn't seem to be reading the attack string or defense string that I put for the trigger to activate, because I also put -suppressAttack and
-suppressDefense and I am still able to see the attack string in my combat logs.Quotemodtools/interaction-trigger -onAttackStr "ORC_ATTACK_A" -onDefenseStr "ORC_DEFEND_D" -suppressAttack -suppressDefend -command [ item/projectile -unit_source \\ATTACKER_ID -unit_target \\DEFENDER_ID -item AMMO:ITEM_AMMO_BOLTS -mat INORGANIC:IRON -number 5 -maxrange 500 -hitchance 100 ]
Would there be any problems if the creature that could do the interaction didn't learn it but was spawned with the ability to do it?
Yes you could, you could replaceDid that. Bad Argument at #1 to 'find' (string expcted, go nil) at line 78, the one I changed.Code: [Select]itemId = tonumber(args.item) or ((args.item == '\\LAST') and (df.global.item_next_id-1))
withCode: [Select]item = 'ARMOR:ITEM_ARMOR_ANIMAL'
mat = 'INORGANIC:STEEL'
itemId = dfhack.items.createItem(dfhack.items.findType(item), dfhack.items.findSubtype(item), dfhack.matinfo.find(mat)['type'], dfhack.matinfo.find(material).index, unit)
After you brought it up I decided that I wanted to expand that system so that you could give units special jewelry, armor to pets, various tools like smoke bombs and grappling hooks, etc... So I am planning on making it more robust, including auto forbidding items so dwarfs won't just take the items off, possibly also including adding ownership of items.
modtools/reaction-trigger -reactionName TEST_PET_ARMOR2 -allowNonworkerTargets -command [ modtools/equip-item-animal -unit \\TARGET_ID -item ARMOR:ITEM_ARMOR_ANIMAL:INORGANIC:STEEL -bodyPart UB -mode Worn ]
modtools/reaction-trigger -reactionName TEST_PET_ARMOR1 -allowNonworkerTargets -command [ modtools/equip-item-animal -unit \\TARGET_ID -item ARMOR:ITEM_ARMOR_ANIMAL -bodyPart UB -mode Worn ]
Is it accurate to call DFHack a modding API that comes with a few built-in mods?
I'm guessing the answer is "no," but does DFHack expose any hardcoded variables, like the happiness bonuses for different positive emotions? I imagine most of them are elided by the compiler, but I know I've, in the past, used vectors full of constants in my own games.
I'm curious about making dwarven moods more difficult to handle. I've always considered it too easy to make dwarves happy by giving them large rooms. What I actually think should happen is that dwarves should become inured to specific luxuries after a while, but that would require new mechanics on Tarn's part (or a really obnoxiously complicated plugin that shadows the entire mood system). But, just making them less ecstatic about having a nice dining room would be a start.
The game does store which tiles are part of a room, though.
Nope. It may be a bug in the current version of DFHack, but currently building_extents is the x, y, width, and height of the bounding box, and a single pointer to a uint8 that's just: "0 - not room; 1 in stockpile; 2 wall; 3 inner; 4 distance boundary" according to df-structures.
Maybe the pointer is supposed to be to an array of something like struct { uint8 extent_type; union { /* the different types of extent */ }; }; but that's gotten lost?
EDIT: Aha! Sorry, I keep forgetting that the source of DFHack is just on Github. Just looked at the code, and figured out what the problem is: the pointer is a pointer to a bare array, but both the Lua API and gui/gm-editor are only set up to access vectors. So, from a plugin, I can just do a lookup into that array, I just won't be able to rely on bounds-checking to catch bugs.
Well, to be fair, it's not really a "problem" in C/C++ because pointers are arrays and arrays are pointers. That's why you can say 5[array] instead of array[5], if you want to be weird about it. The subscript operator is just a bit of convenient syntactic sugar. (And, for size information, you should also really never use sizeof() on an array. It's the closest to undefined behaviour you can get without actually being undefined behaviour. Personally, I don't think it should even be allowed, but there are legacy reasons for keeping it around, and frankly most compiler vendors would probably keep it as undefined behaviour even if the standard was changed.)Short answer: no this can't be vector.
Good to know about that offset shortcut in gm-editor, though. I've seen it in the help page, but there was nothing that indicated what that was supposed to do, and I haven't come across a bare array anywhere else in any of the data structures dfhack exposes, so I haven't had an opportunity to experiment with it. Maybe adding a little note to the help page to clarify that it's for indexing bare arrays would be useful?
But, just out of curiosity, has it been determined that that particular variable is actually a bare array? Is it possible that that's a vector and nobody's noticed yet? I mean, everywhere else that I've seen, vectors are used, even in places where you could legitimately get away with even a statically-sized array, like the unit attributes and personality traits.
In the 40.24 version of DFHack there was a plugin or script that allowed you to switch game-mode in game. Does anyone remember its name and whether or not it's available for 42.06?
Ja, as well as Arena Mode (which was, in fact, necessary for properly switching.)In the 40.24 version of DFHack there was a plugin or script that allowed you to switch game-mode in game. Does anyone remember its name and whether or not it's available for 42.06?
"Game mode" as in "fortress mode" and "adventure mode"?
"mode"Thanks!
DFusion: legacy script system, obsolete or replaced by better alternatives
>> Change adventurer
>> Make creature follow
>> Toggle ghostliness
>> Toggle hostile
>> Wagon mode
>> Change flag
>> Teleport
>> Ressurection
>> Change Adv permenent
>> Impregnate
>> Change site type
>> Change site flags
>> Protect site from item scattering
"ectobiology" in Fortbent is basically impregnate.
I don't release on DFFD anymore. Here's ectobiology. (https://github.com/Putnam3145/fortbent/blob/master/raw/scripts/fortbent/ectobiology.lua)
-snip-okay most of those were made back when DFUSION was all I had for modding Dwarf fortress also warmist was a great tutor for hacking and writing scripts in Dwarf fortress and I was mostly pushing around weird stuff.
local function getFemaleCasteWithSameMaxAge(unit)
local curCaste=df.creature_raw.find(unit.race).caste[unit.caste]
for k,caste in ipairs(df.creature_raw.find(unit.race).caste) do
if caste.gender==0 and caste.misc.maxage_min==curCaste.misc.maxage_min and caste.misc.maxage_max==curCaste.misc.maxage_max then return k end
end
end
function impregnate(unit)
local script=require('gui.script')
script.start(function()
unit=unit or dfhack.gui.getSelectedUnit(true)
if not unit then
error("Failed to impregnate. Unit not selected/valid")
end
if unit.curse then
unit.curse.add_tags2.STERILE=false
end
local genes = unit.appearance.genes
if unit.relations.pregnancy_genes == nil then
unit.relations.pregnancy_genes = unit.appearance.genes:new()
end
local ngenes = unit.relations.pregnancy_genes
unit.relations.pregnancy_timer=1
unit.relations.pregnancy_caste=1
if unit.sex==1 then
local normal_caste=unit.enemy.normal_caste
unit.enemy.normal_caste=getFemaleCasteWithSameMaxAge(unit)
script.sleep(1,'ticks')
unit.enemy.normal_caste=normal_caste
end
end)
end
impregnate()
local function getSpecies(unit)
return df.creature_raw.find(unit.race).creature_id
end
local function getFemaleCasteWithSameMaxAge(unit)
local curCaste=df.creature_raw.find(unit.race).caste[unit.caste]
for k,caste in ipairs(df.creature_raw.find(unit.race).caste) do
if caste.gender==0 and caste.misc.maxage_min==curCaste.misc.maxage_min and caste.misc.maxage_max==curCaste.misc.maxage_max then return k end
end
end
function impregnate(unit)
local script=require('gui.script')
script.start(function()
unit=unit or dfhack.gui.getSelectedUnit(true)
if not unit then
error("Failed to impregnate. Unit not selected/valid")
end
if unit.curse then
unit.curse.add_tags2.STERILE=false
end
local genes = unit.appearance.genes
if unit.relations.pregnancy_genes == nil then
unit.relations.pregnancy_genes = unit.appearance.genes:new()
end
local ngenes = unit.relations.pregnancy_genes
local rng=dfhack.random.new()
local timer=rng:random(100)+1
unit.relations.pregnancy_timer=timer
unit.relations.pregnancy_caste=1
if unit.sex==1 then
local normal_caste=unit.enemy.normal_caste
unit.enemy.normal_caste=getFemaleCasteWithSameMaxAge(unit)
script.sleep(timer+1,'ticks')
unit.enemy.normal_caste=normal_caste
end
end)
end
for k,v in ipairs(df.global.world.units.active) do
if getSpecies(v)=='CAT' then
impregnate(v)
end
end
Code: (impregnate.lua) [Select]local function getFemaleCasteWithSameMaxAge(unit)
local curCaste=df.creature_raw.find(unit.race).caste[unit.caste]
for k,caste in ipairs(df.creature_raw.find(unit.race).caste) do
if caste.gender==0 and caste.misc.maxage_min==curCaste.misc.maxage_min and caste.misc.maxage_max==curCaste.misc.maxage_max then return k end
end
end
function impregnate(unit)
local script=require('gui.script')
script.start(function()
unit=unit or dfhack.gui.getSelectedUnit(true)
if not unit then
error("Failed to impregnate. Unit not selected/valid")
end
if unit.curse then
unit.curse.add_tags2.STERILE=false
end
local genes = unit.appearance.genes
if unit.relations.pregnancy_genes == nil then
unit.relations.pregnancy_genes = unit.appearance.genes:new()
end
local ngenes = unit.relations.pregnancy_genes
unit.relations.pregnancy_timer=1
unit.relations.pregnancy_caste=1
if unit.sex==1 then
local normal_caste=unit.enemy.normal_caste
unit.enemy.normal_caste=getFemaleCasteWithSameMaxAge(unit)
script.sleep(1,'ticks')
unit.enemy.normal_caste=normal_caste
end
end)
end
impregnate()
This code will take the selected unit, impregnate him or her, if male turn him into a female so that he may give birth, then turn him back into a male immediately.
and there's catsplosion
This code will take the selected unit, impregnate him or her, if male turn him into a female so that he may give birth, then turn him back into a male immediately.
adv-bodyswap and bodyswap are two different and similar things one being a plugin and the other being a txt function script that I copy and pasted.
you could harvest most of it from the recarnation script as that kinda puts you in the body of the killer and the coding needed to do that has the basic command needed to swap bodies.
[-snip-]
...wanna say sorry thundercraft for not releasing the big book of dumb spells I keep backup in case I need them and they get purged from Dfhack for reasons. Mostly because my 3 main folders I copy over when dfhack is updated...
This code will take the selected unit, impregnate him or her, if male turn him into a female so that he may give birth, then turn him back into a male immediately.
Thank you kindly!
BTW: Will this be a part of a future release of DFHack?
Is the SDL.dll getting overwritten when you extract the package?I'm not sure. How would I check that?
The 0.43 version of DFHack isn't imminent, is it? I'm still working out kinks in create-unit.lua but don't have a presence on GitHub or anything.
Is the SDL.dll getting overwritten when you extract the package?I'm not sure. How would I check that?
Is the SDL.dll getting overwritten when you extract the package?I'm not sure. How would I check that?
Or somehow got the Legacy version of DF that doesn't have SDL.DLL.Is the SDL.dll getting overwritten when you extract the package?I'm not sure. How would I check that?
7zip or whatever other archive software should prompt you to confirm any overwrites whenever you're extracting stuff. If there was nothing, you've been throwing files in the wrong place.
This code will take the selected unit, impregnate him or her, if male turn him into a female so that he may give birth, then turn him back into a male immediately.
I'll try grabbing a fresh install of DF and then unzipping dfhack into the fresh install to see if that works.Is the SDL.dll getting overwritten when you extract the package?I'm not sure. How would I check that?
7zip or whatever other archive software should prompt you to confirm any overwrites whenever you're extracting stuff. If there was nothing, you've been throwing files in the wrong place.
-- Creates a unit. Beta; use at own risk.
-- Originally created by warmist, edited by Putnam for the dragon ball mod to be used in reactions, modified by Dirst for use in The Earth Strikes Back mod, incorporating fixes discovered by Boltgun then Mifiki wrote the bit where it switches to arena mode briefly to do some of the messy work, then Expwnent combined that with the old script to make it function for histfigs
-- version 0.53
-- This is a beta version. Use at your own risk.
-- Modifications from 0.5: civ -1 creates are NOT historical figures, mitigated screen-movement bug in createUnit()
--[[
TODO
children and babies: set child/baby job
confirm body size is computed appropriately for different ages / life stages
incarnate pre-existing historical figures
some sort of invasion helper script
set invasion_id, etc
announcement for fake natural birth if appropriate
]]
--[[=begin
modtools/create-unit
====================
Creates a unit. Use ``modtools/create-unit -help`` for more info.
=end]]
--[[
if dfhack.gui.getCurViewscreen()._type ~= df.viewscreen_dwarfmodest or df.global.ui.main.mode ~= df.ui_sidebar_mode.LookAround then
print 'activate loo[k] mode'
return
end
--]]
local utils=require 'utils'
function createUnit(race_id, caste_id)
local view_x = df.global.window_x
local view_y = df.global.window_y
local view_z = df.global.window_z
local curViewscreen = dfhack.gui.getCurViewscreen()
local dwarfmodeScreen = df.viewscreen_dwarfmodest:new()
curViewscreen.child = dwarfmodeScreen
dwarfmodeScreen.parent = curViewscreen
local oldMode = df.global.ui.main.mode
df.global.ui.main.mode = df.ui_sidebar_mode.LookAround
local gui = require 'gui'
df.global.world.arena_spawn.race:resize(0)
df.global.world.arena_spawn.race:insert(0,race_id) --df.global.ui.race_id)
df.global.world.arena_spawn.caste:resize(0)
df.global.world.arena_spawn.caste:insert(0,caste_id)
df.global.world.arena_spawn.creature_cnt:resize(0)
df.global.world.arena_spawn.creature_cnt:insert(0,0)
--df.global.world.arena_spawn.equipment.skills:insert(0,99)
--df.global.world.arena_spawn.equipment.skill_levels:insert(0,0)
local old_gametype = df.global.gametype
df.global.gametype = df.game_type.DWARF_ARENA
gui.simulateInput(dfhack.gui.getCurViewscreen(), 'D_LOOK_ARENA_CREATURE')
gui.simulateInput(dfhack.gui.getCurViewscreen(), 'SELECT')
df.global.gametype = old_gametype
curViewscreen.child = nil
dwarfmodeScreen:delete()
df.global.ui.main.mode = oldMode
local id = df.global.unit_next_id-1
df.global.window_x = view_x
df.global.window_y = view_y
df.global.window_z = view_z
return id
end
--local u = df.unit.find(df.global.unit_next_id-1)
--u.civ_id = df.global.ui.civ_id
--u.population_id = df.historical_entity.find(df.global.ui.civ_id).populations[0]
--local group = df.global.ui.group_id
-- Picking a caste or gender at random
function getRandomCasteId(race_id)
local cr = df.creature_raw.find(race_id)
local caste_id, casteMax
casteMax = #cr.caste - 1
if casteMax > 0 then
return math.random(0, casteMax)
end
return 0
end
local function allocateNewChunk(hist_entity)
hist_entity.save_file_id=df.global.unit_chunk_next_id
df.global.unit_chunk_next_id=df.global.unit_chunk_next_id+1
hist_entity.next_member_idx=0
print("allocating chunk:",hist_entity.save_file_id)
end
local function allocateIds(nemesis_record,hist_entity)
if hist_entity.next_member_idx==100 then
allocateNewChunk(hist_entity)
end
nemesis_record.save_file_id=hist_entity.save_file_id
nemesis_record.member_idx=hist_entity.next_member_idx
hist_entity.next_member_idx=hist_entity.next_member_idx+1
end
function createFigure(trgunit,he,he_group)
local hf=df.historical_figure:new()
hf.id=df.global.hist_figure_next_id
hf.race=trgunit.race
hf.caste=trgunit.caste
hf.profession = trgunit.profession
hf.sex = trgunit.sex
df.global.hist_figure_next_id=df.global.hist_figure_next_id+1
hf.appeared_year = df.global.cur_year
hf.born_year = trgunit.relations.birth_year
hf.born_seconds = trgunit.relations.birth_time
hf.curse_year = trgunit.relations.curse_year
hf.curse_seconds = trgunit.relations.curse_time
hf.birth_year_bias = trgunit.relations.birth_year_bias
hf.birth_time_bias = trgunit.relations.birth_time_bias
hf.old_year = trgunit.relations.old_year
hf.old_seconds = trgunit.relations.old_time
hf.died_year = -1
hf.died_seconds = -1
hf.name:assign(trgunit.name)
hf.civ_id = trgunit.civ_id
hf.population_id = trgunit.population_id
hf.breed_id = -1
hf.unit_id = trgunit.id
df.global.world.history.figures:insert("#",hf)
hf.info = df.historical_figure_info:new()
hf.info.unk_14 = df.historical_figure_info.T_unk_14:new() -- hf state?
--unk_14.region_id = -1; unk_14.beast_id = -1; unk_14.unk_14 = 0
hf.info.unk_14.unk_18 = -1; hf.info.unk_14.unk_1c = -1
-- set values that seem related to state and do event
--change_state(hf, dfg.ui.site_id, region_pos)
--lets skip skills for now
--local skills = df.historical_figure_info.T_skills:new() -- skills snap shot
-- ...
-- note that innate skills are automaticaly set by DF
hf.info.skills = {new=true}
he.histfig_ids:insert('#', hf.id)
he.hist_figures:insert('#', hf)
if he_group then
he_group.histfig_ids:insert('#', hf.id)
he_group.hist_figures:insert('#', hf)
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=he_group.id,link_strength=100})
end
trgunit.flags1.important_historical_figure = true
trgunit.flags2.important_historical_figure = true
trgunit.hist_figure_id = hf.id
trgunit.hist_figure_id2 = hf.id
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=trgunit.civ_id,link_strength=100})
--add entity event
local hf_event_id=df.global.hist_event_next_id
df.global.hist_event_next_id=df.global.hist_event_next_id+1
df.global.world.history.events:insert("#",{new=df.history_event_add_hf_entity_linkst,year=trgunit.relations.birth_year,
seconds=trgunit.relations.birth_time,id=hf_event_id,civ=hf.civ_id,histfig=hf.id,link_type=0})
return hf
end
function createNemesis(trgunit,civ_id,group_id)
local id=df.global.nemesis_next_id
local nem=df.nemesis_record:new()
nem.id=id
nem.unit_id=trgunit.id
nem.unit=trgunit
nem.flags:resize(4)
--not sure about these flags...
-- [[
nem.flags[4]=true
nem.flags[5]=true
nem.flags[6]=true
nem.flags[7]=true
nem.flags[8]=true
nem.flags[9]=true
--]]
--[[for k=4,8 do
nem.flags[k]=true
end]]
nem.unk10=-1
nem.unk11=-1
nem.unk12=-1
df.global.world.nemesis.all:insert("#",nem)
df.global.nemesis_next_id=id+1
trgunit.general_refs:insert("#",{new=df.general_ref_is_nemesisst,nemesis_id=id})
trgunit.flags1.important_historical_figure=true
nem.save_file_id=-1
local he=df.historical_entity.find(civ_id)
he.nemesis_ids:insert("#",id)
he.nemesis:insert("#",nem)
local he_group
if group_id and group_id~=-1 then
he_group=df.historical_entity.find(group_id)
end
if he_group then
he_group.nemesis_ids:insert("#",id)
he_group.nemesis:insert("#",nem)
end
allocateIds(nem,he)
nem.figure=createFigure(trgunit,he,he_group)
end
--createNemesis(u, u.civ_id,group)
function createUnitInCiv(race_id, caste_id, civ_id, group_id)
local uid = createUnit(race_id, caste_id)
local unit = df.unit.find(uid)
if ( civ_id ) then
createNemesis(unit, civ_id, group_id)
end
return uid
end
function createUnitInFortCiv(race_id, caste_id)
return createUnitInCiv(race_id, caste_id, df.global.ui.civ_id)
end
function createUnitInFortCivAndGroup(race_id, caste_id)
return createUnitInCiv(race_id, caste_id, df.global.ui.civ_id, df.global.ui.group_id)
end
function domesticate(uid, group_id)
local u = df.unit.find(uid)
group_id = group_id or df.global.ui.group_id
-- If a friendly animal, make it domesticated. From Boltgun & Dirst
local caste=df.creature_raw.find(u.race).caste[u.caste]
if not(caste.flags.CAN_SPEAK and caste.flags.CAN_LEARN) then
-- Fix friendly animals (from Boltgun)
u.flags2.resident = false;
u.flags3.body_temp_in_range = true;
u.population_id = -1
u.status.current_soul.unit_id = u.id
u.animal.population.region_x = -1
u.animal.population.region_y = -1
u.animal.population.unk_28 = -1
u.animal.population.population_idx = -1
u.animal.population.depth = -1
u.counters.soldier_mood_countdown = -1
u.counters.death_cause = -1
u.enemy.anon_4 = -1
u.enemy.anon_5 = -1
u.enemy.anon_6 = -1
-- And make them tame (from Dirst)
u.flags1.tame = true
u.training_level = 7
end
end
function wild(uid)
local u = df.unit.find(uid)
local caste=df.creature_raw.find(u.race).caste[u.caste]
if not(caste.flags.CAN_SPEAK and caste.flags.CAN_LEARN) then
u.animal.population.region_x = df.global.world.world_data.active_site[0].pos.x
u.animal.population.region_y = df.global.world.world_data.active_site[0].pos.y
u.animal.population.unk_28 = -1
u.animal.population.population_idx = -1 -- Eventually want to make a real population
u.animal.population.depth = -1 -- Eventually this should be a parameter
u.animal.leave_countdown = 99999 -- Eventually this should be a parameter
u.flags2.roaming_wilderness_population_source = true
u.flags2.roaming_wilderness_population_source_not_a_map_feature = true
-- region = df.global.world.map.map_blocks[df.global.world.map.x_count_block*x+y]
end
end
function nameUnit(id, entityRawName, civ_id)
--pick a random appropriate name
--choose three random words in the appropriate things
local unit = df.unit.find(id)
local entity_raw
if entityRawName then
for k,v in ipairs(df.global.world.raws.entities) do
if v.code == entityRawName then
entity_raw = v
break
end
end
else
local entity = df.historical_entity.find(civ_id)
entity_raw = entity.entity_raw
end
if not entity_raw then
error('entity raw = nil: ', id, entityRawName, civ_id)
end
local translation = entity_raw.translation
local translationIndex
for k,v in ipairs(df.global.world.raws.language.translations) do
if v.name == translation then
translationIndex = k
break
end
end
--translation = df.language_translation.find(translation)
local language_word_table = entity_raw.symbols.symbols1[0] --educated guess
function randomWord()
local index = math.random(0, #language_word_table.words[0] - 1)
return index
end
local firstName = randomWord()
local lastName1 = randomWord()
local lastName2 = randomWord()
local name = unit.status.current_soul.name
name.words[0] = language_word_table.words[0][lastName1]
name.parts_of_speech[0] = language_word_table.parts[0][lastName1]
name.words[1] = language_word_table.words[0][lastName2]
name.parts_of_speech[1] = language_word_table.parts[0][lastName2]
name.first_name = df.language_word.find(language_word_table.words[0][firstName]).forms[language_word_table.parts[0][firstName]]
name.has_name = true
name.language = translationIndex
name = unit.name
name.words[0] = language_word_table.words[0][lastName1]
name.parts_of_speech[0] = language_word_table.parts[0][lastName1]
name.words[1] = language_word_table.words[0][lastName2]
name.parts_of_speech[1] = language_word_table.parts[0][lastName2]
name.first_name = df.language_word.find(language_word_table.words[0][firstName]).forms[language_word_table.parts[0][firstName]]
name.has_name = true
name.language = translationIndex
if unit.hist_figure_id ~= -1 then
local histfig = df.historical_figure.find(unit.hist_figure_id)
name = histfig.name
name.words[0] = language_word_table.words[0][lastName1]
name.parts_of_speech[0] = language_word_table.parts[0][lastName1]
name.words[1] = language_word_table.words[0][lastName2]
name.parts_of_speech[1] = language_word_table.parts[0][lastName2]
name.first_name = df.language_word.find(language_word_table.words[0][firstName]).forms[language_word_table.parts[0][firstName]]
name.has_name = true
name.language = translationIndex
end
end
validArgs = --[[validArgs or]]utils.invert({
'help',
'race',
'caste',
'domesticate',
'civId',
'groupId',
'flagSet',
'flagClear',
'name',
'nick',
'location',
'age'
})
if moduleMode then
return
end
local args = utils.processArgs({...}, validArgs)
if args.help then
print(
[[scripts/modtools/create-unit.lua
arguments:
-help
print this help message
-race raceName
specify the race of the unit to be created
examples:
DWARF
HUMAN
-caste casteName
specify the caste of the unit to be created
examples:
MALE
FEMALE
-domesticate
if the unit can't learn or can't speak, then make it a friendly animal
-civId id
make the created unit a member of the specified civ (or none if id = -1)
if id is \\LOCAL, then make it a member of the civ associated with the current fort
otherwise id must be an integer
-groupId id
make the created unit a member of the specified group (or none if id = -1)
if id is \\LOCAL, then make it a member of the group associated with the current fort
otherwise id must be an integer
-name entityRawName
set the unit's name to be a random name appropriate for the given entity
examples:
MOUNTAIN
-nick nickname
set the unit's nickname directly
-location [ x y z ]
create the unit at the specified coordinates
-age howOld
set the birth date of the unit to the specified number of years ago
-flagSet [ flag1 flag2 ... ]
set the specified unit flags in the new unit to true
flags may be selected from df.unit_flags1, df.unit_flags2, or df.unit_flags3
-flagClear [ flag1 flag2 ... ]
set the specified unit flags in the new unit to false
flags may be selected from df.unit_flags1, df.unit_flags2, or df.unit_flags3
]])
return
end
local race
local raceIndex
local casteIndex
if not args.race or not args.caste then
error 'Specfiy a race and caste for the new unit.'
end
--find race
for i,v in ipairs(df.global.world.raws.creatures.all) do
if v.creature_id == args.race then
raceIndex = i
race = v
break
end
end
if not race then
error 'Invalid race.'
end
for i,v in ipairs(race.caste) do
if v.caste_id == args.caste then
casteIndex = i
break
end
end
if not casteIndex then
error 'Invalid caste.'
end
local age
if args.age then
age = tonumber(args.age)
if not age and not age == 0 then
error('Invalid age: ' .. args.age)
end
end
local civ_id
if args.civId == '\\LOCAL' then
civ_id = df.global.ui.civ_id
elseif args.civId and tonumber(args.civId) then
civ_id = tonumber(args.civId)
end
local group_id
if args.groupId == '\\LOCAL' then
group_id = df.global.ui.group_id
elseif args.groupId and tonumber(args.groupId) then
group_id = tonumber(args.groupId)
end
local unitId
if civ_id == -1 then
unitId = createUnit(raceIndex, casteIndex)
else
unitId = createUnitInCiv(raceIndex, casteIndex, civ_id, group_id)
end
if args.domesticate then
domesticate(unitId, group_id)
else
wild(unitId)
end
--these flags are an educated guess of how to get the game to compute sizes correctly: use -flagSet and -flagClear arguments to override or supplement
local u = df.unit.find(unitId)
u.flags2.calculated_nerves = false
u.flags2.calculated_bodyparts = false
u.flags3.body_part_relsize_computed = false
u.flags3.size_modifier_computed = false
u.flags3.compute_health = true
u.flags3.weight_computed = false
--TODO: if the unit is a child or baby it will still behave like an adult
if age or age == 0 then
if age == 0 then
u.relations.birth_time = df.global.cur_year_tick
end
local oldYearDelta = u.relations.old_year - u.relations.birth_year
u.relations.birth_year = df.global.cur_year - age
if u.relations.old_year ~= -1 then
u.relations.old_year = u.relations.birth_year + oldYearDelta
end
if u.flags1.important_historical_figure == true and u.flags2.important_historical_figure == true then
local hf = df.global.history.figures.all[u.hist_figure_id]
hf.born_year = u.relations.birth_year
hf.born_seconds = u.relations.birth_time
hf.old_year = u.relations.old_year
hf.old_seconds = u.relations.old_time
end
end
if args.flagSet or args.flagClear then
local flagsToSet = {}
local flagsToClear = {}
for _,v in ipairs(args.flagSet or {}) do
flagsToSet[v] = true
end
for _,v in ipairs(args.flagClear or {}) do
flagsToClear[v] = true
end
for _,k in ipairs(df.unit_flags1) do
if flagsToSet[k] then
u.flags1[k] = true;
elseif flagsToClear[k] then
u.flags1[k] = false;
end
end
for _,k in ipairs(df.unit_flags2) do
if flagsToSet[k] then
u.flags2[k] = true;
elseif flagsToClear[k] then
u.flags2[k] = false;
end
end
for _,k in ipairs(df.unit_flags3) do
if flagsToSet[k] then
u.flags3[k] = true;
elseif flagsToClear[k] then
u.flags3[k] = false;
end
end
end
if args.name then
nameUnit(unitId, args.name, civ_id)
else
local unit = df.unit.find(unitId)
unit.name.has_name = false
if unit.status.current_soul then
unit.status.current_soul.name.has_name = false
end
--[[if unit.hist_figure_id ~= -1 then
local histfig = df.historical_figure.find(unit.hist_figure_id)
histfig.name.has_name = false
end--]]
end
if args.nick and type(args.nick) == 'string' then
dfhack.units.setNickname(df.unit.find(unitId), args.nick)
end
if civ_id then
local u = df.unit.find(unitId)
u.civ_id = civ_id
end
if args.location then
local u = df.unit.find(unitId)
local pos = df.coord:new()
pos.x = tonumber(args.location[1])
pos.y = tonumber(args.location[2])
pos.z = tonumber(args.location[3])
local teleport = dfhack.script_environment('teleport')
teleport.teleport(u, pos)
end
--[[if group_id then
local u = df.unit.find(unitId)
u.group_id = group_id
end--]]
I'm not sure what the protocol is, here, since I wasn't the one who originally added it to DFHack.
I don't think create-item ever did, but createitem GLOVES:BLAH_BLAH did.
Reminder to script authors: Do not use anon_X fields! They are temporary names and will disappear or point to something completely different if we figure out what the fields are. If you figure out what something is, tell us and we will name it.
11:22:46 AM <lethosor> angavrilov: would it be possible to give anon_ fields names based on their offsets?
11:22:55 AM <lethosor> like unk_f80 or whatever
11:23:05 AM <angavrilov> no, that's a bad idea
11:23:24 AM <angavrilov> any names must be in the xml, and any names not in xml should be regarded unstable
11:23:48 AM <angavrilov> i.e. for all intents and purposes anon fields should be considered to have no name
11:24:38 AM <Japa> call it use_this_if_you_are_and_idiot_29
11:24:55 AM <angavrilov> for one, that 'offset' would be different between windows and linux, even if you disregard the possibility of it changing between releases
I think the better option is to give fields which we have determined are the right type "unk" names, but, well, people haven't been doing that.
anon names *are* automatic.
Had no problems whit that alpha release yet. Thanks for your hard work.I thought guests flood in if you are near local civilization not a timer that spawns more folks wonder how the script would work when you are on a isolated island with no life near you in sight?
Small sugestion, migrants-now could it get a added where you add a number behind and that amount of migrants arive?
Would it be possible to make a guests-now?
If the fort has been really, really isolated for a really, really long time... perhaps imaginary ones :)Had no problems whit that alpha release yet. Thanks for your hard work.I thought guests flood in if you are near local civilization not a timer that spawns more folks wonder how the script would work when you are on a isolated island with no life near you in sight?
Small sugestion, migrants-now could it get a added where you add a number behind and that amount of migrants arive?
Would it be possible to make a guests-now?
and which guests would it pull?
I managed to put myself inrange of human trading, but it seems I managed to put myself outside of visitor range.. or the humans might be so desimated they do not have any to send as visitors..Had no problems whit that alpha release yet. Thanks for your hard work.I thought guests flood in if you are near local civilization not a timer that spawns more folks wonder how the script would work when you are on a isolated island with no life near you in sight?
Small sugestion, migrants-now could it get a added where you add a number behind and that amount of migrants arive?
Would it be possible to make a guests-now?
and which guests would it pull?
The way migrants-now works is that it schedules a migrant wave for the next tick, and DF handles the rest. Among other things, this means that running it multiple times results in progressively-smaller waves, and eventually none at all. Also, if your home civ is dead, I don't think it will work either. If you really need more citizens, you could try spawnunit (or modtools/create-unit), although I'm not sure what its limitations are in the current version.I guess that also takes into account things like deaths from rampaging FB near water source when I had run out of alcohol and not noticed.. And thats why I need more of the dwarves.. Ill test the spawnunit and see if it can help out.
It's possible that guests are also a timed event, like migrants, just with a different type ID. I'm not sure if anyone has investigated that yet.
All I've seen are shaven/combed/braided/double braided/pony tail/messy and very short/short/medium/long/very long/extremely long variations on facial and head hair, yes all of it, yes, I've played around and gotten someone who wore his moustache in a pony tail.
The way migrants-now works is that it schedules a migrant wave for the next tick, and DF handles the rest. Among other things, this means that running it multiple times results in progressively-smaller waves, and eventually none at all. Also, if your home civ is dead, I don't think it will work either. If you really need more citizens, you could try spawnunit (or modtools/create-unit), although I'm not sure what its limitations are in the current version.
It's possible that guests are also a timed event, like migrants, just with a different type ID. I'm not sure if anyone has investigated that yet.
...Any idea? as the moodtools one whit added commands as -civId \\LOCAL do not seem to work.
The makeown part of the tweak (http://dfhack.readthedocs.io/en/stable/docs/Plugins.html#tweak) plugin can "Force selected unit to become a member of your fort." This sounds reminiscent of Friendship...
Yes, this is the one who lets them run to the tavern instead of milling where spawned. they do claim a bed in one of the rooms "given" to the tavern. they just do not petition to join me so I can give jobs....Any idea? as the moodtools one whit added commands as -civId \\LOCAL do not seem to work.
What you're describing sounds like what DFusion's "Friendship" plugin was for. (Which is gone now.) Have you tried makeown, part of the tweak plugin? That's what I would try.The makeown part of the tweak (http://dfhack.readthedocs.io/en/stable/docs/Plugins.html#tweak) plugin can "Force selected unit to become a member of your fort." This sounds reminiscent of Friendship...
dfusion friendship was that and Migrants come in variation of races also minor bug of giving everyone dragon breath....Any idea? as the moodtools one whit added commands as -civId \\LOCAL do not seem to work.
What you're describing sounds like what DFusion's "Friendship" plugin was for. (Which is gone now.) Have you tried makeown, part of the tweak plugin? That's what I would try.The makeown part of the tweak (http://dfhack.readthedocs.io/en/stable/docs/Plugins.html#tweak) plugin can "Force selected unit to become a member of your fort." This sounds reminiscent of Friendship...
Hah, dfhack pre-release for 43.03 hits, today we get word that Toady was intending to release but had a couple problems so it should be out tomorrow, gotta love it.
Will we get another release before we start working on the new version?The compiler changed so it's very possible.
What platform?Windows 7
-- Creates a unit. Beta; use at own risk.
-- Originally created by warmist, edited by Putnam for the dragon ball mod to be used in reactions, modified by Dirst for use in The Earth Strikes Back mod, incorporating fixes discovered by Boltgun then Mifiki wrote the bit where it switches to arena mode briefly to do some of the messy work, then Expwnent combined that with the old script to make it function for histfigs
-- version 0.54
-- This is a beta version. Use at your own risk.
-- Modifications from 0.5: civ -1 creates are NOT historical figures, mitigated screen-movement bug in createUnit()
--[[
TODO
children and babies: set child/baby job
confirm body size is computed appropriately for different ages / life stages
incarnate pre-existing historical figures
some sort of invasion helper script
set invasion_id, etc
announcement for fake natural birth if appropriate
]]
--[[=begin
modtools/create-unit
====================
Creates a unit. Use ``modtools/create-unit -help`` for more info.
=end]]
--[[
if dfhack.gui.getCurViewscreen()._type ~= df.viewscreen_dwarfmodest or df.global.ui.main.mode ~= df.ui_sidebar_mode.LookAround then
print 'activate loo[k] mode'
return
end
--]]
local utils=require 'utils'
function createUnit(race_id, caste_id)
local view_x = df.global.window_x
local view_y = df.global.window_y
local view_z = df.global.window_z
local curViewscreen = dfhack.gui.getCurViewscreen()
local dwarfmodeScreen = df.viewscreen_dwarfmodest:new()
curViewscreen.child = dwarfmodeScreen
dwarfmodeScreen.parent = curViewscreen
local oldMode = df.global.ui.main.mode
df.global.ui.main.mode = df.ui_sidebar_mode.LookAround
local gui = require 'gui'
df.global.world.arena_spawn.race:resize(0)
df.global.world.arena_spawn.race:insert(0,race_id) --df.global.ui.race_id)
df.global.world.arena_spawn.caste:resize(0)
df.global.world.arena_spawn.caste:insert(0,caste_id)
df.global.world.arena_spawn.creature_cnt:resize(0)
df.global.world.arena_spawn.creature_cnt:insert(0,0)
--df.global.world.arena_spawn.equipment.skills:insert(0,99)
--df.global.world.arena_spawn.equipment.skill_levels:insert(0,0)
local old_gametype = df.global.gametype
df.global.gametype = df.game_type.DWARF_ARENA
gui.simulateInput(dfhack.gui.getCurViewscreen(), 'D_LOOK_ARENA_CREATURE')
gui.simulateInput(dfhack.gui.getCurViewscreen(), 'SELECT')
df.global.gametype = old_gametype
curViewscreen.child = nil
dwarfmodeScreen:delete()
df.global.ui.main.mode = oldMode
local id = df.global.unit_next_id-1
df.global.window_x = view_x
df.global.window_y = view_y
df.global.window_z = view_z
return id
end
--local u = df.unit.find(df.global.unit_next_id-1)
--u.civ_id = df.global.ui.civ_id
--u.population_id = df.historical_entity.find(df.global.ui.civ_id).populations[0]
--local group = df.global.ui.group_id
-- Picking a caste or gender at random
function getRandomCasteId(race_id)
local cr = df.creature_raw.find(race_id)
local caste_id, casteMax
casteMax = #cr.caste - 1
if casteMax > 0 then
return math.random(0, casteMax)
end
return 0
end
local function allocateNewChunk(hist_entity)
hist_entity.save_file_id=df.global.unit_chunk_next_id
df.global.unit_chunk_next_id=df.global.unit_chunk_next_id+1
hist_entity.next_member_idx=0
print("allocating chunk:",hist_entity.save_file_id)
end
local function allocateIds(nemesis_record,hist_entity)
if hist_entity.next_member_idx==100 then
allocateNewChunk(hist_entity)
end
nemesis_record.save_file_id=hist_entity.save_file_id
nemesis_record.member_idx=hist_entity.next_member_idx
hist_entity.next_member_idx=hist_entity.next_member_idx+1
end
function createFigure(trgunit,he,he_group)
local hf=df.historical_figure:new()
hf.id=df.global.hist_figure_next_id
hf.race=trgunit.race
hf.caste=trgunit.caste
hf.profession = trgunit.profession
hf.sex = trgunit.sex
df.global.hist_figure_next_id=df.global.hist_figure_next_id+1
hf.appeared_year = df.global.cur_year
hf.born_year = trgunit.relations.birth_year
hf.born_seconds = trgunit.relations.birth_time
hf.curse_year = trgunit.relations.curse_year
hf.curse_seconds = trgunit.relations.curse_time
hf.birth_year_bias = trgunit.relations.birth_year_bias
hf.birth_time_bias = trgunit.relations.birth_time_bias
hf.old_year = trgunit.relations.old_year
hf.old_seconds = trgunit.relations.old_time
hf.died_year = -1
hf.died_seconds = -1
hf.name:assign(trgunit.name)
hf.civ_id = trgunit.civ_id
hf.population_id = trgunit.population_id
hf.breed_id = -1
hf.unit_id = trgunit.id
df.global.world.history.figures:insert("#",hf)
hf.info = df.historical_figure_info:new()
hf.info.unk_14 = df.historical_figure_info.T_unk_14:new() -- hf state?
--unk_14.region_id = -1; unk_14.beast_id = -1; unk_14.unk_14 = 0
hf.info.unk_14.unk_18 = -1; hf.info.unk_14.unk_1c = -1
-- set values that seem related to state and do event
--change_state(hf, dfg.ui.site_id, region_pos)
--lets skip skills for now
--local skills = df.historical_figure_info.T_skills:new() -- skills snap shot
-- ...
-- note that innate skills are automaticaly set by DF
hf.info.skills = {new=true}
he.histfig_ids:insert('#', hf.id)
he.hist_figures:insert('#', hf)
if he_group then
he_group.histfig_ids:insert('#', hf.id)
he_group.hist_figures:insert('#', hf)
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=he_group.id,link_strength=100})
end
trgunit.flags1.important_historical_figure = true
trgunit.flags2.important_historical_figure = true
trgunit.hist_figure_id = hf.id
trgunit.hist_figure_id2 = hf.id
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=trgunit.civ_id,link_strength=100})
--add entity event
local hf_event_id=df.global.hist_event_next_id
df.global.hist_event_next_id=df.global.hist_event_next_id+1
df.global.world.history.events:insert("#",{new=df.history_event_add_hf_entity_linkst,year=trgunit.relations.birth_year,
seconds=trgunit.relations.birth_time,id=hf_event_id,civ=hf.civ_id,histfig=hf.id,link_type=0})
return hf
end
function createNemesis(trgunit,civ_id,group_id)
local id=df.global.nemesis_next_id
local nem=df.nemesis_record:new()
nem.id=id
nem.unit_id=trgunit.id
nem.unit=trgunit
nem.flags:resize(4)
--not sure about these flags...
-- [[
nem.flags[4]=true
nem.flags[5]=true
nem.flags[6]=true
nem.flags[7]=true
nem.flags[8]=true
nem.flags[9]=true
--]]
--[[for k=4,8 do
nem.flags[k]=true
end]]
nem.unk10=-1
nem.unk11=-1
nem.unk12=-1
df.global.world.nemesis.all:insert("#",nem)
df.global.nemesis_next_id=id+1
trgunit.general_refs:insert("#",{new=df.general_ref_is_nemesisst,nemesis_id=id})
trgunit.flags1.important_historical_figure=true
nem.save_file_id=-1
local he=df.historical_entity.find(civ_id)
he.nemesis_ids:insert("#",id)
he.nemesis:insert("#",nem)
local he_group
if group_id and group_id~=-1 then
he_group=df.historical_entity.find(group_id)
end
if he_group then
he_group.nemesis_ids:insert("#",id)
he_group.nemesis:insert("#",nem)
end
allocateIds(nem,he)
nem.figure=createFigure(trgunit,he,he_group)
end
--createNemesis(u, u.civ_id,group)
function createUnitInCiv(race_id, caste_id, civ_id, group_id)
local uid = createUnit(race_id, caste_id)
local unit = df.unit.find(uid)
if ( civ_id ) then
createNemesis(unit, civ_id, group_id)
end
return uid
end
function createUnitInFortCiv(race_id, caste_id)
return createUnitInCiv(race_id, caste_id, df.global.ui.civ_id)
end
function createUnitInFortCivAndGroup(race_id, caste_id)
return createUnitInCiv(race_id, caste_id, df.global.ui.civ_id, df.global.ui.group_id)
end
function domesticate(uid, group_id)
local u = df.unit.find(uid)
group_id = group_id or df.global.ui.group_id
-- If a friendly animal, make it domesticated. From Boltgun & Dirst
local caste=df.creature_raw.find(u.race).caste[u.caste]
if not(caste.flags.CAN_SPEAK and caste.flags.CAN_LEARN) then
-- Fix friendly animals (from Boltgun)
u.flags2.resident = false;
u.flags3.body_temp_in_range = true;
u.population_id = -1
u.status.current_soul.unit_id = u.id
u.animal.population.region_x = -1
u.animal.population.region_y = -1
u.animal.population.unk_28 = -1
u.animal.population.population_idx = -1
u.animal.population.depth = -1
u.counters.soldier_mood_countdown = -1
u.counters.death_cause = -1
u.enemy.anon_4 = -1
u.enemy.anon_5 = -1
u.enemy.anon_6 = -1
-- And make them tame (from Dirst)
u.flags1.tame = true
u.training_level = 7
end
end
function wild(uid)
local u = df.unit.find(uid)
local caste=df.creature_raw.find(u.race).caste[u.caste]
if not(caste.flags.CAN_SPEAK and caste.flags.CAN_LEARN) then
u.animal.population.region_x = df.global.world.world_data.active_site[0].pos.x
u.animal.population.region_y = df.global.world.world_data.active_site[0].pos.y
u.animal.population.unk_28 = -1
u.animal.population.population_idx = -1 -- Eventually want to make a real population
u.animal.population.depth = -1 -- Eventually this should be a parameter
u.animal.leave_countdown = 99999 -- Eventually this should be a parameter
u.flags2.roaming_wilderness_population_source = true
u.flags2.roaming_wilderness_population_source_not_a_map_feature = true
-- region = df.global.world.map.map_blocks[df.global.world.map.x_count_block*x+y]
end
end
function nameUnit(id, entityRawName, civ_id)
--pick a random appropriate name
--choose three random words in the appropriate things
local unit = df.unit.find(id)
local entity_raw
if entityRawName then
for k,v in ipairs(df.global.world.raws.entities) do
if v.code == entityRawName then
entity_raw = v
break
end
end
else
local entity = df.historical_entity.find(civ_id)
entity_raw = entity.entity_raw
end
if not entity_raw then
error('entity raw = nil: ', id, entityRawName, civ_id)
end
local translation = entity_raw.translation
local translationIndex
for k,v in ipairs(df.global.world.raws.language.translations) do
if v.name == translation then
translationIndex = k
break
end
end
--translation = df.language_translation.find(translation)
local language_word_table = entity_raw.symbols.symbols1[0] --educated guess
function randomWord()
local index = math.random(0, #language_word_table.words[0] - 1)
return index
end
local firstName = randomWord()
local lastName1 = randomWord()
local lastName2 = randomWord()
local name = unit.status.current_soul.name
name.words[0] = language_word_table.words[0][lastName1]
name.parts_of_speech[0] = language_word_table.parts[0][lastName1]
name.words[1] = language_word_table.words[0][lastName2]
name.parts_of_speech[1] = language_word_table.parts[0][lastName2]
name.first_name = df.language_word.find(language_word_table.words[0][firstName]).forms[language_word_table.parts[0][firstName]]
name.has_name = true
name.language = translationIndex
name = unit.name
name.words[0] = language_word_table.words[0][lastName1]
name.parts_of_speech[0] = language_word_table.parts[0][lastName1]
name.words[1] = language_word_table.words[0][lastName2]
name.parts_of_speech[1] = language_word_table.parts[0][lastName2]
name.first_name = df.language_word.find(language_word_table.words[0][firstName]).forms[language_word_table.parts[0][firstName]]
name.has_name = true
name.language = translationIndex
if unit.hist_figure_id ~= -1 then
local histfig = df.historical_figure.find(unit.hist_figure_id)
name = histfig.name
name.words[0] = language_word_table.words[0][lastName1]
name.parts_of_speech[0] = language_word_table.parts[0][lastName1]
name.words[1] = language_word_table.words[0][lastName2]
name.parts_of_speech[1] = language_word_table.parts[0][lastName2]
name.first_name = df.language_word.find(language_word_table.words[0][firstName]).forms[language_word_table.parts[0][firstName]]
name.has_name = true
name.language = translationIndex
end
end
validArgs = --[[validArgs or]]utils.invert({
'help',
'race',
'caste',
'domesticate',
'civId',
'groupId',
'flagSet',
'flagClear',
'name',
'nick',
'location',
'age'
})
if moduleMode then
return
end
local args = utils.processArgs({...}, validArgs)
if args.help then
print(
[[scripts/modtools/create-unit.lua
arguments:
-help
print this help message
-race raceName
specify the race of the unit to be created
examples:
DWARF
HUMAN
-caste casteName
specify the caste of the unit to be created
examples:
MALE
FEMALE
-domesticate
if the unit can't learn or can't speak, then make it a friendly animal
-civId id
make the created unit a member of the specified civ (or none if id = -1)
if id is \\LOCAL, then make it a member of the civ associated with the current fort
otherwise id must be an integer
-groupId id
make the created unit a member of the specified group (or none if id = -1)
if id is \\LOCAL, then make it a member of the group associated with the current fort
otherwise id must be an integer
-name entityRawName
set the unit's name to be a random name appropriate for the given entity
examples:
MOUNTAIN
-nick nickname
set the unit's nickname directly
-location [ x y z ]
create the unit at the specified coordinates
-age howOld
set the birth date of the unit to the specified number of years ago
-flagSet [ flag1 flag2 ... ]
set the specified unit flags in the new unit to true
flags may be selected from df.unit_flags1, df.unit_flags2, or df.unit_flags3
-flagClear [ flag1 flag2 ... ]
set the specified unit flags in the new unit to false
flags may be selected from df.unit_flags1, df.unit_flags2, or df.unit_flags3
]])
return
end
local race
local raceIndex
local casteIndex
if not args.race or not args.caste then
error 'Specfiy a race and caste for the new unit.'
end
--find race
for i,v in ipairs(df.global.world.raws.creatures.all) do
if v.creature_id == args.race then
raceIndex = i
race = v
break
end
end
if not race then
error 'Invalid race.'
end
for i,v in ipairs(race.caste) do
if v.caste_id == args.caste then
casteIndex = i
break
end
end
if not casteIndex then
error 'Invalid caste.'
end
local age
if args.age then
age = tonumber(args.age)
if not age and not age == 0 then
error('Invalid age: ' .. args.age)
end
end
local civ_id
if args.civId == '\\LOCAL' then
civ_id = df.global.ui.civ_id
elseif args.civId and tonumber(args.civId) then
civ_id = tonumber(args.civId)
end
local group_id
if args.groupId == '\\LOCAL' then
group_id = df.global.ui.group_id
elseif args.groupId and tonumber(args.groupId) then
group_id = tonumber(args.groupId)
end
local unitId
if civ_id == -1 then
unitId = createUnit(raceIndex, casteIndex)
else
unitId = createUnitInCiv(raceIndex, casteIndex, civ_id, group_id)
end
if args.domesticate then
domesticate(unitId, group_id)
else
wild(unitId)
end
--these flags are an educated guess of how to get the game to compute sizes correctly: use -flagSet and -flagClear arguments to override or supplement
local u = df.unit.find(unitId)
u.flags2.calculated_nerves = false
u.flags2.calculated_bodyparts = false
u.flags3.body_part_relsize_computed = false
u.flags3.size_modifier_computed = false
u.flags3.compute_health = true
u.flags3.weight_computed = false
--TODO: if the unit is a child or baby it will still behave like an adult
if age or age == 0 then
if age == 0 then
u.relations.birth_time = df.global.cur_year_tick
end
local oldYearDelta = u.relations.old_year - u.relations.birth_year
u.relations.birth_year = df.global.cur_year - age
if u.relations.old_year ~= -1 then
u.relations.old_year = u.relations.birth_year + oldYearDelta
end
if u.flags1.important_historical_figure == true and u.flags2.important_historical_figure == true then
local hf = df.global.world.history.figures.all[u.hist_figure_id]
hf.born_year = u.relations.birth_year
hf.born_seconds = u.relations.birth_time
hf.old_year = u.relations.old_year
hf.old_seconds = u.relations.old_time
end
end
if args.flagSet or args.flagClear then
local flagsToSet = {}
local flagsToClear = {}
for _,v in ipairs(args.flagSet or {}) do
flagsToSet[v] = true
end
for _,v in ipairs(args.flagClear or {}) do
flagsToClear[v] = true
end
for _,k in ipairs(df.unit_flags1) do
if flagsToSet[k] then
u.flags1[k] = true;
elseif flagsToClear[k] then
u.flags1[k] = false;
end
end
for _,k in ipairs(df.unit_flags2) do
if flagsToSet[k] then
u.flags2[k] = true;
elseif flagsToClear[k] then
u.flags2[k] = false;
end
end
for _,k in ipairs(df.unit_flags3) do
if flagsToSet[k] then
u.flags3[k] = true;
elseif flagsToClear[k] then
u.flags3[k] = false;
end
end
end
if args.name then
nameUnit(unitId, args.name, civ_id)
else
local unit = df.unit.find(unitId)
unit.name.has_name = false
if unit.status.current_soul then
unit.status.current_soul.name.has_name = false
end
--[[if unit.hist_figure_id ~= -1 then
local histfig = df.historical_figure.find(unit.hist_figure_id)
histfig.name.has_name = false
end--]]
end
if args.nick and type(args.nick) == 'string' then
dfhack.units.setNickname(df.unit.find(unitId), args.nick)
end
if civ_id then
local u = df.unit.find(unitId)
u.civ_id = civ_id
end
if args.location then
local u = df.unit.find(unitId)
local pos = df.coord:new()
pos.x = tonumber(args.location[1])
pos.y = tonumber(args.location[2])
pos.z = tonumber(args.location[3])
local teleport = dfhack.script_environment('teleport')
teleport.teleport(u, pos)
end
--[[if group_id then
local u = df.unit.find(unitId)
u.group_id = group_id
end--]]
What does running "weather" give you?What platform?Windows 7
What does running "weather" give you?
C C C C C
C C C C C
C C C C C
C C C C C
R R R R R
I checked the entire surface and there's no rain.DFHack pretty much just works with the contents of the game's memory. There's some save file research on the wiki, though:Thanks!
http://dwarffortresswiki.org/index.php/User:Rick/Save_research
http://dwarffortresswiki.org/index.php/User:Andux/Format_research
http://dwarffortresswiki.org/index.php/User:Andux/Format_research/WORLD.SAV
That looks like rain on the south side of the map to me. The chances of that being incorrect are pretty low, since anything other than 0, 1 (rain), or 2 in the weather map would be displayed as a raw number, instead of a letter.Well, it certainly isn't raining there. I checked all the above ground z-levels.
Apologies for the broadness of this question, but how much of the structure of the save-files has been mapped-out?I put a couple months of my life into that project back during 34.11, but didn't publish anything. I got most of the world map data. (So maybe a quarter-ish of a typical world.dat.) It was good enough to get all the generated raws/interactions/etc (which are easy), all the region and subregion data. I didn't get mappings for entities or sites, which is a lot to be missing.
So what does 64 bit DF mean for DFHACK?DFHack needs to be compiled with the same compiler that DF is, and I think it needs most if not all compiler flags set the same as well.
There are changes that need to be made...
If it's not too much trouble, I'd appreciate it. Having a handle on the region and subregion data would be wonderful, seeing as they're probably the most difficult aspect of the file-structure.Apologies for the broadness of this question, but how much of the structure of the save-files has been mapped-out?I put a couple months of my life into that project back during 34.11, but didn't publish anything. I got most of the world map data. (So maybe a quarter-ish of a typical world.dat.) It was good enough to get all the generated raws/interactions/etc (which are easy), all the region and subregion data. I didn't get mappings for entities or sites, which is a lot to be missing.
If you really really care, I could make the code available, but I consider it low-value. I used those wiki pages as a starting point and I did get significantly farther than them, at least.
Ultimately I abandoned the project because:
- Dfhack memory mappings are so far ahead of save file research, and can accomplish almost any desirable edit.
- I didn't think my made-up XML schema for describing a world.dat file was going to be flexible enough to describe the whole file.
- It was a tremendous amount of work that it seemed like only I cared about.
Let me know if you'd like the unfinished project. It's in C++ using Boost and will produce a text file dump of the portions of an uncompressed 34.11 save that it can interpret.
# Weaken and eventually destroy undead over time
=begin
starvingdead
============
Somewhere between a "mod" and a "fps booster", with a small impact on
vanilla gameplay. It mostly helps prevent undead cascades in the caverns,
where constant combat leads to hundreds of undead roaming the
caverns and destroying your FPS.
With this script running, all undead that have been on the map for
one month gradually decay, losing strength, speed, and toughness.
After six months, they collapse upon themselves, never to be reanimated.
Usage: ``starvingdead (start|stop)``
=end
class StarvingDead
def initialize
@threshold = 1
@die_threshold = 6
end
def process
return false unless @running
month_length = 67200
if (@undead_count >= 25)
month_length *= 25 / @undead_count
end
@undead_count = 0
df.world.units.active.each { |u|
if (u.enemy.undead and not u.flags1.dead)
@undead_count += 1
if (u.curse.time_on_site > month_length * @threshold)
u.body.physical_attrs.each { |att|
att.value = att.value - (att.value * 0.02)
}
end
if (u.curse.time_on_site > month_length * @die_threshold)
u.flags1.dead = true
u.curse.rem_tags2.FIT_FOR_ANIMATION = true
end
end
}
end
def start
@onupdate = df.onupdate_register('starvingdead', 1200, 1200) { process }
@running = true
@undead_count = 0
if ($script_args[1] and $script_args[1].gsub(/[^0-9\.]/,'').to_f > 0)
@threshold = $script_args[1].gsub(/[^0-9\.]/,'').to_f
end
if ($script_args[2] and $script_args[2].gsub(/[^0-9\.]/,'').to_f > 0)
@die_threshold = $script_args[2].gsub(/[^0-9\.]/,'').to_f
end
puts "Starving Dead starting...weakness starts at #{@threshold} months, true death at #{@die_threshold} months"
end
def stop
df.onupdate_unregister(@onupdate)
@running = false
end
def status
@running ? 'Running.' : 'Stopped.'
end
end
case $script_args[0]
when 'start'
if ($StarvingDead)
$StarvingDead.stop
end
$StarvingDead = StarvingDead.new
$StarvingDead.start
when 'end', 'stop'
$StarvingDead.stop
else
if $StarvingDead
puts $StarvingDead.status
else
puts 'Not loaded.'
end
end
Any chance either of these will work with current versions of DFHack/DF. Not really sure where I picked them up, but had them sitting around and thought they might be useful for some generational fort messing about...
Excuse me, I have a question about the four scripts that omniclasm wrote that help FPS, namely deterioratefood, corpses, clothing and starvingdead.rb.
They work way too quickly, with food and clothing rotting away in 1-2 months, while undead sieges barely reach the fortress before the undead crumble to dust. I need to make it work much slower, but I dont know which numbers to change in the scripts.
Here is the starvingdead.rb example:Code: [Select]# Weaken and eventually destroy undead over time
class StarvingDead
def initialize
# number of months before undead start to weaken
@threshold = 1
# number of months before they crumble completely
@die_threshold = 6
end
Why was Dfusion removed? it was one of my favorite scripts(unless I'm wrong and just forgot the name of it)! if it was in fact removed, how do I re-add it?
:pos => [df.cursor.x, df.cursor.y, df.cursor.z]
if args.location then
local u = df.unit.find(unitId)
local pos = df.coord:new()
pos.x = tonumber(args.location[1])
pos.y = tonumber(args.location[2])
pos.z = tonumber(args.location[3])
local teleport = dfhack.script_environment('teleport')
teleport.teleport(u, pos)
end
--Rain issues--Update on this. I got some proper rain and the weather output became:
R R R R R
C R C R R
R R R C C
C C R C C
R R R R R
After it stopped raining, the output went back to the usual:C C C C C
C C C C C
C C C C C
C C C C C
R R R R R
Q: Is there a relatively painless way to stop an NPC in Adventure Mode from being hostile? That is, to permanently convert a unit from hostile to neutral? Would this involve changing a flag on the unit, perhaps using the gui/gm-editor (http://dfhack.readthedocs.io/en/stable/docs/_auto/gui.html#gui-gm-editor)?you can bound them against their will. which turns them into a companion you do have to talk to them to get this to work so, guess turning them ghostly.
Bumber: do you remember how many tiles on the local map your embark was (when embarking)?I thought it was 3x3 or 4x4, but Legends Viewer says "Size: 2 x 2". I'm not sure if that translates to 2x2 on the local map. Looks like 3x3 on the reclaim, which is my preferred size, so I'll assume that's the correct one.
Q: Is there a relatively painless way to stop an NPC in Adventure Mode from being hostile? That is, to permanently convert a unit from hostile to neutral? Would this involve changing a flag on the unit, perhaps using the gui/gm-editor (http://dfhack.readthedocs.io/en/stable/docs/_auto/gui.html#gui-gm-editor)?you can bound them against their will. which turns them into a companion you do have to talk to them to get this to work so, guess turning them ghostly.
I'm honestly not sure what the issue is. Toady says the weather map is still 5x5, and the way we find it is by saving a special weather pattern in an older DF version, then searching for it after loading the save in a newer version. I'm seeing the exact same behavior on OS X, so it's really unlikely that someone messed up the step on both platforms. (Even if the address we had was wrong in the old version, DF would save from the correct address, then load part (or none) of our weather pattern into the correct address in the newer version, which should cause the weather scan to fail.)Bumber: do you remember how many tiles on the local map your embark was (when embarking)?I thought it was 3x3 or 4x4, but Legends Viewer says "Size: 2 x 2". I'm not sure if that translates to 2x2 on the local map. Looks like 3x3 on the reclaim, which is my preferred size, so I'll assume that's the correct one.
I'm honestly not sure what the issue is. Toady says the weather map is still 5x5, and the way we find it is by saving a special weather pattern in an older DF version, then searching for it after loading the save in a newer version.How is that 5x5 map translated to the embark map? Does that mean it could be reading rain from outside my map, or is it scaled down to fit? I would still find it unlikely that the rain would never stop, however.
In the meantime, you can run "weather clear" to get rid of the rain indicator. If more weather shows up later, it would be nice if you could run "weather" again to see what it looks like.
Edit: I tried "weather clear" and the indicator disappeared for about a minute before the reappearing without a "started raining" announcement. R's in the same place as usual, no rain.I already did. A minute of relief, followed by the usual pattern.
It's always 5x5, so it has to be scaled up or down.I'm honestly not sure what the issue is. Toady says the weather map is still 5x5, and the way we find it is by saving a special weather pattern in an older DF version, then searching for it after loading the save in a newer version.How is that 5x5 map translated to the embark map? Does that mean it could be reading rain from outside my map, or is it scaled down to fit? I would still find it unlikely that the rain would never stop, however.
So four rows of "C", and one row of "R"?In the meantime, you can run "weather clear" to get rid of the rain indicator. If more weather shows up later, it would be nice if you could run "weather" again to see what it looks like.Edit: I tried "weather clear" and the indicator disappeared for about a minute before the reappearing without a "started raining" announcement. R's in the same place as usual, no rain.I already did. A minute of relief, followed by the usual pattern.
Any time estimate on the DFhack update for 43.04?Though I'm not a wizard, the usual answer is "it's done when it is done". I've been hearing that the 64-bit release has been making things difficult, however.
It's the new Windows compiler making things difficult. The 64-bit release hasn't been too bad, actually, although we have to update many of the automatic tools to support it as well.Any time estimate on the DFhack update for 43.04?Though I'm not a wizard, the usual answer is "it's done when it is done". I've been hearing that the 64-bit release has been making things difficult, however.
It's always 5x5, so it has to be scaled up or down.I wonder how it works in adventure mode. I can hear rain from a very far distance. I moved for a while on the travel map, and the weather map (not the problem one) didn't change at all.
So four rows of "C", and one row of "R"?Yeah.
Ok, either someone please tell me about a replacement to Dfusion's freaky Friday-like change adventurer script or just tell me how to re-add Dfusion.It's pretty difficult to re-add (you'd have to compile DFHack yourself). I wasn't familiar with DFusion myself, but going by https://github.com/DFHack/dfhack/pull/751, PeridexisErrant and Warmist might be able to help.
You could also check https://github.com/dfhack/dfhack/releases. The status of another 0.43.03 release is iffy, but not impossible.
Ok, either someone please tell me about a replacement to Dfusion's freaky Friday-like change adventurer script or just tell me how to re-add Dfusion.Well, the easy part is set a target grab (dfhackgetselectedunit or whatnot) and grab hist_id, pass it to the find command (what was the dfhack one? not the df.global.find(k) one or whatnot) and it'll pull up the df.global.world.history.hist_figs[k] for you, then have it set flags[0] to true, which should add that unit to the Specific Person part of the adventurer selection screen, I've gm-editor'D a bodyswitch but it was all sorts of slapdash, it should just be a matter of unlinking your unit from df.global.world.units.active[0] and setting your new adventurer target in there, plus tracking down any hanging links left in the hist_fig part I think?
I released a test-version with the 43-03 dfhack alpha two weeks ago, I got no negative feedback.You could also check https://github.com/dfhack/dfhack/releases. The status of another 0.43.03 release is iffy, but not impossible.
I for one would really like a full release for 43.03 so I can release a stable pack for it :)
I released a test-version with the 43-03 dfhack alpha two weeks ago, I got no negative feedback.You could also check https://github.com/dfhack/dfhack/releases. The status of another 0.43.03 release is iffy, but not impossible.
I for one would really like a full release for 43.03 so I can release a stable pack for it :)
There is indeed a stable release coming up, once we can get all the builds done and uploaded (2/3 so far - Windows is in progress, and hopefully a Linux+GCC 4.5 one is on the way too).Huzzah!
Edit: and here it is: https://github.com/dfhack/dfhack/releases/tag/0.43.03-r1
There is indeed a stable release coming up, once we can get all the builds done and uploaded (2/3 so far - Windows is in progress, and hopefully a Linux+GCC 4.5 one is on the way too).
Edit: and here it is: https://github.com/dfhack/dfhack/releases/tag/0.43.03-r1
There is indeed a stable release coming up, once we can get all the builds done and uploaded (2/3 so far - Windows is in progress, and hopefully a Linux+GCC 4.5 one is on the way too).
Edit: and here it is: https://github.com/dfhack/dfhack/releases/tag/0.43.03-r1
Woah. Awesome. Much appreciated!
EDIT: Now that the stable release has come. I've been meaning to ask: How does one alter the body size of an adventure with DFhack? I've tried editing the values with gui/gm-editor before but they revert and the histfig side of the gui/gm-editor doesn't seem to have entries for that.. that or I'm missing something obvious.
It's just that my succubus adventurer has been bugged by the false body descriptions and instead of just "incredibly muscular" it should say "she has loaded a thin but tall/lengthy body with incredible muscles" going by the raw data of my adventurer here and because of those raw values on my character, in the "z" screen it says "small for a succubus". had my head scratching for quite a while.
Anyhow, is there a trick to perma-changing the body size values?
She has an incredibly broad body hung with curtains of lard
Yeah, it's under appearance rather than body itself.
blood count? might be in the wounds section. though I don't know if that has anything to do with punching good.Yeah, it's under appearance rather than body itself.
What about the blood count? the body menu stays the same with same values. At least I now know how to alter a character, right now testing if my punches are more powerful or not.
EDIT: I don't get it. Why aren't the body values changing with the appearance. I'd like to know what data I get after modifying an adventurer's appearance. Damnit.. this is exactly why I hate that randomization function during character creation. I'd rather have a manual customization not dozens of minutes of skimming through randomized values and still ending up with something I didn't really want.
HAVE MANUAL ADVENTURER CUSTOMIZATION IN THE GAME!!!
EDIT2: Sorry.. that latter had nothing to do with DFhack but the game itself. I apologize.
EDIT3: No answer? Okay, no answer as per frickin' usual when I really need an answer. Final comment: Gonna take a long break. People... annoying. Must. Rest.
blood count? might be in the wounds section. though I don't know if that has anything to do with punching good.
# patch start dwarf count
=begin
startdwarf
==========
Use at the embark screen to embark with the specified number of dwarves. Eg.
``startdwarf 500`` would lead to a severe food shortage and FPS issues, while
``startdwarf 10`` would just allow a few more warm bodies to dig in.
The number must be 7 or greater.
=end
nr = $script_args[0].to_i
raise 'too low' if nr < 7
addr = df.get_global_address('start_dwarf_count')
raise 'patch address not available' if addr == 0
df.memory_patch(addr, [nr].pack('L'))
[lua]# ~df.global.world.entities.all[22].unknown1b.diplomacy[3]
<historical_entity.T_unknown1b.T_diplomacy: 0x0d31f1c8>
group_id = 18
relation = 1
anon_1 = 174
historic_events = <vector<int32_t>: 0x0d31f1d4>
historic_events_collection = <vector<int32_t>: 0x0d31f1e4>
anon_2 = 0
Has anyone found a way to make shells / horns / pearls / bones / skulls from certain creatures with the createitem command? Embarked on a barren embark without any creatures or fish and I wanna make bone/shell stuff.
Or even spawn animals itself.
I can't seem to use the spawnunit command because I don't know what caste is and anything I type in is invalid.
if (keyspec.size() == 1 && keyspec[0] >= 'A' && keyspec[0] <= 'Z') {
*psym = SDL::K_a + (keyspec[0]-'A');
return true;
} else if (keyspec.size() == 1 && keyspec[0] >= '0' && keyspec[0] <= '9') {
*psym = SDL::K_0 + (keyspec[0]-'0');
return true;
} else if (keyspec.size() == 2 && keyspec[0] == 'F' && keyspec[1] >= '1' && keyspec[1] <= '9') {
*psym = SDL::K_F1 + (keyspec[1]-'1');
return true;
} else if (keyspec.size() == 3 && keyspec.substr(0, 2) == "F1" && keyspec[2] >= '0' && keyspec[2] <= '2') {
*psym = SDL::K_F10 + (keyspec[2]-'0');
return true;
} else if (keyspec == "Enter") {
*psym = SDL::K_RETURN;
return true;
} else
return false;
Looks like it only takes alphanumerics, function keys, and enter. How hard would it be to extend this to, let's say, all these SDL-supported keys (https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlkey.html)?I'm looking for a way to specify not just an x,y,z in a given fort, but an x,y,z in the given world (basically I want to be able to check if a spot is the correct spot across the whole world, not just an embark site). I know there is df.global.world.map.region_x(y,z), but is that what I want to reference?
So I found the code responsible for parsing keybindings:Coming up with names and translating them all would be tedious. There's probably some way we could make it easier, though, but relying on stuff like SysRq, Help, and Pause to be available probably isn't a good idea.Code: (dfhack/library/Core.cpp) [Select]if (keyspec.size() == 1 && keyspec[0] >= 'A' && keyspec[0] <= 'Z') {
Looks like it only takes alphanumerics, function keys, and enter. How hard would it be to extend this to, let's say, all these SDL-supported keys (https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlkey.html)?
*psym = SDL::K_a + (keyspec[0]-'A');
return true;
} else if (keyspec.size() == 1 && keyspec[0] >= '0' && keyspec[0] <= '9') {
*psym = SDL::K_0 + (keyspec[0]-'0');
return true;
} else if (keyspec.size() == 2 && keyspec[0] == 'F' && keyspec[1] >= '1' && keyspec[1] <= '9') {
*psym = SDL::K_F1 + (keyspec[1]-'1');
return true;
} else if (keyspec.size() == 3 && keyspec.substr(0, 2) == "F1" && keyspec[2] >= '0' && keyspec[2] <= '2') {
*psym = SDL::K_F10 + (keyspec[2]-'0');
return true;
} else if (keyspec == "Enter") {
*psym = SDL::K_RETURN;
return true;
} else
return false;
Are there a lot of assumptions in the other code, or should any SDL key be handled just fine?
I'm looking for a way to specify not just an x,y,z in a given fort, but an x,y,z in the given world (basically I want to be able to check if a spot is the correct spot across the whole world, not just an embark site). I know there is df.global.world.map.region_x(y,z), but is that what I want to reference?
What do you mean "correct spot"?
It's not the script that needs updating (the script hasn't changed in a long time), it's the offset that's missing. I guess nobody remembered to find it. I think the script to find it is working again, though, so it shouldn't be too hard.
Coming up with names and translating them all would be tedious. There's probably some way we could make it easier, though, but relying on stuff like SysRq, Help, and Pause to be available probably isn't a good idea.I was thinking of making a pair of arrays and using the names as shown on the page. The init would remain the same, except that "Enter" refers to numpad enter, not return. It's not a very long list with what's already handled.
What do you mean "correct spot"?
Like imagine you have a spot in an embark at x,y,z. You then retire the fort and start an adventurer. How can you find that exact spot?
whereami.lua
This script reports your current location as X, Y, Z coordinates and a very terse description of the tile such as "SOIL WALL" or "POOL FLOOR".
whereami will also report if the current location is recorded as a bookmark.
Isn't there a specific history event for that?Okay... does anyone know a simplish way in Lua to check for a specific historical event? :)
Is there a trick I can use from Lua to detect when a fort is first embarked/reclaimed, rather than just loaded? It would trigger again if the player savescummed before saving, but not if there was at least one save for that fort (even the automatic autosave).
Something silly like dfhack.newfort() would be ideal, but I doubt it will be that simple.
I have an idea for a persistent counter to give a TESB player about a 250-mined-tile grace period before creatures start spawning (hidden gems are scaled down during this time as well to discourage setting the value sky-high). The issue is that the persistent table is world-specific, not fort-specific. I can't even embed the fort name or site number into the key because people might reclaim. I can't use the unit id of the first dwarf because those are re-used if you savescum.
I'm only counting tiles from 24 layer stones that could have spawned a creature, but if this turns out to be intractable I might bump up the grace period and just let soil count towards it. Thanks for the great fallback idea.Is there a trick I can use from Lua to detect when a fort is first embarked/reclaimed, rather than just loaded? It would trigger again if the player savescummed before saving, but not if there was at least one save for that fort (even the automatic autosave).
Something silly like dfhack.newfort() would be ideal, but I doubt it will be that simple.
I have an idea for a persistent counter to give a TESB player about a 250-mined-tile grace period before creatures start spawning (hidden gems are scaled down during this time as well to discourage setting the value sky-high). The issue is that the persistent table is world-specific, not fort-specific. I can't even embed the fort name or site number into the key because people might reclaim. I can't use the unit id of the first dwarf because those are re-used if you savescum.
Won't excavated_tiles in entity.activity_stats do?
Is there a trick I can use from Lua to detect when a fort is first embarked/reclaimed, rather than just loaded? It would trigger again if the player savescummed before saving, but not if there was at least one save for that fort (even the automatic autosave).
Something silly like dfhack.newfort() would be ideal, but I doubt it will be that simple.
I have an idea for a persistent counter to give a TESB player about a 250-mined-tile grace period before creatures start spawning (hidden gems are scaled down during this time as well to discourage setting the value sky-high). The issue is that the persistent table is world-specific, not fort-specific. I can't even embed the fort name or site number into the key because people might reclaim. I can't use the unit id of the first dwarf because those are re-used if you savescum.
Operationally it is just resetting a counter to zero, so if the trigger is found it can just break. Would be a lot faster to go backwards if I can work that out. In this particular case, though, maybe even checking that excavated tiles is zero would do the trick. Yes, you can do a lot before digging anything, but this is a counter for certain kinds of digging... No harm resetting a zero back to zero.Is there a trick I can use from Lua to detect when a fort is first embarked/reclaimed, rather than just loaded? It would trigger again if the player savescummed before saving, but not if there was at least one save for that fort (even the automatic autosave).
Something silly like dfhack.newfort() would be ideal, but I doubt it will be that simple.
I have an idea for a persistent counter to give a TESB player about a 250-mined-tile grace period before creatures start spawning (hidden gems are scaled down during this time as well to discourage setting the value sky-high). The issue is that the persistent table is world-specific, not fort-specific. I can't even embed the fort name or site number into the key because people might reclaim. I can't use the unit id of the first dwarf because those are re-used if you savescum.
There's no builtin way to do it but that sounds interesting.
I think iterating through all history once on load is probably your safest bet. Check if the fort was founded at the current time. It might trigger multiple times if you save without advancing at least one frame then reload though, so be careful about that corner case. You may or may not want it to retrigger when that happens.
Are excavated tiles set to zero on a reclaim?Just meant going from most recent backward toward earliest. And I'll have to check about resetting on a reclaim.
What do you mean by "go backwards"?
I got a question about item-trigger: does -onStrike also work for ammo?
Oh, thanks.I got a question about item-trigger: does -onStrike also work for ammo?Don't think so, but there is projectile-trigger for ammo
modtools/reaction-trigger -reactionName SPAWN_DEBUG -command [ modtools/create-unit -race GOLD_HOUND -caste DEFAULT -civ_id \\LOCAL -group_id \\LOCAL -domesticate -location [ \\LOCATION ] -age 1 ]
On a phone at the moment so I can't check, but make sure the parameters are right. Might be civId and groupId. In any case, it ought to throw an error unless reaction-trigger suppresses that for some reason.Well, it was part of the problem. changing civ_id to civID spits this out:
Well, it is definitely -civId and -groupId (note the camelCaseCapitalization), and \\LOCAL will make them aligned with the player's fort which ought to be aligned with the person performing the reaction.\\LOCAL is simply not working for me, instead getting me the error I pasted above. Anyway, it's mostly working now, just have no idea why it's sometimes spawning multiple creatures who then proceed to try to murder each other. Any idea why that's happening?
The gps.screen.value iš the first tiles ( upper left corner) character. So it might fail with fps display on ( or off)
For a new fort the onload.init runs while df.global.gps.screen.value is 0, and then it becomes 219 when the embark screen is ready for user input. It is also 219 in fort mode and arena mode and while a saved game is reloading, so I'm not sure what that value is really supposed to represent. But, since you can't get to "screen 0" in an active fort it's good enough for my purposes.
I have a feeling once this updates something will breakNot quite sure what this is supposed to mean.
Oh, I thought you meant something in DFHack (which is already pretty broken). We host downloads on GitHub now, so hopefully that doesn't go down because of us. :)"Thank you for calling Infrastructure Services, I'm showing an alarm in the server room HVAC. Are you calling about that?"
Oh, I thought you meant something in DFHack (which is already pretty broken). We host downloads on GitHub now, so hopefully that doesn't go down because of us. :)
dfhack.timeout(ticks+1,'ticks',dfhack.script_environment('functions/event').queueCheck(id,'WEEKLY',true))
I can't open DF on this computer so I can't test it out. Do I instead needdfhack.timeout(ticks+1,'ticks',function ()
dfhack.script_environment('functions/event').queueCheck(id,'WEEKLY',true)
end)
?
You should definitely use the second instead of the first. The first will call "dfhack.script_environment('functions/event').queueCheck(id,'WEEKLY',true)" exactly once, then pass whatever that returns to dfhack.timeout, which will then try to call it as a function and probably fail.
Also, I'm not quite sure why you're passing ticks+1 as the first argument - that argument is basically "number of ticks later" in this case, so you may as well make ticks whatever you want and use that as the first argument instead (unless I'm misunderstanding something).
modtools/reaction-trigger -reactionName MUTATE_RAT -allowNonworkerTargets -command [ modtools/transform-unit -unit \\TARGET_ID -race RAT_GIANT -caste MALE -suppressAnnouncement ] ]
Just out of curiosity, has anyone looked into how boogeymen, demons and normal animal clusters get spawned by the game? The current version of create-unit uses a trick mifki figured out to use Arena Mode momentarily, but there is still some instability which says to me that at least some of the data structures used in Fort Mode are uninitialized.What kind of instability?
Boogeymen appear out of nowhere; animals and demons appear out of nowhere but pulling from abstract populations. The Starting Seven and the initial migrants might call the same function, or might be completely different because they're built from the ground up to be citizens. Getting access to that method from DFHack would be the holy grail of spawning creatures, or even just the constructor for a unit would ensure that we don't miss something that might have evaded DF Structures.
Is that crashing when you run modtools/reaction-trigger or when modtools/transform-unit gets run?Neither. I can run both.
Neither. I can run both.I'm confused. Is DF actually crashing?
DF crashes to desktop.Neither. I can run both.I'm confused. Is DF actually crashing?
Maybe I should be clearer: Does the crash occur immediately when you run the entire command, or does it occur when (as a result of running that command) modtools/reaction-trigger gets called (not directly by you) at a later point in time?
modtools/reaction-trigger -reactionName MUTATE_RAT_TO_GIANT -allowNonworkerTargets -command [ modtools/add-syndrome -syndrome "transform_rat_giant" -target \\TARGET_ID ]
[SYNDROME]
[SYN_NAME:transform_rat_giant]
[SYN_AFFECTED_CREATURE:SKAVEN_RAT:ALL]
[CE_BODY_TRANSFORMATION:START:0][CE:CREATURE:WOLFRAT:MALE]
It crashes fairly regularly if Roses' attack.lua is used on a spawned creature in 0.43. I circumvented the need for that script in my mod and things seem better, but I still get the occasional crash a few seconds after a creature is spawned. The attack issue might be an anon that changed between 0.42 and 0.43, but the remaining crashes sound to me like an uninitialized value somewhere that is only relevant sometimes. Unfortunately it's a crash-to-desktop so it doesn't leave behind much to troubleshoot. There is nothing in stderr.log after the call to create-unit.Just out of curiosity, has anyone looked into how boogeymen, demons and normal animal clusters get spawned by the game? The current version of create-unit uses a trick mifki figured out to use Arena Mode momentarily, but there is still some instability which says to me that at least some of the data structures used in Fort Mode are uninitialized.What kind of instability?
Boogeymen appear out of nowhere; animals and demons appear out of nowhere but pulling from abstract populations. The Starting Seven and the initial migrants might call the same function, or might be completely different because they're built from the ground up to be citizens. Getting access to that method from DFHack would be the holy grail of spawning creatures, or even just the constructor for a unit would ensure that we don't miss something that might have evaded DF Structures.
There probably aren't entirely separate constructors for citizens and non-citizens. There's probably some method(s) DF uses to turn units into citizens, but unit doesn't have any virtual methods, so finding those methods would require a lot more disassembly and manual searching for each build of DF.
reaction-trigger is really nice for some things, but the good old auto-syndrome can't be beat for others.You have no idea how I feel right now. The lack of autosyndrome is the reason I could not update MasterworkDF and almost gave up modding. Took a break for over a year and then came back, put in over two-hundred hours of work to slowly and painstakingly update the mod... still not done...
I wonder how hard it would be to make a modern version... I'm a little busy right now, but I may have time to play with it some in a week or so.
I don't know how to distinguish between the two options you mention.
It crashes fairly regularly if Roses' attack.lua is used on a spawned creature in 0.43. I circumvented the need for that script in my mod and things seem better, but I still get the occasional crash a few seconds after a creature is spawned. The attack issue might be an anon that changed between 0.42 and 0.43, but the remaining crashes sound to me like an uninitialized value somewhere that is only relevant sometimes. Unfortunately it's a crash-to-desktop so it doesn't leave behind much to troubleshoot. There is nothing in stderr.log after the call to create-unit.Does attack.lua succeed on non-spawned creatures? And are you saying create-unit crashes even without attack.lua?
Oh I understand that the stderr.log isn't going to have Null pointer in .enemy structure... scrawled by a bloody finger. Was just pointing out that no other script had run since.It crashes fairly regularly if Roses' attack.lua is used on a spawned creature in 0.43. I circumvented the need for that script in my mod and things seem better, but I still get the occasional crash a few seconds after a creature is spawned. The attack issue might be an anon that changed between 0.42 and 0.43, but the remaining crashes sound to me like an uninitialized value somewhere that is only relevant sometimes. Unfortunately it's a crash-to-desktop so it doesn't leave behind much to troubleshoot. There is nothing in stderr.log after the call to create-unit.Does attack.lua succeed on non-spawned creatures? And are you saying create-unit crashes even without attack.lua?
No script should be touching anon fields (although apparently create-unit is one of the few that does). Is attack.lua on Github anywhere? It could be an issue with either script, or both.
(Also, information about crashes in stderr.log is very rare. The last command you ran is probably there, and relevant, but of course you would know that already.)
reaction-trigger is really nice for some things, but the good old auto-syndrome can't be beat for others.You have no idea how I feel right now. The lack of autosyndrome is the reason I could not update MasterworkDF and almost gave up modding. Took a break for over a year and then came back, put in over two-hundred hours of work to slowly and painstakingly update the mod... still not done...
I wonder how hard it would be to make a modern version... I'm a little busy right now, but I may have time to play with it some in a week or so.
Lethosor: Here the save. https://www.dropbox.com/s/j529lbe1vgc2kpn/Dwarf%20Fortress%20-%20Meph%20Edition.rar?dl=0
I added the entire game folder, because everything is heavily modded. Its the newest dfhack release. Just open the Onload.ini in the raw folder, I made comments at the top.
tl;dr:
- Embark, look at the kitchen. It has 4 test reactions, 3 to armor an animal, 1 to transform it. The one that transforms it will crash the game. I already pastured a rat on the workshop.
modtools/reaction-trigger -reactionName MUTATE_RAT -allowNonworkerTargets -command [ wrapper -unitSource \\TARGET_ID -unitTarget \\TARGET_ID -aclass CLASS_NAME -script [ modtools/transform-unit -unit \\TARGET-race RAT_GIANT -caste MALE -suppressAnnouncement ] ] ]
Would only target a creature if it has CLASS_NAME as a specific creature class (note that it may require an extra \ or two, I can't test at the moment, but I know checking for creature classes and syndrome classes is something the script does correctly). And in fact there are better ways with the wrapper script than declaring unitSource and unitTarget including choosing creatures within a certain radius of the initiating worker. For example, I think the best way to do it would be,modtools/reaction-trigger -reactionName MUTATE_RAT -allowNonworkerTargets -command [ wrapper -unitSource \\WORKER_ID -target civ -radius [ 10 10 2 ] -maxtargets 1 -aclass CLASS_NAME -script [ modtools/transform-unit -unit \\TARGET-race RAT_GIANT -caste MALE -suppressAnnouncement ] ] ]
That will do a single target within 10x10x2 of the workshop and transform them only if they have the creature class CLASS_NAMEAs for attack.lua, that script comes from my repository and is in raw/scripts/unit/attack.lua. I see no reason that a spawned creature should be any different than a non-spawned creature since attack.lua only influenced the actions of a unit. If there is indeed a difference between the actions of a spawned creature and a normal creature that really needs to be worked out in create-unit.lua. Please let me know if how and when attack.lua is crashing, as that is one of the few scripts that I have thoroughly tested in Arena, Fortress, and Adventure mode. Note that between the last version and this version certain anon fields were given names (particularly attack velocity and attack hit chance). If the script hasn't been correctly updated it may still be trying to access anon fields that are actually named fields.I was referring to the attack.lua packaged with Masterwork (since that's what these particular end-users would be using), and I agree the fault is probably in create-unit. That attack script does not touch any anon fields. Just hoping that working under 0.42 and broken in 0.43 turns out to be a decent clue in fixing create-unit, since I'm not the only person who pokes at it.
For one thing, the error message would be more readable if you could actually copy and paste the text. Assuming the reason you didn't is because you're on Windows, you can do it by right-clicking in the console and/or right-clicking the console title bar.
Anyway, is line 15 "]====]"? Is line 4 "--[====["? Where did you get the script from? If you got it from https://github.com/DFHack/scripts/blob/master/teleport.lua, did you make sure to click "Raw" and download that?
G:\Gry\df_34_11_win\hack\scripts/teleport.lua:31: attempt to call field 'invert' (a nil value)
stack traceback:
G:\Gry\df_34_11_win\hack\scripts/teleport.lua:31: in main chunk
(...tail calls...)
The one in the DFHack/scripts repo was added in 2014, so it's not too surprising that it wouldn't work with 0.34.11. It looks like it relies on a few features for argument processing that were added in 2014, too.
The one in the DFHack/scripts repo was added in 2014, so it's not too surprising that it wouldn't work with 0.34.11. It looks like it relies on a few features for argument processing that were added in 2014, too.
Replace the argument processing and that script will probably work. AFAIK teleporting is a fairly simple matter of changing the creature's position (unit.pos).
I haven't seen this mentioned (did a quick keyword search through the thread) but a request for the autogem cutting plugin:I'll take a look. Meanwhile, it already respects stockpile links, in case that helps.
Have it respect new workshop profile setting.
I haven't seen this mentioned (did a quick keyword search through the thread) but a request for the autogem cutting plugin:I'll take a look. Meanwhile, it already respects stockpile links, in case that helps.
Have it respect new workshop profile setting.
Couldn't you create a stockpile that accepts nothing and link it to the workshop?
Oh, sorry. I thought you had a walled-off workshop that was accepting gem-cutting jobs, or something like that. (These forums aren't the most mobile-friendly...)Couldn't you create a stockpile that accepts nothing and link it to the workshop?
Well then the workshop wouldn't be good for anything?
Oh, sorry. I thought you had a walled-off workshop that was accepting gem-cutting jobs, or something like that. (These forums aren't the most mobile-friendly...)Couldn't you create a stockpile that accepts nothing and link it to the workshop?
Well then the workshop wouldn't be good for anything?
My solution is to clutter the workorder with either duplicates or specifying them for different furniture. So if I want only gem encrusted statues, I tell to use "any material" for the gems and use it on input item statue. So now every statue will be encrusted by any gem lying around.Oh, sorry. I thought you had a walled-off workshop that was accepting gem-cutting jobs, or something like that. (These forums aren't the most mobile-friendly...)Couldn't you create a stockpile that accepts nothing and link it to the workshop?
Well then the workshop wouldn't be good for anything?
LOL, I thought maybe you knew something I don't (well I'm sure you know a lot about DF that I don't) but no worries, Breadman said he'd look at it, and he gave me a workable solution otherwise.
For on of masters of this thread :)At first there was chaos. Many young hackers did the same and did it differently. It was good time, because df was stuck in one version.
Can someone told me short story of DFHack creation, and probadly give some linkes to first discussions about it? I really need it. Thanks.
... At first there was chaos. Many young hackers did the same and did it differently. It was good time, because df was stuck in one version.Very good lyrics! I almost can feel the Iluvatar music weaving into the shining reality of today DFHACK ;)
But soon one of those hackers has risen. He chose the hard path: to join everyone under a dfhack banner (and the nice performance gain by being in same address space) and that person was Peterix. And thus the Dfhack has risen from the chaos and is thriving since that day.
The second big revolution was "Lua". From the depths of internet came a person named "ag" (in these forums). He took the idea i toyed around and made it beautiful and powerful. And thus we could do anything (well almost) without any recompile.
The third big revolution was "Vmethod interposing". Again big thanks to "ag". This allowed us to do "MAGIC" with dfhack. Like catch when df calls some functions and replace them VERY EASILY. And also the gui was born.
Though this is only one half of it. During all that time there were many people - Like Peterix and Quietust - that worked on very important systems. Like the dfhack architecture itself and reversing the df...
Very good lyrics! I almost can feel the Iluvatar music weaving into the shining reality of today DFHACK ;)
You must have a poet soul to transform a relevant bunch of boring and precise technical jargon into an interesting saga song ;D
EDIT: Follow up question, does anyone have a script that reads what the name of something is? Whether a unit or entity or region or anything that has the name vector with words, parts of speech, and language?
print(dfhack.df2console(dfhack.TranslateName(...)))
If you don't pass it through df2console, special characters won't be displayed correctly on all platforms.
Also, if you decide to print the result of that to the console (or any other CP437-encoded text from DF), useThanks for that tip, echoing civ names to the console worked just fine under Windows. Didn't realize that would not be the case everywhere.Code: [Select]print(dfhack.df2console(dfhack.TranslateName(...)))
If you don't pass it through df2console, special characters won't be displayed correctly on all platforms.
The way DFHack hooks in is a bit different on the three platforms, but basically, we hook into four core SDL functions:Thanks for the explanation, it was very informative. You can easily modify those functions and createa modified DLL because SDL is open source, right? If one were to do the same with a closed source library would they have to search through the assembly version of it and modify it or do you know of any other ways?
- SDL_Init: DF calls this on startup, so we implement our own version that does any initialization work we need and then calls the "original" SDL_Init
- SDL_Quit: similar, but called when DF exits cleanly, so we handle any necessary cleanup here and call the original SDL_Quit
- SDL_PollEvent: used to implement keybindings. We call the original function, then check for any keypress events that match DFHack keybindings. If any do match, the DFHack keybindings are invoked; otherwise, the event is passed on to DF.
- SDL_NumJoysticks: probably the most important one. DF calls this every game tick (simulation tick, not graphical frame), so we can essentially pause DF briefly and allow anything to modify DF data safely.
On OS X and Linux, it's fairly simple to make a library that just intercepts these four functions, and doesn't interfere with any other SDL functions at all. However, on Windows, we have to make a new SDL.dll that implements every SDL function DF needs and call the corresponding function in SDLreal.dll (which is just a copy of the original SDL.dll).
There are some parts of DFHack that would be easy to make work with other programs, and some that would be very hard (e.g. the hooks above). I think Peterix was wanting to make DFHack work with other games at some point, but I'm not sure how much progress was made there.
I'm not really sure what a proper term is, but I suppose "DLL injection" fits.
... and the rest of it was a lot of work. After several years of maintenance, I left the project for others to worry about :)
Yeah it's the natural order of things. E.g. currently i don't play because anything i try gets fps death. Next step for that is 1x1 fort with 20 dwarf limit (+20 children +20 visitors). Maybe that could work for some time...... and the rest of it was a lot of work. After several years of maintenance, I left the project for others to worry about :)
Although not being involved in development, are you still playing DF? Were you playing it a lot back then (for example, I must admit, I am developing much more than playing, which is a problem sometimes as I just don't know some gameplay stuff well)?
It's just interesting why people suddenly lose interest in their projects (I'm not saying I don't do that sometimes myself). Back in good old OSx86 days, there was a guy, Maxxus, who first hacked first versions of OS X 10.4 to run on non-Apple hardware and documented the process of binary patching to the kernel. And then he disappeared. We had to use his old kernel with new OS X versions until.. um.. I was able to build a new one from sources. And we didn't, and still don't (AFAIK) know, who he was and why he abandoned the project.
Here, GavJ disappeared after starting to work on a very interesting geological project, fricy disappeared...
(@MaxTM - what kind of blood did you use to draw Peterix back???)
Now I'm doing the same with Minecraft, except with a very limited scope - just a launcher. You wouldn't believe how difficult did Sun/Oracle/Microsoft/AMD/Intel/nVidia make it to launch Java programs on Windows properly.
LucasUP vanished and I took over the LNP...He has shown up in this thread a few times, and he's actually around the IRC channel quite a bit (not active, but responsive to mentions). It's not quite the same situation as other people who have disappeared.
(@MaxTM - what kind of blood did you use to draw Peterix back???)
Oh, right, aren't you one of the MultiMC devs or something like that?Yep. (https://github.com/MultiMC)
LucasUP vanished and I took over the LNP...Funny story, the missus just hit... that time of the month, and I... used some to draw a dorf on the wall, though I'm not sure why as it was actually after Peterix popped back up... less a funny story, really, more of a mess.
(@MaxTM - what kind of blood did you use to draw Peterix back???)
I think you just killed the thread dude :PMax's punishment is that he must debate GoblinCookie, on a topic of his choosing, for at least ten pages.
Edit: regarding the "WTF", unk_a2 was undetermined and there were no field names, so presumably the issue was left open to allow kane-t a chance to continue researching.
Some recent development updates:
Lua was updated to Lua 5.3 (actually some time ago, but nobody seems to have mentioned it here yet). This was necessary to support 64-bit integers properly, since Lua 5.2 didn't support those. Unfortunately, this will cause a few things to fail that used to work before:
- Assigning a floating-point number to a DF field that is an integer
- Assigning a string to a DF integer field
- Passing a floating-point number to a C function (DF/DFHack) that expects an integer
Basically, strings and integers can be converted to floating point numbers automatically, but not to integers. If your scripts do any of those things above, you'll need to update them. In most cases, "math.floor()" should be enough to convert anything to an integer, and it should be consistent with the previous behavior.
DFHack changes:
- The manager-quantity script was re-added as gui/manager-quantity after Enay pointed out that it's still useful for changing work order quantities (oops).
- The lua interpreter (both the interactive and single-expression uses) and gui/gm-editor now support exactly the same "shortcuts" - e.g. scr, screen, world, building, bld, enabler, unit, etc.. These have been moved to utils.lua, so it should be easy for other scripts to use them too.
Structures:
- The viewscreen_setupadventurest layout has been incorrect for a long time, but I finally managed to get it mostly aligned properly and identified a bunch of new fields. (Having both 32 and 64-bit support was really helpful here, incidentally.)
- enabler was incorrect on x64 due to the "flags" bitfield varying in size, which was just fixed. This bitfield will have 32 flags or 64 flags on OS X/Linux depending on the architecture, but only the first two are used regardless of the platform/build.
(Also, I recently discovered that [x] can be used for bulleted lists.)
Some recent development updates:
That floating point and double float stuff sounds like the type of errors I was getting when trying to compile DFHack. Maybe I need to install Lua.No, you don't need to install Lua. Lua is included in the DFHack tree. I'm not really sure what the issue is there, but it looks like you're using one of my GCC builds :/ . Someone here (http://stackoverflow.com/questions/29380046) ran into a similar issue when using a version of GCC built on a newer OS X version, so that could be it. I suppose if you don't want to compile GCC, you could try removing the occurrences of "__header_always_inline" from /gcc/4.8.5p/lib/gcc/x86_64-apple-darwin13.4.0/4.8.5/include-fixed/math.h (make a backup!), but otherwise, I think you'd get better results with a native GCC (one you build on your OS).
Great to have this in the thread, but shouldn't it also go in NEWS.rst (the changelog file)?I put it in this thread because people kept getting directed to here, where there weren't any recent updates. Of course it'll go in NEWS.rst when I get around to updating it (or someone else does), which I always do at least before releases, if not more often. (I won't be copying it verbatim, though, to keep the size reasonable.)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working tree clean
...Wow, I've never seen that before. What GCC 4.8 is that from - Homebrew, self-compiled, MacPorts, something else?
Anyone know the correct offset for the startdwarf plugin? All the ones I've tried appear to be outdated.Do you mean start_dwarf_count? That changes with pretty much every DF version, as do all of the other offsets (except in rare cases/coincidences), so anything in older versions is likely not right in whatever version you're using.
...Wow, I've never seen that before. What GCC 4.8 is that from - Homebrew, self-compiled, MacPorts, something else?
Do you mean start_dwarf_count? That changes with pretty much every DF version, as do all of the other offsets (except in rare cases/coincidences), so anything in older versions is likely not right in whatever version you're using.I'm using 43.03. It's not just outdated, symbols.xml shows that it doesn't even exist.
No, symbols.xml isn't showing that it doesn't exist. It exists, and likely will exist until Toady scraps the 7-dwarf default. The fact that it's missing from symbols.xml simply means that nobody has found it.Do you mean start_dwarf_count? That changes with pretty much every DF version, as do all of the other offsets (except in rare cases/coincidences), so anything in older versions is likely not right in whatever version you're using.I'm using 43.03. It's not just outdated, symbols.xml shows that it doesn't even exist.
...Wow, I've never seen that before. What GCC 4.8 is that from - Homebrew, self-compiled, MacPorts, something else?
Something is wrong with Xcode I think.
What does "xcode-select -p" give you?
How difficult is it to turn constructions into natual stone?
I want to make a plugin that allows you to make dirt walls. (Any dirt, because specifying isn't possible)
I did do some experiments with the tiletypes command, which let me put dirt walls anywhere except constructions.Ah yes i forgot. Also there is layers and soil-layers. So soil is a bit of special thing.
What I didn't test, but what I would want this for, was see if trees grow on the resulting dirt.
I want hanging gardens.
I did do some experiments with the tiletypes command, which let me put dirt walls anywhere except constructions.Hmmm, I think you need to clear the construction tile first, like tiletypes paint m air s empty > construction tiles > paint m soil s wall > the new open spaces
What I didn't test, but what I would want this for, was see if trees grow on the resulting dirt.
I want hanging gardens.
(note: not sure how cave-ins do it though)
Hmmm, I was doing different cave-in experiments with ice and obsidian and constructions in adventurer mode, it's how I clear magma and such for constructions in a lot of areas, and I've used it to punch through the floors of cavern lakes as well.Actually obsidian is yet another special case. Because of that you can only have one "obsidian" per DF (sadly).
I think it's similar to the way ice works except you can't produce just an obsidian floor but 1/7 water will make a sheet of ice when exposed to freezing skies, even if you're in mid-air with no supports around it.Hmmm, I was doing different cave-in experiments with ice and obsidian and constructions in adventurer mode, it's how I clear magma and such for constructions in a lot of areas, and I've used it to punch through the floors of cavern lakes as well.Actually obsidian is yet another special case. Because of that you can only have one "obsidian" per DF (sadly).
Isn't one of the meeting path things that?
EDIT EDIT: Now any items I place with createitem disappear when I unpause the game. I'm trying to make a cool tomb for my friend to explore in adventure mode, and need a specific block that I was unfortunate enough not to embark on. Anyone know how to fix the disappearances?
EDIT EDIT: Now any items I place with createitem disappear when I unpause the game. I'm trying to make a cool tomb for my friend to explore in adventure mode, and need a specific block that I was unfortunate enough not to embark on. Anyone know how to fix the disappearances?
This sounds like what happens when the garbage collect flag is set on an item. They'll sit there until the game is unpaused and then they're immediately cleaned up from the game. Can you use gm-editor and confirm that that's not happening?
Select an item, run "gui/gm-editor", and look for "garbage_collect" under "flags".
Alternatively, you could run ":lua print(dfhack.gui.getSelectedItem().flags.garbage_collect)".
All right, what are the other flags set to?On Ground and In Job are set to true, all other flags are false. Flags 2 are all false.
Wait, they're "in job" directly after you've created them? Or did you let some time pass so they get a stockpile task assigned?
Can you check an item's ID after you create it (the "id" field), unpause, wait for it to disappear, and run ":lua ~df.item.find(ITEM_ID)"? (Replace ITEM_ID with the ID of the item you found earlier.)
Okay, so the item still exists. Try checking the pos field (":lua ~df.item.find(ITEM_ID).pos"). Then you can move the cursor to where the item is by setting the three fields of df.global.cursor (e.g. run "lua", then at the lua prompt, run "df.global.cursor.x = df.item.find(ITEM_ID).pos.x", then again with y and z). You might need to press up/down in DF after doing that to get the window to recenter properly.
Also, you can copy text from the console on Windows by right-clicking the title bar, or right-clicking in the console, depending on your system. It's a lot easier for us to read than full screenshots.
It wasn't x/y/z = -30000 was it? That's the default cursor location when it isn't present, I discovered that when I ran launch without a target the first time, since I aimed it at the cursor to give a speed/direction control via in-game methods, this meant I hurled myself at the lower northwest corner of the map at light speed and blew up.
I've usually been running Dfhack through Lazy and can't say I've used a lot of time trying to configure what is beeing run as default through Dfhack , will there ever been some sort of manageable gui where we could dump / add things we want dfhack to run?Well, there's dfhack.init, where you can specify whatever you want to run on startup, plus a variety of other options for running things when a world or map is (un)loaded. Some LNP launchers have a tab that lets you configure specific DFHack tools, but those are typically limited. The most powerful option for now is editing dfhack.init. I guess a GUI in DF would be possible, but it could be tricky to re-run things as they're changed (without restarting DF, which isn't really desirable).
I've usually been running Dfhack through Lazy and can't say I've used a lot of time trying to configure what is beeing run as default through Dfhack , will there ever been some sort of manageable gui where we could dump / add things we want dfhack to run?Well, there's dfhack.init, where you can specify whatever you want to run on startup, plus a variety of other options for running things when a world or map is (un)loaded. Some LNP launchers have a tab that lets you configure specific DFHack tools, but those are typically limited. The most powerful option for now is editing dfhack.init. I guess a GUI in DF would be possible, but it could be tricky to re-run things as they're changed (without restarting DF, which isn't really desirable).
I've usually been running Dfhack through Lazy and can't say I've used a lot of time trying to configure what is being run as default through Dfhack , will there ever been some sort of manageable gui where we could dump / add things we want dfhack to run?
I've usually been running Dfhack through Lazy and can't say I've used a lot of time trying to configure what is being run as default through Dfhack , will there ever been some sort of manageable gui where we could dump / add things we want dfhack to run?
https://dfhack.readthedocs.io/en/stable/docs/Core.html#init-files
It wasn't x/y/z = -30000 was it? That's the default cursor location when it isn't present, I discovered that when I ran launch without a target the first time, since I aimed it at the cursor to give a speed/direction control via in-game methods, this meant I hurled myself at the lower northwest corner of the map at light speed and blew up.
Nope!
[DFHack]# createitem BLOCKS INORGANIC:OLIVINE 50
[DFHack]# gui/gm-editor
[DFHack]# :lua ~df.item.find(13001).pos
<coord: 0x08fe4f04>
x = 36
y = 60
z = 103
EDIT: That's the position BEFORE it moves. Afterwards, it becomes:
x = 36
y = 60
z = 76
It wasn't x/y/z = -30000 was it? That's the default cursor location when it isn't present, I discovered that when I ran launch without a target the first time, since I aimed it at the cursor to give a speed/direction control via in-game methods, this meant I hurled myself at the lower northwest corner of the map at light speed and blew up.
Nope!
[DFHack]# createitem BLOCKS INORGANIC:OLIVINE 50
[DFHack]# gui/gm-editor
[DFHack]# :lua ~df.item.find(13001).pos
<coord: 0x08fe4f04>
x = 36
y = 60
z = 103
EDIT: That's the position BEFORE it moves. Afterwards, it becomes:
x = 36
y = 60
z = 76
So it falls a bunch of Z-levels and stops. After it falls no further, what happens if you set its position back to the surface? Note that just adjusting the Z value for an item's position is not the correct way to move items because it leaves other flags and data structures un-updated, but works for this one experiment. I just want to see if it starts falling again after you bring it to the surface.
DFhack comes with a console program specifically for this: dfhack-run.ty :)
Just use your alternate tty to browse into your dfhack folder while your dfhacked game is running, and type ./dfhack-run <command>
I'd also note that there are decent API docs for Lua, and none at all for Ruby.Do I hear PE volunteering to take on a side project? :)
I'd also note that there are decent API docs for Lua, and none at all for Ruby.Do I hear PE volunteering to take on a side project? :)
I meant ruby is friendlier than C++, not lua, lua is cuddly.Well at least C++ is !!FUN!!
As an interesting side note, I wrote a Lua compiler a while ago that used syntax much closer to C or Go. It used curly brackets for blocks (curly brackets for tables still worked, the compiler can tell the difference), "&&" instead of "and", "!=" instead of "~=", it even had a "continue" keyword. All this and it still produced bytecode that would run on the standard Lua VM. Code quality generally exactly matched that produced by the standard Lua compiler, but there were a few cases where it was slightly worse due to me being lazy...
Unfortunately it was written in Go, so it would not be possible to use it with standard Lua without a total rewrite or using it as a stand-alone tool (not to mention the fact that the "load" function was something of an issue, as it still used standard Lua syntax).
The idea of the new syntax was to make it easier to work with for a programmer used to C/C++, C#, Java, Go, etc. It worked great, but I never bothered to write a C version and publish it...
Continue was trivial. All you needed to do was keep track of the end of the loop (which you need to do for "break" anyway). "continue" then becomes a jump to just before the end of loop instructions instead of "break"'s jump to just after. This has minor issues with variable scoping in one certain kind of loop, but there are solutions to that that I could have implemented if I had wanted something other than a toy. (my continue was basically a "goto" targeted at the end of the loop)
As for me, the main problem of Lua is still 1-based numbering which, for more or less complex algorithms, makes it easier to rewrite them from scratch to avoid mistakes than to simply change syntax as between other languages.
What about this? http://stackoverflow.com/a/3526946/991806
1 based indexing is an obvious example of massive brain damage... Hmmm... Maybe I should brush up my C skills some and write a language that takes all the best parts of Lua, but use C-like syntax, 0 based indexing, etc. The problem is, I already have too many projects.
1 based indexing is an obvious example of massive brain damage... Hmmm... Maybe I should brush up my C skills some and write a language that takes all the best parts of Lua, but use C-like syntax, 0 based indexing, etc. The problem is, I already have too many projects.
I think we've all had that idea once or twice whenever we stumble on Lua's many oddities. Lua's strengths are very impressive, and the clumsy and verbose syntax is the price you must pay for it. The real problem in writing your own Lualike language, because it applies even to people that don't have too many projects, is this: see you in 20 years when your single-developer language is mature and doesn't randomly glitch out/segfault. Oh you're finished? Well Lua's dead and now we're all using MontyPython, because all the VR devices have an integrated bytecode VM for it. There's your next homemade language dupe project. :P
Is there a pre-alpha for 43.05?We've tried doubling the volunteers' pay ($0x2=$0), but it turns out that no one is slacking and it's just taking a long time.
finding 64-bit offsets is harder since we have to update some tools we were usingIn some cases, that isn't even possible - for example, I've been using IDA demo/free versions on Windows for 32-bit DF, but the only versions of IDA that support 64-bit binaries cost over $1000 for a single license, and most other tools don't even come anywhere close in terms of functionality and usability.
when using catsplosion list, the command shows animals that have already been slaughtered. When does the count reset? Also, I penned my falcons into a room with nestboxes and ran the catsplosion bird_falcon_peregrine and it just says pregnancies accelerated or something, but nothing happens? they dont immediately lay more eggsI don't think egg layers are ever really pregnant, in that they have a separate egg timer. Fiddling with the pregnancy flags probably won't work, and if it did it might lead to live birth.
I assume you may already know about: https://github.com/radare/radare2 but it has no gui or anything, though it does have some documentation: https://radare.gitbooks.io/radare2book/content/ it seems.finding 64-bit offsets is harder since we have to update some tools we were usingIn some cases, that isn't even possible - for example, I've been using IDA demo/free versions on Windows for 32-bit DF, but the only versions of IDA that support 64-bit binaries cost over $1000 for a single license, and most other tools don't even come anywhere close in terms of functionality and usability.
We've tried doubling the volunteers' pay ($0x2=$0), but it turns out that no one is slacking and it's just taking a long time.My brain parses this as:
addi $2,$0,0 # Register2 = 0
(You probably can't use hexadecimal for registers, I assume.)when using catsplosion list, the command shows animals that have already been slaughtered. When does the count reset? Also, I penned my falcons into a room with nestboxes and ran the catsplosion bird_falcon_peregrine and it just says pregnancies accelerated or something, but nothing happens? they dont immediately lay more eggsI don't think egg layers are ever really pregnant, in that they have a separate egg timer. Fiddling with the pregnancy flags probably won't work, and if it did it might lead to live birth.
(Ignorant speculation: it seems like if the main goal is to know where in memory a bunch of structures are, it wouldn't be that hard for him to put in a [PRINTOFFSETS] in an init file and then have DF spit out the & memory addresses of the data structures of interest?)It probably wouldn't be an init setting - more likely, it would be a command-line parameter, and it would actually be quite simple to write (something like printf("gps: %x\n", &gps + base_addr); for each global variable we care about, and we currently track just over 120, and most of them can be found automatically). Whether or not it will actually happen, though, is entirely up to Toady, and I don't believe any of us have directly asked for that sort of functionality simply because our own tools were good enough to do it without his help.
(Ignorant speculation: it seems like if the main goal is to know where in memory a bunch of structures are, it wouldn't be that hard for him to put in a [PRINTOFFSETS] in an init file and then have DF spit out the & memory addresses of the data structures of interest?)In addition to what Quietust said, some of our tools can work on all DF binaries without having to run them, which is nice for people that can't run all of them (although there are also scans for some globals that do require running DF already, so it wouldn't really add extra requirements).
Has Toady ever expressed interest in making it somehow easier to maintain the offsets for tools like this? (Ignorant speculation: it seems like if the main goal is to know where in memory a bunch of structures are, it wouldn't be that hard for him to put in a [PRINTOFFSETS] in an init file and then have DF spit out the & memory addresses of the data structures of interest?)His initial reaction when DFhack first was created was to get upset and try to shut it down. Since then he's realized it's not really such a problem, but Toady is not very comfortable with giving other people increased access to his codebase.
There's a decent availability of IDA Pro copies fallen off the back of a truck. Seems like the problem isn't too hard to solve if you're not overly burdened by moral compunctions.
His initial reaction when DFhack first was created was to get upset and try to shut it down. Since then he's realized it's not really such a problem, but Toady is not very comfortable with giving other people increased access to his codebase.
I wonder if a paypal bounty fund would help or hurt the process; competitive secrecy vs motivation.Is there a pre-alpha for 43.05?We've tried doubling the volunteers' pay ($0x2=$0), but it turns out that no one is slacking and it's just taking a long time.
His initial reaction when DFhack first was created was to get upset and try to shut it down. Since then he's realized it's not really such a problem, but Toady is not very comfortable with giving other people increased access to his codebase.
That was splash damage when someone was working on a "visualizer" for DF who intended to reverse-engineer it and make his own version. He contacted Peterix and Toady banned both, then unbanned Peterix after they talked about it. Nobody smart enough to reverse-engineer Dwarf Fortress is dumb enough to think they can out DF Toady. I don't have a link but someone else might.
I wonder if a paypal bounty fund would help or hurt the process; competitive secrecy vs motivation.Is there a pre-alpha for 43.05?We've tried doubling the volunteers' pay ($0x2=$0), but it turns out that no one is slacking and it's just taking a long time.
I wonder if a paypal bounty fund would help or hurt the process; competitive secrecy vs motivation.Is there a pre-alpha for 43.05?We've tried doubling the volunteers' pay ($0x2=$0), but it turns out that no one is slacking and it's just taking a long time.
Does "visualizer" mean things like Stonesense and Armok Vision?
That was splash damage when someone was working on a "visualizer" for DF who intended to reverse-engineer it and make his own version. He contacted Peterix and Toady banned both, then unbanned Peterix after they talked about it. Nobody smart enough to reverse-engineer Dwarf Fortress is dumb enough to think they can out DF Toady. I don't have a link but someone else might.
http://www.bay12forums.com/smf/index.php?topic=58796.0
I think I picked up some lingering discomfort regarding the nature of DFHack; I remember the phrase "slippery slope" coming up in conversation at Dwarfmoot? DFHack as it is now he's fine with, certainly (otherwise it wouldn't be here).
I wonder if a paypal bounty fund would help or hurt the process; competitive secrecy vs motivation.
The hell is "competitive secrecy"?
He and peterix were working on Khazad, which was a very early visualizer, similar to Armok Vision.
Then he decided to start his own project, an open-source DF, that will be better in every way, and everybody should join the project and leave DF, and anybody who continues to support a closed-source DF is stupid and yadda yadda.
That's when he got banned.
He still occasionally tries to recruit me over skype.
Hmm... haven't been looking recently, but when 64-bit was first released, I thought I saw reports of much better performance on larger embarks or world histories. I thought that would likely expand to an older fortress' accumulated junk.That was me. I tested the same exact world-gen/seed/everything except on 32 and 64 bit.
32 bit started: 11:21:30, hit stop 11:24:30, finished 11:24:45 on year 184.
32 bit pops:
>56349 Dwarves
>30427 Humans
>48514 Elves
>11572 Goblins
>3913 Kobolds
>Total: 150775
64 bit started: 11:27:30, hit stop 11:30:30, finished 11:30:36 on year 186.
64 bit pops:
>59593 Dwarves
>33106 Humans
>42689 Elves
>12330 Goblins
>10884 Kobolds
>Total: 158602
test64 start: 10:38:30, stop: 10:54:01, finished: 10:54:34 (year 300), 16:04 total worldgen
64 bit pops:
>60553 Dwarves
>32485 Humans
>51199 Elves
>36119 Goblins
>5738 Kobolds
>Total: 186094
test32 start: 10:56:30, target: 11:12:01 (year 286),stop: 11:13:24, finish: 11:14:05 (year 300), 18:05 total worldgen
32 bit pops:
>54795 Dwarves
>28097 Humans
>45384 Elves
>27181 Goblins
>8280 Kobolds
>Total: 163737
So in summary, 64 bit world-gen reaches the same year earlier, despite having significantly higher populations (23k+ in the 300 year test), responds faster to the stop signal, and takes longer to slow down as badly as the 32 bit world-gen.Anyway, I personally think some alpha version for osx/win64 could be released now. Or are there are any specific (missing/broken) things that holding off the release?Mainly offsets (different ones on different platforms, but I think all of them are missing debug flags, and 64-bit Linux and Windows are missing more). It's not a deal-breaker for an alpha release, probably, as long as people realize what's missing.
That was me. I tested the same exact world-gen/seed/everything except on 32 and 64 bit.
I'm not interested in doing any 32bit work (my opinion is that we should drop 32bit support to make our lives easier).uld be released now. Or are there are any specific (missing/broken) things that holding off the release?
[Analyzer] determining function types...
[Analyzer] complete
[Analyzer] elapsed: 830 ms
[Analyzer] region unchanged, using previous analysis
[Analyzer] elapsed: 2 ms
[Analyzer] region unchanged, using previous analysis
[Analyzer] elapsed: 1 ms
[Analyzer] identifying executable headers...
[Analyzer] adding entry points to the list...
[Analyzer] found entry point: 0x408ef6
[Analyzer] attempting to add 'main' to the list...
No main symbol found, calculated it to be "00000000004050c0" using heuristic
[Analyzer] attempting to add functions with symbols to the list...
[Analyzer] attempting to add marked functions to the list...
[Analyzer] attempting to collect functions with fuzzy analysis...
I couldn't find 0x408ef6 in https://github.com/DFHack/df-structures/blob/master/symbols.xml but I have no idea if that means anything unfortunately, just going by the stuff that I could figure out, I tried to point it at something in the stack which mentioned the keybind for move cursor left, and trace that back to the start of the function a couple times after hitting said key but it froze up when I was trying to analyze the parent I think.
Yeah, the unit all/active/bad lists aren't populated yet, ui_advmode isn't known, cur_season, created_item_* globals, various others.On what build and OS? Those are part of world, so if they're empty and shouldn't be, that's an issue with world's address or layout.
The legacy version of Dwarf Fortress isn't supported by DFHack either, so there's precedence for not supporting everything.Yeah, but that's not the same thing at all. The legacy version does not use SDL, which DFHack requires in order to hook in. Also, the legacy and SDL versions are otherwise identical besides the rendering engine they use, which isn't true of the 32/64-bit difference.
Plugin isoworldremote is missing required globals: cur_season
Plugin strangemood is missing required globals: created_item_count, created_item_type, created_item_subtype, created_item_mattype, created_item_matindex
Plugin sort is missing required globals: ui_building_assign_type, ui_building_assign_is_marked, ui_building_assign_units, ui_building_assign_items
Plugin search is missing required globals: ui_building_assign_units, ui_look_list
Plugin rendermax is missing required globals: cur_year_tick
Plugin zone is missing required globals: cur_year_tick, ui_building_assign_type, ui_building_assign_is_marked, ui_building_assign_units, ui_building_assign_items
Plugin jobutils is missing required globals: job_next_id
Plugin workflow is missing required globals: job_next_id
Could not activate tweak fast-heat (fast_heat_hook::updateTempFromMap)
Could not activate tweak fast-heat (fast_heat_hook::updateTemperature)
Could not activate tweak fast-heat (fast_heat_hook::adjustTemperature)
Cannot enable plugin: search
multilevel is not a recognized command.
DFHack is ready. Have a nice day!
DFHack version 0.43.05-alpha0 (development build 0.43.03-r1-160-g714ba1a)
Type in '?' or 'help' for general help, 'ls' to see all commands.
[DFHack]
# gui/gm-editor df.global.ui_advmode
[string "expression"]:1: Cannot read field global.ui_advmode: global address not known.
stack traceback:
[C]: in metamethod '__index'
[string "expression"]:1: in main chunk
(...tail calls...)
/home/thefunk/.df/hack/scripts/gui/gm-editor.lua:535: in local 'f'
./hack/lua/dfhack.lua:562: in function 'dfhack.run_script_with_env'
(...tail calls...)
[DFHack]#
Another announcement of sorts:
It turns out Ruby 1.8 (which we use) doesn't actually compile for 64-bit Windows, at least not without techniques that nobody has investigated. Ruby 2+ would compile, but I don't know if it would work, so I'm waiting on jjyg for that.
Besides that, I can't think of any major blockers for a pre-release (there are some for a stable release). Do note that if we did put up a build now, no ruby scripts would work at all in the 64-bit Windows build. (I suppose now would be a good time to convert "multicmd" to a built-in command, before that becomes an issue.)
The biggest issue (at least as i understand it) is that the wrapper for lua is mostly automatically generated from layouts. While the ruby wrapper is handcrafted to some extent. Ideal case would be extending lua wrapper generation to support other languages.Another announcement of sorts:
It turns out Ruby 1.8 (which we use) doesn't actually compile for 64-bit Windows, at least not without techniques that nobody has investigated. Ruby 2+ would compile, but I don't know if it would work, so I'm waiting on jjyg for that.
Besides that, I can't think of any major blockers for a pre-release (there are some for a stable release). Do note that if we did put up a build now, no ruby scripts would work at all in the 64-bit Windows build. (I suppose now would be a good time to convert "multicmd" to a built-in command, before that becomes an issue.)
Hmm. Just to float the idea, what are the arguments for and against dropping Ruby support?
Keep Ruby: seriously, it's fine. Why break what works? People actually do use it!
Drop Ruby:To be clear, I'm not proposing that we should drop Ruby support because it's run into a problem here - it's because Ruby has been a second-class scripting language in DFHack for some time now, the total absence of documentation is annoying me, and it makes supporting other things (eg unifying in-console help) more difficult.
- No API documentation at all
- Relatively poor structures API (I think? Hard to tell when there's no docs...)
- Standardising on Lua would free up developer resources
- Fewer scripts - there are 190 .lua and 38 .rb files in the dfhack repo; 147 to 28 in the scripts repo.
- Fixing and maintaining Ruby support might be a similar amount of work to dropping it and a one-off porting effort; especially if fixing it involves a useful degree of documentation.
- It makes tooling more difficult (number of languages installed, cases for build systems, docs support, etc) for developers and deters new contributors.
Hmm. Just to float the idea, what are the arguments for and against dropping Ruby support?Is it Ruby support that's keeping us back on VS2010 for Windows? Edit: Or is the compile page (https://dfhack.readthedocs.io/en/latest/docs/Compile.html#windows) just out of date with respect to 64-bit DF?
Hmm. Just to float the idea, what are the arguments for and against dropping Ruby support?Is it Ruby support that's keeping us back on VS2010 for Windows? Edit: Or is the compile page (https://dfhack.readthedocs.io/en/latest/docs/Compile.html#windows) just out of date with respect to 64-bit DF?
I've been meaning to try my hand at compiling DFHack (and possibly finding offsets,) but I don't really want to deal with any issues installing VS2010 over VS2013.
The problem with Ruby is that the code contains some assembly language parts which are not supported by VS compiler on 64bit.The only assembly code I see in plugins/ruby is in ruby.cpp:
#ifdef WIN32
__declspec(naked) static int raw_vcall(void *that, void *fptr, unsigned long a0,
unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5)
{
// __thiscall requires that the callee cleans up the stack
// here we dont know how many arguments it will take, so
// we simply fix esp across the funcall
__asm {
push ebp
mov ebp, esp
push a5
push a4
push a3
push a2
push a1
push a0
mov ecx, that
call fptr
mov esp, ebp
pop ebp
ret
}
}
#else
#ifdef WIN64
__declspec(naked) static int raw_vcall(void *that, void *fptr, unsigned long a0,
unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5)
{
// __thiscall requires that the callee cleans up the stack
// here we dont know how many arguments it will take, so
// we simply fix rsp across the funcall
__asm {
push rbp
mov rbp, rsp
push a5
push a4
push a3
push a2
push a1
push a0
mov rcx, that
call fptr
mov rsp, rbp
pop rbp
ret
}
}
Although, I'm not really sure what this function "raw_vcall" is doing, or why the function at fptr wants a pointer to "that" in the CX register (conventionally the 4th parameter, after DI, SI, DX.)Which (I think) we would just add:
So you'd have to assemble separately and use extern, if that's even possible with DF?Which (I think) we would just add:MSVC compiler does not support __asm when compiling for 64bit.
So you'd have to assemble separately and use extern, if that's even possible with DF?Which (I think) we would just add:MSVC compiler does not support __asm when compiling for 64bit.
Or could you use these: https://msdn.microsoft.com/en-us/library/hh977022.aspx (https://msdn.microsoft.com/en-us/library/hh977022.aspx)?
Hmm. Just to float the idea, what are the arguments for and against dropping Ruby support?The structures API is just as good as Lua's (otherwise it would be pretty useless). The way it's implemented makes it somewhat slower when you try to do certain things, from what I remember from BenLubar's projects, but that's not something that would be explained in detail in the API docs anyway.
Keep Ruby: seriously, it's fine. Why break what works? People actually do use it!
Drop Ruby:
- No API documentation at all
- Relatively poor structures API (I think? Hard to tell when there's no docs...)
Yes, once we rewrite everything in Ruby, which is not a small task.
- Standardising on Lua would free up developer resources
I got 42 to 11 on the develop branch (https://github.com/DFHack/dfhack/find/develop). It's worth noting that those are all libraries, so all that means is that the parts of the Lua API written in Lua are more comprehensive and/or split into more files.
- Fewer scripts - there are 190 .lua and 38 .rb files in the dfhack repo; 147 to 28 in the scripts repo.
Ruby 2 shouldn't be too much harder to get working. It just requires enough familiarity with the Ruby interpreter to fix whatever issues come up, which I don't have.
- Fixing and maintaining Ruby support might be a similar amount of work to dropping it and a one-off porting effort; especially if fixing it involves a useful degree of documentation.
Developers do not have to install Ruby, or Lua, at all. Both of those interpreters are bundled with DFHack.
- It makes tooling more difficult (number of languages installed, cases for build systems, docs support, etc) for developers and deters new contributors.
Quote from: gchristopherWould you consider making the lives of the DFHack and other tool creators easier somehow? It seems like if Dwarf Fortress had an init or command line option where it would print out the memory address/offsets of all the key structures, then the community would be on much easier footing to quickly catch up to DF releases. That wouldn't expose any proprietary code or be nearly the effort of implementing a full mod API, since all you'd need to add is print statements for requested structure memory addresses, right?
There have been conversations along these lines over the years, though it has been a while on this particular matter. Utility people can and do PM me. I really don't recall where it was left last time it came up, or if it was decided that finding memory addresses was the fun part?
FWIW, Toady had a pretty friendly response to a question that (as a non-contributor to DFHack or Therapist) was really none of my business.Quote from: gchristopherWould you consider making the lives of the DFHack and other tool creators easier somehow? It seems like if Dwarf Fortress had an init or command line option where it would print out the memory address/offsets of all the key structures, then the community would be on much easier footing to quickly catch up to DF releases. That wouldn't expose any proprietary code or be nearly the effort of implementing a full mod API, since all you'd need to add is print statements for requested structure memory addresses, right?
There have been conversations along these lines over the years, though it has been a while on this particular matter. Utility people can and do PM me. I really don't recall where it was left last time it came up, or if it was decided that finding memory addresses was the fun part?
-- dfhack.gui.makeAnnouncement does not work. The problem lies in assigning the position, no matter what you pass
-- for the position it fails to work.
--dfhack.gui.makeAnnouncement(df.announcement_type.CANCEL_JOB, df.announcement_flags.D_DISPLAY, unit.pos, msg, COLOR_LIGHTRED)
-- The following is the above function reimplemented (more-or-less faithfully) in Lua
local msg = strings.replace(hook.msg, "%name", dfhack.TranslateName(dfhack.units.getVisibleName(unit)))
dfhack.gui.writeToGamelog(msg)
local continued = false
while msg ~= "" do
local new_rep = df.report:new()
new_rep.type = df.announcement_type.CANCEL_JOB
-- new_rep.pos = unit.pos will fail with an error. This is why dfhack.gui.makeAnnouncement fails.
new_rep.pos.x = unit.pos.x
new_rep.pos.y = unit.pos.y
new_rep.pos.z = unit.pos.z
new_rep.color = COLOR_LIGHTRED
new_rep.year = df.global.cur_year
new_rep.time = df.global.cur_year_tick
new_rep.flags.continuation = continued
new_rep.flags.announcement = true
local nmsg = ""
if #msg > 73 then
nmsg = string.sub(msg, 1, 73)
msg = string.sub(msg, 74)
else
nmsg = msg
msg = ""
end
new_rep.text = nmsg
continued = true
new_rep.id = df.global.world.status.next_report_id
df.global.world.status.next_report_id = df.global.world.status.next_report_id + 1
df.global.world.status.reports:insert('#', new_rep)
df.global.world.status.announcements:insert('#', new_rep)
df.global.world.status.display_timer = 2000
end
"finding memory addresses was the fun part"? What planet does he live on?
The statement makes a lot more sense when you put the ‼ symbols on the fun."finding memory addresses was the fun part"? What planet does he live on?
Maybe he meant that it's more fun for him.
The statement makes a lot more sense when you put the ‼ symbols on the fun.
I have long believed that if Toady would just release the header files for DF the world would be a much nicer place...I kinda found discovering the how stuff worked in this game Fun. led to some fun discoveries and dfhack scripts/pluginsThe statement makes a lot more sense when you put the ‼ symbols on the fun.
I knew something was missing :P
In other news: I have discovered that "dfhack.gui.makeAnnouncement" (and a few related functions) do not work. The problem is that no matter what you pass for the position argument it will be the wrong type. (...)This was already discussed on Github (https://github.com/DFHack/dfhack/issues/999), but for anyone who didn't check, the problem was with the second argument (flags):
df.announcement_flags.D_DISPLAY
Thanks. I had to dig around for how to access some of the relevant data, but this was enough for me to put together a toggleaquifer script that suits my purposes. It seems that the rock/soil type does not in fact need to be tagged as aquifer for this to work, and in particular the veins and inclusions can be made into aquifer. So, it was necessary to test that the tiletype is not MineralWall. I also added checks for surrounding open blocks, so that exposed edges don't begin to leak. (Though it is amusing for a slope to just start leaking all over the landscape.)
Linux is nice and easy, git clone *dfhack addy*, cd dfhack, git checkout develop, git submodule --init, cd build, ccmake .., configure it for 64 bit architecture, generate and exit, make install, wait.Linux is nice and easy*
Linux is nice and easy, git clone *dfhack addy*, cd dfhack, git checkout develop, git submodule --init, cd build, ccmake .., configure it for 64 bit architecture, generate and exit, make install, wait.If this was a reply to me, the Linux build instructions changed too. It's mostly just recommending GCC 4.8 instead of 4.5 now, but there are a couple other changes that could cause people issues if they try using old instructions to build DFHack for 0.43.05.
Well, as I say, if you can play df, you can install linux... though I don't remember how I installed arch anymore, but just from checking the latest and stable docs both have the same info, clone > checkout dev > cmake/ccmake > build. Same info in the compile.rst on github.Linux is nice and easy, git clone *dfhack addy*, cd dfhack, git checkout develop, git submodule --init, cd build, ccmake .., configure it for 64 bit architecture, generate and exit, make install, wait.Linux is nice and easy*
* easy when it works
* nice when you are used to building stuff for yourself
* when it does not break in some arcane way
:D
Looks like the Workflow plugin isn't working either. I'm messing with the new manager jobs and conditions system thats new in 43.xx, which pretty much replaces Workflow anyway (or would if i could work the darn thing out), so all good.
Workflow plugin has been removed for exactly that reason, actually.
It wasn't removed - PE just took out the keybindings for it.
Actually the keybindings were removed upstream, by the DFHack maintainers. The plugin still exists. I will however remove the launcher option for Workflow to prevent further confusion.
…
Oh, yeah, that was Eswald that removed the bindings. I don't know if anyone has done a full analysis of whether workflow/stockflow can be removed entirely or not yet.
If I could figure out how to use the new management system to enable limits I'd happily give up on workflow.. in the meantime, for those happy with the constant log spam when workers run out of resources, here's how to enable it (with thanks to the poster in the dfhack thread):Spoiler (click to show/hide)
The Starter Pack has updated to 0.43.03-r03!
As usual, you can get it here. (http://dffd.bay12games.com/file.php?id=7622)
This update checks off a range of new and old bugs, along with some new bugs caused by old bugs. Fun all round.
Hopefully I won't find anything else that needs fixing before a 64bit pack is ready with 43.05... or perhaps a later version. Time to strike the earth!
0.43.03-r03
- DungeonSet: can select in launcher, change on saves correctly, better text tileset
- updated Armok Vision (bugfix)
- added Therapist config (absent due to subtle old bug)
- fixed SoundSense log config
- removed Workflow option in launcher (replaced by vanilla manager upgrade)
SHA256: e2de47c4ec181ad3de39ab403bd6354c3a92e394273cb34bd0f231205ddfb956
If you want to say thanks, check out Toady's Patreon (https://www.patreon.com/bay12games), or even mine! (https://www.patreon.com/PeridexisErrant) ;D
Thanks PE, as always you're amazing
EDIT: Now that i've got the manager stuff working nicely with repeatable jobs and conditions, i haven't found any uses yet for needing Workflow at all so far, so more than happy to use the built in one
It's still useful for somethings the new work order conditions can't seem to handle like milling plants or processing into bags of leaves (although I don't think even workflow can deal with leaves). Dumping filled buckets doesn't hurt either.
No reason for it to be up front and center though.
I don't think gui/workshop-job (http://dfhack.readthedocs.io/en/stable/docs/_auto/gui.html#gui-workshop-job) can be used without workflow.It definitely can.
I mean you can't automate it using work orders. It works for a single job or a repeat (until failure) job.I don't think gui/workshop-job (http://dfhack.readthedocs.io/en/stable/docs/_auto/gui.html#gui-workshop-job) can be used without workflow.It definitely can.
[DFHack]# ambidwarf
error loading module 'luars232' from file 'C:\dfhack\luars232.dll':
Uvedenř modul nebyl nalezen.
stack traceback:
[C]: in ?
[C]: in function 'require'
C:\dfhack/hack/scripts/ambidwarf.lua:1: in function 'f'
C:\dfhack\hack\lua\dfhack.lua:562: in function <C:\dfhack\hack\lua\dfhack.lua:503>
(...tail calls...)
I have issue with using third party LUA library. Basically, I want to be able to send data to serial port from withing DFhack scripts.In cases like these it really helps if you translate the error message into english. However my guess is that it says "Could not load the module"
Console says this:Code: [Select][DFHack]# ambidwarf
error loading module 'luars232' from file 'C:\dfhack\luars232.dll':
Uvedenř modul nebyl nalezen.
stack traceback:
[C]: in ?
[C]: in function 'require'
C:\dfhack/hack/scripts/ambidwarf.lua:1: in function 'f'
C:\dfhack\hack\lua\dfhack.lua:562: in function <C:\dfhack\hack\lua\dfhack.lua:503>
(...tail calls...)
Only setup I have made is copying luars232.dll file to C:\dfhack directory (it comes from project here: https://github.com/ynezz/librs232/downloads )
Script is so far just renamed example for library from here: https://github.com/ynezz/librs232/blob/master/doc/example.lua
I am sure I am doing something wrong, but i have too litle experience with lua to know what :-)
I have issue with using third party LUA library. Basically, I want to be able to send data to serial port from withing DFhack scripts.In cases like these it really helps if you translate the error message into english. However my guess is that it says "Could not load the module"
Console says this:Code: [Select][DFHack]# ambidwarf
error loading module 'luars232' from file 'C:\dfhack\luars232.dll':
Uvedenř modul nebyl nalezen.
stack traceback:
[C]: in ?
[C]: in function 'require'
C:\dfhack/hack/scripts/ambidwarf.lua:1: in function 'f'
C:\dfhack\hack\lua\dfhack.lua:562: in function <C:\dfhack\hack\lua\dfhack.lua:503>
(...tail calls...)
Only setup I have made is copying luars232.dll file to C:\dfhack directory (it comes from project here: https://github.com/ynezz/librs232/downloads )
Script is so far just renamed example for library from here: https://github.com/ynezz/librs232/blob/master/doc/example.lua
I am sure I am doing something wrong, but i have too litle experience with lua to know what :-)
As for the problem itself - my guess is that dfhack does not export/include the required lua lib(s)? or they are of incorrect version. Rebuilding the lib with same lua might help.
It runs pretty well. There are some offsets missing, but not too many.
If people don't mind about a lack of 64-bit ruby support and some missing offsets, it might be possible to make an alpha release (with "alpha" in this case meaning incomplete but possible to test with).
Can you post the error message? It looks like it relies on cur_year_tick (which is unavailable) if age is 0, and cur_year (which is available) if age is specified. I'm not sure what else the issue would be, so if it's something else, that would be nice to know. Detecting the specific DFHack build is not the way to go - if anything, use dfhack.internal.getAddress('cur_year_whatever'), which returns nil for missing offsets.I didn't actually build from source or anything, just know what create-unit needs. That .internal.getAddress idea is really powerful. Might actually be able to wrap that in a sort of safe-access function that allows some error handling.
(Come to think of it, I'm not sure if there is a way to detect the DF platform/architecture in Lua without manually parsing the version string from symbols.xml, i.e. dfhack.getDFVersion().)
I think the viewscreen offsets are missing too at least on linux64, I use a few scripts and some diagnosis methods involving checking gview.(child...child).df_viewscreen_* stuff so that stood out to me.Are you using the latest df-structures commit? The viewscreenst vtable was one that failed, but I checked it manually, so gview should be located now too. viewscreen_layerst is still missing, but I don't think that's ever instantiated directly by DF.
I'll get the structures fixed once I get woken up abit more, but for what it's worth here's the malloc from running valgrind with dfhack to figure out why loading armok vision triggers a memory leak that eats all the ramz.I think the viewscreen offsets are missing too at least on linux64, I use a few scripts and some diagnosis methods involving checking gview.(child...child).df_viewscreen_* stuff so that stood out to me.Are you using the latest df-structures commit? The viewscreenst vtable was one that failed, but I checked it manually, so gview should be located now too. viewscreen_layerst is still missing, but I don't think that's ever instantiated directly by DF.
DFHack version 0.43.05-alpha0 (development build 0.43.03-r1-161-ga5338d2)
Type in '?' or 'help' for general help, 'ls' to see all commands.
[DFHack]# die
==17690==
==17690== HEAP SUMMARY:
==17690== in use at exit: 30,685 bytes in 822 blocks
==17690== total heap usage: 4,890 allocs, 4,068 frees, 212,579 bytes allocated
==17690==
==17690== 12 bytes in 1 blocks are definitely lost in loss record 100 of 314
==17690== at 0x4C29BBE: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17690== by 0x46B16F: xmalloc (in /usr/bin/bash)
==17690== by 0x465068: set_default_locale (in /usr/bin/bash)
==17690== by 0x418688: main (in /usr/bin/bash)
==17690==
==17690== LEAK SUMMARY:
==17690== definitely lost: 12 bytes in 1 blocks
==17690== indirectly lost: 0 bytes in 0 blocks
==17690== possibly lost: 0 bytes in 0 blocks
==17690== still reachable: 30,673 bytes in 821 blocks
==17690== suppressed: 0 bytes in 0 blocks
==17690== Reachable blocks (those to which a pointer was found) are not shown.
==17690== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==17690==
==17690== For counts of detected and suppressed errors, rerun with: -v
==17690== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
@Codician: Are you sure it's DFHack and Windows 10, rather than attempting to use DFHack with an as yet unsupported version of DF (such as 0.43.04 or 0.43.05)? The LNP (which includes DFHack) works fine for the latest supported version of DF (0.43.03) for me, and I haven't seen the wave on complaints from others expected from such a problem.
Apart from that, "seems to have a problem with" is a rather unhelpful problem description. It would help in the determination of what's wrong if you stated in which way it fails. Error messages in particular can contain useful info.
DFHack seems to be having a problem with Windows 10.
DFHack works by replacing the game's SDL.dll with its own versionon Windows only. I suspect the confusion here was partly due to the fact that it doesn't do this on OS X and Linux, but uses a separate launcher script instead.
http://dffd.bay12games.com/file.php?id=12504
Here's a pre-alpha for DFHack windows 43.05 x64. I mainly built it so people can use Armok Vision, but other things might also work.
You're looking at the wrong branch - "master" is only for the last official release (which was quite a while ago), while "develop" has up-to-date stuff for 0.43.05.http://dffd.bay12games.com/file.php?id=12504
Here's a pre-alpha for DFHack windows 43.05 x64. I mainly built it so people can use Armok Vision, but other things might also work.
How did you manage this? The old batch file setup in \dfhack\build seems to be all sorts of busted.
.\build\win64\generate-MSVC-gui.bat
Configure->Use default native compilers
Open dfhack.sln in VS2015
Build->Configuration manager
New x64 from win32 settings
Switch to Release configuration
Right-click INSTALL -> Build
fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'
I did:You did something wrong, then - there should only be an "x64" build configuration. Perhaps your version of CMake is out of date? I've got 3.6.1 and it works fine.Code: [Select]Build->Configuration manager
New x64 from win32 settings
You're looking at the wrong branch - "master" is only for the last official release (which was quite a while ago), while "develop" has up-to-date stuff for 0.43.05.
Running the generate-* batch files complains about not being able to find a CMakeLists.txt in the next folder up, like the old arrangement was.
I'm using develop branch and having issues building for x64.
I did:Code: [Select].\build\win64generate-MSVC-gui.bat
Configure->Use default native compilers
Open dfhack.sln in VS2015
Build->Configuration manager
New x64 from win32 settings
Switch to Release configuration
Right-click INSTALL -> Build
I get a bunch of:Code: [Select]fatal error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'
Edit: Using Windows 7 64-bit. I might be way behind on Windows Updates since I reformatted the machine. Going to try updating.
You did something wrong, then - there should only be an "x64" build configuration. Perhaps your version of CMake is out of date? I've got 3.6.1 and it works fine.It's 3.6.1. Edit: Issue was out-of-date Windows.
There is no "win64generate-MSVC-gui.bat" in the build folder. If you have that, then you have the wrong branch of DFHack.Just a typo. Should be "win64\generate-MSVC-gui.bat".
No, I'm deffo pulling the development branch, the one with the x64-specific stuff. Running the generate-* batch files complains about not being able to find a CMakeLists.txt in the next folder up, like the old arrangement was. If I kick the .bat pile back to the \build folder like they used to be, it cannot find C/CXX compilers (line 22).I got that to work by running it from a cmd prompt sitting in the \dfhack directory. E.g., "C:\dfhack>.\build\win64\generate-MSVC-gui.bat". Then you can just select "\dfhack" as the source code directory (CMakeLists.txt is located here) from the GUI.
They should be compatible. No one has reported any problems so far. If the saves from the 32- and 64-bit versions ever become incompatible with each other, it would probably be because of a weird bug or something....and then weaponized.
So now we have working DFHack for x64 and DT for x32 ;-)And 32-bit DFHack...
32x dfhack?! Who does have it? I see here only 64x.So now we have working DFHack for x64 and DT for x32 ;-)And 32-bit DFHack...
Is there a simple way to cancel jobs from within dfhack?We should add cancel function to dfhack job module
I'm working on editing dig designations from within Armok Vision, but I need to be able to cancel ones that have already been converted into jobs.
Can we somehaow change environment savagery and evilness?Not easily.
I don't think the necessary symbols exist for 0.43.05 yet, though.What? What symbols are those? All I can think of is "world", which should definitely be there.
Do you mean in-game hours (i.e. messing with the fields you were talking about)?in game hours for building stuff in adventure mode.
I miss 'fixdiplomats' though.. have a sneaking suspicion that the Elves have stopped visiting.There are two problems with that statement:
What changes when you have companions?companions just divide the time it takes for you to build stuff, I haven't found a way to quickly build stuff yet as I was working on passing the time through construction manipulation.
I'd check myself but I don't see linux 64 bit ui_advmode symbols yet.What changes when you have companions?companions just divide the time it takes for you to build stuff, I haven't found a way to quickly build stuff yet as I was working on passing the time through construction manipulation.
I guess there might be a way to pump the number high enough.
at this point I'm kinda focused on night trolls and if resurrection would cure a mate's curse or not.
-- Install a periodic ticker that kills saplings over a certain count.
do return end -- Remove this once I figure out a good way to calculate a sapling limit.
-- TODO: Change the way this works:
-- Rather than set a sapling limit set a tree limit. At the game start get a tree count, then use that
-- (plus a few) as the tree cap. Then if there are more trees than the limit delete all saplings, else
-- allow saplings to grow as they will. This will preserve the relative amount of trees on the map at
-- all times. If you embark in a heavily forested biome it will always be heavily forested, while grass
-- lands will remain mostly grass.
-- How many saplings to leave alive on the surface.
local livecount = 25
local function treeTicker()
-- Get a list of all the saplings on the map.
local plants = df.global.world.plants.all
local saplings = {}
for i = 0, #plants - 1, 1 do
local plant = plants[i]
local ttype = dfhack.map.getTileType(plant.pos)
if not plant.flags.is_shrub and df.tiletype.attrs[ttype].shape == df.tiletype_shape["SAPLING"] and df.tiletype.attrs[ttype].special ~= df.tiletype_special["DEAD"] then
-- plant is a live sapling...
if df.tiletype.attrs[dfhack.map.getTileType(plant.pos.x, plant.pos.y, plant.pos.z-1)].material == df.tiletype_material["SOIL"] then
-- ...growing in a soil layer (probably the surface).
table.insert(saplings, {i = i, ref = plant})
end
end
end
-- Choose random saplings to delete...
local del = {}
for #saplings > livecount do
local i = math.random(1, #saplings)
local plant = saplings[i]
table.insert(del, plant)
table.remove(saplings, i)
end
-- ...and sort the list in reverse order by index in plants.all
table.sort(del, function(a, b)
return a.i > b.i
end)
-- Finally delete the selected saplings.
for _, plant in ipairs(del) do
local block = dfhack.maps.ensureTileBlock(plant.pos.x, plant.pos.y, plant.pos.z)
block.tiletype[plant.pos.x%16][plant.pos.y%16] = df.tiletype["SoilFloor1"]
-- The list is high indexes to low indexes, so we can just delete from the list without fear of messing up later indexes.
df.global.world.plants.all:erase(plant.i)
-- Plants do not have an ID number, so we need to compare them based on location.
for j = 0, #df.global.world.plants.tree_dry - 1, 1 do
if same_xyz(df.global.world.plants.tree_dry[j].pos, plant.ref.pos) then
df.global.world.plants.tree_dry:erase(j)
break
end
end
for j = 0, #df.global.world.plants.tree_wet - 1, 1 do
if same_xyz(df.global.world.plants.tree_wet[j].pos, plant.ref.pos) then
df.global.world.plants.tree_wet:erase(j)
break
end
end
plant.ref:delete()
end
-- Every 60 seconds (at 100 FPS) should be fast enough.
dfhack.timeout(6000, 'ticks', treeTicker)
end
treeTicker()
Try replacing hack/scripts/teleport.lua with the latest script from https://github.com/DFHack/scripts/blob/master/teleport.lua
Global variables can work like that, and we should have something there for next time.Is good?
What file specifically do I need to upload?The entire region1 folder. Compress it with 7-Zip (http://www.7-zip.org/) (make a ".7z" file, not a ".zip" file) and it'll take a lot less time to upload to DFFD.
Region1 uncompressed is 1.3 GB.
World.sav uncompressed is 791 MB.
df.global.world.worldgen_parms.seedThat's for the entire world - if you want seeds for each region tile, you probably want world_region_details.
I was trying to make a artifact mod, with weapons and armor that can only be created with a mood, and that said artifacts are magical, but there were problems
- it seems to work when the items are picked up, not actually wielded or worn
- it seems to stop working when the items are put down, but it doesn't end the syndromes. the speed boots continued to speed up people after they put it down
- the weapons that are supposed to put syndromes on hit enemies don't work
- none of the things that would require locations work(the hellhammer can't create a hfs-pit on a hit enemy, or create a summoned demon)
You're going to have to create a separate -onUnequip for that.I did as you can see. But while the syndrome was removed, the creature was still speeded up. then a adventurer who never got anywhere near a speedboot suddenly got very fast, which I used to good to use to retrieve the luckblade
Download Link. (http://dffd.bay12games.com/file.php?id=12556)Vanilla export worked, though.
[DFHack]# Segmentation fault (core dumped)
Invoking: exportlegends info
...\Desktop\df 43.05/hack/scripts/exportlegends.lua:184: Cannot invoke field (global).TranslateName(): C++ exception: bad allocation.
stack traceback:
[C]: in function 'dfhack.TranslateName'
...\Desktop\df 43.05/hack/scripts/exportlegends.lua:184: in global 'export_more_legends_xml'
...\Desktop\df 43.05/hack/scripts/exportlegends.lua:765: in global 'export_legends_info'
...\Desktop\df 43.05/hack/scripts/exportlegends.lua:822: in local 'f'
\Desktop\df 43.05\hack\lua\dfhack.lua:562: in function 'dfhack.run_script_with_env'
(...tail calls...)
I am also getting an error on exporting legends using win 64bit DFHack 0.43.05-alpha1-0-g4d74090. Am a DFhack noob and didn't expect everything to work on 64bit anyway, but figured I'd report.Your issue looks a lot like https://github.com/DFHack/dfhack/issues/1005, which should be fixed in the next release.
Save if useful: http://dffd.bay12games.com/file.php?id=12573 (A rather unweildy 100mb 900ish year world)QuoteInvoking: exportlegends info
...\Desktop\df 43.05/hack/scripts/exportlegends.lua:184: Cannot invoke field (global).TranslateName(): C++ exception: bad allocation.
stack traceback:
[C]: in function 'dfhack.TranslateName'
...\Desktop\df 43.05/hack/scripts/exportlegends.lua:184: in global 'export_more_legends_xml'
...\Desktop\df 43.05/hack/scripts/exportlegends.lua:765: in global 'export_legends_info'
...\Desktop\df 43.05/hack/scripts/exportlegends.lua:822: in local 'f'
\Desktop\df 43.05\hack\lua\dfhack.lua:562: in function 'dfhack.run_script_with_env'
(...tail calls...)
Aye, might be world-specific. Very young world, currently in 3rd year limestone as of save:I've gotten through the stage that was crashing, so it could be the same issue. However, I'm getting crashes in what appear to be the vanilla export stages now (mostly the drainage map, but one hang on the standard biome+site map), which is weird.Download Link. (http://dffd.bay12games.com/file.php?id=12556)Vanilla export worked, though.
Your issue looks a lot like https://github.com/DFHack/dfhack/issues/1005, which should be fixed in the next release.
No unit is selected in the UI.
Error: please select a unit or pass its id as an argument.
Try full-heal -r
Hmmm, I'm a bit drowsy, but couldn't you just lua search for the df.global.world.armies entry with the target being your site.id? I think it was under the controller subfield though, if you knew the general range of pos_x and pos_y which your fort covers you could manually dump them outside the boundaries.
Sorry for the many delays there.
How would I go about submitting scripts for inclusion in DFHack? What repository should I use? (I assume the process is fork>add script>submit pull request)
What are we missing for a full release of dfhack for the 64bit version? How can I help developing or researching memory layouts etc? I searched for answers on the forum for an hour, but could not find a good starting point. Could someone please provide one? Sorry about the openness of my question. If someone has written a guide for this then it is well-hidden. I would really like to start contributing :)http://dfhack.readthedocs.io/en/stable/library/xml/how-to-update.html
Part of the delay is due to a lack of time spent testing. Out of the 247 people that have downloaded the 64-bit Windows build, I've seen exactly one report of a crash that occurs with the majority of Ruby scripts (exterminate, etc.). If only one person bothered to report an obvious crash like that, I'm not entirely confident in that build's overall stability.
That document pretty much just covers globals. Most of the globals (except a few debug flags, I think) are already located.
To answer the original question, we need to check most tools and make sure they don't crash. It's also helpful to explore structure layouts (e.g. with gui/gm-editor) and make sure that doesn't crash either. Also, there are a couple other things to fix, like 64-bit Stonesense (which is mainly just missing allegro libraries).
Part of the delay is due to a lack of time spent testing. Out of the 247 people that have downloaded the 64-bit Windows build, I've seen exactly one report of a crash that occurs with the majority of Ruby scripts (exterminate, etc.). If only one person bothered to report an obvious crash like that, I'm not entirely confident in that build's overall stability.
Okay, it sounds like we really need some automated testing. I'm thinking that for a start, just trying to run all of the commands in a reasonably sensible context (eg correct game mode) and reporting any crashes would be great. This will still take a fair bit of work, including maybe a script to navigate DF menus, but the payoff should be worth it.Yeah, testing is something I've wanted to do. I looked at unit tests recently, although those wouldn't be as useful for the DF-related issues. I have a script that walks through all of the structures (well, mostly), which crashes when something is misaligned badly enough, so that might be a decent place to start. Besides that, actual tests that run in DF would have a couple things to sort out (nothing impossible, though):
More complicated stuff can come later. I'd like command arguments, better context awareness, basic fuzzing, output checking, and so on... but all of that can be built on a basic "run all the commands and see what happens".
This might be my next project :)
Okay, it sounds like we really need some automated testing. I'm thinking that for a start, just trying to run all of the commands in a reasonably sensible context (eg correct game mode) and reporting any crashes would be great. This will still take a fair bit of work, including maybe a script to navigate DF menus, but the payoff should be worth it.Yeah, testing is something I've wanted to do. I looked at unit tests recently, although those wouldn't be as useful for the DF-related issues. I have a script that walks through all of the structures (well, mostly), which crashes when something is misaligned badly enough, so that might be a decent place to start. Besides that, actual tests that run in DF would have a couple things to sort out (nothing impossible, though):
- Needing to start DF (this takes time, although it might be fast on Travis)
- Needing to restart DF if a test crashes DF (but not restarting unnecessarily, to save time)
- Needing to restart DF (or abort and reload the current game?) if a test does something difficult to reverse (3dveins, exterminate, etc.). Hopefully this isn't necessary often, though.
In short, it could be slow, but it's definitely something I want to look into.
0x205cd40
0x2058140
0x1a81280
0x1a7e600
0x1a5e480
0x1a5b800
0x17f4020
0x17f3220
0x1484940
0x147fd40
I had thought I was closing in on it until I noticed the ui_look_list fuckup I was making, but none of those worked, just spat segfaults at me til I gave up and made a fort intending to track down the ui_look_list global before I started having fun poking at my dorfs and whatnot.I'm sure I saw a command to create colony vermin (defaulting to bees). However, I thought the question was about regular animals rather than vermin or sapients?
I am working on some scripts and have a couple questions;1. I don't know. Each tree/shrub on the map has it's individual entity in the df.global.world.plants.all list ("path" might not be completely correct as it's from memory). In addition to that, there's also info on the tile itself that there's a trunk/sapling. Highwood can cover several tiles. Branches are likewise "present" on their tiles. I haven't tried to remove any though, and I don't know if there are additional references (trees designated for cutting end up in the jobs list, but the tree being gone just results in an extra cutting job doing nothing, which happens when getplants is run several times with unpauses in between to designate the same trees). The Plants command creates plants, and you sort of want to do the reverse.
Collection of vague guesses and pointers:
1. Is there a script that removes a tree (and all connecting branches and such) from a map? As in, I target a location or a tree id (I don't know, do tree's have individual ids?) and it will be erased?
2. Similarly, a script that does the same for bushes/shrubs/any growths?
3. Is milo christiansen's script (http://www.bay12forums.com/smf/index.php?topic=150776.msg6233559#msg6233559) still the best way to get a tile's material using lua?
4. Back to trees, is there a way to see how old a tree is and to get more information about it?
5. Do the current scripts for resurrecting corpses handle body parts? That is to say, if I target a corpse whose hand was chopped off and then rez it, will the hand corpse item be removed or will it stay in game?
6. Along the same lines, if a unit is resurrected will the other members of your fort still want to bury them?
I will have more questions later, but that's enough for now.
1. Is there a script that removes a tree (and all connecting branches and such) from a map? As in, I target a location or a tree id (I don't know, do tree's have individual ids?) and it will be erased?
2. Similarly, a script that does the same for bushes/shrubs/any growths?
3. Is milo christiansen's script (http://www.bay12forums.com/smf/index.php?topic=150776.msg6233559#msg6233559) still the best way to get a tile's material using lua?
1. Is there a script that removes a tree (and all connecting branches and such) from a map? As in, I target a location or a tree id (I don't know, do tree's have individual ids?) and it will be erased?
2. Similarly, a script that does the same for bushes/shrubs/any growths?
3. Is milo christiansen's script (http://www.bay12forums.com/smf/index.php?topic=150776.msg6233559#msg6233559) still the best way to get a tile's material using lua?
1) Not that I know of, but it wouldn't be hard to write one...
2) I have a script that forcibly removes surface saplings. Actually if you look back a few pages in this thread I posted an early version of my sapling elimination code.
Speaking of my sapling deletion script I need to get that tested... The script is supposed to be an answer to "the jungle problem" (trees growing super thick on every map regardless of biome). Basically if surface trees go over a set limit it deletes all surface saplings until trees go under the limit again :)
[lua]# ~df.plant.find(2114)
<plant: 0x18452340>
flags = <plant_flags: 0x18452340>
material = 153
pos = <coord: 0x18452344>
grow_counter = 19982037
damage_flags = <plant.T_damage_flags: 0x18452350>
hitpoints = 400000
update_order = 9
site_id = -1
srb_id = -1
contaminants = <vector<spatter_common*>: 0x18452364>
tree_info = <plant_tree_info: 0x185d0a30>
Note that this is the same as just going ~df.global.world.plants.all[2114], the 2114 was just picked at random and then I went to look at that spot on the map. What is growing here is a large three story tree. My efforts to remove it were as follows; -- Note that "del" is a (sorted) table of tables containing the plant index and a reference to the plant object itself
for _, plant in ipairs(del) do
local block = dfhack.maps.ensureTileBlock(plant.pos.x, plant.pos.y, plant.pos.z)
block.tiletype[plant.pos.x%16][plant.pos.y%16] = df.tiletype["SoilFloor1"]
-- The list is high indexes to low indexes, so we can just delete from the list without fear of messing up later indexes.
df.global.world.plants.all:erase(plant.i)
-- Plants do not have an ID number, so we need to compare them based on location.
for j = 0, #df.global.world.plants.tree_dry - 1, 1 do
if same_xyz(df.global.world.plants.tree_dry[j].pos, plant.ref.pos) then
df.global.world.plants.tree_dry:erase(j)
break
end
end
for j = 0, #df.global.world.plants.tree_wet - 1, 1 do
if same_xyz(df.global.world.plants.tree_wet[j].pos, plant.ref.pos) then
df.global.world.plants.tree_wet:erase(j)
break
end
end
plant.ref:delete()
end
So...this means that Stonesense works? Do the other visualizers work as well?That document pretty much just covers globals. Most of the globals (except a few debug flags, I think) are already located.
To answer the original question, we need to check most tools and make sure they don't crash. It's also helpful to explore structure layouts (e.g. with gui/gm-editor) and make sure that doesn't crash either. Also, there are a couple other things to fix, like 64-bit Stonesense (which is mainly just missing allegro libraries).
Part of the delay is due to a lack of time spent testing. Out of the 247 people that have downloaded the 64-bit Windows build, I've seen exactly one report of a crash that occurs with the majority of Ruby scripts (exterminate, etc.). If only one person bothered to report an obvious crash like that, I'm not entirely confident in that build's overall stability.
Stonesense is already updated on windows, for both versions.
If nobody else can do it, I can try to update the Linux build process, but it's a last resort because I'd have to set up a dev environment first.
I'm sure I saw a command to create colony vermin (defaulting to bees). However, I thought the question was about regular animals rather than vermin or sapients?Yeah, I'm after normal animals for a bit of !SCIENCE!. I actually didn't even know that spawning vermin was a thing, lol.
Then delete the plant object from the list. Don't forget that there are actually two other lists containing trees (one for dry, one for wet), also you need to delete the tree object itself or you will leak memory.You'll need to remove it from the matching map_block_column as well (corresponding to its location within your embark region), otherwise the game will probably crash.
Then delete the plant object from the list. Don't forget that there are actually two other lists containing trees (one for dry, one for wet), also you need to delete the tree object itself or you will leak memory.You'll need to remove it from the matching map_block_column as well (corresponding to its location within your embark region), otherwise the game will probably crash.
hmm in other dfhack ideas I wonder if it's possible to remove the site restrictions on building in adventure mode in towns and have it not make a new camp on top of the site either.Uh, put a tile of paint m lava_flow st 1 sv 0 l 0 underneath you and you can build, but it'll make the campsite still to save your changes.
I found a dfhack way to unlock building in adventure mode but doing anything in that mode will spawn a camp.hmm in other dfhack ideas I wonder if it's possible to remove the site restrictions on building in adventure mode in towns and have it not make a new camp on top of the site either.Uh, put a tile of paint m lava_flow st 1 sv 0 l 0 underneath you and you can build, but it'll make the campsite still to save your changes.
Hmmm, there's something I'm forgetting that lets this work, but standing on an actual lava flow or in hell (paint m magma btw) works.
Which flag/setting/etc unlocks it and I"ll fuck around with it next time I get on to hack around.oh found it. apperently there an option that allows you to expand the " you can build here zone"
Then delete the plant object from the list. Don't forget that there are actually two other lists containing trees (one for dry, one for wet), also you need to delete the tree object itself or you will leak memory.You'll need to remove it from the matching map_block_column as well (corresponding to its location within your embark region), otherwise the game will probably crash.
It doesn't crash, but it does corrupt the save, so that is something to be very careful with. I think for now I will set aside the tree deletion and work on the other things.
It doesn't crash, but it does corrupt the save, so that is something to be very careful with. I think for now I will set aside the tree deletion and work on the other things.Then delete the plant object from the list. Don't forget that there are actually two other lists containing trees (one for dry, one for wet), also you need to delete the tree object itself or you will leak memory.You'll need to remove it from the matching map_block_column as well (corresponding to its location within your embark region), otherwise the game will probably crash.
This is VERY good to know. I probably need to change my tree limit script!
Then delete the plant object from the list. Don't forget that there are actually two other lists containing trees (one for dry, one for wet), also you need to delete the tree object itself or you will leak memory.You'll need to remove it from the matching map_block_column as well (corresponding to its location within your embark region), otherwise the game will probably crash.
0 | 3 | 6 | 9 | 12 | 15 |
1 | 4 | 7 | 10 | 13 | 16 |
2 | 5 | 8 | 11 | 14 | 17 |
18 | 21 | 24 | 27 | 30 | 33 |
19 | 22 | 25 | 28 | 31 | 34 |
20 | 23 | 26 | 29 | 32 | 35 |
So basically I am just wondering, am I confusing what map_block_columns are, or is it just that only one map_block_column per embark square actually contains the plant data?
local mapcol = df.global.world.map.column_index[math.floor(x/48)*3][math.floor(y/48)*3]
for i,p in ipairs(mapcol.plants) do
if not p.tree_info then
local pos = p.pos
if pos.x == x and pos.y == y and pos.z == z then
--found the plant
local plantraw = df.plant_raw.find(p.material)
--...
break
end
else
--handle trees differently
end
end
What exactly are map_block_columns referring to? With a 96x96 embark cite I have 6x6 blocks (since blocks are 16x16). [...] It seems the first map_block_column contains all of the plants for the first 3x3 blocks. This trend continues for the entire grid such that for every nine blocks there is only 1 with plant data in it.Is it possible that trees/branches are 'bleeding over' into your embark (check also Z-levels)?
The first map_block_column per embark square has the plant data, and no plants can cross embark square boundaries.To clarify, each map_block_column covers a 16x16 area (the "map_pos" field tells you exactly where it is) and mainly keeps track of special elevations or things which are independent of elevation. In older versions, map_block itself held the list of local plants, but the addition of large trees (which span multiple Z-levels) required moving it to map_block_column, and the fact that trees can span multiple map_blocks is why they're only stored in one column out of each 3x3 group (and why they can't extend between region tiles, which made it possible for Toady to much more easily keep terrain generation in Adventurer mode consistent).
This is because if they were stored per column, they wouldn't be able to cross map_block boundaries.
New update on tree deletion. Successfully deleting the tree from the three different lists (plants.all, plants.tree_dry/tree_wet and map_block_column.plants) will remove the tree from the game and leave all tiles connected to that tree as just saying Tree. The game was fully able to be saved and reloaded as well. Even without changing the tile types. I have also figured out how to identify the position of each branch, thick branch, trunk, and twig of the tree so that they can be set to the correct tiletype.Such hatred for trees to go to these length to destroy them without leaving anything. :D
New update on tree deletion. Successfully deleting the tree from the three different lists (plants.all, plants.tree_dry/tree_wet and map_block_column.plants) will remove the tree from the game and leave all tiles connected to that tree as just saying Tree. The game was fully able to be saved and reloaded as well. Even without changing the tile types. I have also figured out how to identify the position of each branch, thick branch, trunk, and twig of the tree so that they can be set to the correct tiletype.Interesting. A tangent question I get as a result is if the bugged underground tiles described as "grass" that sometimes appear are the result of a similar process, i.e. if they're "actually" underground fungal "grass", but the plant object has somehow been lost?
Probably. Grass is stored on a contaminant layer, similar to mud and blood splatters. So it's possible that the actual grass is missing from there, but the tiletype is still grass.Are you sure? As far as I've seen grass is stored as plants together with trees and shrubs? Mud and blood can lie on top of grass (just look at mud covered caverns!). However, blood can coexist with mud as well, so that's not much of an argument. However, I'll be on the lookout for unspecified grass tiles underground to take a closer look.
Probably. Grass is stored on a contaminant layer, similar to mud and blood splatters. So it's possible that the actual grass is missing from there, but the tiletype is still grass.Are you sure? As far as I've seen grass is stored as plants together with trees and shrubs? Mud and blood can lie on top of grass (just look at mud covered caverns!). However, blood can coexist with mud as well, so that's not much of an argument. However, I'll be on the lookout for unspecified grass tiles underground to take a closer look.
We will make these trees unpersons. Soon they will be removed even from people's thoughts.New update on tree deletion. Successfully deleting the tree from the three different lists (plants.all, plants.tree_dry/tree_wet and map_block_column.plants) will remove the tree from the game and leave all tiles connected to that tree as just saying Tree. The game was fully able to be saved and reloaded as well. Even without changing the tile types. I have also figured out how to identify the position of each branch, thick branch, trunk, and twig of the tree so that they can be set to the correct tiletype.Such hatred for trees to go to these length to destroy them without leaving anything. :D
As for the first message, if you installed DFHack manually, did you remember to copy the dfhack-config folder?
So I'm using the alpha for the new version, where do I get the "ruby library" to use startdwarves?Which is "the" alpha? There have been two, 0.43.05-alpha1 and 0.43.05-alpha2. The latter comes with a ruby plugin and runtime library.
Was that 32-bit DFHack? I wouldn't expect 64-bit DFHack to launch at all on a 32-bit system, but that's very strange.As for the first message, if you installed DFHack manually, did you remember to copy the dfhack-config folder?
Yes I did. And I copied the whole folder from the 32bit machine to the 64bit one and it worked.
Edit*
Oh, dfhack-config is empty except for the default subfolder. It appeared dfhack failed to create files in that folder for some reason.
Oh, there was an update? I should probably install that thenSo I'm using the alpha for the new version, where do I get the "ruby library" to use startdwarves?Which is "the" alpha? There have been two, 0.43.05-alpha1 and 0.43.05-alpha2. The latter comes with a ruby plugin and runtime library
Was that 32-bit DFHack? I wouldn't expect 64-bit DFHack to launch at all on a 32-bit system, but that's very strange.
Sorry that I'm so bad at this but this ZIP has... quite a lot more files then the one that I had and frankly, I've got no idea what they do or what to do with themDid you download a release archive for Windows or something else?
New update on tree deletion. Successfully deleting the tree from the three different lists (plants.all, plants.tree_dry/tree_wet and map_block_column.plants) will remove the tree from the game and leave all tiles connected to that tree as just saying Tree. The game was fully able to be saved and reloaded as well. Even without changing the tile types. I have also figured out how to identify the position of each branch, thick branch, trunk, and twig of the tree so that they can be set to the correct tiletype.
function getTreePositions(tree)
n = 0
nTrunk = 0
nTwigs = 0
nBranches = 0
nTBranches = 0
positions = {}
positionsTrunk = {}
positionsTwigs = {}
positionsBranches = {}
positionsTBranches = {}
local x1 = tree.pos.x - math.floor(tree.tree_info.dim_x / 2)
local x2 = tree.pos.x + math.floor(tree.tree_info.dim_x / 2)
local y1 = tree.pos.y - math.floor(tree.tree_info.dim_y / 2)
local y2 = tree.pos.y + math.floor(tree.tree_info.dim_y / 2)
local z1 = tree.pos.z
local z2 = tree.pos.z + tree.tree_info.body_height
for x = x1,x2 do
for y = y1,y2 do
for z = z1,z2 do
pos = {x=x,y=y,z=z}
body = tree.tree_info.body[pos.z-z1]:_displace((pos.y - y1) * tree.tree_info.dim_x + (pos.x - x1))
if body.trunk then
n = n + 1
positions[n] = pos
nTrunk = nTrunk + 1
positionsTrunk[nTrunk] = pos
elseif body.twigs then
n = n + 1
positions[n] = pos
nTwigs = nTwigs + 1
positionsTwigs[nTwigs] = pos
elseif body.branches then
n = n + 1
positions[n] = pos
nBranches = nBranches + 1
positionsBranches[nBranches] = pos
elseif body.thick_branches_1 or body.thick_branches_2 or body.thick_branches_3 or body.thick_branches_4 then
n = n + 1
positions[n] = pos
nTBranches = nTBranches + 1
positionsTBranches[nTBranches] = pos
end
end
end
end
return positions,positionsTrunk,positionsTBranches,positionsBranches,positionsTwigs
end
Shouldn't it be "local z2 = tree.pos.z + tree.tree_info.body_height - 1"?
Have you seen thick_branches_* being actually set?
Sorry that I'm so bad at this but this ZIP has... quite a lot more files then the one that I had and frankly, I've got no idea what they do or what to do with themDid you download a release archive for Windows or something else?
To be clear, under DFHack 0.43.05-alpha2 (http://DFHack 0.43.05-alpha2), you want either "dfhack-0.43.05-alpha2-Windows-32.zip" or "dfhack-0.43.05-alpha2-Windows-64.zip".
okay trying to see if I can fix the crash that would happen if you play on a dfhack spawn site in fort modeTo help a bit more with this, crosspost from the adventurer threads, a pre-existing zone from an adventurer site seems to cause a crash any time visitors arrive in fort mode trying to go to the camp zone. Get "succession traveler placed out of bounds" type errors and poof game crashes to desktop.
and hit a snag on trying to insert a pointer to unk_188 in the site.
edit: so uhh just copied the unk_188 of another site and now need to see if this fix the seasonal bug with fort mode on dfhack made sites.
FirstCall()
Initized HOOKS!
Log information is appended to the end of stderr.log. That's status information that DFHack logs on startup.
Anyway, adaptation is a Ruby script, so it's probably https://github.com/DFHack/dfhack/issues/1023, which we already know about. I don't think anyone's mentioned that script, though, so I'll add it to the list. Thanks!
Does that work? I always thought that once you get cave adaptation it's there for all times.Log information is appended to the end of stderr.log. That's status information that DFHack logs on startup.
Anyway, adaptation is a Ruby script, so it's probably https://github.com/DFHack/dfhack/issues/1023, which we already know about. I don't think anyone's mentioned that script, though, so I'll add it to the list. Thanks!
cool, no problem! and thanks for the info. I'll just fix cave adaptation in soldiers the old-school way, by stationing them outside until they stop puking. Ahhh, Dwarf Fortess.
By the way, ab9rf should have fixed that issue. Turns out accessing globals on Win64 would always crash, because addresses were getting truncated somewhere in the Ruby API.Log information is appended to the end of stderr.log. That's status information that DFHack logs on startup.
Anyway, adaptation is a Ruby script, so it's probably https://github.com/DFHack/dfhack/issues/1023, which we already know about. I don't think anyone's mentioned that script, though, so I'll add it to the list. Thanks!
cool, no problem! and thanks for the info. I'll just fix cave adaptation in soldiers the old-school way, by stationing them outside until they stop puking. Ahhh, Dwarf Fortess.
What causes visitors to display that they're ready to leave (it seems they have a path for a meeting with the edge, but something ought to cause them to set up that path in the first place)? I've failed to find it, and I'd like to hack units that have overstayed their welcome by several years (causing scandals by running around naked as well as uselessly using up a visitor slot) to nudge them to depart.I can't answer this well myself (maybe someone else can), but I did fairly minimal research into visitors when that version of DF came out, and I don't remember seeing a lot done by other people, so it's possible that nobody has discovered the relevant structure(s) yet (or they've been mapped but not named, which would make things a lot easier). It definitely seems like something unit-specific, so maybe look for unit fields added around 0.42.
Here is a new alpha release, with the Ruby fix (and several other fixes): https://github.com/DFHack/dfhack/releases/tag/0.43.05-alpha3Thanks lethosor.
Do keep reporting issues that come up, although hopefully there are fewer now.What causes visitors to display that they're ready to leave (it seems they have a path for a meeting with the edge, but something ought to cause them to set up that path in the first place)? I've failed to find it, and I'd like to hack units that have overstayed their welcome by several years (causing scandals by running around naked as well as uselessly using up a visitor slot) to nudge them to depart.I can't answer this well myself (maybe someone else can), but I did fairly minimal research into visitors when that version of DF came out, and I don't remember seeing a lot done by other people, so it's possible that nobody has discovered the relevant structure(s) yet (or they've been mapped but not named, which would make things a lot easier). It definitely seems like something unit-specific, so maybe look for unit fields added around 0.42.
I tried force MegaBeast and nothing happened, no errors but also no megabeastprobably the same reason there no events for guests arriving.
There is a MegaBeast event, which is why the script doesn't throw an error. I don't know exactly why it's not working, though, or if it's worked since 0.40. Is this a new world?I tried force MegaBeast and nothing happened, no errors but also no megabeastprobably the same reason there no events for guests arriving.
Neither. They're names of relevant data you can access (using Lua syntax in this case). One option is running "gui/gm-editor" followed by the expression you want, e.g. "gui/gm-editor df.global.world.history.total_powers". (Note that I have not checked that specifically to see how easy it is to hunt down megabeasts, or if that's what you're looking for - this is just one way to access DF data in general from Lua.)it's possible to just summon every historical being into one spot with fast traveling party manipulation but uhh oh boy hope you have a good pc for doing that.
Neither. They're names of relevant data you can access (using Lua syntax in this case). One option is running "gui/gm-editor" followed by the expression you want, e.g. "gui/gm-editor df.global.world.history.total_powers". (Note that I have not checked that specifically to see how easy it is to hunt down megabeasts, or if that's what you're looking for - this is just one way to access DF data in general from Lua.)it's possible to just summon every historical being into one spot with fast traveling party manipulation but uhh oh boy hope you have a good pc for doing that.
You just move an army to your location and fill it with ALL historical figure ids. You can also set army contents to number=100, race=some_race instead.Neither. They're names of relevant data you can access (using Lua syntax in this case). One option is running "gui/gm-editor" followed by the expression you want, e.g. "gui/gm-editor df.global.world.history.total_powers". (Note that I have not checked that specifically to see how easy it is to hunt down megabeasts, or if that's what you're looking for - this is just one way to access DF data in general from Lua.)it's possible to just summon every historical being into one spot with fast traveling party manipulation but uhh oh boy hope you have a good pc for doing that.
...Can you share how? I kind of need that for a new force siege script.
Oh, adventure mode? I can't get it to work at all in fort mode.well you can't fast travel in fort mode I mean unless someone figured out how... well now time to see if you can move a fort.
Oh, adventure mode? I can't get it to work at all in fort mode.If you are talking about force-siege then yes, i could only get armies to appear in adv-mode. However i remember reading somewhere that someone had luck with army controllers...
Putnam and I were both screwing around with moving armies, if you set the army_controller.pos_x/pos_y in the right spots you can get the army to march to it apparently.So next: set it to fort position. You might need to mess with civ_id to make it enemy - instant invaders?
I managed to get a siege by teleport+controller-change once. I messed further and the game crashed to just before the first time I did it. I recreated the exact process (I was editing a script to do it) and it didn't work.I think it needs to enter the tile your for is in on it's own to let df manage the logic of spawning units and so on.
More like job manager being stupid somewhere. A common instance with minecarts: Your minecart is deliberately inaccessible, but it has stopped, and job is generated to carry it to route stop - never mind that no dwarf can reach it.Or just forbid it?
In that case, I find it is best to delete the route.
It seems 43.05 alpha 3 is quite buggy. I'm using x64 version, and for some reason the enhanced stockpile management menu messes up items if I mark listed items as dump. The game creates ghost items on the screen, whose positions are random and can't be checked using k. And the game tends to crash after that. Autodump seems to have similar issue.I suspect I know what's causing this, but it's not quite the same as the issues I've found (and probably fixed). See, e.g, #1047 (https://github.com/DFHack/dfhack/issues/1047/), #1050 (https://github.com/DFHack/dfhack/pull/1050), #173 (https://github.com/DFHack/df-structures/pull/173)
Or just forbid it?And wait a bit until the job disappears from listing, then unforbid, mark for dumping...But you likely don't need the route if it is inaccessible on purpose, and will have to do this whole forbid-wait-unforbid every time, not just the first time.
I suspect I know what's causing this, but it's not quite the same as the issues I've found (and probably fixed). See, e.g, #1047 (https://github.com/DFHack/dfhack/issues/1047/), #1050 (https://github.com/DFHack/dfhack/pull/1050), #173 (https://github.com/DFHack/df-structures/pull/173)I reverted back to alpha 2 and it worked this time.
A couple places:
- https://github.com/DFHack/df-structures/blob/master/df.keybindings.xml
- lua @df.interface_key
- data/init/interface.txt (this might not list all of them)
- https://github.com/svenstaro/dwarf_fortress_unfuck/blob/master/g_src/keybindings.h
For present and future reference, you could check that by loading the vanilla game for most issues.
Here's another question for those of you more knowledgeable about the gui programming. Right now I know how to put pictures and things onto the screen, but if I write text over them it appears as a black box with writing. Is it possible to make that box transparent so that you just see the text?By "pictures and things", are you referring to tiles? You can't put text partially on top of other tiles.
Here's another question for those of you more knowledgeable about the gui programming. Right now I know how to put pictures and things onto the screen, but if I write text over them it appears as a black box with writing. Is it possible to make that box transparent so that you just see the text?By "pictures and things", are you referring to tiles? You can't put text partially on top of other tiles.
Ah, I see what you mean now. Was hoping to be able to make a cool visual out of something like this for my Bestiary/Herbiary/Journalyou could play off the black and background with having the image be a giant inkblot that expands and reveals the ingame text and have the paper scroll out to show the other png doodles.Spoiler (click to show/hide)
My basic principle is that it is always a bug when DFHack can crash DF, or when scripts give the user a traceback instead of an error message.Oh drat, that kiboshes the Ruby plugin then. It's fairly trivial to crash it, because Ruby code can access arbitrary memory pointers, and a segmentation error is an uncaught signal on Linux or uncaught exception on Windows, both of which lead to an immediate die. The Lua runtime seems to handle this a bit more robustly, with the exception/signal being confined to the Lua interpreter thread.
My basic principle is that it is always a bug when DFHack can crash DF, or when scripts give the user a traceback instead of an error message.
Oh drat, that kiboshes the Ruby plugin then. It's fairly trivial to crash it, because Ruby code can access arbitrary memory pointers, and a segmentation error is an uncaught signal on Linux or uncaught exception on Windows, both of which lead to an immediate die. The Lua runtime seems to handle this a bit more robustly, with the exception/signal being confined to the Lua interpreter thread.
Actually it does not. E.g. if you try to print values from global.world.units.bad[id] when they are really deallocated it crashes df. This is because all data access checking would incur too much of a penalty and you don't want to deep print everything anyway.My basic principle is that it is always a bug when DFHack can crash DF, or when scripts give the user a traceback instead of an error message.Oh drat, that kiboshes the Ruby plugin then. It's fairly trivial to crash it, because Ruby code can access arbitrary memory pointers, and a segmentation error is an uncaught signal on Linux or uncaught exception on Windows, both of which lead to an immediate die. The Lua runtime seems to handle this a bit more robustly, with the exception/signal being confined to the Lua interpreter thread.
Any chance either of these will work with current versions of DFHack/DF. Not really sure where I picked them up, but had them sitting around and thought they might be useful for some generational fort messing about...
I have no idea whether or not those scripts would still work. However, I do know that the current DFHack already has this functionality. Check the DFHack documentation for gui/family-affairs (http://dfhack.readthedocs.io/en/stable/docs/_auto/gui.html#gui-family-affairs): "view, add, remove, or otherwise change romantic relationships". This includes a user-friendly interface and, among other things, it allows the user to force a marriage or divorce.
I'm putting up a build now to fix the issues with buildingplan/etc. that showed up in alpha3, as well as some other outstanding Linux issues. Right now, there are only OS X and Linux builds. If anyone's around that can do both Windows builds (and check them with devel/check-release), that would be much appreciated.Would you like to rub beards and we can see which one of us ends up birthing horrific babies for the other?
Edit: https://github.com/DFHack/dfhack/releases/tag/0.43.05-alpha4
./dfhack: line 66: 3825 Segmentation fault (core dumped) setarch i386 -R env LD_PRELOAD="$PRELOAD_LIB" ./libs/Dwarf_Fortress "$@"
Sorry, but I still don't understand how "autodump destroy" works. If I mark a forbidden arrow on the map for dumping (under the k cursor), it seems unaffected by "autodump destroy" or "autodump destroy-here". A regular dumping job is created for it and it still stays on the map. What am I doing wrong?
It seems 43.05 alpha 3 is quite buggy. I'm using x64 version, and for some reason the enhanced stockpile management menu messes up items if I mark listed items as dump. The game creates ghost items on the screen, whose positions are random and can't be checked using k. And the game tends to crash after that. Autodump seems to have similar issue.
Well, those addresses must be wrong. I'm not sure how exactly they were located, but as long as they're within the section of memory that contains globals, which they probably are, you'll get unpredictable values instead of crashes.
Incidentally, it could be easier to locate the correct address if you know exactly what those values should be, as long as they're not particularly low.
activity_next_id -1802810881 > 22785
artifact_next_id -159036100 > 44417
item_next_id 2055948296 > 1903806
unit_next_id -2079390469 > 71293
hist_event_next_id 1149847552 > 720562
hist_figure_next_id -11891208 > 76043
squad_next_id -2092433408 > 110
Those should be right, I just checked a few which changed while I was checking (hist_event_next_id should have been and the newest entry in events was indeed 720562) so yeah, they're pretty whacky, but that would be why launch/advfort crash me and artifake just spits errors but so many other scripts work fine.
Randomly or when you press a specific key? Have you tried it without TwbT?
# assign weapon racks to squads so that they can be used
keybinding add P@dwarfmode/QueryBuilding/Some/Weaponrack gui/assign-rack
...df_43.05/hack/scripts/gui/extended-status.lua:172: Cannot invoke field (global).getCurFocus(): C++ exception: string too long.
stack traceback:
[C]: in field 'getCurFocus'
...df_43.05/hack/scripts/gui/extended-status.lua:172: in function <...df_43.05/hack/scripts/gui/extended-status.lua:171>
...df_43.05/hack/scripts/gui/load-screen.lua:471: Cannot invoke field (global).getCurFocus(): C++ exception: string too long.
stack traceback:
[C]: in field 'getCurFocus'
...df_43.05/hack/scripts/gui/load-screen.lua:471: in function <...df_43.05/hack/scripts/gui/load-screen.lua:468>
...df_43.05/hack/scripts/view-item-info.lua:386: Cannot invoke field (global).getCurViewscreen(): C++ exception: string too long.
stack traceback:
[C]: in field 'getCurViewscreen'
...df_43.05/hack/scripts/view-item-info.lua:386: in function <...df_43.05/hack/scripts/view-item-info.lua:380>
Are you sure those show up when you open manipulator? They look like ones that showed up earlier.
Anyway, something is badly broken. That keybinding shouldn't even be run on that screen. What platform are you using?
lua ~unit
Couldn't you search for the entry in df.global.world.items.other.CORPSE?
I've avoided screwing with ui_look_list because it's crashed every time I played with it in past versions, stable or not.
That appears to have been removed in 0.40.O ok. I was not aware. thank you.
[DFHack]# teleport -showunitid
460
[DFHack]# teleport -showpos
x = 72
y = 74
z = 79
[DFHack]# teleport -unit 460 -x 72 -y 74 -z 79
Cannot write field coord.y: integer expected.
stack traceback:
[C]: in ?
[C]: in ?
[C]: in field 'getTileBlock'
/path/to/df_linux/hack/scripts/teleport.lua:16: in global 'teleport'
/path/to/df_linux/hack/scripts/teleport.lua:54: in local 'script_code'
./hack/lua/dfhack.lua:562: in function 'dfhack.run_script_with_env'
(...tail calls...)
Does anyone happen to have a precompiled copy of the 43.05 alpha4 they can put up for download somewhere?
I don't see any messages in logs, but I have an occasional crash when setting custom profession names in manipulator.
Using 0.43.05-alpha4 + TWBT.
Which ones aren't aligned properly?
Also, there are a couple random crashes I haven't been able to track down yet, including the manipulator crash on 64-bit Windows and a box-select crash on 64-bit Linux.
So, I hadn't thought much about this since originally I just attributed it to being on a personally compiled super-alpha develop branch of dfhack, but now with so many of the globals located I was trying to get some of my scripts back in order and ran into a problem with artifake not using the right value for artifact_next_id, and it seems to be because there isn't a value that makes sense for it at all?I know that it should be like 17980 or so, not -159036100, and there are similar value issues for item_next_id and others seen there. The same problem happens with the alpha4 release so I'm rather confused that it otherwise works fine despite this.Spoiler (click to show/hide)
Those ones for sure aren't aligned properly.Well, those addresses must be wrong. I'm not sure how exactly they were located, but as long as they're within the section of memory that contains globals, which they probably are, you'll get unpredictable values instead of crashes.
Incidentally, it could be easier to locate the correct address if you know exactly what those values should be, as long as they're not particularly low.Code: [Select]activity_next_id -1802810881 > 22785
Those should be right, I just checked a few which changed while I was checking (hist_event_next_id should have been and the newest entry in events was indeed 720562) so yeah, they're pretty whacky, but that would be why launch/advfort crash me and artifake just spits errors but so many other scripts work fine.
artifact_next_id -159036100 > 44417
item_next_id 2055948296 > 1903806
unit_next_id -2079390469 > 71293
hist_event_next_id 1149847552 > 720562
hist_figure_next_id -11891208 > 76043
squad_next_id -2092433408 > 110
Using a few prepared saves, I've located all of the *_next_id globals for 64-bit Linux. There are still a few others to locate, though they hopefully shouldn't be too difficult.A goddamn scholar and gentleman, truly.
Probably not what you're asking for, but in case it is:
- PSV values for elevation are translated from a range of 0-400 into a range of 0-250
- PSV values for temperature are modified by altitude and latitude (only if at least one pole is present) using formulae I only have table approximations for.
PHYS_ATT_CAP_PERC does work though, and setting it to 1000 results in gm-editor showing 5000 for the attribute and 50000 for the cap, as expected.
Last, there are some random requests and promises that have accumulated (some memory address help for modders, a little bit of XML, a few priority bug fixes).
Well, all I can say is that faster DFHack updates (due to less work being required) will surely be a massive win for everyone.
Hopefully the data comes in a form that will be easy to generate (less work for Toady), and easy to integrate into the current DFHack update workflow.
I guess we will see...
Structure layouts would take a massive amount of effort from Toady (that or it would require him to release headers, which he doesn't want to do). Global addresses should take a couple hours at most, assuming he can figure out discrepancies between our names and his.
you probably need to change their civ ids and remove the resident flag on them if you end up spawning friendlies
which might mean digging around the unit's data through gui/gm-editor.
you probably need to change their civ ids and remove the resident flag on them if you end up spawning friendlies
which might mean digging around the unit's data through gui/gm-editor.
so... I manually changed the civId and the resident flag is off, but I still can't assign jobs on him (DT considers him a non citizen). Which flags determine if he's a citizen?
you probably need to change their civ ids and remove the resident flag on them if you end up spawning friendlies
which might mean digging around the unit's data through gui/gm-editor.
so... I manually changed the civId and the resident flag is off, but I still can't assign jobs on him (DT considers him a non citizen). Which flags determine if he's a citizen?
Citizenship should be tied to civ_id and pop_id as well as having a correct hist_fig. I would look at the unit you spawned and a civ member with gui/gm-editor and see what differences there are. If none pop out at you you may need to change the values in the hist_fig as well.
you probably need to change their civ ids and remove the resident flag on them if you end up spawning friendlies
which might mean digging around the unit's data through gui/gm-editor.
so... I manually changed the civId and the resident flag is off, but I still can't assign jobs on him (DT considers him a non citizen). Which flags determine if he's a citizen?
Citizenship should be tied to civ_id and pop_id as well as having a correct hist_fig. I would look at the unit you spawned and a civ member with gui/gm-editor and see what differences there are. If none pop out at you you may need to change the values in the hist_fig as well.
I tried to clear relevant data off some intelligent pets (gremlins, i had heard rumours that freshly tamed gremlins could apply for residencies and citizenships, also playing as a goblin civ so keeping them was fine) the creature had the correct same civ, but no population information or additional data in those fields. Generally no luck though i could tone down its tameness in gm-editor to see if it has any effect or wait it out for a little while for it to do actions on its own (if inclined to residency petition at all)
I will try messing with the historical data, thanks for the nugget of guidance, and i hope it helps you too in understanding more about (something about meeting structure MEET_WORKERS, mixed in with locking onto a target = the noble & place being pre-determined when they prompt to apply) the mutual behaviours so that one day we could have a script where we simply click a target and they apply for citizenship/residency.
if Table.A then
if Table.A.B then
if Table.A.B.C then
if Table.A.B.C.D then
if Table.A.B.C.D.E then ...
Is there a simpler way of doing this? Can I do, if Table.A and Table.A.B and Table.A.B.C and Table.A.B.C.D and Table.A.B.C.D.E then ...?
On a related note, is there a script for creating trees? Because I realized when I was doing this that you could create trees the same way we create units with modtools/create-unit. You can even specify the age of the tree and a few other things (like type). Wasn't sure if we could already do this, but if not then a simple edit of create-unit will give you create-tree.I don't believe anyone has done this, but it could work.
On an unrelated note, I have a lua programming question. Say I have a table, Table.A.B.C.D.E, if I want to check if the last entry is there I can simply do if Table.A.B.C.D.E then ... But if I want to check if the last entry is there and I'm not sure if the others are there I have to do a nested if, (i.e.Code: [Select]if Table.A then
Is there a simpler way of doing this? Can I do, if Table.A and Table.A.B and Table.A.B.C and Table.A.B.C.D and Table.A.B.C.D.E then ...?
if Table.A.B then
if Table.A.B.C then
if Table.A.B.C.D then
if Table.A.B.C.D.E then ...
On another note, forgive my ignorance but on which edition of DFhack was the stockpile manager ([ i ] over stockpile) added? I've identified a bug which the stockpile manager helps to fix in this issue report about refuse materials not releasing rotted goods it percieves to be teeth/ivory & horns because they have no meat content. Just by using the stockpile controls to stop discriminating rotted goods ([CTRL] + [X])That looks like the "stocks" plugin, which has been around in some form since 0.34.11. I don't know when the "i" option was added. Incidentally, that option is apparently buggy in 0.43.05 - see this issue (https://github.com/DFHack/dfhack/issues/1045).
0010130: Refuse stockpile disallows 'rotted' items from being used in reactions - teeth/ivory, horn (hotfix included) (http://www.bay12games.com/dwarves/mantisbt/view.php?id=10130)
its a good addition, and i'd personally like to know for reference how far back into DFhack it goes so it can help combat this bug further by applying the adjustment.
function CheckTable(tbl, keys)
for _, key in ipairs(keys) do
if tbl[key] == nil then return false end
tbl = tbl[key]
end
return true
end
-- Usage:
local a = {a = {b = {c = 1}}}
CheckTable(a, {"a", "b", "c"}) -- returns true
CheckTable(a, {"x", "y", "z"}) -- returns false
Yes: safe_index(Table, "A", "B", "C", "D", "E"). It will return nil if any keys are not found.
On another note, forgive my ignorance but on which edition of DFhack was the stockpile manager ([ i ] over stockpile) added? I've identified a bug which the stockpile manager helps to fix in this issue report about refuse materials not releasing rotted goods it percieves to be teeth/ivory & horns because they have no meat content. Just by using the stockpile controls to stop discriminating rotted goods ([CTRL] + [X])That looks like the "stocks" plugin, which has been around in some form since 0.34.11. I don't know when the "i" option was added. Incidentally, that option is apparently buggy in 0.43.05 - see this issue (https://github.com/DFHack/dfhack/issues/1045).
0010130: Refuse stockpile disallows 'rotted' items from being used in reactions - teeth/ivory, horn (hotfix included) (http://www.bay12games.com/dwarves/mantisbt/view.php?id=10130)
its a good addition, and i'd personally like to know for reference how far back into DFhack it goes so it can help combat this bug further by applying the adjustment.
It was renamed to drain-aquifer.I looked through the list like three times and missed it. I am blind. Thanks for the help.
Also, it's mentioned in http://dfhack.readthedocs.io/en/stable/docs/History.html. If you ever have similar questions, http://dfhack.readthedocs.io/en/stable/NEWS.html and that page are good places to look.
I use ctrl+f for exactly this reason :)It was renamed to drain-aquifer.I looked through the list like three times and missed it. I am blind. Thanks for the help.
Also, it's mentioned in http://dfhack.readthedocs.io/en/stable/docs/History.html. If you ever have similar questions, http://dfhack.readthedocs.io/en/stable/NEWS.html and that page are good places to look.
local qmap=dfhack.gui.getCurViewscreen()
local qx=qmap.cursor_x*48
local qy=qmap.cursor_y*48
local rx=qmap.player_region_x*48
local ry=qmap.player_region_y*48
local qarm=df.global.world.armies.all
for k,v in ipairs(qarm) do
if v.flags[0] then
local my_arm=df.global.world.armies.all[k].pos
if rx~=qx then do
my_arm.x=qx
my_arm.y=qy
qmap.player_region_x=qmap.cursor_x
qmap.player_region_y=qmap.cursor_y
end
end
end
end
I wanted to put in a check attempt to make it look for the requisite screens (dfhack.gui.getCurViewscreen()==viewscreen_adventurer_logst)/travel state(df.global.ui_advmode.menu==26) but it got annoying figuring out which one wasn't working so I'll bother with that later when I push it upstream probably, since it just doesn't do anything outside of travel/quest combo.local utils=require 'utils'
local gui = require 'gui'
validArgs = --[[validArgs or]]utils.invert({
'help',
'unit',
'corpse',
'location',
'kill',
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print('')
return
end
corpse = nil
if args.unit and tonumber(args.unit) then
unit = df.unit.find(tonumber(args.unit))
if not unit then return end
if unit.flags1.dead then
for _,id in pairs(unit.corpse_parts) do
item = df.item.find(id)
if df.item_corpsest:is_instance(item) and not item.body.components.body_part_status[0].missing and item.corpse_flags.unbutchered then
corpse = item
break
end
end
else
if args.kill then
print('-kill not currently working')
else
print('Unit is still alive and has not been ordered -kill')
end
end
elseif args.corpse and tonumber(args.corpse) then
item = df.item.find(tonumber(args.corpse))
if not item then return end
if df.item_corpsest:is_instance(item) then
if not item.body.components.body_part_status[0].missing and item.corpse_flags.unbutchered then
corpse = item
end
end
elseif args.location then
locx = tonumber(args.location[1])
locy = tonumber(args.location[2])
locz = tonumber(args.location[3])
block = dfhack.maps.ensureTileBlock(locx,locy,locz)
if block.occupancy[locx%16][locy%16].item then
for _,id in pairs(block.items) do
item = df.item.find(id)
if df.item_corpsest:is_instance(item) then
if item.pos.x == locx and item.pos.y == locy and item.pos.z == locz then
if not item.body.components.body_part_status[0].missing and item.corpse_flags.unbutchered then
corpse = item
break
end
end
end
end
end
end
if not corpse then return end
local view_x = df.global.window_x
local view_y = df.global.window_y
local view_z = df.global.window_z
local curViewscreen = dfhack.gui.getCurViewscreen()
local dwarfmodeScreen = df.viewscreen_dwarfmodest:new()
curViewscreen.child = dwarfmodeScreen
dwarfmodeScreen.parent = curViewscreen
local oldMode = df.global.ui.main.mode
df.global.ui.main.mode = df.ui_sidebar_mode.LookAround
local old_gametype = df.global.gametype
df.global.gametype = df.game_type.DWARF_ARENA
df.global.cursor.x = corpse.pos.x
df.global.cursor.y = corpse.pos.y
df.global.cursor.z = corpse.pos.z
for i,_ in pairs(df.global.ui_look_list.items) do
df.global.ui_look_cursor = i
if dfhack.gui.getCurFocus() == 'dwarfmode/LookAround/Item' then
if corpse.id == dfhack.gui.getSelectedItem().id then
break
end
end
end
gui.simulateInput(dfhack.gui.getCurViewscreen(), 'D_LOOK_ARENA_ADV_MODE')
df.global.gametype = old_gametype
curViewscreen.child = nil
dwarfmodeScreen:delete()
df.global.ui.main.mode = oldMode
df.global.window_x = view_x
df.global.window_y = view_y
df.global.window_z = view_z
So I managed to get around the internet limitation by writing the script on a piece of paper and then typing it in at work
So I managed to get around the internet limitation by writing the script on a piece of paper and then typing it in at work
I commend your dedication! I would never have the patience to do that...
The script looks very interesting, I may (finally) be able to get rid of the butchershop in Underhive Settlement... If I can come up with a way to replace slaughtering too...
Hmmm, I remember there was an extra step needed in there for the actual transfer, trying to just flip the relevant flags gives you the creepy "I am a bat in a cave in the far northwest, I have no mouth, and I must scream" bug.
Changing animals and other creatures with gm-editor properly would involve tracking down everything that points to that animal being a specific species.
Anybody know offhand what all is needed to put yourself into travel mode fully? Setting the menu type to 26 and travel_not_moved to true in arena mode lets you move around there but that isn't what I was looking for with the questport, but until you've moved or entered a wait timer you don't get an army entry you can edit.
@Rumrusher
Given that the units I'm trying to bodyswap to are already retired adventurers, that won't really help. Didn't you have a way of cutting the two week waiting period down though? That would work.
gui/gm-editor dfhack.gui.getCurViewscreen()"gui/gm-editor scr" does the same thing, by the way.
uhh gui/gm-editor dfhack.gui.getCurViewscreen() at the calendar then change either the tick or a year to 0 and you will instantly jump to the adv menu.
"gui/gm-editor scr" does the same thing, by the way.Thanks.
The auto-melt for stockpiles doesn't seem to do anything.. I let it run for a month or two. Auto-trade works though. I'm on alpha 4.It works for me fairly reliably. Note that while auto-melt marks things for melting, it doesn't queue up melt object jobs at a furnace. You have to use some other mechanism to arrange for that.
Workflow (without a quota) will make repeat jobs suspend instead of cancelling when there are no inputs, and automatically resume when there are - which is perfect for automelt.The auto-melt for stockpiles doesn't seem to do anything.. I let it run for a month or two. Auto-trade works though. I'm on alpha 4.It works for me fairly reliably. Note that while auto-melt marks things for melting, it doesn't queue up melt object jobs at a furnace. You have to use some other mechanism to arrange for that.
Except last I knew that didn't work anymore... Maybe it was fixed.
You can also use DF's built-in job manager to get essentially the same effect now. Queue up a repeating "melt object" job with an input threshold on "meltable items" or something like that.Workflow (without a quota) will make repeat jobs suspend instead of cancelling when there are no inputs, and automatically resume when there are - which is perfect for automelt.The auto-melt for stockpiles doesn't seem to do anything.. I let it run for a month or two. Auto-trade works though. I'm on alpha 4.It works for me fairly reliably. Note that while auto-melt marks things for melting, it doesn't queue up melt object jobs at a furnace. You have to use some other mechanism to arrange for that.
A couple people have been reporting a Linux crash that was fixed a couple weeks ago, so I decided it would be a good time for another build:
https://github.com/DFHack/dfhack/releases/tag/0.43.05-beta1
Hopefully this one is more stable than others. We seem to have moved past the catastrophic issue stage, so this is now a "beta" build. Do keep checking for problems, though.
Awesome. Many thanks to both of you.A couple people have been reporting a Linux crash that was fixed a couple weeks ago, so I decided it would be a good time for another build:
https://github.com/DFHack/dfhack/releases/tag/0.43.05-beta1
Hopefully this one is more stable than others. We seem to have moved past the catastrophic issue stage, so this is now a "beta" build. Do keep checking for problems, though.
Update: Windows builds are now available, thanks to Quietust.
local gui=require 'gui'
local qp=df.global.gview.view.child
local qmap=dfhack.gui.getCurViewscreen()
local qarm=df.global.world.armies.all
if df.viewscreen_adventure_logst:is_instance(qmap) then
local qx=qmap.cursor_x*48
local qy=qmap.cursor_y*48
local rx=qmap.player_region_x*48
local ry=qmap.player_region_y*48
df.global.ui_advmode.unk_1=qx
df.global.ui_advmode.unk_2=qy
if df.global.ui_advmode.menu==0 then
gui.simulateInput(qp.child,'LEAVESCREEN')
df.global.ui_advmode.menu=26
df.global.ui_advmode.travel_not_moved=true
gui.simulateInput(qp,'CURSOR_DOWN')
dfhack.timeout(15,'frames',function()
gui.simulateInput(qp,'A_TRAVEL_LOG') end)
-- print('Ready to teleport!') end)
elseif df.global.ui_advmode.menu==26 then
for k,v in ipairs(qarm) do
if v.flags[0] then
local my_arm=df.global.world.armies.all[k].pos
if (rx~=qx or ry~=qy) then do
my_arm.x=qx
my_arm.y=qy
qmap.player_region_x=qmap.cursor_x
qmap.player_region_y=qmap.cursor_y
end
end
end
end
end
end
Only bug I know of atm is that you can't use it if you've gotten the "you cannot travel til you leave this site" message, not sure which flag or whatnot has to be flipped to fix that, but assuming you don't try to travel out before using it, the script will zoop you out just fine.
The script API allows that with script.sleep
Yes. It essentially suspends the current function (although it has to be wrapped with script.start).
script.start(function ()
at the beginning of it and close it out with aend)
Then put script.sleep inside of it wherever I want to pause the script?(note that the advfort ones refer to it as "gscript", and the others use "script")
Also i'm pretty sure both of them are using it incorrectly or superfluously. As each time i understand how it works i somehow manage to confuse myself into not understanding it anymore.(note that the advfort ones refer to it as "gscript", and the others use "script")
Oof. That's because I didn't know advfort or advfort-items used it when I wrote the other two, so I just sort of went at it freshly instead of following existing convention.
Way harder than it needs to be, just target yourself and run gui/gm-editor then go down to body in the raws for a weremonitor I just checked it's adultsize 8100, while body.blood_max is 8100, as is body.size_info.size_base, while size_cur on this one is 9617. Just add a zero to get the value on the wiki lists, sperm whale man I checked was 1,181,315 while wiki lists 12,535,000 as max, so a weremonitor can wear the same armor as a kangaroo man, find your blood_max and size_cur as a wererhino and add a 0 then check the wiki list.I did not know that's how those numbers worked.
Oof. That's because I didn't know advfort or advfort-items used it when I wrote the other two, so I just sort of went at it freshly instead of following existing convention.There's already some inconsistency between things like dlg/dialog, script/gscript/guiScript, etc. between scripts (turns out gui/gm-editor and gui/gm-unit use "guiScript"). As long as you stay consistent within a script, it's fine.
This reminded me that we (I) need some "script" dialogs that would let e.g. choose X units, Y items and then run "some command X Y". That would allow to have a more flexible and user friendly interface for some more used stuff.Are you talking about adding stuff to the Lua libraries (e.g. library/lua/gui/script.lua) or adding scripts that wrap certain commands?
Are you talking about adding stuff to the Lua libraries (e.g. library/lua/gui/script.lua) or adding scripts that wrap certain commands?
Yeah, I could imagine there might be a case where blood_max wasn't accurate, but size_base should always be the critter size and I don't know if it possible to have size_cur so different you can't wear the same armor anymore.Way harder than it needs to be, just target yourself and run gui/gm-editor then go down to body in the raws for a weremonitor I just checked it's adultsize 8100, while body.blood_max is 8100, as is body.size_info.size_base, while size_cur on this one is 9617. Just add a zero to get the value on the wiki lists, sperm whale man I checked was 1,181,315 while wiki lists 12,535,000 as max, so a weremonitor can wear the same armor as a kangaroo man, find your blood_max and size_cur as a wererhino and add a 0 then check the wiki list.I did not know that's how those numbers worked.
Not sure if this is the correct thread. I was trying to use the Planning Mode for furniture, doors, tables and chairs. I check that any material and quality is allowed. after 8 or so tables were placed shortly after startup, the rest has sat for several seasons. There were idle dwarfs, but no one installed the furniture. I am using workflow, and I save and restart often as I do not have a long time to play at any one setting, so the planned furniture would have been a great benefit if it had worked. Am I missing something obvious or is it bugged? Using the latest version of LBPI've noticed this too in dfhack 43.05 beta1 when I reload a saved game from the main menu after having exited out of another one. It seems to go away if I restart the dwarf fortress executable itself, and the dwarves resume placing the queued furniture.
Any help is appreciated!
Planning mode was bugged in early 43.05 alphas. I thought it was fixed in the beta, but maybe we missed something.Not sure if this is the correct thread. I was trying to use the Planning Mode for furniture, doors, tables and chairs. I check that any material and quality is allowed. after 8 or so tables were placed shortly after startup, the rest has sat for several seasons. There were idle dwarfs, but no one installed the furniture. I am using workflow, and I save and restart often as I do not have a long time to play at any one setting, so the planned furniture would have been a great benefit if it had worked. Am I missing something obvious or is it bugged? Using the latest version of LBPI've noticed this too in dfhack 43.05 beta1 when I reload a saved game from the main menu after having exited out of another one. It seems to go away if I restart the dwarf fortress executable itself, and the dwarves resume placing the queued furniture.
Any help is appreciated!
I understand that DFHack uses the happiness number, and Dwarf Therapist uses Stress value, but shouldn't these two lead to the same happiness category?That is not the case - the Happiness number was removed when Stress was added, and the difference is entirely due to DFHack and Therapist using different labels for the different ranges.
If the happiness categories (http://dwarffortresswiki.org/index.php/v0.34:Thought) listed in the wiki to 0.34.x are still validThose categories are NOT valid anymore - you should be looking at the DF2014 page (i.e. the one for the current version), not one for an outdated version.
I don't quite understand what you're telling me. My problem may be much simpler than you think. If the happiness categories (http://dwarffortresswiki.org/index.php/v0.34:Thought) listed in the wiki to 0.34.x are still valid, then DFHack tells me that I have 7 dwarves who are "happy". But Dwarf Therapist categorizes them as "fine", which is two categories lower.Quietust gives you the rigorously correct answer, so far as I know. I take a more casual approach.
I understand that DFHack uses the happiness number, and Dwarf Therapist uses Stress value, but shouldn't these two lead to the same happiness category?
Or maybe, if these values are linked to fundamentally different feelings, Dwarf Therapist should rename it's column and instead of Happiness it should say Stress.
Hello,You have the wrong remotefortressreader version.
I'm running DFHack version 0.43.03-r1 (release) on Windows 10 (the console says Warning: Plugin RemoteFortressReader compiled for DFHack 0.34.11-r3-3104-g58ed20b running DFHack 0.43.03-r1-0-g9889379) with Dwarf Fortress 0.43.03, 32 bit.
No, whoever built that plugin didn't have the proper git tags for some reason. If the plugin had been build against 0.34.11, it would fail to load entirely. That one was build with DFHack 0.43.03-r1 (it must have been, since it loads under that DFHack version), but its more detailed version is reported as "3104 commits after 0.34.11-r3" instead of anything more recent.Hello,You have the wrong remotefortressreader version.
I'm running DFHack version 0.43.03-r1 (release) on Windows 10 (the console says Warning: Plugin RemoteFortressReader compiled for DFHack 0.34.11-r3-3104-g58ed20b running DFHack 0.43.03-r1-0-g9889379) with Dwarf Fortress 0.43.03, 32 bit.
If the warning would mention the same DF version both times, it'd likely be fine, but this won't work at all.
You need to get a copy of the plugin that matches your DF version.
I understand that DFHack uses the happiness number, and Dwarf Therapist uses Stress value, but shouldn't these two lead to the same happiness category?That is not the case - the Happiness number was removed when Stress was added, and the difference is entirely due to DFHack and Therapist using different labels for the different ranges.If the happiness categories (http://dwarffortresswiki.org/index.php/v0.34:Thought) listed in the wiki to 0.34.x are still validThose categories are NOT valid anymore - you should be looking at the DF2014 page (i.e. the one for the current version), not one for an outdated version.
whoever built that plugin didn't have the proper git tags for some reasonThanks, I reported this to PeridexisErrant. The build is from his current Starter Pack.
43.03-r1 is still the current version even for 43.05?No. DFHack releases never support DF versions newer than the ones they're named for. They sometimes support older versions, though (e.g. DFHack 0.43.03-r1 supports DF 0.43.03, 0.43.02, and 0.43.01).
uhh well its working fine so far, df hack of 0.43.03-r1 applied on DF 64 bit windows 0.43.05. only issue i've been having and its impossible to tell if its default DF or because i've been using fastdwarf obsessively, is that there's a lot of "distracted" dwarves that rapidly need to perform tavern and temple activities. still happens with normal speed and moving dwarves but i only have about 20 out of 100 dwarves legitimately working (and everyone is maximal happy), thus dorfs still desperately using tavern and temple.43.03-r1 is still the current version even for 43.05?No. DFHack releases never support DF versions newer than the ones they're named for. They sometimes support older versions, though (e.g. DFHack 0.43.03-r1 supports DF 0.43.03, 0.43.02, and 0.43.01).
I can guarantee that you're either not using DF 0.43.05 or not using DFHack 0.43.03-r1. Can you double-check the version that gets logged in the console (or on the title screen)?uhh well its working fine so far, df hack of 0.43.03-r1 applied on DF 64 bit windows 0.43.05. only issue i've been having and its impossible to tell if its default DF or because i've been using fastdwarf obsessively, is that there's a lot of "distracted" dwarves that rapidly need to perform tavern and temple activities. still happens with normal speed and moving dwarves but i only have about 20 out of 100 dwarves legitimately working (and everyone is maximal happy), thus dorfs still desperately using tavern and temple.43.03-r1 is still the current version even for 43.05?No. DFHack releases never support DF versions newer than the ones they're named for. They sometimes support older versions, though (e.g. DFHack 0.43.03-r1 supports DF 0.43.03, 0.43.02, and 0.43.01).
edit: clarified versions.
about job orders, there's a LACK of things to do and yet the purple (aka important) break messages still occur and i can bring up my stress values if needed, they're all -40,000 or higher except for immigrants... which i will need to cull next map i play as fps plummets after 40 dwarves... yay teleporting dorfs doesn't help :DIt probably depends on which dwarves are doing work. This thread (http://www.bay12forums.com/smf/index.php?topic=155793.0) might explain it better. Also, teleporting dwarves doesn't make them do actual jobs faster - it only cuts down on travel time. I suppose that could allow them more time to take care of their needs, but it wouldn't necessarily be enough if they're doing time-consuming jobs.
Is modtools/create-unit fully functional in the 43.05 beta 1 release? I'm able to use it to spawn units that show up on the citizens list and can be assigned labors, but they don't have proper ethics (they have their "he personally values" but not the civ ethics,) any gods, and an English first name. The command I'm using is:It hasn't changed since 0.42, as far as I know. It should be functional, but there have always been a few things it doesn't handle. I'm not sure what you mean by an "English first name" - are they missing a nickname? modtools/create-unit has an option for nicknames (see "modtools/create-unit -help"). There's also "spawnunit", which you might find easier for typical usage.
modtools/create-unit -race DWARF -caste MALE -civId \\LOCAL -groupId \\LOCAL -name MOUNTAIN
Is stonesense included in dfhack-0.43.05-beta1-Linux-64-gcc-4.8.1? The rest of DFHack works properly, but when I try and use the "stonesense" command at the DFHack# prompt, I get "stonesense is not a recognized command".It is not, sorry.
Is modtools/create-unit fully functional in the 43.05 beta 1 release? I'm able to use it to spawn units that show up on the citizens list and can be assigned labors, but they don't have proper ethics (they have their "he personally values" but not the civ ethics,) any gods, and an English first name. The command I'm using is:It hasn't changed since 0.42, as far as I know. It should be functional, but there have always been a few things it doesn't handle. I'm not sure what you mean by an "English first name" - are they missing a nickname? modtools/create-unit has an option for nicknames (see "modtools/create-unit -help"). There's also "spawnunit", which you might find easier for typical usage.
modtools/create-unit -race DWARF -caste MALE -civId \\LOCAL -groupId \\LOCAL -name MOUNTAIN
I apologise if this question has been asked before or this is the inappropriate place, but what has become of autosyndrome and its successors, item-trigger and reaction-trigger? I cannot find them anywhere in the new dfhack nor recent mention in the forums.
There is an item-trigger and reaction-trigger script in modtools, along with interaction-trigger.
Still getting the odd crash when zooming to units.Mind linking me to where this was reported before? I don't remember seeing it recently. Have you verified that it doesn't occur without DFHack (assuming it occurs consistently with DFHack)?
Getting a crash now and then when going to some units through to unit menu as well as when pressing v to inspect or examining creatures. Mostly seems to happen to creatures on different z levels, think it might be with some of the DFHack options on some of these things.This is from quite a while ago. I can't think of many DFHack tools that have anything to do with that screen. What DFHack version are you using? Are you using Truetype? TwbT? You could try disabling the search and manipulator plugins, I guess.
modtools/reaction-trigger -reactionName RELEASE_DWARF_MIGRANTS -command [ modtools/create-unit-friendly -race DWARF -caste MALE -civId a -groupId a -location [ \\LOCATION ] -name MOUNTAIN -age 20 ]
[lua]# world.raws.creatures.all[31].caste[0].body_info.extra_butcher_objects[0]
<caste_body_info.T_extra_butcher_objects: 0x05ee36d0>
anon_1 = 24
anon_2 =
anon_3 = 11
anon_4 =
anon_5 =
anon_6 =
anon_7 =
anon_8 =
anon_9 = 1
anon_10 = -1
anon_11 = -1
anon_12 = -1
anon_13 = 1
So hey, I was wondering, is there a script that fixes the "hostility" of tamed megabeasts? I glanced over the source code for the loyalty cascade fix and to my limited understanding, it only targets citizens?After my experience with raw modding, I believe the hostility is a function of the [MEGABEAST] token itself being present on the tamed creatures and not actually a bug with unit loyalty. That being said, I would also like a script to fix this if it is possible to make one.
modtools/reaction-trigger -reactionName KILL_CAPTIVE_DWARF -command [ create-unit -race FAKE_SAPIENT -caste MALE_DWARF -location [ \\LOCATION ] -age 20 -flagSet [ scuttle ] ]
:modtools/reaction-trigger -reactionName RELEASE_DWARF_MIGRANTS -command [ create-unit -race DWARF -caste MALE -civId a -groupId a -location [ \\LOCATION ] -name MOUNTAIN -age 20 ]
modtools/reaction-trigger -reactionName RELEASE_DWARF_MIGRANTS -command [ create-unit -race DWARF -caste MALE -civId \\LOCAL -groupId \\LOCAL -location [ \\LOCATION ] -name MOUNTAIN -age 20 ]
Still getting the odd crash when zooming to units.Mind linking me to where this was reported before? I don't remember seeing it recently. Have you verified that it doesn't occur without DFHack (assuming it occurs consistently with DFHack)?
Edit: found it:Getting a crash now and then when going to some units through to unit menu as well as when pressing v to inspect or examining creatures. Mostly seems to happen to creatures on different z levels, think it might be with some of the DFHack options on some of these things.This is from quite a while ago. I can't think of many DFHack tools that have anything to do with that screen. What DFHack version are you using? Are you using Truetype? TwbT? You could try disabling the search and manipulator plugins, I guess.
just seems to happen when I use z: Go to UnitBy "seems to", are you saying that it crashes some time later, or that you can't get anything else to cause the crash?
Continuing from my previous conversation.....
Okay so here I am again. So I moved the New version of create-unit.lua to the raw\scripts folder that had fixed my earlier problem allowing me to run this onLoad.init command with no issues:Code: [Select]modtools/reaction-trigger -reactionName KILL_CAPTIVE_DWARF -command [ create-unit -race FAKE_SAPIENT -caste MALE_DWARF -location [ \\LOCATION ] -age 20 -flagSet [ scuttle ] ]
:
And yes a dead dwarf appears at the feet of the one who operates this command, from the reaction... well its a fake dwarf... but it gets the job done of getting dwarf skulls (and other commands for humans, elves, goblins, kobolds, etc skulls and meat for everyone!).
well we had a different script that when reviewed was the new version of create-unit.lua renamed to create-unit-friendly.lua with a few minor changes.... I was shocked at how similar it was, and decided that because I couldn't get it to do anything right(moved it etc like I did with create-unit.lua), I removed it, retried these lines with create-unit...Code: [Select]modtools/reaction-trigger -reactionName RELEASE_DWARF_MIGRANTS -command [ create-unit -race DWARF -caste MALE -civId a -groupId a -location [ \\LOCATION ] -name MOUNTAIN -age 20 ]
modtools/reaction-trigger -reactionName RELEASE_DWARF_MIGRANTS -command [ create-unit -race DWARF -caste MALE -civId \\LOCAL -groupId \\LOCAL -location [ \\LOCATION ] -name MOUNTAIN -age 20 ]
The first line is the original line from the original onLoad.init, modified to access create-unit, we got a dwarf, but it was just set to friendly, and not a part of the fort civ/group at all. It eventually wandered around the tavern then disembarked to who knows where....
The second line is the line written based on the information in the first part of "create-unit.lua" that says to use \\LOCAL to make the created unit a member of the local civ and group.... and well this dwarf did the same as the first one. It appeared but was set to friendly, not a member of the civ/group, hung out roamed a statue garden then left to points unknown. so now we have 2 free roaming dwarves just enjoying themselves free from the politics of any civ (and not forced into slave labor in my deep mines)...
The only thing I have to say is I'm glad it pops up in the right location? but how do I force the dwarf to be a member of the fort?
481 if args.civId == 'LOCAL' then
482 civ_id = df.global.ui.civ_id
483 elseif args.civId and tonumber(args.civId) then
484 civ_id = tonumber(args.civId)
485 end
486
487 local group_id
488 if args.groupId == 'LOCAL' then
489 group_id = df.global.ui.group_id
490 elseif args.groupId and tonumber(args.groupId) then
491 group_id = tonumber(args.groupId)
492 end
Anyway, please be sure to report any issues you run into with 0.43.05-beta1. I'm hoping we can put up a stable release relatively soon.
What version, precisely, of DFHack are you using? "the pre release" isn't specific enough for me to tell. Something like "0.43.05-alpha3" would be, and that should be displayed on the title screen (and in the DFHack console).
By "seems to", are you saying that it crashes some time later, or that you can't get anything else to cause the crash?
The only minor bug is that seedwatch does not auto-restart after loading (unlike autobutcher which works fine when loading up a save).That's really more of a missing feature - seedwatch has never persisted across save/load cycles.
DFHack 0.43.05-beta1 though I have had it in the back in 42s ones as well. It's the last thing I do before the crash I get no other crash besides this one.0.42, really? This is the first time I've heard of the issue, so I'm fairly surprised. Does it occur with specific units? In a specific save? If so, uploading the save would be helpful.
Started up DFHack and started going to units doesn't seem to be causing it at least not yet so something else must happen somewhere to cause it.
...ed\Dwarf Fortress/hack/scripts/modtools/item-trigger.lua:116: attempt to index a nil value
stack traceback:
...ed\Dwarf Fortress/hack/scripts/modtools/item-trigger.lua:116: in global 'getitemType'
...ed\Dwarf Fortress/hack/scripts/modtools/item-trigger.lua:126: in global 'handler'
...ed\Dwarf Fortress/hack/scripts/modtools/item-trigger.lua:166: in global 'equipHandler'
...ed\Dwarf Fortress/hack/scripts/modtools/item-trigger.lua:175: in function <...ed\Dwarf Fortress/hack/scripts/modtools/item-trigger.lua:170>
function getitemType(item)
print("item: ", item)
if item:getSubtype() ~= -1 then
itemType = dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()).id
else
itemType = df.item_type[item:getType()]
end
return itemType
end
the print ("item: ",item) line is nice it gives me some info... not enough, but it got me looking for an answer. here's what the code looks like in the console when an error hits:0.42, really? This is the first time I've heard of the issue, so I'm fairly surprised. Does it occur with specific units? In a specific save? If so, uploading the save would be helpful.No idea though doing it at the start of loading a save doesn't seem to cause it so it must require something else to have happened before it. Seems like it would be a pretty painful crash to hunt down.
Okay I've been having an issue with item-trigger.luaNice catch! My best guess is that it's a DFHack issue, with something not handling plant growths correctly. The error appears to be happening on this line:
...
so now the issue is... why are plant growths causing this error... I tried a couple other lines trying to get the name of the item and it just errors out on the line... anyone have a clue what the line is I need to get the name to appear, so then I can start checking these "growths" for why they are erroring out?
itemType = dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()).id
which implies that one of these things is nil.function getitemType(item)
print("item: ", item)
if item:getSubtype() ~= -1 then
print(item:getType())
print(item:getSubtype())
print(dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()))
print(dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()).id)
itemType = dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()).id
else
itemType = df.item_type[item:getType()]
end
return itemType
end
I suspect that the third call to print under the "if" statement will print nil and the fourth will trigger an error for plant growths (the first two should be okay, since item has to be non-nil for "item:getSubtype()" in the "if" statement to work at all).
Okay I've been having an issue with item-trigger.luaNice catch! My best guess is that it's a DFHack issue, with something not handling plant growths correctly. The error appears to be happening on this line:
...
so now the issue is... why are plant growths causing this error... I tried a couple other lines trying to get the name of the item and it just errors out on the line... anyone have a clue what the line is I need to get the name to appear, so then I can start checking these "growths" for why they are erroring out?Code: [Select]itemType = dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()).id
which implies that one of these things is nil.
Try this:Code: [Select]function getitemType(item)
I suspect that the third call to print under the "if" statement will print nil and the fourth will trigger an error for plant growths (the first two should be okay, since item has to be non-nil for "item:getSubtype()" in the "if" statement to work at all).
print("item: ", item)
if item:getSubtype() ~= -1 then
print(item:getType())
print(item:getSubtype())
print(dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()))
print(dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()).id)
itemType = dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()).id
else
itemType = df.item_type[item:getType()]
end
return itemType
end
function getitemType(item)
if item:getSubtype() ~= -1 then
if dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()) then
itemType = dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()).id
else
print("getSubtypeDef has returned nil. type:",item,item:getType(),"subtype:",item:getSubtype())
end
else
itemType = df.item_type[item:getType()]
end
return itemType
end
if item:getSubtype() ~= -1 and dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()) then
separate note/issue: was there a change to unit.relations.{xxxxx}? I have one script that uses that and it now constantly spits out that relations is not found. Think there must of been a change in dfhack to that, too.Yes. Most stuff that was in "relations" was moved out into the main "unit" struct - e.g. "unit.relations.pregnancy_timer" is now "unit.pregnancy_timer". This was done because the old layout was wrong, and it had to be fixed to work properly with 64-bit DF.
Amostubal separate note/issue: If I'm not mistaken, units.relations stuff has been shifted up one level into the units structure itself (try gui/gm-editor on a unit and search for what you're looking for). I think that happened from 0.40.X to 0.42.X.0.43.05, not 0.42
Okay, it looks like the issue is a combination of several things:
- Plant growths can have subtypes that aren't -1
- item-trigger assumes that anything with a subtype that isn't -1 has an entry in world.raws.itemdefs
- There isn't anything in world.raws.itemdefs for plant growths (and there doesn't appear to be anything there we haven't identified yet, either)
I think changing the "if" statement to this would work:Code: [Select]if item:getSubtype() ~= -1 and dfhack.items.getSubtypeDef(item:getType(),item:getSubtype()) then
separate note/issue: was there a change to unit.relations.{xxxxx}? I have one script that uses that and it now constantly spits out that relations is not found. Think there must of been a change in dfhack to that, too.Yes. Most stuff that was in "relations" was moved out into the main "unit" struct - e.g. "unit.relations.pregnancy_timer" is now "unit.pregnancy_timer". This was done because the old layout was wrong, and it had to be fixed to work properly with 64-bit DF.
Ninja edit:Amostubal separate note/issue: If I'm not mistaken, units.relations stuff has been shifted up one level into the units structure itself (try gui/gm-editor on a unit and search for what you're looking for). I think that happened from 0.40.X to 0.42.X.0.43.05, not 0.42
function equipHandler(unit, item, isEquip)
local mode = (isEquip and 'onEquip') or (not isEquip and 'onUnequip')
local table = {}
table.mode = mode
table.item = df.item.find(item)
table.unit = df.unit.find(unit)
if table.item and table.unit then -- they must both be not nil or errors will occur after this point with instant reactions.
handler(table)
end
end
leave it up to me to do something that would cause errors to occur.... relation issue: how to get lastattacker ID lol.... on-death.lua script from roses.... was going to contact them next on that one. its under relationship_ids in the gm-editor. but unit.relationship_id.lastAttacker, unit.relationship_ids.lastAttacker, and unit.lastAttacker all do not work.unit.relationship_ids.LastAttacker. Case matters.
relation issue: how to get lastattacker ID lol.... on-death.lua script from roses.... was going to contact them next on that one. its under relationship_ids in the gm-editor. but unit.relationship_id.lastAttacker, unit.relationship_ids.lastAttacker, and unit.lastAttacker all do not work.unit.relationship_ids.LastAttacker. Case matters.
Did you try \LOCAL ?
Edit: no, that won't work. However, I have been using \\LOCAL in the console (with modtools/create-unit) for other tests in 0.43.05-beta1, and it has been working consistently. Perhaps you have an older version of the script still. Try replacing your hack/scripts/modtools/create-unit.lua with the original from 0.43.05-beta1, and get rid of the file you have in raw/scripts (e.g. move it somewhere outside of your DF folder if you don't want to delete it). Scripts in raw/scripts always take priority, so a broken script there will override a working script in hack/scripts.
Edit 2: oh, and you should probably be using modtools/create-unit.
modtools/create-unit -race GOLEM_ORICHALCUM -caste GOLEM -civId \\LOCAL -groupId \\LOCAL -name MOUNTAIN -age 1
modtools/reaction-trigger -reactionName ORICHALCUM_GOLEM -command [ modtools/create-unit -race GOLEM_ORICHALCUM -caste GOLEM -civId \\LOCAL -groupId \\LOCAL -location [ \\LOCATION ] -name MOUNTAIN -age 1 ]
function teleport(unit,pos)
local unitoccupancy = dfhack.maps.getTileBlock(unit.pos).occupancy[unit.pos.x%16][unit.pos.y%16]
local newoccupancy = dfhack.maps.getTileBlock(pos).occupancy[pos.x%16][pos.y%16]
if newoccupancy.unit then
unit.flags1.on_ground=true
end
unit.pos.x = pos.x
unit.pos.y = pos.y
unit.pos.z = pos.z
if not unit.flags1.on_ground then unitoccupancy.unit = false else unitoccupancy.unit_grounded = false end
end
function teleport(unit,pos)
if dfhack.maps.getTileBlock(unit.pos) then
local unitoccupancy = dfhack.maps.getTileBlock(unit.pos).occupancy[unit.pos.x%16][unit.pos.y%16]
local newoccupancy = dfhack.maps.getTileBlock(pos).occupancy[pos.x%16][pos.y%16]
if newoccupancy.unit then
unit.flags1.on_ground=true
end
unit.pos.x = pos.x
unit.pos.y = pos.y
unit.pos.z = pos.z
if not unit.flags1.on_ground then unitoccupancy.unit = false else unitoccupancy.unit_grounded = false end
else --dfhack.maps.getTileBlock(unit.pos) has failed. they probably came from create-unit.
print("was unable to getTileBlock for Teleport. Using an alternative method")
local newoccupancy = dfhack.maps.getTileBlock(pos).occupancy[pos.x%16][pos.y%16]
if newoccupancy.unit then
unit.flags1.on_ground=true
end
unit.pos.x = pos.x
unit.pos.y = pos.y
unit.pos.z = pos.z
--we wont need to set previous occupancy, because the unit literally existed outside of time and space, and we do not have access to it.
end
end
You could switch from getTileBlock to ensureTileBlock, not sure if that will fix the problem though.nah same problem.... I'm not sure what the rest of the script is for other than repairing occupancy of the 2 blocks that its transfering between. The interesting thing, is that I have an operating save, where the above reaction is being tested.... basically load and the reaction completes a few seconds later. every other attempt it crashes with the above script, a flat out wipe clean and gone crash, nothing left.... I hate those, nothing in the errorlog or the stderr
- Google support, etc
The changes needed are adding the lineI meant to ask what would be required without using that line (i.e. are there changes to the protobuf syntax that would require changing the body of those files?).
syntax = "proto2";
to each file.
Question, will the onJobCompleted eventful event trigger when a tree is chopped down or a plant is harvested? I am thinking about adding a script that lets you "research" better farming techniques, thus increasing your yield.AFAIK tile mined worked okay. That is the way the auto-expanding burrows worked before.
EDIT: Or a tile is mined? Basically if I can detect whenever one of these things happen you could limit certain yields, and be able to research better "techniques" which would increase yield.
Well since mine is still the last I will put my new questions on to this one,When you do that, this thread doesn't show up under "Updated topics" for anyone who's replied, which makes it less likely for people to notice that you've asked more questions.
Well currently all of those functions are only available in hard coded buildings. I was hoping to make it possible to create custom buildings with those jobsTry adding sand collecting job to other buildings. Do the dwarves figure out how to do it? if so you just need to auto-add job.
Well currently all of those functions are only available in hard coded buildings. I was hoping to make it possible to create custom buildings with those jobsTry adding sand collecting job to other buildings. Do the dwarves figure out how to do it? if so you just need to auto-add job.
If you want something more... different (like building which auto-fills bags with sand when it has power) you'll need to do it manually.
Mine doesn't open. Well, it does, but it immediately closes. Help?
Well currently all of those functions are only available in hard coded buildings. I was hoping to make it possible to create custom buildings with those jobsTry adding sand collecting job to other buildings. Do the dwarves figure out how to do it? if so you just need to auto-add job.
If you want something more... different (like building which auto-fills bags with sand when it has power) you'll need to do it manually.
How do I add the sand collecting job to other buildings?
That should display a dialog and just deactivate DFHack (keeping DF open) - if it's not doing that when the DF/DFHack versions aren't compatible, that's another issue.Mine doesn't open. Well, it does, but it immediately closes. Help?
Sounds like you might have a mismatch between DF version and DFHack version
Can jobs be created from nothing with dfhack.job.linkIntoWorld(job,new_id)? When it talks about jobs is that just reactions, just "tasks" (e.g. Gather Sand, Milk Creature, Tame Animal, etc...), or both?
I'm guessing the eventful.addReactionToShop won't work for adding "tasks" to buildings since they don't have a reaction ID. Is there a similar function for adding "tasks"?
Can jobs be created from nothing with dfhack.job.linkIntoWorld(job,new_id)? When it talks about jobs is that just reactions, just "tasks" (e.g. Gather Sand, Milk Creature, Tame Animal, etc...), or both?
I'm guessing the eventful.addReactionToShop won't work for adding "tasks" to buildings since they don't have a reaction ID. Is there a similar function for adding "tasks"?
Yes jobs can be created from nothing. DF even assigns workers for some works. You might need to add it to job postings (or how it's called).
Yes task are a bit special. For one thing it needs other references which are not set by reaction framework. E.g. Tame Animal needs an animal target, which you could set manually. Imho you could add fake reactions that when triggered create the correct job. However each special task has it's own arcaneinvocationsetup. That is basically why i'm procrastinating with advfort development (and the fact that it's a maze of code).
See also http://www.bay12forums.com/smf/index.php?topic=139553.msg7411188#msg7411188 above..Sorry, I didn't reply to that because I'm really not familiar with autochop. I'm guessing the issues with designations and jobs targeting the wrong trees are related to the job creation issues, at least to an extent.
Does autochop currently have a feature to prioritize trees? [..] Do you mean you designated some trees manually?Prioritising (mature) trees is a suggestion for a fix; AFAIK it's not currently implemented at all. However, prioritising manually selected trees over autochop's designation is a much-desired feature :)
Interesting. I will definitely have to take a look at assigning tasks through reaction-trigger. If I could figure that all out then you could get rid of all vanilla buildings and have a total conversion.
Interesting. I will definitely have to take a look at assigning tasks through reaction-trigger. If I could figure that all out then you could get rid of all vanilla buildings and have a total conversion.
My Underhive Settlement reboot removes all vanilla workshops. Well, all except the butcher shop, as the slaughter job will not work at any other workshop (but milking will, go figure).
To do hardcoded jobs that cannot be replaced with reactions I hack a button for that job into the workshop sidebar. Triggering the job from a reaction will probably work better though...
Hey lethosor or anyone else knows...A couple things: "tweak" is a plugin, and "tweak makeown" is a subcommand of that plugin that does what you expect (ideally). There's also a "makeown.lua" file in hack/lua that other scripts can use more easily, which I just found out about thanks to you. "tweak" also has a lot of other unrelated subcommands.
Whats the status of makeown and tweak, are they all the way out? They still show up in the DFHack readthedocs...
http://dfhack.readthedocs.io/en/stable/docs/Plugins.html?highlight=makeown
The reason I'm asking is we were having issues with a few commands trying to convert an invader into a citizen.
apparently our previous script was using makeown but it apparently hasn't been updated in quite some time, and now we came across 2 lines that are giving us issues that we really aren't sure what they did to begin with.
makeown.lua:151: Cannot write field historical_figure.anon_1: not found.
we removed the .relations from these 2 lines, since relations is gone... what were anon_1, anon_2, anon_3 discovered to be looking at? or what are they trying to reference.
hf.anon_1 = unit.anon_2
hf.anon_2 = unit.anon_3
....
if its not a script that's going to get fixed and re-released, does anyone else have a method to accomplish what makeown did, convert a unit to a citizen of the fort?
Here's a new beta release: https://github.com/DFHack/dfhack/releases/tag/0.43.05-beta2. Still waiting on Windows for now, but this adds 64-bit Stonesense support on OS X and Linux (which was already available on Windows), so I didn't want to delay this further.
I created a forum account to be able express my excitement. Thank you, lethosor!Here's a new beta release: https://github.com/DFHack/dfhack/releases/tag/0.43.05-beta2. Still waiting on Windows for now, but this adds 64-bit Stonesense support on OS X and Linux (which was already available on Windows), so I didn't want to delay this further.
I logged on to my account on this site for the first time in months just to be able to say: Squeeeee! :D
just thought of this now, is it possible to Copy the entire world data of another save and paste it into another world?I'm afraid I fail to understand exactly what you're trying to achieve, so the answer is hit-and-miss:
like take some old gen world and port it over to an Arena save? or is this working into Save corruption territory?
well it's more taking the small Arena world map swapping it with a different world map.just thought of this now, is it possible to Copy the entire world data of another save and paste it into another world?I'm afraid I fail to understand exactly what you're trying to achieve, so the answer is hit-and-miss:
like take some old gen world and port it over to an Arena save? or is this working into Save corruption territory?
- You can copy your save, retire, and start in another mode, then revert to the original save, but I guess that's not what you want.
- Transplanting the history etc. from one geography to another would result in a mess, since some settlements would end up in the ocean, for instance. While it should be possible in principle by shifting settlements around, it would be very hard to do in practice.
- Keeping the geography and replacing it with a different history is easy: just keep the main seed and let DF randomize the other ones when generating a new world.
- Transplanting a fortress would likewise be a mess. The "easy" part would be to copy the site, but you'd also have to stitch the civ in, and its sites, and relation to other civs would have to be adjusted, etc. Likewise, the inhabitants would have to be adjusted, so Urist McTraderLover could not be friends with 15 traders from civs that only existed in the original world, etc. You also have regions, geo-regions, etc. to take into consideration, as well as instruments, dance forms, and so on that don't exist in the new world.
However, I suspect you're after something completely different...
You can use dfhack.run_command_silent(), although that would probably require writing another script to actually send the output to another file.
All output is returned from that function instead of being printed, including errors. It's returned as a table, I think, which includes the color of each piece of text, so you could identify errors that way if you wanted.
It's difficult to damage candy, toggling the artifact_mood and artifact flags prevents item damage too.Was more thinking of some way to slow it way down.
Not sure where to ask but is there an 'embark anywhere' utility with dfhack?"embark-tools anywhere". This is a good place to ask.
Three questions:There's Gui::revealInDwarfmodeMap() in C++. That doesn't seem to be exported to Lua, and I can't find a good equivalent. There's the Viewport class in the "gui.dwarfmode" module, but it looks like that requires more setup to use (I couldn't figure it out by playing around with it, but there are probably examples - maybe gui/liquids?). Anyway, I should have that available to Lua in r1.
1. Is there an easy way to center the game screen on a given position? I seem to remember there was a function already built in, but I can't seem to find it.
2. Is there a builtin pop up box? What I mean is, I am altering one of my guis to allow changing of classes, but I want there to be a warning, something like "Are you sure you want to change class, Press Enter for Yes, Press Esc for No". I know I can use the same method I use for the gui (i.e. make a widget.Panel and add the options in there) but I was just wondering if there was already a pre-constructed option.Take a look at the "gui.dialogs" module (specifically showYesNoPrompt()).
3. Does anyone have a working script that fully constructs a building? I remember making a rough one awhile back (to test the feasibility of multi-story buildings) but I seem to have lost that code. I know it is possible using the dfhack.buildings functions and then altering the construction stage, thought I would check if anyone has something already working before I re-do that work.I haven't seen anything like this before, sorry. If you do come up with something that works, or find your original code, it would be nice to share that in case others find it useful.
In case the handful of people who have reported autochop being totally broken didn't see my responses on GitHub (or if anyone else is curious): we've finally identified and fixed the issues with autochop creating and removing tree-cutting jobs, which probably dated back to 0.40.20 (the job priorities release). Issues such as dwarves standing by felled trees trying to cut them down a second time should be resolved now, as well as ones where autochop wouldn't actually stop trees from being cut down when requested.
I'm working on similar fixes for getplants now, but that was about the last major issue we had left to resolve before a stable release. If anyone wants to try out the autochop fixes, they're currently on the develop branch (https://github.com/dfhack/dfhack/tree/develop).
I need a bit of help here, this is driving me nuts after two hrs of trying to figure it out. The Workflow Status GUI is accessible through selecting a workshop, then Alt-w and then Shift-S. How can I set a key bind like Alt-w or some other so I can get the Workflow Status GUI straight up from game or from z-stock menu? Please help me out and let me know what to do. I am using the 43.03 Peridexis Newb Pack.
And thank you guys for working on DFHack!
keybinding add Alt-W@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workflow
keybinding add Alt-W@overallstatus "gui/workflow status"
I'm not quite sure what you're referring to. Does alt+w in the main fortress mode screen open the status screen you're thinking of? What if you run "gui/workflow status"?
EDIT 2: Just to sum up because it's seems a bit strange how this thing worked out. I read thatThey were removed because we weren't sure if people would still want those bindings, and we weren't sure if workflow was going to be stable. They have been re-added after DFHack 0.43.05-beta2.
keybinding add Alt-W@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workflow
keybinding add Alt-W@overallstatus "gui/workflow status"
have been removed because it was not needed anymore.
And adding this two commands to my init file did nothing to bring up the menu. The direct access to Workflow Status screen where you can manage the work orders is done by:Did you restart DF after editing your init file?
keybinding add Alt-E@ "gui/workflow status"
This will open the Status screen from any menu you are in. I just hope I didn't mess up any other bind with Alt-E. I used it because I was unable to find an key bind to it so I hope it's fine.
keybinding add Alt-W@dfhack/lua/status_overlay "gui/workflow status"
You might have a script running that changes the "z" screen (by adding an "x: Additional options" item), which adds an extra screen and keeps "overallstatus" from working.
modtools/reaction-trigger -reactionName TESB_DECONSTRUCT_TRIBUTE -command [ modtools/anonymous-script "dfhack.buildings.deconstruct(df.building.find(args[1]))" \\BUILDING_ID ]
(anonymous lua script):1: Cannot write field building.find(): integer expected.
stack traceback:
[C]: in field 'find'
(anonymous lua script):1: in main chunk
[C]: in function 'dfhack.safecall'
...warf Fortress/hack/scripts/modtools/anonymous-script.lua:26: in local 'script_code'
...ied-MWDF\MWDF Project\Dwarf Fortress\hack\lua\dfhack.lua:562: in function 'dfhack.run_script_with_env'
(...tail calls...)
[C]: in field 'runCommand'
...ied-MWDF\MWDF Project\Dwarf Fortress\hack\lua\dfhack.lua:580: in upvalue '_run_command'
...ied-MWDF\MWDF Project\Dwarf Fortress\hack\lua\dfhack.lua:595: in function 'dfhack.run_command'
...warf Fortress/hack/scripts/modtools/reaction-trigger.lua:146: in local 'doAction'
...warf Fortress/hack/scripts/modtools/reaction-trigger.lua:186: in function <...warf Fortress/hack/scripts/modtools/reaction-trigger.lua:115>
replace df.building.find(args[1]) with df.building.find(tonumber(args[1]))
@Rumrusher: Are you sure entito is a pointer to the target struct rather than a copy of the data of the target struct? I'm too hazy on Lua's rules myself to say anything with certainty, but it looks like a possible cause (and could be tested by using the full path to see if that takes hold).yeah it is given I could just make all civs have a position but, I figure doing this saves me when I roll in an hardcoded civ with no way to setting the entity position on a raw level to give me military.
Using a script rather than providing modified raws to swap in and out seems like a needlessly complicated way of doing things to me...
@lethosor - you have been asking in this thread http://www.bay12forums.com/smf/index.php?topic=163671.0 (http://www.bay12forums.com/smf/index.php?topic=163671.0) if the script works for caravans and I confirm it did help me get the rest of the human caravan on the map. My case was a bit specific because when caravan was announced only guards entered the map but soon after some darn monkey attacked and killed a horse. Since I have horses on the map I didn't think it's related to caravan but indeed the monkey managed to kill the caravan horse and the rest of the caravan got stuck outside of map. Using the script a few in-game days later got the rest of the traders on the map but now they are stuck at the bin that was "dropped" by the dead horse and are stuck at the edge of the map again. As far as I know I just have to wait for them to go insane and die but that shouldn't affect future caravans visits from humans right?Maybe, but I'm not sure.
In regards to sieges - I had one announced the other day and the game pauses and zooms to where the units entered the map. There is always only a few that get spotted on the edge like 10 units or so right from the start and other units enter the map following the ones that appeared when siege is announced. I made a quicksave because it was late for me and I said will deal with this siege next time I play. So I made a backup of the save and then I let the siege go forward for a while just to see how many attackers came and there was around 80 goblins & trolls (in the "u"/others screen). So before I started the game next time I used the backed up quicksave to start right from where the siege was announced. But this time there were only goblins that were already on the map, so some 8 goblins and all the other units from the siege were gone and have never entered the map (there were also only 8 present in the "u"/others screen). So it seems that quicksave at the time that siege is announced only saves the units that are present on the map but not the ones that still follow right behind them. It cuts out those that are entering the map. So that siege ended very fast with only a few goblins that I killed and I never got a siege again. I am not sure how much in-game time has passed since then but it seems like a lot. So do you guys have any experience with that and do you think that those goblins that didn't spawn might be stuck "somewhere in the savegame folder/world.sav file" between the world map and fort map and could create a mess long term or prevent other goblin sieges to happen? Any ideas on this one?Sounds like a DF bug to me. Did you try saving from the options menu as well?
Also I think that the game does NOT save farm plots settings properly. The fertilize on/off function might not be saved properly, actually is always set/reset to "on" after you load the game. I set some farms to not be fertilized but when I reload all are set to fertilize "on" again. I did check if it might be because seasons changed but the fertilize "on/off" settings have all been reset for all farms and for all seasons. Might be a bug hiding in the potato farm that no one noticed :) Anyway you guys probably can check in a minute what stats are saved for farm plots and see if fertilize "on/off" option is also saved or not. Sounds strange to my because not saving it should crash the game on load I guess but hey this is DF and anything is possible :DI can't find any DFHack tools that deal with fertilization at all, so I don't think it's a DFHack issue. I've never had it happen, in any case. Just to check, does the "f" option when you select a farm plot say "Fertilize" or "Cancel fert"?
Sounds like a DF bug to me. Did you try saving from the options menu as well?
I can't find any DFHack tools that deal with fertilization at all, so I don't think it's a DFHack issue. I've never had it happen, in any case. Just to check, does the "f" option when you select a farm plot say "Fertilize" or "Cancel fert"?
After I let the siege go for a while I exited the game normally not with the kill command, so esc and savegame etc. The prob is that next time I run the game I deleted this last savegame because I had the quick save from only a few minutes before. I never loaded the save to be able to see if that one might be corrupt but never happened to me anyway so I am sure it was nothing wrong there. I am sure that quicksave cut out the units like there is a glitch between region-snapshot.dat and unit.dat. Where does the U screen/others get the units data from? Do like units get generated on the spot when siege is announced and are visible on U screen/others immediately/first and then units enter the map (same with caravans, megabeasts, etc)? It might explain why people get this strange "units not entering the map" because they save spot on when the game announces the event and pauses. If you then exit the game and reload the units that did not enter the map get bugged somehow/stuck out of map unable to enter.I suppose saving at that point could be the cause, although quicksave only triggers an autosave, so if that were the cause, it wouldn't be quicksave-specific.
Yes it does change. I set them all to Cancel, only wanted my pig tail farms to be fertilized but after a reload all farms had fertilize back on.Are you saying that you switched it to display "f: Cancel fert"? I'm pretty sure that means you enabled fertilization, although I could be misunderstanding.
I suppose saving at that point could be the cause, although quicksave only triggers an autosave, so if that were the cause, it wouldn't be quicksave-specific.Like you said saving at that point could be the cause. Might be worth keeping this in mind and test it further when events pop up to see if there is a savegame generating related bug
Yes it does change. I set them all to Cancel, only wanted my pig tail farms to be fertilized but after a reload all farms had fertilize back on.
Are you saying that you switched it to display "f: Cancel fert"? I'm pretty sure that means you enabled fertilization, although I could be misunderstanding.
When you build a farm plot, the default setting for fertilize is on, as fertilize. You can pres "f" and it sets the farm plot to cancel fert, meaning it won't be fertilized. If you set farms to cancel fert, save and reload those same farms will have fertilize back on.I'm pretty sure that's not right. "f: fertilize" means "if you press f, this plot will be fertilized, but right now it's not", and "f: Cancel fert" means "this plot is being fertilized, so pressing f will cancel fertilization". I'm basing this off of personal experience (I've never had a plot fertilized, so I'm pretty sure it's not the default), and the fact that fertilization counts are only displayed when "cancel fert" is displayed, which would be pretty useless if "cancel fert" meant "fertilization is inactive". I'll admit that it is inconsistent with other menus, though.
Oh and btw an idea for Autobucher. Is it possible that one more thing would be included in those options and that is to be able to set collect eggs on/off for every "race". The don't collect eggs option, should be possible by a script that setts forbid on certain race eggs in the nest box. It sucks locking and unlocking or forbidding eggs. This option would perfectly round up the autobutcher tool.I tried making a separate plugin to forbid eggs once, and found that it was a lot harder than I expected. It might be easier now that we have ways to cancel jobs easily, and I've been meaning to look into it again at some point.
@Patric & lethosorI think it would be best to keep autobutcher from marking units who have claimed a nestbox with (fertile) eggs. It doesn't look like it does that yet.
I am on it, I have all the save games set and ready to test in all possible ways. Will write what I come up with in a structure so it can be reported to Toady afterwards if I locate the bugs close enough. I plan to do it tomorrow or latest on monday.
I have been thinking about eggs some more and I am interested if you guys know if those can be forbidden by a script while eggs are inside a nest box. Also the autobutcher works the way that it slaughters the oldest animal when a child matures so this will cause problems. If an animal which laied eggs is butchered then those will not hatch. Those forbidden eggs then stay for ever and the nest box is occupied. Not sure how to get around that with a code. I have been doing a lot of this manually to try and figure out the best way.
I tried making a separate plugin to forbid eggs once, and found that it was a lot harder than I expected. It might be easier now that we have ways to cancel jobs easily, and I've been meaning to look into it again at some point.I wrote the "nestboxes" plugin I can't remember how many years ago that does this: it forbids fertile eggs, no matter where they are, so they are left alone and allowed to hatch. (Some people consider this cheaty.) I suppose we could move this out of devel, it is perfectly stable.
I was having an issue in 0.40 where forbidding them wouldn't stop existing egg-hauling jobs. (Also, there's an item_eggst flag that you can check instead of working with pregnancy information.) I think the addition of Job::removeJob() would make it easier to stop existing hauling jobs, so hopefully we can get one of the plugins working for r2.Nestboxes runs fairly frequently (every five ticks), but it would be an idea to stop hauling jobs.