diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index c56102254..f323fa9f9 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -657,62 +657,6 @@ local function push_out_item_stuck_in_solid(self, dtime, p, def, is_in_water) end end -local function move_items_in_water (self, p, def, node, is_floating, is_in_water) - -- Move item around on flowing liquids; add 'source' check to allow items to continue flowing a bit in the source block of flowing water. - if def and not is_floating and (def.liquidtype == "flowing" or def.liquidtype == "source") then - self._flowing = true - - --[[ Get flowing direction (function call from flowlib), if there's a liquid. - NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7. - Luckily, this is exactly what we need if we only care about water, which has this flowing distance. ]] - local vec = flowlib.quick_flow(p, node) - -- 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.2 - -- Set new item moving speed into the direciton of the liquid - local newv = vector.multiply(vec, f) - -- Swap to acceleration instead of a static speed to better mimic MC mechanics. - self.object:set_acceleration(vector.new(newv.x, -0.22, newv.z)) - - self.physical_state = true - self._flowing = true - self.object:set_properties({ - physical = true - }) - return true - end - if is_in_water and def.liquidtype == "source" then - local cur_vec = self.object:get_velocity() - -- apply some acceleration in the opposite direction so it doesn't slide forever - local vec = { - x = 0 - cur_vec.x * 0.9, - y = 3 - cur_vec.y * 0.9, - z = 0 - cur_vec.z * 0.9 - } - self.object:set_acceleration(vec) - -- slow down the item in water - local vel = self.object:get_velocity() - if vel.y < 0 then - vel.y = vel.y * 0.9 - end - self.object:set_velocity(vel) - if self.physical_state ~= false or self._flowing ~= true then - self.physical_state = true - self._flowing = true - self.object:set_properties({ - physical = true - }) - end - end - elseif self._flowing == true and not is_in_water and not is_floating then - -- Disable flowing physics if not on/in flowing liquid - self._flowing = false - enable_physics(self.object, self, true) - return true - end -end - minetest.register_entity(":__builtin:item", { initial_properties = { hp_max = 1, @@ -1053,7 +997,7 @@ minetest.register_entity(":__builtin:item", { if push_out_item_stuck_in_solid(self, dtime, p, def, is_in_water) then return end - if move_items_in_water (self, p, def, node, is_floating, is_in_water) then return end + mcl_physics.apply_entity_environmental_physics(self) -- If node is not registered or node is walkably solid and resting on nodebox local nn = minetest.get_node(vector.offset(p, 0, -0.5, 0)).name diff --git a/mods/ENTITIES/mcl_item_entity/mod.conf b/mods/ENTITIES/mcl_item_entity/mod.conf index acd9f00f3..26c80d0ea 100644 --- a/mods/ENTITIES/mcl_item_entity/mod.conf +++ b/mods/ENTITIES/mcl_item_entity/mod.conf @@ -1,4 +1,4 @@ name = mcl_item_entity author = PilzAdam description = Dropped items will be attracted to the player like a magnet. -depends = flowlib, mcl_enchanting +depends = mcl_physics, mcl_enchanting diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index b3d1ac142..b98656adb 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -411,7 +411,8 @@ local function on_step_work (self, dtime) local player_in_active_range = self:player_in_active_range() self:check_suspend(player_in_active_range) - self:check_water_flow() + -- Handle environmental physics + mcl_physics.apply_entity_environmental_physics(self) if not self._jumping_cliff then self._can_jump_cliff = self:can_jump_cliff() diff --git a/mods/ENTITIES/mcl_mobs/mod.conf b/mods/ENTITIES/mcl_mobs/mod.conf index 927c1c905..3c331852b 100644 --- a/mods/ENTITIES/mcl_mobs/mod.conf +++ b/mods/ENTITIES/mcl_mobs/mod.conf @@ -2,4 +2,4 @@ name = mcl_mobs author = PilzAdam description = Adds a mob API for mods to add animals or monsters, etc. depends = mcl_particles, mcl_luck -optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience, mcl_sculk +optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience, mcl_sculk, mcl_physics diff --git a/mods/ENTITIES/mcl_mobs/physics.lua b/mods/ENTITIES/mcl_mobs/physics.lua index 5c1d34684..6b13e729b 100644 --- a/mods/ENTITIES/mcl_mobs/physics.lua +++ b/mods/ENTITIES/mcl_mobs/physics.lua @@ -996,43 +996,7 @@ function mob_class:falling(pos) end function mob_class:check_water_flow() - -- Add water flowing for mobs from mcl_item_entity - local p, node, nn, def - p = self.object:get_pos() - node = minetest.get_node_or_nil(p) - if node then - nn = node.name - def = minetest.registered_nodes[nn] - end - - -- Move item around on flowing liquids - if def and def.liquidtype == "flowing" then - - --[[ Get flowing direction (function call from flowlib), if there's a liquid. - NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7. - Luckily, this is exactly what we need if we only care about water, which has this flowing distance. ]] - local vec = flowlib.quick_flow(p, node) - -- 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) - self.object:set_acceleration({x = 0, y = 0, z = 0}) - self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z}) - - self.physical_state = true - self._flowing = true - self.object:set_properties({ - physical = true - }) - return - end - elseif self._flowing == true then - -- Disable flowing physics if not on/in flowing liquid - self._flowing = false - return - end + -- Deprecated. Do nothing end function mob_class:check_dying() diff --git a/mods/ENVIRONMENT/mcl_physics/api.lua b/mods/ENVIRONMENT/mcl_physics/api.lua new file mode 100644 index 000000000..b744d774f --- /dev/null +++ b/mods/ENVIRONMENT/mcl_physics/api.lua @@ -0,0 +1,53 @@ +local mod = mcl_physics + +local registered_environment_effects = {} + +function mod.register_enviornment_effect(effect) + local list = registered_effects + list[#list + 1] = effect +end + +function mod.get_environment_effect(pos, vel, staticdata, mass) + local v = vector.new(0,0,0) + local a = vector.new(0,0,0) + + -- Accumulate all enviornmental effects + for _,effect in ipairs(registered_environment_effects) do + local dv,da = effect(pos, vel, staticdata) + if dv then + v = v + dv + end + if da then + a = a + da + end + end + + if vector.length(v) > 0.01 or vector.length(a) > vector.length(a) > 0.01 then + return v,a + else + return -- nil,nil + end +end + +function mod.apply_entity_environmental_physics(self, data) + data = data or {} + + local pos = self.object:get_pos() + local vel = self.object:get_velocity() + local new_velocity,new_acceleration = mcl_physics.get_environment_effect(pos, vel, data, 1) + + -- Update entity states + self._flowing = data.flowing + + -- Apply environmental effects if there are any + if new_velocity or new_acceleration then + if new_acceleration then self.object:set_acceleration(new_acceleration) end + if new_velocity then self.object:set_velocity(new_velocity) end + + self.physical_state = true + self._flowing = true + self.object:set_properties({ + physical = true + }) + end +end diff --git a/mods/ENVIRONMENT/mcl_physics/init.lua b/mods/ENVIRONMENT/mcl_physics/init.lua new file mode 100644 index 000000000..fa072e20b --- /dev/null +++ b/mods/ENVIRONMENT/mcl_physics/init.lua @@ -0,0 +1,40 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local mod = {} +mcl_physics = mod + +dofile(modpath.."/api.lua") + +-- TODO: move to Flowlib +local FLOW_SPEED = 1.39 +mod.register_effect(function(pos, vel, staticdata) + -- 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 + + -- Make sure we are in a liquid before continuing + local is_flowing = (nodedef.liquidtype == "flowing") + staticdata.flowing = is_flowing + if not is_flowing then + -- Apply decelleration if the entity moved from flowing water to + -- stationary water + if nodedef.liquidtype == "source" then + return nil,vector.new( + 0 - vel.x * 0.9, + 3 - vel.y * 0.9, + 0 - vel.z * 0.9 + ) + end + return + end + + -- Get liquid flow direction + local vec = vector.multiply(flowlib.quick_flow(pos, node), FLOW_SPEED) + return vector.new(vec.x, -0.22, vec.z),nil +end) + +-- Node effects +mod.register_effect + diff --git a/mods/ENVIRONMENT/mcl_physics/mod.conf b/mods/ENVIRONMENT/mcl_physics/mod.conf new file mode 100644 index 000000000..42ea23306 --- /dev/null +++ b/mods/ENVIRONMENT/mcl_physics/mod.conf @@ -0,0 +1,4 @@ +name = mcl_physics +author = teknomunk +description = Environmental physics +depends = flowlib