aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--advtrains.zipbin1575449 -> 1575848 bytes
-rw-r--r--init.lua14
-rw-r--r--trainhud.lua97
-rw-r--r--trainlogic.lua44
-rw-r--r--wagons.lua28
5 files changed, 118 insertions, 65 deletions
diff --git a/advtrains.zip b/advtrains.zip
index a3c834d..e79b3c0 100644
--- a/advtrains.zip
+++ b/advtrains.zip
Binary files differ
diff --git a/init.lua b/init.lua
index 37904e6..41b624e 100644
--- a/init.lua
+++ b/init.lua
@@ -26,17 +26,17 @@ advtrains.meseconrules =
{x=0, y=1, z=-1},
{x=0, y=-1, z=-1},
{x=0, y=-2, z=0}}
-dofile(advtrains.modpath.."/trainlogic.lua");
+dofile(advtrains.modpath.."/trainlogic.lua")
dofile(advtrains.modpath.."/trainhud.lua")
dofile(advtrains.modpath.."/trackplacer.lua")
dofile(advtrains.modpath.."/tracks.lua")
dofile(advtrains.modpath.."/atc.lua")
dofile(advtrains.modpath.."/wagons.lua")
-dofile(advtrains.modpath.."/pseudoload.lua");
-dofile(advtrains.modpath.."/couple.lua");
-dofile(advtrains.modpath.."/damage.lua");
+dofile(advtrains.modpath.."/pseudoload.lua")
+dofile(advtrains.modpath.."/couple.lua")
+dofile(advtrains.modpath.."/damage.lua")
-dofile(advtrains.modpath.."/signals.lua");
-dofile(advtrains.modpath.."/misc_nodes.lua");
-dofile(advtrains.modpath.."/crafting.lua");
+dofile(advtrains.modpath.."/signals.lua")
+dofile(advtrains.modpath.."/misc_nodes.lua")
+dofile(advtrains.modpath.."/crafting.lua")
diff --git a/trainhud.lua b/trainhud.lua
index 81b9e94..610412a 100644
--- a/trainhud.lua
+++ b/trainhud.lua
@@ -1,10 +1,70 @@
-
+--trainhud.lua: holds all the code for train controlling
+
advtrains.hud = {}
minetest.register_on_leaveplayer(function(player)
advtrains.hud[player:get_player_name()] = nil
end)
+local mletter={[1]="F", [-1]="R", [0]="N"}
+
+function advtrains.on_control_change(pc, train, flip)
+ if pc.sneak then
+ if pc.up then
+ train.tarvelocity = advtrains.all_traintypes[train.traintype].max_speed or 10
+ end
+ if pc.down then
+ train.tarvelocity = 0
+ end
+ if pc.left then
+ train.tarvelocity = 4
+ end
+ if pc.right then
+ train.tarvelocity = 8
+ end
+ if pc.jump then
+ train.brake = true
+ --0: released, 1: brake and pressed, 2: released and brake, 3: pressed and brake
+ if not train.brake_hold_state or train.brake_hold_state==0 then
+ train.brake_hold_state = 1
+ elseif train.brake_hold_state==2 then
+ train.brake_hold_state = 3
+ end
+ elseif train.brake_hold_state==1 then
+ train.brake_hold_state = 2
+ elseif train.brake_hold_state==3 then
+ train.brake = false
+ train.brake_hold_state = 0
+ end
+ else
+ if pc.up then
+ train.tarvelocity = train.tarvelocity + 1
+ end
+ if pc.down then
+ if train.velocity>0 then
+ train.tarvelocity = math.max(train.tarvelocity - 1, 0)
+ else
+ train.movedir = -train.movedir
+ end
+ end
+ if train.brake_hold_state~=2 then
+ train.brake = false
+ end
+ if pc.jump then
+ train.brake = true
+ end
+ if pc.aux1 then
+ --horn
+ end
+ end
+end
+function advtrains.update_driver_hud(pname, train, flip)
+ advtrains.set_trainhud(pname, advtrains.hud_train_format(train, flip))
+end
+function advtrains.clear_driver_hud(pname)
+ advtrains.set_trainhud(pname, "")
+end
+
function advtrains.set_trainhud(name, text)
local hud = advtrains.hud[name]
local player=minetest.get_player_by_name(name)
@@ -32,28 +92,17 @@ function advtrains.set_trainhud(name, text)
end
end
function advtrains.hud_train_format(train, flip)
- local fct=1
- if flip then fct=-1 end
- if not train then return "" end
+ local fct=flip and -1 or 1
+ if not train or not train.traintype then return "" end
+
local max=advtrains.all_traintypes[train.traintype].max_speed or 10
- local vel=advtrains.abs_ceil(train.velocity)*fct
- local tvel=advtrains.abs_ceil(train.tarvelocity)*fct
- local firstLine, secondLine
- if vel<0 then
- firstLine="Speed: <"..string.rep("_", vel+max)..string.rep("+", -vel).."|"..string.rep("_", max)..">"
- else
- firstLine="Speed: <"..string.rep("_", max).."|"..string.rep("+", vel)..string.rep("_", max-vel)..">"
- end
- if tvel<0 then
- secondLine="Target: <"..string.rep("_", tvel+max)..string.rep("+", -tvel).."|"..string.rep("_", max)..">"
- else
- secondLine="Target: <"..string.rep("_", max).."|"..string.rep("+", tvel)..string.rep("_", max-tvel)..">"
- end
- if vel==0 then
- return firstLine.."\n"..secondLine.."\nup for forward, down for backward, use to get off train. "
- elseif vel<0 then
- return firstLine.."\n"..secondLine.."\nPress up to decelerate, down to accelerate, sneak to stop."
- elseif vel>0 then
- return firstLine.."\n"..secondLine.."\nPress up to accelerate, down to decelerate, sneak to stop."
- end
+ local vel=advtrains.abs_ceil(train.velocity)
+ local tvel=advtrains.abs_ceil(train.tarvelocity)
+ local topLine, firstLine, secondLine
+
+ topLine=train.traintype.." ["..mletter[fct*train.movedir].."] "..(train.brake and "="..( train.brake_hold_state==2 and "^" or "" ).."B=" or "")
+ firstLine="Speed: |"..string.rep("+", vel)..string.rep("_", max-vel)..">"
+ secondLine="Target: |"..string.rep("+", tvel)..string.rep("_", max-tvel)..">"
+
+ return topLine.."\n"..firstLine.."\n"..secondLine
end
diff --git a/trainlogic.lua b/trainlogic.lua
index 5b9390c..11849fd 100644
--- a/trainlogic.lua
+++ b/trainlogic.lua
@@ -34,8 +34,10 @@ function endstep()
end
end
+--TODO: these values need to be integrated when i remove traintypes.
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)
advtrains.audit_interval=30
@@ -171,6 +173,9 @@ function advtrains.train_step(id, train, dtime)
if not train.velocity then
train.velocity=0
end
+ if not train.movedir or (train.movedir~=1 and train.movedir~=-1) then
+ train.movedir=1
+ end
--very unimportant thing: check if couple is here
if train.couple_eid_front and (not minetest.luaentities[train.couple_eid_front] or not minetest.luaentities[train.couple_eid_front].is_couple) then train.couple_eid_front=nil end
if train.couple_eid_back and (not minetest.luaentities[train.couple_eid_back] or not minetest.luaentities[train.couple_eid_back].is_couple) then train.couple_eid_back=nil end
@@ -201,13 +206,12 @@ function advtrains.train_step(id, train, dtime)
local back_off_track=train.min_index_on_track and train_end_index<train.min_index_on_track
if front_off_track and back_off_track then--allow movement in both directions
if train.tarvelocity>1 then train.tarvelocity=1 end
- if train.tarvelocity<-1 then train.tarvelocity=-1 end
elseif front_off_track then--allow movement only backward
- if train.tarvelocity>0 then train.tarvelocity=0 end
- if train.tarvelocity<-1 then train.tarvelocity=-1 end
+ if train.movedir==1 and train.tarvelocity>0 then train.tarvelocity=0 end
+ if train.movedir==-1 and train.tarvelocity>1 then train.tarvelocity=1 end
elseif back_off_track then--allow movement only forward
- if train.tarvelocity>1 then train.tarvelocity=1 end
- if train.tarvelocity<0 then train.tarvelocity=0 end
+ if train.movedir==-1 and train.tarvelocity>0 then train.tarvelocity=0 end
+ if train.movedir==1 and train.tarvelocity>1 then train.tarvelocity=1 end
end
--update advtrains.detector
@@ -269,9 +273,9 @@ function advtrains.train_step(id, train, dtime)
--this time, based on NODES and the advtrains.detector.on_node table.
local collpos
local coll_grace=1
- if train.velocity>0 then
+ if train.movedir==1 then
collpos=advtrains.get_real_index_position(path, train.index-coll_grace)
- elseif train.velocity<0 then
+ else
collpos=advtrains.get_real_index_position(path, train_end_index+coll_grace)
end
if collpos then
@@ -282,7 +286,8 @@ function advtrains.train_step(id, train, dtime)
if advtrains.detector.on_node[testpts] and advtrains.detector.on_node[testpts]~=id then
--collides
train.recently_collided_with_env=true
- train.velocity=-0.5*train.velocity
+ train.velocity=0.5*train.velocity
+ train.movedir=train.movedir*-1
train.tarvelocity=0
end
end
@@ -345,32 +350,41 @@ function advtrains.train_step(id, train, dtime)
if train.locomotives_in_train==0 then
train.tarvelocity=0
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)
+ end
--apply tarvel(but with physics in mind!)
if train.velocity~=train.tarvelocity then
local applydiff=0
local mass=#train.trainparts
- local diff=math.abs(train.tarvelocity)-math.abs(train.velocity)
+ local diff=train.tarvelocity-train.velocity
if diff>0 then--accelerating, force will be brought on only by locomotives.
--print("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.
--print("braking with emergency force")
- applydiff=(math.min((advtrains.train_emerg_force*dtime), math.abs(diff)))
- else
+ applydiff= -(math.min((advtrains.train_emerg_force*dtime), math.abs(diff)))
+ elseif train.brake then
--print("braking with default force")
- applydiff=(math.min((advtrains.train_brake_force*dtime), math.abs(diff)))
+ --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
+ --print("roll")
+ applydiff= -(math.min((advtrains.train_roll_force*dtime), math.abs(diff)))
end
end
- train.last_accel=(applydiff*math.sign(train.tarvelocity-train.velocity))
- train.velocity=train.velocity+train.last_accel
+ train.last_accel=(applydiff*train.movedir)
+ train.velocity=math.min(math.max( train.velocity+applydiff , 0), advtrains.all_traintypes[train.traintype].max_speed)
else
train.last_accel=0
end
--move
--TODO 3,5 + 0.7
- train.index=train.index and train.index+((train.velocity/(train.path_dist[math.floor(train.index)] or 1))*dtime) or 0
+ train.index=train.index and train.index+(((train.velocity*train.movedir)/(train.path_dist[math.floor(train.index)] or 1))*dtime) or 0
end
diff --git a/wagons.lua b/wagons.lua
index 7a99bca..296bc54 100644
--- a/wagons.lua
+++ b/wagons.lua
@@ -259,24 +259,13 @@ function wagon:on_step(dtime)
local driver=self.seatp[seatno] and minetest.get_player_by_name(self.seatp[seatno])
if driver and driver:get_player_control_bits()~=self.old_player_control_bits then
local pc=driver:get_player_control()
- if pc.sneak then --stop
- self:train().tarvelocity=0
- elseif (not self.wagon_flipped and pc.up) or (self.wagon_flipped and pc.down) then --faster
- self:train().tarvelocity=math.min(self:train().tarvelocity+1, advtrains.all_traintypes[self:train().traintype].max_speed or 10)
- elseif (not self.wagon_flipped and pc.down) or (self.wagon_flipped and pc.up) then --slower
- self:train().tarvelocity=math.max(self:train().tarvelocity-1, -(advtrains.all_traintypes[self:train().traintype].max_speed or 10))
- elseif pc.aux1 then --slower
- if true or math.abs(self:train().velocity)<=3 then--TODO debug
- self:get_off(seatno)
- return
- else
- minetest.chat_send_player(driver:get_player_name(), "Can't get off driving train!")
- end
- end
+
+ advtrains.on_control_change(pc, self:train(), self.wagon_flipped)
+
self.old_player_control_bits=driver:get_player_control_bits()
end
if driver then
- advtrains.set_trainhud(driver:get_player_name(), advtrains.hud_train_format(self:train(), self.wagon_flipped))
+ advtrains.update_driver_hud(driver:get_player_name(), self:train(), self.wagon_flipped)
end
end
end
@@ -310,7 +299,8 @@ function wagon:on_step(dtime)
return
end
if not self.pos_in_train then
- print("["..self.unique_id.."][fatal] no pos_in_train set.")
+ --why ever. but better continue next step...
+ advtrains.update_trainpart_properties(self.train_id)
return
end
@@ -347,7 +337,7 @@ function wagon:on_step(dtime)
end
--FIX: use index of the wagon, not of the train.
- local velocity=gp.velocity/(gp.path_dist[math.floor(index)] or 1)
+ local velocity=(gp.velocity*gp.movedir)/(gp.path_dist[math.floor(index)] or 1)
local acceleration=(gp.last_accel or 0)/(gp.path_dist[math.floor(index)] or 1)
local factor=index-math.floor(index)
local actual_pos={x=first_pos.x-(first_pos.x-second_pos.x)*factor, y=first_pos.y-(first_pos.y-second_pos.y)*factor, z=first_pos.z-(first_pos.z-second_pos.z)*factor,}
@@ -414,7 +404,7 @@ function wagon:get_on(clicker, seatno)
self.seatp={}
end
if not self.seats[seatno] then return end
- if self.seatp[seatno] then
+ if self.seatp[seatno] and self.seatp[seatno]~=clicker:get_player_name() then
self:get_off(seatno)
end
self.seatp[seatno] = clicker:get_player_name()
@@ -441,7 +431,7 @@ function wagon:get_off(seatno)
local pname = self.seatp[seatno]
local clicker = minetest.get_player_by_name(pname)
advtrains.player_to_wagon_mapping[pname]=nil
- advtrains.set_trainhud(pname, "")
+ advtrains.clear_driver_hud(pname)
if clicker then
clicker:set_detach()
clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})