Fix final bugs and to-do's (u.a.save/load system)
parent
254c32e304
commit
2a76d4a960
|
@ -34,7 +34,7 @@ minetest.register_entity("advtrains:discouple", {
|
|||
return advtrains.pcall(function()
|
||||
local pname = player:get_player_name()
|
||||
if pname and pname~="" and self.wagon then
|
||||
if self.wagon:safe_decouple(pname) then
|
||||
if advtrains.safe_decouple_wagon(self.wagon.id, pname) then
|
||||
self.object:remove()
|
||||
else
|
||||
minetest.add_entity(self.object:getpos(), "advtrains:lockmarker")
|
||||
|
@ -53,7 +53,7 @@ minetest.register_entity("advtrains:discouple", {
|
|||
self.object:remove()
|
||||
return
|
||||
end
|
||||
if not self.wagon:train() and self.wagon:train().velocity > 0 then
|
||||
if not self.wagon:train() or self.wagon:train().velocity > 0 then
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
|
|
|
@ -37,7 +37,7 @@ advtrains.pos_add_dir = advtrains.dirCoordSet
|
|||
|
||||
function advtrains.pos_add_angle(pos, ang)
|
||||
-- 0 is +Z -> meaning of sin/cos swapped
|
||||
return vector.add(pos, {x = -math.cos(ang), y = 0, z = math.sin(ang)})
|
||||
return vector.add(pos, {x = -math.sin(ang), y = 0, z = math.cos(ang)})
|
||||
end
|
||||
|
||||
function advtrains.dirToCoord(dir)
|
||||
|
@ -103,7 +103,7 @@ function advtrains.yawToClosestConn(yaw, conns)
|
|||
local min_connid, min_diff=1, 10
|
||||
for connid, conn in ipairs(conns) do
|
||||
local yaw1 = advtrains.dir_to_angle(conn.c)
|
||||
local diff = advtrains.minAngleDiffRad(yaw, yaw1)
|
||||
local diff = math.abs(advtrains.minAngleDiffRad(yaw, yaw1))
|
||||
if diff < min_diff then
|
||||
min_connid = connid
|
||||
min_diff = diff
|
||||
|
|
|
@ -41,14 +41,12 @@ function advtrains.pcall(fun)
|
|||
local succ, return1, return2, return3, return4=xpcall(fun, function(err)
|
||||
atwarn("Lua Error occured: ", err)
|
||||
atwarn(debug.traceback())
|
||||
if advtrains.atprint_context_tid_full then
|
||||
advtrains.path_print(advtrains.trains[advtrains.atprint_context_tid_full], atdebug)
|
||||
if advtrains.atprint_context_tid then
|
||||
advtrains.path_print(advtrains.trains[advtrains.atprint_context_tid], atdebug)
|
||||
end
|
||||
end)
|
||||
if not succ then
|
||||
--reload_saves()
|
||||
no_action=true --this does also not belong here!
|
||||
minetest.request_shutdown()
|
||||
reload_saves()
|
||||
else
|
||||
return return1, return2, return3, return4
|
||||
end
|
||||
|
@ -123,6 +121,7 @@ if minetest.settings:get_bool("advtrains_enable_debugging") then
|
|||
--atlog("@@",advtrains.atprint_context_tid,t,...)
|
||||
end
|
||||
dofile(advtrains.modpath.."/debugringbuffer.lua")
|
||||
|
||||
end
|
||||
|
||||
function assertt(var, typ)
|
||||
|
@ -185,7 +184,8 @@ dofile(advtrains.modpath.."/log.lua")
|
|||
function advtrains.avt_load()
|
||||
local file, err = io.open(advtrains.fpath, "r")
|
||||
if not file then
|
||||
minetest.log("error", " Failed to read advtrains save data from file "..advtrains.fpath..": "..(err or "Unknown Error"))
|
||||
minetest.log("warning", " Failed to read advtrains save data from file "..advtrains.fpath..": "..(err or "Unknown Error"))
|
||||
minetest.log("warning", " (this is normal when first enabling advtrains on this world)")
|
||||
else
|
||||
local tbl = minetest.deserialize(file:read("*a"))
|
||||
if type(tbl) == "table" then
|
||||
|
@ -196,7 +196,7 @@ function advtrains.avt_load()
|
|||
for id, train in pairs(advtrains.trains) do
|
||||
train.id = id
|
||||
end
|
||||
advtrains.wagon_save = tbl.wagon_save
|
||||
advtrains.wagons = tbl.wagon_save
|
||||
advtrains.player_to_train_mapping = tbl.ptmap or {}
|
||||
advtrains.ndb.load_data(tbl.ndb)
|
||||
advtrains.atc.load_data(tbl.atc)
|
||||
|
@ -251,48 +251,30 @@ end
|
|||
|
||||
advtrains.avt_save = function(remove_players_from_wagons)
|
||||
--atprint("saving")
|
||||
--No more invalidating.
|
||||
--Instead, remove path a.s.o from the saved table manually
|
||||
|
||||
-- update wagon saves
|
||||
for _,wagon in pairs(minetest.luaentities) do
|
||||
if wagon.is_wagon and wagon.initialized then
|
||||
wagon:get_staticdata()
|
||||
end
|
||||
end
|
||||
--cross out userdata
|
||||
for w_id, data in pairs(advtrains.wagon_save) do
|
||||
data.name=nil
|
||||
data.object=nil
|
||||
if data.driver then
|
||||
data.driver_name=data.driver:get_player_name()
|
||||
data.driver=nil
|
||||
else
|
||||
data.driver_name=nil
|
||||
end
|
||||
if data.discouple then
|
||||
data.discouple.object:remove()
|
||||
data.discouple=nil
|
||||
end
|
||||
if remove_players_from_wagons then
|
||||
if remove_players_from_wagons then
|
||||
for w_id, data in pairs(advtrains.wagons) do
|
||||
data.seatp={}
|
||||
end
|
||||
end
|
||||
if remove_players_from_wagons then
|
||||
advtrains.player_to_train_mapping={}
|
||||
end
|
||||
|
||||
local tmp_trains={}
|
||||
for id, train in pairs(advtrains.trains) do
|
||||
--first, deep_copy the train
|
||||
local v=advtrains.save_keys(train, {
|
||||
"last_pos", "last_pos_prev", "movedir", "velocity", "tarvelocity",
|
||||
"trainparts", "savedpos_off_track_index_offset", "recently_collided_with_env",
|
||||
"atc_brake_target", "atc_wait_finish", "atc_command", "atc_delay", "door_open",
|
||||
"text_outside", "text_inside", "couple_lck_front", "couple_lck_back", "line"
|
||||
})
|
||||
--then save it
|
||||
tmp_trains[id]=v
|
||||
if #train.trainparts > 0 then
|
||||
local v=advtrains.save_keys(train, {
|
||||
"last_pos", "last_connid", "last_frac", "velocity", "tarvelocity",
|
||||
"trainparts", "recently_collided_with_env",
|
||||
"atc_brake_target", "atc_wait_finish", "atc_command", "atc_delay", "door_open",
|
||||
"text_outside", "text_inside", "couple_lck_front", "couple_lck_back", "line"
|
||||
})
|
||||
--then save it
|
||||
tmp_trains[id]=v
|
||||
else
|
||||
atwarn("Train",id,"had no wagons left because of some bug. It is being deleted. Wave it goodbye!")
|
||||
advtrains.remove_train(id)
|
||||
end
|
||||
end
|
||||
|
||||
--versions:
|
||||
|
@ -356,7 +338,7 @@ minetest.register_globalstep(function(dtime_mt)
|
|||
if save_timer<=0 then
|
||||
local t=os.clock()
|
||||
--save
|
||||
--advtrains.save()
|
||||
advtrains.save()
|
||||
save_timer=save_interval
|
||||
atprintbm("saving", t)
|
||||
end
|
||||
|
@ -430,3 +412,4 @@ minetest.register_chatcommand("at_reroute",
|
|||
|
||||
local tot=(os.clock()-lot)*1000
|
||||
minetest.log("action", "[advtrains] Loaded in "..tot.."ms")
|
||||
|
||||
|
|
|
@ -172,9 +172,9 @@ function o.check_collision(pos, train_id)
|
|||
if ti~=train_id then
|
||||
local idx = t[i+1]
|
||||
local train = advtrains.trains[ti]
|
||||
atdebug("checking train",t[i],"index",idx,"<>",train.index,train.end_index)
|
||||
--atdebug("checking train",t[i],"index",idx,"<>",train.index,train.end_index)
|
||||
if idx >= train.end_index and idx <= train.index then
|
||||
atdebug("collides.")
|
||||
--atdebug("collides.")
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
@ -190,7 +190,7 @@ end
|
|||
function o.get_occupations(train, index)
|
||||
local ppos, ontrack = advtrains.path_get(train, index)
|
||||
if not ontrack then
|
||||
atdebug("Train",train.id,"get_occupations requested off-track",index)
|
||||
atwarn("Train",train.id,"get_occupations requested off-track",index)
|
||||
return {}, ppos
|
||||
end
|
||||
local pos = advtrains.round_vector_floor_y(ppos)
|
||||
|
|
|
@ -1,76 +1,6 @@
|
|||
-- path.lua
|
||||
-- Functions for pathpredicting, put in a separate file.
|
||||
|
||||
function advtrains.conway(midreal, prev, drives_on)--in order prev,mid,return
|
||||
local mid=advtrains.round_vector_floor_y(midreal)
|
||||
|
||||
local midnode_ok, midconns=advtrains.get_rail_info_at(mid, drives_on)
|
||||
if not midnode_ok then
|
||||
return nil
|
||||
end
|
||||
local pconnid
|
||||
for connid, conn in ipairs(midconns) do
|
||||
local tps = advtrains.dirCoordSet(mid, conn.c)
|
||||
if tps.x==prev.x and tps.z==prev.z then
|
||||
pconnid=connid
|
||||
end
|
||||
end
|
||||
local nconnid = advtrains.get_matching_conn(pconnid, #midconns)
|
||||
|
||||
local next, next_connid, _, nextrailheight = advtrains.get_adjacent_rail(mid, midconns, nconnid, drives_on)
|
||||
if not next then
|
||||
return nil
|
||||
end
|
||||
return vector.add(advtrains.round_vector_floor_y(next), {x=0, y=nextrailheight, z=0}), midconns[nconnid].c
|
||||
end
|
||||
|
||||
function advtrains.pathpredict(id, train, gen_front, gen_back)
|
||||
|
||||
local maxn=train.path_extent_max or 0
|
||||
while maxn < gen_front do--pregenerate
|
||||
local conway
|
||||
if train.max_index_on_track == maxn then
|
||||
--atprint("maxn conway for ",maxn,train.path[maxn],maxn-1,train.path[maxn-1])
|
||||
conway=advtrains.conway(train.path[maxn], train.path[maxn-1], train.drives_on)
|
||||
end
|
||||
if conway then
|
||||
train.path[maxn+1]=conway
|
||||
train.max_index_on_track=maxn+1
|
||||
else
|
||||
--do as if nothing has happened and preceed with path
|
||||
--but do not update max_index_on_track
|
||||
atprint("over-generating path max to index ",(maxn+1)," (position ",train.path[maxn]," )")
|
||||
train.path[maxn+1]=vector.add(train.path[maxn], vector.subtract(train.path[maxn], train.path[maxn-1]))
|
||||
end
|
||||
train.path_dist[maxn]=vector.distance(train.path[maxn+1], train.path[maxn])
|
||||
maxn=maxn+1
|
||||
end
|
||||
train.path_extent_max=maxn
|
||||
|
||||
local minn=train.path_extent_min or -1
|
||||
while minn > gen_back do
|
||||
local conway
|
||||
if train.min_index_on_track == minn then
|
||||
--atprint("minn conway for ",minn,train.path[minn],minn+1,train.path[minn+1])
|
||||
conway=advtrains.conway(train.path[minn], train.path[minn+1], train.drives_on)
|
||||
end
|
||||
if conway then
|
||||
train.path[minn-1]=conway
|
||||
train.min_index_on_track=minn-1
|
||||
else
|
||||
--do as if nothing has happened and preceed with path
|
||||
--but do not update min_index_on_track
|
||||
atprint("over-generating path min to index ",(minn-1)," (position ",train.path[minn]," )")
|
||||
train.path[minn-1]=vector.add(train.path[minn], vector.subtract(train.path[minn], train.path[minn+1]))
|
||||
end
|
||||
train.path_dist[minn-1]=vector.distance(train.path[minn], train.path[minn-1])
|
||||
minn=minn-1
|
||||
end
|
||||
train.path_extent_min=minn
|
||||
if not train.min_index_on_track then train.min_index_on_track=-1 end
|
||||
if not train.max_index_on_track then train.max_index_on_track=0 end
|
||||
end
|
||||
|
||||
-- Naming conventions:
|
||||
-- 'index' - An index of the train.path table.
|
||||
-- 'offset' - A value in meters that determines how far on the path to walk relative to a certain index
|
||||
|
@ -145,7 +75,7 @@ function advtrains.path_setrestore(train, invert)
|
|||
end
|
||||
-- Get restore position, connid and frac (in this order) for a train that will originate at the passed index
|
||||
-- If invert is set, it will return path_cp and multiply frac by -1, in order to reverse the train there.
|
||||
function advtrains.path_getrestore(train, index, invert, tmp)
|
||||
function advtrains.path_getrestore(train, index, invert)
|
||||
local idx = index
|
||||
local cns = train.path_cn
|
||||
|
||||
|
@ -153,7 +83,7 @@ function advtrains.path_getrestore(train, index, invert, tmp)
|
|||
cns = train.path_cp
|
||||
end
|
||||
|
||||
fli = atfloor(index)
|
||||
local fli = atfloor(index)
|
||||
advtrains.path_get(train, fli)
|
||||
if fli > train.path_trk_f then
|
||||
fli = train.path_trk_f
|
||||
|
@ -161,9 +91,6 @@ function advtrains.path_getrestore(train, index, invert, tmp)
|
|||
if fli < train.path_trk_b then
|
||||
fli = train.path_trk_b
|
||||
end
|
||||
if not tmp then
|
||||
atdebug ("getrestore ",atround(train.index),"calc",atround(index),fli)
|
||||
end
|
||||
return advtrains.path_get(train, fli),
|
||||
cns[fli],
|
||||
(idx - fli) * (invert and -1 or 1)
|
||||
|
@ -195,7 +122,13 @@ end
|
|||
function advtrains.path_print(train, printf)
|
||||
printf("i: CP Position Dir CN ->Dist->")
|
||||
for i = train.path_ext_b, train.path_ext_f do
|
||||
if i==train.path_trk_b then
|
||||
printf("--Back on-track border here--")
|
||||
end
|
||||
printf(i,": ",train.path_cp[i]," ",train.path[i]," ",train.path_dir[i]," ",train.path_cn[i]," ->",train.path_dist[i],"->")
|
||||
if i==train.path_trk_f then
|
||||
printf("--Front on-track border here--")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -231,6 +164,7 @@ function advtrains.path_get(train, index)
|
|||
else
|
||||
-- off-track fallback behavior
|
||||
adj_pos = advtrains.pos_add_angle(pos, train.path_dir[pef-1])
|
||||
--atdebug("Offtrack overgenerating(front) at",adj_pos,"index",peb,"trkf",train.path_trk_f)
|
||||
train.path_dir[pef] = train.path_dir[pef-1]
|
||||
end
|
||||
train.path[pef] = adj_pos
|
||||
|
@ -260,6 +194,7 @@ function advtrains.path_get(train, index)
|
|||
else
|
||||
-- off-track fallback behavior
|
||||
adj_pos = advtrains.pos_add_angle(pos, train.path_dir[peb+1] + math.pi)
|
||||
--atdebug("Offtrack overgenerating(back) at",adj_pos,"index",peb,"trkb",train.path_trk_b)
|
||||
train.path_dir[peb] = train.path_dir[peb+1]
|
||||
end
|
||||
train.path[peb] = adj_pos
|
||||
|
@ -326,7 +261,6 @@ function advtrains.path_get_index_by_offset(train, index, offset)
|
|||
idx = idx - 1
|
||||
advtrains.path_get_adjacent(train, idx)
|
||||
if not train.path_dist[idx] then
|
||||
atdebug("second while",idx)
|
||||
for i=-5,5 do
|
||||
atdebug(idx+i,train.path_dist[idx+i])
|
||||
end
|
||||
|
@ -363,6 +297,8 @@ function advtrains.path_clear_unused(train)
|
|||
train.path_dir[i+1] = nil
|
||||
train.path_ext_f = i - 1
|
||||
end
|
||||
train.path_trk_b = math.max(train.path_trk_b, train.path_ext_b)
|
||||
train.path_trk_f = math.min(train.path_trk_f, train.path_ext_f)
|
||||
|
||||
train.path_req_f = math.ceil(train.index)
|
||||
train.path_req_b = math.floor(train.end_index or train.index)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
--trainlogic.lua
|
||||
--controls train entities stuff about connecting/disconnecting/colliding trains and other things
|
||||
|
||||
-- TODO: what should happen when a train has no trainparts anymore?
|
||||
|
||||
local benchmark=false
|
||||
local bm={}
|
||||
|
@ -68,17 +67,17 @@ advtrains.mainloop_trainlogic=function(dtime)
|
|||
local t=os.clock()
|
||||
|
||||
for k,v in pairs(advtrains.trains) do
|
||||
advtrains.atprint_context_tid=sid(k)
|
||||
advtrains.atprint_context_tid=k
|
||||
advtrains.train_ensure_init(k, v)
|
||||
end
|
||||
|
||||
for k,v in pairs(advtrains.trains) do
|
||||
advtrains.atprint_context_tid=sid(k)
|
||||
advtrains.atprint_context_tid=k
|
||||
advtrains.train_step_b(k, v, dtime)
|
||||
end
|
||||
|
||||
for k,v in pairs(advtrains.trains) do
|
||||
advtrains.atprint_context_tid=sid(k)
|
||||
advtrains.atprint_context_tid=k
|
||||
advtrains.train_step_c(k, v, dtime)
|
||||
end
|
||||
|
||||
|
@ -242,7 +241,7 @@ function advtrains.train_ensure_init(id, train)
|
|||
advtrains.update_trainpart_properties(id)
|
||||
recalc_end_index(train)
|
||||
|
||||
atdebug("Train",id,": Successfully restored path at",train.last_pos," connid",train.last_connid," frac",train.last_frac)
|
||||
--atdebug("Train",id,": Successfully restored path at",train.last_pos," connid",train.last_connid," frac",train.last_frac)
|
||||
|
||||
-- run on_new_path callbacks
|
||||
run_callbacks_new_path(id, train)
|
||||
|
@ -470,8 +469,7 @@ end
|
|||
-- asserted to rely on this)
|
||||
|
||||
local function tnc_call_enter_callback(pos, train_id)
|
||||
--atprint("instructed to call enter calback")
|
||||
|
||||
--atdebug("tnc enter",pos,train_id)
|
||||
local node = advtrains.ndb.get_node(pos) --this spares the check if node is nil, it has a name in any case
|
||||
local mregnode=minetest.registered_nodes[node.name]
|
||||
if mregnode and mregnode.advtrains and mregnode.advtrains.on_train_enter then
|
||||
|
@ -479,8 +477,7 @@ local function tnc_call_enter_callback(pos, train_id)
|
|||
end
|
||||
end
|
||||
local function tnc_call_leave_callback(pos, train_id)
|
||||
--atprint("instructed to call leave calback")
|
||||
|
||||
--atdebug("tnc leave",pos,train_id)
|
||||
local node = advtrains.ndb.get_node(pos) --this spares the check if node is nil, it has a name in any case
|
||||
local mregnode=minetest.registered_nodes[node.name]
|
||||
if mregnode and mregnode.advtrains and mregnode.advtrains.on_train_leave then
|
||||
|
@ -493,7 +490,7 @@ advtrains.te_register_on_new_path(function(id, train)
|
|||
old_index = atround(train.index),
|
||||
old_end_index = atround(train.end_index),
|
||||
}
|
||||
atdebug(id,"tnc init",train.index,train.end_index)
|
||||
--atdebug(id,"tnc init",train.index,train.end_index)
|
||||
end)
|
||||
|
||||
advtrains.te_register_on_update(function(id, train)
|
||||
|
@ -523,7 +520,7 @@ advtrains.te_register_on_create(function(id, train)
|
|||
tnc_call_enter_callback(pos, id)
|
||||
end_index = end_index + 1
|
||||
end
|
||||
atdebug(id,"tnc create",train.index,train.end_index)
|
||||
--atdebug(id,"tnc create",train.index,train.end_index)
|
||||
end)
|
||||
|
||||
advtrains.te_register_on_remove(function(id, train)
|
||||
|
@ -534,7 +531,7 @@ advtrains.te_register_on_remove(function(id, train)
|
|||
tnc_call_leave_callback(pos, id)
|
||||
end_index = end_index + 1
|
||||
end
|
||||
atdebug(id,"tnc remove",train.index,train.end_index)
|
||||
--atdebug(id,"tnc remove",train.index,train.end_index)
|
||||
end)
|
||||
|
||||
-- Calculates the indices where the window borders of the occupation windows are.
|
||||
|
@ -570,8 +567,6 @@ local function calc_occwindows(id, train)
|
|||
}
|
||||
end
|
||||
|
||||
--TODO: Collisions!
|
||||
|
||||
|
||||
--returns new id
|
||||
function advtrains.create_new_train_at(pos, connid, ioff, trainparts)
|
||||
|
@ -590,7 +585,7 @@ function advtrains.create_new_train_at(pos, connid, ioff, trainparts)
|
|||
t.trainparts=trainparts
|
||||
|
||||
advtrains.trains[new_id] = t
|
||||
atdebug("Created new train:",t)
|
||||
--atdebug("Created new train:",t)
|
||||
|
||||
advtrains.train_ensure_init(new_id, advtrains.trains[new_id])
|
||||
|
||||
|
@ -610,7 +605,7 @@ function advtrains.remove_train(id)
|
|||
advtrains.couple_invalidate(train)
|
||||
|
||||
local tp = train.trainparts
|
||||
atdebug("Removing train",id,"leftover trainparts:",tp)
|
||||
--atdebug("Removing train",id,"leftover trainparts:",tp)
|
||||
|
||||
advtrains.trains[id] = nil
|
||||
|
||||
|
@ -635,6 +630,23 @@ function advtrains.add_wagon_to_train(wagon_id, train_id, index)
|
|||
run_callbacks_update(train_id, train)
|
||||
end
|
||||
|
||||
function advtrains.safe_decouple_wagon(w_id, pname)
|
||||
if not minetest.check_player_privs(pname, "train_operator") then
|
||||
minetest.chat_send_player(pname, "Missing train_operator privilege")
|
||||
return false
|
||||
end
|
||||
local data = advtrains.wagons[w_id]
|
||||
if data.dcpl_lock then
|
||||
minetest.chat_send_player(pname, "Couple is locked (ask owner or admin to unlock it)")
|
||||
return false
|
||||
end
|
||||
atprint("wagon:discouple() Splitting train", data.train_id)
|
||||
local train = advtrains.trains[data.train_id]
|
||||
advtrains.log("Discouple", pname, train.last_pos, train.text_outside)
|
||||
advtrains.split_train_at_wagon(w_id)
|
||||
return true
|
||||
end
|
||||
|
||||
-- this function sets wagon's pos_in_train(parts) properties and train's max_speed and drives_on (and more)
|
||||
function advtrains.update_trainpart_properties(train_id, invert_flipstate)
|
||||
local train=advtrains.trains[train_id]
|
||||
|
@ -692,14 +704,15 @@ local ablkrng = minetest.settings:get("active_block_range")*16
|
|||
function advtrains.spawn_wagons(train_id)
|
||||
local train = advtrains.trains[train_id]
|
||||
|
||||
for i, w_id in ipairs(train.trainparts) do
|
||||
for i = 1, #train.trainparts do
|
||||
local w_id = train.trainparts[i]
|
||||
local data = advtrains.wagons[w_id]
|
||||
if data then
|
||||
if data.train_id ~= train_id then
|
||||
atwarn("Train",train_id,"Wagon #",1,": Saved train ID",data.train_id,"did not match!")
|
||||
data.train_id = train_id
|
||||
end
|
||||
if not data.object or not data.object:getyaw() then
|
||||
if not advtrains.wagon_objects[w_id] or not advtrains.wagon_objects[w_id]:getyaw() then
|
||||
-- eventually need to spawn new object. check if position is loaded.
|
||||
local index = advtrains.path_get_index_by_offset(train, train.index, -data.pos_in_train)
|
||||
local pos = advtrains.path_get(train, atfloor(index))
|
||||
|
@ -717,6 +730,10 @@ function advtrains.spawn_wagons(train_id)
|
|||
wagon:set_id(w_id)
|
||||
end
|
||||
end
|
||||
else
|
||||
atwarn("Train",train_id,"Wagon #",1,": A wagon with id",w_id,"does not exist! Wagon will be removed from train.")
|
||||
table.remove(train.trainparts, i)
|
||||
i = i - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -745,6 +762,11 @@ function advtrains.split_train_at_wagon(wagon_id)
|
|||
end
|
||||
end
|
||||
|
||||
--update train parts
|
||||
advtrains.update_trainpart_properties(old_id)
|
||||
recalc_end_index(train)
|
||||
run_callbacks_update(old_id, train)
|
||||
|
||||
--create subtrain
|
||||
local newtrain_id=advtrains.create_new_train_at(pos, connid, frac, tp)
|
||||
local newtrain=advtrains.trains[newtrain_id]
|
||||
|
@ -757,11 +779,6 @@ function advtrains.split_train_at_wagon(wagon_id)
|
|||
newtrain.couple_lck_front=false
|
||||
train.couple_lck_back=false
|
||||
|
||||
--update train parts
|
||||
advtrains.update_trainpart_properties(old_id)
|
||||
recalc_end_index(train)
|
||||
run_callbacks_update(old_id, train)
|
||||
|
||||
end
|
||||
|
||||
-- coupling
|
||||
|
@ -778,7 +795,7 @@ local function createcouple(pos, train1, t1_is_front, train2, t2_is_front)
|
|||
le.train_id_2=train2.id
|
||||
le.t1_is_front=t1_is_front
|
||||
le.t2_is_front=t2_is_front
|
||||
atdebug("created couple between",train1.id,t1_is_front,train2.id,t2_is_front)
|
||||
--atdebug("created couple between",train1.id,t1_is_front,train2.id,t2_is_front)
|
||||
if t1_is_front then
|
||||
train1.cpl_front = obj
|
||||
else
|
||||
|
@ -793,7 +810,7 @@ local function createcouple(pos, train1, t1_is_front, train2, t2_is_front)
|
|||
end
|
||||
|
||||
function advtrains.train_check_couples(train)
|
||||
atdebug("rechecking couples")
|
||||
--atdebug("rechecking couples")
|
||||
if train.cpl_front then
|
||||
if not train.cpl_front:getyaw() then
|
||||
-- objectref is no longer valid. reset.
|
||||
|
@ -806,7 +823,7 @@ function advtrains.train_check_couples(train)
|
|||
for tid, idx in pairs(front_trains) do
|
||||
local other_train = advtrains.trains[tid]
|
||||
advtrains.train_ensure_init(tid, other_train)
|
||||
atdebug(train.id,"front: ",idx,"on",tid,atround(other_train.index),atround(other_train.end_index))
|
||||
--atdebug(train.id,"front: ",idx,"on",tid,atround(other_train.index),atround(other_train.end_index))
|
||||
if other_train.velocity == 0 then
|
||||
if idx>=other_train.index and idx<=other_train.index + CPL_ZONE then
|
||||
createcouple(pos, train, true, other_train, true)
|
||||
|
@ -924,8 +941,12 @@ function advtrains.invert_train(train_id)
|
|||
advtrains.update_trainpart_properties(train_id, true)
|
||||
end
|
||||
|
||||
-- returns: train id, index of one of the trains that stand at this position.
|
||||
function advtrains.get_train_at_pos(pos)
|
||||
return advtrains.occ.get_trains_at(pos)[1]
|
||||
local t = advtrains.occ.get_trains_at(pos)
|
||||
for tid,idx in pairs(t) do
|
||||
return tid, idx
|
||||
end
|
||||
end
|
||||
|
||||
function advtrains.invalidate_all_paths(pos)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
advtrains.wagons = {}
|
||||
advtrains.wagon_prototypes = {}
|
||||
advtrains.wagon_objects = {}
|
||||
|
||||
--
|
||||
function advtrains.create_wagon(wtype, owner)
|
||||
|
@ -21,7 +22,7 @@ function advtrains.create_wagon(wtype, owner)
|
|||
wgn.id = new_id
|
||||
---wgn.train_id = train_id --- will get this via update_trainpart_properties
|
||||
advtrains.wagons[new_id] = wgn
|
||||
atdebug("Created new wagon:",wgn)
|
||||
--atdebug("Created new wagon:",wgn)
|
||||
return new_id
|
||||
end
|
||||
|
||||
|
@ -60,9 +61,9 @@ function wagon:set_id(wid)
|
|||
self.initialized = true
|
||||
|
||||
local data = advtrains.wagons[self.id]
|
||||
advtrains.wagon_objects[self.id] = self.object
|
||||
|
||||
data.object = self.object
|
||||
atdebug("Created wagon entity:",self.name," w_id",wid," t_id",data.train_id)
|
||||
--atdebug("Created wagon entity:",self.name," w_id",wid," t_id",data.train_id)
|
||||
|
||||
if self.has_inventory then
|
||||
--to be used later
|
||||
|
@ -196,7 +197,7 @@ function wagon:destroy()
|
|||
if self.discouple then self.discouple.object:remove() end--will have no effect on unloaded objects
|
||||
end
|
||||
end
|
||||
atdebug("[wagon ", self.id, "]: destroying")
|
||||
--atdebug("[wagon ", self.id, "]: destroying")
|
||||
|
||||
self.object:remove()
|
||||
end
|
||||
|
@ -210,7 +211,7 @@ function wagon:on_step(dtime)
|
|||
local data = advtrains.wagons[self.id]
|
||||
|
||||
if not pos then
|
||||
atdebug("["..self.id.."][fatal] missing position (object:getpos() returned nil)")
|
||||
--atdebug("["..self.id.."][fatal] missing position (object:getpos() returned nil)")
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -437,7 +438,6 @@ function wagon:on_step(dtime)
|
|||
else
|
||||
train.recently_collided_with_env=true
|
||||
train.velocity=0
|
||||
-- TODO what should happen when a train collides?
|
||||
train.tarvelocity=0
|
||||
self.collision_count=(self.collision_count or 0)+1
|
||||
end
|
||||
|
@ -852,11 +852,7 @@ function wagon:handle_bordcom_fields(pname, formname, fields)
|
|||
end
|
||||
for i, tpid in ipairs(train.trainparts) do
|
||||
if fields["dcpl_"..i] then
|
||||
for _,wagon in pairs(minetest.luaentities) do
|
||||
if wagon.is_wagon and wagon.initialized and wagon.id==tpid then
|
||||
wagon:safe_decouple(pname) -- TODO: Move this into external function (don't search entity?)
|
||||
end
|
||||
end
|
||||
advtrains.safe_decouple_wagon(tpid, pname)
|
||||
end
|
||||
if i>1 and fields["dcpl_lck_"..i] then
|
||||
local ent = advtrains.wagons[tpid]
|
||||
|
@ -1026,26 +1022,10 @@ function wagon:reattach_all()
|
|||
end
|
||||
end
|
||||
|
||||
function wagon:safe_decouple(pname)
|
||||
if not minetest.check_player_privs(pname, "train_operator") then
|
||||
minetest.chat_send_player(pname, "Missing train_operator privilege")
|
||||
return false
|
||||
end
|
||||
local data = advtrains.wagons[self.id]
|
||||
if data.dcpl_lock then
|
||||
minetest.chat_send_player(pname, "Couple is locked (ask owner or admin to unlock it)")
|
||||
return false
|
||||
end
|
||||
atprint("wagon:discouple() Splitting train", self.train_id)
|
||||
advtrains.log("Discouple", pname, self.object:getpos(), self:train().text_outside)
|
||||
advtrains.split_train_at_wagon(self.id)--found in trainlogic.lua
|
||||
return true
|
||||
end
|
||||
|
||||
function advtrains.get_wagon_prototype(data)
|
||||
local wt = data.type
|
||||
if not advtrains.wagon_prototypes[wt] then
|
||||
atprint("Unable to load wagon type",wt,", using placeholder")
|
||||
if not data.type or not advtrains.wagon_prototypes[wt] then
|
||||
atwarn("Unable to load wagon type",wt,", using placeholder")
|
||||
wt="advtrains:wagon_placeholder"
|
||||
end
|
||||
return wt, advtrains.wagon_prototypes[wt]
|
||||
|
|
Loading…
Reference in New Issue