Bay 12 Games Forum

Dwarf Fortress => DF Modding => Utilities and 3rd Party Applications => Topic started by: Meph on July 30, 2014, 11:29:13 am

Title: Script to fill bucket/barrel with water/magma near a workshop
Post by: Meph on July 30, 2014, 11:29:13 am
Edit: Solution to be found here: http://www.bay12forums.com/smf/index.php?topic=141497.msg5526201#msg5526201

Hey everyone,

IndigoFenix wrote this script a while back, but it hasnt been used by anyone so far. It should check for water/magma under a workshop and cancel the reaction if there is none. I want to use it to store/move these liquids by putting them in containers. For example a worker goes to the still (which is build above water), and does the "fill barrel with water" reaction, to get a water barrel.

It doesnt work though, the barrel gets filled regardless of there being water or not.

Here the script:
Code: [Select]
--Lets you make reactions that require water or magma under the workshop.  Reactions must start with LUA_HOOK_USEWATER or LUA_HOOK_USEMAGMA.

function usewater(reaction,unit,job,input_items,input_reagents,output_items,call_native)
local building = dfhack.buildings.findAtTile(unit.pos)
local pos = {}
pos.x = building.centerx
pos.y = building.centery
pos.z = building.z
baseBlock = dfhack.maps.ensureTileBlock(pos.x,pos.y,pos.z)
liquidBlock = dfhack.maps.ensureTileBlock(pos.x,pos.y,pos.z-1)
if liquidBlock.designation[pos.x%16][pos.y%16].flow_size > 0 and liquidBlock.designation[pos.x%16][pos.y%16].liquid_type == true then
liquidBlock.designation[pos.x%16][pos.y%16].flow_size = liquidBlock.designation[pos.x%16][pos.y%16].flow_size - 1
else
dfhack.gui.showAnnouncement( dfhack.TranslateName(unit.name).." cancels "..reaction.name..": Needs water." , COLOR_RED, true)
for i=0,#input_items-1,1 do
input_items[i].flags.PRESERVE_REAGENT = true
end
for i=0,#reaction.products-1,1 do
reaction.products[i].probability = 0
end
end
end

function usemagma(reaction,unit,job,input_items,input_reagents,output_items,call_native)
local building = dfhack.buildings.findAtTile(unit.pos)
local pos = {}
pos.x = building.centerx
pos.y = building.centery
pos.z = building.z
baseBlock = dfhack.maps.ensureTileBlock(pos.x,pos.y,pos.z)
liquidBlock = dfhack.maps.ensureTileBlock(pos.x,pos.y,pos.z-1)
if liquidBlock.designation[pos.x%16][pos.y%16].flow_size > 0 and liquidBlock.designation[pos.x%16][pos.y%16].liquid_type == false then
liquidBlock.designation[pos.x%16][pos.y%16].flow_size = liquidBlock.designation[pos.x%16][pos.y%16].flow_size - 1
else
dfhack.gui.showAnnouncement( dfhack.TranslateName(unit.name).." cancels "..reaction.name..": Needs magma." , COLOR_RED, true)
for i=0,#input_items-1,1 do
input_items[i].flags.PRESERVE_REAGENT = true
end
for i=0,#reaction.products-1,1 do
reaction.products[i].probability = 0
end
end
end

dfhack.onStateChange.load = function(code)
local registered_reactions
if code==SC_MAP_LOADED then
--registered_reactions = {}
for i,reaction in ipairs(df.global.world.raws.reactions) do
if string.starts(reaction.code,'LUA_HOOK_USEWATER') then
eventful.registerReaction(reaction.code,usewater)
registered_reactions = true
elseif string.starts(reaction.code,'LUA_HOOK_USEMAGMA') then
eventful.registerReaction(reaction.code,usemagma)
registered_reactions = true
end
end
if registered_reactions then
print('Use Liquid Reactions: Loaded.')
end
elseif code==SC_MAP_UNLOADED then
end
end

if dfhack.isMapLoaded() then dfhack.onStateChange.load(SC_MAP_LOADED) end

The reaction I used for testing is this:
Code: [Select]
[REACTION:LUA_HOOK_USEWATER_WATERWELL]
[NAME:Fill a barrel with water]
[BUILDING:STILL:CUSTOM_ALT_W]
[REAGENT:A:1:BARREL:NONE:NONE:NONE][PRESERVE_REAGENT] [EMPTY]
[PRODUCT:100:10:DRINK:NONE:WATER:NONE][PRODUCT_TO_CONTAINER:A]
[SKILL:BREWING]

The reaction runs fine, and a barrel of water is created. Problem: It should say "no water available" and cancel the reaction, but it doesnt.

I named the script "waterwell.lua" and added "waterwell enable" to the dfhack init.
Title: Re: Need help with water/magma script
Post by: Roses on July 30, 2014, 12:13:38 pm
I can't see anything obviously wrong with it. You might try putting
Code: [Select]
print(liquidBlock.designation[pos.x%16][pos.y%16].flow_size,liquidBlock.designation[pos.x%16][pos.y%16].liquid_type)
Above the if statement to test.
Title: Re: Need help with water/magma script
Post by: Meph on July 30, 2014, 12:22:11 pm
I added it above the
Code: [Select]
if liquidBlock.designation[pos.x%16][pos.y%16].flow_size > 0 and liquidBlock.designation[pos.x%16][pos.y%16].liquid_type == true then
Ran it again, nothing changed.

The other problem I ran into: How do you even build a workshop above water? I couldnt get a still to be placed over water/channel/downstairs.
Title: Re: Need help with water/magma script
Post by: Roses on July 30, 2014, 12:26:07 pm
Are you getting the message 'Use Liquid Reactions: Loaded.'?

If you aren't seeing anything printed out after adding that line, it means its not even running the function when the reaction is run. The only difference between the code from mine that I can see is the "dfhack.onStateChange.load" I gave it a custom name "dfhack.onStateChange.loadUpgradeBuilding", its possible that the "dfhack.onStateChange.load" is used somewhere else and so its not registering, but I am not sure if thats how it works.

So I guess my last suggestion is change both instances of dfhack.onStateChange.load to dfhack.onStateChange.loadUseLiquid
Title: Re: Need help with water/magma script
Post by: Meph on July 30, 2014, 12:57:11 pm
I did, nothing. But I missed something else: It doesnt give any error message when the reaction is run, but when dfhack loads:

Code: [Select]
...rworkDF V.5.10\Dwarf Fortress\hack\scripts/waterwell.lua:52: attempt to index global 'eventful' (a nil value)
stack traceback:
        ...rworkDF V.5.10\Dwarf Fortress\hack\scripts/waterwell.lua:52: in function <...rworkDF V.5.10\Dwarf Fortress\hack\scripts/waterwell.lua:46>
[DFHack]#
Title: Re: Need help with water/magma script
Post by: Roses on July 30, 2014, 01:00:45 pm
Ah, you need
Code: [Select]
local eventful = require 'plugins.eventful'
local utils = require 'utils'

somewhere outside of the functions. Mine is right above the dfhack.onStateChange.load = function(code)
Title: Re: Need help with water/magma script
Post by: milo christiansen on July 30, 2014, 01:02:47 pm
Slightly OT, but potentially useful:

Take a look at the DFHack workshops in the latest Rubble, they almost all use water or magma in some way.

To summarize:
Most of these workshops use up liquids when they operate.
It is possible to run the reaction without liquids in most cases, but you don't get anything and it prints an error announcement.
The buildings that deal with water all take it through downward passable tiles around the workshop.

I have a simple library I use that has functions for:
Eating fluids from below an area
Eating fluids in a specified tile
Spawning fluids below an area
Spawning fluids in a specified tile
Finding a minecart (optionally magma safe) in a tile
Finding a minecart (optionally magma safe) in an area
Filling a minecart with a specified liquid

Pretty much all the things a modder would want to do with fluids.
The module and it's optional driver command are both in the DFHack script list thread (name "rubble_fluids"), but the latest version is always included in the "Libs/DFHack/Fluids" Rubble addon.

As for the script you are trying to use: it looks like it may be easier to use (you don't need to write any lua logic of your own) but a lot less flexable.

(BTW: feel free to steal any of the scripts included with Rubble, "User/DFHack/Cart Filler" and "User/DFHack/Cart Filler/Powered" may be particularly interesting)

I do have a barrel filler addon (that works fine), but it was made for Better Dorfs and never moved to Rubble, I'll post the script later (if I remember).
Title: Re: Need help with water/magma script
Post by: Meph on July 30, 2014, 01:27:06 pm
Roses: Thanks, it works now.

But I do have to do an epic facepalm. I cant build any workshops above water. -.- Only NEEDS_MAGMA workshops can be build over channels/open space and liquids. Argh.

milo christiansen: Thanks, I will have a look. But how did you solve the problem I mention above? I cant manage to build anything over liquids. I even build one on a brook, but it didnt count...

Quote
The buildings that deal with water all take it through downward passable tiles around the workshop.
So if you have water around it, one z level below, it works?
Title: Re: Need help with water/magma script
Post by: milo christiansen on July 30, 2014, 01:31:02 pm
Yup, works great too (I do the same thing with some magma shops, just because :p)

(I did mention that you need a downward passable tile above the liquids didn't I? well if not now I have.)
Title: Re: Need help with water/magma script
Post by: Roses on July 30, 2014, 01:35:46 pm
You can pretty easily modify that script Meph to check the tiles right next to the workshop, if I get a second I will do it for you.
Title: Re: Need help with water/magma script
Post by: Meph on July 30, 2014, 01:39:56 pm
Roses, that would be great. I did have a look at the scripts in rubble, but wow, there is a lot more than I'd even know how to alter to fit my needs.

This one, just for the record:
Code: [Select]
--[[
Rubble Fluids DFHack Lua Module

Copyright 2014 Milo Christiansen

This software is provided 'as-is', without any express or implied warranty. In
no event will the authors be held liable for any damages arising from the use of
this software.

Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to
the following restrictions:

1. The origin of this software must not be misrepresented; you must not claim
that you wrote the original software. If you use this software in a product, an
acknowledgment in the product documentation would be appreciated but is not
required.

2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.

3. This notice may not be removed or altered from any source distribution.
]]

local _ENV = mkmodule("rubble_fluids")

-- Returns true if the specified tile is downward passable (to flows).
function passableDown(x, y, z)
ttype = dfhack.maps.getTileType(x, y, z)
tshape = df.tiletype.attrs[ttype].shape
return df.tiletype_shape.attrs[tshape].passable_flow_down
end

-- Eat fluid from the specified tile, returns true if it succeeds.
function eatFluid(x, y, z, magma, amount, minimum)
local block = dfhack.maps.ensureTileBlock(x,y,z)

if block.designation[x%16][y%16].flow_size >= minimum then
if block.designation[x%16][y%16].liquid_type == magma then
block.designation[x%16][y%16].flow_size = block.designation[x%16][y%16].flow_size - amount
else
return false
end
else
return false
end

dfhack.maps.enableBlockUpdates(block,true,true)
return true
end

-- Eat from below a specified area, there needs to be access to the fluid via a downward passable tile.
function eatFromArea(x1, y1, x2, y2, z, magma, amount, minimum)
for cx = x1, x2, 1 do
for cy = y1, y2, 1 do
if passableDown(cx, cy, z) then
if eatFluid(cx, cy, z-1, magma, amount, minimum) then
return true
end
end
end
end
return false
end

-- Check if there is enough fluid of the correct type in the specified tile.
function checkFluid(x, y, z, magma, amount, minimum)
local block = dfhack.maps.ensureTileBlock(x,y,z)

if block.designation[x%16][y%16].flow_size >= minimum then
if block.designation[x%16][y%16].liquid_type == magma then
return true
else
return false
end
end
return false
end

-- Check if there is enough fluids of the correct type below a specified area.
function checkInArea(x1, y1, x2, y2, z, magma, amount, minimum)
for cx = x1, x2, 1 do
for cy = y1, y2, 1 do
if passableDown(cx, cy, z) then
if checkFluid(cx, cy, z-1, magma, amount, minimum) then
return true
end
end
end
end
return false
end

-- spawn fluid, returns true if the fluid could be spawned
function spawnFluid(x, y, z, magma, amount)
local block = dfhack.maps.ensureTileBlock(x,y,z)

local ttype = block.tiletypes[x%16][y%16]
local tshape = df.tiletype.attrs[ttype].shape
if not df.tiletype_shape.attrs[tshape].passable_flow then
return false
end

if amount > 7 then
dfhack.printerr("rubble_fluids: Attempt to spawn more than 7 fluid in tile.")
return false
end

local flow = block.designation[x%16][y%16].flow_size
if flow == 7 or flow + amount > 7 then
return false
end

if block.designation[x%16][y%16].liquid_type ~= magma then
return false
end

block.designation[x%16][y%16].flow_size = flow + amount
dfhack.maps.enableBlockUpdates(block,true,true)
return true
end

-- Spawn below a specified area, there needs to be access via a downward passable tile
function spawnInArea(x1, y1, x2, y2, z, magma, amount)
for cx = x1, x2, 1 do
for cy = y1, y2, 1 do
if passableDown(cx, cy, z) then
if spawnFluid(cx, cy, z-1, magma, amount) then
return true
end
end
end
end
return false
end

-- Returns true if item is magma safe.
function magmaSafe(item)
-- Should work, but always returns false, not sure what's wrong.
--item:isTemperatureSafe(2)

-- Not sure if all this is required, but better safe than sorry.
local mat = dfhack.matinfo.decode(item)
if mat.material.heat.heatdam_point > 12000 and
mat.material.heat.melting_point > 12000 and
mat.material.heat.ignite_point > 12000 and
mat.material.heat.boiling_point > 12000 then
return true
end
return false
end

-- Find an empty (possibly magma safe) cart in the specified tile
function findCart(x, y, z, magmasafe)
local itemblock = dfhack.maps.ensureTileBlock(x, y, z)
if itemblock.occupancy[x%16][y%16].item == true then
for c=#itemblock.items-1,0,-1 do
cart=df.item.find(itemblock.items[c])
if cart:isTrackCart() then
if cart.pos.x == x and cart.pos.y == y and cart.pos.z == z then
if #dfhack.items.getContainedItems(cart) == 0 then
if magmasafe then
if magmaSafe(cart) then
return cart
end
else
return cart
end
end
end
end
end
end
return nil
end

-- Find a empty (possibly magma safe) cart in the specified area.
function findCartArea(x1, y1, x2, y2, z, magmasafe)
for cx = x1, x2, 1 do
for cy = y1, y2, 1 do
cart = findCart(cx, cy, z, magmasafe)
if cart ~= nil then
return cart
end
end
end
return nil
end

-- Fill a minecart with magma or water.
function fillCart(cart, magma)
capacity = math.floor(cart.subtype.container_capacity/60)

local item=df['item_liquid_miscst']:new()
item.id=df.global.item_next_id
df.global.world.items.all:insert('#',item)
df.global.item_next_id=df.global.item_next_id+1

local mat
if magma then
mat = dfhack.matinfo.find("INORGANIC:NONE")
-- This keeps the magma from becoming solid after a few seconds
-- apparently items start out at the default room temperature.
item.temperature.whole = 12000
else
mat = dfhack.matinfo.find("WATER:NONE")
end

item:setMaterial(mat.type)
item:setMaterialIndex(mat.index)
item.stack_size = capacity
item:categorize(true)
item.flags.removed=true

dfhack.items.moveToContainer(item, cart)
end

-- This should add skill exp to a unit
-- doesn't seem to fit the theme until you consider just how often this lib gets used from Lua hooks
-- (and AFAIK Lua hooks do not award exp for completed reactions)
-- This is lifted (almost) directly from the machina script from Masterwork
function levelUp(unit, skillId, amount)
max_skill = 20

local skill = df.unit_skill:new()
local foundSkill = false
for k, soulSkill in ipairs(unit.status.current_soul.skills) do
if soulSkill.id == skillId then
skill = soulSkill
foundSkill = true
break
end
end
 
if foundSkill then
-- Let's not train beyond the max skill
if skill.rating >= max_skill then
return false
end
 
skill.experience = skill.experience + amount
if skill.experience > 100 * skill.rating + 500 then
skill.experience = skill.experience - (100 * skill.rating + 500)
skill.rating = skill.rating + 1
end
else
skill.id = skillId
skill.experience = amount
skill.rating = 0
unit.status.current_soul.skills:insert('#',skill)
end

return true
end

return _ENV
Title: Re: Need help with water/magma script
Post by: milo christiansen on July 30, 2014, 01:43:53 pm
That's the module, no need to modify it as it is just a collection of functions that are used by the workshop scripts (that script would be installed in "hack/lua" rather than "hack/scripts")

More useful for you would be the scripts in the "User/DFHack" group (for example "User/DFHack/Cart Filler/user_dfhack_cart_filler.lua").
Title: Re: Need help with water/magma script
Post by: Roses on July 30, 2014, 01:45:33 pm
Code: [Select]
function usewater(reaction,unit,job,input_items,input_reagents,output_items,call_native)
local building = dfhack.buildings.findAtTile(unit.pos)
local pos = {}
pos.x1 = building.x1
pos.x2 = building.x2
pos.y1 = building.y1
pos.y2 = building.y2
pos.z = building.z
for x = pos.x1-1, pos.x2+1, 1 do
for y = pos.y1-1, pos.y2+1, 1 do
baseBlock = dfhack.maps.ensureTileBlock(x,y,pos.z)
liquidBlock = dfhack.maps.ensureTileBlock(x,y,pos.z-1)
if liquidBlock.designation[x%16][y%16].flow_size > 0 and liquidBlock.designation[x%16][y%16].liquid_type == true then
liquidBlock.designation[x%16][y%16].flow_size = liquidBlock.designation[x%16][y%16].flow_size - 1
return
end
end
end
dfhack.gui.showAnnouncement( dfhack.TranslateName(unit.name).." cancels "..reaction.name..": Needs water." , COLOR_RED, true)
for i=0,#input_items-1,1 do
input_items[i].flags.PRESERVE_REAGENT = true
end
for i=0,#reaction.products-1,1 do
reaction.products[i].probability = 0
end
end

That *should* work for the water check, it checks all tiles underneath the workshop and the tiles adjacent to the workshop (could make it just check adjacent, but as long as your workshop is small, like a 3x3 or smaller it won't matter). I'm not at a computer that can play DF at the moment so you will have to test it for me
Title: Re: Need help with water/magma script
Post by: Meph on July 30, 2014, 02:05:48 pm
Ok, the script I am using atm is this, the one you just posted, Roses.
Code: [Select]
--Lets you make reactions that require water or magma under the workshop.  Reactions must start with LUA_HOOK_USEWATER or LUA_HOOK_USEMAGMA.
local eventful = require 'plugins.eventful'
local utils = require 'utils'


function usewater(reaction,unit,job,input_items,input_reagents,output_items,call_native)
local building = dfhack.buildings.findAtTile(unit.pos)
local pos = {}
pos.x1 = building.x1
pos.x2 = building.x2
pos.y1 = building.y1
pos.y2 = building.y2
pos.z = building.z
for x = pos.x1-1, pos.x2+1, 1 do
for y = pos.y1-1, pos.y2+1, 1 do
baseBlock = dfhack.maps.ensureTileBlock(x,y,pos.z)
liquidBlock = dfhack.maps.ensureTileBlock(x,y,pos.z-1)
if liquidBlock.designation[x%16][y%16].flow_size > 0 and liquidBlock.designation[x%16][y%16].liquid_type == true then
liquidBlock.designation[x%16][y%16].flow_size = liquidBlock.designation[x%16][y%16].flow_size - 1
return
end
end
end
dfhack.gui.showAnnouncement( dfhack.TranslateName(unit.name).." cancels "..reaction.name..": Needs water." , COLOR_RED, true)
for i=0,#input_items-1,1 do
input_items[i].flags.PRESERVE_REAGENT = true
end
for i=0,#reaction.products-1,1 do
reaction.products[i].probability = 0
end
end


function usemagma(reaction,unit,job,input_items,input_reagents,output_items,call_native)
local building = dfhack.buildings.findAtTile(unit.pos)
local pos = {}
pos.x = building.centerx
pos.y = building.centery
pos.z = building.z
baseBlock = dfhack.maps.ensureTileBlock(pos.x,pos.y,pos.z)
liquidBlock = dfhack.maps.ensureTileBlock(pos.x,pos.y,pos.z-1)
if liquidBlock.designation[pos.x%16][pos.y%16].flow_size > 0 and liquidBlock.designation[pos.x%16][pos.y%16].liquid_type == false then
liquidBlock.designation[pos.x%16][pos.y%16].flow_size = liquidBlock.designation[pos.x%16][pos.y%16].flow_size - 1
else
dfhack.gui.showAnnouncement( dfhack.TranslateName(unit.name).." cancels "..reaction.name..": Needs magma." , COLOR_RED, true)
for i=0,#input_items-1,1 do
input_items[i].flags.PRESERVE_REAGENT = true
end
for i=0,#reaction.products-1,1 do
reaction.products[i].probability = 0
end
end
end

dfhack.onStateChange.loadUseLiquid = function(code)
local registered_reactions
if code==SC_MAP_LOADED then
--registered_reactions = {}
for i,reaction in ipairs(df.global.world.raws.reactions) do
if string.starts(reaction.code,'LUA_HOOK_USEWATER') then
eventful.registerReaction(reaction.code,usewater)
registered_reactions = true
elseif string.starts(reaction.code,'LUA_HOOK_USEMAGMA') then
eventful.registerReaction(reaction.code,usemagma)
registered_reactions = true
end
end
if registered_reactions then
print('Use Liquid Reactions: Loaded.')
end
elseif code==SC_MAP_UNLOADED then
end
end

if dfhack.isMapLoaded() then dfhack.onStateChange.loadUseLiquid(SC_MAP_LOADED) end

And this is the water test:
(http://i.imgur.com/59wzKm9.png)

It has everything.. water next to it, downstairs into the water, flooded up/downstairs, channels... but it always says: Water needed, and cancels the reaction. (I also tried one on a brook, and one with water directly underneath, with floor in between.) Ahhh, DF can be so silly sometimes. All I want is for the dwarves to store water before it freezes in winter.
Title: Re: Need help with water/magma script
Post by: milo christiansen on July 30, 2014, 02:08:57 pm
Isn't liquid_type "true" for magma (not water)?
Title: Re: Need help with water/magma script
Post by: Roses on July 30, 2014, 02:10:43 pm
Yes I believe milo is right, I didn't notice that when I was looking over it, but I think IndigoFenix got them backwards. Change true to false and false to true and it should work.
Title: Re: Need help with water/magma script
Post by: Meph on July 30, 2014, 02:24:30 pm
Thank you two so much. It works!

Humans are still pretty dumb. But I got it to work as intended. I can add liquid_misc to buckets, which is used to bring water to prisoners and injured humans, while I can make drink:none:water:none and add it to a barrel, which will be used by normal humans, they drink it straight from the barrel. NICE!

Now people can barrel and stockpile water. :)

PS: Thirsty people will ignore water in buckets. lol. Barrels are fine though, and buckets are fine for the hospital.
Title: Re: Need help with water/magma script
Post by: Roses on July 30, 2014, 02:33:05 pm
Who drinks water out of a bucket? I am a barrel man all the way. Nothing like picking up an entire barrel full of water to start the day out. And you can't do a barrel stand off a bucket!
Title: Re: Need help with water/magma script
Post by: Meph on July 30, 2014, 02:57:01 pm
Its actually pretty useful, because I can finally use water as reagents in custom reactions... like alchemy or tea or water magic reactions. Previously that wasnt possible, because dwarves are too stupid to realize that they potentially could fill a bucket with water. But now I can do it manually. :)

This is one of those things that fits every mod well.
Title: Re: Need help with water/magma script
Post by: Roses on July 30, 2014, 03:12:45 pm
Indeed, I will have to add it into mine as well. I always found it odd that you couldn't fill up a barrel with water.
Title: Re: Need help with water/magma script
Post by: Meph on July 30, 2014, 03:23:11 pm
Here the reactions:

Code: [Select]

[REACTION:LUA_HOOK_USEWATER_WATERWELL]
[NAME:Fill a bucket with water]
[BUILDING:STILL:CUSTOM_ALT_W]
[REAGENT:A:1:BUCKET:NONE:NONE:NONE][PRESERVE_REAGENT] [EMPTY]
[PRODUCT:100:7:LIQUID_MISC:NONE:WATER:NONE][PRODUCT_TO_CONTAINER:A]
[PRODUCT_DIMENSION:150]
[SKILL:BREWING]

[REACTION:LUA_HOOK_USEWATER_WATERWELL2]
[NAME:Fill a barrel with water]
[BUILDING:STILL:CUSTOM_ALT_B]
[REAGENT:A:1:BARREL:NONE:NONE:NONE][PRESERVE_REAGENT] [EMPTY]
[PRODUCT:100:10:DRINK:NONE:WATER:NONE][PRODUCT_TO_CONTAINER:A]
[PRODUCT_DIMENSION:150]
[SKILL:BREWING]

Note that a bucket cant have more than 7 units of liquids. It must be LIQUID_MISC to be used. For the barrel it has to be DRINK, otherwise they wont drink from it. Btw, any liquid can be made a drink that way, even magma. DRINK:NONE:INORGANIC:NONE will make a magma barrel. Even a wooden one is fine, and people drinking from it are unharmed. This would mean you can make a magma-brewery for very hot drinks. :D

I chose 10 for the barrel. I think its fair. 15 can be done as well, anything larger will spill.

Edit: Here the working script, in case other people want to use it.
Spoiler (click to show/hide)
Title: Re: Script to fill bucket/barrel with water/magma near a workshop
Post by: Roses on July 30, 2014, 03:47:32 pm
You may want to change the usemagma function to match the usewater function (you can copy and paste everything from the usewater function, just make sure to change the false to a true), otherwise it will only check under the very center of the workshop.
Title: Re: Script to fill bucket/barrel with water/magma near a workshop
Post by: Meph on July 30, 2014, 04:01:55 pm
Done. Thanks for the reminder.
Title: Re: Script to fill bucket/barrel with water/magma near a workshop
Post by: stuntcock42 on August 21, 2014, 03:38:46 am
Hi Meph.  I used your script in a small mod but made a few tweaks that might be useful for general-purpose stuff.
Code: [Select]
function usewater(reaction,unit,input_items,input_reagents,output_items,call_native)
local building = dfhack.buildings.findAtTile(unit.pos)
local pos = {}
pos.x1 = building.x1
pos.x2 = building.x2
pos.y1 = building.y1
pos.y2 = building.y2
pos.z = building.z
for x = pos.x1-1, pos.x2+1, 1 do
for y = pos.y1-1, pos.y2+1, 1 do
baseBlock = dfhack.maps.ensureTileBlock(x,y,pos.z)
liquidBlock = dfhack.maps.ensureTileBlock(x,y,pos.z-1)
if liquidBlock.designation[x%16][y%16].flow_size > 0 and liquidBlock.designation[x%16][y%16].liquid_type == false then
liquidBlock.designation[x%16][y%16].flow_size = liquidBlock.designation[x%16][y%16].flow_size - 1
call_native.value=true    -- Allow the job to succeed.  Consume any applicable Reagents, create the appropriate Products, and train the related Skill.
return
end
end
end
dfhack.gui.showZoomAnnouncement(df.announcement_type.CANCEL_JOB, unit.pos, dfhack.TranslateName(unit.name).." cancels "..reaction.name..": Needs water." , COLOR_RED, true)
call_native.value=false    -- Force the job to fail.  Create no Products; do not provide any experience points in the associated Skill.  Note: the failed job WILL consume the normal set of Reagents.
dfhack.job.setJobCooldown(building, unit, 5)    -- Prevent the worker from immediately re-attempting the failed Job.
return
end
Title: Re: Script to fill bucket/barrel with water/magma near a workshop
Post by: Meph on August 21, 2014, 03:42:57 am
Thats a good set of improvements :)

How did you make vanilla brewing require water? Also dfhack that hooks into the 'brew drink' reaction?
Title: Re: Script to fill bucket/barrel with water/magma near a workshop
Post by: palu on August 21, 2014, 04:39:07 pm
In 40.0x, brewing is a custom reaction.
Title: Re: Script to fill bucket/barrel with water/magma near a workshop
Post by: Meph on August 25, 2014, 05:08:39 am
In 40.0x, brewing is a custom reaction.
:o

I need to have a better look at the new version it seems. :)
Title: Re: Script to fill bucket/barrel with water/magma near a workshop
Post by: Nate McCloud on March 01, 2018, 04:24:02 am
Really sorry for necroposting, but I want to use this script so I can have a working obsidian forge building for crafting obsidian without risking burning my dwarves. The only problem is, I don't see any way to require that the workshop have both water AND magma underneath it. How would I do that with this script?