mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-22 10:31:06 +01:00
Merge pull request 'Items float when in water / liquids and other changes' (#2481) from SumianVoice/MineClone2_c:item_floating into master
Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/2481
This commit is contained in:
commit
eaf4eb3945
8 changed files with 159 additions and 79 deletions
|
@ -318,18 +318,14 @@ function minetest.handle_node_drops(pos, drops, digger)
|
|||
-- Spawn item and apply random speed
|
||||
local obj = minetest.add_item(dpos, drop_item)
|
||||
if obj then
|
||||
local x = math.random(1, 5)
|
||||
if math.random(1,2) == 1 then
|
||||
x = -x
|
||||
-- set the velocity multiplier to the stored amount or if the game dug this node, apply a bigger velocity
|
||||
local v = 1
|
||||
if digger and digger:is_player() then
|
||||
obj:get_luaentity().random_velocity = 1
|
||||
else
|
||||
obj:get_luaentity().random_velocity = 1.6
|
||||
end
|
||||
local z = math.random(1, 5)
|
||||
if math.random(1,2) == 1 then
|
||||
z = -z
|
||||
end
|
||||
obj:set_velocity({x=1/x, y=obj:get_velocity().y, z=1/z})
|
||||
|
||||
obj:get_luaentity().age = item_drop_settings.dug_buffer
|
||||
|
||||
obj:get_luaentity()._insta_collect = false
|
||||
end
|
||||
end
|
||||
|
@ -408,9 +404,33 @@ minetest.register_entity(":__builtin:item", {
|
|||
-- Number of seconds this item entity has existed so far
|
||||
age = 0,
|
||||
|
||||
-- Multiplier for initial random velocity when the item is spawned
|
||||
random_velocity = 1,
|
||||
|
||||
-- How old it has become in the collection animation
|
||||
collection_age = 0,
|
||||
|
||||
-- Function to apply a random velocity
|
||||
apply_random_vel = function(self, speed)
|
||||
if not self or not self.object or not self.object:get_luaentity() then
|
||||
return
|
||||
end
|
||||
-- if you passed a value then use that for the velocity multiplier
|
||||
if speed ~= nil then self.random_velocity = speed end
|
||||
|
||||
local vel = self.object:get_velocity()
|
||||
if vel and vel.x == 0 and vel.z == 0 and self.random_velocity > 0 then
|
||||
local v = self.random_velocity
|
||||
local x = math.random(5, 10) / 10 * v
|
||||
if math.random(0,10) < 5 then x = -x end
|
||||
local z = math.random(5, 10) / 10 * v
|
||||
if math.random(0,10) < 5 then z = -z end
|
||||
local y = math.random(2,4)
|
||||
self.object:set_velocity({x=x, y=y, z=z})
|
||||
end
|
||||
self.random_velocity = 0
|
||||
end,
|
||||
|
||||
set_item = function(self, itemstring)
|
||||
self.itemstring = itemstring
|
||||
if self.itemstring == "" then
|
||||
|
@ -463,27 +483,9 @@ minetest.register_entity(":__builtin:item", {
|
|||
glow = glow,
|
||||
}
|
||||
self.object:set_properties(prop)
|
||||
if item_drop_settings.random_item_velocity == true then
|
||||
minetest.after(0, function(self)
|
||||
if not self or not self.object or not self.object:get_luaentity() then
|
||||
return
|
||||
end
|
||||
local vel = self.object:get_velocity()
|
||||
if vel and vel.x == 0 and vel.z == 0 then
|
||||
local x = math.random(1, 5)
|
||||
if math.random(1,2) == 1 then
|
||||
x = -x
|
||||
end
|
||||
local z = math.random(1, 5)
|
||||
if math.random(1,2) == 1 then
|
||||
z = -z
|
||||
end
|
||||
local y = math.random(2,4)
|
||||
self.object:set_velocity({x=1/x, y=y, z=1/z})
|
||||
end
|
||||
end, self)
|
||||
if item_drop_settings.random_item_velocity == true and self.age < 1 then
|
||||
minetest.after(0, self.apply_random_vel, self)
|
||||
end
|
||||
|
||||
end,
|
||||
|
||||
get_staticdata = function(self)
|
||||
|
@ -572,7 +574,7 @@ minetest.register_entity(":__builtin:item", {
|
|||
self._forcetimer = 0
|
||||
|
||||
self.object:set_armor_groups({immortal = 1})
|
||||
self.object:set_velocity({x = 0, y = 2, z = 0})
|
||||
-- self.object:set_velocity({x = 0, y = 2, z = 0})
|
||||
self.object:set_acceleration({x = 0, y = -get_gravity(), z = 0})
|
||||
self:set_item(self.itemstring)
|
||||
end,
|
||||
|
@ -602,12 +604,13 @@ minetest.register_entity(":__builtin:item", {
|
|||
end
|
||||
-- Merge the remote stack into this one
|
||||
|
||||
local pos = object:get_pos()
|
||||
pos.y = pos.y + ((total_count - count) / max_count) * 0.15
|
||||
self.object:move_to(pos)
|
||||
-- local pos = object:get_pos()
|
||||
-- pos.y = pos.y + ((total_count - count) / max_count) * 0.15
|
||||
-- self.object:move_to(pos)
|
||||
|
||||
self.age = 0 -- Handle as new entity
|
||||
own_stack:set_count(total_count)
|
||||
self.random_velocity = 0
|
||||
self:set_item(own_stack:to_string())
|
||||
|
||||
entity._removed = true
|
||||
|
@ -646,33 +649,53 @@ minetest.register_entity(":__builtin:item", {
|
|||
local node = minetest.get_node_or_nil(p)
|
||||
local in_unloaded = (node == nil)
|
||||
|
||||
if self.is_clock then
|
||||
self.object:set_properties({
|
||||
textures = {"mcl_clock:clock_" .. (mcl_worlds.clock_works(p) and mcl_clock.old_time or mcl_clock.random_frame)}
|
||||
})
|
||||
end
|
||||
|
||||
-- If no collector was found for a long enough time, declare the magnet as disabled
|
||||
if self._magnet_active and (self._collector_timer == nil or (self._collector_timer > item_drop_settings.magnet_time)) then
|
||||
self._magnet_active = false
|
||||
enable_physics(self.object, self)
|
||||
return
|
||||
end
|
||||
if in_unloaded then
|
||||
-- Don't infinetly fall into unloaded map
|
||||
disable_physics(self.object, self)
|
||||
return
|
||||
end
|
||||
|
||||
-- Destroy item in lava, fire or special nodes
|
||||
if self.is_clock then
|
||||
self.object:set_properties({
|
||||
textures = {"mcl_clock:clock_" .. (mcl_worlds.clock_works(p) and mcl_clock.old_time or mcl_clock.random_frame)}
|
||||
})
|
||||
end
|
||||
|
||||
local nn = node.name
|
||||
local is_in_water = (minetest.get_item_group(nn, "liquid") ~= 0)
|
||||
local nn_above = minetest.get_node({x=p.x, y=p.y+0.1, z=p.z}).name
|
||||
-- make sure it's more or less stationary and is at water level
|
||||
local sleep_threshold = 0.3
|
||||
local is_floating = false
|
||||
local is_stationary = math.abs(self.object:get_velocity().x) < sleep_threshold
|
||||
and math.abs(self.object:get_velocity().y) < sleep_threshold
|
||||
and math.abs(self.object:get_velocity().z) < sleep_threshold
|
||||
if is_in_water and is_stationary then
|
||||
is_floating = (is_in_water
|
||||
and (minetest.get_item_group(nn_above, "liquid") == 0))
|
||||
end
|
||||
|
||||
if is_floating and self.physical_state == true then
|
||||
self.object:set_velocity({x = 0, y = 0, z = 0})
|
||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
||||
disable_physics(self.object, self)
|
||||
end
|
||||
-- If no collector was found for a long enough time, declare the magnet as disabled
|
||||
if self._magnet_active and (self._collector_timer == nil or (self._collector_timer > item_drop_settings.magnet_time)) then
|
||||
self._magnet_active = false
|
||||
enable_physics(self.object, self)
|
||||
return
|
||||
end
|
||||
|
||||
-- Destroy item in lava, fire or special nodes
|
||||
|
||||
local def = minetest.registered_nodes[nn]
|
||||
local lg = minetest.get_item_group(nn, "lava")
|
||||
local fg = minetest.get_item_group(nn, "fire")
|
||||
local dg = minetest.get_item_group(nn, "destroys_items")
|
||||
if (def and (lg ~= 0 or fg ~= 0 or dg == 1)) then
|
||||
--Wait 2 seconds to allow mob drops to be cooked, & picked up instead of instantly destroyed.
|
||||
if self.age > 2 then
|
||||
if self.age > 2 and minetest.get_item_group(self.itemstring, "fire_immune") == 0 then
|
||||
if dg ~= 2 then
|
||||
minetest.sound_play("builtin_item_lava", {pos = self.object:get_pos(), gain = 0.5})
|
||||
end
|
||||
|
@ -695,7 +718,7 @@ minetest.register_entity(":__builtin:item", {
|
|||
end
|
||||
|
||||
-- Push item out when stuck inside solid opaque node
|
||||
if def and def.walkable and def.groups and def.groups.opaque == 1 then
|
||||
if not is_in_water and def and def.walkable and def.groups and def.groups.opaque == 1 then
|
||||
local shootdir
|
||||
local cx = (p.x % 1) - 0.5
|
||||
local cz = (p.z % 1) - 0.5
|
||||
|
@ -736,9 +759,9 @@ minetest.register_entity(":__builtin:item", {
|
|||
local newv = vector.multiply(shootdir, 3)
|
||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
||||
self.object:set_velocity(newv)
|
||||
|
||||
disable_physics(self.object, self, false, false)
|
||||
|
||||
|
||||
if shootdir.y == 0 then
|
||||
self._force = newv
|
||||
p.x = math.floor(p.x)
|
||||
|
@ -776,7 +799,8 @@ minetest.register_entity(":__builtin:item", {
|
|||
end
|
||||
|
||||
-- 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 def.liquidtype == "flowing" or def.liquidtype == "source" then
|
||||
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.
|
||||
|
@ -798,37 +822,65 @@ minetest.register_entity(":__builtin:item", {
|
|||
})
|
||||
return
|
||||
end
|
||||
elseif self._flowing == true then
|
||||
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)
|
||||
local pos = self.object:get_pos()
|
||||
disable_physics(self.object, self, false, false)
|
||||
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 is_on_floor = (minetest.registered_nodes[nn].walkable
|
||||
and not minetest.registered_nodes[nn].groups.slippery and v.y == 0)
|
||||
|
||||
if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable and not minetest.registered_nodes[nn].groups.slippery 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
|
||||
for _, object in pairs(minetest.get_objects_inside_radius(p, 0.8)) do
|
||||
local obj = object:get_luaentity()
|
||||
if obj and obj.name == "__builtin:item"
|
||||
and obj.physical_state == false then
|
||||
if self:try_merge_with(own_stack, object, obj) then
|
||||
return
|
||||
end
|
||||
if not minetest.registered_nodes[nn]
|
||||
or is_floating or is_on_floor then
|
||||
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
|
||||
-- Merge with close entities of the same item
|
||||
for _, object in pairs(minetest.get_objects_inside_radius(p, 0.8)) do
|
||||
local obj = object:get_luaentity()
|
||||
if obj and obj.name == "__builtin:item"
|
||||
and obj.physical_state == false then
|
||||
if self:try_merge_with(own_stack, object, obj) then
|
||||
return
|
||||
end
|
||||
end
|
||||
disable_physics(self.object, self)
|
||||
-- don't disable if underwater
|
||||
if not is_in_water then
|
||||
disable_physics(self.object, self)
|
||||
end
|
||||
end
|
||||
else
|
||||
if self._magnet_active == false then
|
||||
if self._magnet_active == false and not is_floating then
|
||||
enable_physics(self.object, self)
|
||||
end
|
||||
end
|
||||
|
||||
end,
|
||||
|
||||
-- Note: on_punch intentionally left out. The player should *not* be able to collect items by punching
|
||||
|
|
|
@ -252,7 +252,16 @@ local dispenserdef = {
|
|||
elseif inv:room_for_item("main", od_ret) then
|
||||
inv:add_item("main", od_ret)
|
||||
else
|
||||
minetest.add_item(droppos, dropitem)
|
||||
local pos_variation = 100
|
||||
droppos = {
|
||||
x = droppos.x + math.random(-pos_variation, pos_variation) / 1000,
|
||||
y = droppos.y + math.random(-pos_variation, pos_variation) / 1000,
|
||||
z = droppos.z + math.random(-pos_variation, pos_variation) / 1000,
|
||||
}
|
||||
local item_entity = minetest.add_item(droppos, dropitem)
|
||||
local drop_vel = vector.subtract(droppos, pos)
|
||||
local speed = 3
|
||||
item_entity:set_velocity(drop_vel * speed)
|
||||
end
|
||||
else
|
||||
stack:take_item()
|
||||
|
@ -260,7 +269,16 @@ local dispenserdef = {
|
|||
end
|
||||
else
|
||||
-- Drop item otherwise
|
||||
minetest.add_item(droppos, dropitem)
|
||||
local pos_variation = 100
|
||||
droppos = {
|
||||
x = droppos.x + math.random(-pos_variation, pos_variation) / 1000,
|
||||
y = droppos.y + math.random(-pos_variation, pos_variation) / 1000,
|
||||
z = droppos.z + math.random(-pos_variation, pos_variation) / 1000,
|
||||
}
|
||||
local item_entity = minetest.add_item(droppos, dropitem)
|
||||
local drop_vel = vector.subtract(droppos, pos)
|
||||
local speed = 3
|
||||
item_entity:set_velocity(drop_vel * speed)
|
||||
stack:take_item()
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
end
|
||||
|
|
|
@ -134,7 +134,16 @@ local dropperdef = {
|
|||
-- No container?
|
||||
if not dropped and not dropnodedef.groups.container then
|
||||
-- Drop item normally
|
||||
minetest.add_item(droppos, dropitem)
|
||||
local pos_variation = 100
|
||||
droppos = {
|
||||
x = droppos.x + math.random(-pos_variation, pos_variation) / 1000,
|
||||
y = droppos.y + math.random(-pos_variation, pos_variation) / 1000,
|
||||
z = droppos.z + math.random(-pos_variation, pos_variation) / 1000,
|
||||
}
|
||||
local item_entity = minetest.add_item(droppos, dropitem)
|
||||
local drop_vel = vector.subtract(droppos, pos)
|
||||
local speed = 3
|
||||
item_entity:set_velocity(drop_vel * speed)
|
||||
stack:take_item()
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
end
|
||||
|
|
|
@ -100,6 +100,7 @@ mcl_armor.register_set({
|
|||
legs = 6,
|
||||
feet = 3,
|
||||
},
|
||||
groups = { fire_immune=1 },
|
||||
toughness = 2,
|
||||
craft_material = "mcl_nether:netherite_ingot",
|
||||
sound_equip = "mcl_armor_equip_diamond",
|
||||
|
|
|
@ -215,8 +215,8 @@ minetest.register_abm({
|
|||
local posy = pos.y
|
||||
while minetest.get_node(vector.new(pos.x, posy, pos.z)).name == "mcl_core:cactus" do
|
||||
local pos = vector.new(pos.x, posy, pos.z)
|
||||
minetest.remove_node(pos)
|
||||
minetest.add_item(vector.offset(pos, math.random(-0.5, 0.5), 0, math.random(-0.5, 0.5)), "mcl_core:cactus")
|
||||
minetest.dig_node(pos)
|
||||
-- minetest.add_item(vector.offset(pos, math.random(-0.5, 0.5), 0, math.random(-0.5, 0.5)), "mcl_core:cactus")
|
||||
posy = posy + 1
|
||||
end
|
||||
break
|
||||
|
|
|
@ -285,7 +285,7 @@ minetest.register_tool("mcl_farming:hoe_netherite", {
|
|||
inventory_image = "farming_tool_netheritehoe.png",
|
||||
wield_scale = mcl_vars.tool_wield_scale,
|
||||
on_place = hoe_on_place_function(uses.netherite),
|
||||
groups = { tool=1, hoe=1, enchantability=10 },
|
||||
groups = { tool=1, hoe=1, enchantability=10, fire_immune=1 },
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 0.25,
|
||||
damage_groups = { fleshy = 4, },
|
||||
|
|
|
@ -71,7 +71,7 @@ minetest.register_node("mcl_nether:netheriteblock", {
|
|||
stack_max = 64,
|
||||
tiles = {"mcl_nether_netheriteblock.png"},
|
||||
is_ground_content = true,
|
||||
groups = {pickaxey=4, building_block=1, material_stone=1, xp = 0},
|
||||
groups = { pickaxey=4, building_block=1, material_stone=1, xp = 0, fire_immune=1 },
|
||||
drop = "mcl_nether:netheriteblock",
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
_mcl_blast_resistance = 1200,
|
||||
|
@ -285,7 +285,7 @@ minetest.register_craftitem("mcl_nether:netherite_scrap", {
|
|||
_doc_items_longdesc = S("Netherite scrap is a crafting ingredient for netherite ingots."),
|
||||
inventory_image = "mcl_nether_netherite_scrap.png",
|
||||
stack_max = 64,
|
||||
groups = { craftitem = 1 },
|
||||
groups = { craftitem = 1, fire_immune=1 },
|
||||
})
|
||||
|
||||
minetest.register_craftitem("mcl_nether:netherite_ingot", {
|
||||
|
@ -293,7 +293,7 @@ minetest.register_craftitem("mcl_nether:netherite_ingot", {
|
|||
_doc_items_longdesc = S("Netherite ingots can be used with a smithing table to upgrade items to netherite."),
|
||||
inventory_image = "mcl_nether_netherite_ingot.png",
|
||||
stack_max = 64,
|
||||
groups = { craftitem = 1 },
|
||||
groups = { craftitem = 1, fire_immune=1 },
|
||||
})
|
||||
|
||||
minetest.register_craftitem("mcl_nether:netherbrick", {
|
||||
|
|
|
@ -184,7 +184,7 @@ minetest.register_tool("mcl_tools:pick_netherite", {
|
|||
_doc_items_longdesc = pickaxe_longdesc,
|
||||
inventory_image = "default_tool_netheritepick.png",
|
||||
wield_scale = wield_scale,
|
||||
groups = { tool=1, pickaxe=1, dig_speed_class=6, enchantability=10 },
|
||||
groups = { tool=1, pickaxe=1, dig_speed_class=6, enchantability=10, fire_immune=1 },
|
||||
tool_capabilities = {
|
||||
-- 1/1.2
|
||||
full_punch_interval = 0.83333333,
|
||||
|
@ -384,7 +384,7 @@ minetest.register_tool("mcl_tools:shovel_netherite", {
|
|||
_doc_items_usagehelp = shovel_use,
|
||||
inventory_image = "default_tool_netheriteshovel.png",
|
||||
wield_scale = wield_scale,
|
||||
groups = { tool=1, shovel=1, dig_speed_class=6, enchantability=10 },
|
||||
groups = { tool=1, shovel=1, dig_speed_class=6, enchantability=10, fire_immune=1 },
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 1,
|
||||
max_drop_level=5,
|
||||
|
@ -539,7 +539,7 @@ minetest.register_tool("mcl_tools:axe_netherite", {
|
|||
_doc_items_longdesc = axe_longdesc,
|
||||
inventory_image = "default_tool_netheriteaxe.png",
|
||||
wield_scale = wield_scale,
|
||||
groups = { tool=1, axe=1, dig_speed_class=6, enchantability=10 },
|
||||
groups = { tool=1, axe=1, dig_speed_class=6, enchantability=10, fire_immune=1 },
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 1.0,
|
||||
max_drop_level=5,
|
||||
|
@ -664,7 +664,7 @@ minetest.register_tool("mcl_tools:sword_netherite", {
|
|||
_doc_items_longdesc = sword_longdesc,
|
||||
inventory_image = "default_tool_netheritesword.png",
|
||||
wield_scale = wield_scale,
|
||||
groups = { weapon=1, sword=1, dig_speed_class=5, enchantability=10 },
|
||||
groups = { weapon=1, sword=1, dig_speed_class=5, enchantability=10, fire_immune=1 },
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 0.625,
|
||||
max_drop_level=5,
|
||||
|
|
Loading…
Reference in a new issue