aboutsummaryrefslogtreecommitdiff
path: root/assets/blender/ks
diff options
context:
space:
mode:
authororwell96 <orwell@bleipb.de>2019-01-22 23:16:26 +0100
committerorwell96 <orwell@bleipb.de>2019-01-22 23:16:26 +0100
commit2b871069617383eaa1c7d4fb89ccab766c9f68b0 (patch)
treee7dbd54957b1ddd7bfcbe4899bf87bf9aa96fb0b /assets/blender/ks
parent9bdddb619b3872285e6d335e62854de3360178b4 (diff)
downloadadvtrains-2b871069617383eaa1c7d4fb89ccab766c9f68b0.tar.gz
advtrains-2b871069617383eaa1c7d4fb89ccab766c9f68b0.tar.bz2
advtrains-2b871069617383eaa1c7d4fb89ccab766c9f68b0.zip
Make LZB params adjustable
Diffstat (limited to 'assets/blender/ks')
0 files changed, 0 insertions, 0 deletions
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
-- atc_rail.lua
-- registers and handles the ATC rail. Active component.
-- This is the only component that can interface with trains, so train interface goes here too.

--Using subtable
local r={}

-- Note on appr_internal:
-- The Approach callback is a special corner case: the train is not on the node, and it is executed synchronized 
-- (in the train step right during LZB traversal). We therefore need access to the train id and the lzbdata table
function r.fire_event(pos, evtdata, appr_internal)
	
	local ph=minetest.pos_to_string(pos)
	local railtbl = atlatc.active.nodes[ph]
	
	if not railtbl then
		atwarn("LuaATC interface rail at",ph,": Data not in memory! Please visit position and click 'Save'!")
		return
	end
	
	--prepare ingame API for ATC. Regenerate each time since pos needs to be known
	--If no train, then return false.
	
	-- try to get the train from the event data
	-- This workaround is required because the callback is one step delayed, and a fast train may have already left the node.
	-- Also used for approach callback
	local train_id = evtdata._train_id
	local atc_arrow = evtdata._train_arrow
	local train, tvel
	
	if train_id then
		train=advtrains.trains[train_id]
		-- speed
		tvel=train.velocity
	-- if still no train_id available, try to get the train at my position
	else
		train_id=advtrains.get_train_at_pos(pos)
		if train_id then
			train=advtrains.trains[train_id]
			advtrains.train_ensure_init(train_id, train)
			-- look up atc_arrow
			local index = advtrains.path_lookup(train, pos)
			atc_arrow = (train.path_cn[index] == 1)
			-- speed
			tvel=train.velocity
		end
	end
	
	local customfct={
		atc_send = function(cmd)
			if not train_id then return false end
			assertt(cmd, "string")
			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" or index < 2 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,
		split_at_fc = function(cmd, len)
			assertt(cmd, "string")
			if not train_id then return false end
			local new_id, fc = advtrains.split_train_at_fc(train, false, len)
			if new_id then
				minetest.after(1,advtrains.atc.train_set_command,advtrains.trains[new_id], cmd, atc_arrow)
			end
			return fc or ""
		end,
		split_off_locomotive = function(cmd, len)
			assertt(cmd, "string")
			if not train_id then return false end
			local new_id, fc = advtrains.split_train_at_fc(train, true, len)
			if new_id then
				minetest.after(1,advtrains.atc.train_set_command,advtrains.trains[new_id], cmd, atc_arrow)
			end						
		end,
		train_length = function ()
			if not train_id then return false end
			return #train.trainparts
		end,
		step_fc = function()
			if not train_id then return false end
			advtrains.train_step_fc(train)
		end,
		get_fc = function()
			if not train_id then return end
			local fc_list = {}
			for index,wagon_id in ipairs(train.trainparts) do
				fc_list[index] = table.concat(advtrains.wagons[wagon_id].fc,"!") or ""
			end
			return fc_list
		end,
		set_fc = function(fc_list,reset_index)
			assertt(fc_list, "table")
			if not train_id then return false end
			-- safety type-check for entered values
			for _,v in ipairs(fc_list) do
				if v and type(v) ~= "string" then
					error("FC entries must be a string")
					return
				end
			end
			for index,wagon_id in ipairs(train.trainparts) do
				if fc_list[index] then -- has FC to enter to this wagon
					local data = advtrains.wagons[wagon_id]
					if data then -- wagon actually exists
						--effectively copyied from wagons.lua, allowing for the :split function and reset_index
						data.fc = fc_list[index]:split("!")
						if reset_index or not data.fcind then
							data.fcind = 1
						elseif data.fcind > #data.fc then
							data.fcind = #data.fc
						end
					end
				end
			end
		end,
		set_shunt = function()
			-- enable shunting mode
			if not train_id then return false end
			train.is_shunt = true
		end,
		unset_shunt = function()
			if not train_id then return false end
			train.is_shunt = nil
		end,
		set_autocouple = function ()
			if not train_id then return false end
			train.autocouple = true			
		end,
		unset_autocouple = function ()
			if not train_id then return false end
			train.autocouple = nil
 		end,
		set_line = function(line)
			if type(line)~="string" and type(line)~="number" then
				return false
			end
			train.line = line .. ""
			minetest.after(0, advtrains.invalidate_path, train_id)
			return true
		end,
		get_line = function()
			return train.line
		end,
		set_rc = function(rc)
			if type(rc)~="string"then
				return false
			end
			train.routingcode = rc
			minetest.after(0, advtrains.invalidate_path, train_id)
			return true
		end,
		get_rc = function()
			return train.routingcode
		end,
		atc_reset = function()
			if not train_id then return false end
			advtrains.atc.train_reset_command(train)
			return true
		end,
		atc_arrow = atc_arrow,
		atc_id = train_id,
		atc_speed = tvel,
		atc_set_text_outside = function(text)
			if not train_id then return false end
			if text then assertt(text, "string") end
			advtrains.trains[train_id].text_outside=text
			return true
		end,
		atc_set_text_inside = function(text)
			if not train_id then return false end
			if text then assertt(text, "string") end
			advtrains.trains[train_id].text_inside=text
			return true
		end,
		atc_get_text_outside = function()
			if not train_id then return false end
			return advtrains.trains[train_id].text_outside
		end,
		atc_get_text_inside = function(text)
			if not train_id then return false end
			return advtrains.trains[train_id].text_inside
		end,
		atc_set_lzb_tsr = function(speed)
			if not appr_internal then
				error("atc_set_lzb_tsr() can only be used during 'approach' events!")
			end
			assert(tonumber(speed), "Number expected!")
			
			local index = appr_internal.index
			advtrains.lzb_add_checkpoint(train, index, speed, nil)
			
			return true
		end,
	}
	-- interlocking specific
	if advtrains.interlocking then
		customfct.atc_set_ars_disable = function(value)
			advtrains.interlocking.ars_set_disable(train, value)
		end
	end
	
	atlatc.active.run_in_env(pos, evtdata, customfct)
	
end

advtrains.register_tracks("default", {
	nodename_prefix="advtrains_luaautomation:dtrack",
	texture_prefix="advtrains_dtrack_atc",
	models_prefix="advtrains_dtrack",
	models_suffix=".b3d",
	shared_texture="advtrains_dtrack_shared_atc.png",
	description=atltrans("LuaATC Rail"),
	formats={},
	get_additional_definiton = function(def, preset, suffix, rotation)
		return {
			after_place_node = atlatc.active.after_place_node,
			after_dig_node = atlatc.active.after_dig_node,

			on_receive_fields = function(pos, ...)
				atlatc.active.on_receive_fields(pos, ...)
				
				--set arrowconn (for ATC)
				local ph=minetest.pos_to_string(pos)
				local _, conns=advtrains.get_rail_info_at(pos, advtrains.all_tracktypes)
				local nodeent = atlatc.active.nodes[ph]
				if nodeent then
					nodeent.arrowconn=conns[1].c
				end
			end,

			advtrains = {
				on_train_enter = function(pos, train_id, train, index)
					--do async. Event is fired in train steps
					atlatc.interrupt.add(0, pos, {type="train", train=true, id=train_id,
							_train_id = train_id, _train_arrow = (train.path_cn[index] == 1)})
				end,
				on_train_approach = function(pos, train_id, train, index, has_entered, lzbdata)
					-- Insert an event only if the rail indicated that it supports approach callbacks
					local ph=minetest.pos_to_string(pos)
					local railtbl = atlatc.active.nodes[ph]
					-- uses a "magic variable" in the local environment of the node
					-- This hack is necessary because code might not be prepared to get approach events...
					if railtbl and railtbl.data and railtbl.data.__approach_callback_mode then
						local acm = railtbl.data.__approach_callback_mode
						local in_arrow = (train.path_cn[index] == 1)
						if acm==2 or (acm==1 and in_arrow) then
							local evtdata = {type="approach", approach=true, id=train_id, has_entered = has_entered,
									_train_id = train_id, _train_arrow = in_arrow} -- reuses code from train_enter
							-- This event is *required* to run synchronously, because it might set the ars_disable flag on the train and add LZB checkpoints,
							-- although this is generally discouraged because this happens right in a train step
							-- At this moment, I am not aware whether this may cause side effects, and I must encourage users not to do expensive calculations here.
							r.fire_event(pos, evtdata, {train_id = train_id, train = train, index = index, lzbdata = lzbdata})
						end
					end
				end,
			},
			luaautomation = {
				fire_event=r.fire_event
			},
			digiline = {
				receptor = {},
				effector = {
					action = atlatc.active.on_digiline_receive
				},
			},
		}
	end,
}, advtrains.trackpresets.t_30deg_straightonly)


atlatc.rail = r