Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import lombok.experimental.UtilityClass;
import net.dv8tion.jda.api.components.buttons.Button;
Expand All @@ -12,26 +11,18 @@
import ti4.discord.interactions.buttons.Buttons;
import ti4.discord.interactions.routing.ButtonHandler;
import ti4.game.Game;
import ti4.game.Planet;
import ti4.game.Player;
import ti4.game.Tile;
import ti4.helpers.ActionCardHelper;
import ti4.helpers.ButtonHelper;
import ti4.helpers.ComponentActionHelper;
import ti4.helpers.Constants;
import ti4.helpers.FoWHelper;
import ti4.helpers.Helper;
import ti4.helpers.NewStuffHelper;
import ti4.image.Mapper;
import ti4.message.MessageHelper;
import ti4.model.ExploreModel;
import ti4.model.TechnologyModel;
import ti4.model.UnitModel;
import ti4.service.combat.StartCombatService;
import ti4.service.emoji.CardEmojis;
import ti4.service.emoji.TechEmojis;
import ti4.service.emoji.UnitEmojis;
import ti4.service.unit.AddUnitService;

@UtilityClass
public class ArcanumTechHandler {
Expand All @@ -40,18 +31,8 @@ public class ArcanumTechHandler {
private static final String SHUFFLE_PURGED_EXPLORE = "shuffleSealOfRevelation_";
private static final String USE_SIGIL_OF_TRANSMUTATION = "useSigilOfTransmutation";
private static final String SIGIL_OF_TRANSMUTATION_TILE = "sigilOfTransmutationTile_";
private static final List<String> PRIMORDIAL_TECHS =
List.of("tharcanumpmy", "tharcanumpmg", "tharcanumpmr", "tharcanumpmb");
private static final List<String> EXPLORE_TYPES =
List.of(Constants.CULTURAL, Constants.HAZARDOUS, Constants.INDUSTRIAL, Constants.FRONTIER);
private static final String MIRACLE = "tharcanumpmg";
private static final String DISCARD_AC = "miracleAcDiscard";
private static final String GAIN_CC = "miracleGainCC";
private static final String PLACE_INF = "miraclePlaceFourInf";
private static final String SELECT_AC = "miracleSelectAcToDiscard_";
private static final String PLACE_INFANTRY = "miraclePlaceInfantry_";
private static final String FINISH_INFANTRY = "miracleFinishInfantry_";
private static final String INFANTRY_PLACED = "miracleInfantryPlaced_";

// Seal of Revelation
public static void resolveSealOfRevelation(GenericInteractionCreateEvent event, Game game, Player player) {
Expand Down Expand Up @@ -176,41 +157,6 @@ private static void offerPlanetExplorationButtons(GenericInteractionCreateEvent
buttons);
}

// Forbidden Knowledge
public static boolean hasFourTechsMatchingPrimordial(Player player) {
if (player == null) {
return false;
}

TechnologyModel.TechnologyType primordialType = null;
for (String primordialTech : PRIMORDIAL_TECHS) {
if (!player.hasTech(primordialTech)) {
continue;
}

TechnologyModel techModel = Mapper.getTech(primordialTech);
if (techModel != null) {
primordialType = techModel.getFirstType();
}
break;
}
if (primordialType == null) {
return false;
}

int matchingTechs = 0;
for (String tech : player.getTechs()) {
if (PRIMORDIAL_TECHS.contains(tech)) {
continue;
}
TechnologyModel techModel = Mapper.getTech(tech);
if (techModel != null && techModel.getTypes().contains(primordialType)) {
matchingTechs++;
}
}
return matchingTechs >= 4;
}

// Sigil of Transmutation
public static void offerSigilOfTransmutation(ButtonInteractionEvent event, Game game, Player player, Tile tile) {
if (event == null
Expand Down Expand Up @@ -263,7 +209,6 @@ public static void useSigilOfTransmutation(ButtonInteractionEvent event, Game ga
if (!spaceCannonPromptAlreadyAvailable && FoWHelper.otherPlayersHaveShipsInSystem(player, tile, game)) {
StartCombatService.sendSpaceCannonButtonsToThread(event.getMessageChannel(), game, player, tile);
}
ComponentActionHelper.serveNextComponentActionButtons(event, game, player);
ButtonHelper.deleteMessage(event);
}

Expand Down Expand Up @@ -313,247 +258,4 @@ public static void resetSigilOfTransmutationForNewDestination(Game game, Player
player.refreshTech(SIGIL_OF_TRANSMUTATION);
}
}

// Power Word: Miracle
public static void resolvePowerWordMiracle(GenericInteractionCreateEvent event, Game game, Player player) {
if (game == null
|| player == null
|| !player.hasTech(MIRACLE)
|| !player.getExhaustedTechs().contains(MIRACLE)
|| !hasFourTechsMatchingPrimordial(player)) {
return;
}
ComponentActionHelper.serveNextComponentActionButtons(event, game, player);

List<Button> buttons = new ArrayList<>();
buttons.add(Buttons.green(
player.factionButtonChecker() + DISCARD_AC, "Discard 1 AC and Draw 2", CardEmojis.getACEmoji(game)));
buttons.add(Buttons.green(player.factionButtonChecker() + GAIN_CC, "Gain 1 Command Token"));
buttons.add(Buttons.green(player.factionButtonChecker() + PLACE_INF, "Place 4 Infantry", UnitEmojis.infantry));

MessageHelper.sendMessageToChannelWithButtons(
event.getMessageChannel(),
player.getRepresentation() + ", please choose an effect for _Power Word: Miracle_.",
buttons);
}

@ButtonHandler(DISCARD_AC)
public static void getAcDiscardButtons(ButtonInteractionEvent event, Game game, Player player) {
if (game == null
|| player == null
|| !player.hasTech(MIRACLE)
|| !player.getExhaustedTechs().contains(MIRACLE)
|| !hasFourTechsMatchingPrimordial(player)) {
return;
}
ButtonHelper.deleteButtonAndDeleteMessageIfEmpty(event);

List<Button> discardButtons = new ArrayList<>();

for (Map.Entry<String, Integer> actionCard : player.getActionCards().entrySet()) {
discardButtons.add(Buttons.blue(
player.factionButtonChecker() + SELECT_AC + actionCard.getValue(),
"(" + actionCard.getValue() + ") "
+ Mapper.getActionCard(actionCard.getKey()).getName(),
CardEmojis.getACEmoji(game)));
}

MessageHelper.sendMessageToChannelWithButtons(
player.getCardsInfoThread(),
player.getRepresentation() + ", please choose an action card to discard.",
discardButtons);
}

@ButtonHandler(SELECT_AC)
public static void resolveMiracleAcDiscard(
ButtonInteractionEvent event, Game game, Player player, String buttonID) {
if (player == null || game == null || !player.hasTech(MIRACLE) || !hasFourTechsMatchingPrimordial(player)) {
return;
}

int handIndex;

try {
handIndex = Integer.parseInt(buttonID.substring(SELECT_AC.length()));
} catch (NumberFormatException e) {
ButtonHelper.deleteMessage(event);
return;
}

if (!player.getExhaustedTechs().contains("tharcanumpmg")
|| !player.getActionCards().containsValue(handIndex)) {
ButtonHelper.deleteMessage(event);
return;
}

ActionCardHelper.discardAC(event, game, player, handIndex);
ActionCardHelper.drawActionCards(player, 2);
ButtonHelper.deleteMessage(event);
}

@ButtonHandler(GAIN_CC)
public static void resolveMiracleCCGain(ButtonInteractionEvent event, Game game, Player player) {
if (player == null || game == null || !player.hasTech(MIRACLE) || !hasFourTechsMatchingPrimordial(player)) {
return;
}
ButtonHelper.deleteButtonAndDeleteMessageIfEmpty(event);

MessageHelper.sendMessageToChannelWithButtons(
event.getMessageChannel(),
player.getRepresentation() + ", please choose where to gain 1 command token.",
ButtonHelper.getGainCCButtons(player));
}

@ButtonHandler(PLACE_INF)
public static void getMiracleInfantryPlacementButtons(ButtonInteractionEvent event, Game game, Player player) {
if (game == null
|| player == null
|| !player.hasTech(MIRACLE)
|| !player.getExhaustedTechs().contains(MIRACLE)
|| !hasFourTechsMatchingPrimordial(player)) {
return;
}

ButtonHelper.deleteButtonAndDeleteMessageIfEmpty(event);
int round = game.getRound();
game.setStoredValue(INFANTRY_PLACED + player.getFaction() + "_" + round, "0");
List<Button> planetButtons = getMiracleInfantryButtons(game, player, round);
if (planetButtons.isEmpty()) {
game.removeStoredValue(INFANTRY_PLACED + player.getFaction() + "_" + round);
MessageHelper.sendMessageToChannel(
event.getMessageChannel(),
player.getRepresentation() + " has no eligible planet for the infantry.");
return;
}

String message = player.getRepresentation()
+ ", please choose planets on which to place up to 4 infantry with _Power Word: Miracle_.";
String buttonPrefix = player.factionButtonChecker() + PLACE_INFANTRY + round + "_";
Button done = Buttons.red(player.factionButtonChecker() + FINISH_INFANTRY + round, "Done Placing Infantry");
List<Button> displayedButtons = planetButtons.size() < 25
? new ArrayList<>(planetButtons)
: NewStuffHelper.buttonPagination(planetButtons, List.of(done), buttonPrefix, 25, 0, false);
if (planetButtons.size() < 25) {
displayedButtons.add(done);
}
MessageHelper.sendMessageToChannelWithButtons(event.getMessageChannel(), message, displayedButtons);
}

@ButtonHandler(PLACE_INFANTRY)
public static void placeMiracleInfantry(ButtonInteractionEvent event, Game game, Player player, String buttonID) {
if (game == null
|| player == null
|| !player.hasTech(MIRACLE)
|| !player.getExhaustedTechs().contains(MIRACLE)) {
ButtonHelper.deleteMessage(event);
return;
}

String placementData = buttonID.substring(PLACE_INFANTRY.length());
int separator = placementData.indexOf('_');
if (separator < 1) {
ButtonHelper.deleteMessage(event);
return;
}

int round;
try {
round = Integer.parseInt(placementData.substring(0, separator));
} catch (NumberFormatException e) {
ButtonHelper.deleteMessage(event);
return;
}

String stateKey = INFANTRY_PLACED + player.getFaction() + "_" + round;
String placedValue = game.getStoredValue(stateKey);
if (round != game.getRound() || placedValue.isEmpty()) {
ButtonHelper.deleteMessage(event);
return;
}

List<Button> planetButtons = getMiracleInfantryButtons(game, player, round);
String message = player.getRepresentation()
+ ", please choose planets on which to place up to 4 infantry with _Power Word: Miracle_.";
String buttonPrefix = player.factionButtonChecker() + PLACE_INFANTRY + round + "_";
Button done = Buttons.red(player.factionButtonChecker() + FINISH_INFANTRY + round, "Done Placing Infantry");
String planetName = placementData.substring(separator + 1);
if (planetName.startsWith("page")) {
try {
int page = Integer.parseInt(planetName.substring("page".length()));
NewStuffHelper.sendOrEditButtons(
event,
event.getMessageChannel(),
message,
NewStuffHelper.buttonPagination(planetButtons, List.of(done), buttonPrefix, 25, page, false));
} catch (NumberFormatException e) {
ButtonHelper.deleteMessage(event);
}
return;
}

int placed;
try {
placed = Integer.parseInt(placedValue);
} catch (NumberFormatException e) {
ButtonHelper.deleteMessage(event);
return;
}
Planet planet = game.getUnitHolderFromPlanet(planetName);
if (placed >= 4) {
MessageHelper.sendMessageToChannel(
event.getMessageChannel(),
player.getRepresentation()
+ " has already placed all 4 infantry. Press **Done Placing Infantry** when finished.");
return;
}
if (planet == null
|| !player.getPlanetsAllianceMode().contains(planetName)
|| planet.isSpaceStation(game)
|| planet.getTokenList().stream().anyMatch(token -> token.contains("dmz"))) {
ButtonHelper.deleteMessage(event);
return;
}

AddUnitService.addUnits(
event, game.getTileFromPlanet(planetName), game, player.getColor(), "1 gf " + planetName);
game.setStoredValue(stateKey, String.valueOf(placed + 1));
MessageHelper.sendMessageToChannel(
event.getMessageChannel(),
player.getRepresentation() + " placed 1 infantry on " + Helper.getPlanetRepresentation(planetName, game)
+ " with _Power Word: Miracle_ (" + (placed + 1) + "/4)."
+ (placed == 3 ? " Press **Done Placing Infantry** when finished." : ""));
}

@ButtonHandler(FINISH_INFANTRY)
public static void finishMiracleInfantry(ButtonInteractionEvent event, Game game, Player player, String buttonID) {
if (game == null || player == null) {
ButtonHelper.deleteMessage(event);
return;
}

try {
int round = Integer.parseInt(buttonID.substring(FINISH_INFANTRY.length()));
game.removeStoredValue(INFANTRY_PLACED + player.getFaction() + "_" + round);
} catch (NumberFormatException ignored) {
// The message is still safe to remove if an old or malformed completion button is pressed.
}
ButtonHelper.deleteMessage(event);
}

private static List<Button> getMiracleInfantryButtons(Game game, Player player, int round) {
List<Button> planetButtons = new ArrayList<>();
for (String planetName : player.getPlanetsAllianceMode()) {
Planet planet = game.getUnitHolderFromPlanet(planetName);
if (planet == null
|| planet.isSpaceStation(game)
|| planet.getTokenList().stream().anyMatch(token -> token.contains("dmz"))) {
continue;
}
planetButtons.add(Buttons.green(
player.factionButtonChecker() + PLACE_INFANTRY + round + "_" + planetName,
"Add 1 infantry to " + Helper.getPlanetRepresentation(planetName, game),
UnitEmojis.infantry));
}
return planetButtons;
}
}
Loading
Loading