A few fixes and tweaks
This commit is contained in:
parent
2efd6cbd55
commit
ebdbf22191
142
cartbase.lua
142
cartbase.lua
@ -55,8 +55,9 @@ end
|
||||
--@param dtime Time since last call, in seconds
|
||||
function cartbase.on_step_handler(self, dtime)
|
||||
|
||||
if self.skipnextstep then
|
||||
self.skipnextstep = false
|
||||
if self.skipsteps > 0 then
|
||||
dbg.v3("Skipping step")
|
||||
self.skipsteps = self.skipsteps -1
|
||||
self.dtime_debt = self.dtime_debt + dtime
|
||||
return
|
||||
end
|
||||
@ -83,6 +84,10 @@ function cartbase.on_step_handler(self, dtime)
|
||||
oldpos = {x=self.pos.x, y=self.pos.y, z=self.pos.z}
|
||||
end
|
||||
|
||||
if self.pos and self.speed > 0 then
|
||||
dbg.v3("New step, dtime "..dtime.." at "..minetest.pos_to_string(self.pos))
|
||||
end
|
||||
|
||||
-- Keep track of this over all step slices and do it once, otherwise
|
||||
-- it goes wrong if it happens twice (i.e. very fast over two close
|
||||
-- together curves)
|
||||
@ -112,7 +117,7 @@ function cartbase.on_step_handler(self, dtime)
|
||||
end
|
||||
|
||||
end
|
||||
if dtime >= 0 and not nomore then
|
||||
if dtime > 0 and not nomore then
|
||||
nomore = cartbase.update(self, dtime)
|
||||
dtime = 0
|
||||
end
|
||||
@ -120,7 +125,9 @@ function cartbase.on_step_handler(self, dtime)
|
||||
-- TODO - seeing if skipping an extra step resolves the mesecons
|
||||
-- delay which occasionally causes rails to not be switched
|
||||
-- in time
|
||||
self.skipnextstep = true
|
||||
-- TODO - in fact, the switching happens at the *end* of the *next*
|
||||
-- step, so we have to skip two!!
|
||||
self.skipsteps = 2
|
||||
end
|
||||
self.dtime_debt = dtime
|
||||
|
||||
@ -146,15 +153,20 @@ end
|
||||
|
||||
|
||||
--- Handle update for a cart.
|
||||
--@param self The cart
|
||||
--@param dtime Time since last call, in seconds, which should always be within
|
||||
-- low enough that the cart doesn't >= 0.5 nodes.
|
||||
--@return True if something happened which means no further step slices should
|
||||
-- be processed during this step. (Currently, this is specifically only
|
||||
-- when a digiline message is sent, because a common usage of that is
|
||||
-- to pass information to a luacontroller, which then uses mesecons to
|
||||
-- switch a rail. This will not necessarily have happened until the next
|
||||
-- server step - and hopefully by then!)
|
||||
-- @param self The cart
|
||||
-- @param dtime Time since last call, in seconds, which should always be
|
||||
-- low enough that the cart doesn't move >= 0.5 nodes.
|
||||
-- @return True if something happened which means no further step slices should
|
||||
-- be processed during this step. (Currently, this is specifically only
|
||||
-- when a digiline message is sent, because a common usage of that is
|
||||
-- to pass information to a luacontroller, which then uses mesecons to
|
||||
-- switch a rail. This will not necessarily have happened until the next
|
||||
-- server step - and hopefully by then!)
|
||||
--
|
||||
-- Note that although some processing is done before the cart is moved, NOTHING
|
||||
-- should set the speed (and in particular, increase it) before the movement,
|
||||
-- because this method is called with a dtime calculated to be safe for the
|
||||
-- speed at the time of calling.
|
||||
function cartbase.update(self, dtime)
|
||||
|
||||
local no_more_slices = false
|
||||
@ -190,15 +202,6 @@ function cartbase.update(self, dtime)
|
||||
return no_more_slices
|
||||
end
|
||||
|
||||
-- Eject a player if necessary
|
||||
if (state.railstatus.eject or state.railstatus.onautolauncher)
|
||||
and self.linkedplayer ~= nil then
|
||||
dbg.v1("Ejecting player from cart")
|
||||
self.linkedplayer:set_detach()
|
||||
self.linkedplayer:setpos(state.pos)
|
||||
self.linkedplayer = nil
|
||||
end
|
||||
|
||||
-- Grab the cart into something's inventory if necessary
|
||||
-- (only allowed when there is no passenger or cargo)
|
||||
if state.railstatus.grab and cartbase.is_empty(self) then
|
||||
@ -217,15 +220,6 @@ function cartbase.update(self, dtime)
|
||||
return no_more_slices
|
||||
end
|
||||
|
||||
-- Set speed/direction from launcher
|
||||
if state.railstatus.launch then
|
||||
cartbase.setdirection(self, state, state.railstatus.launch)
|
||||
state.speed = LAUNCH_CART_SPEED
|
||||
elseif state.railstatus.autolaunch and self.linkedplayer ~= nil then
|
||||
cartbase.setdirection(self, state, state.railstatus.autolaunch)
|
||||
state.speed = LAUNCH_CART_SPEED
|
||||
end
|
||||
|
||||
-- Handle loading/unloading from/to a hopper
|
||||
if (self.carttype == "cargo" or self.carttype == "boring") and state.railstatus.hopper and self.speed == 0 then
|
||||
local hpos = state.railstatus.hopper
|
||||
@ -302,9 +296,26 @@ function cartbase.update(self, dtime)
|
||||
state.speed = 0
|
||||
end
|
||||
|
||||
-- Move the cart
|
||||
if state.speed > 0 then
|
||||
|
||||
-- Move the cart
|
||||
local movedist = state.speed * dtime
|
||||
dbg.v3("Cart moving "..movedist.." at speed "..state.speed.." and dtime "..dtime)
|
||||
local xz = direction_to_xz(state.direction)
|
||||
local axis, oaxis
|
||||
if xz.x ~= 0 then
|
||||
axis = "x"
|
||||
oaxis = "z"
|
||||
else
|
||||
axis = "z"
|
||||
oaxis = "x"
|
||||
end
|
||||
state.movein = false
|
||||
if (xz[axis] > 0 and state.pos[axis] < state.nodepos[axis]) or
|
||||
(xz[axis] < 0 and state.pos[axis] > state.nodepos[axis]) then
|
||||
state.movein = true
|
||||
end
|
||||
|
||||
-- Get the status of the rails at our next location
|
||||
cartbase.get_next_railstatus(self, state, false)
|
||||
local drop = false
|
||||
@ -327,30 +338,14 @@ function cartbase.update(self, dtime)
|
||||
return no_more_slices
|
||||
end
|
||||
|
||||
local movedist = state.speed * dtime
|
||||
local xz = direction_to_xz(state.direction)
|
||||
local axis, oaxis
|
||||
if xz.x ~= 0 then
|
||||
axis = "x"
|
||||
oaxis = "z"
|
||||
else
|
||||
axis = "z"
|
||||
oaxis = "x"
|
||||
end
|
||||
local movein = false
|
||||
if (xz[axis] > 0 and state.pos[axis] < state.nodepos[axis]) or
|
||||
(xz[axis] < 0 and state.pos[axis] > state.nodepos[axis]) then
|
||||
movein = true
|
||||
end
|
||||
|
||||
dbg.v3("Cart on "..state.railstatus.railtype.." at "..minetest.pos_to_string(state.pos)..
|
||||
", dir:"..state.direction.." speed:"..state.speed..
|
||||
" next rail:"..state.nextrailstatus.railtype..
|
||||
" "..(drop and "(drop)" or "")..
|
||||
" "..(movein and "(movein)" or "(moveout)"))
|
||||
" "..(state.movein and "(movein)" or "(moveout)"))
|
||||
|
||||
state.pos[axis] = state.pos[axis] + movedist * xz[axis]
|
||||
if movein then
|
||||
if state.movein then
|
||||
if (xz[axis] > 0 and state.pos[axis] >= state.nodepos[axis]) or
|
||||
(xz[axis] < 0 and state.pos[axis] <= state.nodepos[axis]) then
|
||||
|
||||
@ -362,6 +357,7 @@ function cartbase.update(self, dtime)
|
||||
local detpos = state.railstatus.detector
|
||||
minetest.add_node(detpos, {name="railcarts:cart_detector_on"})
|
||||
mesecon:receptor_on(detpos, mesecon.rules.default)
|
||||
no_more_slices = true
|
||||
dbg.v2("Triggered cart detector at "..minetest.pos_to_string(detpos))
|
||||
end
|
||||
|
||||
@ -490,6 +486,16 @@ function cartbase.update(self, dtime)
|
||||
else
|
||||
--Moving out
|
||||
|
||||
-- Eject a player if necessary - only when moving out, to avoid
|
||||
-- false ejections when the cart will change direction on a
|
||||
-- switch
|
||||
if state.railstatus.eject and self.linkedplayer ~= nil then
|
||||
dbg.v1("Ejecting player from cart")
|
||||
self.linkedplayer:set_detach()
|
||||
self.linkedplayer:setpos(state.pos)
|
||||
self.linkedplayer = nil
|
||||
end
|
||||
|
||||
local newnodepos = vector.round(state.pos)
|
||||
if state.nodepos[axis] ~= newnodepos[axis] then
|
||||
dbg.v3("New nodepos "..newnodepos[axis]..", old "..state.nodepos[axis])
|
||||
@ -502,6 +508,26 @@ function cartbase.update(self, dtime)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
-- speed == 0
|
||||
|
||||
if state.railstatus.onautolauncher and self.linkedplayer ~= nil then
|
||||
dbg.v1("Ejecting player from cart")
|
||||
self.linkedplayer:set_detach()
|
||||
self.linkedplayer:setpos(state.pos)
|
||||
self.linkedplayer = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Set speed/direction from launcher
|
||||
if state.railstatus.launch then
|
||||
cartbase.setdirection(self, state, state.railstatus.launch)
|
||||
state.speed = LAUNCH_CART_SPEED
|
||||
elseif state.railstatus.autolaunch and self.linkedplayer ~= nil then
|
||||
cartbase.setdirection(self, state, state.railstatus.autolaunch)
|
||||
state.speed = LAUNCH_CART_SPEED
|
||||
end
|
||||
|
||||
-- Set ourselves autonomous if necessary (requires minetest patch)
|
||||
@ -528,7 +554,15 @@ end
|
||||
|
||||
--- Get the status of the rails at the next node
|
||||
--@param state The current state, which will have a next_railstatus
|
||||
-- field added. (And only railstatus, pos, speed and direction are relevant)
|
||||
-- field added. (And only railstatus, pos, speed, movein and
|
||||
-- direction are relevant)
|
||||
--
|
||||
-- If movein is true, the track is used to determine the
|
||||
-- outbound direction (e.g. curves, switches)
|
||||
-- If movein is false, the current direction is used instead.
|
||||
-- This is to ensure that movement isn't messed up by the
|
||||
-- track switching underneath the cart.
|
||||
--
|
||||
--@param below True to look below instead of at the same level
|
||||
function cartbase.get_next_railstatus(self, state, below)
|
||||
|
||||
@ -552,7 +586,7 @@ function cartbase.get_next_railstatus(self, state, below)
|
||||
end
|
||||
end
|
||||
|
||||
if is_curve(state.railstatus.railtype) then
|
||||
if is_curve(state.railstatus.railtype) and state.movein then
|
||||
if state.railstatus.railtype == "x+" then
|
||||
if state.direction == 0 or state.direction == 1 then
|
||||
xz = {x=1,z=0}
|
||||
@ -642,7 +676,7 @@ function cartbase.punch_move(self, own_pos, hitterpos)
|
||||
return
|
||||
end
|
||||
|
||||
state = {direction=newdir, speed=1, railstatus=railstatus, pos=self.pos}
|
||||
state = {direction=newdir, speed=1, railstatus=railstatus, pos=self.pos, movein=true}
|
||||
cartbase.get_next_railstatus(self, state, false)
|
||||
if state.nextrailstatus.railtype == "inv" then
|
||||
-- check below, so we can push down a hill
|
||||
@ -684,7 +718,7 @@ function cartbase.on_activate_handler(self, staticdata)
|
||||
self.tag = nil
|
||||
self.wait = 0
|
||||
self.loadwait = 0
|
||||
self.skipnextstep = false
|
||||
self.skipsteps = 0
|
||||
self.lastmove = 0
|
||||
self.dtime_debt = 0
|
||||
|
||||
|
13
items.lua
13
items.lua
@ -1,4 +1,7 @@
|
||||
|
||||
local dbg
|
||||
if moddebug then dbg=moddebug.dbg("railcarts") else dbg={v1=function() end,v2=function() end,v3=function() end} end
|
||||
|
||||
minetest.register_craft({
|
||||
output = "railcarts:cart",
|
||||
recipe = {
|
||||
@ -115,11 +118,10 @@ minetest.register_node(":default:rail", {
|
||||
mesecons = {
|
||||
effector = {
|
||||
rules = railrules,
|
||||
action_on =
|
||||
function(pos, node)
|
||||
action_on = function(pos, node)
|
||||
node.name = "railcarts:rail_switched"
|
||||
minetest.swap_node(pos, node)
|
||||
debug.v2("Rails switched at "..minetest.pos_to_string(pos))
|
||||
dbg.v2("Rails switched at "..minetest.pos_to_string(pos))
|
||||
end
|
||||
}
|
||||
}
|
||||
@ -141,11 +143,10 @@ minetest.register_node("railcarts:rail_switched", {
|
||||
mesecons = {
|
||||
effector = {
|
||||
rules = railrules,
|
||||
action_off =
|
||||
function(pos, node)
|
||||
action_off = function(pos, node)
|
||||
node.name = "default:rail"
|
||||
minetest.swap_node(pos, node)
|
||||
debug.v2("Rails switched back at "..minetest.pos_to_string(pos))
|
||||
dbg.v2("Rails switched back at "..minetest.pos_to_string(pos))
|
||||
end
|
||||
}
|
||||
}
|
||||
|
4
rail.lua
4
rail.lua
@ -107,7 +107,7 @@ end
|
||||
-- that caused the unloaded status
|
||||
-- slope, if the rail is sloped, the up direction, 0-3 (and railtype can only
|
||||
-- be "x" or "z"
|
||||
-- eject, which if true means any player in the cart should be
|
||||
-- eject, which if true means any player in the cart should be ejected
|
||||
-- grab, which if it exists is the position of a node which should 'grab' the
|
||||
-- cart into its inventory (i.e. an autolauncher)
|
||||
-- launch, which is a launch direction
|
||||
@ -238,8 +238,8 @@ function get_railstatus(fppos, direction, speed)
|
||||
end
|
||||
|
||||
if direction then
|
||||
-- Check if a player should be ejected
|
||||
if speed > 0 then
|
||||
-- Check if a player should be ejected
|
||||
if direction == 1 and is_ejector(surrounds.x_next_above) and is_rail(surrounds.x_next) then
|
||||
status.eject = true
|
||||
elseif direction == 3 and is_ejector(surrounds.x_prev_above) and is_rail(surrounds.x_prev) then
|
||||
|
Loading…
x
Reference in New Issue
Block a user