Fix cart reproduction bugs
parent
6812c99ade
commit
b771ffcc6b
|
@ -149,6 +149,7 @@ History
|
|||
2020-07-24 V1.08 Adapted to new techage ICTA style
|
||||
2020-08-14 V1.09 Hopper support for digtron, protector:chest and default:furnace added
|
||||
2020-11-12 V1.10 Make carts more robust against server lag
|
||||
2021-04-10 V2.00 Complete revision to make carts robust against server load/lag,
|
||||
Speed limit signs and cart terminal added
|
||||
2021-09-02 V2.01 Chat command /stopcart added
|
||||
2021-04-10 V2.00 Complete revision to make carts robust against server load/lag,
|
||||
Speed limit signs and cart terminal added
|
||||
2021-09-02 V2.01 Chat command /stopcart added
|
||||
2021-10-18 V2.02 Cart reproduction bug fixed
|
||||
|
|
19
baselib.lua
19
baselib.lua
|
@ -257,9 +257,6 @@ function minecart.add_nodecart(pos, node_name, param2, cargo, owner, userID)
|
|||
pos2 = minetest.find_node_near(pos, 1, minecart.lRails)
|
||||
if not pos2 or not minecart.is_rail(pos2) then
|
||||
pos2 = minetest.find_node_near(pos, 2, minecart.lRails)
|
||||
if not pos2 or not minecart.is_rail(pos2) then
|
||||
pos2 = minetest.find_node_near(pos, 2, {"air"})
|
||||
end
|
||||
end
|
||||
else
|
||||
pos2 = vector.new(pos)
|
||||
|
@ -282,8 +279,6 @@ function minecart.add_nodecart(pos, node_name, param2, cargo, owner, userID)
|
|||
ndef.after_place_node(pos2)
|
||||
end
|
||||
return pos2
|
||||
else
|
||||
minetest.add_item(pos, ItemStack({name = node_name}))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -363,10 +358,13 @@ function minecart.entity_to_node(pos, entity)
|
|||
local dir = minetest.yaw_to_dir(rot.y)
|
||||
local facedir = minetest.dir_to_facedir(dir)
|
||||
minecart.stop_recording(entity, pos)
|
||||
entity.object:remove()
|
||||
local pos2 = minecart.add_nodecart(pos, entity.node_name, facedir, entity.cargo, entity.owner, entity.userID)
|
||||
minecart.stop_monitoring(entity.owner, entity.userID, pos2)
|
||||
minecart.monitoring_remove_cart(entity.owner, entity.userID)
|
||||
if pos2 then
|
||||
minecart.stop_monitoring(entity.owner, entity.userID, pos2)
|
||||
entity.object:remove()
|
||||
else
|
||||
minecart.start_entitycart(entity, pos, facedir)
|
||||
end
|
||||
end
|
||||
|
||||
function minecart.add_node_to_player_inventory(pos, player, node_name)
|
||||
|
@ -389,9 +387,10 @@ function minecart.remove_entity(self, pos, player)
|
|||
minetest.sound_stop(self.sound_handle)
|
||||
self.sound_handle = nil
|
||||
end
|
||||
minecart.add_node_to_player_inventory(pos, player, self.node_name or "minecart:cart")
|
||||
if player then
|
||||
minecart.add_node_to_player_inventory(pos, player, self.node_name or "minecart:cart")
|
||||
end
|
||||
minecart.stop_monitoring(self.owner, self.userID, pos)
|
||||
minecart.stop_recording(self, pos)
|
||||
minecart.monitoring_remove_cart(self.owner, self.userID)
|
||||
self.object:remove()
|
||||
end
|
||||
|
|
15
buffer.lua
15
buffer.lua
|
@ -159,13 +159,16 @@ minetest.register_craft({
|
|||
})
|
||||
|
||||
minetest.register_lbm({
|
||||
label = "Delete waiting times",
|
||||
name = "minecart:del_time",
|
||||
label = "Delete metadata",
|
||||
name = "minecart:metadata",
|
||||
nodenames = {"minecart:buffer"},
|
||||
run_at_every_load = false,
|
||||
run_at_every_load = true,
|
||||
action = function(pos, node)
|
||||
-- delete old data
|
||||
minecart.get_route(pos)
|
||||
M(pos):set_string("formspec", formspec(pos))
|
||||
-- delete old metadata around the buffer (bugfix)
|
||||
local pos1 = {x = pos.x - 2, y = pos.y - 2, z = pos.z - 2}
|
||||
local pos2 = {x = pos.x + 2, y = pos.y + 2, z = pos.z + 2}
|
||||
for _, pos in ipairs(minetest.find_nodes_with_meta(pos1, pos2)) do
|
||||
minecart.del_metadata(pos)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
|
|
@ -186,7 +186,7 @@ local function play_sound(self)
|
|||
if self.object then
|
||||
self.sound_handle = minetest.sound_play(
|
||||
"carts_cart_moving", {
|
||||
object = self.object,
|
||||
pos = self.object:get_pos(),
|
||||
gain = (self.curr_speed or 0) / MAX_SPEED,
|
||||
})
|
||||
end
|
||||
|
|
4
init.lua
4
init.lua
|
@ -13,7 +13,7 @@
|
|||
minecart = {}
|
||||
|
||||
-- Version for compatibility checks, see readme.md/history
|
||||
minecart.version = 2.01
|
||||
minecart.version = 2.02
|
||||
|
||||
minecart.hopper_enabled = minetest.settings:get_bool("minecart_hopper_enabled") ~= false
|
||||
minecart.teleport_enabled = minetest.settings:get_bool("minecart_teleport_enabled") == true
|
||||
|
@ -35,7 +35,7 @@ dofile(MP .. "/api.lua")
|
|||
dofile(MP .. "/minecart.lua")
|
||||
dofile(MP .. "/buffer.lua")
|
||||
dofile(MP .. "/protection.lua")
|
||||
--dofile(MP .. "/tool.lua") # for debugging only
|
||||
--dofile(MP .. "/tool.lua") -- for debugging only
|
||||
dofile(MP .. "/signs.lua")
|
||||
dofile(MP .. "/terminal.lua")
|
||||
dofile(MP .. "/pusher.lua")
|
||||
|
|
|
@ -68,9 +68,6 @@ local function get_checkpoint(cart)
|
|||
cp = cart.checkpoints[cart.idx]
|
||||
end
|
||||
local pos = H2P(cp[1])
|
||||
-- if M(pos):contains("waypoints") then
|
||||
-- print("get_checkpoint", P2S(H2P(cp[1])), P2S(H2P(cp[2])))
|
||||
-- end
|
||||
return cp, cart.idx == #cart.checkpoints
|
||||
end
|
||||
|
||||
|
@ -103,21 +100,41 @@ local function get_cart_info(owner, userID, query_pos)
|
|||
end
|
||||
end
|
||||
|
||||
local function logging(cart, err)
|
||||
local s = string.format("[Minecart] Cart %s/%u %s!", cart.owner, cart.userID, err)
|
||||
minetest.log("warning", s)
|
||||
end
|
||||
|
||||
-- check cart data
|
||||
local function valid_cart(cart)
|
||||
if cart.objID == nil or cart.objID == 0 then
|
||||
return false
|
||||
end
|
||||
if tCartsOnRail[cart.owner] and tCartsOnRail[cart.owner][cart.userID] then
|
||||
return true
|
||||
end
|
||||
logging(cart, "with invalid data")
|
||||
local entity = minetest.luaentities[cart.objID]
|
||||
if entity then
|
||||
entity.object:remove()
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function monitoring(cycle)
|
||||
local cart = pop(cycle)
|
||||
|
||||
-- All running cars
|
||||
while cart do
|
||||
-- All running cars
|
||||
if cart.objID and cart.objID ~= 0 then
|
||||
if valid_cart(cart) then
|
||||
cart.idx = cart.idx + 1
|
||||
local entity = minetest.luaentities[cart.objID]
|
||||
if entity then -- cart entity running
|
||||
local pos = entity.object:get_pos()
|
||||
if pos then
|
||||
cart.last_pos = vector.round(pos)
|
||||
--print("entity card " .. cart.userID .. " at " .. P2S(cart.last_pos))
|
||||
else
|
||||
minetest.log("warning", "[Minecart] entity card without pos!")
|
||||
logging(cart, "without pos")
|
||||
end
|
||||
push(cycle, cart)
|
||||
elseif cart.checkpoints then
|
||||
|
@ -130,16 +147,15 @@ local function monitoring(cycle)
|
|||
end
|
||||
push(cycle, cart)
|
||||
else
|
||||
minetest.log("warning", "[Minecart] zombie got lost")
|
||||
logging(cart, "as zombie got lost")
|
||||
end
|
||||
else
|
||||
local pos = cart.last_pos or cart.pos
|
||||
pos = minecart.add_nodecart(pos, cart.node_name, 0, cart.cargo, cart.owner, cart.userID)
|
||||
cart.objID = 0
|
||||
cart.pos = pos
|
||||
--print("cart to node", cycle, cart.userID, P2S(pos))
|
||||
minecart.stop_monitoring(cart.owner, cart.userID, pos)
|
||||
logging(cart, "stopped at " .. P2S(pos))
|
||||
end
|
||||
elseif cart and not cart.objID and tCartsOnRail[cart.owner] then
|
||||
elseif not cart.objID and tCartsOnRail[cart.owner] then
|
||||
-- Delete carts marked as "to be deleted"
|
||||
tCartsOnRail[cart.owner][cart.userID] = nil
|
||||
end
|
||||
|
@ -184,6 +200,7 @@ function minecart.stop_monitoring(owner, userID, pos)
|
|||
--print("stop_monitoring", owner, userID)
|
||||
if tCartsOnRail[owner] and tCartsOnRail[owner][userID] then
|
||||
tCartsOnRail[owner][userID].pos = pos
|
||||
-- Mark as "stopped"
|
||||
tCartsOnRail[owner][userID].objID = 0
|
||||
minecart.store_carts()
|
||||
end
|
||||
|
@ -192,14 +209,20 @@ end
|
|||
function minecart.monitoring_remove_cart(owner, userID)
|
||||
--print("monitoring_remove_cart", owner, userID)
|
||||
if tCartsOnRail[owner] and tCartsOnRail[owner][userID] then
|
||||
tCartsOnRail[owner][userID].objID = nil
|
||||
tCartsOnRail[owner][userID] = nil
|
||||
-- Cart stopped?
|
||||
if tCartsOnRail[owner][userID].objID == 0 then
|
||||
-- Can directly be deleted
|
||||
tCartsOnRail[owner][userID] = nil
|
||||
else -- Cart running
|
||||
-- Mark as "to be deleted" by monitoring
|
||||
tCartsOnRail[owner][userID].objID = nil
|
||||
end
|
||||
minecart.store_carts()
|
||||
end
|
||||
end
|
||||
|
||||
function minecart.monitoring_valid_cart(owner, userID, pos, node_name)
|
||||
if tCartsOnRail[owner] and tCartsOnRail[owner][userID] then
|
||||
if tCartsOnRail[owner] and tCartsOnRail[owner][userID] and tCartsOnRail[owner][userID].pos then
|
||||
return vector.equals(tCartsOnRail[owner][userID].pos, pos) and
|
||||
tCartsOnRail[owner][userID].node_name == node_name
|
||||
end
|
||||
|
@ -245,28 +268,38 @@ minetest.register_chatcommand("mycart", {
|
|||
|
||||
minetest.register_chatcommand("stopcart", {
|
||||
params = "<cart-num>",
|
||||
description = S("Stop amd return a missing/running cart."),
|
||||
description = S("Stop and return/drop a missing/running cart."),
|
||||
func = function(owner, param)
|
||||
local userID = tonumber(param)
|
||||
local player_pos = minetest.get_player_by_name(owner):get_pos()
|
||||
if userID then
|
||||
local data = minecart.get_cart_monitoring_data(owner, userID)
|
||||
if data then
|
||||
if data.objID and data.objID ~= 0 then
|
||||
local entity = minetest.luaentities[data.objID]
|
||||
if entity then -- cart entity running
|
||||
minecart.entity_to_node(player_pos, entity)
|
||||
if data and data.objID then
|
||||
local entity = minetest.luaentities[data.objID]
|
||||
--print("stopcart", userID, data.pos, data.objID, entity)
|
||||
if data.objID == 0 then
|
||||
-- Cart as node
|
||||
if data.pos then
|
||||
local meta = M(data.pos)
|
||||
if owner == meta:get_string("owner") and userID == meta:get_int("userID") then
|
||||
minecart.remove_nodecart(data.pos)
|
||||
end
|
||||
end
|
||||
elseif entity then
|
||||
-- Cart as entity
|
||||
minecart.remove_entity(entity, data.pos)
|
||||
else
|
||||
local pos = data.last_pos or data.pos
|
||||
local cargo, _, _ = minecart.remove_nodecart(pos)
|
||||
minecart.add_nodecart(player_pos, data.node_name, 0, cargo, owner, userID)
|
||||
minecart.monitoring_remove_cart(owner, userID)
|
||||
-- Cart as zombie/invalid/corrupted
|
||||
-- nothing to do
|
||||
end
|
||||
return true, S("Cart") .. " " .. userID .. " " .. S("stopped")
|
||||
minetest.add_item(player_pos, ItemStack({name = data.node_name}))
|
||||
minecart.monitoring_remove_cart(owner, userID)
|
||||
return true, S("Cart") .. " " .. userID .. " " .. S("dropped")
|
||||
else
|
||||
return false, S("Cart") .. " " .. userID .. " " .. S("is not existing!")
|
||||
end
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
})
|
||||
|
|
|
@ -585,6 +585,9 @@ end
|
|||
-- minecart.get_next_buffer(pos, facedir)
|
||||
minecart.get_next_buffer = get_next_buffer
|
||||
|
||||
-- minecart.del_metadata(pos)
|
||||
minecart.del_metadata = del_metadata
|
||||
|
||||
--minetest.register_lbm({
|
||||
-- label = "Delete waypoints",
|
||||
-- name = "minecart:del_meta",
|
||||
|
|
31
storage.lua
31
storage.lua
|
@ -50,30 +50,15 @@ minetest.register_on_mods_loaded(function()
|
|||
else
|
||||
local t = minetest.deserialize(storage:get_string("CartsOnRail")) or {}
|
||||
for owner, carts in pairs(t) do
|
||||
minecart.CartsOnRail[owner] = {}
|
||||
minecart.CartsOnRail[owner] = minecart.CartsOnRail[owner] or {}
|
||||
for userID, cart in pairs(carts) do
|
||||
print("reload cart", owner, userID, cart.objID)
|
||||
minecart.CartsOnRail[owner][userID] = cart
|
||||
-- mark all entity carts as zombified
|
||||
if cart.objID and cart.objID ~= 0 then
|
||||
cart.objID = -1
|
||||
minecart.push(1, cart)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.after(10, function()
|
||||
for owner, carts in pairs(minecart.CartsOnRail) do
|
||||
for userID, cart in pairs(carts) do
|
||||
-- Remove node carts that are not available anymore
|
||||
if cart.pos and (cart.objID == 0 or not cart.objID) then
|
||||
local node = minecart.get_node_lvm(cart.pos)
|
||||
if not minecart.tNodeNames[node.name] then
|
||||
-- Mark as "to be deleted"
|
||||
print("Node cart deleted", owner, userID)
|
||||
minecart.CartsOnRail[owner][userID] = nil
|
||||
if cart.objID then
|
||||
minecart.CartsOnRail[owner][userID] = cart
|
||||
-- mark all entity carts as zombified
|
||||
if cart.objID ~= 0 then
|
||||
cart.objID = -1
|
||||
minecart.push(1, cart)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue