update advtrains

This commit is contained in:
Sergei Mozhaisky 2019-12-16 10:20:03 +00:00
parent eae328ced3
commit 4acb48aa39
54 changed files with 208 additions and 234 deletions

View File

@ -0,0 +1,60 @@
minetest.register_craft({
output = 'advtrains:across_off',
recipe = {
{'dye:red', 'default:steel_ingot', 'dye:red'},
{'', 'default:steel_ingot', ''},
{'', 'default:steel_ingot', ''},
},
})
minetest.register_craft({
output = 'advtrains:signal_wall_l_off',
recipe = {
{'default:steel_ingot', '', ''},
{'default:torch', 'dye:red', 'dye:green'},
{'default:steel_ingot', '', ''},
},
})
minetest.register_craft({
output = 'advtrains:signal_wall_r_off',
recipe = {
{'', '', 'default:steel_ingot'},
{'dye:green', 'dye:red', 'default:torch'},
{'', '', 'default:steel_ingot'},
},
})
minetest.register_craft({
output = 'advtrains:signal_wall_t_off',
recipe = {
{'default:steel_ingot', 'default:torch', 'default:steel_ingot'},
{'', 'dye:red', ''},
{'', 'dye:green', ''},
},
})
if minetest.get_modpath("technic") then
minetest.register_craft({
output = 'advtrains:dtrack_placer 49',
recipe = {
{'technic:zinc_ingot', 'group:stick', 'technic:zinc_ingot'},
{'technic:zinc_ingot', 'group:stick', 'technic:zinc_ingot'},
{'technic:zinc_ingot', 'group:stick', 'technic:zinc_ingot'},
},
})
minetest.register_craft({
output = 'advtrains:dtrack_placer 49',
recipe = {
{'technic:lead_ingot', 'group:stick', 'technic:lead_ingot'},
{'technic:lead_ingot', 'group:stick', 'technic:lead_ingot'},
{'technic:lead_ingot', 'group:stick', 'technic:lead_ingot'},
},
})
end

View File

@ -13,6 +13,10 @@ if minetest.get_modpath("nixie_tubes") then
dofile(MP.."/craft/nixie_tubes.lua")
end
if minetest.get_modpath("advtrains") then
dofile(MP.."/craft/advtrains.lua")
end
if minetest.get_modpath("advtrains_luaautomation") then
dofile(MP.."/craft/advtrains_luaautomation.lua")
end

View File

@ -2,40 +2,15 @@
--crafting.lua
--registers crafting recipes
if minetest.get_modpath("technic") then
minetest.register_craft({
output = 'advtrains:dtrack_placer 49',
recipe = {
{'technic:zinc_ingot', 'group:stick', 'technic:zinc_ingot'},
{'technic:zinc_ingot', 'group:stick', 'technic:zinc_ingot'},
{'technic:zinc_ingot', 'group:stick', 'technic:zinc_ingot'},
},
})
minetest.register_craft({
output = 'advtrains:dtrack_placer 49',
recipe = {
{'technic:lead_ingot', 'group:stick', 'technic:lead_ingot'},
{'technic:lead_ingot', 'group:stick', 'technic:lead_ingot'},
{'technic:lead_ingot', 'group:stick', 'technic:lead_ingot'},
},
})
end
--tracks
minetest.register_craft({
output = 'advtrains:dtrack_placer 49',
output = 'advtrains:dtrack_placer 50',
recipe = {
{'default:steel_ingot', 'group:stick', 'default:steel_ingot'},
{'default:steel_ingot', 'group:stick', 'default:steel_ingot'},
{'default:steel_ingot', 'group:stick', 'default:steel_ingot'},
},
})
minetest.register_craft({
type = "shapeless",
output = 'advtrains:dtrack_slopeplacer 2',
@ -49,7 +24,7 @@ minetest.register_craft({
minetest.register_craft({
output = 'advtrains:dtrack_bumper_placer 2',
recipe = {
{'default:wood', 'dye:red'},
{'group:wood', 'dye:red'},
{'default:steel_ingot', 'default:steel_ingot'},
{'advtrains:dtrack_placer', 'advtrains:dtrack_placer'},
},
@ -131,44 +106,5 @@ minetest.register_craft({
})
minetest.register_craft({
output = 'advtrains:across_off',
recipe = {
{'dye:red', 'default:steel_ingot', 'dye:red'},
{'', 'default:steel_ingot', ''},
{'', 'default:steel_ingot', ''},
},
})
minetest.register_craft({
output = 'advtrains:signal_wall_l_off',
recipe = {
{'default:steel_ingot', '', ''},
{'default:torch', 'dye:red', 'dye:green'},
{'default:steel_ingot', '', ''},
},
})
minetest.register_craft({
output = 'advtrains:signal_wall_r_off',
recipe = {
{'', '', 'default:steel_ingot'},
{'dye:green', 'dye:red', 'default:torch'},
{'', '', 'default:steel_ingot'},
},
})
minetest.register_craft({
output = 'advtrains:signal_wall_t_off',
recipe = {
{'default:steel_ingot', 'default:torch', 'default:steel_ingot'},
{'', 'dye:red', ''},
{'', 'dye:green', ''},
},
})
--misc_nodes
--crafts for platforms see misc_nodes.lua

View File

@ -5,9 +5,13 @@ advtrains.log = function() end
if minetest.settings:get_bool("advtrains_enable_logging") then
advtrains.logfile = advtrains.fpath .. "_log"
local log = io.open(advtrains.logfile, "a+")
function advtrains.log (event, player, pos, data)
local log = io.open(advtrains.logfile, "a+")
log:write(os.date()..": "..event.." by "..player.." at "..minetest.pos_to_string(pos).." -- "..(data or "").."\n")
log:close()
end
minetest.register_on_shutdown(function()
log:close()
end)
end

View File

@ -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

View File

@ -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.

View File

@ -17,12 +17,18 @@
-- path_cn - Connid of the current node that points towards path[i+1]
-- path_cp - Connid of the current node that points towards path[i-1]
-- When the day comes on that path!=node, these will only be set if this index represents a transition between rail nodes
-- path_dist - The distance (in meters) between this (path[i]) and the next (path[i+1]) item of the path
-- path_dist - The total distance of this path element from path element 0
-- path_dir - The direction of this path item's transition to the next path item, which is the angle of conns[path_cn[i]].c
--Variables:
-- path_ext_f/b - how far path[i] is set
-- path_trk_f/b - how far the path extends along a track. beyond those values, paths are generated in a straight line.
-- path_req_f/b - how far path items were requested in the last step
--
--Distance and index:
-- There is an important difference between the path index and the actual distance on the track: The distance between two path items can be larger than 1,
-- but the corresponding index increment is still 1.
-- Indexes in advtrains can be fractional values. If they are, it means that the actual position is interpolated between the 2 adjacent path items.
-- If you need to proceed along the path by a specific actual distance, it does NOT work to simply add it to the index. You should use the path_get_index_by_offset() function.
-- creates the path data structure, reconstructing the train from a position and a connid
-- Important! train.drives_on must exist while calling this method
@ -40,7 +46,7 @@ function advtrains.path_create(train, pos, connid, rel_index)
train.path = { [0] = { x=posr.x, y=posr.y+rhe, z=posr.z } }
train.path_cn = { [0] = connid }
train.path_cp = { [0] = mconnid }
train.path_dist = {}
train.path_dist = { [0] = 0 }
train.path_dir = {
[0] = advtrains.conn_angle_median(conns[mconnid].c, conns[connid].c)
@ -135,12 +141,12 @@ function advtrains.path_print(train, printf)
printf("path_print: Path is invalidated/inexistant.")
return
end
printf("i: CP Position Dir CN ->Dist->")
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],"->")
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
@ -156,7 +162,9 @@ function advtrains.path_get(train, index)
if index ~= atfloor(index) then
error("For train "..train.id..": Called path_get() but index="..index.." is not a round number")
end
local pef = train.path_ext_f
-- generate forward (front of train, positive)
while index > pef do
local pos = train.path[pef]
local connid = train.path_cn[pef]
@ -183,10 +191,13 @@ function advtrains.path_get(train, index)
train.path_dir[pef] = train.path_dir[pef-1]
end
train.path[pef] = adj_pos
train.path_dist[pef - 1] = vector.distance(pos, adj_pos)
train.path_dist[pef] = train.path_dist[pef-1] + vector.distance(pos, adj_pos)
end
train.path_ext_f = pef
local peb = train.path_ext_b
-- generate backward (back of train, negative)
while index < peb do
local pos = train.path[peb]
local connid = train.path_cp[peb]
@ -213,7 +224,7 @@ function advtrains.path_get(train, index)
train.path_dir[peb] = train.path_dir[peb+1]
end
train.path[peb] = adj_pos
train.path_dist[peb] = vector.distance(pos, adj_pos)
train.path_dist[peb] = train.path_dist[peb+1] - vector.distance(pos, adj_pos)
end
train.path_ext_b = peb
@ -256,37 +267,53 @@ function advtrains.path_get_adjacent(train, index)
return p_floor, p_ceil, frac
end
local function n_interpolate(s, e, f)
return s + (e-s)*f
end
-- This function determines the index resulting from moving along the path by 'offset' meters
-- starting from 'index'. See also the comment on the top of the file.
function advtrains.path_get_index_by_offset(train, index, offset)
local off = offset
local idx = atfloor(index)
-- go down to floor. Calculate required path_dist
advtrains.path_get_adjacent(train, idx)
off = off + ((index-idx) * train.path_dist[idx])
--atdebug("pibo: 1 off=",off,"idx=",idx," index=",index)
-- Step 1: determine my current absolute pos on the path
local start_index_f = math.floor(index)
local _, _, frac = advtrains.path_get_adjacent(train, index)
local dist1, dist2 = train.path_dist[start_index_f], train.path_dist[start_index_f+1]
local start_dist = n_interpolate(dist1, dist2, frac)
-- then walk the path back until we overshoot (off becomes >=0)
while off<0 do
idx = idx - 1
advtrains.path_get_adjacent(train, idx)
off = off + train.path_dist[idx]
end
--atdebug("pibo: 2 off=",off,"idx=",idx)
-- then walk the path forward until we would overshoot
while off - train.path_dist[idx] >= 0 do
idx = idx + 1
advtrains.path_get_adjacent(train, idx)
if not train.path_dist[idx] then
for i=-5,5 do
atdebug(idx+i,train.path_dist[idx+i])
end
end
off = off - train.path_dist[idx]
end
--atdebug("pibo: 3 off=",off,"idx=",idx," returns:",idx + (off / train.path_dist[idx]))
-- we should now be on the floor of the index we actually want.
-- give them the rest!
-- Step 2: determine the total end distance and estimate the index we'd come out
local end_dist = start_dist + offset
return idx + (off / train.path_dist[idx])
local c_idx = math.floor(index + offset)
-- Step 3: move forward/backward to find real index
-- We assume here that the distance between 2 path items is never smaller than 1.
-- Our estimated index is therefore either exact or too far over, and we're going to go back
-- towards the origin. It is therefore sufficient to query path_get a single time
-- How we'll adjust c_idx
-- Desired position: -------#------
-- Path items : --|--|--|--|--
-- c_idx : ^
advtrains.path_get_adjacent(train, c_idx)
while train.path_dist[c_idx] < end_dist do
c_idx = c_idx + 1
end
while train.path_dist[c_idx] > end_dist do
c_idx = c_idx - 1
end
-- Step 4: now c_idx points to the place shown above. Find out the fractional part.
dist1, dist2 = train.path_dist[c_idx], train.path_dist[c_idx+1]
frac = (end_dist - dist1) / (dist2 - dist1)
assert(frac>=0 and frac<1, frac)
return c_idx + frac
end
local PATH_CLEAR_KEEP = 4

View File

Before

Width:  |  Height:  |  Size: 302 B

After

Width:  |  Height:  |  Size: 302 B

View File

Before

Width:  |  Height:  |  Size: 524 B

After

Width:  |  Height:  |  Size: 524 B

View File

Before

Width:  |  Height:  |  Size: 413 B

After

Width:  |  Height:  |  Size: 413 B

View File

Before

Width:  |  Height:  |  Size: 309 B

After

Width:  |  Height:  |  Size: 309 B

View File

Before

Width:  |  Height:  |  Size: 339 B

After

Width:  |  Height:  |  Size: 339 B

View File

Before

Width:  |  Height:  |  Size: 293 B

After

Width:  |  Height:  |  Size: 293 B

View File

Before

Width:  |  Height:  |  Size: 352 B

After

Width:  |  Height:  |  Size: 352 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 193 B

After

Width:  |  Height:  |  Size: 193 B

View File

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 856 B

After

Width:  |  Height:  |  Size: 856 B

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

Before

Width:  |  Height:  |  Size: 328 B

After

Width:  |  Height:  |  Size: 328 B

View File

Before

Width:  |  Height:  |  Size: 582 B

After

Width:  |  Height:  |  Size: 582 B

View File

Before

Width:  |  Height:  |  Size: 328 B

After

Width:  |  Height:  |  Size: 328 B

View File

@ -116,8 +116,10 @@ function advtrains.tp_player_to_train(player)
player:setpos(train.last_pos)
end
end
minetest.register_on_joinplayer(function()
minetest.register_on_joinplayer(function(player)
return advtrains.pcall(function()
advtrains.hud[player:get_player_name()] = nil
advtrains.hhud[player:get_player_name()] = nil
--independent of this, cause all wagons of the train which are loaded to reattach their players
--needed because already loaded wagons won't call reattach_all()
for _,wagon in pairs(minetest.luaentities) do
@ -472,7 +474,8 @@ function advtrains.train_step_b(id, train, dtime)
--- 4. move train ---
local pdist = train.path_dist[math.floor(train.index)] or 1
local idx_floor = math.floor(train.index)
local pdist = (train.path_dist[idx_floor+1] - train.path_dist[idx_floor])
local distance = (train.velocity*dtime) / pdist
--debugging code
@ -703,40 +706,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 +954,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 +984,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

View File

@ -45,6 +45,7 @@ local wagon={
textures = {"black.png"},
is_wagon=true,
wagon_span=1,--how many index units of space does this wagon consume
wagon_width=3, -- Wagon width in meters
has_inventory=false,
static_save=false,
}
@ -113,6 +114,12 @@ function wagon:set_id(wid)
minetest.after(0.2, function() self:reattach_all() end)
if self.set_textures then
self:set_textures(data)
end
if self.custom_on_activate then
self:custom_on_activate()
end
@ -166,23 +173,30 @@ function wagon:on_punch(puncher, time_from_last_punch, tool_capabilities, direct
minetest.chat_send_player(puncher:get_player_name(), attrans("This wagon is owned by @1, you can't destroy it.", data.owner));
return
end
if #(self:train().trainparts)>1 then
minetest.chat_send_player(puncher:get_player_name(), attrans("Wagon needs to be decoupled from other wagons in order to destroy it."));
return
end
local pc=puncher:get_player_control()
if not pc.sneak then
minetest.chat_send_player(puncher:get_player_name(), attrans("Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon."))
return
end
if self.custom_may_destroy then
if not self.custom_may_destroy(self, puncher, time_from_last_punch, tool_capabilities, direction) then
return
end
end
local itemstack = puncher:get_wielded_item()
-- WARNING: This part of the API is guaranteed to change! DO NOT USE!
if self.set_livery and itemstack:get_name() == "bike:painter" then
self:set_livery(puncher, itemstack, data)
return
end
if #(self:train().trainparts)>1 then
minetest.chat_send_player(puncher:get_player_name(), attrans("Wagon needs to be decoupled from other wagons in order to destroy it."));
return
end
local pc=puncher:get_player_control()
if not pc.sneak then
minetest.chat_send_player(puncher:get_player_name(), attrans("Warning: If you destroy this wagon, you only get some steel back! If you are sure, hold Sneak and left-click the wagon."))
return
end
if not self:destroy() then return end
local inv = puncher:get_inventory()
@ -418,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
@ -694,12 +701,17 @@ function wagon:get_off(seatno)
local fct=data.wagon_flipped and -1 or 1
local aci = advtrains.path_get_index_by_offset(train, index, ino*fct)
local ix1, ix2 = advtrains.path_get_adjacent(train, aci)
local d = train.door_open
if self.wagon_width then
d = d * math.floor(self.wagon_width/2)
end
-- the two wanted positions are ix1 and ix2 + (2nd-1st rotated by 90deg)
-- (x z) rotated by 90deg is (-z x) (http://stackoverflow.com/a/4780141)
local add = { x = (ix2.z-ix1.z)*train.door_open, y = 0, z = (ix1.x-ix2.x)*train.door_open }
local oadd = { x = (ix2.z-ix1.z)*train.door_open*2, y = 1, z = (ix1.x-ix2.x)*train.door_open*2}
local add = { x = (ix2.z-ix1.z)*d, y = 0, z = (ix1.x-ix2.x)*d }
local oadd = { x = (ix2.z-ix1.z)*(d+train.door_open), y = 1, z = (ix1.x-ix2.x)*(d+train.door_open)}
local platpos=vector.round(vector.add(ix1, add))
local offpos=vector.round(vector.add(ix1, oadd))
--atdebug("platpos:", platpos, "offpos:", offpos)
if minetest.get_item_group(minetest.get_node(platpos).name, "platform")>0 then
minetest.after(GETOFF_TP_DELAY, function() clicker:setpos(offpos) end)