aboutsummaryrefslogtreecommitdiff
path: root/advtrains/advtrains
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains/advtrains')
-rw-r--r--advtrains/advtrains/api_doc.txt2
-rw-r--r--advtrains/advtrains/atc.lua15
-rw-r--r--advtrains/advtrains/init.lua10
-rw-r--r--advtrains/advtrains/lua_atc.lua166
-rw-r--r--advtrains/advtrains/nodedb.lua4
-rw-r--r--advtrains/advtrains/signals.lua22
-rw-r--r--advtrains/advtrains/trackplacer.lua4
-rw-r--r--advtrains/advtrains/tracks.lua54
-rw-r--r--advtrains/advtrains/trainlogic.lua30
9 files changed, 83 insertions, 224 deletions
diff --git a/advtrains/advtrains/api_doc.txt b/advtrains/advtrains/api_doc.txt
index af9c071..09b3cc1 100644
--- a/advtrains/advtrains/api_doc.txt
+++ b/advtrains/advtrains/api_doc.txt
@@ -134,7 +134,7 @@ minetest.register_node(nodename, {
^- the height value of this rail that is saved in the path. usually the median of rely1 and rely2.
can_dig=function(pos)
- return not advtrains.is_train_at_pos(pos)
+ return not advtrains.get_train_at_pos(pos)
end,
after_dig_node=function(pos)
advtrains.invalidate_all_paths()
diff --git a/advtrains/advtrains/atc.lua b/advtrains/advtrains/atc.lua
index dcddc65..85c62d8 100644
--- a/advtrains/advtrains/atc.lua
+++ b/advtrains/advtrains/atc.lua
@@ -5,7 +5,14 @@ local atc={}
-- ATC persistence table. advtrains.atc is created by init.lua when it loads the save file.
atc.controllers = {}
function atc.load_data(data)
- atc.controllers = data and data.controllers or {}
+ local temp = data and data.controllers or {}
+ --transcode atc controller data to node hashes: table access times for numbers are far less than for strings
+ for pts, data in pairs(temp) do
+ if type(pts)=="string" then
+ pts=minetest.hash_node_position(minetest.string_to_pos(pts))
+ end
+ atc.controllers[pts] = data
+ end
end
function atc.save_data()
return {controllers = atc.controllers}
@@ -21,7 +28,7 @@ end
--general
function atc.send_command(pos)
- local pts=minetest.pos_to_string(pos)
+ local pts=minetest.hash_node_position(pos)
if atc.controllers[pts] then
--atprint("Called send_command at "..pts)
local train_id = advtrains.detector.on_node[pts]
@@ -81,7 +88,7 @@ advtrains.register_tracks("default", {
after_dig_node=function(pos)
advtrains.invalidate_all_paths()
advtrains.ndb.clear(pos)
- local pts=minetest.pos_to_string(pos)
+ local pts=minetest.hash_node_position(pos)
atc.controllers[pts]=nil
end,
on_receive_fields = function(pos, formname, fields, player)
@@ -115,7 +122,7 @@ advtrains.register_tracks("default", {
end
meta:set_string("formspec", atc.get_atc_controller_formspec(pos, meta))
- local pts=minetest.pos_to_string(pos)
+ local pts=minetest.hash_node_position(pos)
local _, conn1=advtrains.get_rail_info_at(pos, advtrains.all_tracktypes)
atc.controllers[pts]={command=fields.command, arrowconn=conn1}
atc.send_command(pos)
diff --git a/advtrains/advtrains/init.lua b/advtrains/advtrains/init.lua
index c2f2a6a..5ae5e80 100644
--- a/advtrains/advtrains/init.lua
+++ b/advtrains/advtrains/init.lua
@@ -11,7 +11,7 @@ advtrains = {trains={}, wagon_save={}}
advtrains.modpath = minetest.get_modpath("advtrains")
-local function print_concat_table(a)
+function advtrains.print_concat_table(a)
local str=""
local stra=""
for i=1,50 do
@@ -43,7 +43,11 @@ local function print_concat_table(a)
end
atprint=function() end
if minetest.setting_getbool("advtrains_debug") then
- atprint=function(t, ...) minetest.log("action", "[advtrains]"..print_concat_table({t, ...})) minetest.chat_send_all("[advtrains]"..print_concat_table({t, ...})) end
+ atprint=function(t, ...)
+ local text=advtrains.print_concat_table({t, ...})
+ minetest.log("action", "[advtrains]"..text)
+ minetest.chat_send_all("[advtrains]"..text)
+ end
end
sid=function(id) return string.sub(id, -4) end
@@ -98,7 +102,6 @@ else
advtrains.wagon_save = tbl.wagon_save
advtrains.ndb.load_data(tbl.ndb)
advtrains.atc.load_data(tbl.atc)
- --advtrains.latc.load_data(tbl.latc)
else
--oh no, its the old one...
advtrains.trains=tbl
@@ -167,7 +170,6 @@ advtrains.save = function()
trains = advtrains.trains,
wagon_save = advtrains.wagon_save,
atc = advtrains.atc.save_data(),
- --latc = advtrains.latc.save_data(),
ndb = advtrains.ndb.save_data(),
version = 1,
}
diff --git a/advtrains/advtrains/lua_atc.lua b/advtrains/advtrains/lua_atc.lua
deleted file mode 100644
index 313d70d..0000000
--- a/advtrains/advtrains/lua_atc.lua
+++ /dev/null
@@ -1,166 +0,0 @@
--------------
---LUA ATC controllers
-
-local latc={}
-
-function latc.load_data(data)
-end
-function latc.save_data()
- return stuff
-end
-
-latc.data
-latc.env_cdata
-latc.init_code=""
-latc.step_code=""
-
-advtrains.fpath_latc=minetest.get_worldpath().."/advtrains_latc"
-local file, err = io.open(advtrains.fpath_atc, "r")
-if not file then
- local er=err or "Unknown Error"
- atprint("Failed loading advtrains latc save file "..er)
-else
- local tbl = minetest.deserialize(file:read("*a"))
- if type(tbl) == "table" then
- atc.controllers=tbl.controllers
- end
- file:close()
-end
-function latc.save()
-
- local datastr = minetest.serialize({controllers = atc.controllers})
- if not datastr then
- minetest.log("error", " Failed to serialize latc data!")
- return
- end
- local file, err = io.open(advtrains.fpath_atc, "w")
- if err then
- return err
- end
- file:write(datastr)
- file:close()
-end
-
---Privilege
---Only trusted players should be enabled to build stuff which can break the server.
---If I later decide to have multiple environments ('data' tables), I better store an owner for every controller for future reference.
-
-minetest.register_privilege("advtrains_lua_atc", { description = "Player can place and modify LUA ATC components. Grant with care! Allows to execute bad LUA code.", give_to_singleplayer = false, default= false })
-
---Environment
---Code from mesecons_luacontroller (credit goes to Jeija and mesecons contributors)
-
-local safe_globals = {
- "assert", "error", "ipairs", "next", "pairs", "select",
- "tonumber", "tostring", "type", "unpack", "_VERSION"
-}
-local function safe_print(param)
- print(dump(param))
-end
-
-local function safe_date()
- return(os.date("*t",os.time()))
-end
-
--- string.rep(str, n) with a high value for n can be used to DoS
--- the server. Therefore, limit max. length of generated string.
-local function safe_string_rep(str, n)
- if #str * n > mesecon.setting("luacontroller_string_rep_max", 64000) then
- debug.sethook() -- Clear hook
- error("string.rep: string length overflow", 2)
- end
-
- return string.rep(str, n)
-end
-
--- string.find with a pattern can be used to DoS the server.
--- Therefore, limit string.find to patternless matching.
-local function safe_string_find(...)
- if (select(4, ...)) ~= true then
- debug.sethook() -- Clear hook
- error("string.find: 'plain' (fourth parameter) must always be true in a LuaController")
- end
-
- return string.find(...)
-end
-
-latc.static_env = {
- print = safe_print,
- string = {
- byte = string.byte,
- char = string.char,
- format = string.format,
- len = string.len,
- lower = string.lower,
- upper = string.upper,
- rep = safe_string_rep,
- reverse = string.reverse,
- sub = string.sub,
- find = safe_string_find,
- },
- math = {
- abs = math.abs,
- acos = math.acos,
- asin = math.asin,
- atan = math.atan,
- atan2 = math.atan2,
- ceil = math.ceil,
- cos = math.cos,
- cosh = math.cosh,
- deg = math.deg,
- exp = math.exp,
- floor = math.floor,
- fmod = math.fmod,
- frexp = math.frexp,
- huge = math.huge,
- ldexp = math.ldexp,
- log = math.log,
- log10 = math.log10,
- max = math.max,
- min = math.min,
- modf = math.modf,
- pi = math.pi,
- pow = math.pow,
- rad = math.rad,
- random = math.random,
- sin = math.sin,
- sinh = math.sinh,
- sqrt = math.sqrt,
- tan = math.tan,
- tanh = math.tanh,
- },
- table = {
- concat = table.concat,
- insert = table.insert,
- maxn = table.maxn,
- remove = table.remove,
- sort = table.sort,
- },
- os = {
- clock = os.clock,
- difftime = os.difftime,
- time = os.time,
- datetable = safe_date,
- },
-}
-latc.static_env._G = env
-
-for _, name in pairs(safe_globals) do
- latc.static_env[name] = _G[name]
-end
-
-
---The environment all code calls get is a proxy table with a metatable.
---When an index is read:
--- Look in static_env
--- Look in volatile_env (user_written functions and userdata)
--- Look in saved_env (everything that's not a function or userdata)
---when an index is written:
--- If in static_env, do not allow
--- if function or userdata, volatile_env
--- if table, see below
--- else, save in saved_env
-
-
-
-advtrains.latc=latc
diff --git a/advtrains/advtrains/nodedb.lua b/advtrains/advtrains/nodedb.lua
index 0a8c1e8..e3ed56d 100644
--- a/advtrains/advtrains/nodedb.lua
+++ b/advtrains/advtrains/nodedb.lua
@@ -208,6 +208,10 @@ minetest.register_abm({
if (nodeid~=node.name or param2~=node.param2) then
atprint("nodedb: lbm replaced", pos, "with nodeid", nodeid, "param2", param2, "cid is", cid)
minetest.swap_node(pos, {name=nodeid, param2 = param2})
+ local ndef=minetest.registered_nodes[nodeid]
+ if ndef and ndef.on_updated_from_nodedb then
+ ndef.on_updated_from_nodedb(pos, node)
+ end
end
end
else
diff --git a/advtrains/advtrains/signals.lua b/advtrains/advtrains/signals.lua
index d521c8a..b475d3c 100644
--- a/advtrains/advtrains/signals.lua
+++ b/advtrains/advtrains/signals.lua
@@ -1,6 +1,6 @@
--advtrains by orwell96
--signals.lua
-for r,f in pairs({on="off", off="on"}) do
+for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red", als="green"}}) do
advtrains.trackplacer.register_tracktype("advtrains:retrosignal", "")
advtrains.trackplacer.register_tracktype("advtrains:signal", "")
@@ -32,12 +32,12 @@ for r,f in pairs({on="off", off="on"}) do
save_in_nodedb=1,
},
mesecons = {effector = {
- ["action_"..f] = function (pos, node)
- advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_"..f..rotation, param2 = node.param2})
+ ["action_"..f.as] = function (pos, node)
+ advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_"..f.as..rotation, param2 = node.param2})
end
}},
on_rightclick=function(pos, node, clicker)
- advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_"..f..rotation, param2 = node.param2})
+ advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_"..f.as..rotation, param2 = node.param2})
end,
})
advtrains.trackplacer.add_worked("advtrains:retrosignal", r, rotation, nil)
@@ -65,12 +65,20 @@ for r,f in pairs({on="off", off="on"}) do
light_source = 1,
sunlight_propagates=true,
mesecons = {effector = {
- ["action_"..f] = function (pos, node)
- advtrains.ndb.swap_node(pos, {name = "advtrains:signal_"..f..rotation, param2 = node.param2})
+ ["action_"..f.as] = function (pos, node)
+ advtrains.ndb.swap_node(pos, {name = "advtrains:signal_"..f.as..rotation, param2 = node.param2})
end
}},
+ luaautomation = {
+ getstate = f.ls,
+ setstate = function(pos, node, newstate)
+ if newstate == f.als then
+ advtrains.ndb.swap_node(pos, {name = "advtrains:signal_"..f.as..rotation, param2 = node.param2})
+ end
+ end,
+ },
on_rightclick=function(pos, node, clicker)
- advtrains.ndb.swap_node(pos, {name = "advtrains:signal_"..f..rotation, param2 = node.param2})
+ advtrains.ndb.swap_node(pos, {name = "advtrains:signal_"..f.as..rotation, param2 = node.param2})
end,
})
advtrains.trackplacer.add_worked("advtrains:signal", r, rotation, nil)
diff --git a/advtrains/advtrains/trackplacer.lua b/advtrains/advtrains/trackplacer.lua
index d1045aa..e5e3340 100644
--- a/advtrains/advtrains/trackplacer.lua
+++ b/advtrains/advtrains/trackplacer.lua
@@ -230,7 +230,7 @@ minetest.register_craftitem("advtrains:trackworker",{
local node=minetest.get_node(pos)
--if not advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then return end
- if advtrains.is_train_at_pos(pos) then return end
+ if advtrains.get_train_at_pos(pos) then return end
local nnprefix, suffix, rotation=string.match(node.name, "^(.+)_([^_]+)(_[^_]+)$")
--atprint(node.name.."\npattern recognizes:"..nodeprefix.." / "..railtype.." / "..rotation)
@@ -272,7 +272,7 @@ minetest.register_craftitem("advtrains:trackworker",{
end
--if not advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then return end
- if advtrains.is_train_at_pos(pos) then return end
+ if advtrains.get_train_at_pos(pos) then return end
local nnprefix, suffix, rotation=string.match(node.name, "^(.+)_([^_]+)(_[^_]+)$")
--atprint(node.name.."\npattern recognizes:"..nodeprefix.." / "..railtype.." / "..rotation)
if not tp.tracks[nnprefix] or not tp.tracks[nnprefix].twcycle[suffix] then
diff --git a/advtrains/advtrains/tracks.lua b/advtrains/advtrains/tracks.lua
index a44acb3..a63ff4d 100644
--- a/advtrains/advtrains/tracks.lua
+++ b/advtrains/advtrains/tracks.lua
@@ -77,6 +77,12 @@ ap.t_30deg={
swrst="on",
swrcr="off",
},
+ switchst={
+ swlst="st",
+ swlcr="cr",
+ swrst="st",
+ swrcr="cr",
+ },
regtp=true,
trackplacer={
st=true,
@@ -195,6 +201,12 @@ ap.t_45deg={
swrst="on",
swrcr="off",
},
+ switchst={
+ swlst="st",
+ swlcr="cr",
+ swrst="st",
+ swrcr="cr",
+ },
regtp=true,
trackplacer={
st=true,
@@ -233,16 +245,27 @@ advtrains.trackpresets = ap
common={} change something on common rail appearance
}]]
function advtrains.register_tracks(tracktype, def, preset)
- local function make_switchfunc(suffix_target, mesecon_state)
- local switchfunc=function(pos, node)
- advtrains.ndb.swap_node(pos, {name=def.nodename_prefix.."_"..suffix_target, param2=node.param2})
+ local function make_switchfunc(suffix_target, mesecon_state, is_state)
+ local switchfunc=function(pos, node, newstate)
+ if newstate~=is_state then
+ advtrains.ndb.swap_node(pos, {name=def.nodename_prefix.."_"..suffix_target, param2=node.param2})
+ end
+ advtrains.invalidate_all_paths()
+ end
+ local mesec
+ if mesecon_state then -- if mesecons is not wanted, do not.
+ mesec = {effector = {
+ ["action_"..mesecon_state] = switchfunc,
+ rules=advtrains.meseconrules
+ }}
end
- return switchfunc, {effector = {
- ["action_"..mesecon_state] = switchfunc,
- rules=advtrains.meseconrules
- }}
+ return switchfunc, mesec,
+ {
+ getstate = is_state,
+ setstate = switchfunc,
+ }
end
- local function make_overdef(suffix, rotation, conns, switchfunc, mesecontbl, in_creative_inv, drop_slope)
+ local function make_overdef(suffix, rotation, conns, switchfunc, mesecontbl, luaautomation, in_creative_inv, drop_slope)
local img_suffix=suffix..rotation
return {
mesh = def.shared_model or (def.models_prefix.."_"..img_suffix..def.models_suffix),
@@ -266,6 +289,7 @@ function advtrains.register_tracks(tracktype, def, preset)
not_blocking_trains=1,
},
mesecons=mesecontbl,
+ luaautomation=luaautomation,
drop = increativeinv and def.nodename_prefix.."_"..suffix..rotation or (drop_slope and def.nodename_prefix.."_slopeplacer" or def.nodename_prefix.."_placer"),
}
end
@@ -294,7 +318,7 @@ function advtrains.register_tracks(tracktype, def, preset)
railheight=0,
drop=def.nodename_prefix.."_placer",
can_dig=function(pos)
- return not advtrains.is_train_at_pos(pos)
+ return not advtrains.get_train_at_pos(pos)
end,
after_dig_node=function(pos)
advtrains.invalidate_all_paths()
@@ -315,9 +339,9 @@ function advtrains.register_tracks(tracktype, def, preset)
for suffix, conns in pairs(preset.variant) do
for rotid, rotation in ipairs(preset.rotation) do
if not def.formats[suffix] or def.formats[suffix][rotid] then
- local switchfunc, mesecontbl
+ local switchfunc, mesecontbl, luaautomation
if preset.switch[suffix] then
- switchfunc, mesecontbl=make_switchfunc(preset.switch[suffix]..rotation, preset.switchmc[suffix])
+ switchfunc, mesecontbl, luaautomation=make_switchfunc(preset.switch[suffix]..rotation, preset.switchmc[suffix], preset.switchst[suffix])
end
local adef={}
if def.get_additional_definiton then
@@ -329,7 +353,7 @@ function advtrains.register_tracks(tracktype, def, preset)
make_overdef(
suffix, rotation,
cycle_conns(conns, rotid),
- switchfunc, mesecontbl, preset.increativeinv[suffix], preset.slopenodes[suffix]
+ switchfunc, mesecontbl, luaautomation, preset.increativeinv[suffix], preset.slopenodes[suffix]
),
adef
)
@@ -389,19 +413,19 @@ advtrains.detector.on_node = {}
function advtrains.detector.enter_node(pos, train_id)
local ppos=advtrains.round_vector_floor_y(pos)
- local pts=minetest.pos_to_string(ppos)
+ local pts=minetest.hash_node_position(ppos)
advtrains.detector.on_node[pts]=train_id
advtrains.detector.call_enter_callback(ppos, train_id)
end
function advtrains.detector.leave_node(pos, train_id)
local ppos=advtrains.round_vector_floor_y(pos)
- local pts=minetest.pos_to_string(ppos)
+ local pts=minetest.hash_node_position(ppos)
advtrains.detector.on_node[pts]=nil
advtrains.detector.call_leave_callback(ppos, train_id)
end
function advtrains.detector.stay_node(pos, train_id)
local ppos=advtrains.round_vector_floor_y(pos)
- local pts=minetest.pos_to_string(ppos)
+ local pts=minetest.hash_node_position(ppos)
advtrains.detector.on_node[pts]=train_id
end
diff --git a/advtrains/advtrains/trainlogic.lua b/advtrains/advtrains/trainlogic.lua
index 1bc732d..f28528f 100644
--- a/advtrains/advtrains/trainlogic.lua
+++ b/advtrains/advtrains/trainlogic.lua
@@ -404,7 +404,7 @@ function advtrains.train_step_b(id, train, dtime)
for x=-1,1 do
for z=-1,1 do
local testpos=vector.add(rcollpos, {x=x, y=0, z=z})
- local testpts=minetest.pos_to_string(testpos)
+ local testpts=minetest.hash_node_position(testpos)
if advtrains.detector.on_node[testpts] and advtrains.detector.on_node[testpts]~=id then
--collides
advtrains.spawn_couple_on_collide(id, testpos, advtrains.detector.on_node[testpts], train.movedir==-1)
@@ -754,31 +754,11 @@ function advtrains.invert_train(train_id)
advtrains.update_trainpart_properties(train_id, true)
end
-function advtrains.is_train_at_pos(pos)
- --atprint("istrainat: pos "..minetest.pos_to_string(pos))
- local checked_trains={}
- local objrefs=minetest.get_objects_inside_radius(pos, 2)
- for _,v in pairs(objrefs) do
- local le=v:get_luaentity()
- if le and le.is_wagon and le.initialized and le.train_id and not checked_trains[le.train_id] then
- --atprint("istrainat: checking "..le.train_id)
- checked_trains[le.train_id]=true
- local path=le:train().path
- if path then
- --atprint("has path")
- for i=math.floor(advtrains.get_train_end_index(le:train())+0.5),math.floor(le:train().index+0.5) do
- if path[i] then
- --atprint("has pathitem "..i.." "..minetest.pos_to_string(path[i]))
- if vector.equals(advtrains.round_vector_floor_y(path[i]), pos) then
- return true
- end
- end
- end
- end
- end
- end
- return false
+function advtrains.get_train_at_pos(pos)
+ local ph=minetest.hash_node_position(advtrains.round_vector_floor_y(pos))
+ return advtrains.detector.on_node[ph]
end
+
function advtrains.invalidate_all_paths()
--atprint("invalidating all paths")
for k,v in pairs(advtrains.trains) do