diff options
-rw-r--r-- | advtrains/lzb.lua | 9 | ||||
-rw-r--r-- | advtrains/occupation.lua | 43 | ||||
-rw-r--r-- | advtrains/trainlogic.lua | 92 | ||||
-rw-r--r-- | advtrains/wagons.lua | 15 | ||||
-rwxr-xr-x | advtrains_train_steam/init.lua | 23 |
5 files changed, 56 insertions, 126 deletions
diff --git a/advtrains/lzb.lua b/advtrains/lzb.lua index afbf68e..6cbf4ab 100644 --- a/advtrains/lzb.lua +++ b/advtrains/lzb.lua @@ -85,9 +85,9 @@ end --[[ Distance needed to accelerate from v0 to v1 with constant acceleration a: - v1 - v0 a / v1 - v0 \ 2 -s = v0 * ------- + - * | ------- | - a 2 \ a / + v1 - v0 a / v1 - v0 \ 2 v1^2 - v0^2 +s = v0 * ------- + - * | ------- | = ----------- + a 2 \ a / 2*a ]] local function apply_control(id, train) @@ -112,8 +112,7 @@ local function apply_control(id, train) local v0 = train.velocity local v1 = it.spd if v1 and v1 <= v0 then - local f = (v1-v0) / a - local s = v0*f + a*f*f/2 + local s = (v1*v1 - v0*v0) / (2*a) local st = s + params.ADD_SLOW if v0 > 3 then diff --git a/advtrains/occupation.lua b/advtrains/occupation.lua index f5c7d88..da60278 100644 --- a/advtrains/occupation.lua +++ b/advtrains/occupation.lua @@ -1,48 +1,7 @@ -- occupation.lua --[[ Collects and manages positions where trains occupy and/or reserve/require space -THIS SECTION ABOVE IS OUTDATED, look below - -Zone diagram of a train: - |___| |___| --> Direction of travel - oo oo+oo oo -=|=======|===|===========|===|=======|===================|========|=== - |SafetyB|CpB| Train |CpF|SafetyF| Brake |Aware | -[1] [2] [3] [4] [5] [6] [7] [8] - -ID|Name |Desc - 0 Free Zone that was occupied before, which has now been left - 1 Train Zone where the train actually is. - 2 SafetyB Safety zone behind the train. extends 4m - 3 SafetyF Safety zone in front of the train. extends 4m - If a train is about to enter this zone, immediately brake it down to 2 - 4 CpB Backside coupling zone. If the coupling zones of 2 trains overlap, they can be coupled - 5 CpF Frontside coupling zone - 6 Brake Brake distance of the train. Extends to the point ~5 nodes in front - of the point where the train would stop if it would regularily brake now. - 7 Aware Awareness zone. Extends 10-20 nodes beyond the Brake zone - Whenever any of the non-aware zones of other trains are detected here, the train will start to brake. - -Table format: -occ[y][x][z] = { - [1] = train 1 id - [2] = train 1 ZoneID -// [3] = entry seqnum* - ... - [2n-1] = train n id - [2n ] = train n ZoneID -// [3n-2] = train n id -// [3n-1] = train n ZoneID -// [3n ] = entry seqnum* -} -occ_chg[n] = { - pos = vector, - train_id, - old_val, (0 when entry did not exist before) - new_val, (0 when entry was deleted) -} - ---------------------- + It turned out that, especially for the TSS, some more, even overlapping zones are required. Packing those into a data structure would just become a huge mess! Instead, this occupation system will store the path indices of positions in the corresponding. diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua index 86f60c1..580a7d4 100644 --- a/advtrains/trainlogic.lua +++ b/advtrains/trainlogic.lua @@ -703,40 +703,6 @@ advtrains.te_register_on_remove(function(id, train) --atdebug(id,"tnc remove",train.index,train.end_index) end) --- Calculates the indices where the window borders of the occupation windows are. --- TODO adapt this code to new system, probably into a callback (probably only the brake distance code is needed) -local function calc_occwindows(id, train) - local end_index = advtrains.path_get_index_by_offset(train, train.index, -train.trainlen) - train.end_index = end_index - local cpl_b = end_index - COUPLE_ZONE - local safety_b = advtrains.path_get_index_by_offset(train, cpl_b, -SAFETY_ZONE) - local cpl_f = end_index + COUPLE_ZONE - local safety_f = advtrains.path_get_index_by_offset(train, cpl_f, SAFETY_ZONE) - - -- calculate brake distance - local acc_all = t_accel_all[1] - local acc_eng = t_accel_eng[1] - local nwagons = #train.trainparts - local acc = acc_all + (acc_eng*train.locomotives_in_train)/nwagons - local vel = train.velocity - local brakedst = (vel*vel) / (2*acc) - - local brake_i = math.max(advtrains.path_get_index_by_offset(train, train.index, brakedst + BRAKE_SPACE), safety_f) - local aware_i = advtrains.path_get_index_by_offset(train, brake_i, AWARE_ZONE) - - return { - safety_b, - cpl_b, - end_index, - train.index, - cpl_f, - safety_f, - brake_i, - aware_i, - } -end - - --returns new id function advtrains.create_new_train_at(pos, connid, ioff, trainparts) local new_id=advtrains.random_id() @@ -985,21 +951,23 @@ function advtrains.train_check_couples(train) if not train.cpl_front then -- recheck front couple local front_trains, pos = advtrains.occ.get_occupations(train, atround(train.index) + CPL_CHK_DST) - for tid, idx in pairs(front_trains) do - local other_train = advtrains.trains[tid] - if not advtrains.train_ensure_init(tid, other_train) then - atwarn("Train",tid,"is not initialized! Couldn't check couples!") - return - end - --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) - break + if minetest.get_node_or_nil(pos) then -- if the position is loaded... + for tid, idx in pairs(front_trains) do + local other_train = advtrains.trains[tid] + if not advtrains.train_ensure_init(tid, other_train) then + atwarn("Train",tid,"is not initialized! Couldn't check couples!") + return end - if idx<=other_train.end_index and idx>=other_train.end_index - CPL_ZONE then - createcouple(pos, train, true, other_train, false) - break + --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) + break + end + if idx<=other_train.end_index and idx>=other_train.end_index - CPL_ZONE then + createcouple(pos, train, true, other_train, false) + break + end end end end @@ -1013,20 +981,22 @@ function advtrains.train_check_couples(train) if not train.cpl_back then -- recheck back couple local back_trains, pos = advtrains.occ.get_occupations(train, atround(train.end_index) - CPL_CHK_DST) - for tid, idx in pairs(back_trains) do - local other_train = advtrains.trains[tid] - if not advtrains.train_ensure_init(tid, other_train) then - atwarn("Train",tid,"is not initialized! Couldn't check couples!") - return - end - if other_train.velocity == 0 then - if idx>=other_train.index and idx<=other_train.index + CPL_ZONE then - createcouple(pos, train, false, other_train, true) - break + if minetest.get_node_or_nil(pos) then -- if the position is loaded... + for tid, idx in pairs(back_trains) do + local other_train = advtrains.trains[tid] + if not advtrains.train_ensure_init(tid, other_train) then + atwarn("Train",tid,"is not initialized! Couldn't check couples!") + return end - if idx<=other_train.end_index and idx>=other_train.end_index - CPL_ZONE then - createcouple(pos, train, false, other_train, false) - break + if other_train.velocity == 0 then + if idx>=other_train.index and idx<=other_train.index + CPL_ZONE then + createcouple(pos, train, false, other_train, true) + break + end + if idx<=other_train.end_index and idx>=other_train.end_index - CPL_ZONE then + createcouple(pos, train, false, other_train, false) + break + end end end end diff --git a/advtrains/wagons.lua b/advtrains/wagons.lua index 924762c..4dbe85c 100644 --- a/advtrains/wagons.lua +++ b/advtrains/wagons.lua @@ -432,17 +432,10 @@ function wagon:on_step(dtime) end
end
if collides then
- if self.collision_count and self.collision_count>10 then
- --enable collision mercy to get trains stuck in walls out of walls
- --actually do nothing except limiting the velocity to 1
- train.velocity=math.min(train.velocity, 1)
- else
- train.recently_collided_with_env=true
- train.velocity=0
- self.collision_count=(self.collision_count or 0)+1
- end
- else
- self.collision_count=nil
+ -- screw collision mercy
+ train.recently_collided_with_env=true
+ train.velocity=0
+ advtrains.atc.train_reset_command(train)
end
end
diff --git a/advtrains_train_steam/init.lua b/advtrains_train_steam/init.lua index db2d087..5d6955c 100755 --- a/advtrains_train_steam/init.lua +++ b/advtrains_train_steam/init.lua @@ -5,6 +5,9 @@ else S = function(s,a,...)a={a,...}return s:gsub("@(%d+)",function(n)return a[tonumber(n)]end)end end +-- length of the steam engine loop sound +local SND_LOOP_LEN = 5 + advtrains.register_wagon("newlocomotive", { mesh="advtrains_engine_steam.b3d", textures = {"advtrains_engine_steam.png"}, @@ -111,14 +114,20 @@ advtrains.register_wagon("detailed_steam_engine", { self.object:set_animation({x=1,y=80}, advtrains.abs_ceil(velocity)*15, 0, true) self.old_anim_velocity=advtrains.abs_ceil(velocity) end - if velocity > 0 and not self.sound_loop_handle then - self.sound_loop_handle = minetest.sound_play({name="advtrains_steam_loop", gain=2}, {object = self.object, loop=true}) - elseif velocity==0 then - if self.sound_loop_handle then - minetest.sound_stop(self.sound_loop_handle) - self.sound_loop_handle = nil + end, + custom_on_step=function(self, dtime) + if self:train().velocity > 0 then -- First make sure that the train isn't standing + if not self.sound_loop_tmr or self.sound_loop_tmr <= 0 then + -- start the sound if it was never started or has expired + self.sound_loop_handle = minetest.sound_play({name="advtrains_steam_loop", gain=2}, {object=self.object}) + self.sound_loop_tmr = SND_LOOP_LEN end - end + --decrease the sound timer + self.sound_loop_tmr = self.sound_loop_tmr - dtime + else + -- If the train is standing, the sound will be stopped in some time. We do not need to interfere with it. + self.sound_loop_tmr = nil + end end, custom_on_activate = function(self, staticdata_table, dtime_s) minetest.add_particlespawner({ |