Merge pull request 'Add persistence to XP Orbs' (#4265) from teknomunk/MineClone2:persist-xp-orbs into master

Reviewed-on: VoxeLibre/VoxeLibre#4265
Reviewed-by: Mikita Wiśniewski <rudzik8@protonmail.com>
This commit is contained in:
the-real-herowl 2024-07-31 00:03:05 +02:00
commit 1745b6d400
1 changed files with 48 additions and 48 deletions

View File

@ -1,7 +1,12 @@
local size_min, size_max = 20, 59 -- Constants
local delta_size = size_max - size_min local size_min = 20 / 100 -- minimum size, prescaled
local size_max = 59 / 100 -- maximum size, prescaled
local delta_size = (size_max - size_min) / 10 -- Size change for each XP size level
local max_orb_age = 300 -- seconds
local gravity = vector.new(0, -((tonumber(minetest.settings:get("movement_gravity"))) or 9.81), 0)
local size_to_xp = { local size_to_xp = {
-- min and max XP amount for a given size
{-32768, 2}, -- 1 {-32768, 2}, -- 1
{ 3, 6}, -- 2 { 3, 6}, -- 2
{ 7, 16}, -- 3 { 7, 16}, -- 3
@ -16,24 +21,20 @@ local size_to_xp = {
} }
local function xp_to_size(xp) local function xp_to_size(xp)
local i, l = 1, #size_to_xp xp = xp or 0
while xp > size_to_xp[i][1] and i < l do -- Find the size for the xp amount
i = i + 1 for i=1,11 do
local bucket = size_to_xp[i]
if xp >= bucket[1] and xp <= bucket[2] then
return (i - 1) * delta_size + size_min
end
end end
return ((i - 1) / (l - 1) * delta_size + size_min) / 100 -- Fallback is the minimum size
return size_min
end end
local max_orb_age = 300 -- seconds
local gravity = vector.new(0, -((tonumber(minetest.settings:get("movement_gravity"))) or 9.81), 0)
local collector, pos, pos2
local direction, distance, player_velocity, goal
local currentvel, acceleration, multiplier, velocity
local node, vel, def
local is_moving, is_slippery, slippery, slip_factor
local size
local function xp_step(self, dtime) local function xp_step(self, dtime)
--if item set to be collected then only execute go to player --if item set to be collected then only execute go to player
if self.collected == true then if self.collected == true then
@ -41,33 +42,32 @@ local function xp_step(self, dtime)
self.collected = false self.collected = false
return return
end end
collector = minetest.get_player_by_name(self.collector)
local collector = minetest.get_player_by_name(self.collector)
if collector and collector:get_hp() > 0 and vector.distance(self.object:get_pos(),collector:get_pos()) < 7.25 then if collector and collector:get_hp() > 0 and vector.distance(self.object:get_pos(),collector:get_pos()) < 7.25 then
self.object:set_acceleration(vector.new(0,0,0)) self.object:set_acceleration(vector.new(0,0,0))
self.disable_physics(self) self.disable_physics(self)
--get the variables --get the variables
pos = self.object:get_pos() local pos = self.object:get_pos()
pos2 = collector:get_pos() local pos2 = collector:get_pos()
player_velocity = collector:get_velocity() or collector:get_player_velocity() local player_velocity = collector:get_velocity() or collector:get_player_velocity()
pos2.y = pos2.y + 0.8 pos2.y = pos2.y + 0.8
direction = vector.direction(pos,pos2) local direction = vector.direction(pos,pos2)
distance = vector.distance(pos2,pos) local distance = vector.distance(pos2,pos)
multiplier = distance local multiplier = distance
if multiplier < 1 then if multiplier < 1 then
multiplier = 1 multiplier = 1
end end
goal = vector.multiply(direction,multiplier) local currentvel = self.object:get_velocity()
currentvel = self.object:get_velocity()
if distance > 1 then if distance > 1 then
multiplier = 20 - distance multiplier = 20 - distance
velocity = vector.multiply(direction,multiplier) local velocity = vector.multiply(direction, multiplier)
goal = velocity local acceleration = vector.new(velocity.x - currentvel.x, velocity.y - currentvel.y, velocity.z - currentvel.z)
acceleration = vector.new(goal.x-currentvel.x,goal.y-currentvel.y,goal.z-currentvel.z) self.object:add_velocity(vector.add(acceleration, player_velocity))
self.object:add_velocity(vector.add(acceleration,player_velocity))
elseif distance < 0.8 then elseif distance < 0.8 then
mcl_experience.add_xp(collector, self._xp) mcl_experience.add_xp(collector, self._xp)
self.object:remove() self.object:remove()
@ -75,28 +75,26 @@ local function xp_step(self, dtime)
return return
else else
self.collector = nil self.collector = nil
self.enable_physics(self) self:enable_physics()
end end
end end
-- Age orbs
self.age = self.age + dtime self.age = self.age + dtime
if self.age > max_orb_age then if self.age > max_orb_age then
self.object:remove() self.object:remove()
return return
end end
pos = self.object:get_pos() local pos = self.object:get_pos()
if not pos then return end
if pos then -- Get the node directly below the XP orb
node = minetest.get_node_or_nil({ local node = minetest.get_node_or_nil({
x = pos.x, x = pos.x,
y = pos.y -0.25, y = pos.y - 0.25, -- Orb collision box is +/-0.2, so go a bit below that
z = pos.z z = pos.z
}) })
else
return
end
-- Remove nodes in 'ignore' -- Remove nodes in 'ignore'
if node and node.name == "ignore" then if node and node.name == "ignore" then
@ -109,18 +107,18 @@ local function xp_step(self, dtime)
end end
-- Slide on slippery nodes -- Slide on slippery nodes
vel = self.object:get_velocity() local vel = self.object:get_velocity()
def = node and minetest.registered_nodes[node.name] local def = node and minetest.registered_nodes[node.name]
is_moving = (def and not def.walkable) or local is_moving = (def and not def.walkable) or
vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0 vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0
is_slippery = false local is_slippery = false
if def and def.walkable then if def and def.walkable then
slippery = minetest.get_item_group(node.name, "slippery") local slippery = minetest.get_item_group(node.name, "slippery")
is_slippery = slippery ~= 0 is_slippery = slippery ~= 0
if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then
-- Horizontal deceleration -- Horizontal deceleration
slip_factor = 4.0 / (slippery + 4) local slip_factor = 4.0 / (slippery + 4)
self.object:set_acceleration({ self.object:set_acceleration({
x = -vel.x * slip_factor, x = -vel.x * slip_factor,
y = 0, y = 0,
@ -160,7 +158,6 @@ minetest.register_entity("mcl_experience:orb", {
initial_sprite_basepos = {x = 0, y = 0}, initial_sprite_basepos = {x = 0, y = 0},
is_visible = true, is_visible = true,
pointable = false, pointable = false,
static_save = false,
}, },
moving_state = true, moving_state = true,
slippery_state = false, slippery_state = false,
@ -191,7 +188,7 @@ minetest.register_entity("mcl_experience:orb", {
-- This was a minetest bug for a while: https://github.com/minetest/minetest/issues/14420 -- This was a minetest bug for a while: https://github.com/minetest/minetest/issues/14420
local xp = tonumber(staticdata) or 0 local xp = tonumber(staticdata) or 0
self._xp = xp self._xp = xp
size = xp_to_size(xp) local size = xp_to_size(xp)
self.object:set_properties({ self.object:set_properties({
visual_size = {x = size, y = size}, visual_size = {x = size, y = size},
@ -199,6 +196,9 @@ minetest.register_entity("mcl_experience:orb", {
}) })
self.object:set_sprite({x=1,y=math.random(1,14)}, 14, 0.05, false) self.object:set_sprite({x=1,y=math.random(1,14)}, 14, 0.05, false)
end, end,
get_staticdata = function(self)
return tostring(self._xp or 0)
end,
enable_physics = function(self) enable_physics = function(self)
if not self.physical_state then if not self.physical_state then