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
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

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({
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
}
}

View File

@ -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