From c54e0b341a88349e1a4fc7d902fdd9d9e1a6040d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20P=C3=A9rez-Cerezo?= Date: Sun, 26 Jul 2020 21:07:47 +0200 Subject: [PATCH] add split_train_at_fc luaatc command This command splits the train at the second non-empty FC it encounters, taking with it the first few freight cars that all go to the same destination. --- advtrains/trainlogic.lua | 35 +++++++++++++- advtrains/wagons.lua | 72 +++++++++++++++++++++------- advtrains_luaautomation/atc_rail.lua | 9 ++++ 3 files changed, 98 insertions(+), 18 deletions(-) diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua index 3e57db2..1bda0f2 100644 --- a/advtrains/trainlogic.lua +++ b/advtrains/trainlogic.lua @@ -892,6 +892,36 @@ function advtrains.spawn_wagons(train_id) end end +function advtrains.split_train_at_fc(train) + -- splits train at first different current FC + local train_id = train.id + local fc = false + local ind = 0 + for i = 1, #train.trainparts do + local w_id = train.trainparts[i] + local data = advtrains.wagons[w_id] + if data then + local wfc = advtrains.get_cur_fc(data) + if wfc ~= "" then + if fc then + if fc ~= wfc then + ind = i + break + end + else + fc = wfc + end + end + end + end + if ind > 0 then + return advtrains.split_train_at_index(train, ind), fc + end + if fc then + return nil, fc + end +end + function advtrains.split_train_at_index(train, index) -- this function splits a train at index, creating a new train from the back part of the train. @@ -1080,7 +1110,10 @@ function advtrains.do_connect_trains(first_id, second_id, vel) end advtrains.remove_train(second_id) - + if vel < 0 then + advtrains.invert_train(first_id) + vel = -vel + end first.velocity= vel or 0 advtrains.update_trainpart_properties(first_id) diff --git a/advtrains/wagons.lua b/advtrains/wagons.lua index 873e22d..d805bc6 100644 --- a/advtrains/wagons.lua +++ b/advtrains/wagons.lua @@ -826,9 +826,7 @@ function wagon:show_wagon_properties(pname) local cur = data.fc[data.fcind] or "" form=form.."label[1.5,3.75;"..cur.."]" - if data.fcind < #data.fc then - form=form.."button[3.5,3.5;1,1;fcn;next FC]" - end + form=form.."button[3.5,3.5;1,1;fcn;next FC]" end form=form.."button_exit[0.5,4.5;4,1;save;"..attrans("Save wagon properties").."]" minetest.show_formspec(pname, "advtrains_prop_"..self.id, form) @@ -851,12 +849,62 @@ local function checklock(pname, own1, own2, wl1, wl2) end function string:split(sep) - local sep, fields = sep or ":", {} + local fields = {} local pattern = string.format("([^%s]+)", sep) self:gsub(pattern, function(c) fields[#fields+1] = c end) return fields end +function wagon.set_fc(data, fcstr) + data.fc = string.split(fcstr, "!") + if not data.fcind then + data.fcind = 1 + elseif data.fcind > #data.fc then + data.fcind = #data.fc + end +end + +function wagon.prev_fc(data) + if data.fcind > 1 then + data.fcind = data.fcind -1 + end + if data.fcind == 1 and data.fcrev then + data.fcrev = nil + end +end + +function wagon.next_fc(data) + if data.fcrev then + wagon.prev_fc(data) + return + end + if data.fcind < #data.fc then + data.fcind = data.fcind + 1 + else + data.fcind = 1 + end + if data.fcind == #data.fc and data.fc[data.fcind] == "?" then + data.fcrev = true + wagon.prev_fc(data) + return + end +end + +function advtrains.get_cur_fc(data) + if not ( data.fc and data.fcind ) then + return "" + end + return data.fc[data.fcind] or "" +end + +function advtrains.step_fc(data) + wagon.next_fc(data) +end + + + + + function wagon:show_bordcom(pname) if not self:train() then return end local train = self:train() @@ -1072,24 +1120,14 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) data.roadnumber = fields.roadnumber end if fields.fc then - data.fc = string.split(fields.fc, "!") - if not data.fcind then - data.fcind = 1 - elseif data.fcind > #data.fc then - data.fcind = #data.fc - end + wagon.set_fc(data, fields.fc) end if fields.fcp then - if data.fcind > 1 then - data.fcind = data.fcind - 1 - end + wagon.prev_fc(data) wagon.show_wagon_properties({id=uid}, pname) end if fields.fcn then - if data.fcind < #data.fc then - minetest.chat_send_all(data.fcind) - data.fcind = data.fcind + 1 - end + wagon.next_fc(data) wagon.show_wagon_properties({id=uid}, pname) end end diff --git a/advtrains_luaautomation/atc_rail.lua b/advtrains_luaautomation/atc_rail.lua index 0b9c911..69c519a 100644 --- a/advtrains_luaautomation/atc_rail.lua +++ b/advtrains_luaautomation/atc_rail.lua @@ -66,6 +66,15 @@ function r.fire_event(pos, evtdata) end return false end, + split_at_fc = function(cmd) + assertt(cmd, "string") + if not train_id then return false end + local new_id, fc = advtrains.split_train_at_fc(train) + if new_id then + minetest.after(1,advtrains.atc.train_set_command,advtrains.trains[new_id], cmd, atc_arrow) + end + return fc + end, set_shunt = function() if not train_id then return false end train.autocouple = true