Skip to content

Commit 4e7187b

Browse files
Merge pull request #5 from TheCodingDad-TisonK/development
feat: v2.1.0.0 — custom HUD, grouped settings UX, effect delivery
2 parents a0b0e46 + 42d1a66 commit 4e7187b

7 files changed

Lines changed: 984 additions & 159 deletions

File tree

FS25_RandomWorldEvents.zip

-375 KB
Binary file not shown.

RandomWorldEvents.lua

Lines changed: 93 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,25 @@ RandomWorldEvents = {
2020

2121
events = {
2222
enabled = true,
23-
frequency = 5,
24-
intensity = 2,
23+
frequency = 5,
24+
intensity = 2,
2525
showNotifications = true,
2626
showWarnings = true,
27-
cooldown = 30,
28-
27+
showHUD = true,
28+
cooldown = 30,
29+
2930
weatherEvents = false,
3031
economicEvents = true,
3132
vehicleEvents = true,
3233
fieldEvents = true,
3334
wildlifeEvents = true,
3435
specialEvents = true,
35-
36+
3637
debugLevel = 1
3738
},
39+
40+
-- HUD scale stored at top-level (not under events/physics) for clarity
41+
hudScale = 1.0,
3842

3943
debug = {
4044
enabled = false,
@@ -57,6 +61,9 @@ RandomWorldEvents = {
5761
needsSave = false,
5862
saveTime = nil,
5963

64+
-- HUD instance (created in loadGUI)
65+
eventHUD = nil,
66+
6067
-- Per-tick handler table populated by event modules.
6168
-- Each entry: [name] = function(rweInstance) ... end
6269
-- Called from applyActiveEventEffects() while an event is active.
@@ -116,6 +123,7 @@ function RandomWorldEvents:createSettingsManager()
116123
intensity = 2,
117124
showNotifications = true,
118125
showWarnings = true,
126+
showHUD = true,
119127
cooldown = 30,
120128
weatherEvents = false,
121129
economicEvents = true,
@@ -125,6 +133,7 @@ function RandomWorldEvents:createSettingsManager()
125133
specialEvents = true,
126134
debugLevel = 1
127135
},
136+
hudScale = 1.0,
128137
debug = {
129138
enabled = false,
130139
debugLevel = 1,
@@ -160,7 +169,9 @@ function RandomWorldEvents:createSettingsManager()
160169
settingsObject.events.intensity = xml:getInt(manager.XMLTAG..".events.intensity", manager.defaultConfig.events.intensity)
161170
settingsObject.events.showNotifications = xml:getBool(manager.XMLTAG..".events.showNotifications", manager.defaultConfig.events.showNotifications)
162171
settingsObject.events.showWarnings = xml:getBool(manager.XMLTAG..".events.showWarnings", manager.defaultConfig.events.showWarnings)
172+
settingsObject.events.showHUD = xml:getBool(manager.XMLTAG..".events.showHUD", manager.defaultConfig.events.showHUD)
163173
settingsObject.events.cooldown = xml:getInt(manager.XMLTAG..".events.cooldown", manager.defaultConfig.events.cooldown)
174+
settingsObject.hudScale = xml:getFloat(manager.XMLTAG..".hudScale", manager.defaultConfig.hudScale)
164175
settingsObject.events.weatherEvents = xml:getBool(manager.XMLTAG..".events.weatherEvents", manager.defaultConfig.events.weatherEvents)
165176
settingsObject.events.economicEvents = xml:getBool(manager.XMLTAG..".events.economicEvents", manager.defaultConfig.events.economicEvents)
166177
settingsObject.events.vehicleEvents = xml:getBool(manager.XMLTAG..".events.vehicleEvents", manager.defaultConfig.events.vehicleEvents)
@@ -187,10 +198,11 @@ function RandomWorldEvents:createSettingsManager()
187198
end
188199

189200
-- Use deep copy to avoid reference issues
190-
settingsObject.events = {}
191-
settingsObject.debug = {}
192-
settingsObject.physics = {}
193-
201+
settingsObject.events = {}
202+
settingsObject.debug = {}
203+
settingsObject.physics = {}
204+
settingsObject.hudScale = manager.defaultConfig.hudScale
205+
194206
for k, v in pairs(manager.defaultConfig.events) do
195207
settingsObject.events[k] = v
196208
end
@@ -217,7 +229,9 @@ function RandomWorldEvents:createSettingsManager()
217229
xml:setInt(manager.XMLTAG..".events.intensity", settingsObject.events.intensity)
218230
xml:setBool(manager.XMLTAG..".events.showNotifications", settingsObject.events.showNotifications)
219231
xml:setBool(manager.XMLTAG..".events.showWarnings", settingsObject.events.showWarnings)
232+
xml:setBool(manager.XMLTAG..".events.showHUD", settingsObject.events.showHUD)
220233
xml:setInt(manager.XMLTAG..".events.cooldown", settingsObject.events.cooldown)
234+
xml:setFloat(manager.XMLTAG..".hudScale", settingsObject.hudScale or 1.0)
221235
xml:setBool(manager.XMLTAG..".events.weatherEvents", settingsObject.events.weatherEvents)
222236
xml:setBool(manager.XMLTAG..".events.economicEvents", settingsObject.events.economicEvents)
223237
xml:setBool(manager.XMLTAG..".events.vehicleEvents", settingsObject.events.vehicleEvents)
@@ -382,13 +396,33 @@ function RandomWorldEvents:triggerRandomEvent()
382396
Logging.info("[RWE] Event triggered: " .. eventId .. " (Duration: " .. (duration / 60000) .. " minutes)")
383397

384398
local message = event.onStart(self.events.intensity)
385-
if message and self.events.showNotifications then
386-
g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_INFO, message)
387-
end
388-
399+
self:notifyEvent(message, event.category, true)
400+
389401
return true
390402
end
391403

404+
--- Show a rich event notification.
405+
-- Uses HUD flash queue when available; falls back to ingame notification.
406+
-- @param message Display text (nil = silent)
407+
-- @param categoryKey Event category string
408+
-- @param isPositive true = good event, false = bad event
409+
function RandomWorldEvents:notifyEvent(message, categoryKey, isPositive)
410+
if not message then return end
411+
412+
-- Always push to HUD flash queue (even if HUD is hidden — it queues for when shown)
413+
if self.eventHUD then
414+
self.eventHUD:pushFlash(message, categoryKey, isPositive)
415+
end
416+
417+
-- Also show the standard ingame notification if enabled
418+
if self.events.showNotifications and g_currentMission then
419+
local notifType = isPositive
420+
and FSBaseMission.INGAME_NOTIFICATION_OK
421+
or FSBaseMission.INGAME_NOTIFICATION_CRITICAL
422+
g_currentMission:addIngameNotification(notifType, message)
423+
end
424+
end
425+
392426
-- =====================
393427
-- PHYSICS SYSTEM (FS25)
394428
-- =====================
@@ -427,8 +461,11 @@ end
427461
-- =====================
428462

429463
function RandomWorldEvents:update(dt)
430-
if not self.isInitialized then
431-
return
464+
if not self.isInitialized then return end
465+
466+
-- Tick HUD
467+
if self.eventHUD then
468+
self.eventHUD:update(dt)
432469
end
433470

434471
-- Event system update
@@ -451,9 +488,7 @@ function RandomWorldEvents:update(dt)
451488
local event = self.EVENTS[self.EVENT_STATE.activeEvent]
452489
if event and event.onEnd then
453490
local message = event.onEnd()
454-
if message and self.events.showNotifications then
455-
g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_INFO, message)
456-
end
491+
self:notifyEvent(message, event and event.category, nil)
457492
end
458493
Logging.info("[RWE] Event ended: " .. tostring(self.EVENT_STATE.activeEvent))
459494
self.EVENT_STATE.activeEvent = nil
@@ -536,11 +571,7 @@ function RandomWorldEvents:consoleCommandEnd()
536571
local event = self.EVENTS[self.EVENT_STATE.activeEvent]
537572
if event and event.onEnd then
538573
local message = event.onEnd()
539-
if message then
540-
if self.events.showNotifications then
541-
g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_INFO, message)
542-
end
543-
end
574+
self:notifyEvent(message, event and event.category, nil)
544575
end
545576

546577
self.EVENT_STATE.activeEvent = nil
@@ -610,9 +641,18 @@ end
610641
-- =====================
611642

612643
function RandomWorldEvents:loadGUI()
644+
-- Create the event HUD overlay
645+
self.eventHUD = RWEEventHUD.new(self)
646+
if self.eventHUD then
647+
self.eventHUD.scale = self.hudScale or 1.0
648+
self.eventHUD:loadLayout()
649+
Logging.info("[RWE] Event HUD created")
650+
else
651+
Logging.warning("[RWE] RWEEventHUD not available — HUD disabled")
652+
end
653+
613654
-- Settings are injected into ESC > Settings via RWESettingsIntegration (hooks pattern).
614-
-- No custom screen registration needed.
615-
Logging.info("[RWE] GUI ready (settings via InGameMenuSettingsFrame hook)")
655+
Logging.info("[RWE] GUI ready")
616656
end
617657

618658
-- =====================
@@ -646,7 +686,7 @@ local function load(mission)
646686
if rweManager.events.enabled and rweManager.events.showNotifications then
647687
mission:addIngameNotification(
648688
FSBaseMission.INGAME_NOTIFICATION_OK,
649-
"Random World Events v2.0.0.6 loaded"
689+
"Random World Events v2.1.0.0 loaded"
650690
)
651691
end
652692

@@ -662,28 +702,42 @@ end
662702

663703
local function delete(mission)
664704
if rweManager then
705+
if rweManager.eventHUD then
706+
rweManager.eventHUD:saveLayout()
707+
rweManager.eventHUD:delete()
708+
rweManager.eventHUD = nil
709+
end
665710
rweManager:saveSettings()
666711
rweManager = nil
667712
getfenv(0)["g_RandomWorldEvents"] = nil
668713
Logging.info("[RandomWorldEvents] Shutting down")
669714
end
670715
end
671716

672-
local function keyEvent(unicode, sym, modifier, isDown)
717+
local function keyEvent(mission, unicode, sym, modifier, isDown)
673718
if not isDown or not rweManager then return end
674719

675-
if sym == 284 then -- F3 — hint: settings are in ESC > Settings
676-
if g_currentMission then
677-
g_currentMission:addIngameNotification(
678-
FSBaseMission.INGAME_NOTIFICATION_INFO,
679-
"RWE: Open ESC > Settings to configure Random World Events"
680-
)
720+
if sym == 284 then -- F3 — toggle HUD
721+
if rweManager.eventHUD then
722+
rweManager.eventHUD:toggleVisibility()
681723
end
682724
elseif sym == 290 then -- F9 — force-trigger a random event
683725
rweManager:triggerRandomEvent()
684726
end
685727
end
686728

729+
local function draw(mission)
730+
if rweManager and rweManager.eventHUD then
731+
rweManager.eventHUD:draw()
732+
end
733+
end
734+
735+
local function mouseEvent(mission, posX, posY, isDown, isUp, button)
736+
if rweManager and rweManager.eventHUD then
737+
rweManager.eventHUD:onMouseEvent(posX, posY, isDown, isUp, button)
738+
end
739+
end
740+
687741
local function loadFinished(mission, ...)
688742
if rweManager and not rweManager.guiLoaded then
689743
rweManager:loadGUI()
@@ -694,12 +748,14 @@ end
694748
-- Hook into FS25
695749
Mission00.load = Utils.prependedFunction(Mission00.load, load)
696750
Mission00.loadMission00Finished = Utils.appendedFunction(Mission00.loadMission00Finished, loadFinished)
697-
FSBaseMission.update = Utils.appendedFunction(FSBaseMission.update, update)
698-
FSBaseMission.delete = Utils.appendedFunction(FSBaseMission.delete, delete)
699-
FSBaseMission.keyEvent = Utils.appendedFunction(FSBaseMission.keyEvent, keyEvent)
751+
FSBaseMission.update = Utils.appendedFunction(FSBaseMission.update, update)
752+
FSBaseMission.draw = Utils.appendedFunction(FSBaseMission.draw, draw)
753+
FSBaseMission.mouseEvent = Utils.appendedFunction(FSBaseMission.mouseEvent, mouseEvent)
754+
FSBaseMission.delete = Utils.appendedFunction(FSBaseMission.delete, delete)
755+
FSBaseMission.keyEvent = Utils.appendedFunction(FSBaseMission.keyEvent, keyEvent)
700756

701757
Logging.info("========================================")
702-
Logging.info(" FS25 Random World Events v2.0.0.6 ")
758+
Logging.info(" FS25 Random World Events v2.1.0.0 ")
703759
Logging.info(" Successfully Loaded ")
704760
Logging.info(" Type 'rwe' in console for help ")
705761
Logging.info("========================================")

build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ root_files = [
2424
'icon.dds',
2525
'README.md',
2626
]
27-
subdirs = ['icons', 'gui', 'xml', 'utils']
27+
subdirs = ['icons', 'gui', 'xml', 'utils', 'api']
2828
2929
with zipfile.ZipFile(out_zip, 'w', compression=zipfile.ZIP_DEFLATED) as zf:
3030
for f in root_files:

0 commit comments

Comments
 (0)