Start changing APIs and applying proof-of-concept to ks signals
This commit is contained in:
parent
aa9033f901
commit
2dab59f055
|
@ -12,7 +12,7 @@ end
|
|||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname()) .. DIR_DELIM
|
||||
|
||||
advtrains.interlocking.aspect = dofile(modpath.."aspect.lua")
|
||||
--advtrains.interlocking.aspect = dofile(modpath.."aspect.lua")
|
||||
|
||||
dofile(modpath.."database.lua")
|
||||
dofile(modpath.."distant.lua")
|
||||
|
|
|
@ -2,18 +2,19 @@
|
|||
|
||||
local F = advtrains.formspec
|
||||
|
||||
local DANGER = {
|
||||
local signal = {}
|
||||
|
||||
signal.MASP_HALT = {
|
||||
name = "halt"
|
||||
halt = true,
|
||||
}
|
||||
|
||||
signal.ASPI_HALT = {
|
||||
main = 0,
|
||||
shunt = false,
|
||||
}
|
||||
advtrains.interlocking.DANGER = DANGER
|
||||
|
||||
advtrains.interlocking.GENERIC_FREE = {
|
||||
main = -1,
|
||||
shunt = false,
|
||||
dst = false,
|
||||
}
|
||||
advtrains.interlocking.FULL_FREE = {
|
||||
signal.ASPI_FREE = {
|
||||
main = -1,
|
||||
shunt = false,
|
||||
proceed_as_main = true,
|
||||
|
@ -25,14 +26,12 @@ Most parts of ywang's implementation are fine, especially I like the formspecs.
|
|||
- Signal gets distant assigned via field in signal aspect table (instead of explicitly)
|
||||
- Signal speed/shunt are no longer free-text but rather they need to be predefined in the node definition
|
||||
To do this: Differentiation between:
|
||||
== Aspect Group ==
|
||||
== Main Aspect ==
|
||||
This is what a signal is assigned by either the route system or the user.
|
||||
It is a string key which has an appropriate entry in the node definition (where it has a description assigned)
|
||||
The signal mod defines a function to set a signal to the most appropriate aspect. This function gets
|
||||
a) the aspect group name
|
||||
a) the main aspect table (straight from node def)
|
||||
b) the distant signal's aspect group name & aspect table
|
||||
EVERY signal must define the special aspect group "halt". This must always be the most restrictive aspect possible.
|
||||
The "halt" aspect group should ignore any distant info, in most cases it is called without them anyway.
|
||||
|
||||
== Aspect ==
|
||||
One concrete combination of lights/shapes that a signal signal shows. Handling these is at the discretion of
|
||||
|
@ -50,6 +49,11 @@ Note that once apply_aspect returns, there is no need for advtrains anymore to q
|
|||
When the signal, for any reason, wants to change its aspect by itself *without* going through the signal API then
|
||||
it should update the aspect info cache by calling advtrains.interlocking.signal.update_aspect_info(pos)
|
||||
|
||||
Note that the apply_aspect function MUST accept the following main aspect, even if it is not defined in the main_aspects table:
|
||||
{ name = "halt", halt = true }
|
||||
It should cause the signal to show its most restrictive aspect. Typically it is a halt aspect, but e.g. for distant-only
|
||||
signals this would be "expect stop".
|
||||
|
||||
== Aspect Info ==
|
||||
The actual signal aspect in the already-known format. This is what the trains use to determine halt/proceed and speed. In this, the dst field has to be resolved.
|
||||
asp = {
|
||||
|
@ -62,7 +66,10 @@ asp = {
|
|||
Node definition of signals:
|
||||
- The signal needs some logic to figure out, for each combination of its own aspect group and the distant signal's aspect, what aspect info it can/will show.
|
||||
ndef.advtrains = {
|
||||
aspect_groups = { [name] = { description = "Proceed at full speed", <more data at discretion of signal>} }
|
||||
main_aspects = {
|
||||
{ name = "proceed" description = "Proceed at full speed", <more data at discretion of signal>}
|
||||
{ name = "proceed2" description = "Proceed at full speed", <more data at discretion of signal>}
|
||||
} -- The numerical order determines the layout of the list in the selection dialog.
|
||||
apply_aspect = function(pos, asp_group, dst_aspgrp, dst_aspinfo)
|
||||
-- set the node to show the desired aspect
|
||||
-- called by advtrains when this signal's aspect group or the distant signal's aspect changes
|
||||
|
@ -72,28 +79,61 @@ ndef.advtrains = {
|
|||
}
|
||||
]]
|
||||
|
||||
advtrains.interlocking.signal_convert_aspect_if_necessary = advtrains.interlocking.aspect
|
||||
-- Set a signal's aspect.
|
||||
-- Signal aspects should only be set through this function. It takes care of:
|
||||
-- - Storing the main aspect and dst pos for this signal permanently (until next change)
|
||||
-- - Assigning the distant signal for this signal
|
||||
-- - Calling apply_aspect() in the signal's node definition to make the signal show the aspect
|
||||
-- - Calling apply_aspect() again whenever the distant signal changes its aspect
|
||||
-- - Notifying this signal's distant signals about changes to this signal (unless skip_dst_notify is specified)
|
||||
function signal.set_aspect(pos, main_aspect, dst_pos, skip_dst_notify)
|
||||
-- TODO
|
||||
end
|
||||
|
||||
function advtrains.interlocking.update_signal_aspect(tcbs, skipdst)
|
||||
-- Gets the stored main aspect and distant signal position for this signal
|
||||
-- This information equals the information last passed to set_aspect
|
||||
-- It does not take into consideration the actual speed signalling, please use
|
||||
-- get_aspect_info() for this
|
||||
-- returns: main_aspect, dst_pos
|
||||
function signal.get_aspect(pos)
|
||||
--TODO
|
||||
end
|
||||
|
||||
function signal.get_distant_signals_of(pos)
|
||||
--TODO
|
||||
end
|
||||
|
||||
-- Called when either this signal has changed its main aspect
|
||||
-- or when this distant signal's currently assigned main signal has changed its aspect
|
||||
-- It retrieves the signal's main aspect and aspect info and calls apply_aspect of the node definition
|
||||
-- to update the signal's appearance and aspect info
|
||||
-- pts: The signal position to update as encoded_pos
|
||||
function signal.reapply_aspect(pts, p_mainaspect)
|
||||
--TODO
|
||||
end
|
||||
|
||||
-- Update this signal's aspect based on the set route
|
||||
--
|
||||
function signal.update_route_aspect(tcbs, skip_dst_notify)
|
||||
if tcbs.signal then
|
||||
local asp = tcbs.aspect or DANGER
|
||||
advtrains.interlocking.signal_set_aspect(tcbs.signal, asp, skipdst)
|
||||
local asp = tcbs.aspect or signal.MASP_HALT
|
||||
signal.set_aspect(tcbs.signal, asp, skip_dst_notify)
|
||||
end
|
||||
end
|
||||
|
||||
function advtrains.interlocking.signal_can_dig(pos)
|
||||
function signal.can_dig(pos)
|
||||
return not advtrains.interlocking.db.get_sigd_for_signal(pos)
|
||||
end
|
||||
|
||||
function advtrains.interlocking.signal_after_dig(pos)
|
||||
-- clear influence point
|
||||
|
||||
advtrains.interlocking.signal_clear_aspect(pos)
|
||||
advtrains.distant.unassign_all(pos, true)
|
||||
advtrains.distant.unassign_all(pos, true) -- TODO
|
||||
end
|
||||
|
||||
-- should be called when aspect has changed on this signal.
|
||||
function advtrains.interlocking.signal_on_aspect_changed(pos)
|
||||
-- Update waiting trains and distant signals about a changed signal aspect
|
||||
function signal.notify_on_aspect_changed(pos, skip_dst_notify)
|
||||
--TODO update distant?
|
||||
local ipts, iconn = advtrains.interlocking.db.get_ip_by_signalpos(pos)
|
||||
if not ipts then return end
|
||||
local ipos = minetest.string_to_pos(ipts)
|
||||
|
@ -103,7 +143,7 @@ function advtrains.interlocking.signal_on_aspect_changed(pos)
|
|||
minetest.after(0, advtrains.invalidate_all_paths, ipos)
|
||||
end
|
||||
|
||||
function advtrains.interlocking.signal_rc_handler(pos, node, player, itemstack, pointed_thing)
|
||||
function signal.on_rightclick(pos, node, player, itemstack, pointed_thing)
|
||||
local pname = player:get_player_name()
|
||||
local control = player:get_player_control()
|
||||
if control.aux1 then
|
||||
|
@ -122,7 +162,7 @@ function advtrains.interlocking.show_signal_form(pos, node, pname)
|
|||
if ndef.advtrains and ndef.advtrains.set_aspect then
|
||||
-- permit to set aspect manually
|
||||
local function callback(pname, aspect)
|
||||
advtrains.interlocking.signal_set_aspect(pos, aspect)
|
||||
signal.set_aspect(pos, aspect)
|
||||
end
|
||||
local isasp = advtrains.interlocking.signal_get_aspect(pos, node)
|
||||
|
||||
|
@ -138,18 +178,6 @@ function advtrains.interlocking.show_signal_form(pos, node, pname)
|
|||
end
|
||||
end
|
||||
|
||||
-- Returns the aspect the signal at pos is supposed to show
|
||||
function advtrains.interlocking.signal_get_supposed_aspect(pos)
|
||||
local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos)
|
||||
if sigd then
|
||||
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
||||
if tcbs.aspect then
|
||||
return convert_aspect_if_necessary(tcbs.aspect)
|
||||
end
|
||||
end
|
||||
return DANGER;
|
||||
end
|
||||
|
||||
local players_assign_ip = {}
|
||||
|
||||
local function ipmarker(ipos, connid)
|
||||
|
@ -236,7 +264,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
end)
|
||||
|
||||
-- inits the signal IP assignment process
|
||||
function advtrains.interlocking.signal_init_ip_assign(pos, pname)
|
||||
function signal.init_ip_assign(pos, pname)
|
||||
if not minetest.check_player_privs(pname, "interlocking") then
|
||||
minetest.chat_send_player(pname, "Insufficient privileges to use this!")
|
||||
return
|
||||
|
@ -281,3 +309,6 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
|||
players_assign_ip[pname] = nil
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
advtrains.interlocking.signal = signal
|
||||
|
|
|
@ -11,10 +11,9 @@ local function asp_to_zs3type(asp)
|
|||
return math.min(16,4*math.floor(n/4))
|
||||
end
|
||||
|
||||
local function setzs3(msp, lim, rot)
|
||||
local function setzs3(msp, asp, rot)
|
||||
local pos = {x = msp.x, y = msp.y+1, z = msp.z}
|
||||
local node = advtrains.ndb.get_node(pos)
|
||||
local asp = asp_to_zs3type(lim)
|
||||
if node.name:find("^advtrains_signals_ks:zs3_") then
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:zs3_"..asp.."_"..rot, param2 = node.param2})
|
||||
end
|
||||
|
@ -50,67 +49,106 @@ local function getzs3v(msp)
|
|||
end
|
||||
|
||||
local setaspectf = function(rot)
|
||||
return function(pos, node, asp)
|
||||
setzs3(pos, asp.main, rot)
|
||||
if asp.main == 0 then
|
||||
if asp.shunt then
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_shunt_"..rot, param2 = node.param2})
|
||||
else
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_danger_"..rot, param2 = node.param2})
|
||||
end
|
||||
return function(pos, node, main_aspect, dst_aspect, dst_aspect_info)
|
||||
-- set zs3 signal to show speed according to main_aspect
|
||||
setzs3(pos, asp.zs3, rot)
|
||||
-- select appropriate lamps based on mainaspect and dst
|
||||
if main_aspect.shunt then
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_shunt_"..rot, param2 = node.param2})
|
||||
setzs3v(pos, nil, rot)
|
||||
elseif main_aspect.halt then
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_danger_"..rot, param2 = node.param2})
|
||||
setzs3v(pos, nil, rot)
|
||||
else
|
||||
if not asp.dst or asp.dst == -1 then
|
||||
if not dst_aspect_info
|
||||
or not dst_aspect_info.main
|
||||
or dst_aspect_info.main == -1 then
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_free_"..rot, param2 = node.param2})
|
||||
elseif asp.dst == 0 then
|
||||
setzs3v(pos, nil, rot)
|
||||
elseif dst_aspect_info.main == 0 then
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_slow_"..rot, param2 = node.param2})
|
||||
setzs3v(pos, nil, rot)
|
||||
else
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_nextslow_"..rot, param2 = node.param2})
|
||||
setzs3v(pos, dst_aspect_info.main, rot)
|
||||
end
|
||||
setzs3v(pos, asp.dst, rot)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local suppasp = {
|
||||
main = {0, 4, 6, 8, 12, 16, -1},
|
||||
dst = {0, 4, 6, 8, 12, 16, -1, false},
|
||||
shunt = nil,
|
||||
proceed_as_main = true,
|
||||
info = {
|
||||
call_on = false,
|
||||
dead_end = false,
|
||||
w_speed = nil,
|
||||
}
|
||||
-- Main aspects main signal
|
||||
-- These aspects tell only the speed signalization at this signal.
|
||||
-- Actual signal aspect is chosen based on this and the Dst signal.
|
||||
local mainaspects_main = {
|
||||
{
|
||||
name = "proceed"
|
||||
description = "Proceed",
|
||||
zs3 = "off"
|
||||
},
|
||||
{
|
||||
name = "shunt"
|
||||
description = "Shunt",
|
||||
zs3 = "off",
|
||||
shunt = true,
|
||||
},
|
||||
{
|
||||
name = "proceed_16"
|
||||
description = "Proceed (speed 16)",
|
||||
zs3 = "16",
|
||||
},
|
||||
{
|
||||
name = "proceed_12"
|
||||
description = "Proceed (speed 12)",
|
||||
zs3 = "12",
|
||||
},
|
||||
{
|
||||
name = "proceed_8"
|
||||
description = "Proceed (speed 8)",
|
||||
zs3 = "8",
|
||||
},
|
||||
{
|
||||
name = "proceed_6"
|
||||
description = "Proceed (speed 6)",
|
||||
zs3 = "6",
|
||||
},
|
||||
{
|
||||
name = "proceed_4"
|
||||
description = "Proceed (speed 4)",
|
||||
zs3 = "4",
|
||||
},
|
||||
{
|
||||
name = "halt"
|
||||
description = "Halt",
|
||||
zs3 = "off",
|
||||
halt = true,
|
||||
},
|
||||
}
|
||||
|
||||
--Rangiersignal
|
||||
local setaspectf_ra = function(rot)
|
||||
return function(pos, node, asp)
|
||||
if asp.shunt then
|
||||
local applyaspectf_ra = function(rot)
|
||||
-- we get here the full main_aspect table
|
||||
return function(pos, node, main_aspect, dst_aspect, dst_aspect_info)
|
||||
if main_aspect.shunt then
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:ra_shuntd_"..rot, param2 = node.param2})
|
||||
else
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:ra_danger_"..rot, param2 = node.param2})
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta then
|
||||
meta:set_string("infotext", minetest.serialize(asp))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local suppasp_ra = {
|
||||
main = { false },
|
||||
dst = { false },
|
||||
shunt = nil,
|
||||
proceed_as_main = false,
|
||||
|
||||
info = {
|
||||
call_on = false,
|
||||
dead_end = false,
|
||||
w_speed = nil,
|
||||
}
|
||||
-- Main aspects shunt signal
|
||||
-- Shunt signals have only two states, distant doesn't matter
|
||||
local mainaspects_shunt = {
|
||||
{
|
||||
name = "shunt"
|
||||
description = "Shunt",
|
||||
shunt = true,
|
||||
},
|
||||
{
|
||||
name = "halt"
|
||||
description = "Halt",
|
||||
halt = true,
|
||||
},
|
||||
}
|
||||
|
||||
advtrains.trackplacer.register_tracktype("advtrains_signals_ks:hs")
|
||||
|
@ -192,9 +230,9 @@ for _, rtab in ipairs({
|
|||
drop = "advtrains_signals_ks:hs_danger_0",
|
||||
inventory_image = "advtrains_signals_ks_hs_inv.png",
|
||||
advtrains = {
|
||||
set_aspect = setaspectf(rot),
|
||||
supported_aspects = suppasp,
|
||||
get_aspect = afunc,
|
||||
main_aspects = mainaspects_main
|
||||
apply_aspect = applyaspectf_main(rot),
|
||||
get_aspect_info = afunc,
|
||||
},
|
||||
on_rightclick = advtrains.interlocking.signal_rc_handler,
|
||||
can_dig = advtrains.interlocking.signal_can_dig,
|
||||
|
@ -235,11 +273,9 @@ for _, rtab in ipairs({
|
|||
drop = "advtrains_signals_ks:ra_danger_0",
|
||||
inventory_image = "advtrains_signals_ks_ra_inv.png",
|
||||
advtrains = {
|
||||
set_aspect = setaspectf_ra(rot),
|
||||
supported_aspects = suppasp_ra,
|
||||
get_aspect = function(pos, node)
|
||||
return prts.asp
|
||||
end,
|
||||
main_aspects = mainaspects_ra,
|
||||
apply_aspect = applyaspectf_ra(rot),
|
||||
get_aspect_info = prts.asp,
|
||||
},
|
||||
on_rightclick = advtrains.interlocking.signal_rc_handler,
|
||||
can_dig = advtrains.interlocking.signal_can_dig,
|
||||
|
@ -276,7 +312,7 @@ for _, rtab in ipairs({
|
|||
drop = "advtrains_signals_ks:"..prefix.."_"..dtyp.."_0",
|
||||
inventory_image = inv,
|
||||
advtrains = {
|
||||
get_aspect = function() return asp end
|
||||
get_aspect_info = asp
|
||||
},
|
||||
on_rightclick = advtrains.interlocking.signal_rc_handler,
|
||||
can_dig = advtrains.interlocking.signal_can_dig,
|
||||
|
|
Loading…
Reference in New Issue