aboutsummaryrefslogtreecommitdiff
path: root/advtrains
diff options
context:
space:
mode:
authororwell96 <orwell@bleipb.de>2018-01-07 20:41:48 +0100
committerorwell96 <orwell@bleipb.de>2018-01-07 20:41:48 +0100
commit1f26781b6a79135159205231f580beb06e789d4d (patch)
treebd3effc793bc510922e76b407426dd06bc0907cc /advtrains
parent07442cfe8ff1a23053446c18e2ada854eeed18d8 (diff)
downloadadvtrains-1f26781b6a79135159205231f580beb06e789d4d.tar.gz
advtrains-1f26781b6a79135159205231f580beb06e789d4d.tar.bz2
advtrains-1f26781b6a79135159205231f580beb06e789d4d.zip
Change controls for trains (again)
Diffstat (limited to 'advtrains')
-rw-r--r--advtrains/init.lua2
-rw-r--r--advtrains/trainhud.lua74
-rw-r--r--advtrains/trainlogic.lua157
3 files changed, 154 insertions, 79 deletions
diff --git a/advtrains/init.lua b/advtrains/init.lua
index 99849cb..4834a45 100644
--- a/advtrains/init.lua
+++ b/advtrains/init.lua
@@ -271,7 +271,7 @@ advtrains.avt_save = function(remove_players_from_wagons)
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_state"
+ "atc_brake_target", "atc_wait_finish", "atc_command", "atc_delay", "door_open"
})
--then invalidate
if train.index then
diff --git a/advtrains/trainhud.lua b/advtrains/trainhud.lua
index 78c7624..9b7b9e8 100644
--- a/advtrains/trainhud.lua
+++ b/advtrains/trainhud.lua
@@ -1,9 +1,11 @@
--trainhud.lua: holds all the code for train controlling
advtrains.hud = {}
+advtrains.hhud = {}
minetest.register_on_leaveplayer(function(player)
advtrains.hud[player:get_player_name()] = nil
+advtrains.hhud[player:get_player_name()] = nil
end)
local mletter={[1]="F", [-1]="R", [0]="N"}
@@ -40,12 +42,23 @@ function advtrains.on_control_change(pc, train, flip)
end
--shift+use:see wagons.lua
else
+ local act=false
if pc.up then
- train.tarvelocity = math.min(train.tarvelocity + 1, maxspeed)
+ train.lever=4
+ act=true
+ end
+ if pc.jump then
+ train.lever = 1
+ act=true
end
if pc.down then
if train.velocity>0 then
- train.tarvelocity = math.max(train.tarvelocity - 1, 0)
+ if pc.jump then
+ train.lever = 0
+ else
+ train.lever = 2
+ end
+ act=true
else
train.movedir = -train.movedir
end
@@ -64,12 +77,7 @@ function advtrains.on_control_change(pc, train, flip)
train.door_open = train.movedir
end
end
- if train.brake_hold_state~=2 then
- train.brake = false
- end
- if pc.jump then
- train.brake = true
- end
+ train.active_control = act
if pc.aux1 then
--horn
end
@@ -109,6 +117,44 @@ function advtrains.set_trainhud(name, text)
hud.oldText=text
end
end
+function advtrains.set_help_hud(name, text)
+ local hud = advtrains.hhud[name]
+ local player=minetest.get_player_by_name(name)
+ if not player then
+ return
+ end
+ if not hud then
+ hud = {}
+ advtrains.hhud[name] = hud
+ hud.id = player:hud_add({
+ hud_elem_type = "text",
+ name = "ADVTRAINS_HELP",
+ number = 0xFFFFFF,
+ position = {x=1, y=0.3},
+ offset = {x=0, y=0},
+ text = text,
+ scale = {x=200, y=60},
+ alignment = {x=1, y=0},
+ })
+ hud.oldText=text
+ return
+ elseif hud.oldText ~= text then
+ player:hud_change(hud.id, "text", text)
+ hud.oldText=text
+ end
+end
+
+--train.lever:
+--Speed control lever in train, for new train control system.
+--[[
+Value Disp Control Meaning
+0 BB S+Space Emergency Brake
+1 B Space Normal Brake
+2 - S Roll
+3 o <none> Stay at speed
+4 + W Accelerate
+]]
+
function advtrains.hud_train_format(train, flip)
local fct=flip and -1 or 1
if not train then return "" end
@@ -118,9 +164,19 @@ function advtrains.hud_train_format(train, flip)
local tvel=advtrains.abs_ceil(train.tarvelocity)
local vel_kmh=advtrains.abs_ceil(advtrains.ms_to_kmh(train.velocity))
local tvel_kmh=advtrains.abs_ceil(advtrains.ms_to_kmh(train.tarvelocity))
+
+ local levers = "B - o +"
+ local tlev=train.lever
+ if train.velocity==0 and not train.active_control then tlev=1 end
+ if tlev == 0 then levers = ">BB< - o +" end
+ if tlev == 1 then levers = ">B< - o +" end
+ if tlev == 2 then levers = "B >-< o +" end
+ if tlev == 3 then levers = "B - >o< +" end
+ if tlev == 4 then levers = "B - o >+<" end
+
local topLine, firstLine, secondLine
- topLine=" ["..mletter[fct*train.movedir].."] "..doorstr[(train.door_open or 0) * train.movedir].." "..(train.brake and "="..( train.brake_hold_state==2 and "^" or "" ).."B=" or "")
+ topLine=" ["..mletter[fct*train.movedir].."] {"..levers.."} "..doorstr[(train.door_open or 0) * train.movedir]
firstLine=attrans("Speed:").." |"..string.rep("+", vel)..string.rep("_", max-vel).."> "..vel_kmh.." km/h"
secondLine=attrans("Target:").." |"..string.rep("+", tvel)..string.rep("_", max-tvel).."> "..tvel_kmh.." km/h"
diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua
index 4a0b26c..5681817 100644
--- a/advtrains/trainlogic.lua
+++ b/advtrains/trainlogic.lua
@@ -31,11 +31,20 @@ function endstep()
end
end
-advtrains.train_accel_force=2--per second and divided by number of wagons
-advtrains.train_brake_force=3--per second, not divided by number of wagons
-advtrains.train_roll_force=0.5--per second, not divided by number of wagons, acceleration when rolling without brake
-advtrains.train_emerg_force=10--for emergency brakes(when going off track)
-
+--acceleration for lever modes (trainhud.lua), per wagon
+local t_accel_all={
+ [0] = -10,
+ [1] = -3,
+ [2] = -0.5,
+ [4] = 0,
+}
+--acceleration per engine
+local t_accel_eng={
+ [0] = 0,
+ [1] = 0,
+ [2] = 0,
+ [4] = 2,
+}
advtrains.mainloop_trainlogic=function(dtime)
--build a table of all players indexed by pts. used by damage and door system.
@@ -226,15 +235,16 @@ function advtrains.train_step_a(id, train, dtime)
--- 3. handle velocity influences ---
local train_moves=(train.velocity~=0)
+ local tarvel_cap
if train.recently_collided_with_env then
- train.tarvelocity=0
+ tarvel_cap=0
if not train_moves then
train.recently_collided_with_env=nil--reset status when stopped
end
end
if train.locomotives_in_train==0 then
- train.tarvelocity=0
+ tarvel_cap=0
end
--- 3a. this can be useful for debugs/warnings and is used for check_trainpartload ---
@@ -250,86 +260,95 @@ function advtrains.train_step_a(id, train, dtime)
local pprint
if front_off_track and back_off_track then--allow movement in both directions
- if train.tarvelocity>1 then
- train.tarvelocity=1
- atprint("Train",t_info,"is off track at both ends. Clipping velocity to 1")
- pprint=true
- end
+ tarvel_cap=1
elseif front_off_track then--allow movement only backward
- if train.movedir==1 and train.tarvelocity>0 then
- train.tarvelocity=0
- atprint("Train",t_info,"is off track. Trying to drive further out. Velocity clipped to 0")
- pprint=true
+ if train.movedir==1 then
+ tarvel_cap=0
end
- if train.movedir==-1 and train.tarvelocity>1 then
- train.tarvelocity=1
- atprint("Train",t_info,"is off track. Velocity clipped to 1")
- pprint=true
+ if train.movedir==-1 then
+ tarvel_cap=1
end
elseif back_off_track then--allow movement only forward
- if train.movedir==-1 and train.tarvelocity>0 then
- train.tarvelocity=0
- atprint("Train",t_info,"is off track. Trying to drive further out. Velocity clipped to 0")
- pprint=true
+ if train.movedir==1 then
+ tarvel_cap=1
end
- if train.movedir==1 and train.tarvelocity>1 then
- train.tarvelocity=1
- atprint("Train",t_info,"is off track. Velocity clipped to 1")
- pprint=true
+ if train.movedir==-1 then
+ tarvel_cap=0
end
end
- if pprint then
- atprint("max_iot", train.max_index_on_track, "min_iot", train.min_index_on_track, "<> index", train.index, "end_index", train.end_index)
- end
- --interpret ATC command
- if train.atc_brake_target and train.atc_brake_target>=train.velocity then
- train.atc_brake_target=nil
- end
- if train.atc_wait_finish then
- if not train.atc_brake_target and train.velocity==train.tarvelocity then
- train.atc_wait_finish=nil
+ --interpret ATC command and apply auto-lever control when not actively controlled
+ local trainvelocity = train.velocity
+ if not train.lever then train.lever=3 end
+ if train.active_control then
+ advtrains.atc.train_reset_command(id)
+ else
+ if train.atc_brake_target and train.atc_brake_target>=trainvelocity then
+ train.atc_brake_target=nil
end
- end
- if train.atc_command then
- if train.atc_delay<=0 and not train.atc_wait_finish then
- advtrains.atc.execute_atc_command(id, train)
- else
- train.atc_delay=train.atc_delay-dtime
+ if train.atc_wait_finish then
+ if not train.atc_brake_target and train.velocity==train.tarvelocity then
+ train.atc_wait_finish=nil
+ end
+ end
+ if train.atc_command then
+ if train.atc_delay<=0 and not train.atc_wait_finish then
+ advtrains.atc.execute_atc_command(id, train)
+ else
+ train.atc_delay=train.atc_delay-dtime
+ end
+ end
+
+ train.lever = 3
+ if train.tarvelocity>trainvelocity then train.lever=4 end
+ if train.tarvelocity<trainvelocity then
+ if (train.atc_brake_target and train.atc_brake_target<trainvelocity) then
+ train.lever=1
+ else
+ train.lever=2
+ end
end
end
- --make brake adjust the tarvelocity if necessary
- if train.brake and (math.ceil(train.velocity)-1)<train.tarvelocity then
- train.tarvelocity=math.max((math.ceil(train.velocity)-1), 0)
+ if tarvel_cap and tarvel_cap<train.tarvelocity then
+ train.tarvelocity=tarvel_cap
+ end
+ local tmp_lever = train.lever
+ if tarvel_cap and trainvelocity>tarvel_cap then
+ tmp_lever = 0
end
--- 3a. actually calculate new velocity ---
- if train.velocity~=train.tarvelocity then
- local applydiff=0
- local mass=#train.trainparts
- local diff=train.tarvelocity-train.velocity
- if diff>0 then--accelerating, force will be brought on only by locomotives.
- --atprint("accelerating with default force")
- applydiff=(math.min((advtrains.train_accel_force*train.locomotives_in_train*dtime)/mass, math.abs(diff)))
- else--decelerating
- if front_off_track or back_off_track or train.recently_collided_with_env then --every wagon has a brake, so not divided by mass.
- --atprint("braking with emergency force")
- applydiff= -(math.min((advtrains.train_emerg_force*dtime), math.abs(diff)))
- elseif train.brake or (train.atc_brake_target and train.atc_brake_target<train.velocity) then
- --atprint("braking with default force")
- --no math.min, because it can grow beyond tarvelocity, see up there
- --dont worry, it will never fall below zero.
- applydiff= -((advtrains.train_brake_force*dtime))
- else
- --atprint("roll")
- applydiff= -(math.min((advtrains.train_roll_force*dtime), math.abs(diff)))
+ if tmp_lever~=3 then
+ local acc_all = t_accel_all[tmp_lever]
+ local acc_eng = t_accel_eng[tmp_lever]
+ local nwagons = #train.trainparts
+ local accel = acc_all + (acc_eng*train.locomotives_in_train)/nwagons
+ local vdiff = accel*dtime
+ if not train.active_control then
+ local tvdiff = train.tarvelocity - trainvelocity
+ if math.abs(vdiff) > math.abs(tvdiff) then
+ --applying this change would cross tarvelocity
+ vdiff=tvdiff
end
end
- train.last_accel=(applydiff*train.movedir)
- train.velocity=math.min(math.max( train.velocity+applydiff , 0), train.max_speed or 10)
+ if tarvel_cap and trainvelocity<=tarvel_cap and trainvelocity+vdiff>tarvel_cap then
+ vdiff = tarvel_cap - train.velocity
+ end
+ if trainvelocity+vdiff < 0 then
+ vdiff = - trainvelocity
+ end
+ local mspeed = (train.max_speed or 10)
+ if trainvelocity+vdiff > mspeed then
+ vdiff = mspeed - trainvelocity
+ end
+ train.last_accel=(vdiff*train.movedir)
+ train.velocity=train.velocity+vdiff
+ if train.active_control then
+ train.tarvelocity = train.velocity
+ end
else
- train.last_accel=0
+ train.last_accel = 0
end
--- 4. move train ---
l kwa"></span> <!--l. 97--><p class="indent" > <img src="10_home_moritz_Home_Projekte_Minetest_minetest____nual_img_Bildschirmfoto_2016-09-17_09-48-54.png" alt="PIC" > <!--l. 99--><p class="indent" > Bumpers are objects that are usually placed at the end of a track to prevent trains rolling off it. After placed, they can be rotated using the Trackworker. <!--l. 103--><p class="indent" > <img src="11_home_moritz_Home_Projekte_Minetest_minetest____nual_img_Bildschirmfoto_2016-09-17_09-50-27.png" alt="PIC" ><img src="12_home_moritz_Home_Projekte_Minetest_minetest____nual_img_Bildschirmfoto_2016-09-17_09-51-02.png" alt="PIC" > <!--l. 105--><p class="indent" > These are a regular analog signal and an electric signal. Like everything, you can rotate them using the Trackworker. Right-click or power with mesecons to signal trains that they can pass or have to stop. The signals do not have any effect on trains, they can only signal the driver. A more advanced signalling system (with distant signals/signal combinations) is planned. <!--l. 112--><p class="indent" > <img src="13_home_moritz_Home_Projekte_Minetest_minetest____nual_img_Bildschirmfoto_2016-09-17_09-58-39.png" alt="PIC" ><img src="14_home_moritz_Home_Projekte_Minetest_minetest____nual_img_Bildschirmfoto_2016-09-17_09-58-20.png" alt="PIC" > <!--l. 114--><p class="indent" > These are some platform nodes. I suggest using the left one, it&#8217;s only half height and looks better. These nodes also have a sandstone variant, craft with sandstone bricks <!--l. 118--><p class="indent" > <img src="15_home_moritz_Home_Projekte_Minetest_minetest____nual_img_Bildschirmfoto_2017-03-09_11-33-09.png" alt="PIC" > <!--l. 120--><p class="indent" > These detector rails turn adjacent mesecons on when a train is standing/driving over them. <!--l. 123--><p class="indent" > Notice: Detector rails and bumpers currently aren&#8217;t aligned to the regular tracks. This will be fixed soon. Meanwhile, you need to rotate them manually. <!--l. 127--><p class="indent" > <!--l. 127--><p class="noindent" ><span class="ecsx-1200">Trains</span> <!--l. 129--><p class="indent" > There are some wagons included in this modpack, however community members (namely mbb and Andrey) have made some more wagons that can be downloaded and enabled separately. Visit the forum topic (<a href="https://forum.minetest.net/viewtopic.php?f=11&t=14726" class="url" ><span class="ectt-1000">https://forum.minetest.net/viewtopic.php?f=11&amp;t=14726</span></a>) to download them. <!--l. 134--><p class="indent" > To see what&#8217;s included, look up in a craft guide or consult the creative mode inventory. <!--l. 137--><p class="indent" > To place wagons simply craft and click a track. To remove a wagon, punch it. Only the person who placed the wagon can do this. In survival if you destroy trains you get only some of your steel back, so you will be asked to confirm if you really want to destroy a wagon. <!--l. 142--><p class="indent" > <!--l. 142--><p class="noindent" ><span class="ecsx-1200">Driving</span> <span class="ecsx-1200">trains</span> <!--l. 144--><p class="indent" > Right-click any wagon to get on. This will attach you to the wagon and register you as passenger. Depending on how the wagon is set up, you are either in a passenger seat or inside a driver stand. Right-clicking again will show your possibilities on what you can do in/with the wagon. <!--l. 150--><p class="indent" > Example: <!--l. 152--><p class="indent" > <img src="16_home_moritz_Home_Projekte_Minetest_minetest____nual_img_Bildschirmfoto_2017-03-09_11-42-49.png" alt="PIC" > <!--l. 154--><p class="indent" > When entering a subway wagon, you are formally inside the passenger area. You can see this by the fact that there&#8217;s no head-up display. Right-clicking brings up this form. <!--l. 158--><p class="indent" > The first button will make you move to the Driver stand, so you can drive the train. <!--l. 161--><p class="indent" > The second button should say &#8220;Wagon properties&#8221; and appears only for the wagon owner. See &#8220;Wagon Properties&#8221;. <!--l. 164--><p class="indent" > The last button tells that the doors are closed, so you can&#8217;t get off at this time. If the doors are open or the wagon has no doors, this button says &#8220;Get off&#8221;. <!--l. 168--><p class="indent" > It is always possible to bypass closed doors and get off by holding the Sneak key and right-clicking the wagon or by holding Sneak and Use at the same time. Remember that this may result in your death when the train is travelling fast. <!--l. 173--><p class="indent" > The Japanese train and the Subway train support automatic getting on by just walking into the wagon. As soon as you stand on a platform and walk towards a door, you will automatically get on the wagon. On these, pressing W or S while inside the Passenger Area will also make you get off. <!--l. 179--><p class="indent" > <!--l. 179--><p class="noindent" ><span class="ecsx-1200">Train</span> <span class="ecsx-1200">controls</span> <!--l. 181--><p class="indent" > If you are inside a driver stand you are presented with a head-up display: <!--l. 184--><p class="indent" > The upper bar shows your current speed and the lower bar shows what speed you ordered the train to hold. Assuming you have the default controls (WASD, Shift for sneak, Space for jump), the following key bindings apply: <ul class="itemize1"> <li class="itemize">W - faster </li> <li class="itemize">S - slower / change direction </li> <li class="itemize">A / D &#8211; open/close doors </li> <li class="itemize">Space: brake (shown by =B=, target speed will be decreased automatically) </li> <li class="itemize">Sneak+S: set speed to 0 (train rolls out, brake to stop!) </li> <li class="itemize">Sneak+W: Set full speed </li> <li class="itemize">Sneak+A: Set speed to 4 (~40km/h) </li> <li class="itemize">Sneak+D: Set speed to 8 (~100km/h) </li> <li class="itemize">Sneak+Space: toggle brake (the brake will not release when releasing the keys, shown by =^B=)</li></ul> <!--l. 201--><p class="indent" > <!--l. 201--><p class="noindent" ><span class="ecsx-1200">Coupling</span> <span class="ecsx-1200">wagons</span> <!--l. 203--><p class="indent" > You just learned how to drive an engine. Now place a wagon anywhere and drive your engine slowly towards that wagon. As soon as they collided your engine will stop. Now get off and right-click the green icon that appeared between the engine and the train. You have coupled the wagon to the engine. <!--l. 209--><p class="indent" > <img src="17_home_moritz_Home_Projekte_Minetest_minetest____ssets_manual_img_screenshot_20161203_231622.png" alt="PIC" > <!--l. 211--><p class="indent" > To discouple a wagon, punch the red icon between the wagons you want to discouple while the train is standing. <!--l. 214--><p class="indent" > <!--l. 214--><p class="noindent" ><span class="ecsx-1200">Automatic</span> <span class="ecsx-1200">Train</span> <span class="ecsx-1200">Control</span> <span class="ecsx-1200">(ATC)</span> <!--l. 216--><p class="indent" > ATC rails allow you to automate train operation. There are two types of ATC rails: <!--l. 219--><p class="indent" > <!--l. 219--><p class="noindent" ><span class="ecsx-1000">Regular</span> <span class="ecsx-1000">ATC</span> <!--l. 221--><p class="indent" > The ATC rail does not have a crafting recipe. When placed, you can set a command and it will be sent to any train driving over the controller. <!--l. 224--><p class="indent" > Only the static mode is implemented, changing the mode has no effect. <!--l. 226--><p class="indent" > For a detailed explanation how ATC commands work and their syntax see atc_command.txt <!--l. 229--><p class="indent" > Note: to rotate ATC rails, you need to bypass the formspec that is set for the node. To do this, hold Sneak when right-clicking the rail with the trackworker tool. <!--l. 233--><p class="indent" > <!--l. 233--><p class="noindent" ><span class="ecsx-1000">LUA</span> <span class="ecsx-1000">ATC</span> <!--l. 235--><p class="indent" > The LUA ATC suite is part of the mod advtrains_luaautomation. The LUA ATC components are quite similar to Mesecons Luacontrollers and allow to create all kinds of automation systems. This tool is not intended for beginners or regular players, but for server admins who wish to create a heavily automated subway system. <!--l. 241--><p class="indent" > More information on those can be found inside the mod directory of advtrains_luaautomation. </body></html>