aboutsummaryrefslogtreecommitdiff
path: root/advtrains/trainhud.lua
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains/trainhud.lua')
-rw-r--r--advtrains/trainhud.lua362
1 files changed, 362 insertions, 0 deletions
diff --git a/advtrains/trainhud.lua b/advtrains/trainhud.lua
index 449216a..f8f931d 100644
--- a/advtrains/trainhud.lua
+++ b/advtrains/trainhud.lua
@@ -0,0 +1,362 @@
+--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"}
+
+function advtrains.on_control_change(pc, train, flip)
+ local maxspeed = train.max_speed or 10
+ if pc.sneak then
+ if pc.up then
+ train.tarvelocity = maxspeed
+ 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]]
+ --shift+use:see wagons.lua
+ else
+ local act=false
+ if pc.jump then
+ train.ctrl_user = 1
+ act=true
+ end
+ -- If atc command set, only "Jump" key can clear command. To prevent accidental control.
+ if train.tarvelocity or train.atc_command then
+ return
+ end
+ if pc.up then
+ train.ctrl_user=4
+ act=true
+ end
+ if pc.down then
+ if train.velocity>0 then
+ if pc.jump then
+ train.ctrl_user = 0
+ else
+ train.ctrl_user = 2
+ end
+ act=true
+ else
+ advtrains.invert_train(train.id)
+ advtrains.atc.train_reset_command(train)
+ end
+ end
+ if pc.left then
+ if train.door_open ~= 0 then
+ train.door_open = 0
+ else
+ train.door_open = -1
+ end
+ end
+ if pc.right then
+ if train.door_open ~= 0 then
+ train.door_open = 0
+ else
+ train.door_open = 1
+ end
+ end
+ if not act then
+ train.ctrl_user = nil
+ end
+ end
+end
+function advtrains.update_driver_hud(pname, train, flip, thud, ghud, nointext)
+ local inside=nointext and "" or (train.text_inside or "").."\n"
+ local ft = (thud or advtrains.hud.dtext)(train, flip)
+ local ht, gs = (ghud or advtrains.hud.presets.default)(train, flip)
+ advtrains.set_trainhud(pname, inside..ft, ht, gs)
+end
+function advtrains.clear_driver_hud(pname)
+ advtrains.set_trainhud(pname, "")
+end
+
+function advtrains.set_trainhud(name, text, driver, gs)
+ gs = gs or 110
+ local hud = advtrains.hud[name]
+ local player=minetest.get_player_by_name(name)
+ if not player then
+ return
+ end
+ local driverhud = {
+ hud_elem_type = "image",
+ name = "ADVTRAINS_DRIVER",
+ position = {x=0.5, y=1},
+ offset = {x=0,y=-170},
+ text = driver or "",
+ alignment = {x=0,y=-1},
+ scale = {x=1,y=1},}
+ if not hud then
+ hud = {["driver"]={}}
+ advtrains.hud[name] = hud
+ hud.id = player:hud_add({
+ hud_elem_type = "text",
+ name = "ADVTRAINS",
+ number = 0xFFFFFF,
+ position = {x=0.5, y=1},
+ offset = {x=0, y=-190-gs},
+ text = text,
+ scale = {x=200, y=60},
+ alignment = {x=0, y=-1},
+ })
+ hud.oldText=text
+ hud.driver = player:hud_add(driverhud)
+ else
+ if hud.oldText ~= text then
+ player:hud_change(hud.id, "text", text)
+ player:hud_change(hud.id, "offset", {x=0, y=-190-gs})
+ hud.oldText=text
+ end
+ if hud.driver then
+ player:hud_change(hud.driver, "text", driver or "")
+ elseif driver then
+ hud.driver = player:hud_add(driverhud)
+ end
+ 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.texture_escape(str)
+ return string.gsub(str, "[%[%()^:]", "\\%1")
+end
+
+function advtrains.hud.dtext(train, flip)
+ local st = {}
+ if train.debug then st = {train.debug} end
+ local res = advtrains.speed_restriction
+
+ st[#st+1] = attrans("Train ID: @1", train.id)
+
+ if res and res == 0 then
+ st[#st+1] = attrans("OVERRUN RED SIGNAL! Examine situation and reverse train to move again.")
+ end
+
+ if train.atc_command then
+ st[#st+1] = string.format("ATC: %s%s", train.atc_delay and advtrains.abs_ceil(train.atc_delay).."s " or "", train.atc_command or "")
+ end
+
+ return table.concat(st, "\n")
+end
+
+function advtrains.hud.sevenseg(digit, x, y, w, h, pc, nc)
+ local st = {}
+ local sformat = string.format
+ local f = "%d,%d=(advtrains_hud_bg.png^[resize\\:%dx%d%s)"
+ local segs = {
+ {h, 0, w, h},
+ {0, h, h, w},
+ {w+h, h, h, w},
+ {h, w+h, w, h},
+ {0, w+2*h, h, w},
+ {w+h, w+2*h, h, w},
+ {h, 2*(w+h), w, h}}
+ local trans = {
+ [0] = {true, true, true, false, true, true, true},
+ [1] = {false, false, true, false, false, true, false},
+ [2] = {true, false, true, true, true, false, true},
+ [3] = {true, false, true, true, false, true, true},
+ [4] = {false, true, true, true, false, true, false},
+ [5] = {true, true, false, true, false, true, true},
+ [6] = {true, true, false, true, true, true, true},
+ [7] = {true, false, true, false, false, true, false},
+ [8] = {true, true, true, true, true, true, true},
+ [9] = {true, true, true, true, false, true, true}
+ }
+ local ent = trans[digit or 10]
+ if not ent then return end
+ for i = 1, 7, 1 do
+ if ent[i] then
+ local s = segs[i]
+ st[#st+1] = sformat(f, x+s[1], y+s[2], s[3], s[4], pc and "^[colorize\\:"..pc or "")
+ elseif nc then
+ local s = segs[i]
+ st[#st+1] = sformat(f, x+s[1], y+s[2], s[3], s[4], "^[colorize\\:"..nc)
+ end
+ end
+ return table.concat(st,":")
+end
+
+function advtrains.hud.number(number, padding, x, y, w, h, margin, pcolor, ncolor)
+ local st = {}
+ local number = math.abs(math.floor(number or 0))
+ if not padding then
+ if number == 0 then
+ padding = 0
+ else
+ padding = math.floor(math.log10(number))
+ end
+ else
+ padding = padding - 1
+ end
+ for i = padding, 0, -1 do
+ st[#st+1] = advtrains.hud.sevenseg(math.floor(number/10^i)%10, x+(padding-i)*(w+2*h+margin), y, w, h, pcolor, ncolor)
+ end
+ return table.concat(st,":")
+end
+
+function advtrains.hud.leverof(train)
+ if not train then return nil end
+ local tlev=train.lever or 3
+ if train.velocity==0 and not train.active_control then tlev=1 end
+ if train.hud_lzb_effect_tmr then
+ tlev=1
+ end
+ return tlev
+end
+
+function advtrains.hud.lever(lever, x, y, w1, w2, height)
+ local sformat = string.format
+ local hs = height/5
+ local st = {
+ sformat("%d,%d=(advtrains_hud_bg.png^[colorize\\:cyan^[resize\\:%dx%d)", x, y, w1, hs),
+ sformat("%d,%d=(advtrains_hud_bg.png^[colorize\\:white^[resize\\:%dx%d)", x, y+hs, w1, hs),
+ sformat("%d,%d=(advtrains_hud_bg.png^[colorize\\:orange^[resize\\:%dx%d)", x, y+hs*2, w1, hs*2),
+ sformat("%d,%d=(advtrains_hud_bg.png^[colorize\\:red^[resize\\:%dx%d)", x, y+hs*4, w1, hs),
+ sformat("%d,%d=(advtrains_hud_bg.png^[colorize\\:darkslategray^[resize\\:%dx%d)", x+(w2+w1)/2, y+(hs-w1)/2, w1, hs*4+2*w1),
+ sformat("%d,%d=(advtrains_hud_bg.png^[colorize\\:gray^[resize\\:%dx%d)", x+w1, y+(4-lever)*hs, w2, hs),
+ }
+ return table.concat(st, ":")
+end
+
+function advtrains.hud.door(o, x, y, w, h, m)
+ local sformat = string.format
+ local dw = (w-m*2)/4
+ local ww = w-(dw+m)*2
+ local wh = h/2-m
+ local st = {
+ sformat("%d,%d=(advtrains_hud_bg.png^[resize\\:%dx%d^[colorize\\:white)", x+dw+m, y, ww, h),
+ sformat("%d,%d=(advtrains_hud_bg.png^[resize\\:%dx%d)", x+dw+m*2, y+m, ww-2*m, wh),
+ sformat("%d,%d=(advtrains_hud_bg.png^[resize\\:%dx%d^[colorize\\:%s)", x, y, dw, h, o==-1 and "white" or "darkslategray"),
+ sformat("%d,%d=(advtrains_hud_bg.png^[resize\\:%dx%d)", x+m, y+m, dw-2*m, wh),
+ sformat("%d,%d=(advtrains_hud_bg.png^[resize\\:%dx%d^[colorize\\:%s)", x+w-dw, y, dw, h, o==1 and "white" or "darkslategray"),
+ sformat("%d,%d=(advtrains_hud_bg.png^[resize\\:%dx%d)", x+w-dw+m, y+m, dw-2*m, wh),
+ }
+ return table.concat(st, ":")
+end
+
+function advtrains.hud.speed_horizontal(train, x, y, w, h, m)
+ local sformat = string.format
+ local barw, barh = (w-m*19)/20, h-10
+ local max = train.max_speed or 10
+ local res = train.speed_restriction
+ local vel = advtrains.abs_ceil(train.velocity)
+ local tar = train.tarvelocity
+ local res = train.speed_restriction
+ local st = {}
+ for i = 1, vel do
+ st[i] = sformat("%d,%d=(advtrains_hud_bg.png^[resize\\:%dx%d^[colorize\\:white)", x+(i-1)*(barw+m), y+5, barw, barh)
+ end
+ for i = vel+1, max do
+ st[i] = sformat("%d,%d=(advtrains_hud_bg.png^[resize\\:%dx%d^[colorize\\:darkslategray)", x+(i-1)*(barw+m), y+5, barw, barh)
+ end
+ if res and res > 0 and res < max then
+ st[#st+1] = sformat("%d,%d=(advtrains_hud_bg.png^[resize\\:%dx%d^[colorize\\:red)", x+res*(barw+m)-m, y, m, h)
+ end
+ if tar then
+ local tc = math.min(tar, max)
+ st[#st+1] = sformat("%d,%d=(advtrains_hud_bg.png^[resize\\:%dx%d^[colorize\\:cyan)", x+tc*(barw+m)-m, y+5+barh, m, 5)
+ end
+ return table.concat(st, ":")
+end
+
+function advtrains.hud.getlzb(train)
+ if train.lzb and train.lzb.checkpoints then
+ local oc = train.lzb.checkpoints
+ for i = 1, #oc do
+ local spd = oc[i].speed
+ spd = advtrains.speed.min(spd,train.speed_restriction)
+ local dist = math.floor((oc[i].index or train.index)-train.index)
+ if spd == -1 or spd == nil then
+ return -1, dist
+ elseif type(spd) == "number" and spd >= 0 then
+ return spd, dist
+ end
+ end
+ end
+end
+
+dofile(advtrains.modpath.."/trainhud_presets.lua")
+
+local texture = advtrains.hud.presets.default { -- dummy train object to demonstrate the train hud
+ max_speed = 17, speed_restriction = 15, velocity = 14, tarvelocity = 12,
+ active_control = true, lever = 3, ctrl = {lzb = true}, is_shunt = true,
+ door_open = 1, lzb = {checkpoints = {{speed=6, index=125.7}}}, index = 0,
+ hud_lzb_effect_tmr = true, autocouple = true,
+}
+
+minetest.register_node("advtrains:hud_demo",{
+ description = "Train HUD demonstration",
+ tiles = {texture},
+ groups = {cracky = 3, not_in_creative_inventory = 1}
+})
+
+minetest.register_craft {
+ output = "advtrains:hud_demo",
+ recipe = {
+ {"default:paper", "default:paper", "default:paper"},
+ {"default:paper", "advtrains:trackworker", "default:paper"},
+ {"default:paper", "default:paper", "default:paper"},
+ }
+}