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
|
return #match+1
|
||||||
end,
|
end,
|
||||||
["B([0-9]+)"]=function(id, train, match)
|
["B([0-9]+)"]=function(id, train, match)
|
||||||
if train.velocity>tonumber(match) then
|
local btar = tonumber(match)
|
||||||
train.atc_brake_target=tonumber(match)
|
if train.velocity>btar then
|
||||||
if not train.tarvelocity or train.tarvelocity>train.atc_brake_target then
|
train.atc_brake_target=btar
|
||||||
train.tarvelocity=train.atc_brake_target
|
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
|
||||||
end
|
end
|
||||||
return #match+1
|
return #match+1
|
||||||
|
@ -267,6 +273,10 @@ local matchptn={
|
||||||
advtrains.interlocking.ars_set_disable(train, match=="0")
|
advtrains.interlocking.ars_set_disable(train, match=="0")
|
||||||
return 2
|
return 2
|
||||||
end,
|
end,
|
||||||
|
["Cpl"]=function(id, train)
|
||||||
|
train.atc_wait_autocouple=true
|
||||||
|
return 3
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
eval_conditional = function(command, arrow, speed)
|
eval_conditional = function(command, arrow, speed)
|
||||||
|
@ -358,11 +368,13 @@ function atc.execute_atc_command(id, train)
|
||||||
local match=string.match(command, "^"..pattern)
|
local match=string.match(command, "^"..pattern)
|
||||||
if match then
|
if match then
|
||||||
local patlen=func(id, train, match)
|
local patlen=func(id, train, match)
|
||||||
|
--atdebug("Executing: "..string.sub(command, 1, patlen))
|
||||||
atprint("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)
|
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.)
|
--continue (recursive, cmds shouldn't get too long, and it's a end-recursion.)
|
||||||
atc.execute_atc_command(id, train)
|
atc.execute_atc_command(id, train)
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,14 +11,9 @@
|
||||||
-- When the initiating train has autocouple set, trains are immediately coupled
|
-- When the initiating train has autocouple set, trains are immediately coupled
|
||||||
-- When not, a couple entity is spawned and coupling commences on click
|
-- 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:
|
-- 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
|
-- 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
|
-- 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
|
-- 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)
|
-- 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)
|
-- 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
|
-- Depending on autocouple, either couples immediately or spawns a couple entity
|
||||||
function advtrains.couple_initiate_with(init_train, stat_train, stat_is_front)
|
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)
|
--atdebug("Couple init autocouple=",init_train.autocouple,"atc_w_acpl=",init_train.atc_wait_autocouple)
|
||||||
if init_train.autocouple then
|
if init_train.autocouple or init_train.atc_wait_autocouple then
|
||||||
advtrains.couple_trains(init_train, true, stat_train, stat_is_front)
|
advtrains.couple_trains(init_train, false, stat_train, stat_is_front)
|
||||||
|
-- clear atc couple waiting blocker
|
||||||
|
init_train.atc_wait_autocouple = nil
|
||||||
else
|
else
|
||||||
local pos = advtrains.path_get_interpolated(init_train, init_train.index)
|
local pos = advtrains.path_get_interpolated(init_train, init_train.index)
|
||||||
create_couple_entity(pos, init_train, true, stat_train, stat_is_front)
|
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
|
||||||
|
|
||||||
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)
|
wck_t2 = check_twagon_owner(train2, t2_is_front, pname)
|
||||||
end
|
end
|
||||||
if (wck_t1 or wck_t2) or not pname then
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Actually performs the train coupling. Always retains train ID of train1
|
-- Actually performs the train coupling. Always retains train ID of train1
|
||||||
function advtrains.couple_trains(train1, t1_is_front, train2, t2_is_front)
|
function advtrains.couple_trains(init_train, invert_init_train, stat_train, stat_train_opposite)
|
||||||
--atdebug("Couple trains init=",init_train.id,"stat=",stat_train.id,"statreverse=",stat_must_reverse)
|
--atdebug("Couple trains init=",init_train.id,"initinv=",invert_init_train,"stat=",stat_train.id,"statreverse=",stat_train_opposite)
|
||||||
-- 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
|
|
||||||
|
|
||||||
advtrains.do_connect_trains(train1, train2)
|
if not advtrains.train_ensure_init(init_train.id, init_train) then
|
||||||
end
|
atwarn("Coupling: initiating train",init_train.id,"is not initialized! Operation aborted!")
|
||||||
|
|
||||||
-- 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!")
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not advtrains.train_ensure_init(second.id, second) then
|
if not advtrains.train_ensure_init(stat_train.id, stat_train) then
|
||||||
atwarn("Coupling: second train",second.id,"is not initialized! Operation aborted!")
|
atwarn("Coupling: stationary train",stat_train.id,"is not initialized! Operation aborted!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local first_wagoncnt=#first.trainparts
|
-- only used with the couple entity
|
||||||
local second_wagoncnt=#second.trainparts
|
if invert_init_train then
|
||||||
|
advtrains.invert_train(init_train.id)
|
||||||
for _,v in ipairs(second.trainparts) do
|
|
||||||
table.insert(first.trainparts, v)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
advtrains.remove_train(second.id)
|
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
|
||||||
|
|
||||||
first.velocity = 0
|
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
|
||||||
|
|
||||||
advtrains.update_trainpart_properties(first.id)
|
-- TODO: migrate some of the properties from stat_train to init_train?
|
||||||
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
|
return true
|
||||||
end
|
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",
|
"atc_brake_target", "atc_wait_finish", "atc_command", "atc_delay", "door_open",
|
||||||
"text_outside", "text_inside", "line", "routingcode",
|
"text_outside", "text_inside", "line", "routingcode",
|
||||||
"il_sections", "speed_restriction", "is_shunt",
|
"il_sections", "speed_restriction", "is_shunt",
|
||||||
"points_split", "autocouple", "ars_disable",
|
"points_split", "autocouple", "atc_wait_autocouple", "ars_disable",
|
||||||
})
|
})
|
||||||
--then save it
|
--then save it
|
||||||
tmp_trains[id]=v
|
tmp_trains[id]=v
|
||||||
|
|
|
@ -418,9 +418,11 @@ function advtrains.train_step_b(id, train, dtime)
|
||||||
ctrl_lever = userc
|
ctrl_lever = userc
|
||||||
else
|
else
|
||||||
if train.atc_command then
|
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)
|
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
|
train.atc_delay=train.atc_delay-dtime
|
||||||
end
|
end
|
||||||
elseif train.atc_delay then
|
elseif train.atc_delay then
|
||||||
|
@ -711,12 +713,15 @@ function advtrains.train_step_c(id, train, dtime)
|
||||||
if train.ontrack_collision_info then
|
if train.ontrack_collision_info then
|
||||||
train.velocity = 0
|
train.velocity = 0
|
||||||
train.acceleration = 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]
|
local otrn = advtrains.trains[train.ontrack_collision_info.otid]
|
||||||
|
|
||||||
if otrn.velocity == 0 then -- other train must be standing, else don't initiate coupling
|
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)
|
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
|
end
|
||||||
|
|
||||||
train.ontrack_collision_info = nil
|
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
|
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.
|
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:
|
# conditional statements:
|
||||||
|
|
||||||
I<condition><code>;
|
I<condition><code>;
|
||||||
|
|
Loading…
Reference in New Issue