Train Coupling: Change behavior so that train direction of initiating train is kept, add ATC Cpl command
This commit is contained in:
parent
4989da3663
commit
e7d0a5fac2
|
@ -199,10 +199,16 @@ local matchptn={
|
|||
return #match+1
|
||||
end,
|
||||
["B([0-9]+)"]=function(id, train, match)
|
||||
if train.velocity>tonumber(match) then
|
||||
train.atc_brake_target=tonumber(match)
|
||||
if not train.tarvelocity or train.tarvelocity>train.atc_brake_target then
|
||||
train.tarvelocity=train.atc_brake_target
|
||||
local btar = tonumber(match)
|
||||
if train.velocity>btar then
|
||||
train.atc_brake_target=btar
|
||||
if not train.tarvelocity or train.tarvelocity>btar then
|
||||
train.tarvelocity=btar
|
||||
end
|
||||
else
|
||||
-- independent of brake target, must make sure that tarvelocity is not greater than it
|
||||
if train.tarvelocity and train.tarvelocity>btar then
|
||||
train.tarvelocity=btar
|
||||
end
|
||||
end
|
||||
return #match+1
|
||||
|
@ -267,6 +273,10 @@ local matchptn={
|
|||
advtrains.interlocking.ars_set_disable(train, match=="0")
|
||||
return 2
|
||||
end,
|
||||
["Cpl"]=function(id, train)
|
||||
train.atc_wait_autocouple=true
|
||||
return 3
|
||||
end,
|
||||
}
|
||||
|
||||
eval_conditional = function(command, arrow, speed)
|
||||
|
@ -358,11 +368,13 @@ function atc.execute_atc_command(id, train)
|
|||
local match=string.match(command, "^"..pattern)
|
||||
if match then
|
||||
local patlen=func(id, train, match)
|
||||
|
||||
atprint("Executing: "..string.sub(command, 1, patlen))
|
||||
|
||||
--atdebug("Executing: "..string.sub(command, 1, patlen))
|
||||
--atdebug("Train ATC State: tvel=",train.tarvelocity,"brktar=",train.atc_brake_target,"delay=",train.atc_delay,"wfinish=",train.atc_wait_finish,"wacpl=",train.atc_wait_autocouple)
|
||||
|
||||
train.atc_command=string.sub(command, patlen+1)
|
||||
if train.atc_delay<=0 and not train.atc_wait_finish then
|
||||
if train.atc_delay<=0
|
||||
and not train.atc_wait_finish
|
||||
and not train.atc_wait_autocouple then
|
||||
--continue (recursive, cmds shouldn't get too long, and it's a end-recursion.)
|
||||
atc.execute_atc_command(id, train)
|
||||
end
|
||||
|
|
|
@ -11,14 +11,9 @@
|
|||
-- When the initiating train has autocouple set, trains are immediately coupled
|
||||
-- When not, a couple entity is spawned and coupling commences on click
|
||||
-- Coupling MUST preserve the train ID of the initiating train, so it is done like this:
|
||||
-- initiating train is reversed
|
||||
-- stationary train is reversed if required, so that it points towards the initiating train
|
||||
-- do_connect_trains(initiating, stationary)
|
||||
-- As a result, the coupled train is reversed in direction. Alternative way of doing things (might be considered later):
|
||||
-- stationary train is reversed if required, so that it points away from the initiating train
|
||||
-- index of initiating train is set so that it matches the front pos of stationary train
|
||||
-- wagons of stationary train are inserted at the beginning of initiating train
|
||||
-- remove stationary train
|
||||
-- wagons of stationary train are inserted at the beginning of initiating train (considers direction of stat_train and inserts reverse if required)
|
||||
|
||||
-- train.couple_* contain references to ObjectRefs of couple objects, which contain all relevant information
|
||||
-- These objectRefs will delete themselves once the couples no longer match (see below)
|
||||
|
@ -142,12 +137,16 @@ end
|
|||
-- Called from train_step_b() when the current train (init_train) just stopped at one of the end indices of another train (stat_train)
|
||||
-- Depending on autocouple, either couples immediately or spawns a couple entity
|
||||
function advtrains.couple_initiate_with(init_train, stat_train, stat_is_front)
|
||||
--atdebug("Initiating couplign between init=",init_train.id,"stat=",stat_train.id,"backside=",stat_is_backside)
|
||||
if init_train.autocouple then
|
||||
advtrains.couple_trains(init_train, true, stat_train, stat_is_front)
|
||||
--atdebug("Couple init autocouple=",init_train.autocouple,"atc_w_acpl=",init_train.atc_wait_autocouple)
|
||||
if init_train.autocouple or init_train.atc_wait_autocouple then
|
||||
advtrains.couple_trains(init_train, false, stat_train, stat_is_front)
|
||||
-- clear atc couple waiting blocker
|
||||
init_train.atc_wait_autocouple = nil
|
||||
else
|
||||
local pos = advtrains.path_get_interpolated(init_train, init_train.index)
|
||||
create_couple_entity(pos, init_train, true, stat_train, stat_is_front)
|
||||
-- clear ATC command on collision
|
||||
advtrains.atc.train_reset_command(init_train)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -177,50 +176,61 @@ function advtrains.safe_couple_trains(train1, t1_is_front, train2, t2_is_front,
|
|||
wck_t2 = check_twagon_owner(train2, t2_is_front, pname)
|
||||
end
|
||||
if (wck_t1 or wck_t2) or not pname then
|
||||
advtrains.couple_trains(train1, t1_is_front, train2, t2_is_front)
|
||||
advtrains.couple_trains(train1, not t1_is_front, train2, t2_is_front)
|
||||
end
|
||||
end
|
||||
|
||||
-- Actually performs the train coupling. Always retains train ID of train1
|
||||
function advtrains.couple_trains(train1, t1_is_front, train2, t2_is_front)
|
||||
--atdebug("Couple trains init=",init_train.id,"stat=",stat_train.id,"statreverse=",stat_must_reverse)
|
||||
-- see comment on top of file
|
||||
if t1_is_front then
|
||||
advtrains.invert_train(train1.id)
|
||||
end
|
||||
if not t2_is_front then
|
||||
advtrains.invert_train(train2.id)
|
||||
end
|
||||
function advtrains.couple_trains(init_train, invert_init_train, stat_train, stat_train_opposite)
|
||||
--atdebug("Couple trains init=",init_train.id,"initinv=",invert_init_train,"stat=",stat_train.id,"statreverse=",stat_train_opposite)
|
||||
|
||||
advtrains.do_connect_trains(train1, train2)
|
||||
end
|
||||
|
||||
-- Adds the wagons of first to second and deletes second_id afterwards
|
||||
-- Assumes that second_id stands right behind first_id and both trains point to the same direction
|
||||
function advtrains.do_connect_trains(first, second)
|
||||
|
||||
if not advtrains.train_ensure_init(first.id, first) then
|
||||
atwarn("Coupling: first train",first.id,"is not initialized! Operation aborted!")
|
||||
if not advtrains.train_ensure_init(init_train.id, init_train) then
|
||||
atwarn("Coupling: initiating train",init_train.id,"is not initialized! Operation aborted!")
|
||||
return
|
||||
end
|
||||
if not advtrains.train_ensure_init(second.id, second) then
|
||||
atwarn("Coupling: second train",second.id,"is not initialized! Operation aborted!")
|
||||
if not advtrains.train_ensure_init(stat_train.id, stat_train) then
|
||||
atwarn("Coupling: stationary train",stat_train.id,"is not initialized! Operation aborted!")
|
||||
return
|
||||
end
|
||||
|
||||
local first_wagoncnt=#first.trainparts
|
||||
local second_wagoncnt=#second.trainparts
|
||||
|
||||
for _,v in ipairs(second.trainparts) do
|
||||
table.insert(first.trainparts, v)
|
||||
end
|
||||
|
||||
advtrains.remove_train(second.id)
|
||||
|
||||
first.velocity = 0
|
||||
-- only used with the couple entity
|
||||
if invert_init_train then
|
||||
advtrains.invert_train(init_train.id)
|
||||
end
|
||||
|
||||
local itp = init_train.trainparts
|
||||
local init_wagoncnt = #itp
|
||||
local stp = stat_train.trainparts
|
||||
local stat_wagoncnt = #stp
|
||||
local stat_trainlen = stat_train.trainlen -- save the train length of stat train, to be added to index
|
||||
|
||||
if stat_train_opposite then
|
||||
-- insert wagons in inverse order and set their wagon_flipped state
|
||||
for i=1,stat_wagoncnt do
|
||||
table.insert(itp, 1, stp[i])
|
||||
local wdata = advtrains.wagons[stp[i]]
|
||||
if wdata then
|
||||
wdata.wagon_flipped = not wdata.wagon_flipped
|
||||
else
|
||||
atwarn("While coupling, wagon",stp[i],"of stationary train",stat_train.id,"not found!")
|
||||
end
|
||||
end
|
||||
else
|
||||
--insert wagons in normal order
|
||||
for i=stat_wagoncnt,1,-1 do
|
||||
table.insert(itp, 1, stp[i])
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO: migrate some of the properties from stat_train to init_train?
|
||||
|
||||
advtrains.update_trainpart_properties(first.id)
|
||||
advtrains.couple_invalidate(first)
|
||||
advtrains.remove_train(stat_train.id)
|
||||
|
||||
-- Set train index forward
|
||||
init_train.index = advtrains.path_get_index_by_offset(init_train, init_train.index, stat_trainlen)
|
||||
|
||||
advtrains.update_trainpart_properties(init_train.id)
|
||||
advtrains.couple_invalidate(init_train)
|
||||
return true
|
||||
end
|
||||
|
||||
|
|
|
@ -468,7 +468,7 @@ advtrains.avt_save = function(remove_players_from_wagons)
|
|||
"atc_brake_target", "atc_wait_finish", "atc_command", "atc_delay", "door_open",
|
||||
"text_outside", "text_inside", "line", "routingcode",
|
||||
"il_sections", "speed_restriction", "is_shunt",
|
||||
"points_split", "autocouple", "ars_disable",
|
||||
"points_split", "autocouple", "atc_wait_autocouple", "ars_disable",
|
||||
})
|
||||
--then save it
|
||||
tmp_trains[id]=v
|
||||
|
|
|
@ -418,9 +418,11 @@ function advtrains.train_step_b(id, train, dtime)
|
|||
ctrl_lever = userc
|
||||
else
|
||||
if train.atc_command then
|
||||
if (not train.atc_delay or train.atc_delay<=0) and not train.atc_wait_finish then
|
||||
if (not train.atc_delay or train.atc_delay<=0)
|
||||
and not train.atc_wait_finish
|
||||
and not train.atc_wait_autocouple then
|
||||
advtrains.atc.execute_atc_command(id, train)
|
||||
else
|
||||
elseif train.atc_delay and train.atc_delay > 0 then
|
||||
train.atc_delay=train.atc_delay-dtime
|
||||
end
|
||||
elseif train.atc_delay then
|
||||
|
@ -711,12 +713,15 @@ function advtrains.train_step_c(id, train, dtime)
|
|||
if train.ontrack_collision_info then
|
||||
train.velocity = 0
|
||||
train.acceleration = 0
|
||||
advtrains.atc.train_reset_command(train)
|
||||
--advtrains.atc.train_reset_command(train) will occur in couple_initiate_with if required
|
||||
|
||||
local otrn = advtrains.trains[train.ontrack_collision_info.otid]
|
||||
|
||||
if otrn.velocity == 0 then -- other train must be standing, else don't initiate coupling
|
||||
advtrains.couple_initiate_with(train, otrn, not train.ontrack_collision_info.same_dir)
|
||||
else
|
||||
-- other collision - stop any ATC control
|
||||
advtrains.atc.train_reset_command(train)
|
||||
end
|
||||
|
||||
train.ontrack_collision_info = nil
|
||||
|
|
|
@ -51,6 +51,10 @@ Kick all passengers out of the trains
|
|||
This command kicks all passengers (non-driving players) off the train. This command works only
|
||||
if the train is stopped and its doors are open.
|
||||
|
||||
Cpl
|
||||
Temporarily switch the train to "Autocouple" mode and wait for coupling.
|
||||
This command makes the train continue at its current speed until it hits another standing wagon or train. Then, it couples to this train and ATC command execution continues.
|
||||
|
||||
# conditional statements:
|
||||
|
||||
I<condition><code>;
|
||||
|
|
Loading…
Reference in New Issue