From 1f6038c75a1f928951c8b4513c5c3f7615b78d99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gabriel=20P=C3=A9rez-Cerezo?= <gabriel@gpcf.eu>
Date: Sun, 11 Aug 2019 17:42:30 +0200
Subject: Add decoupling to luaatc

---
 advtrains/trainlogic.lua             | 46 ++++++++++++++++++++----------------
 advtrains_luaautomation/atc_rail.lua | 13 ++++++++++
 2 files changed, 38 insertions(+), 21 deletions(-)

diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua
index 91a67d5..ee1880d 100644
--- a/advtrains/trainlogic.lua
+++ b/advtrains/trainlogic.lua
@@ -892,38 +892,35 @@ function advtrains.spawn_wagons(train_id)
 		end
 	end
 end
-		
 
-function advtrains.split_train_at_wagon(wagon_id)
-	--get train
-	local data = advtrains.wagons[wagon_id]
-	local old_id = data.train_id
-	local train=advtrains.trains[old_id]
+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.
+
+	local train_id=train.id
+	if index > #train.trainparts then
+		-- index specified too long
+		return
+	end
+	local w_id = train.trainparts[index]
+	local data = advtrains.wagons[w_id]
 	local _, wagon = advtrains.get_wagon_prototype(data)
-	
-	if not advtrains.train_ensure_init(old_id, train) then
-		atwarn("Train",old_id,"is not initialized! Operation aborted!")
+	if not advtrains.train_ensure_init(train_id, train) then
+		atwarn("Train",train_id,"is not initialized! Operation aborted!")
 		return
 	end
 	
-	local index=advtrains.path_get_index_by_offset(train, train.index, - data.pos_in_train + wagon.wagon_span)
-	
-	-- find new initial path position for this train
-	local pos, connid, frac = advtrains.path_getrestore(train, index)
-	
-	-- build trainparts table, passing it directly to the train constructor
+	local p_index=advtrains.path_get_index_by_offset(train, train.index, - data.pos_in_train + wagon.wagon_span)
+	local pos, connid, frac = advtrains.path_getrestore(train, p_index)
 	local tp = {}
 	for k,v in ipairs(train.trainparts) do
-		if k >= data.pos_in_trainparts then
+		if k >= index then
 			table.insert(tp, v)
-			train.trainparts[k]=nil
+			train.trainparts[k] = nil
 		end
 	end
-	
-	--update train parts
-	advtrains.update_trainpart_properties(old_id)
+	advtrains.update_trainpart_properties(train_id)
 	recalc_end_index(train)
-	run_callbacks_update(old_id, train)
+	run_callbacks_update(train_id, train)
 	
 	--create subtrain
 	local newtrain_id=advtrains.create_new_train_at(pos, connid, frac, tp)
@@ -931,6 +928,13 @@ function advtrains.split_train_at_wagon(wagon_id)
 	
 	newtrain.velocity=train.velocity
 	return newtrain_id -- return new train ID, so new train can be manipulated
+
+end
+
+function advtrains.split_train_at_wagon(wagon_id)
+	--get train
+	local data = advtrains.wagons[wagon_id]
+	advtrains.split_train_at_index(advtrains.trains[data.train_id], data.pos_in_trainparts)
 end
 
 -- coupling
diff --git a/advtrains_luaautomation/atc_rail.lua b/advtrains_luaautomation/atc_rail.lua
index bc1e00e..89cd2c1 100644
--- a/advtrains_luaautomation/atc_rail.lua
+++ b/advtrains_luaautomation/atc_rail.lua
@@ -53,6 +53,19 @@ function r.fire_event(pos, evtdata)
 			advtrains.atc.train_set_command(train, cmd, atc_arrow)
 			return true
 		end,
+		split_at_index = function(index, cmd)
+			if not train_id then return false end
+			assertt(cmd, "string")
+			if type(index) ~= "number" then
+				return false
+			end
+			local new_id = advtrains.split_train_at_index(train, index)
+			if new_id then
+				minetest.after(1,advtrains.atc.train_set_command,advtrains.trains[new_id], cmd, atc_arrow)
+				return true
+			end
+			return false
+		end,
 		set_line = function(line)
 			if type(line)~="string" and type(line)~="number" then
 				return false
-- 
cgit v1.2.3