From 9d04d6366dc33d694d3be6cbf468efe751be56d8 Mon Sep 17 00:00:00 2001 From: James Strong <54325531+heisenbugged@users.noreply.github.com> Date: Thu, 16 Apr 2026 00:07:16 -0500 Subject: [PATCH 1/5] Hide automatic speaker order announcements in FoW --- .../java/ti4/service/game/SetOrderService.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/ti4/service/game/SetOrderService.java b/src/main/java/ti4/service/game/SetOrderService.java index a2fa3b13d6..8b5db981b2 100644 --- a/src/main/java/ti4/service/game/SetOrderService.java +++ b/src/main/java/ti4/service/game/SetOrderService.java @@ -11,6 +11,7 @@ import ti4.game.Player; import ti4.message.MessageHelper; import ti4.service.emoji.MiscEmojis; +import ti4.service.fow.GMService; @UtilityClass public class SetOrderService { @@ -37,8 +38,21 @@ public static void setPlayerOrder(GenericInteractionCreateEvent event, Game game sb.append(MiscEmojis.SpeakerToken); } } - MessageChannel channel = event == null ? game.getActionsChannel() : event.getMessageChannel(); - MessageHelper.sendMessageToChannel(channel, sb.toString()); + MessageChannel channel = getAnnouncementChannel(event, game); + if (channel != null) { + MessageHelper.sendMessageToChannel(channel, sb.toString()); + } + } + + private static MessageChannel getAnnouncementChannel(GenericInteractionCreateEvent event, Game game) { + if (game.isFowMode()) { + MessageChannel gmChannel = GMService.getGMChannel(game); + if (gmChannel != null && !gmChannel.equals(game.getMainGameChannel())) { + return gmChannel; + } + return null; + } + return event == null ? game.getActionsChannel() : event.getMessageChannel(); } private static void setPlayerOrder(Map newPlayerOrder, Map players, User user) { From 762c2cc9247512acfd6c5f5b40fa4765419967e2 Mon Sep 17 00:00:00 2001 From: James Strong <54325531+heisenbugged@users.noreply.github.com> Date: Thu, 16 Apr 2026 00:09:56 -0500 Subject: [PATCH 2/5] fix: notify affected players about FoW unit changes --- .../ti4/helpers/ButtonHelperAbilities.java | 9 ++++++++ .../ti4/helpers/ButtonHelperCommanders.java | 22 +++++++++++++++++++ .../helpers/ButtonHelperFactionSpecific.java | 21 ++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/src/main/java/ti4/helpers/ButtonHelperAbilities.java b/src/main/java/ti4/helpers/ButtonHelperAbilities.java index 1df24b3dfa..cba4238b7a 100644 --- a/src/main/java/ti4/helpers/ButtonHelperAbilities.java +++ b/src/main/java/ti4/helpers/ButtonHelperAbilities.java @@ -2536,6 +2536,7 @@ public static void resolveFollowUpIndoctrinationQuestion( AddUnitService.addUnits(event, tile, game, player.getColor(), "1 " + unit + " " + planet); String opponent = "their opponent's"; String colour = ""; + Player indoctrinatedPlayer = null; for (Player p2 : game.getPlayers().values()) { if (p2.getColor() == null || p2 == player @@ -2548,6 +2549,7 @@ public static void resolveFollowUpIndoctrinationQuestion( ButtonHelper.resolveInfantryRemoval(p2, 1, tile); opponent = p2.getRepresentationNoPing(); colour = p2.getColor(); + indoctrinatedPlayer = p2; break; } } @@ -2611,6 +2613,13 @@ public static void resolveFollowUpIndoctrinationQuestion( player.getRepresentationNoPing() + " replaced 1 of " + opponent + " infantry with 1 " + unit + " on " + Helper.getPlanetRepresentation(planet, game) + " using **Indoctrination**."); } + if (game.isFowMode() && indoctrinatedPlayer != null) { + MessageHelper.sendPrivateMessageToPlayer( + indoctrinatedPlayer, + game, + player.getFactionEmoji() + " replaced 1 of your infantry with 1 " + unit + " on " + + Helper.getPlanetRepresentation(planet, game) + " using **Indoctrination**."); + } options.add(Buttons.red("deleteButtons", "Done Exhausting Planets")); MessageHelper.sendMessageToChannelWithButtons( event.getMessageChannel(), diff --git a/src/main/java/ti4/helpers/ButtonHelperCommanders.java b/src/main/java/ti4/helpers/ButtonHelperCommanders.java index 16a5eed5ac..444a8085d5 100644 --- a/src/main/java/ti4/helpers/ButtonHelperCommanders.java +++ b/src/main/java/ti4/helpers/ButtonHelperCommanders.java @@ -869,11 +869,23 @@ public static void resolveSolCommander(Player player, Game game, String buttonID String planet = buttonID.split("_")[1]; ButtonHelper.deleteButtonAndDeleteMessageIfEmpty(event); Tile tile = game.getTileFromPlanet(planet); + List playersToNotify = game.isFowMode() + ? game.getRealPlayersExcludingThis(player).stream() + .filter(p2 -> FoWHelper.playerHasUnitsOnPlanet(p2, tile, planet)) + .toList() + : List.of(); AddUnitService.addUnits(event, tile, game, player.getColor(), "1 inf " + planet); MessageHelper.sendMessageToChannel( event.getMessageChannel(), player.getFactionEmoji() + " placed 1 infantry on " + Helper.getPlanetRepresentation(planet, game) + " using Claire Gibson, the Sol Commander."); + for (Player p2 : playersToNotify) { + MessageHelper.sendPrivateMessageToPlayer( + p2, + game, + player.getFactionEmoji() + " placed 1 infantry on " + Helper.getPlanetRepresentation(planet, game) + + " using Claire Gibson, the Sol Commander."); + } } @ButtonHandler("utilizeMykoBT_") @@ -901,6 +913,7 @@ public static void utilizePharadnCommander( Player player, Game game, String buttonID, ButtonInteractionEvent event) { String planet = buttonID.split("_")[1]; Tile tile = game.getTileFromPlanet(planet); + Player destroyedPlayer = null; for (Player p2 : game.getPlayers().values()) { if (p2.getColor() == null || p2 == player @@ -910,6 +923,7 @@ public static void utilizePharadnCommander( if (FoWHelper.playerHasInfantryOnPlanet(p2, tile, planet) && !player.getAllianceMembers().contains(p2.getFaction())) { DestroyUnitService.destroyUnits(event, tile, game, p2.getColor(), "1 infantry " + planet, true); + destroyedPlayer = p2; break; } } @@ -917,6 +931,14 @@ public static void utilizePharadnCommander( event.getMessageChannel(), player.getFactionEmoji() + " destroyed 1 opposing infantry on " + Helper.getPlanetRepresentation(planet, game) + " using the Avhkan, the Pharad’n commander."); + if (game.isFowMode() && destroyedPlayer != null) { + MessageHelper.sendPrivateMessageToPlayer( + destroyedPlayer, + game, + player.getFactionEmoji() + " destroyed 1 of your infantry on " + + Helper.getPlanetRepresentation(planet, game) + + " using the Avhkan, the Pharad’n commander."); + } } @ButtonHandler("yssarilcommander_") diff --git a/src/main/java/ti4/helpers/ButtonHelperFactionSpecific.java b/src/main/java/ti4/helpers/ButtonHelperFactionSpecific.java index 7091d7037c..5bb6dbfe91 100644 --- a/src/main/java/ti4/helpers/ButtonHelperFactionSpecific.java +++ b/src/main/java/ti4/helpers/ButtonHelperFactionSpecific.java @@ -3044,6 +3044,11 @@ public static void resolveLetnevMech(Player player, Game game, String buttonID, String planet = buttonID.split("_")[1]; String unit = buttonID.split("_")[2]; Tile tile = game.getTileFromPlanet(planet); + List playersToNotify = game.isFowMode() + ? game.getRealPlayersExcludingThis(player).stream() + .filter(p2 -> FoWHelper.playerHasUnitsOnPlanet(p2, tile, planet)) + .toList() + : List.of(); AddUnitService.addUnits(event, tile, game, player.getColor(), "1 " + unit + " " + planet); RemoveUnitService.removeUnits(event, tile, game, player.getColor(), "1 infantry " + planet); List