Add collisionbox parameter (currently unused due to performance hit/behavior change), optimize vl_physics.get_environment_effect(), fix type (mcl_physics -> vl_physics)

This commit is contained in:
teknomunk 2025-02-22 05:50:14 -06:00
parent ce65c8ee75
commit 7b79c35f0c
4 changed files with 50 additions and 33 deletions
mods
ENTITIES/mcl_mobs
ENVIRONMENT/vl_physics
PLAYER/mcl_playerplus

View file

@ -319,7 +319,7 @@ local function on_step_work(self, dtime, moveresult)
self:check_suspend(player_in_active_range)
-- Handle environmental physics
mcl_physics.apply_entity_environmental_physics(self)
vl_physics.apply_entity_environmental_physics(self)
self._can_jump_cliff = not self._jumping_cliff and self:can_jump_cliff()
self:flop()

View file

@ -7,13 +7,21 @@ function mod.register_environment_effect(effect)
list[#list + 1] = effect
end
function mod.get_environment_effect(pos, vel, staticdata, mass, entity)
-- Get the physics effects that affect an entity
---@param pos vector.Vector Current position of the entity
---@param collision_box table The collision box of the entity used to determine if the entity
-- overlaps nodes
---@param vel Number The entity's previous velocity
---@param staticdata table
---@param mass Number
---@param entity core.LuaEntity
function mod.get_environment_effect(pos, collision_box, vel, staticdata, mass, entity)
local v = vector.zero()
local a = vector.zero()
-- Accumulate all enviornmental effects
for _,effect in ipairs(registered_environment_effects) do
local dv,da = effect(pos, vel, staticdata, entity)
local dv,da = effect(pos, collisionbox, vel, staticdata, entity)
if dv then
v = v + dv
end
@ -40,7 +48,7 @@ function mod.apply_entity_environmental_physics(self, data)
local pos = self.object:get_pos()
local vel = self.object:get_velocity()
local new_velocity,new_acceleration = vl_physics.get_environment_effect(pos, vel, data, mass, self)
local new_velocity,new_acceleration = vl_physics.get_environment_effect(pos, nil, vel, data, mass, self)
--if new_velocity then print("new_velocity="..tostring(new_velocity)) end
--if new_acceleration then print("new_acceleration="..tostring(new_acceleration)) end

View file

@ -5,11 +5,14 @@ vl_physics = mod
dofile(modpath.."/api.lua")
-- Locallized functions
local math_round = math.round
-- Flowing water
-- TODO: move to Flowlib
local FLOW_SPEED = 1.39
local BOUANCY = 3
mod.register_environment_effect(function(pos, vel, staticdata, entity)
mod.register_environment_effect(function(pos, collisionbox, vel, staticdata, entity)
-- Get the node and node definition
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
@ -25,7 +28,7 @@ mod.register_environment_effect(function(pos, vel, staticdata, entity)
end)
-- Simple gravity and bouancy
mod.register_environment_effect(function(pos, vel, staticdata, entity)
mod.register_environment_effect(function(pos, collisionbox, vel, staticdata, entity)
-- Get the node and node definition
local node = minetest.get_node_or_nil(pos);
local nodedef = nil
@ -52,49 +55,52 @@ end)
local DEFAULT_NODE_PHYSICS = {
friction = 0.9
}
local function apply_node_physics(node, vel, staticdata, entity)
local function apply_node_physics(pos, v, a, vel, staticdata, entity)
local node = core.get_node(pos)
local node_def = minetest.registered_nodes[node.name] or {}
local node_physics = node_def._vl_physics or DEFAULT_NODE_PHYSICS
-- Custom node physics
local node_physics_effect = node_physics.effect
if node_physics_effect then
return node_physics_effect(pos, vel, staticdata)
end
-- Default behavior
local accel = vector.zero()
-- Default node physics
-- Friction
if node.name ~= "air" then
if node.name ~= "air" and vector.length(vel) > 0.01 then
local friction_scale = node_physics.friction
accel = accel + vel * -friction_scale
a.x = a.x + vel.x * -friction_scale
a.y = a.y + vel.y * -friction_scale
a.z = a.z + vel.z * -friction_scale
end
return vector.zero(), accel
end
mod.register_environment_effect(function(pos, vel, staticdata, entity)
local a = vector.zero()
local v = vector.zero()
-- Apply node physics for the node we are inside of
local pos1_r = vector.round(pos)
local node1 = minetest.get_node(pos1_r)
local v1,a1 = apply_node_physics(node1, vel, staticdata, entity)
v = v + v1
a = a + a1
local DEFAULT_COLLISION_BOX = { -0.312, -0.55, -0.312, 0.312, 1.25, 0.312 }
local npos = vector.zero()
local a = vector.zero()
local v = vector.zero()
mod.register_environment_effect(function(pos, collisionbox, vel, staticdata, entity)
-- Reset acceleration and velocity
a.x,a.y,a.z = 0,0,0
v.x,v.y,v.z = 0,0,0
-- TODO: only apply when touching under_node
local pos2_r = vector.offset(pos1_r,0,-1,0)
local node2 = minetest.get_node(pos2_r)
local v2,a2 = apply_node_physics(node2, vel, staticdata, entity)
v = v + v2
a = a + a2
npos.x = math_round(pos.x)
npos.z = math_round(pos.z)
for y = math_round(pos.y)-1,math_round(pos.y) do
npos.y = y
-- Male speeds of less than 1/100 block/second count as zero
if vector.length(v) < 0.01 then
v = nil
-- Apply node physics for the node we are inside of
apply_node_physics(npos, v, a, vel, staticdata, entity)
end
return v,a
-- Make speeds of less than 1/100 block/second count as zero
local len = v.x*v.x + v.y+v.y + v.z+v.z
if len < 0.0001 then
return nil, a
else
return v,a
end
end)

View file

@ -180,7 +180,10 @@ minetest.register_globalstep(function(dtime)
local c_x, c_y = unpack(player_collision(player))
-- Apply enviornmental physics effects
local v,a = vl_physics.get_environment_effect(player:get_pos(), player_velocity, {}, 1, player)
local collisionbox = nil -- TODO: get the player's current collision box
local v,a = vl_physics.get_environment_effect(player:get_pos(), collisionbox,
player_velocity, {}, 1, {object = player}
)
if v then player:add_velocity(v) end
if player_velocity.x + player_velocity.y < .5 and c_x + c_y > 0 then