forked from VoxeLibre/VoxeLibre
Apply entity physics to experience orbs, add node friction and make ice more slipery than other nodes, pass entity thru to effects
This commit is contained in:
parent
6254884881
commit
0d7a0a9413
|
@ -7,13 +7,13 @@ function mod.register_environment_effect(effect)
|
||||||
list[#list + 1] = effect
|
list[#list + 1] = effect
|
||||||
end
|
end
|
||||||
|
|
||||||
function mod.get_environment_effect(pos, vel, staticdata, mass)
|
function mod.get_environment_effect(pos, vel, staticdata, mass, entity)
|
||||||
local v = vector.new(0,0,0)
|
local v = vector.zero()
|
||||||
local a = vector.new(0,0,0)
|
local a = vector.zero()
|
||||||
|
|
||||||
-- Accumulate all enviornmental effects
|
-- Accumulate all enviornmental effects
|
||||||
for _,effect in ipairs(registered_environment_effects) do
|
for _,effect in ipairs(registered_environment_effects) do
|
||||||
local dv,da = effect(pos, vel, staticdata)
|
local dv,da = effect(pos, vel, staticdata, entity)
|
||||||
if dv then
|
if dv then
|
||||||
v = v + dv
|
v = v + dv
|
||||||
end
|
end
|
||||||
|
@ -29,15 +29,21 @@ function mod.get_environment_effect(pos, vel, staticdata, mass)
|
||||||
return v,a
|
return v,a
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local DEFAULT_ENTITY_PHYSICS = {
|
||||||
|
mass = 1,
|
||||||
|
}
|
||||||
function mod.apply_entity_environmental_physics(self, data)
|
function mod.apply_entity_environmental_physics(self, data)
|
||||||
data = data or {}
|
data = data or {}
|
||||||
|
|
||||||
|
local physics = self._mcl_physics or DEFAULT_ENTITY_PHYSICS
|
||||||
|
local mass = physics.mass or DEFAULT_ENTITY_PHYSICS.mass
|
||||||
|
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
local vel = self.object:get_velocity()
|
local vel = self.object:get_velocity()
|
||||||
local new_velocity,new_acceleration = mcl_physics.get_environment_effect(pos, vel, data, 1)
|
local new_velocity,new_acceleration = mcl_physics.get_environment_effect(pos, vel, data, mass, self)
|
||||||
|
|
||||||
if new_velocity then print("new_velocity="..tostring(new_velocity)) end
|
--if new_velocity then print("new_velocity="..tostring(new_velocity)) end
|
||||||
if new_acceleration then print("new_acceleration="..tostring(new_acceleration)) end
|
--if new_acceleration then print("new_acceleration="..tostring(new_acceleration)) end
|
||||||
|
|
||||||
-- Update entity states
|
-- Update entity states
|
||||||
self._flowing = data.flowing
|
self._flowing = data.flowing
|
||||||
|
|
|
@ -9,7 +9,7 @@ dofile(modpath.."/api.lua")
|
||||||
-- TODO: move to Flowlib
|
-- TODO: move to Flowlib
|
||||||
local FLOW_SPEED = 1.39
|
local FLOW_SPEED = 1.39
|
||||||
local BOUANCY = 3
|
local BOUANCY = 3
|
||||||
mod.register_environment_effect(function(pos, vel, staticdata)
|
mod.register_environment_effect(function(pos, vel, staticdata, entity)
|
||||||
-- Get the node and node definition
|
-- Get the node and node definition
|
||||||
local node = minetest.get_node_or_nil(pos); if not node then return end
|
local node = minetest.get_node_or_nil(pos); if not node then return end
|
||||||
local nodedef = minetest.registered_nodes[node.name]; if not nodedef then return end
|
local nodedef = minetest.registered_nodes[node.name]; if not nodedef then return end
|
||||||
|
@ -21,17 +21,20 @@ mod.register_environment_effect(function(pos, vel, staticdata)
|
||||||
|
|
||||||
-- Get liquid flow direction
|
-- Get liquid flow direction
|
||||||
local vec = vector.multiply(flowlib.quick_flow(pos, node), FLOW_SPEED)
|
local vec = vector.multiply(flowlib.quick_flow(pos, node), FLOW_SPEED)
|
||||||
return vector.new(vec.x, -0.22, vec.z),nil
|
return vector.new(vec.x, -0.22, vec.z),nil -- TODO: move bouancy velocity out of here
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Simple gravity and bouancy
|
-- Simple gravity and bouancy
|
||||||
mod.register_environment_effect(function(pos, vel, staticdata)
|
mod.register_environment_effect(function(pos, vel, staticdata, entity)
|
||||||
-- Get the node and node definition
|
-- Get the node and node definition
|
||||||
local node = minetest.get_node_or_nil(pos);
|
local node = minetest.get_node_or_nil(pos);
|
||||||
local nodedef = nil
|
local nodedef = nil
|
||||||
if node then nodedef = minetest.registered_nodes[node.name] end
|
if node then nodedef = minetest.registered_nodes[node.name] end
|
||||||
|
|
||||||
if nodedef and nodedef.liquidtype == "source" then
|
if nodedef and nodedef.liquidtype == "source" then -- TODO: make this apply to flowing liquids as well
|
||||||
|
-- TODO: make this not apply to fish
|
||||||
|
--print("entity="..dump(entity))
|
||||||
|
|
||||||
-- Apply decceleration and bouancy if the entity moved from flowing water to
|
-- Apply decceleration and bouancy if the entity moved from flowing water to
|
||||||
-- stationary water
|
-- stationary water
|
||||||
return nil,vector.new(
|
return nil,vector.new(
|
||||||
|
@ -46,16 +49,35 @@ mod.register_environment_effect(function(pos, vel, staticdata)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Node effects
|
-- Node effects
|
||||||
mod.register_environment_effect(function(pos, vel, staticdata)
|
local DEFAULT_NODE_PHYSICS = {
|
||||||
local pos_r = vector.round(pos)
|
friction = 0.9
|
||||||
local node = minetest.get_node(pos_r)
|
}
|
||||||
local nodedef = minetest.registered_nodes[node.name]
|
local function apply_node_physics(node, vel, staticdata, entity)
|
||||||
if not nodedef then return end
|
local node_def = minetest.registered_nodes[node.name] or {}
|
||||||
|
local node_physics = node_def._mcl_physics or DEFAULT_NODE_PHYSICS
|
||||||
|
|
||||||
if nodedef._mcl_physics_effect then
|
local node_physics_effect = node_physics.effect
|
||||||
return nodedef._mcl_physics_effect(pos, vel, staticdata)
|
if node_physics_effect then
|
||||||
|
return node_physics_effect(pos, vel, staticdata)
|
||||||
end
|
end
|
||||||
|
|
||||||
return -- nil,nil
|
-- Default behavior
|
||||||
|
local accel = vector.zero()
|
||||||
|
|
||||||
|
-- Friction
|
||||||
|
local friction_scale = node_physics.friction
|
||||||
|
accel = accel + vel * -friction_scale
|
||||||
|
|
||||||
|
return vector.zero(), accel
|
||||||
|
end
|
||||||
|
mod.register_environment_effect(function(pos, vel, staticdata, entity)
|
||||||
|
local pos1_r = vector.round(pos)
|
||||||
|
local v1,a1 = apply_node_physics(minetest.get_node(pos1_r), vel, staticdata, entity)
|
||||||
|
|
||||||
|
-- TODO: only apply when touching under_node
|
||||||
|
local pos2_r = vector.offset(pos1_r,0,-1,0)
|
||||||
|
local v2,a2 = apply_node_physics(minetest.get_node(pos2_r), vel, staticdata, entity)
|
||||||
|
|
||||||
|
return (v1 + v2), (a1 + a2)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
|
@ -107,42 +107,7 @@ local function xp_step(self, dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Slide on slippery nodes
|
-- Slide on slippery nodes
|
||||||
local vel = self.object:get_velocity()
|
mcl_physics.apply_entity_environmental_physics(self)
|
||||||
local def = node and minetest.registered_nodes[node.name]
|
|
||||||
local is_moving = (def and not def.walkable) or
|
|
||||||
vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0
|
|
||||||
local is_slippery = false
|
|
||||||
|
|
||||||
if def and def.walkable then
|
|
||||||
local slippery = minetest.get_item_group(node.name, "slippery")
|
|
||||||
is_slippery = slippery ~= 0
|
|
||||||
if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then
|
|
||||||
-- Horizontal deceleration
|
|
||||||
local slip_factor = 4.0 / (slippery + 4)
|
|
||||||
self.object:set_acceleration({
|
|
||||||
x = -vel.x * slip_factor,
|
|
||||||
y = 0,
|
|
||||||
z = -vel.z * slip_factor
|
|
||||||
})
|
|
||||||
elseif vel.y == 0 then
|
|
||||||
is_moving = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.moving_state == is_moving and self.slippery_state == is_slippery then
|
|
||||||
-- Do not update anything until the moving state changes
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
self.moving_state = is_moving
|
|
||||||
self.slippery_state = is_slippery
|
|
||||||
|
|
||||||
if is_moving then
|
|
||||||
self.object:set_acceleration(gravity)
|
|
||||||
else
|
|
||||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
|
||||||
self.object:set_velocity({x = 0, y = 0, z = 0})
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_entity("mcl_experience:orb", {
|
minetest.register_entity("mcl_experience:orb", {
|
||||||
|
|
|
@ -919,6 +919,9 @@ minetest.register_node("mcl_core:ice", {
|
||||||
_mcl_blast_resistance = 0.5,
|
_mcl_blast_resistance = 0.5,
|
||||||
_mcl_hardness = 0.5,
|
_mcl_hardness = 0.5,
|
||||||
_mcl_silk_touch_drop = true,
|
_mcl_silk_touch_drop = true,
|
||||||
|
_mcl_physics = {
|
||||||
|
friction = 0.4,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_node("mcl_core:packed_ice", {
|
minetest.register_node("mcl_core:packed_ice", {
|
||||||
|
@ -933,6 +936,9 @@ minetest.register_node("mcl_core:packed_ice", {
|
||||||
_mcl_blast_resistance = 0.5,
|
_mcl_blast_resistance = 0.5,
|
||||||
_mcl_hardness = 0.5,
|
_mcl_hardness = 0.5,
|
||||||
_mcl_silk_touch_drop = true,
|
_mcl_silk_touch_drop = true,
|
||||||
|
_mcl_physics = {
|
||||||
|
friction = 0.15,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Frosted Ice (4 nodes)
|
-- Frosted Ice (4 nodes)
|
||||||
|
|
Loading…
Reference in New Issue