forked from MineClone5/MineClone5
Merge pull request 'Major changes to item physics' (#181) from Gustavo6046/MineClone5:item-physics into master
Reviewed-on: MineClone5/MineClone5#181
This commit is contained in:
commit
52712f9133
|
@ -27,6 +27,11 @@ local mcl_item_entity = {}
|
|||
local item_drop_settings = {} --settings table
|
||||
item_drop_settings.dug_buffer = 0.65 -- the warm up period before a dug item can be collected
|
||||
item_drop_settings.age = 1.0 --how old a dropped item (_insta_collect==false) has to be before collecting
|
||||
item_drop_settings.fluid_flow_rate = 1.39 --the speed of a flowing fluid, used when computing push and drag forces of water on items; default is tuned to Minecraft
|
||||
item_drop_settings.fluid_drag = 1.8 --how much drag water has on items (how quickly an item's motion will settle onto the water's flow speed)
|
||||
item_drop_settings.ground_drag = 3.0 --how much friction with the ground slows items sliding on it
|
||||
item_drop_settings.slippery_drag_factor = 0.25 --scales item friction with the ground on slippery floors (e.g. ice)
|
||||
item_drop_settings.slippery_fluid_drag_factor = 0.4 --scales item drag with waterflow on slippery floors (e.g. ice)
|
||||
item_drop_settings.radius_magnet = 2.0 --radius of item magnet. MUST BE LARGER THAN radius_collect!
|
||||
item_drop_settings.xp_radius_magnet = 7.25 --radius of xp magnet. MUST BE LARGER THAN radius_collect!
|
||||
item_drop_settings.radius_collect = 0.2 --radius of collection
|
||||
|
@ -778,11 +783,35 @@ minetest.register_entity(":__builtin:item", {
|
|||
-- Just to make sure we don't manipulate the speed for no reason
|
||||
if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then
|
||||
-- Minecraft Wiki: Flowing speed is "about 1.39 meters per second"
|
||||
local f = 1.39
|
||||
-- Set new item moving speed into the direciton of the liquid
|
||||
local newv = vector.multiply(vec, f)
|
||||
local f = item_drop_settings.fluid_flow_rate --1.39
|
||||
|
||||
-- Apply the force of the flowing liquid onto the item's velocity
|
||||
local newv = vector.multiply(vec, f)
|
||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
||||
self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z})
|
||||
|
||||
local oldvel = self.object:get_velocity() -- v is vector, vel is velocity
|
||||
|
||||
-- drag
|
||||
local fluid_drag = item_drop_settings.fluid_drag
|
||||
|
||||
local floornn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
|
||||
local floornode = floornn and minetest.registered_nodes[floornn]
|
||||
if floornode and minetest.get_item_group(floornode.name, "slippery") then
|
||||
-- scale fluid drag on slippery floors
|
||||
fluid_drag = fluid_drag * item_drop_settings.slippery_fluid_drag_factor
|
||||
end
|
||||
|
||||
newv.x = newv.x - (oldvel.x - newv.x) * fluid_drag * dtime
|
||||
newv.y = newv.y - (oldvel.y - newv.y) * fluid_drag * dtime
|
||||
newv.z = newv.z - (oldvel.z - newv.z) * fluid_drag * dtime
|
||||
|
||||
newv.y = newv.y + -0.22 -- (keep slight downward thrust from previous version of code)
|
||||
-- NOTE: is there any particular reason we have this, anyway?
|
||||
-- since fluid drag is now on, we could as well just
|
||||
-- apply gravity here; drag will slow down the fall
|
||||
-- realistically
|
||||
|
||||
self.object:set_velocity({x = oldvel.x + newv.x * dtime, y = oldvel.y + newv.y * dtime, z = oldvel.z + newv.z * dtime})
|
||||
|
||||
self.physical_state = true
|
||||
self._flowing = true
|
||||
|
@ -794,15 +823,17 @@ minetest.register_entity(":__builtin:item", {
|
|||
elseif self._flowing == true then
|
||||
-- Disable flowing physics if not on/in flowing liquid
|
||||
self._flowing = false
|
||||
enable_physics(self.object, self, true)
|
||||
--enable_physics(self.object, self, true) -- do not reset velocity upon leaving water!
|
||||
self.object:set_acceleration({x=0,y=-get_gravity(),z=0}) -- resume applying gravity
|
||||
return
|
||||
end
|
||||
|
||||
-- If node is not registered or node is walkably solid and resting on nodebox
|
||||
local nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
|
||||
local v = self.object:get_velocity()
|
||||
local node = nn and minetest.registered_nodes[nn]
|
||||
|
||||
if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable and v.y == 0 then
|
||||
if not node or node.walkable and v.y == 0 then
|
||||
if self.physical_state then
|
||||
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
|
||||
-- Merge with close entities of the same item
|
||||
|
@ -815,7 +846,28 @@ minetest.register_entity(":__builtin:item", {
|
|||
end
|
||||
end
|
||||
end
|
||||
disable_physics(self.object, self)
|
||||
--disable_physics(self.object, self)
|
||||
-- apply ground drag
|
||||
local oldvel = self.object:get_velocity()
|
||||
|
||||
-- ignore momentum if it's tiny
|
||||
if math.abs(oldvel.x) < 0.05 and math.abs(oldvel.z) < 0.05 then
|
||||
disable_physics(self.object, self)
|
||||
return
|
||||
end
|
||||
|
||||
local ground_drag = item_drop_settings.ground_drag
|
||||
|
||||
if node and minetest.get_item_group(node.name, "slippery") ~= 0 then
|
||||
ground_drag = ground_drag * item_drop_settings.slippery_drag_factor
|
||||
end
|
||||
|
||||
local newvel = {
|
||||
x = oldvel.x - oldvel.x * ground_drag * dtime,
|
||||
y = 0,
|
||||
z = oldvel.z - oldvel.z * ground_drag * dtime
|
||||
}
|
||||
self.object:set_velocity(newvel)
|
||||
end
|
||||
else
|
||||
if self._magnet_active == false then
|
||||
|
|
|
@ -260,9 +260,22 @@ local dispenserdef = {
|
|||
end
|
||||
else
|
||||
-- Drop item otherwise
|
||||
minetest.add_item(droppos, dropitem)
|
||||
stack:take_item()
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
-- Drop item normally
|
||||
local dropitemobj = minetest.add_item(droppos, dropitem)
|
||||
stack:take_item()
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
|
||||
-- Set item velocity (overrides the default random drop direction)
|
||||
local shoot_force = 1.3
|
||||
|
||||
local newv = minetest.facedir_to_dir(node.param2)
|
||||
newv = {
|
||||
x = newv.x * shoot_force,
|
||||
y = newv.y * shoot_force,
|
||||
z = newv.z * shoot_force
|
||||
}
|
||||
|
||||
dropitemobj:set_velocity(newv)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -134,9 +134,21 @@ local dropperdef = {
|
|||
-- No container?
|
||||
if not dropped and not dropnodedef.groups.container then
|
||||
-- Drop item normally
|
||||
minetest.add_item(droppos, dropitem)
|
||||
local dropitemobj = minetest.add_item(droppos, dropitem)
|
||||
stack:take_item()
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
|
||||
-- Set item velocity (overrides the default random drop direction)
|
||||
local shoot_force = 1.3
|
||||
|
||||
local newv = minetest.facedir_to_dir(node.param2)
|
||||
newv = {
|
||||
x = -newv.x * shoot_force,
|
||||
y = -newv.y * shoot_force,
|
||||
z = -newv.z * shoot_force
|
||||
}
|
||||
|
||||
dropitemobj:set_velocity(newv)
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
|
Loading…
Reference in New Issue