Add persistent player-specific metadata into mcl_playerinfo, simple cart reattachment (only exists if the luaentity for the cart exists when the player logs in)

This commit is contained in:
teknomunk 2024-04-12 19:01:15 +00:00
parent cef458a959
commit 4d0c767e66
3 changed files with 103 additions and 32 deletions

View File

@ -42,6 +42,8 @@ local function detach_driver(self)
-- Update cart informatino -- Update cart informatino
self._driver = nil self._driver = nil
self._start_pos = nil self._start_pos = nil
local meta = mcl_playerinfo.get_mod_meta(driver_name, modname)
meta.attached_to = nil
-- Detatch the player object from the minecart -- Detatch the player object from the minecart
local player = minetest.get_player_by_name(driver_name) local player = minetest.get_player_by_name(driver_name)
@ -609,3 +611,42 @@ minetest.register_globalstep(function(dtime)
end end
end) end)
minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
local meta = mcl_playerinfo.get_mod_meta(player_name, modname)
local cart_uuid = meta.attached_to
if cart_uuid then
print("Trying to reattach "..player_name.." to cart #"..cart_uuid)
local cartdata = get_cart_data(cart_uuid)
-- Can't get into a cart that was destroyed
if not cartdata then
print("Failed to get cartdata")
return
end
-- Don't reattach players if someone else got in the cart
if cartdata.last_player ~= player_name then
print("Somebody else got in the cart while you were gone")
return
end
minetest.after(0.2,function(player_name, cart_uuid)
local player = minetest.get_player_by_name(player_name)
if not player then
print("Can't get an ObjectRef for "..player_name)
return
end
local cart = mcl_util.get_luaentity_from_uuid(cart_uuid)
if not cart then
print("Can't find the luaentity for cart #"..cart_uuid)
return
end
mod.attach_driver(cart, player)
end, player_name, cart_uuid)
end
end)

View File

@ -16,6 +16,41 @@ local function activate_normal_minecart(self)
end end
end end
function mod.attach_driver(cart, player)
local staticdata = cart._staticdata
-- Make sure we have a player
if not player or not player:is_player() then return end
local player_name = player:get_player_name()
if cart._driver or player:get_player_control().sneak then return end
-- Update cart information
cart._driver = player_name
cart._start_pos = cart.object:get_pos()
-- Keep track of player attachment
local meta = mcl_playerinfo.get_mod_meta(player_name, modname)
meta.attached_to = cart._uuid
staticdata.last_player = player_name
-- Update player information
local uuid = staticdata.uuid
mcl_player.player_attached[player_name] = true
minetest.log("action", player_name.." entered minecart #"..tostring(uuid).." at "..tostring(cart._start_pos))
-- Attach the player object to the minecart
player:set_attach(cart.object, "", vector.new(1,-1.75,-2), vector.new(0,0,0))
minetest.after(0.2, function(name)
local player = minetest.get_player_by_name(name)
if player then
mcl_player.player_set_animation(player, "sit" , 30)
player:set_eye_offset(vector.new(0,-5.5,0), vector.new(0,-4,0))
mcl_title.set(player, "actionbar", {text=S("Sneak to dismount"), color="white", stay=60})
end
end, player_name)
end
mod.register_minecart({ mod.register_minecart({
itemstring = "mcl_minecarts:minecart", itemstring = "mcl_minecarts:minecart",
craft = { craft = {
@ -39,37 +74,7 @@ mod.register_minecart({
}, },
icon = "mcl_minecarts_minecart_normal.png", icon = "mcl_minecarts_minecart_normal.png",
drop = {"mcl_minecarts:minecart"}, drop = {"mcl_minecarts:minecart"},
on_rightclick = function(self, clicker) on_rightclick = mod.attach_driver,
-- Make sure we have a player
if not clicker or not clicker:is_player() then return end
local player_name = clicker:get_player_name()
if self._driver or clicker:get_player_control().sneak then return end
-- Update cart information
self._driver = player_name
self._start_pos = self.object:get_pos()
-- Update player information
local uuid = self._staticdata.uuid
local playerinfo = mcl_playerinfo[player_name]
if playerinfo and self._staticdata then
playerinfo.attached_to = uuid
end
mcl_player.player_attached[player_name] = true
minetest.log("action", player_name.." entered minecart #"..tostring(uuid).." at "..tostring(self._start_pos))
-- Attach the player object to the minecart
clicker:set_attach(self.object, "", vector.new(1,-1.75,-2), vector.new(0,0,0))
minetest.after(0.2, function(name)
local player = minetest.get_player_by_name(name)
if player then
mcl_player.player_set_animation(player, "sit" , 30)
player:set_eye_offset(vector.new(0,-5.5,0), vector.new(0,-4,0))
mcl_title.set(clicker, "actionbar", {text=S("Sneak to dismount"), color="white", stay=60})
end
end, player_name)
end,
on_activate_by_rail = activate_normal_minecart, on_activate_by_rail = activate_normal_minecart,
_mcl_minecarts_on_step = function(self, dtime) _mcl_minecarts_on_step = function(self, dtime)
-- Grab mob -- Grab mob

View File

@ -1,7 +1,10 @@
local table = table local table = table
local storage = minetest.get_mod_storage()
-- Player state for public API -- Player state for public API
mcl_playerinfo = {} mcl_playerinfo = {}
local player_mod_metadata = {}
-- Get node but use fallback for nil or unknown -- Get node but use fallback for nil or unknown
local function node_ok(pos, fallback) local function node_ok(pos, fallback)
@ -73,6 +76,23 @@ minetest.register_globalstep(function(dtime)
end) end)
function mcl_playerinfo.get_mod_meta(player_name, modname)
-- Load the player's metadata
local meta = player_mod_metadata[player_name]
if not meta then
meta = minetest.deserialize(storage:get_string(player_name))
end
if not meta then
meta = {}
end
player_mod_metadata[player_name] = meta
-- Get the requested module's section of the metadata
local mod_meta = meta[modname] or {}
meta[modname] = mod_meta
return mod_meta
end
-- set to blank on join (for 3rd party mods) -- set to blank on join (for 3rd party mods)
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
local name = player:get_player_name() local name = player:get_player_name()
@ -84,7 +104,6 @@ minetest.register_on_joinplayer(function(player)
node_stand_below = "", node_stand_below = "",
node_head_top = "", node_head_top = "",
} }
end) end)
-- clear when player leaves -- clear when player leaves
@ -93,3 +112,9 @@ minetest.register_on_leaveplayer(function(player)
mcl_playerinfo[name] = nil mcl_playerinfo[name] = nil
end) end)
minetest.register_on_shutdown(function()
for name,data in pairs(player_mod_metadata) do
storage:set_string(name, minetest.serialize(data))
end
end)