9fde03f950
- En flow-traktors linje følger flowets niveau (venter/fejl) som Flows-listen. - Solgte/slettede køretøjer (isDeleted, ingen/død rootNode) vises ikke under stået stille. - Standardtasten er venstre Alt + Insert (S er spillets gå/bremse-akse).
460 lines
21 KiB
Lua
460 lines
21 KiB
Lua
-- AD Status Hud
|
|
-- Statusvinduet på skærmen (i stil med Simple Inspector): slås til/fra med input-handlingen SPU_TOGGLE_STATUS
|
|
-- (standard venstre Alt + Insert). Øjebliksbilledet bygges af modens egne statusfunktioner (samme som fanerne) højst
|
|
-- hvert sekund i update() og kun mens vinduet er tændt; draw() tegner kun de cachede linjer og bredder.
|
|
-- Synligheden gemmes pr. bruger i modSettings/FS25_ADSmartPickup/status.xml (standard skjult).
|
|
-- Kører kun på en klient (ikke dedikeret server). Alle spilkald er beskyttet; fejl logges én gang pr. nøgle.
|
|
|
|
ADStatusHud = {}
|
|
|
|
ADStatusHud.LOG_PREFIX = "ADSmartPickup: status: "
|
|
ADStatusHud.REFRESH_MS = 1000
|
|
ADStatusHud.STUCK_WARN_MS = 120000 -- stået stille så længe (uden at Smart Pickup holder den) = advarsel
|
|
ADStatusHud.TEXT_SIZE_PX = 14
|
|
ADStatusHud.MARGIN_PX = 8
|
|
ADStatusHud.SCREEN_OFFSET_PX = 16 -- afstand til skærmens højre kant
|
|
ADStatusHud.TOP_Y = 1 - 0.12 -- øverste kant (normaliseret); under spillets info-boks
|
|
ADStatusHud.SETTINGS_DIR = "modSettings/FS25_ADSmartPickup/"
|
|
ADStatusHud.SETTINGS_FILE = "status.xml"
|
|
ADStatusHud.SETTINGS_ROOT = "adSmartPickupStatus"
|
|
ADStatusHud.HEADER_COLOR = {1, 1, 1, 1}
|
|
|
|
ADStatusHud.visible = false
|
|
ADStatusHud.lines = {} -- {{text, level, header, color, width}}
|
|
ADStatusHud.layout = nil -- {x, y, width, height, textSize, marginX, marginY, padding}
|
|
|
|
local timerMs = 0
|
|
local settingsLoaded = false
|
|
local overlays = nil
|
|
local loggedErrors = {}
|
|
local registerToggleActionRef -- sat nederst (tastens handler til krogen)
|
|
|
|
-- ---- hjælpere ----
|
|
|
|
local function logOnce(key, err)
|
|
if loggedErrors[key] then return end
|
|
loggedErrors[key] = true
|
|
if Logging ~= nil and Logging.warning ~= nil then
|
|
Logging.warning(ADStatusHud.LOG_PREFIX .. "%s fejlede: %s", tostring(key), tostring(err))
|
|
end
|
|
end
|
|
|
|
local function guarded(key, fn, ...)
|
|
local ok, result = pcall(fn, ...)
|
|
if not ok then
|
|
logOnce(key, result)
|
|
return nil
|
|
end
|
|
return result
|
|
end
|
|
|
|
local function textOf(key)
|
|
if g_i18n == nil then return key end
|
|
local ok, text = pcall(g_i18n.getText, g_i18n, key)
|
|
return ok and text or key
|
|
end
|
|
|
|
function ADStatusHud.isClient()
|
|
local mission = g_currentMission
|
|
if mission == nil or mission.getIsClient == nil then return false end
|
|
local ok, isClient = pcall(mission.getIsClient, mission)
|
|
return ok and isClient == true
|
|
end
|
|
|
|
-- Fanernes egne tekst-/statusfunktioner ligger som metoder på SmartPickupFrame og bruger kun self.i18n:
|
|
-- en let "frame" med spillets i18n genbruger dem uden at røre menuen.
|
|
local function frameProxy()
|
|
if SmartPickupFrame == nil then return nil end
|
|
return setmetatable({i18n = g_i18n, lastStartFailed = {}}, {__index = SmartPickupFrame})
|
|
end
|
|
|
|
local function fillTitle(fillType)
|
|
if fillType == nil or g_fillTypeManager == nil then return "?" end
|
|
local title = g_fillTypeManager.getFillTypeTitleByIndex ~= nil and g_fillTypeManager:getFillTypeTitleByIndex(fillType)
|
|
or g_fillTypeManager:getFillTypeNameByIndex(fillType)
|
|
return tostring(title or "?")
|
|
end
|
|
|
|
-- ---- øjebliksbillede ----
|
|
|
|
local WAGON_ACTIONS = {
|
|
fetching = {key = "spu_status_act_fetchWagon", level = "waiting"},
|
|
waiting = {key = "spu_status_act_waitWagon", level = "waiting"},
|
|
emptying = {key = "spu_status_act_emptying", level = "running"},
|
|
homing = {key = "spu_status_act_homing", level = "running"},
|
|
}
|
|
|
|
-- Traktorens handling som kort tekst + niveau (ADRunsController.getVehicleActivity som Flows-fanen).
|
|
local function vehicleAction(adEnv, vehicle)
|
|
local wagonState = ADFlowWagons ~= nil and ADFlowWagons.statusOf ~= nil and ADFlowWagons.statusOf(vehicle) or nil
|
|
if wagonState ~= nil and WAGON_ACTIONS[wagonState] ~= nil then
|
|
return textOf(WAGON_ACTIONS[wagonState].key), WAGON_ACTIONS[wagonState].level
|
|
end
|
|
local activity = ADRunsController.getVehicleActivity(adEnv, vehicle)
|
|
local place = tostring(activity.place or "?")
|
|
if activity.kind == "stopped" then
|
|
return textOf("spu_activity_stopped"), "stopped"
|
|
elseif activity.kind == "waiting" then
|
|
return string.format(textOf("spu_status_act_waiting"), place), "waiting"
|
|
elseif activity.kind == "holding" then
|
|
return string.format(textOf("spu_status_act_holding"), place), "waiting"
|
|
elseif activity.kind == "empty" and activity.fillType ~= nil then
|
|
return string.format(textOf("spu_status_act_fetch"), fillTitle(activity.fillType), place), "running"
|
|
end
|
|
return string.format(textOf("spu_status_act_driving"), place), "running"
|
|
end
|
|
|
|
-- Fyld i % af hele vogntoget (AutoDrives egne opgørelser, som kildevalget bruger); nil uden kapacitet.
|
|
local function fillPercent(adEnv, vehicle)
|
|
local autoDrive = adEnv.AutoDrive
|
|
if autoDrive == nil or autoDrive.getAllUnits == nil or autoDrive.getAllFillLevels == nil then return nil end
|
|
local level, capacity = autoDrive.getAllFillLevels(autoDrive.getAllUnits(vehicle))
|
|
if type(level) ~= "number" or type(capacity) ~= "number" or capacity <= 0 then return nil end
|
|
return math.max(0, math.min(100, level / capacity * 100))
|
|
end
|
|
|
|
local function farmVehiclesById(adEnv)
|
|
local byId = {}
|
|
for _, vehicle in ipairs(ADRunsController.getFarmVehicles(adEnv)) do
|
|
local id = ADRunsController.getVehicleId(vehicle)
|
|
if id ~= nil then byId[id] = vehicle end
|
|
end
|
|
return byId
|
|
end
|
|
|
|
-- Én linje pr. traktor i et kørende flow (flows der kan stoppes: startet, eller holder vogn/henter).
|
|
function ADStatusHud.flowEntries(adEnv, proxy)
|
|
local entries = {}
|
|
if ADRunsController == nil or ADRunsController.store == nil or ADFlowView == nil then return entries end
|
|
local byId = farmVehiclesById(adEnv)
|
|
for _, run in ipairs(ADFlowView.orderedRuns(ADRunsController.store.runs or {})) do
|
|
local status = ADRunsController.getRunStatus(adEnv, run)
|
|
if status.canStop then
|
|
local runLevel = proxy ~= nil and proxy.flowLevel ~= nil and guarded("flowLevel", proxy.flowLevel, proxy, adEnv, run) or nil
|
|
for _, vehicleId in ipairs(run.vehicleIds or {}) do
|
|
local vehicle = byId[vehicleId]
|
|
if vehicle ~= nil then
|
|
local action, level = vehicleAction(adEnv, vehicle)
|
|
-- farven følger flowets niveau som Flows-listen (venter/fejl), ellers traktorens egen handling
|
|
if runLevel == "error" or runLevel == "waiting" then level = runLevel end
|
|
table.insert(entries, {vehicle = tostring(ADRuns.vehicleLabel(vehicle)), action = action,
|
|
fillPercent = guarded("fillPercent", fillPercent, adEnv, vehicle), level = level})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return entries
|
|
end
|
|
|
|
-- Én linje pr. mark med aktivt markarbejde (samme statustekst og farve som Marker-fanen).
|
|
function ADStatusHud.fieldEntries(proxy)
|
|
local entries = {}
|
|
if ADFields == nil or ADFieldJobs == nil or ADFieldModel == nil or proxy == nil then return entries end
|
|
for _, info in ipairs(ADFields.list()) do
|
|
local field = ADFieldJobs.getField(info.id)
|
|
if field ~= nil and (ADFieldModel.isWorking(field) or ADFieldJobs.awaitingPlayer(info.id) ~= nil) then
|
|
local names = {}
|
|
for _, assignment in ipairs(ADFieldJobs.assignmentsFor(info.id)) do
|
|
table.insert(names, ADRuns.vehicleLabel(assignment.vehicle))
|
|
end
|
|
table.insert(entries, {
|
|
fieldId = info.id,
|
|
work = proxy:fieldStatusText(field, info, true),
|
|
vehicle = #names > 0 and ADFlowView.joinCounted(names, ", ", nil) or nil,
|
|
progress = SmartPickupFrame.monthCpProgress ~= nil and guarded("fieldProgress", SmartPickupFrame.monthCpProgress, info.id) or nil,
|
|
level = proxy:fieldLevel(info.id),
|
|
})
|
|
end
|
|
end
|
|
return entries
|
|
end
|
|
|
|
-- Kæder med manglende led + ventende forslag + slukkede nødvendige fabrikker (samme punkter og tekster som
|
|
-- "Kræver handling"; de to sidste står under Advarsler).
|
|
function ADStatusHud.chainEntries(proxy)
|
|
local chains, suggestions = {}, {}
|
|
local result = {chains = chains, suggestions = suggestions, dependencies = {}}
|
|
if ADChain == nil or ADChain.last == nil or ADStorageStats == nil or ADStorageStats.chainEntries == nil or proxy == nil then
|
|
return result
|
|
end
|
|
for _, entry in ipairs(ADStorageStats.chainEntries(ADChain.last)) do
|
|
if entry.kind == "chainProblem" then
|
|
table.insert(chains, {text = proxy:alertText(entry), level = "error"})
|
|
elseif entry.kind == "chainSuggest" then
|
|
table.insert(suggestions, {text = proxy:alertText(entry), level = "waiting"})
|
|
elseif entry.kind == "dependencyOff" then
|
|
table.insert(result.dependencies, {text = proxy:alertText(entry), level = "error"})
|
|
end
|
|
end
|
|
return result
|
|
end
|
|
|
|
-- Solgt/slettet køretøj (ADStuckDiag kan holde det et øjeblik efter salget).
|
|
local function isGone(vehicle)
|
|
if vehicle == nil or vehicle.isDeleted then return true end
|
|
if vehicle.rootNode == nil then return true end
|
|
return entityExists ~= nil and not entityExists(vehicle.rootNode)
|
|
end
|
|
|
|
-- Gårdens køretøjer der har stået stille over grænsen, uden at Smart Pickup selv holder dem (Wait/udkørsel).
|
|
function ADStatusHud.stuckEntries()
|
|
local entries = {}
|
|
if ADStuckDiag == nil or ADStuckDiag.stillVehicles == nil then return entries end
|
|
local farmId = g_currentMission ~= nil and g_currentMission.getFarmId ~= nil and g_currentMission:getFarmId() or nil
|
|
for _, still in ipairs(ADStuckDiag.stillVehicles(ADStatusHud.STUCK_WARN_MS)) do
|
|
local vehicle = still.vehicle
|
|
local owned = not isGone(vehicle) and (farmId == nil or (vehicle.getOwnerFarmId ~= nil and vehicle:getOwnerFarmId() == farmId))
|
|
local held = owned and ((ADUnloadWait ~= nil and ADUnloadWait.getWaitFor ~= nil and ADUnloadWait.getWaitFor(vehicle) ~= nil)
|
|
or (ADOutbound ~= nil and ADOutbound.getHoldFor ~= nil and ADOutbound.getHoldFor(vehicle) ~= nil))
|
|
if owned and not held then
|
|
table.insert(entries, {text = string.format(textOf("spu_status_stuck"), tostring(ADRuns.vehicleLabel(vehicle)),
|
|
math.floor(still.ms / 60000)), level = "error"})
|
|
end
|
|
end
|
|
return entries
|
|
end
|
|
|
|
function ADStatusHud.snapshot(adEnv)
|
|
local proxy = frameProxy()
|
|
local snapshot = {flows = {}, fields = {}, chains = {}, warnings = {}}
|
|
if adEnv ~= nil then
|
|
snapshot.flows = guarded("flows", ADStatusHud.flowEntries, adEnv, proxy) or {}
|
|
end
|
|
snapshot.fields = guarded("fields", ADStatusHud.fieldEntries, proxy) or {}
|
|
local chainResult = guarded("chains", ADStatusHud.chainEntries, proxy) or {}
|
|
snapshot.chains = chainResult.chains or {}
|
|
for _, entry in ipairs(chainResult.dependencies or {}) do table.insert(snapshot.warnings, entry) end
|
|
for _, entry in ipairs(guarded("stuck", ADStatusHud.stuckEntries) or {}) do table.insert(snapshot.warnings, entry) end
|
|
for _, entry in ipairs(chainResult.suggestions or {}) do table.insert(snapshot.warnings, entry) end
|
|
return snapshot
|
|
end
|
|
|
|
-- ---- layout og cache (kun i update) ----
|
|
|
|
local function gameInfoDisplay()
|
|
local hud = g_currentMission ~= nil and g_currentMission.hud or nil
|
|
return hud ~= nil and hud.gameInfoDisplay or nil
|
|
end
|
|
|
|
-- Størrelser i skærmkoordinater, skaleret som spillets egen HUD (Simple Inspector-mønster).
|
|
local function measureUnits()
|
|
local display = gameInfoDisplay()
|
|
if display == nil or display.scalePixelToScreenHeight == nil or display.scalePixelToScreenVector == nil then return nil end
|
|
local textSize = display:scalePixelToScreenHeight(ADStatusHud.TEXT_SIZE_PX)
|
|
local marginX, marginY = display:scalePixelToScreenVector({ADStatusHud.MARGIN_PX, ADStatusHud.MARGIN_PX})
|
|
local offsetX = display:scalePixelToScreenVector({ADStatusHud.SCREEN_OFFSET_PX, 0})
|
|
return textSize, marginX, marginY, offsetX
|
|
end
|
|
|
|
-- Øverste kant: fast under info-boksen; ligger info-boksens position lavere, rykkes vinduet ned under den.
|
|
local function topY(marginY)
|
|
local top = ADStatusHud.TOP_Y
|
|
local display = gameInfoDisplay()
|
|
if display ~= nil and display.getPosition ~= nil then
|
|
local ok, _, y = pcall(display.getPosition, display)
|
|
if ok and type(y) == "number" and y > 0.5 and y < 1 then top = math.min(top, y - marginY) end
|
|
end
|
|
return top
|
|
end
|
|
|
|
function ADStatusHud.rebuild(adEnv)
|
|
local lines = ADStatusView.lines(ADStatusHud.snapshot(adEnv), textOf, ADStatusView.MAX_LINES)
|
|
local textSize, marginX, marginY, offsetX = measureUnits()
|
|
if textSize == nil then
|
|
ADStatusHud.lines, ADStatusHud.layout = {}, nil
|
|
return
|
|
end
|
|
local maxWidth = 0
|
|
for _, line in ipairs(lines) do
|
|
setTextBold(line.header == true)
|
|
line.width = getTextWidth(textSize, line.text)
|
|
line.color = line.header and ADStatusHud.HEADER_COLOR or (ADFlowView.LEVEL_COLORS[line.level] or ADStatusHud.HEADER_COLOR)
|
|
if line.width > maxWidth then maxWidth = line.width end
|
|
end
|
|
setTextBold(false)
|
|
local width = maxWidth + 2 * marginX
|
|
local height = #lines * textSize + 2 * marginY
|
|
local top = topY(marginY)
|
|
ADStatusHud.lines = lines
|
|
ADStatusHud.layout = {x = 1 - offsetX - width, y = top - height, top = top, width = width, height = height,
|
|
textSize = textSize, marginX = marginX, marginY = marginY, padding = marginX * 0.5}
|
|
end
|
|
|
|
-- ---- overlays ----
|
|
|
|
local function createOverlays()
|
|
if overlays ~= nil then return overlays end
|
|
if g_overlayManager == nil or HUD == nil or HUD.COLOR == nil or HUD.COLOR.BACKGROUND == nil then return nil end
|
|
local r, g, b, a = unpack(HUD.COLOR.BACKGROUND)
|
|
local created = {
|
|
middle = g_overlayManager:createOverlay("gui.gameInfo_middle", 0, 0, 0, 0),
|
|
left = g_overlayManager:createOverlay("gui.gameInfo_left", 0, 0, 0, 0),
|
|
right = g_overlayManager:createOverlay("gui.gameInfo_right", 0, 0, 0, 0),
|
|
}
|
|
for _, overlay in pairs(created) do overlay:setColor(r, g, b, a) end
|
|
overlays = created
|
|
return overlays
|
|
end
|
|
|
|
local function deleteOverlays()
|
|
if overlays == nil then return end
|
|
for _, overlay in pairs(overlays) do
|
|
if overlay.delete ~= nil then pcall(overlay.delete, overlay) end
|
|
end
|
|
overlays = nil
|
|
end
|
|
|
|
-- ---- indstillinger (pr. bruger, ikke i savegamet) ----
|
|
|
|
local function settingsPath()
|
|
if getUserProfileAppPath == nil then return nil end
|
|
return getUserProfileAppPath() .. ADStatusHud.SETTINGS_DIR .. ADStatusHud.SETTINGS_FILE
|
|
end
|
|
|
|
function ADStatusHud.loadSettings()
|
|
settingsLoaded = true
|
|
local path = settingsPath()
|
|
if path == nil or fileExists == nil or not fileExists(path) then return end
|
|
local xmlFile = XMLFile.load("ADSmartPickupStatus", path)
|
|
if xmlFile == nil then return end
|
|
ADStatusHud.visible = xmlFile:getBool(ADStatusHud.SETTINGS_ROOT .. "#visible", false) == true
|
|
xmlFile:delete()
|
|
end
|
|
|
|
function ADStatusHud.saveSettings()
|
|
local path = settingsPath()
|
|
if path == nil then return end
|
|
if createFolder ~= nil then
|
|
createFolder(getUserProfileAppPath() .. "modSettings/")
|
|
createFolder(getUserProfileAppPath() .. ADStatusHud.SETTINGS_DIR)
|
|
end
|
|
local xmlFile = XMLFile.create("ADSmartPickupStatus", path, ADStatusHud.SETTINGS_ROOT)
|
|
if xmlFile == nil then
|
|
logOnce("saveSettings", "kunne ikke oprette " .. path)
|
|
return
|
|
end
|
|
xmlFile:setBool(ADStatusHud.SETTINGS_ROOT .. "#visible", ADStatusHud.visible == true)
|
|
xmlFile:save()
|
|
xmlFile:delete()
|
|
end
|
|
|
|
-- ---- offentlige kald fra moden ----
|
|
|
|
function ADStatusHud.toggle()
|
|
ADStatusHud.visible = not ADStatusHud.visible
|
|
timerMs = ADStatusHud.REFRESH_MS -- byg straks ved næste update
|
|
if not ADStatusHud.visible then ADStatusHud.lines, ADStatusHud.layout = {}, nil end
|
|
guarded("saveSettings", ADStatusHud.saveSettings)
|
|
end
|
|
|
|
-- Action-event-callback (target = ADStatusHud).
|
|
function ADStatusHud.onToggleAction()
|
|
ADStatusHud.toggle()
|
|
end
|
|
|
|
function ADStatusHud.update(dt, adEnv)
|
|
if not ADStatusHud.isClient() then return end
|
|
if not settingsLoaded then
|
|
guarded("loadSettings", ADStatusHud.loadSettings)
|
|
timerMs = ADStatusHud.REFRESH_MS
|
|
end
|
|
if not ADStatusHud.visible then return end
|
|
timerMs = timerMs + (dt or 0)
|
|
if timerMs < ADStatusHud.REFRESH_MS then return end
|
|
timerMs = 0
|
|
guarded("rebuild", ADStatusHud.rebuild, adEnv)
|
|
end
|
|
|
|
-- Tegnes ikke ved åben menu/dialog, skjult HUD, søvn eller åben chat.
|
|
local function shouldSkipDraw()
|
|
if g_gui ~= nil and g_gui:getIsGuiVisible() then return true end
|
|
if g_noHudModeEnabled then return true end
|
|
local mission = g_currentMission
|
|
local hud = mission ~= nil and mission.hud or nil
|
|
if hud == nil or hud.isVisible == false then return true end
|
|
if g_sleepManager ~= nil and g_sleepManager.getIsSleeping ~= nil and g_sleepManager:getIsSleeping() then return true end
|
|
if hud.chatDisplay ~= nil and hud.chatDisplay.getVisible ~= nil and hud.chatDisplay:getVisible() then return true end
|
|
return false
|
|
end
|
|
|
|
local function render(layout, bg)
|
|
bg.middle:setDimension(layout.width, layout.height)
|
|
bg.middle:setPosition(layout.x, layout.y)
|
|
bg.middle:render()
|
|
bg.left:setDimension(layout.padding, layout.height)
|
|
bg.left:setPosition(layout.x - layout.padding, layout.y)
|
|
bg.left:render()
|
|
bg.right:setDimension(layout.padding, layout.height)
|
|
bg.right:setPosition(layout.x + layout.width, layout.y)
|
|
bg.right:render()
|
|
setTextAlignment(RenderText.ALIGN_LEFT)
|
|
setTextVerticalAlignment(RenderText.VERTICAL_ALIGN_TOP)
|
|
local textX, textY = layout.x + layout.marginX, layout.top - layout.marginY
|
|
for _, line in ipairs(ADStatusHud.lines) do
|
|
local color = line.color
|
|
setTextBold(line.header == true)
|
|
setTextColor(color[1], color[2], color[3], color[4])
|
|
renderText(textX, textY, layout.textSize, line.text)
|
|
textY = textY - layout.textSize
|
|
end
|
|
end
|
|
|
|
function ADStatusHud.draw()
|
|
if not ADStatusHud.visible or ADStatusHud.layout == nil or #ADStatusHud.lines == 0 then return end
|
|
if shouldSkipDraw() then return end
|
|
local bg = createOverlays()
|
|
if bg == nil then return end
|
|
local ok, err = pcall(render, ADStatusHud.layout, bg)
|
|
-- tekststate nulstilles altid, også efter en fejl (andre mods/spillet tegner videre med den)
|
|
setTextColor(1, 1, 1, 1)
|
|
setTextAlignment(RenderText.ALIGN_LEFT)
|
|
setTextVerticalAlignment(RenderText.VERTICAL_ALIGN_BASELINE)
|
|
setTextBold(false)
|
|
if not ok then logOnce("draw", err) end
|
|
end
|
|
|
|
function ADStatusHud.delete()
|
|
deleteOverlays()
|
|
if PlayerInputComponent ~= nil and PlayerInputComponent.spuStatusToggleHandler == registerToggleActionRef then
|
|
PlayerInputComponent.spuStatusToggleHandler = nil
|
|
end
|
|
ADStatusHud.lines, ADStatusHud.layout = {}, nil
|
|
settingsLoaded = false
|
|
timerMs = 0
|
|
end
|
|
|
|
-- ---- tast: global spiller-handling (til fods og i køretøjer) ----
|
|
|
|
-- PlayerInputComponent.registerGlobalPlayerActionEvents kaldes ved hvert kontekstskift (til fods / i køretøj);
|
|
-- samme mønster som FS25_Courseplay (CP_OPEN_INGAME_MENU) og FS25_EasyDevControls. Hjælpeteksten skjules i F1.
|
|
local function registerToggleAction(component)
|
|
if not ADStatusHud.isClient() then return end
|
|
local player = component ~= nil and component.player or nil
|
|
if player ~= nil and player.isOwner == false then return end
|
|
if g_inputBinding == nil or InputAction == nil or InputAction.SPU_TOGGLE_STATUS == nil then return end
|
|
local _, eventId = g_inputBinding:registerActionEvent(InputAction.SPU_TOGGLE_STATUS, ADStatusHud, ADStatusHud.onToggleAction,
|
|
false, true, false, true)
|
|
if eventId ~= nil then g_inputBinding:setActionEventTextVisibility(eventId, false) end
|
|
end
|
|
|
|
registerToggleActionRef = function(component) guarded("registerAction", registerToggleAction, component) end
|
|
|
|
-- Spillets klasse overlever en genindlæsning af savegamet, moden gør ikke: krogen lægges kun én gang (markør på
|
|
-- klassen) og kalder den aktuelle indlæsnings handler, så en gammel ADStatusHud aldrig registrerer tasten igen.
|
|
function ADStatusHud.installInputHook()
|
|
if PlayerInputComponent == nil or PlayerInputComponent.registerGlobalPlayerActionEvents == nil or Utils == nil then return false end
|
|
PlayerInputComponent.spuStatusToggleHandler = registerToggleActionRef
|
|
if PlayerInputComponent.spuStatusToggleHooked then return true end
|
|
PlayerInputComponent.registerGlobalPlayerActionEvents = Utils.appendedFunction(PlayerInputComponent.registerGlobalPlayerActionEvents,
|
|
function(component, ...)
|
|
local handler = PlayerInputComponent.spuStatusToggleHandler
|
|
if handler ~= nil then handler(component) end
|
|
end)
|
|
PlayerInputComponent.spuStatusToggleHooked = true
|
|
return true
|
|
end
|
|
|
|
if PlayerInputComponent ~= nil and Utils ~= nil then
|
|
ADStatusHud.installInputHook()
|
|
end
|