Add Item water flow (by TenPlus1), fix Statbars and backport Falling node sound from MT5.0

master
MoNTE48 2019-07-09 12:48:03 +02:00
parent 0e7f6299a9
commit 6ce5a4e4b2
5 changed files with 140 additions and 85 deletions

View File

@ -40,7 +40,7 @@ core.register_entity(":__builtin:falling_node", {
on_activate = function(self, staticdata)
self.object:set_armor_groups({immortal = 1})
local ds = core.deserialize(staticdata)
if ds and ds.node then
self:set_node(ds.node, ds.meta)
@ -54,8 +54,9 @@ core.register_entity(":__builtin:falling_node", {
on_step = function(self, dtime)
-- Set gravity
local acceleration = self.object:get_acceleration()
if not vector.equals(acceleration, {x = 0, y = -9.81, z = 0}) then
self.object:setacceleration({x = 0, y = -9.81, z = 0})
local gravity = tonumber(core.settings:get("movement_gravity")) or 9.81
if not vector.equals(acceleration, {x = 0, y = -gravity, z = 0}) then
self.object:setacceleration({x = 0, y = -gravity, z = 0})
end
-- Turn to actual node when colliding with ground, or continue to move
local pos = self.object:get_pos()
@ -110,12 +111,16 @@ core.register_entity(":__builtin:falling_node", {
end
end
-- Create node and remove entity
if core.registered_nodes[self.node.name] then
local def = core.registered_nodes[self.node.name]
if def then
core.add_node(np, self.node)
if self.meta then
local meta = core.get_meta(np)
meta:from_table(self.meta)
end
if def.sounds and def.sounds.place and def.sounds.place.name then
core.sound_play(def.sounds.place, {pos = np})
end
end
self.object:remove()
core.check_for_falling(np)
@ -327,19 +332,3 @@ local function on_punchnode(p, node)
core.check_for_falling(p)
end
core.register_on_punchnode(on_punchnode)
--
-- Globally exported functions
--
-- TODO remove this function after the 0.4.15 release
function nodeupdate(p)
core.log("deprecated", "nodeupdate: deprecated, please use core.check_for_falling instead")
core.check_for_falling(p)
end
-- TODO remove this function after the 0.4.15 release
function nodeupdate_single(p)
core.log("deprecated", "nodeupdate_single: deprecated, please use core.check_single_for_falling instead")
core.check_single_for_falling(p)
end

View File

@ -506,6 +506,7 @@ function core.item_throw(name, thrower, speed, accel, on_impact)
local s = speed or 19 -- default speed
local a = accel or -3 -- default acceleration
local dir = thrower:get_look_dir()
local gravity = tonumber(core.settings:get("movement_gravity")) or 9.81
ent.thrower = thrower:get_player_name()
ent.throw_timer = 0
ent.throw_direction = dir
@ -513,7 +514,7 @@ function core.item_throw(name, thrower, speed, accel, on_impact)
ent.on_impact = on_impact and on_impact or function() end
obj:set_properties(properties)
obj:set_velocity({x=dir.x * s, y=dir.y * s, z=dir.z * s})
obj:set_acceleration({x=dir.x * a, y=-9.81, z=dir.z * a})
obj:set_acceleration({x=dir.x * a, y=-gravity, z=dir.z * a})
return obj
else
obj:remove()

View File

@ -14,9 +14,66 @@ end
-- If item_entity_ttl is not set, enity will have default life time
-- Setting it to -1 disables the feature
local time_to_live = tonumber(core.settings:get("item_entity_ttl")) or 900
local time_to_live = tonumber(core.settings:get("item_entity_ttl")) or 600
local gravity = tonumber(core.settings:get("movement_gravity")) or 9.81
-- Water flow functions by QwertyMine3 (WTFPL), and TenPlus1 (MIT)
local function to_unit_vector(dir_vector)
local inv_roots = {
[0] = 1,
[1] = 1,
[2] = 0.70710678118655,
[4] = 0.5,
[5] = 0.44721359549996,
[8] = 0.35355339059327
}
local sum = dir_vector.x * dir_vector.x + dir_vector.z * dir_vector.z
return {
x = dir_vector.x * inv_roots[sum],
y = dir_vector.y,
z = dir_vector.z * inv_roots[sum]
}
end
local function quick_flow_logic(node, pos_testing, direction)
local node_testing = core.get_node_or_nil(pos_testing)
if node_testing == nil then
node_testing = core.registered_nodes["default:dirt"]
end
if core.registered_nodes[node_testing.name].liquidtype ~= "flowing"
and core.registered_nodes[node_testing.name].liquidtype ~= "source" then
return 0
end
local param2_testing = node_testing.param2
if param2_testing < node.param2 then
if (node.param2 - param2_testing) > 6 then
return -direction
else
return direction
end
elseif param2_testing > node.param2 then
if (param2_testing - node.param2) > 6 then
return direction
else
return -direction
end
end
return 0
end
local function quick_flow(pos, node)
if not core.registered_nodes[node.name].groups.liquid then
return {x = 0, y = 0, z = 0}
end
local x, z = 0, 0
x = x + quick_flow_logic(node, {x = pos.x - 1, y = pos.y, z = pos.z},-1)
x = x + quick_flow_logic(node, {x = pos.x + 1, y = pos.y, z = pos.z}, 1)
z = z + quick_flow_logic(node, {x = pos.x, y = pos.y, z = pos.z - 1},-1)
z = z + quick_flow_logic(node, {x = pos.x, y = pos.y, z = pos.z + 1}, 1)
return to_unit_vector({x = x, y = 0, z = z})
end
core.register_entity(":__builtin:throwing_item", {
physical = false,
visual = "wielditem",
@ -156,11 +213,18 @@ core.register_entity(":__builtin:item", {
end
local pos = self.object:get_pos()
local node = core.get_node_or_nil({
self.node_inside = core.get_node_or_nil(pos)
self.def_inside = self.node_inside
and core.registered_nodes[self.node_inside.name]
self.node_under = core.get_node_or_nil({
x = pos.x,
y = pos.y + self.object:get_properties().collisionbox[2] - 0.05,
z = pos.z
})
self.def_under = self.node_under
and core.registered_nodes[self.node_under.name]
local node = self.node_inside
-- Delete in 'ignore' nodes
if node and node.name == "ignore" then
self.itemstring = ""
@ -169,11 +233,42 @@ core.register_entity(":__builtin:item", {
end
local vel = self.object:get_velocity()
local def = node and core.registered_nodes[node.name]
local def = self.def_inside
local is_moving = (def and not def.walkable) or
vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0
local is_slippery = false
-- Destroy item when dropped into lava
if def and def.groups and def.groups.lava then
core.sound_play("default_cool_lava", {pos = pos, max_hear_distance = 10})
self.object:remove()
core.add_particlespawner({
amount = 3,
time = 0.1,
minpos = {x = pos.x - 0.1, y = pos.y + 0.1, z = pos.z - 0.1 },
maxpos = {x = pos.x + 0.1, y = pos.y + 0.2, z = pos.z + 0.1 },
minvel = {x = 0, y = 2.5, z = 0},
maxvel = {x = 0, y = 2.5, z = 0},
minacc = {x = -0.15, y = -0.02, z = -0.15},
maxacc = {x = 0.15, y = -0.01, z = 0.15},
minexptime = 4,
maxexptime = 6,
minsize = 2,
maxsize = 4,
texture = "item_smoke.png"
})
return
end
-- Moving items in the water flow
if def and def.liquidtype == "flowing" then
local vec = quick_flow(pos, node)
self.object:set_velocity({x = vec.x, y = vel.y, z = vec.z})
return
end
node = self.node_under
def = self.def_under
if def and def.walkable then
local slippery = core.get_item_group(node.name, "slippery")
is_slippery = slippery ~= 0
@ -206,10 +301,11 @@ core.register_entity(":__builtin:item", {
self.object:set_velocity({x = 0, y = 0, z = 0})
end
--Only collect items if not moving
-- Only collect items if not moving
if is_moving then
return
end
-- Collect the items around to merge with
local own_stack = ItemStack(self.itemstring)
if own_stack:get_free_space() == 0 then
@ -227,32 +323,6 @@ core.register_entity(":__builtin:item", {
end
end
end
local node = core.get_node_or_nil(self.object:get_pos())
if not node then
return
end
if core.get_item_group(node.name, "lava") > 0 then
core.sound_play("default_cool_lava", {pos = pos, max_hear_distance = 10})
self.object:remove()
core.add_particlespawner({
amount = 3,
time = 0.1,
minpos = {x = pos.x - 0.1, y = pos.y + 0.1, z = pos.z - 0.1 },
maxpos = {x = pos.x + 0.1, y = pos.y + 0.2, z = pos.z + 0.1 },
minvel = {x = 0, y = 2.5, z = 0},
maxvel = {x = 0, y = 2.5, z = 0},
minacc = {x = -0.15, y = -0.02, z = -0.15},
maxacc = {x = 0.15, y = -0.01, z = 0.15},
minexptime = 4,
maxexptime = 6,
minsize = 2,
maxsize = 4,
texture = "item_smoke.png"
})
return
end
end,
on_punch = function(self, hitter)

View File

@ -1,30 +1,25 @@
-- cache setting
local enable_damage = core.settings:get_bool("enable_damage")
local health_bar_definition = {}
local health_bar_definition = {
hud_elem_type = "statbar",
position = {x = 0.5, y = 1},
alignment = {x = -1, y = -1},
offset = {x = -247, y = -108},
size = {x = 24, y = 24},
text = "heart.png",
background = "heart_bg.png",
number = 20
}
if enable_damage then
hud.register("health", {
hud_elem_type = "statbar",
position = {x = 0.5, y = 1},
alignment = {x = -1, y = -1},
offset = {x = -247, y = -108},
size = {x = 24, y = 24},
text = "heart.png",
background = "heart_bg.png",
number = 20,
})
end
local breath_bar_definition =
{
local breath_bar_definition = {
hud_elem_type = "statbar",
position = {x = 0.5, y = 1},
alignment = {x = -1, y = -1},
offset = {x = 8, y = -134},
size = {x = 24, y = 24},
text = "bubble.png",
number = 20,
number = 20
}
local hud_ids = {}
@ -50,8 +45,10 @@ local function initialize_builtin_statbars(player)
if player:hud_get_flags().healthbar and enable_damage then
if hud_ids[name].id_healthbar == nil then
health_bar_definition.number = player:get_hp()
hud_ids[name].id_healthbar = player:hud_add(health_bar_definition)
hud_ids[name].id_healthbar = hud.register("health", health_bar_definition)
minetest.after(0, function()
hud.change_item(player, "health", {number = player:get_hp()})
end)
end
else
if hud_ids[name].id_healthbar ~= nil then
@ -127,7 +124,7 @@ local function player_event_handler(player, eventname)
return false
end
function core.hud_replace_builtin(name, definition)
--[[function core.hud_replace_builtin(name, definition)
if definition == nil or
type(definition) ~= "table" or
@ -162,13 +159,15 @@ function core.hud_replace_builtin(name, definition)
end
return false
end]]
if enable_damage then
core.register_on_joinplayer(initialize_builtin_statbars)
core.register_on_leaveplayer(cleanup_builtin_statbars)
core.register_playerevent(player_event_handler)
end
core.register_on_leaveplayer(cleanup_builtin_statbars)
core.register_playerevent(player_event_handler)
-- Hud Item name
local timer, wield = {}, {}
local timeout = 2
@ -181,10 +180,6 @@ hud.register("itemname", {
text = ""
})
core.register_on_joinplayer(function(player)
initialize_builtin_statbars(player)
end)
minetest.register_playerstep(function(dtime, playernames)
for _, name in pairs(playernames) do
local player = minetest.get_player_by_name(name)
@ -195,7 +190,7 @@ minetest.register_playerstep(function(dtime, playernames)
timer[player] = timer[player] and timer[player] + dtime or 0
wield[player] = wield[player] or ""
if timer[player] > timeout and player then
if timer[player] > timeout then
hud.change_item(player, "itemname", {text = ""})
timer[player] = 0
return

View File

@ -45,13 +45,13 @@ minetest.register_node("tnt:tnt", {
action_on = (function(p, node)
minetest.remove_node(p)
spawn_tnt(p, "tnt:tnt")
nodeupdate(p)
minetest.check_for_falling(p)
end),
}},
on_ignite = function(pos, igniter)
minetest.remove_node(pos)
spawn_tnt(pos, "tnt:tnt")
nodeupdate(pos)
minetest.check_for_falling(pos)
end,
})
@ -59,7 +59,7 @@ minetest.register_on_punchnode(function(p, node)
if node.name == "tnt:tnt" then
minetest.remove_node(p)
spawn_tnt(p, "tnt:tnt")
nodeupdate(p)
minetest.check_for_falling(p)
end
end)
@ -72,7 +72,7 @@ minetest.register_abm({
action = function(pos, node)
minetest.remove_node(pos)
spawn_tnt(pos, "tnt:tnt")
nodeupdate(pos)
minetest.check_for_falling(pos)
end,
})
@ -146,7 +146,7 @@ function TNT:on_step(dtime)
n.name ~= "default:bedrock" and n.name ~= "protector:protect" then
activate_if_tnt(n.name, np, pos, 3)
minetest.remove_node(np)
nodeupdate(np)
minetest.check_for_falling(np)
if n.name ~= "tnt:tnt" and math.random() > 0.9 then
local drop = minetest.get_node_drops(n.name, "")
for _,item in ipairs(drop) do