aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorY. Wang <y5nw@protonmail.com>2024-10-27 20:29:54 +0100
committerY. Wang <y5nw@protonmail.com>2024-10-27 20:29:54 +0100
commitab26f1d56ae1a4ef70ddda41f583dce5b071f32c (patch)
tree4da105213c9d009890af3e39759af15cf54eccb9
parent9ada994d5b3bd874e537b0bc9641b925058bdf51 (diff)
downloadadvtrains-ab26f1d56ae1a4ef70ddda41f583dce5b071f32c.tar.gz
advtrains-ab26f1d56ae1a4ef70ddda41f583dce5b071f32c.tar.bz2
advtrains-ab26f1d56ae1a4ef70ddda41f583dce5b071f32c.zip
Rework HUD again
-rw-r--r--advtrains/texture.lua36
-rw-r--r--advtrains/textures/advtrains_hud_arrow.pngbin91 -> 318 bytes
-rw-r--r--advtrains/textures/advtrains_hud_ars.pngbin0 -> 340 bytes
-rw-r--r--advtrains/textures/advtrains_hud_atc.pngbin528 -> 330 bytes
-rw-r--r--advtrains/textures/advtrains_hud_cpl.pngbin0 -> 342 bytes
-rw-r--r--advtrains/textures/advtrains_hud_door.pngbin0 -> 333 bytes
-rw-r--r--advtrains/textures/advtrains_hud_lzb.pngbin398 -> 334 bytes
-rw-r--r--advtrains/textures/advtrains_hud_shunt.pngbin476 -> 334 bytes
-rw-r--r--advtrains/textures/advtrains_hud_smallnum.pngbin0 -> 328 bytes
-rw-r--r--advtrains/textures/advtrains_hud_twid.pngbin0 -> 301 bytes
-rw-r--r--advtrains/trainhud.lua186
-rw-r--r--advtrains/wagons.lua2
12 files changed, 192 insertions, 32 deletions
diff --git a/advtrains/texture.lua b/advtrains/texture.lua
index e6d83b0..34fe83c 100644
--- a/advtrains/texture.lua
+++ b/advtrains/texture.lua
@@ -67,6 +67,8 @@ end)
tx_lib.multiply = mkmodifier("[multiply:%s", {tx.escape})
tx_lib.resize = mkmodifier("[resize:%dx%d", {})
tx_lib.transform = mkmodifier("[transform%s", {tx.escape})
+tx_lib.makealpha = mkmodifier("[makealpha:%s", {tx.escape})
+tx_lib.verticalframe = mkmodifier("[verticalframe:%d:%d]", {})
-- [combine
@@ -93,8 +95,11 @@ function tx.combine(w, h, bg)
return obj
end
-function combine:add_fill(x, y, ...)
- return self:add(x, y, tx.fill(...))
+function combine:add_fill(x, y, w, h, ...)
+ if w < 1 or h < 1 then
+ return obj
+ end
+ return self:add(x, y, tx.fill(w, h, ...))
end
local function add_multicolor_fill(n, self, x, y, w, h, ...)
@@ -225,4 +230,31 @@ function combine:add_n7seg(x, y, w, h, n, prec, ...)
return self:add_str7seg(x, y, w, h, pfx .. ("0"):rep(prec-#str-#pfx) .. str, ...)
end
+function combine:add_small_digit(x, y, s, d, fill)
+ d = math.floor(tonumber(d))
+ if not d or d ~= d or d < 0 or d > 9 then
+ error("invalid value passed to advtrains.combine_texture:add_small_digit")
+ end
+ return self:add(x, y, tx"advtrains_hud_smallnum.png":verticalframe(10, d):makealpha"black":multiply(fill):resize(3*s, 5*s))
+end
+
+function combine:add_smallnum(x, y, s, n, prec, ...)
+ if not (type(n) == "number" and type(prec) == "number") then
+ error("invalid number or precision passed to numeric display")
+ elseif n < 0 then
+ error("cannot use negative number")
+ elseif prec < 0 then
+ error("cannot use negative length")
+ end
+ n = math.floor(n)
+ local digits = {}
+ for k = prec, 1, -1 do
+ digits[k] = n % 10
+ n = math.floor(n/10)
+ end
+ for k, d in ipairs(digits) do
+ self:add_small_digit(x+4*s*(k-1), y, s, d, ...)
+ end
+end
+
return tx
diff --git a/advtrains/textures/advtrains_hud_arrow.png b/advtrains/textures/advtrains_hud_arrow.png
index 71d75b0..bffbc63 100644
--- a/advtrains/textures/advtrains_hud_arrow.png
+++ b/advtrains/textures/advtrains_hud_arrow.png
Binary files differ
diff --git a/advtrains/textures/advtrains_hud_ars.png b/advtrains/textures/advtrains_hud_ars.png
new file mode 100644
index 0000000..9ad9715
--- /dev/null
+++ b/advtrains/textures/advtrains_hud_ars.png
Binary files differ
diff --git a/advtrains/textures/advtrains_hud_atc.png b/advtrains/textures/advtrains_hud_atc.png
index e033653..869e12c 100644
--- a/advtrains/textures/advtrains_hud_atc.png
+++ b/advtrains/textures/advtrains_hud_atc.png
Binary files differ
diff --git a/advtrains/textures/advtrains_hud_cpl.png b/advtrains/textures/advtrains_hud_cpl.png
new file mode 100644
index 0000000..f39cc21
--- /dev/null
+++ b/advtrains/textures/advtrains_hud_cpl.png
Binary files differ
diff --git a/advtrains/textures/advtrains_hud_door.png b/advtrains/textures/advtrains_hud_door.png
new file mode 100644
index 0000000..73e78f5
--- /dev/null
+++ b/advtrains/textures/advtrains_hud_door.png
Binary files differ
diff --git a/advtrains/textures/advtrains_hud_lzb.png b/advtrains/textures/advtrains_hud_lzb.png
index e1b5f70..101b8b1 100644
--- a/advtrains/textures/advtrains_hud_lzb.png
+++ b/advtrains/textures/advtrains_hud_lzb.png
Binary files differ
diff --git a/advtrains/textures/advtrains_hud_shunt.png b/advtrains/textures/advtrains_hud_shunt.png
index f4d27a5..b0dfe3f 100644
--- a/advtrains/textures/advtrains_hud_shunt.png
+++ b/advtrains/textures/advtrains_hud_shunt.png
Binary files differ
diff --git a/advtrains/textures/advtrains_hud_smallnum.png b/advtrains/textures/advtrains_hud_smallnum.png
new file mode 100644
index 0000000..544df8f
--- /dev/null
+++ b/advtrains/textures/advtrains_hud_smallnum.png
Binary files differ
diff --git a/advtrains/textures/advtrains_hud_twid.png b/advtrains/textures/advtrains_hud_twid.png
new file mode 100644
index 0000000..af5e98f
--- /dev/null
+++ b/advtrains/textures/advtrains_hud_twid.png
Binary files differ
diff --git a/advtrains/trainhud.lua b/advtrains/trainhud.lua
index f9f4876..de17c3c 100644
--- a/advtrains/trainhud.lua
+++ b/advtrains/trainhud.lua
@@ -88,9 +88,9 @@ function advtrains.on_control_change(pc, train, flip)
end
end
end
-function advtrains.update_driver_hud(pname, train, flip)
+function advtrains.update_driver_hud(pname, train, wdata)
local inside=train.text_inside or ""
- local ft, ht = advtrains.hud_train_format(train, flip)
+ local ft, ht = advtrains.hud_train_format(train, wdata)
advtrains.set_trainhud(pname, inside.."\n"..ft, ht)
end
function advtrains.clear_driver_hud(pname)
@@ -184,10 +184,11 @@ Value Disp Control Meaning
4 + W Accelerate
]]
-function advtrains.hud_train_format(train, flip)
+function advtrains.hud_train_format(train, wdata)
if not train then return "","" end
local sformat = string.format -- this appears to be faster than (...):format
+ local flip = wdata.wagon_flipped
local max = train.max_speed or 10
local res = train.speed_restriction
local vel = advtrains.abs_ceil(train.velocity)
@@ -199,27 +200,37 @@ function advtrains.hud_train_format(train, flip)
tlev=1
end
- local hud = T.combine(440, 110, "black")
+ local hud = T.combine(500, 100, "black")
local st = {}
if train.debug then st = {train.debug} end
- -- lever
- hud:add_multicolor_fill_topdown(275, 10, 5, 90, 1, "cyan", 1, "white", 2, "orange", 1, "red")
- hud:add_lever_topdown(280, 10, 30, 90, 18, 6, (4-tlev)/4, "gray", "darkslategray")
- -- reverser
- hud:add(245, 10, T"advtrains_hud_arrow.png":transform"FY":multiply(flip and "gray" or "cyan"))
- hud:add(245, 85, T"advtrains_hud_arrow.png":multiply(flip and "orange" or "gray"))
- hud:add_lever_topdown(240, 30, 25, 50, 15, 5, flip and 1 or 0, "gray", "darkslategray")
- -- train control/safety indication
- hud:add(10, 10, T"advtrains_hud_atc.png":resize(30, 30):multiply((train.tarvelocity or train.atc_command) and "cyan" or "darkslategray"))
- hud:add(50, 10, T"advtrains_hud_lzb.png":resize(30, 30):multiply(train.hud_lzb_effect_tmr and "red" or "darkslategray"))
- hud:add(90, 10, T"advtrains_hud_shunt.png":resize(30, 30):multiply(train.is_shunt and "orange" or "darkslategray"))
- -- door
- hud:add_fill(187, 10, 26, 30, "white"):add_fill(189, 12, 22, 11, "black")
- hud:add_fill(170, 10, 15, 30, train.door_open==-1 and "white" or "darkslategray"):add_fill(172, 12, 11, 11, "black")
- hud:add_fill(215, 10, 15, 30, train.door_open==1 and "white" or "darkslategray"):add_fill(217, 12, 11, 11, "black")
- -- speed indication(s)
- hud:add_n7seg(320, 10, 110, 90, vel, 2, "red")
+ ---[[ lever
+ hud:add_multicolor_fill_topdown(375, 10, 5, 80, 1, "cyan", 1, "white", 2, "orange", 1, "red")
+ hud:add_lever_topdown(345, 10, 30, 80, 16, 6, (4-tlev)/4, "gray", "darkslategray")
+ --]]
+ ---[[ reverser
+ hud:add(320, 10, T"advtrains_hud_arrow.png":multiply(flip and "gray" or "cyan"))
+ hud:add(320, 80, T"advtrains_hud_arrow.png":transform"FY":multiply(flip and "orange" or "gray"))
+ hud:add_lever_topdown(320, 25, 15, 50, 15, 5, flip and 1 or 0, "gray", "darkslategray")
+ --]]
+ ---[[ train/wagon ID
+ hud:add(10, 10, T"advtrains_hud_twid.png":verticalframe(2, 0):multiply"gray":resize(10, 10))
+ hud:add_smallnum(22, 10, 2, tonumber(train.id) or 0, 6, "gray")
+ hud:add(10, 30, T"advtrains_hud_twid.png":verticalframe(2, 1):multiply"gray":resize(10, 10))
+ hud:add_smallnum(22, 30, 2, tonumber(wdata.id) or 0, 6, "gray")
+ --]]
+ ---[[ train control/safety indication
+ hud:add(73, 10, T"advtrains_hud_shunt.png":multiply(train.is_shunt and "orange" or "darkslategray"))
+ hud:add(108, 10, T"advtrains_hud_cpl.png":multiply((train.autocouple or train.atc_wait_autocouple) and "cyan" or "darkslategray"))
+ hud:add(143, 10, T"advtrains_hud_ars.png":multiply(train.ars_disable and "darkslategray" or "cyan"))
+ hud:add(178, 10, T"advtrains_hud_atc.png":multiply((train.tarvelocity or train.atc_command) and "cyan" or "darkslategray"))
+ hud:add(213, 10, T"advtrains_hud_lzb.png":multiply(train.hud_lzb_effect_tmr and "red" or "darkslategray"))
+ --]]
+ ---[[ door
+ hud:add(283, 10, T"advtrains_hud_door.png":multiply(train.door_open==-1 and "white" or "darkslategray"))
+ hud:add(298, 10, T"advtrains_hud_door.png":multiply(train.door_open==1 and "white" or "darkslategray"):transform"FX")
+ --]]
+ --[[ speed indicators
hud:add_segmentbar_leftright(10, 65, 217, 20, 3, 20, max, 20, "darkslategray", 0, vel, "white")
if res and res > 0 then
hud:add_fill(7+res*11, 60, 3, 30, "red")
@@ -227,8 +238,10 @@ function advtrains.hud_train_format(train, flip)
if train.tarvelocity then
hud:add(1+train.tarvelocity*11, 85, T"advtrains_hud_arrow.png":transform"FY":multiply"cyan")
end
+ --]]
local lzbdisp
local lzb = train.lzb
+ local lzbspd
if lzb and lzb.checkpoints then
local oc = lzb.checkpoints
for i = 1, #oc do
@@ -250,7 +263,7 @@ function advtrains.hud_train_format(train, flip)
local c = not spd and "lime" or (type(spd) == "number" and (spd == 0) and "red" or "orange") or nil
if c then
if spd and spd~=0 then
- hud:add(1+spd*11, 50, T"advtrains_hud_arrow.png":multiply"red")
+ lzbspd = spd
end
local dist = math.floor(((oc[i].index or train.index)-train.index))
dist = math.max(0, math.min(999, dist))
@@ -262,9 +275,53 @@ function advtrains.hud_train_format(train, flip)
if not lzbdisp then
lzbdisp = {c = "darkslategray", d = 888}
end
- hud:add_fill(130, 10, 30, 5, lzbdisp.c)
- hud:add_fill(130, 35, 30, 5, lzbdisp.c)
- hud:add_n7seg(131, 18, 28, 14, lzbdisp.d, 3, lzbdisp.c)
+ hud:add_fill(248, 10, 30, 5, lzbdisp.c)
+ hud:add_fill(248, 35, 30, 5, lzbdisp.c)
+ hud:add_smallnum(248, 20, 2, lzbdisp.d, 4, lzbdisp.c)
+
+ hud:add_n7seg(390, 10, 100, 80, vel, 2, "red")
+
+ ---[[ new speed indication bar
+ local dispmax = 100
+ local vmax = train.max_speed or 20
+ for _, n in ipairs {10, 15, 20, 30, 50, 60} do
+ if vmax and train.max_speed <= n then
+ dispmax = n
+ break
+ end
+ end
+ local vsize = 300/dispmax
+ hud:add_fill(10, 60, train.velocity*vsize, 30, "white")
+
+ local vmaxmark = 10+math.floor(vmax*vsize)
+ hud:add_fill(vmaxmark, 60, 310-vmaxmark, 30, "darkslategray")
+
+ local largestep = dispmax > 30 and 10 or 5
+ local smallstep = dispmax > 30 and 2 or 1
+ for i = smallstep, vmax, smallstep do
+ local markpos = math.min(9 + i*vsize, vmaxmark-2)
+ local marksize = 20
+ if i % largestep == 0 then
+ marksize = 30
+
+ local numlen = math.floor(math.log10(i)) + 1
+ hud:add_smallnum(markpos + 4 - 8*numlen, 45, 2, i, numlen, "gray")
+ end
+ hud:add_fill(markpos, 60, 2, marksize, "gray")
+ end
+
+ if res and res > 0 then
+ hud:add_fill(math.min(10+math.max(0, math.floor(res*vsize)-1), vmaxmark-2), 60, 2, 30, "red")
+ end
+
+ if train.tarvelocity then
+ hud:add_fill(math.min(10+math.max(0, math.floor(train.tarvelocity*vsize)-1), vmaxmark-2), 60, 2, 10, "cyan")
+ end
+
+ if lzbspd then
+ hud:add_fill(math.min(10+math.max(0, math.floor(lzbspd*vsize)-1), vmaxmark-2), 80, 2, 10, "orange")
+ end
+ --]]
if res and res == 0 then
table.insert(st, attrans("OVERRUN RED SIGNAL! Examine situation and reverse train to move again."))
@@ -277,19 +334,90 @@ function advtrains.hud_train_format(train, flip)
return table.concat(st,"\n"), tostring(hud)
end
-local _, texture = advtrains.hud_train_format { -- dummy train object to demonstrate the train hud
+local default_hud = { -- dummy train object to demonstrate the train hud
max_speed = 15, speed_restriction = 15, velocity = 15, tarvelocity = 12,
active_control = true, lever = 3, ctrl = {lzb = true}, is_shunt = true,
door_open = 1, lzb = {checkpoints = {{speed=6, index=125.7}}}, index = 100,
+ id = "012345",
}
+local default_wagon = { id = "987654" }
+local _, texture = advtrains.hud_train_format(default_hud, default_wagon)
+
+local hud_test_cache = {}
+
+local speed_scrollbaroptions = "scrollbaroptions[min=0;max=100;smallstep=1]"
+local function hudtest_speed_scrollbar(fs, y, id, label, val)
+ table.insert(fs, ("label[0.5,%f;%s]"):format(y, core.formspec_escape(label)))
+ table.insert(fs, speed_scrollbaroptions)
+ table.insert(fs, ("scrollbar[4,%f;6.5,0.4;horizontal;%s;%d]"):format(y-0.2, core.formspec_escape(id), val))
+end
+
+local function show_hud_test(pname)
+ local fs = {"formspec_version[2]", "size[11,6.5]"}
+ local hud = hud_test_cache[pname] or default_hud
+
+ table.insert(fs, ("checkbox[0.5,0.75;noars;Disable ARS;%s]"):format(hud.ars_disable or "false"))
+ table.insert(fs, ("checkbox[4,0.75;shunt;Shunt;%s]"):format(hud.is_shunt or "false"))
+ table.insert(fs, ("checkbox[7.5,0.75;ac;Autocouple;%s]"):format(hud.autocuople or "false"))
-minetest.register_node("advtrains:hud_demo",{
+ hudtest_speed_scrollbar(fs, 1.25, "velocity", ("Speed: %d"):format(hud.velocity), hud.velocity)
+ hudtest_speed_scrollbar(fs, 1.75, "vmax", ("Max speed: %d"):format(hud.max_speed), hud.max_speed)
+ hudtest_speed_scrollbar(fs, 2.25, "res", hud.speed_restriction and ("Restriction: %d"):format(hud.speed_restriction) or "No speed restriction", hud.speed_restriction or 0)
+
+ local _, tx = advtrains.hud_train_format(hud, default_wagon)
+ table.insert(fs, ("image[0.5,4;10,2;%s]"):format(core.formspec_escape(tx)))
+
+ core.show_formspec(pname, "advtrains:hud_dev", table.concat(fs))
+end
+
+core.register_on_player_receive_fields(function(player, formname, fields)
+ if formname ~= "advtrains:hud_dev" then
+ return
+ end
+ if core.is_yes(fields.quit) or core.is_yes(fields.key_enter) then
+ return true
+ end
+
+ local pname = player:get_player_name()
+ local hud = hud_test_cache[pname]
+ if not hud then
+ hud = table.copy(default_hud)
+ hud_test_cache[pname] = hud
+ end
+
+ for fk, tk in pairs {noars = "ars_disable", shunt = "is_shunt", ac = "autocouple"} do
+ if fields[fk] then
+ hud[tk] = core.is_yes(fields[fk])
+ end
+ end
+
+ for fk, tk in pairs {velocity = "velocity", vmax = "max_speed", res = "speed_restriction"} do
+ local event = core.explode_scrollbar_event(fields[fk] or "")
+ if event and event.type == "CHG" then
+ hud[tk] = event.value
+ end
+ end
+ hud.velocity = math.min(hud.velocity, hud.max_speed)
+ if hud.speed_restriction <= 0 then
+ hud.speed_restriction = nil
+ end
+
+ show_hud_test(pname)
+ return true
+end)
+
+core.register_node("advtrains:hud_demo",{
description = "Train HUD demonstration",
tiles = {texture},
- groups = {cracky = 3, not_in_creative_inventory = 1}
+ groups = {cracky = 3, not_in_creative_inventory = 1},
+ on_rightclick = function(_, _, clicker)
+ if clicker:is_player() then
+ show_hud_test(clicker:get_player_name())
+ end
+ end,
})
-minetest.register_craft {
+core.register_craft {
output = "advtrains:hud_demo",
recipe = {
{"default:paper", "default:paper", "default:paper"},
diff --git a/advtrains/wagons.lua b/advtrains/wagons.lua
index 536c8d4..9b20d7a 100644
--- a/advtrains/wagons.lua
+++ b/advtrains/wagons.lua
@@ -320,7 +320,7 @@ function wagon:on_step(dtime)
local has_driverstand = pname and advtrains.check_driving_couple_protection(pname, data.owner, data.whitelist)
has_driverstand = has_driverstand and self:is_driver_stand(seat)
if has_driverstand and driver then
- advtrains.update_driver_hud(driver:get_player_name(), self:train(), data.wagon_flipped)
+ advtrains.update_driver_hud(driver:get_player_name(), self:train(), data)
elseif driver then
--only show the inside text
local inside=self:train().text_inside or ""