diff options
Diffstat (limited to 'advtrains/trainlogic.lua')
-rw-r--r-- | advtrains/trainlogic.lua | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua index 4650f9e..f136577 100644 --- a/advtrains/trainlogic.lua +++ b/advtrains/trainlogic.lua @@ -143,8 +143,11 @@ minetest.register_on_joinplayer(function(player) local id=advtrains.player_to_train_mapping[pname] if id then for _,wagon in pairs(minetest.luaentities) do - if wagon.is_wagon and wagon.initialized and wagon.train_id==id then - wagon:reattach_all() + if wagon.is_wagon and wagon.initialized and wagon.id then + local wdata = advtrains.wagons[wagon.id] + if wdata and wdata.train_id == id then + wagon:reattach_all() + end end end end @@ -251,6 +254,11 @@ local callbacks_update, run_callbacks_update = mkcallback("update") local callbacks_create, run_callbacks_create = mkcallback("create") local callbacks_remove, run_callbacks_remove = mkcallback("remove") +-- required to call from couple.lua +function advtrains.update_train_start_and_end(train) + recalc_end_index(train) + run_callbacks_update(train.id, train) +end -- train_ensure_init: responsible for creating a state that we can work on, after one of the following events has happened: -- - the train's path got cleared @@ -387,7 +395,7 @@ function advtrains.train_step_b(id, train, dtime) -- interlocking speed restriction elseif train.speed_restriction then --atprint("in train_step_b: applying interlocking speed restriction",train.speed_restriction) - sit_v_cap = train.speed_restriction + sit_v_cap = math.min(sit_v_cap or math.huge, train.speed_restriction) end --apply off-track handling: @@ -611,7 +619,7 @@ function advtrains.train_step_b(id, train, dtime) local base_cn = train.path_cn[base_idx] --atdebug(id,"Begin Checking for on-track collisions new_idx=",new_index_curr_tv,"base_idx=",base_idx,"base_pos=",base_pos,"base_cn=",base_cn) -- query occupation - local occ = advtrains.occ.get_trains_over(base_pos) + local occ = advtrains.occ.reverse_lookup_sel(base_pos, "close_proximity") -- iterate other trains for otid, ob_idx in pairs(occ) do if otid ~= id then @@ -641,9 +649,10 @@ function advtrains.train_step_b(id, train, dtime) -- Phase 2 - project ref_index back onto our path and check again (necessary because there might be a turnout on the way and we are driving into the flank if target_is_inside then - local our_index = advtrains.path_project(otrn, ref_index, id) + local our_index = advtrains.path_project(otrn, ref_index, id, "before_end") --atdebug("Backprojected our_index",our_index) - if our_index and our_index <= new_index_curr_tv then + if our_index and our_index <= new_index_curr_tv + and our_index >= train.index then --FIX: If train was already past the collision point in the previous step, there is no collision! Fixes bug with split_at_index -- ON_TRACK COLLISION IS HAPPENING -- the actual collision is handled in train_step_c, so set appropriate signal variables train.ontrack_collision_info = { @@ -1044,7 +1053,16 @@ function advtrains.update_trainpart_properties(train_id, invert_flipstate) if data then local wagon = advtrains.wagon_prototypes[data.type or data.entity_name] if not wagon then - atwarn("Wagon '",data.type,"' couldn't be found. Please check that all required modules are loaded!") + local ent = advtrains.wagon_objects[w_id] + local pdesc + if ent then + pdesc = "at " .. minetest.pos_to_string(ent:get_pos()) + elseif train.last_pos then + pdesc = "near " .. minetest.pos_to_string(train.last_pos) + else + pdesc = "at an unknown location" + end + atwarn(string.format("Wagon %q %s could not be found. Please check that all required modules are loaded!", data.type, pdesc)) wagon = advtrains.wagon_prototypes["advtrains:wagon_placeholder"] end @@ -1113,6 +1131,7 @@ end 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. + --atdebug("split_train_at_index invoked on",train.id,"index",index) local train_id=train.id if index > #train.trainparts then @@ -1135,6 +1154,7 @@ function advtrains.split_train_at_index(train, index) 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) + --atdebug("new train position p_index",p_index,"pos",pos,"connid",connid,"frac",frac) local tp = {} for k,v in ipairs(train.trainparts) do if k >= index then @@ -1144,12 +1164,14 @@ function advtrains.split_train_at_index(train, index) end advtrains.update_trainpart_properties(train_id) recalc_end_index(train) + --atdebug("old train index",train.index,"end_index",train.end_index) run_callbacks_update(train_id, train) --create subtrain local newtrain_id=advtrains.create_new_train_at(pos, connid, frac, tp) local newtrain=advtrains.trains[newtrain_id] - + --atdebug("new train created with ID",newtrain_id,"index",newtrain.index,"end_index",newtrain.end_index) + newtrain.velocity=train.velocity -- copy various properties from the old to the new train newtrain.door_open = train.door_open @@ -1158,6 +1180,7 @@ function advtrains.split_train_at_index(train, index) newtrain.line = train.line newtrain.routingcode = train.routingcode newtrain.speed_restriction = train.speed_restriction + newtrain.speed_restrictions_t = table.copy(train.speed_restrictions_t or {main=train.speed_restriction}) newtrain.is_shunt = train.is_shunt newtrain.points_split = advtrains.merge_tables(train.points_split) newtrain.autocouple = train.autocouple @@ -1195,15 +1218,14 @@ function advtrains.invert_train(train_id) advtrains.update_trainpart_properties(train_id, true) -- recalculate path - advtrains.train_ensure_init(train_id, train) -- If interlocking present, check whether this train is in a section and then set as shunt move after reversion if advtrains.interlocking and train.il_sections and #train.il_sections > 0 then train.is_shunt = true - train.speed_restriction = advtrains.SHUNT_SPEED_MAX + advtrains.speed.set_restriction(train, "main", advtrains.SHUNT_SPEED_MAX) else train.is_shunt = false - train.speed_restriction = nil + advtrains.speed.set_restriction(train, "main", -1) end end @@ -1221,7 +1243,7 @@ function advtrains.invalidate_all_paths(pos) local tab if pos then -- if position given, check occupation system - tab = advtrains.occ.get_trains_over(pos) + tab = advtrains.occ.reverse_lookup_quick(pos) else tab = advtrains.trains end @@ -1234,7 +1256,7 @@ end -- Calls invalidate_path_ahead on all trains occupying (having paths over) this node -- Can be called during train step. function advtrains.invalidate_all_paths_ahead(pos) - local tab = advtrains.occ.get_trains_over(pos) + local tab = advtrains.occ.reverse_lookup_sel(pos, "first_ahead") for id,index in pairs(tab) do local train = advtrains.trains[id] |