From b4bb5572af4fe6c80c37e0c217e847ef07a431f2 Mon Sep 17 00:00:00 2001 From: Infinitay Date: Sat, 20 Dec 2025 07:47:28 -0500 Subject: [PATCH 1/8] feat(module): Created PluginModule class for modular plugin lifecycle - Created an abstract class PluginModule to better handle multiple modules within the plugin and to appropriately handle the lifecycle - Construct injected common fields such as OverlayManager, Client, and the config - Field injected on-demand fields such as EventBus and GameEventManager - Automatically (un)registers the module from the EventBus - Re-fire various events by utilizing GameEventManager#simulateGameEvents within #startUp - Abstracted #onStartUp to handle module starts, #onShutdown to handle module stops, and #isEnabled to determine the status of the module --- .../pluginmodulesystem/PluginModule.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/main/java/randomeventhelper/pluginmodulesystem/PluginModule.java diff --git a/src/main/java/randomeventhelper/pluginmodulesystem/PluginModule.java b/src/main/java/randomeventhelper/pluginmodulesystem/PluginModule.java new file mode 100644 index 0000000..bb49a8c --- /dev/null +++ b/src/main/java/randomeventhelper/pluginmodulesystem/PluginModule.java @@ -0,0 +1,55 @@ +package randomeventhelper.pluginmodulesystem; + +import javax.inject.Inject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import net.runelite.api.Client; +import net.runelite.api.GameState; +import net.runelite.client.callback.ClientThread; +import net.runelite.client.config.Config; +import net.runelite.client.eventbus.EventBus; +import net.runelite.client.ui.overlay.OverlayManager; +import net.runelite.client.util.GameEventManager; +import randomeventhelper.RandomEventHelperConfig; + +@Slf4j +// Thanks to Llemon for this - Since we are now relying on constructor injection, we will need a constructor followed by injecting it +// To keep it a little cleaner, you can still use lombok RAC and also pass in @Inject into it so that the constructor will be injected properly +// Also, keep in mind that we don't need to define final variables within the module classes themselves since they will be passed in via the constructor injection super call +@RequiredArgsConstructor(onConstructor = @__(@Inject)) +public abstract class PluginModule +{ + // It's fine to field inject these since we only need access to them here and not in the module classes themselves + @Inject + protected EventBus eventBus; + @Inject + protected GameEventManager gameEventManager; + protected final OverlayManager overlayManager; + protected final RandomEventHelperConfig config; + protected final Client client; + + public abstract void onStartUp(); + + public abstract void onShutdown(); + + public abstract boolean isEnabled(); + + public void startUp() + { + this.eventBus.register(this); + this.onStartUp(); + if (client.getGameState().getState() >= GameState.LOGGED_IN.getState()) + { + // Remember to pass in the instance (this) and not the class (#getClass) + this.gameEventManager.simulateGameEvents(this); + } + log.debug("Started the {} module", this.getClass().getSimpleName()); + } + + public void shutdown() + { + this.eventBus.unregister(this); + this.onShutdown(); + log.debug("Shutdown the {} module", this.getClass().getSimpleName()); + } +} From c471c4b831047a1f6ce642e59f137ab98c67a5eb Mon Sep 17 00:00:00 2001 From: Infinitay Date: Sun, 21 Dec 2025 18:59:05 -0500 Subject: [PATCH 2/8] refactor: Start refactoring RandomEventHelper to modular plugin lifecycle - Removed prior injections that have yet to be refactored - Refactored #startUp, #shutDown, and #onConfigChanged to utilize the new modular system to handle state changes --- .../RandomEventHelperPlugin.java | 227 ++---------------- .../pluginmodulesystem/PluginModule.java | 3 +- 2 files changed, 26 insertions(+), 204 deletions(-) diff --git a/src/main/java/randomeventhelper/RandomEventHelperPlugin.java b/src/main/java/randomeventhelper/RandomEventHelperPlugin.java index f9e56e5..535e018 100644 --- a/src/main/java/randomeventhelper/RandomEventHelperPlugin.java +++ b/src/main/java/randomeventhelper/RandomEventHelperPlugin.java @@ -1,6 +1,8 @@ package randomeventhelper; +import com.google.common.collect.ImmutableMap; import com.google.inject.Provides; +import java.util.Map; import javax.inject.Inject; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Actor; @@ -30,6 +32,7 @@ import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.ui.overlay.OverlayManager; +import randomeventhelper.pluginmodulesystem.PluginModule; import randomeventhelper.randomevents.beekeeper.BeekeeperHelper; import randomeventhelper.randomevents.drilldemon.DrillDemonHelper; import randomeventhelper.randomevents.freakyforester.FreakyForesterHelper; @@ -70,90 +73,24 @@ public class RandomEventHelperPlugin extends Plugin @Inject private RandomEventHelperItemOverlay itemOverlay; - @Inject - private SurpriseExamHelper surpriseExamHelper; - - @Inject - private BeekeeperHelper beekeeperHelper; - - @Inject - private FreakyForesterHelper freakyForesterHelper; - - @Inject - private PinballHelper pinballHelper; - - @Inject - private DrillDemonHelper drillDemonHelper; - - @Inject - private GravediggerHelper gravediggerHelper; - - @Inject - private GravediggerOverlay gravediggerOverlay; - - @Inject - private MimeHelper mimeHelper; - - @Inject - private MazeHelper mazeHelper; - - @Inject - private SandwichLadyHelper sandwichLadyHelper; - - @Inject - private QuizMasterHelper quizMasterHelper; - - @Inject - private PirateHelper pirateHelper; + // -> + private Map pluginModulesMap; @Override protected void startUp() throws Exception { this.overlayManager.add(overlay); this.overlayManager.add(itemOverlay); - if (config.isSurpriseExamEnabled()) - { - surpriseExamHelper.startUp(); - } - if (config.isBeekeeperEnabled()) - { - beekeeperHelper.startUp(); - } - if (config.isFreakyForesterEnabled()) - { - freakyForesterHelper.startUp(); - } - if (config.isPinballEnabled()) - { - pinballHelper.startUp(); - } - if (config.isDrillDemonEnabled()) - { - drillDemonHelper.startUp(); - } - if (config.isGravediggerEnabled()) - { - gravediggerHelper.startUp(gravediggerOverlay); - } - if (config.isMimeEnabled()) - { - mimeHelper.startUp(); - } - if (config.isMazeEnabled()) - { - mazeHelper.startUp(); - } - if (config.isSandwichLadyEnabled()) - { - sandwichLadyHelper.startUp(); - } - if (config.isQuizMasterEnabled()) - { - quizMasterHelper.startUp(); - } - if (config.isCaptArnavChestEnabled()) + + pluginModulesMap = ImmutableMap.builder() + .build(); + // Start only the enabled modules + for (PluginModule module : pluginModulesMap.values()) { - pirateHelper.startUp(); + if (module.isEnabled()) + { + module.startUp(); + } } } @@ -162,17 +99,11 @@ protected void shutDown() throws Exception { this.overlayManager.remove(overlay); this.overlayManager.remove(itemOverlay); - surpriseExamHelper.shutDown(); - beekeeperHelper.shutDown(); - freakyForesterHelper.shutDown(); - pinballHelper.shutDown(); - drillDemonHelper.shutDown(); - gravediggerHelper.shutDown(); - mimeHelper.shutDown(); - mazeHelper.shutDown(); - sandwichLadyHelper.shutDown(); - quizMasterHelper.shutDown(); - pirateHelper.shutDown(); + // Shutdown all modules regardless of their enabled state + for (PluginModule module : pluginModulesMap.values()) + { + module.shutdown(); + } } @Subscribe @@ -181,125 +112,17 @@ public void onConfigChanged(ConfigChanged configChanged) if (configChanged.getGroup().equals("randomeventhelper")) { log.debug("Config changed: {} | New value: {}", configChanged.getKey(), configChanged.getNewValue()); - if (configChanged.getKey().equals("isSurpriseExamEnabled")) - { - if (config.isSurpriseExamEnabled()) - { - surpriseExamHelper.startUp(); - } - else - { - surpriseExamHelper.shutDown(); - } - } - else if (configChanged.getKey().equals("isBeekeeperEnabled")) - { - if (config.isBeekeeperEnabled()) - { - beekeeperHelper.startUp(); - } - else - { - beekeeperHelper.shutDown(); - } - } - else if (configChanged.getKey().equals("isFreakyForesterEnabled")) - { - if (config.isFreakyForesterEnabled()) - { - freakyForesterHelper.startUp(); - } - else - { - freakyForesterHelper.shutDown(); - } - } - else if (configChanged.getKey().equals("isPinballEnabled")) - { - if (config.isPinballEnabled()) - { - pinballHelper.startUp(); - } - else - { - pinballHelper.shutDown(); - } - } - else if (configChanged.getKey().equals("isDrillDemonEnabled")) - { - if (config.isDrillDemonEnabled()) - { - drillDemonHelper.startUp(); - } - else - { - drillDemonHelper.shutDown(); - } - } - else if (configChanged.getKey().equals("isGravediggerEnabled")) - { - if (config.isGravediggerEnabled()) - { - gravediggerHelper.startUp(gravediggerOverlay); - } - else - { - gravediggerHelper.shutDown(); - } - } - else if (configChanged.getKey().equals("isMimeEnabled")) - { - if (config.isMimeEnabled()) - { - mimeHelper.startUp(); - } - else - { - mimeHelper.shutDown(); - } - } - else if (configChanged.getKey().equals("isMazeEnabled")) - { - if (config.isMazeEnabled()) - { - mazeHelper.startUp(); - } - else - { - mazeHelper.shutDown(); - } - } - else if (configChanged.getKey().equals("isSandwichLadyEnabled")) - { - if (config.isSandwichLadyEnabled()) - { - sandwichLadyHelper.startUp(); - } - else - { - sandwichLadyHelper.shutDown(); - } - } - else if (configChanged.getKey().equals("isQuizMasterEnabled")) - { - if (config.isQuizMasterEnabled()) - { - quizMasterHelper.startUp(); - } - else - { - quizMasterHelper.shutDown(); - } - } - else if (configChanged.getKey().equals("isCaptArnavChestEnabled")) + // Let's first handle plugin module updates - so lets first check to see if the changed config key is a mapped module + PluginModule module = pluginModulesMap.get(configChanged.getKey()); + if (module != null) { - if (config.isCaptArnavChestEnabled()) + if (module.isEnabled()) { - pirateHelper.startUp(); + module.startUp(); } else { - pirateHelper.shutDown(); + module.shutdown(); } } } diff --git a/src/main/java/randomeventhelper/pluginmodulesystem/PluginModule.java b/src/main/java/randomeventhelper/pluginmodulesystem/PluginModule.java index bb49a8c..3b52d11 100644 --- a/src/main/java/randomeventhelper/pluginmodulesystem/PluginModule.java +++ b/src/main/java/randomeventhelper/pluginmodulesystem/PluginModule.java @@ -5,8 +5,6 @@ import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; import net.runelite.api.GameState; -import net.runelite.client.callback.ClientThread; -import net.runelite.client.config.Config; import net.runelite.client.eventbus.EventBus; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.GameEventManager; @@ -41,6 +39,7 @@ public void startUp() if (client.getGameState().getState() >= GameState.LOGGED_IN.getState()) { // Remember to pass in the instance (this) and not the class (#getClass) + // Re-posts NpcSpawned, PlayerSpawned, WallObjectSpawned, DecorativeObjectSpawned, GroundObjectSpawned, GameObjectSpawned, ItemSpawned, WorldEntitySpawned this.gameEventManager.simulateGameEvents(this); } log.debug("Started the {} module", this.getClass().getSimpleName()); From 191c2b6326f3b784bb79707032015d2b2e22d36e Mon Sep 17 00:00:00 2001 From: Infinitay Date: Sun, 21 Dec 2025 19:11:59 -0500 Subject: [PATCH 3/8] refactor(surpriseexam): Migrate SurpriseExamHelper to PluginModule lifecycle - Refactored SurpriseExamHelper to the modular plugin lifecycle - Now extends PluginModule and implements respective methods, moving the existing start/stop login there - Use constructor injection and removed duplicate field injections - Injected SurpriseExamHelper and added it to the pluginModulesMap --- .../RandomEventHelperPlugin.java | 4 +++ .../surpriseexam/SurpriseExamHelper.java | 31 ++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/randomeventhelper/RandomEventHelperPlugin.java b/src/main/java/randomeventhelper/RandomEventHelperPlugin.java index 535e018..0e748f7 100644 --- a/src/main/java/randomeventhelper/RandomEventHelperPlugin.java +++ b/src/main/java/randomeventhelper/RandomEventHelperPlugin.java @@ -73,6 +73,9 @@ public class RandomEventHelperPlugin extends Plugin @Inject private RandomEventHelperItemOverlay itemOverlay; + @Inject + private SurpriseExamHelper surpriseExamHelper; + // -> private Map pluginModulesMap; @@ -83,6 +86,7 @@ protected void startUp() throws Exception this.overlayManager.add(itemOverlay); pluginModulesMap = ImmutableMap.builder() + .put("isSurpriseExamEnabled", surpriseExamHelper) .build(); // Start only the enabled modules for (PluginModule module : pluginModulesMap.values()) diff --git a/src/main/java/randomeventhelper/randomevents/surpriseexam/SurpriseExamHelper.java b/src/main/java/randomeventhelper/randomevents/surpriseexam/SurpriseExamHelper.java index dab2c2e..0195368 100644 --- a/src/main/java/randomeventhelper/randomevents/surpriseexam/SurpriseExamHelper.java +++ b/src/main/java/randomeventhelper/randomevents/surpriseexam/SurpriseExamHelper.java @@ -23,20 +23,15 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.widgets.Widget; import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.overlay.OverlayManager; +import randomeventhelper.RandomEventHelperConfig; +import randomeventhelper.pluginmodulesystem.PluginModule; @Slf4j @Singleton -public class SurpriseExamHelper +public class SurpriseExamHelper extends PluginModule { - @Inject - private EventBus eventBus; - - @Inject - private Client client; - @Inject private ClientThread clientThread; @@ -111,9 +106,15 @@ public class SurpriseExamHelper InterfaceID.PatternNext.SELECT_3 }; - public void startUp() + @Inject + public SurpriseExamHelper(OverlayManager overlayManager, RandomEventHelperConfig config, Client client) + { + super(overlayManager, config, client); + } + + @Override + public void onStartUp() { - this.eventBus.register(this); this.overlayManager.add(overlay); this.patternCardHint = null; this.patternCardAnswers = null; @@ -123,9 +124,9 @@ public void startUp() this.relationshipSystem = new OSRSItemRelationshipSystem(); } - public void shutDown() + @Override + public void onShutdown() { - this.eventBus.unregister(this); this.overlayManager.remove(overlay); this.patternCardHint = null; this.patternCardAnswers = null; @@ -135,6 +136,12 @@ public void shutDown() this.relationshipSystem = null; } + @Override + public boolean isEnabled() + { + return this.config.isSurpriseExamEnabled(); + } + @Subscribe public void onWidgetLoaded(WidgetLoaded widgetLoaded) { From 172025135bd553ac1ade4104d08e7ffbe16fa254 Mon Sep 17 00:00:00 2001 From: Infinitay Date: Sun, 21 Dec 2025 20:08:48 -0500 Subject: [PATCH 4/8] feat(PluginModule): Add #isLoggedIn to check if the player is logged in --- .../randomeventhelper/pluginmodulesystem/PluginModule.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/randomeventhelper/pluginmodulesystem/PluginModule.java b/src/main/java/randomeventhelper/pluginmodulesystem/PluginModule.java index 3b52d11..49c9cd0 100644 --- a/src/main/java/randomeventhelper/pluginmodulesystem/PluginModule.java +++ b/src/main/java/randomeventhelper/pluginmodulesystem/PluginModule.java @@ -36,7 +36,7 @@ public void startUp() { this.eventBus.register(this); this.onStartUp(); - if (client.getGameState().getState() >= GameState.LOGGED_IN.getState()) + if (this.client.getGameState().getState() >= GameState.LOGGED_IN.getState()) { // Remember to pass in the instance (this) and not the class (#getClass) // Re-posts NpcSpawned, PlayerSpawned, WallObjectSpawned, DecorativeObjectSpawned, GroundObjectSpawned, GameObjectSpawned, ItemSpawned, WorldEntitySpawned @@ -51,4 +51,9 @@ public void shutdown() this.onShutdown(); log.debug("Shutdown the {} module", this.getClass().getSimpleName()); } + + public boolean isLoggedIn() + { + return this.client.getGameState().getState() >= GameState.LOGGED_IN.getState(); + } } From 751e08058f9095914b9dfeffd883c6320ddf3d1b Mon Sep 17 00:00:00 2001 From: Infinitay Date: Sun, 21 Dec 2025 20:09:32 -0500 Subject: [PATCH 5/8] feat(surpriseexam): Improve support for starting during active event - Improved handling initial runs when (re)starting the plugin when already inside the Surprise Exam random event - Primarily for when the puzzle interface is already on screen --- .../surpriseexam/SurpriseExamHelper.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/randomeventhelper/randomevents/surpriseexam/SurpriseExamHelper.java b/src/main/java/randomeventhelper/randomevents/surpriseexam/SurpriseExamHelper.java index 0195368..573f71c 100644 --- a/src/main/java/randomeventhelper/randomevents/surpriseexam/SurpriseExamHelper.java +++ b/src/main/java/randomeventhelper/randomevents/surpriseexam/SurpriseExamHelper.java @@ -122,6 +122,24 @@ public void onStartUp() this.patternNextAnswer = null; this.patternNextAnswerWidget = null; this.relationshipSystem = new OSRSItemRelationshipSystem(); + + if (this.isLoggedIn()) + { + this.clientThread.invokeLater(() -> { + if (this.client.getWidget(InterfaceID.PatternCards.HINT) != null) + { + WidgetLoaded matchingCardsWidgetLoaded = new WidgetLoaded(); + matchingCardsWidgetLoaded.setGroupId(InterfaceID.PATTERN_CARDS); + this.eventBus.post(matchingCardsWidgetLoaded); + } + if (this.client.getWidget(InterfaceID.PatternNext.UNIVERSE_TEXT12) != null) + { + WidgetLoaded whatsNextWidgetLoaded = new WidgetLoaded(); + whatsNextWidgetLoaded.setGroupId(InterfaceID.PATTERN_NEXT); + this.eventBus.post(whatsNextWidgetLoaded); + } + }); + } } @Override From 78101cec6ac49b5ae485de7f3f41235c0fe09dc5 Mon Sep 17 00:00:00 2001 From: Infinitay Date: Mon, 22 Dec 2025 15:38:28 -0500 Subject: [PATCH 6/8] refactor(captarnav): Migrate PirateHelper to PluginModule lifecycle - Refactored PirateHelper to the modular plugin lifecycle - Now extends PluginModule and implements respective methods, moving the existing start/stop login there - Use constructor injection and removed duplicate field injections - Injected PirateHelper and added it to the pluginModulesMap --- .../RandomEventHelperPlugin.java | 4 +++ .../randomevents/pirate/PirateHelper.java | 31 ++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/randomeventhelper/RandomEventHelperPlugin.java b/src/main/java/randomeventhelper/RandomEventHelperPlugin.java index 0e748f7..c4f644d 100644 --- a/src/main/java/randomeventhelper/RandomEventHelperPlugin.java +++ b/src/main/java/randomeventhelper/RandomEventHelperPlugin.java @@ -73,6 +73,9 @@ public class RandomEventHelperPlugin extends Plugin @Inject private RandomEventHelperItemOverlay itemOverlay; + @Inject + private PirateHelper pirateHelper; + @Inject private SurpriseExamHelper surpriseExamHelper; @@ -86,6 +89,7 @@ protected void startUp() throws Exception this.overlayManager.add(itemOverlay); pluginModulesMap = ImmutableMap.builder() + .put("isCaptArnavChestEnabled", pirateHelper) .put("isSurpriseExamEnabled", surpriseExamHelper) .build(); // Start only the enabled modules diff --git a/src/main/java/randomeventhelper/randomevents/pirate/PirateHelper.java b/src/main/java/randomeventhelper/randomevents/pirate/PirateHelper.java index dbffc01..4603631 100644 --- a/src/main/java/randomeventhelper/randomevents/pirate/PirateHelper.java +++ b/src/main/java/randomeventhelper/randomevents/pirate/PirateHelper.java @@ -14,22 +14,17 @@ import net.runelite.api.gameval.VarbitID; import net.runelite.api.widgets.Widget; import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.overlay.OverlayManager; import net.runelite.client.util.Text; +import randomeventhelper.RandomEventHelperConfig; import randomeventhelper.RandomEventHelperPlugin; +import randomeventhelper.pluginmodulesystem.PluginModule; @Slf4j @Singleton -public class PirateHelper +public class PirateHelper extends PluginModule { - @Inject - private EventBus eventBus; - - @Inject - private Client client; - @Inject private ClientThread clientThread; @@ -49,24 +44,36 @@ public class PirateHelper @Getter private Map widgetMap; - public void startUp() + @Inject + public PirateHelper(OverlayManager overlayManager, RandomEventHelperConfig config, Client client) + { + super(overlayManager, config, client); + } + + @Override + public void onStartUp() { - this.eventBus.register(this); this.overlayManager.add(pirateOverlay); this.pirateChestSolver = new PirateChestSolver(); this.initiallyLoaded = false; this.widgetMap = Maps.newHashMap(); } - public void shutDown() + @Override + public void onShutdown() { - this.eventBus.unregister(this); this.overlayManager.remove(pirateOverlay); this.pirateChestSolver = null; this.initiallyLoaded = false; this.widgetMap = null; } + @Override + public boolean isEnabled() + { + return this.config.isCaptArnavChestEnabled(); + } + @Subscribe public void onVarbitChanged(VarbitChanged varbitChanged) { From b0d167be71b4efd93d31d0bd9e083b2cffb501fc Mon Sep 17 00:00:00 2001 From: Infinitay Date: Tue, 23 Dec 2025 21:49:33 -0500 Subject: [PATCH 7/8] refactor(mime): Migrate MimeHelper to PluginModule lifecycle - Refactored MimeHelper to the modular plugin lifecycle - Now extends PluginModule and implements respective methods, moving the existing start/stop login there - Use constructor injection and removed duplicate field injections - Injected MimeHelper and added it to the pluginModulesMap --- .../RandomEventHelperPlugin.java | 4 +++ .../randomevents/mime/MimeHelper.java | 31 ++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/randomeventhelper/RandomEventHelperPlugin.java b/src/main/java/randomeventhelper/RandomEventHelperPlugin.java index c4f644d..f8986a9 100644 --- a/src/main/java/randomeventhelper/RandomEventHelperPlugin.java +++ b/src/main/java/randomeventhelper/RandomEventHelperPlugin.java @@ -76,6 +76,9 @@ public class RandomEventHelperPlugin extends Plugin @Inject private PirateHelper pirateHelper; + @Inject + private MimeHelper mimeHelper; + @Inject private SurpriseExamHelper surpriseExamHelper; @@ -90,6 +93,7 @@ protected void startUp() throws Exception pluginModulesMap = ImmutableMap.builder() .put("isCaptArnavChestEnabled", pirateHelper) + .put("isMimeEnabled", mimeHelper) .put("isSurpriseExamEnabled", surpriseExamHelper) .build(); // Start only the enabled modules diff --git a/src/main/java/randomeventhelper/randomevents/mime/MimeHelper.java b/src/main/java/randomeventhelper/randomevents/mime/MimeHelper.java index e87425c..1233da8 100644 --- a/src/main/java/randomeventhelper/randomevents/mime/MimeHelper.java +++ b/src/main/java/randomeventhelper/randomevents/mime/MimeHelper.java @@ -14,21 +14,16 @@ import net.runelite.api.gameval.NpcID; import net.runelite.api.widgets.Widget; import net.runelite.client.callback.ClientThread; -import net.runelite.client.eventbus.EventBus; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.ui.overlay.OverlayManager; +import randomeventhelper.RandomEventHelperConfig; import randomeventhelper.RandomEventHelperPlugin; +import randomeventhelper.pluginmodulesystem.PluginModule; @Slf4j @Singleton -public class MimeHelper +public class MimeHelper extends PluginModule { - @Inject - private EventBus eventBus; - - @Inject - private Client client; - @Inject private ClientThread clientThread; @@ -49,24 +44,36 @@ public class MimeHelper private static final int MIME_RANDOM_EVENT_REGION_ID = 8010; - public void startUp() + @Inject + public MimeHelper(OverlayManager overlayManager, RandomEventHelperConfig config, Client client) + { + super(overlayManager, config, client); + } + + @Override + public void onStartUp() { - this.eventBus.register(this); this.overlayManager.add(mimeOverlay); this.mimeNPC = null; this.currentMimeEmote = null; this.mimeEmoteAnswerWidget = null; } - public void shutDown() + @Override + public void onShutdown() { - this.eventBus.unregister(this); this.overlayManager.remove(mimeOverlay); this.mimeNPC = null; this.currentMimeEmote = null; this.mimeEmoteAnswerWidget = null; } + @Override + public boolean isEnabled() + { + return this.config.isMimeEnabled(); + } + @Subscribe public void onAnimationChanged(AnimationChanged animationChanged) { From 36f21ee696a106e5c13128168e37cae967e89167 Mon Sep 17 00:00:00 2001 From: Infinitay Date: Wed, 24 Dec 2025 00:51:44 -0500 Subject: [PATCH 8/8] feat(mime): Improve support for starting during active event, overlay, refactor - Improved handling initial runs when (re)starting the plugin when already inside the Mime random event - Primarily for when the emote button interface is already on screen - Change Mime text when undetermined emote answer - Use default font size for overlay - Refactored Mime animation checks and answer updating into #updateMimeAnimation --- .../randomevents/mime/MimeHelper.java | 54 ++++++++++++++----- .../randomevents/mime/MimeOverlay.java | 5 +- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/main/java/randomeventhelper/randomevents/mime/MimeHelper.java b/src/main/java/randomeventhelper/randomevents/mime/MimeHelper.java index 1233da8..05fe7be 100644 --- a/src/main/java/randomeventhelper/randomevents/mime/MimeHelper.java +++ b/src/main/java/randomeventhelper/randomevents/mime/MimeHelper.java @@ -57,6 +57,20 @@ public void onStartUp() this.mimeNPC = null; this.currentMimeEmote = null; this.mimeEmoteAnswerWidget = null; + + // Not really needed since we depend on AnimationChanged, so if the plugin is off, then we won't ever catch it + // And if we do catch the animation, then the widget always loads anyway afterward + if (this.isLoggedIn()) + { + this.clientThread.invokeLater(() -> { + if (this.client.getWidget(InterfaceID.MacroMimeEmotes.BUTTON_0) != null) + { + WidgetLoaded mimeEmoteButtonWidgetLoaded = new WidgetLoaded(); + mimeEmoteButtonWidgetLoaded.setGroupId(InterfaceID.MACRO_MIME_EMOTES); + this.eventBus.post(mimeEmoteButtonWidgetLoaded); + } + }); + } } @Override @@ -90,19 +104,8 @@ public void onAnimationChanged(AnimationChanged animationChanged) { return; } - if (mime.getAnimation() != -1 && mime.getAnimation() != 858) - { - MimeEmote mimeEmote = MimeEmote.getMimeEmoteFromAnimationID(mime.getAnimation()); - this.currentMimeEmote = mimeEmote; - if (mimeEmote != null) - { - log.debug("Mime Animation Detected: {}", mimeEmote); - } - else - { - log.debug("Unknown Mime Animation Detected: Animation ID = {}", mime.getAnimation()); - } - } + + this.updateMimeAnimation(mime); } @Subscribe @@ -141,6 +144,9 @@ public void onNpcSpawned(NpcSpawned npcSpawned) { this.mimeNPC = npcSpawned.getNpc(); log.debug("Mime NPC Spawned, setting mimeNPC: {}", this.mimeNPC); + + // In case the Mime is already doing an emote (starting mid-event, etc.) + this.updateMimeAnimation(this.mimeNPC); } } @@ -155,4 +161,26 @@ public void onNpcDespawned(NpcDespawned npcDespawned) log.debug("Mime NPC Despawned, clearing Mime Random Event data"); } } + + private void updateMimeAnimation(NPC mimeNPC) + { + if (mimeNPC.getAnimation() != -1 && mimeNPC.getAnimation() != 858) + { + MimeEmote mimeEmote = MimeEmote.getMimeEmoteFromAnimationID(mimeNPC.getAnimation()); + if (mimeEmote == this.currentMimeEmote) + { + log.debug("Mime Animation unchanged: {}", mimeEmote); + return; + } + this.currentMimeEmote = mimeEmote; + if (mimeEmote != null) + { + log.debug("Mime Animation Detected: {}", mimeEmote); + } + else + { + log.debug("Unknown Mime Animation Detected: Animation ID = {}", mimeNPC.getAnimation()); + } + } + } } diff --git a/src/main/java/randomeventhelper/randomevents/mime/MimeOverlay.java b/src/main/java/randomeventhelper/randomevents/mime/MimeOverlay.java index faa85a5..4f3b297 100644 --- a/src/main/java/randomeventhelper/randomevents/mime/MimeOverlay.java +++ b/src/main/java/randomeventhelper/randomevents/mime/MimeOverlay.java @@ -42,10 +42,9 @@ public Dimension render(Graphics2D graphics2D) { OverlayUtil.renderPolygon(graphics2D, plugin.getMimeEmoteAnswerWidget().getBounds(), Color.GREEN); } - if (plugin.getMimeNPC() != null && plugin.getCurrentMimeEmote() != null) + if (plugin.getMimeNPC() != null) { - String mimeEmoteText = plugin.getCurrentMimeEmote().name(); - graphics2D.setFont(graphics2D.getFont().deriveFont(18f)); + String mimeEmoteText = plugin.getCurrentMimeEmote() != null ? plugin.getCurrentMimeEmote().name() : "Waiting for emote"; int mimeHeight = plugin.getMimeNPC().getLogicalHeight(); int mimeTextOffset = plugin.getMimeNPC().getAnimationHeightOffset(); Point textPoint = plugin.getMimeNPC().getCanvasTextLocation(graphics2D, mimeEmoteText, mimeHeight + mimeTextOffset);