269 lines
7.5 KiB
Lua
269 lines
7.5 KiB
Lua
--
|
|
-- Normal beakers
|
|
--
|
|
|
|
local box = {
|
|
{-0.099, -0.483, -0.099, 0.099, -0.291, 0.099},
|
|
{-0.053, -0.291, -0.053, 0.053, -0.206, 0.053},
|
|
{-0.071, -0.206, -0.071, 0.071, -0.186, 0.071},
|
|
}
|
|
|
|
-- Empty beaker
|
|
minetest.register_node("alchemy:beaker_empty", {
|
|
description = "Empty Beaker",
|
|
drawtype = "mesh",
|
|
groups = {vessel = 1, beaker = 1}, -- Unbreakable but picked up on punch - no particles
|
|
paramtype = "light",
|
|
sunlight_propagates = true,
|
|
inventory_image = "beaker_empty.png",
|
|
|
|
tiles = {
|
|
"beaker.png"
|
|
},
|
|
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = box,
|
|
},
|
|
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = box,
|
|
},
|
|
|
|
mesh = "beaker_empty.x",
|
|
|
|
on_punch = function(pos, node, puncher)
|
|
local pName = puncher:get_player_name()
|
|
-- Check protection
|
|
if minetest.is_protected(pos, pName) then
|
|
minetest.record_protection_violation(pos, pName)
|
|
return
|
|
end
|
|
-- Pick up node
|
|
minetest.node_dig(pos, node, puncher)
|
|
end
|
|
})
|
|
|
|
-- Full beaker(s)
|
|
local function register_beaker(name, description, texture)
|
|
|
|
local bname = "alchemy:beaker_" .. name
|
|
local desc = "Beaker of " .. description
|
|
|
|
minetest.register_node(bname, {
|
|
description = desc,
|
|
drawtype = "mesh",
|
|
groups = {vessel = 1, beaker = 1}, -- Unbreakable but picked up on punch - no particles
|
|
paramtype = "light",
|
|
stack_max = 1,
|
|
sunlight_propagates = true,
|
|
inventory_image = texture .. "^beaker_mask.png^[makealpha:0,0,0^beaker_empty.png",
|
|
|
|
tiles = {
|
|
"beaker.png",
|
|
texture
|
|
},
|
|
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = box,
|
|
},
|
|
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = box,
|
|
},
|
|
|
|
mesh = "beaker.x",
|
|
|
|
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
|
local sMeta = itemstack:get_meta()
|
|
local meta = minetest.get_meta(pos)
|
|
local concentration = sMeta:get_int("concentration")
|
|
if concentration == 0 then
|
|
concentration = 1
|
|
end
|
|
meta:set_int("concentration", concentration)
|
|
meta:set_string("infotext", desc .. "\nConcentration: " .. concentration)
|
|
end,
|
|
|
|
|
|
on_punch = function(pos, node, puncher)
|
|
local pName = puncher:get_player_name()
|
|
-- Check protection
|
|
if minetest.is_protected(pos, pName) then
|
|
minetest.record_protection_violation(pos, pName)
|
|
return
|
|
end
|
|
-- Dig node
|
|
local playerInv = puncher:get_inventory()
|
|
local oldmeta = minetest.get_meta(pos)
|
|
local stack = ItemStack(node.name)
|
|
local stackMeta = stack:get_meta()
|
|
local concentration = oldmeta:get_int("concentration")
|
|
if concentration == 0 then
|
|
concentration = 1
|
|
end
|
|
stackMeta:set_int("concentration", concentration)
|
|
alchemy.helpers.set_beaker_descripton(stack)
|
|
minetest.remove_node(pos)
|
|
if playerInv:room_for_item("main", stack) then
|
|
playerInv:add_item("main", stack)
|
|
else
|
|
minetest.add_entity(pos, "__builtin:item", stack:to_string())
|
|
end
|
|
end,
|
|
|
|
on_drop = function(itemstack, dropper, pos)
|
|
-- Get effect function
|
|
local effect = alchemy.effects[name]
|
|
-- Get concentration level
|
|
local cLevel = itemstack:get_meta():get_int("concentration")
|
|
if cLevel == 0 then cLevel = 1 end
|
|
-- Run effect
|
|
if effect then
|
|
effect(dropper, pos, cLevel)
|
|
end
|
|
itemstack:take_item()
|
|
return itemstack
|
|
end
|
|
})
|
|
end
|
|
|
|
--
|
|
-- Splash beakers
|
|
--
|
|
|
|
local splash_radius = 2
|
|
local splash_box = {
|
|
{-0.1, -0.5, -0.1, 0.1, -0.1, 0.1}
|
|
}
|
|
|
|
minetest.register_entity("alchemy:splash_entity", {
|
|
initial_properties = {
|
|
visual = "mesh",
|
|
mesh = "beaker_splash.x",
|
|
weight = 5,
|
|
physical = true,
|
|
collide_with_objects = false,
|
|
selectionbox = {
|
|
type = "fixed",
|
|
fixed = {0, 0, 0, 0, 0, 0}
|
|
},
|
|
collisionbox = {
|
|
type = "fixed",
|
|
fixed = splash_box
|
|
}
|
|
},
|
|
on_activate = function(e, sdata)
|
|
-- Check if sdata exists
|
|
if sdata == nil then
|
|
e.object:remove()
|
|
return
|
|
end
|
|
sdata = minetest.deserialize(sdata)
|
|
if sdata == nil then
|
|
e.object:remove()
|
|
return
|
|
end
|
|
-- Set texture
|
|
e.object:set_properties({textures = {"beaker.png", sdata.tex}})
|
|
-- Set params
|
|
e.cLevel = sdata.cLevel
|
|
e.name = sdata.name
|
|
e.texpart = sdata.texpart
|
|
e.orig_vel = sdata.orig_vel
|
|
end,
|
|
on_step = function(e)
|
|
-- Check if upward velocity is 0 or velocity changed directions
|
|
local v = e.object:get_velocity()
|
|
if v.y == 0 or math.abs(v.x - e.orig_vel.x) > 0.1 or math.abs(v.z - e.orig_vel.z) > 0.1 then
|
|
local pos = e.object:get_pos()
|
|
-- Get effect function
|
|
local effect = alchemy.effects[e.name]
|
|
-- Run effect for nearby players
|
|
for _, p in pairs(minetest.get_objects_inside_radius(pos, splash_radius)) do
|
|
if p:is_player() then
|
|
effect(p, pos, e.cLevel)
|
|
end
|
|
end
|
|
-- Add particles
|
|
minetest.add_particlespawner({
|
|
amount = 30,
|
|
time = 0.5,
|
|
minpos = pos,
|
|
maxpos = pos,
|
|
minvel = {x = -1, y = 0, z = -1},
|
|
maxvel = {x = 1, y = 3, z = 1},
|
|
minacc = {x = 0, y = 0, z = 0},
|
|
maxacc = {x = 0, y = 0, z = 0},
|
|
minexptime = 1,
|
|
maxexptime = 2,
|
|
minsize = 0.5,
|
|
maxsize = 1,
|
|
texture = e.texpart
|
|
})
|
|
-- Remove entity
|
|
e.object:remove()
|
|
return
|
|
end
|
|
-- Move down
|
|
end
|
|
})
|
|
|
|
local function register_splash_beaker(name, description, texture)
|
|
|
|
local bname = "alchemy:splash_beaker_" .. name
|
|
local desc = "Splash Beaker of " .. description
|
|
local tex = texture .. "^splash_beaker_mask.png^[makealpha:0,0,0^splash_beaker_empty.png"
|
|
|
|
minetest.register_node(bname, {
|
|
description = desc,
|
|
drawtype = "mesh",
|
|
mesh = "beaker_splash.x",
|
|
tiles = {"beaker.png", texture},
|
|
inventory_image = tex,
|
|
on_drop = function(itemstack, dropper, pos)
|
|
-- Get concentration level
|
|
local cLevel = itemstack:get_meta():get_int("concentration")
|
|
if cLevel == 0 then cLevel = 1 end
|
|
-- Get random section of texture
|
|
local texpart = ("[combine:3x3:%d,%d=" .. texture):format(math.random(-29, 0), math.random(-29, 0))
|
|
-- Spawn entity
|
|
local pos = dropper:get_pos()
|
|
local vel = vector.multiply(dropper:get_look_dir(), 20)
|
|
pos.y = pos.y + dropper:get_properties().eye_height
|
|
local e = minetest.add_entity(pos, "alchemy:splash_entity", minetest.serialize({
|
|
tex = texture,
|
|
texpart = texpart,
|
|
cLevel = cLevel,
|
|
name = name,
|
|
orig_vel = vel
|
|
}))
|
|
e:set_rotation({
|
|
x = math.random() * 2 - 1,
|
|
y = math.random() * 2 - 1,
|
|
z = math.random() * 2 - 1,
|
|
})
|
|
e:set_velocity(vel)
|
|
e:set_acceleration({x = 0, y = -20, z = 0})
|
|
-- Remove item
|
|
itemstack:take_item()
|
|
return itemstack
|
|
end
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = bname,
|
|
type = "shapeless",
|
|
recipe = {
|
|
"default:diamond", "alchemy:beaker_" .. name
|
|
}
|
|
})
|
|
|
|
end
|
|
|
|
alchemy.register_beaker = register_beaker
|
|
alchemy.register_splash_beaker = register_splash_beaker
|