A few fixes and tweaks

This commit is contained in:
Ciaran Gultnieks 2014-05-21 18:30:31 +01:00
parent 2efd6cbd55
commit ebdbf22191
3 changed files with 97 additions and 62 deletions

View File

@ -55,8 +55,9 @@ end
--@param dtime Time since last call, in seconds --@param dtime Time since last call, in seconds
function cartbase.on_step_handler(self, dtime) function cartbase.on_step_handler(self, dtime)
if self.skipnextstep then if self.skipsteps > 0 then
self.skipnextstep = false dbg.v3("Skipping step")
self.skipsteps = self.skipsteps -1
self.dtime_debt = self.dtime_debt + dtime self.dtime_debt = self.dtime_debt + dtime
return return
end 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} oldpos = {x=self.pos.x, y=self.pos.y, z=self.pos.z}
end 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 -- 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 -- it goes wrong if it happens twice (i.e. very fast over two close
-- together curves) -- together curves)
@ -112,7 +117,7 @@ function cartbase.on_step_handler(self, dtime)
end end
end end
if dtime >= 0 and not nomore then if dtime > 0 and not nomore then
nomore = cartbase.update(self, dtime) nomore = cartbase.update(self, dtime)
dtime = 0 dtime = 0
end end
@ -120,7 +125,9 @@ function cartbase.on_step_handler(self, dtime)
-- TODO - seeing if skipping an extra step resolves the mesecons -- TODO - seeing if skipping an extra step resolves the mesecons
-- delay which occasionally causes rails to not be switched -- delay which occasionally causes rails to not be switched
-- in time -- 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 end
self.dtime_debt = dtime self.dtime_debt = dtime
@ -146,15 +153,20 @@ end
--- Handle update for a cart. --- Handle update for a cart.
--@param self The cart -- @param self The cart
--@param dtime Time since last call, in seconds, which should always be within -- @param dtime Time since last call, in seconds, which should always be
-- low enough that the cart doesn't >= 0.5 nodes. -- low enough that the cart doesn't move >= 0.5 nodes.
--@return True if something happened which means no further step slices should -- @return True if something happened which means no further step slices should
-- be processed during this step. (Currently, this is specifically only -- be processed during this step. (Currently, this is specifically only
-- when a digiline message is sent, because a common usage of that is -- when a digiline message is sent, because a common usage of that is
-- to pass information to a luacontroller, which then uses mesecons to -- to pass information to a luacontroller, which then uses mesecons to
-- switch a rail. This will not necessarily have happened until the next -- switch a rail. This will not necessarily have happened until the next
-- server step - and hopefully by then!) -- 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) function cartbase.update(self, dtime)
local no_more_slices = false local no_more_slices = false
@ -190,15 +202,6 @@ function cartbase.update(self, dtime)
return no_more_slices return no_more_slices
end 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 -- Grab the cart into something's inventory if necessary
-- (only allowed when there is no passenger or cargo) -- (only allowed when there is no passenger or cargo)
if state.railstatus.grab and cartbase.is_empty(self) then if state.railstatus.grab and cartbase.is_empty(self) then
@ -217,15 +220,6 @@ function cartbase.update(self, dtime)
return no_more_slices return no_more_slices
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
-- Handle loading/unloading from/to a hopper -- Handle loading/unloading from/to a hopper
if (self.carttype == "cargo" or self.carttype == "boring") and state.railstatus.hopper and self.speed == 0 then if (self.carttype == "cargo" or self.carttype == "boring") and state.railstatus.hopper and self.speed == 0 then
local hpos = state.railstatus.hopper local hpos = state.railstatus.hopper
@ -302,9 +296,26 @@ function cartbase.update(self, dtime)
state.speed = 0 state.speed = 0
end end
-- Move the cart
if state.speed > 0 then 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 -- Get the status of the rails at our next location
cartbase.get_next_railstatus(self, state, false) cartbase.get_next_railstatus(self, state, false)
local drop = false local drop = false
@ -327,30 +338,14 @@ function cartbase.update(self, dtime)
return no_more_slices return no_more_slices
end 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).. dbg.v3("Cart on "..state.railstatus.railtype.." at "..minetest.pos_to_string(state.pos)..
", dir:"..state.direction.." speed:"..state.speed.. ", dir:"..state.direction.." speed:"..state.speed..
" next rail:"..state.nextrailstatus.railtype.. " next rail:"..state.nextrailstatus.railtype..
" "..(drop and "(drop)" or "").. " "..(drop and "(drop)" or "")..
" "..(movein and "(movein)" or "(moveout)")) " "..(state.movein and "(movein)" or "(moveout)"))
state.pos[axis] = state.pos[axis] + movedist * xz[axis] 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 if (xz[axis] > 0 and state.pos[axis] >= state.nodepos[axis]) or
(xz[axis] < 0 and state.pos[axis] <= state.nodepos[axis]) then (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 local detpos = state.railstatus.detector
minetest.add_node(detpos, {name="railcarts:cart_detector_on"}) minetest.add_node(detpos, {name="railcarts:cart_detector_on"})
mesecon:receptor_on(detpos, mesecon.rules.default) mesecon:receptor_on(detpos, mesecon.rules.default)
no_more_slices = true
dbg.v2("Triggered cart detector at "..minetest.pos_to_string(detpos)) dbg.v2("Triggered cart detector at "..minetest.pos_to_string(detpos))
end end
@ -490,6 +486,16 @@ function cartbase.update(self, dtime)
else else
--Moving out --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) local newnodepos = vector.round(state.pos)
if state.nodepos[axis] ~= newnodepos[axis] then if state.nodepos[axis] ~= newnodepos[axis] then
dbg.v3("New nodepos "..newnodepos[axis]..", old "..state.nodepos[axis]) dbg.v3("New nodepos "..newnodepos[axis]..", old "..state.nodepos[axis])
@ -502,6 +508,26 @@ function cartbase.update(self, dtime)
end end
end 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 end
-- Set ourselves autonomous if necessary (requires minetest patch) -- Set ourselves autonomous if necessary (requires minetest patch)
@ -528,7 +554,15 @@ end
--- Get the status of the rails at the next node --- Get the status of the rails at the next node
--@param state The current state, which will have a next_railstatus --@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 --@param below True to look below instead of at the same level
function cartbase.get_next_railstatus(self, state, below) function cartbase.get_next_railstatus(self, state, below)
@ -552,7 +586,7 @@ function cartbase.get_next_railstatus(self, state, below)
end end
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.railstatus.railtype == "x+" then
if state.direction == 0 or state.direction == 1 then if state.direction == 0 or state.direction == 1 then
xz = {x=1,z=0} xz = {x=1,z=0}
@ -642,7 +676,7 @@ function cartbase.punch_move(self, own_pos, hitterpos)
return return
end 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) cartbase.get_next_railstatus(self, state, false)
if state.nextrailstatus.railtype == "inv" then if state.nextrailstatus.railtype == "inv" then
-- check below, so we can push down a hill -- check below, so we can push down a hill
@ -684,7 +718,7 @@ function cartbase.on_activate_handler(self, staticdata)
self.tag = nil self.tag = nil
self.wait = 0 self.wait = 0
self.loadwait = 0 self.loadwait = 0
self.skipnextstep = false self.skipsteps = 0
self.lastmove = 0 self.lastmove = 0
self.dtime_debt = 0 self.dtime_debt = 0

View File

@ -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({ minetest.register_craft({
output = "railcarts:cart", output = "railcarts:cart",
recipe = { recipe = {
@ -115,11 +118,10 @@ minetest.register_node(":default:rail", {
mesecons = { mesecons = {
effector = { effector = {
rules = railrules, rules = railrules,
action_on = action_on = function(pos, node)
function(pos, node)
node.name = "railcarts:rail_switched" node.name = "railcarts:rail_switched"
minetest.swap_node(pos, node) 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 end
} }
} }
@ -141,11 +143,10 @@ minetest.register_node("railcarts:rail_switched", {
mesecons = { mesecons = {
effector = { effector = {
rules = railrules, rules = railrules,
action_off = action_off = function(pos, node)
function(pos, node)
node.name = "default:rail" node.name = "default:rail"
minetest.swap_node(pos, node) 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 end
} }
} }

View File

@ -107,7 +107,7 @@ end
-- that caused the unloaded status -- that caused the unloaded status
-- slope, if the rail is sloped, the up direction, 0-3 (and railtype can only -- slope, if the rail is sloped, the up direction, 0-3 (and railtype can only
-- be "x" or "z" -- 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 -- grab, which if it exists is the position of a node which should 'grab' the
-- cart into its inventory (i.e. an autolauncher) -- cart into its inventory (i.e. an autolauncher)
-- launch, which is a launch direction -- launch, which is a launch direction
@ -238,8 +238,8 @@ function get_railstatus(fppos, direction, speed)
end end
if direction then if direction then
-- Check if a player should be ejected
if speed > 0 then 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 if direction == 1 and is_ejector(surrounds.x_next_above) and is_rail(surrounds.x_next) then
status.eject = true status.eject = true
elseif direction == 3 and is_ejector(surrounds.x_prev_above) and is_rail(surrounds.x_prev) then elseif direction == 3 and is_ejector(surrounds.x_prev_above) and is_rail(surrounds.x_prev) then