diff --git a/src/main/java/com/turtlehoarder/cobblemonchallenge/battle/ChallengeBattleBuilder.java b/src/main/java/com/turtlehoarder/cobblemonchallenge/battle/ChallengeBattleBuilder.java index 464e071..e01421d 100644 --- a/src/main/java/com/turtlehoarder/cobblemonchallenge/battle/ChallengeBattleBuilder.java +++ b/src/main/java/com/turtlehoarder/cobblemonchallenge/battle/ChallengeBattleBuilder.java @@ -24,14 +24,14 @@ public class ChallengeBattleBuilder { public static Vector clonedPokemonList = new Vector<>(); public static Vector challengeBattles = new Vector<>(); private ChallengeFormat format = ChallengeFormat.STANDARD_6V6; - public void lvlxpvp(ServerPlayer player1, ServerPlayer player2, BattleFormat battleFormat, int level, List player1Selection, List player2Selection) throws ChallengeBuilderException { + public void lvlxpvp(ServerPlayer player1, ServerPlayer player2, BattleFormat battleFormat, int minLevel, int maxLevel, int handicapP1, int handicapP2, List player1Selection, List player2Selection) throws ChallengeBuilderException { PartyStore p1Party = Cobblemon.INSTANCE.getStorage().getParty(player1); PartyStore p2Party = Cobblemon.INSTANCE.getStorage().getParty(player2); // Clone parties so original is not effected - List player1Team = createBattleTeamFromParty(p1Party, player1Selection, level); - List player2Team = createBattleTeamFromParty(p2Party, player2Selection, level); + List player1Team = createBattleTeamFromParty(p1Party, player1Selection, minLevel, maxLevel, handicapP1); + List player2Team = createBattleTeamFromParty(p2Party, player2Selection, minLevel, maxLevel, handicapP2); PlayerBattleActor player1Actor = new PlayerBattleActor(player1.getUUID(), player1Team); PlayerBattleActor player2Actor = new PlayerBattleActor(player2.getUUID(), player2Team); @@ -44,7 +44,8 @@ public void lvlxpvp(ServerPlayer player1, ServerPlayer player2, BattleFormat bat } // Method to create our own clones according to the format - private List createBattleTeamFromParty(PartyStore party, List selectedSlots, int level) throws ChallengeBuilderException { + private List createBattleTeamFromParty(PartyStore party, List selectedSlots, int minLevel, int maxLevel, int handicap) throws ChallengeBuilderException { + List battlePokemonList = new ArrayList(); if (format == ChallengeFormat.STANDARD_6V6) { int leadSlot = selectedSlots.get(0); @@ -53,13 +54,16 @@ private List createBattleTeamFromParty(PartyStore party, List CHALLENGE_REQUESTS = new HashMap<>(); public static final HashMap ACTIVE_SELECTIONS = new HashMap<>(); private static final HashMap LAST_SENT_CHALLENGE = new HashMap<>(); + public static void register(CommandDispatcher dispatcher) { - // Basic challenge command that initiates a challenge with the default challenge level - LiteralArgumentBuilder baseCommandBuilder = Commands.literal("challenge") + // Overview: + // > always player name with level or min/maxLevel are mutually exclusive + // > 12 command trees + // > further additions may need a UI implementation to refine/make more user friendly + + // (default everything) + // handicap + // no preview + // handicap + no preview + + // level + // level + handicap + // level + no preview + // level + handicap + no preview + + // min/max + // min/max + handicap + // min/max + no preview + // min/max + handicap + no preview + + // (default everything) + LiteralArgumentBuilder defaultChallengeProperties = Commands.literal("challenge") .then(Commands.argument("player", EntityArgument.player()) - .executes(c -> challengePlayer(c, DEFAULT_LEVEL, true))); + .executes(c -> challengePlayer(c, DEFAULT_LEVEL, DEFAULT_LEVEL, DEFAULT_HANDICAP, DEFAULT_HANDICAP, true)) + ); + + // handicap + LiteralArgumentBuilder handicapChallengeProperties = Commands.literal("challenge") + .then(Commands.argument("player", EntityArgument.player()) + .then(Commands.literal("handicapP1") + .then(Commands.argument("setP1HandicapTo", IntegerArgumentType.integer(-99,99)) + .then(Commands.literal("handicapP2") + .then(Commands.argument("setP2HandicapTo", IntegerArgumentType.integer(-99,99)) + .executes(c -> challengePlayer(c, DEFAULT_LEVEL, DEFAULT_LEVEL, IntegerArgumentType.getInteger(c, "setP1HandicapTo"), IntegerArgumentType.getInteger(c, "setP2HandicapTo"), true)) + ) + + ) + ) + ) + ); - // Basic challenge command that initiates a challenge with the default challenge level - LiteralArgumentBuilder baseCommandBuilderNoPreview = Commands.literal("challenge") + // no preview + LiteralArgumentBuilder noPreviewChallengeProperties = Commands.literal("challenge") .then(Commands.argument("player", EntityArgument.player()) .then(Commands.literal("nopreview") - .executes(c -> challengePlayer(c, DEFAULT_LEVEL, false)))); + .executes(c -> challengePlayer(c, DEFAULT_LEVEL, DEFAULT_LEVEL, DEFAULT_HANDICAP, DEFAULT_HANDICAP, false)) + ) + ); + + // handicap + no preview + LiteralArgumentBuilder handicapNoPreviewChallengeProperties = Commands.literal("challenge") + .then(Commands.argument("player", EntityArgument.player()) + .then(Commands.literal("handicapP1") + .then(Commands.argument("setP1HandicapTo", IntegerArgumentType.integer(-99,99)) + .then(Commands.literal("handicapP2") + .then(Commands.argument("setP2HandicapTo", IntegerArgumentType.integer(-99,99)) + .then(Commands.literal("nopreview") + .executes(c -> challengePlayer(c, DEFAULT_LEVEL, DEFAULT_LEVEL, IntegerArgumentType.getInteger(c, "setP1HandicapTo"), IntegerArgumentType.getInteger(c, "setP2HandicapTo"), false)) + ) + ) + ) + ) + ) + ); + // level + LiteralArgumentBuilder levelChallengeProperties = Commands.literal("challenge") + .then(Commands.argument("player", EntityArgument.player()) + .then(Commands.literal("level") + .then(Commands.argument("setLevelTo", IntegerArgumentType.integer(1,100)) + .executes(c -> challengePlayer(c, IntegerArgumentType.getInteger(c, "setLevelTo"), IntegerArgumentType.getInteger(c, "setLevelTo"), DEFAULT_HANDICAP, DEFAULT_HANDICAP, true)) - // Challenge command that initiates a challenge with a given level - LiteralArgumentBuilder commandBuilderWithLevelOption = Commands.literal("challenge") + ) + ) + ); + + // level + handicap + LiteralArgumentBuilder levelHandicapChallengeProperties = Commands.literal("challenge") .then(Commands.argument("player", EntityArgument.player()) .then(Commands.literal("level") .then(Commands.argument("setLevelTo", IntegerArgumentType.integer(1,100)) - .executes(c -> challengePlayer(c, IntegerArgumentType.getInteger(c, "setLevelTo"), true) + .then(Commands.literal("handicapP1") + .then(Commands.argument("setP1HandicapTo", IntegerArgumentType.integer(-99,99)) + .then(Commands.literal("handicapP2") + .then(Commands.argument("setP2HandicapTo", IntegerArgumentType.integer(-99,99)) + .executes(c -> challengePlayer(c, IntegerArgumentType.getInteger(c, "setLevelTo"), IntegerArgumentType.getInteger(c, "setLevelTo"), IntegerArgumentType.getInteger(c, "setP1HandicapTo"), IntegerArgumentType.getInteger(c, "setP2HandicapTo"), true)) + ) + ) + ) ) + ) ) ); - // Challenge command that initiates a challenge with a given level - LiteralArgumentBuilder commandBuilderWithLevelOptionNoPreview = Commands.literal("challenge") + + // level + no preview + LiteralArgumentBuilder levelNoPreviewChallengeProperties = Commands.literal("challenge") .then(Commands.argument("player", EntityArgument.player()) .then(Commands.literal("level") .then(Commands.argument("setLevelTo", IntegerArgumentType.integer(1,100)) .then(Commands.literal("nopreview") - .executes(c -> challengePlayer(c, IntegerArgumentType.getInteger(c, "setLevelTo"), false) + .executes(c -> challengePlayer(c, IntegerArgumentType.getInteger(c, "setLevelTo"), IntegerArgumentType.getInteger(c, "setLevelTo"), DEFAULT_HANDICAP, DEFAULT_HANDICAP, false)) + ) + + ) + ) + ); + + // level + handicap + no preview + LiteralArgumentBuilder levelHandicapNoPreviewChallengeProperties = Commands.literal("challenge") + .then(Commands.argument("player", EntityArgument.player()) + .then(Commands.literal("level") + .then(Commands.argument("setLevelTo", IntegerArgumentType.integer(1,100)) + .then(Commands.literal("handicapP1") + .then(Commands.argument("setP1HandicapTo", IntegerArgumentType.integer(-99,99)) + .then(Commands.literal("handicapP2") + .then(Commands.argument("setP2HandicapTo", IntegerArgumentType.integer(-99,99)) + .then(Commands.literal("nopreview") + .executes(c -> challengePlayer(c, IntegerArgumentType.getInteger(c, "setLevelTo"), IntegerArgumentType.getInteger(c, "setLevelTo"), IntegerArgumentType.getInteger(c, "setP1HandicapTo"), IntegerArgumentType.getInteger(c, "setP2HandicapTo"), false)) + ) + ) + ) ) ) + ) ) ); - // Challenge command that initiates a challenge with a given level - LiteralArgumentBuilder commandBuilderWithLevelOptionNoPreviewBefore = Commands.literal("challenge") + // min/max + LiteralArgumentBuilder minMaxLevelChallengeProperties = Commands.literal("challenge") .then(Commands.argument("player", EntityArgument.player()) - .then(Commands.literal("nopreview") - .then(Commands.literal("level") - .then(Commands.argument("setLevelTo", IntegerArgumentType.integer(1,100)) - .executes(c -> challengePlayer(c, IntegerArgumentType.getInteger(c, "setLevelTo"), false) + .then(Commands.literal("minLevel") + .then(Commands.argument("setMinLevelTo", IntegerArgumentType.integer(1,100)) + .then(Commands.literal("maxLevel") + .then(Commands.argument("setMaxLevelTo", IntegerArgumentType.integer(1,100)) + .executes(c -> challengePlayer(c, IntegerArgumentType.getInteger(c, "setMinLevelTo"), IntegerArgumentType.getInteger(c, "setMaxLevelTo"), DEFAULT_HANDICAP, DEFAULT_HANDICAP, true)) + ) + ) + + ) + ) + ); + + // min/max + handicap + LiteralArgumentBuilder minMaxLevelHandicapChallengeProperties = Commands.literal("challenge") + .then(Commands.argument("player", EntityArgument.player()) + .then(Commands.literal("minLevel") + .then(Commands.argument("setMinLevelTo", IntegerArgumentType.integer(1,100)) + .then(Commands.literal("maxLevel") + .then(Commands.argument("setMaxLevelTo", IntegerArgumentType.integer(1,100)) + .then(Commands.literal("handicapP1") + .then(Commands.argument("setP1HandicapTo", IntegerArgumentType.integer(-99,99)) + .then(Commands.literal("handicapP2") + .then(Commands.argument("setP2HandicapTo", IntegerArgumentType.integer(-99,99)) + .executes(c -> challengePlayer(c, IntegerArgumentType.getInteger(c, "setMinLevelTo"), IntegerArgumentType.getInteger(c, "setMaxLevelTo"), IntegerArgumentType.getInteger(c, "setP1HandicapTo"), IntegerArgumentType.getInteger(c, "setP2HandicapTo"), true)) + ) + ) + ) + ) + ) + ) + + ) + ) + ); + + // min/max + no preview + LiteralArgumentBuilder minMaxLevelNoPreviewChallengeProperties = Commands.literal("challenge") + .then(Commands.argument("player", EntityArgument.player()) + .then(Commands.literal("minLevel") + .then(Commands.argument("setMinLevelTo", IntegerArgumentType.integer(1,100)) + .then(Commands.literal("maxLevel") + .then(Commands.argument("setMaxLevelTo", IntegerArgumentType.integer(1,100)) + .then(Commands.literal("nopreview") + .executes(c -> challengePlayer(c, IntegerArgumentType.getInteger(c, "setMinLevelTo"), IntegerArgumentType.getInteger(c, "setMaxLevelTo"), DEFAULT_HANDICAP, DEFAULT_HANDICAP, false)) + ) + ) + ) + + ) + ) + ); + + // min/max + handicap + no preview + LiteralArgumentBuilder minMaxLevelHandicapNoPreviewChallengeProperties = Commands.literal("challenge") + .then(Commands.argument("player", EntityArgument.player()) + .then(Commands.literal("minLevel") + .then(Commands.argument("setMinLevelTo", IntegerArgumentType.integer(1,100)) + .then(Commands.literal("maxLevel") + .then(Commands.argument("setMaxLevelTo", IntegerArgumentType.integer(1,100)) + .then(Commands.literal("handicapP1") + .then(Commands.argument("setP1HandicapTo", IntegerArgumentType.integer(-99,99)) + .then(Commands.literal("handicapP2") + .then(Commands.argument("setP2HandicapTo", IntegerArgumentType.integer(-99,99)) + .then(Commands.literal("nopreview") + .executes(c -> challengePlayer(c, IntegerArgumentType.getInteger(c, "setMinLevelTo"), IntegerArgumentType.getInteger(c, "setMaxLevelTo"), IntegerArgumentType.getInteger(c, "setP1HandicapTo"), IntegerArgumentType.getInteger(c, "setP2HandicapTo"), false)) + ) + ) + ) + ) + ) ) ) + ) ) ); // Command called to accept challenges - LiteralArgumentBuilder commandBuilderAcceptChallenge = Commands.literal("acceptchallenge") + LiteralArgumentBuilder acceptChallengeAndProperties = Commands.literal("acceptchallenge") .then(Commands.argument("id", StringArgumentType.string()).executes(c -> acceptChallenge(c, StringArgumentType.getString(c, "id")))); // Command called to deny challenges - LiteralArgumentBuilder commandBuilderRejectChallenge = Commands.literal("rejectchallenge") + LiteralArgumentBuilder rejectChallengeAndProperties = Commands.literal("rejectchallenge") .then(Commands.argument("id", StringArgumentType.string()).executes(c -> rejectChallenge(c, StringArgumentType.getString(c, "id")))); - dispatcher.register(commandBuilderAcceptChallenge); - dispatcher.register(commandBuilderRejectChallenge); - dispatcher.register(commandBuilderWithLevelOption); - // Register nopreview section - dispatcher.register(commandBuilderWithLevelOptionNoPreview); - dispatcher.register(baseCommandBuilderNoPreview); - dispatcher.register(commandBuilderWithLevelOptionNoPreviewBefore); - dispatcher.register(baseCommandBuilder); + dispatcher.register(acceptChallengeAndProperties); + dispatcher.register(rejectChallengeAndProperties); + + // 12 possible Challenge Properties Commands + dispatcher.register(defaultChallengeProperties); + dispatcher.register(handicapChallengeProperties); + dispatcher.register(noPreviewChallengeProperties); + dispatcher.register(handicapNoPreviewChallengeProperties); + + dispatcher.register(levelChallengeProperties); + dispatcher.register(levelHandicapChallengeProperties); + dispatcher.register(levelNoPreviewChallengeProperties); + dispatcher.register(levelHandicapNoPreviewChallengeProperties); + + dispatcher.register(minMaxLevelChallengeProperties); + dispatcher.register(minMaxLevelHandicapChallengeProperties); + dispatcher.register(minMaxLevelNoPreviewChallengeProperties); + dispatcher.register(minMaxLevelHandicapNoPreviewChallengeProperties); } - public static int challengePlayer(CommandContext c, int level, boolean preview) { + public static int challengePlayer(CommandContext c, int minLevel, int maxLevel, int handicapP1, int handicapP2, boolean preview) { try { ServerPlayer challengerPlayer = c.getSource().getPlayer(); ServerPlayer challengedPlayer = c.getArgument("player", EntitySelector.class).findSinglePlayer(c.getSource()); @@ -147,14 +320,22 @@ public static int challengePlayer(CommandContext c, int leve return 0; } - ChallengeRequest request = ChallengeUtil.createChallengeRequest(challengerPlayer, challengedPlayer, level, preview); + // make sure the min max range contains at least one functional value + // > defaults to maxLevel + if (minLevel > maxLevel){ + minLevel = maxLevel; + } + + ChallengeRequest request = ChallengeUtil.createChallengeRequest(challengerPlayer, challengedPlayer, minLevel, maxLevel, handicapP1, handicapP2, preview); CHALLENGE_REQUESTS.put(request.id, request); - String options = ""; - if (!request.preview()) { - options = ChatFormatting.GOLD + " [NoTeamPreview]"; - } - MutableComponent notificationComponent = Component.literal(ChatFormatting.YELLOW + String.format("You have been challenged to a " + ChatFormatting.BOLD + "level %d Pokemon battle" + ChatFormatting.RESET + ChatFormatting.YELLOW + " by %s!" + options, level, challengerPlayer.getDisplayName().getString())); MutableComponent interactiveComponent = Component.literal("Click to accept or deny: "); + String levelComponent = (minLevel == maxLevel) ? ChatFormatting.YELLOW + String.format("You have been challenged to a " + ChatFormatting.BOLD + "level %d Pokemon battle", maxLevel) : ChatFormatting.YELLOW + String.format("You have been challenged to a " + ChatFormatting.BOLD + "level %d - %d Pokemon battle", minLevel, maxLevel); + String challengerComponent = ChatFormatting.YELLOW + " by " + challengerPlayer.getDisplayName().getString() + "!"; + String optionsComponent = request.preview() ? "" : ChatFormatting.RED + " [NoTeamPreview]"; + String handicapComponent = (handicapP1 == 0 && handicapP2 == 0) ? "" : ChatFormatting.BLUE + " [" + challengerPlayer.getDisplayName().getString() + " handicap of " + handicapP1 + "] [" + challengedPlayer.getDisplayName().getString() + " handicap of " + handicapP2 + "]"; + MutableComponent notificationComponent = Component.literal(levelComponent + challengerComponent + optionsComponent + handicapComponent); + + MutableComponent interactiveComponent = Component.literal("Click to accept or deny: "); interactiveComponent.append(Component.literal(ChatFormatting.GREEN + "Battle!").setStyle(Style.EMPTY.withBold(true).withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/acceptchallenge %s", request.id))))); interactiveComponent.append(Component.literal(" or ")); interactiveComponent.append(Component.literal(ChatFormatting.RED + "Reject").setStyle(Style.EMPTY.withBold(true).withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.format("/rejectchallenge %s", request.id))))); diff --git a/src/main/java/com/turtlehoarder/cobblemonchallenge/config/ChallengeConfig.java b/src/main/java/com/turtlehoarder/cobblemonchallenge/config/ChallengeConfig.java index 729bd73..62ba39a 100644 --- a/src/main/java/com/turtlehoarder/cobblemonchallenge/config/ChallengeConfig.java +++ b/src/main/java/com/turtlehoarder/cobblemonchallenge/config/ChallengeConfig.java @@ -9,6 +9,7 @@ public class ChallengeConfig { public static Boolean CHALLENGE_DISTANCE_RESTRICTION; public static int MAX_CHALLENGE_DISTANCE; public static int DEFAULT_CHALLENGE_LEVEL; + public static int DEFAULT_HANDICAP; public static int REQUEST_EXPIRATION_MILLIS; public static int CHALLENGE_COOLDOWN_MILLIS; @@ -23,6 +24,7 @@ private static void createConfigs() { configs.addKeyValuePair(new Pair<>("challengeDistanceRestriction", true)); configs.addKeyValuePair(new Pair<>("maxChallengeDistance", 50)); configs.addKeyValuePair(new Pair<>("defaultChallengeLevel", 50)); + configs.addKeyValuePair(new Pair<>("defaultHandicap", 0)); configs.addKeyValuePair(new Pair<>("challengeExpirationTime", 60000)); configs.addKeyValuePair(new Pair<>("challengeCooldownTime", 5000)); } @@ -31,6 +33,7 @@ private static void assignConfigs() { CHALLENGE_COOLDOWN_MILLIS = CONFIG.getOrDefault("challengeCooldownTime", 5000); CHALLENGE_DISTANCE_RESTRICTION = CONFIG.getOrDefault("challengeDistanceRestriction", true); DEFAULT_CHALLENGE_LEVEL = CONFIG.getOrDefault("defaultChallengeLevel", 50); + DEFAULT_HANDICAP = CONFIG.getOrDefault("defaultHandicap", 0); MAX_CHALLENGE_DISTANCE = CONFIG.getOrDefault("maxChallengeDistance", 50); REQUEST_EXPIRATION_MILLIS = CONFIG.getOrDefault("challengeExpirationTime", 60000); } diff --git a/src/main/java/com/turtlehoarder/cobblemonchallenge/gui/LeadPokemonMenuProvider.java b/src/main/java/com/turtlehoarder/cobblemonchallenge/gui/LeadPokemonMenuProvider.java index 78967c5..faf1348 100644 --- a/src/main/java/com/turtlehoarder/cobblemonchallenge/gui/LeadPokemonMenuProvider.java +++ b/src/main/java/com/turtlehoarder/cobblemonchallenge/gui/LeadPokemonMenuProvider.java @@ -70,15 +70,19 @@ private void setupPokemonRepresentation(LeadPokemonMenu leadPokemonMenu) { PartyStore p2Party = Cobblemon.INSTANCE.getStorage().getParty(rival); setupGlassFiller(leadPokemonMenu); + int handicapP1 = (this.selector == request.challengerPlayer()) ? request.handicapP1() : request.handicapP2(); + int handicapP2 = (this.selector == request.challengerPlayer()) ? request.handicapP2() : request.handicapP1(); + for (int x = 0; x < p1Party.size(); x ++) { int itemSlot = x * 9; // Lefthand column of the menu Pokemon pokemon = p1Party.get(x); if (pokemon == null) // Skip any empty slots in the pokemon team continue; BattlePokemon copy = BattlePokemon.Companion.safeCopyOf(pokemon); - pokemon = ChallengeUtil.applyFormatTransformations(ChallengeFormat.STANDARD_6V6, copy, request.level()).getEffectedPokemon(); // Apply battle transformations to each pokemon + int adjustedLevelP1 = ChallengeUtil.getBattlePokemonAdjustedLevel(pokemon.getLevel(), request.minLevel(), request.maxLevel(), handicapP1); + pokemon = ChallengeUtil.applyFormatTransformations(ChallengeFormat.STANDARD_6V6, copy, adjustedLevelP1).getEffectedPokemon(); // Apply battle transformations to each pokemon ItemStack pokemonItem = PokemonItem.from(pokemon, 1); - pokemonItem.setHoverName(Component.literal(ChatFormatting.AQUA + String.format("%s (lvl%d)", pokemon.getDisplayName().getString(), request.level()))); + pokemonItem.setHoverName(Component.literal(ChatFormatting.AQUA + String.format("%s (lvl%d)", pokemon.getDisplayName().getString(), adjustedLevelP1))); ListTag pokemonLoreTag = ChallengeUtil.generateLoreTagForPokemon(pokemon); pokemonItem.getOrCreateTagElement("display").put("Lore", pokemonLoreTag); leadPokemonMenu.setItem(itemSlot, leadPokemonMenu.getStateId(), pokemonItem); @@ -93,7 +97,8 @@ private void setupPokemonRepresentation(LeadPokemonMenu leadPokemonMenu) { } if (selectionSession.teamPreviewOn()) { ItemStack pokemonItem = PokemonItem.from(pokemon, 1); - pokemonItem.setHoverName(Component.literal(ChatFormatting.RED + String.format("%s's %s (lvl%d)", rival.getDisplayName().getString(), pokemon.getDisplayName().getString(), request.level()))); + int adjustedLevelP2 = ChallengeUtil.getBattlePokemonAdjustedLevel(pokemon.getLevel(), request.minLevel(), request.maxLevel(), handicapP2); + pokemonItem.setHoverName(Component.literal(ChatFormatting.RED + String.format("%s's %s (lvl%d)", rival.getDisplayName().getString(), pokemon.getDisplayName().getString(), adjustedLevelP2))); leadPokemonMenu.setItem(itemSlot, leadPokemonMenu.getStateId(), pokemonItem); } else { ItemStack pokemonItem = new ItemStack(CobblemonItems.POKE_BALL.asItem()); diff --git a/src/main/java/com/turtlehoarder/cobblemonchallenge/gui/LeadPokemonSelectionSession.java b/src/main/java/com/turtlehoarder/cobblemonchallenge/gui/LeadPokemonSelectionSession.java index 2d8aea5..59412df 100644 --- a/src/main/java/com/turtlehoarder/cobblemonchallenge/gui/LeadPokemonSelectionSession.java +++ b/src/main/java/com/turtlehoarder/cobblemonchallenge/gui/LeadPokemonSelectionSession.java @@ -61,13 +61,16 @@ public void onPokemonSelected(LeadPokemonMenuProvider menuProvider) { } private void beginBattle() { - int level = originRequest.level(); + int minLevel = originRequest.minLevel(); + int maxLevel = originRequest.maxLevel(); + int handicapP1 = originRequest.handicapP1(); + int handicapP2 = originRequest.handicapP2(); SESSIONS_TO_CANCEL.add(this); challengerMenuProvider.forceCloseMenu(); challengedMenuProvider.forceCloseMenu(); ChallengeBattleBuilder challengeBuilder = new ChallengeBattleBuilder(); try { - challengeBuilder.lvlxpvp(originRequest.challengerPlayer(), originRequest.challengedPlayer(), BattleFormat.Companion.getGEN_9_SINGLES(), level, challengerMenuProvider.selectedSlots, challengedMenuProvider.selectedSlots); + challengeBuilder.lvlxpvp(originRequest.challengerPlayer(), originRequest.challengedPlayer(), BattleFormat.Companion.getGEN_9_SINGLES(), minLevel, maxLevel, handicapP1, handicapP2, challengerMenuProvider.selectedSlots, challengedMenuProvider.selectedSlots); } catch (ChallengeBuilderException e) { e.printStackTrace(); } diff --git a/src/main/java/com/turtlehoarder/cobblemonchallenge/util/ChallengeUtil.java b/src/main/java/com/turtlehoarder/cobblemonchallenge/util/ChallengeUtil.java index 748e3b3..ec62f2e 100644 --- a/src/main/java/com/turtlehoarder/cobblemonchallenge/util/ChallengeUtil.java +++ b/src/main/java/com/turtlehoarder/cobblemonchallenge/util/ChallengeUtil.java @@ -57,9 +57,9 @@ public static boolean isPlayerOnline(ServerPlayer player) { return player.getServer().getPlayerList().getPlayer(player.getUUID()) != null; } - public static ChallengeCommand.ChallengeRequest createChallengeRequest(ServerPlayer challengerPlayer, ServerPlayer challengedPlayer, int level, boolean preview) { + public static ChallengeCommand.ChallengeRequest createChallengeRequest(ServerPlayer challengerPlayer, ServerPlayer challengedPlayer, int minLevel, int maxLevel, int handicapP1, int handicapP2, boolean preview) { String key = UUID.randomUUID().toString().replaceAll("-", ""); - ChallengeCommand.ChallengeRequest newRequest = new ChallengeCommand.ChallengeRequest(key, challengerPlayer, challengedPlayer, level, preview, System.currentTimeMillis()); + ChallengeCommand.ChallengeRequest newRequest = new ChallengeCommand.ChallengeRequest(key, challengerPlayer, challengedPlayer, minLevel, maxLevel, handicapP1, handicapP2, preview, System.currentTimeMillis()); return newRequest; } @@ -127,4 +127,13 @@ public static BattlePokemon applyFormatTransformations(ChallengeFormat format, B } return pokemon; } + + // Method for clamping Battle Pokemon to level range, between 1-100, & applying handicap + // > the handicap applied AFTER level clamp to range + // > A players level may be outside this range after the handicap is applied + // > But, the finalized handicap will be a hard clamped to (1,100) + public static int getBattlePokemonAdjustedLevel(int actualLevel, int minLevel, int maxLevel, int handicap) { + int adjustedLevel = (actualLevel < minLevel) ? minLevel + handicap : Math.min(actualLevel, maxLevel) + handicap; + return (adjustedLevel < 1) ? 1 : Math.min(adjustedLevel, 100); + } } \ No newline at end of file