From b495e43c07ffec586e0558bd9f051c2853945c91 Mon Sep 17 00:00:00 2001 From: Melledy <121644117+Melledy@users.noreply.github.com> Date: Mon, 16 Oct 2023 08:04:19 -0700 Subject: [PATCH] Calculate stars in challenges properly --- .../java/emu/lunarcore/data/GameData.java | 1 + .../lunarcore/data/excel/ChallengeExcel.java | 2 + .../data/excel/ChallengeTargetExcel.java | 23 ++++++++ .../emu/lunarcore/game/avatar/GameAvatar.java | 4 ++ .../game/challenge/ChallengeData.java | 55 ++++++++++++++++--- 5 files changed, 77 insertions(+), 8 deletions(-) create mode 100644 src/main/java/emu/lunarcore/data/excel/ChallengeTargetExcel.java diff --git a/src/main/java/emu/lunarcore/data/GameData.java b/src/main/java/emu/lunarcore/data/GameData.java index cbae59d..9961246 100644 --- a/src/main/java/emu/lunarcore/data/GameData.java +++ b/src/main/java/emu/lunarcore/data/GameData.java @@ -28,6 +28,7 @@ public class GameData { @Getter private static Int2ObjectMap mapEntranceExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap heroExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap challengeExcelMap = new Int2ObjectOpenHashMap<>(); + @Getter private static Int2ObjectMap challengeTargetExcelMap = new Int2ObjectOpenHashMap<>(); @Getter private static Int2ObjectMap shopExcelMap = new Int2ObjectOpenHashMap<>(); private static Int2ObjectMap avatarPromotionExcelMap = new Int2ObjectOpenHashMap<>(); diff --git a/src/main/java/emu/lunarcore/data/excel/ChallengeExcel.java b/src/main/java/emu/lunarcore/data/excel/ChallengeExcel.java index a284cfc..57ba3e7 100644 --- a/src/main/java/emu/lunarcore/data/excel/ChallengeExcel.java +++ b/src/main/java/emu/lunarcore/data/excel/ChallengeExcel.java @@ -13,6 +13,8 @@ public class ChallengeExcel extends GameResource { private int ChallengeCountDown; private int MazeBuffID; + private int[] ChallengeTargetID; + private int MazeGroupID1; private int[] ConfigList1; private int[] NpcMonsterIDList1; diff --git a/src/main/java/emu/lunarcore/data/excel/ChallengeTargetExcel.java b/src/main/java/emu/lunarcore/data/excel/ChallengeTargetExcel.java new file mode 100644 index 0000000..bc5f36a --- /dev/null +++ b/src/main/java/emu/lunarcore/data/excel/ChallengeTargetExcel.java @@ -0,0 +1,23 @@ +package emu.lunarcore.data.excel; + +import emu.lunarcore.data.GameResource; +import emu.lunarcore.data.ResourceType; +import emu.lunarcore.data.ResourceType.LoadPriority; +import lombok.Getter; + +@Getter +@ResourceType(name = {"ChallengeTargetConfig.json"}, loadPriority = LoadPriority.HIGH) +public class ChallengeTargetExcel extends GameResource { + private int ID; + private ChallengeType ChallengeTargetType; + private int ChallengeTargetParam1; + + @Override + public int getId() { + return ID; + } + + public enum ChallengeType { + None, ROUNDS, DEAD_AVATAR, KILL_MONSTER, AVATAR_BASE_TYPE_MORE, AVATAR_BASE_TYPE_LESS, ROUNDS_LEFT; + } +} diff --git a/src/main/java/emu/lunarcore/game/avatar/GameAvatar.java b/src/main/java/emu/lunarcore/game/avatar/GameAvatar.java index 0007e2d..8d74230 100644 --- a/src/main/java/emu/lunarcore/game/avatar/GameAvatar.java +++ b/src/main/java/emu/lunarcore/game/avatar/GameAvatar.java @@ -145,6 +145,10 @@ public class GameAvatar implements GameEntity { public void setCurrentSp(int amount) { this.currentSp = Math.max(Math.min(amount, getMaxSp()), 0); } + + public boolean isAlive() { + return this.getCurrentHp() <= 0; + } public int getRank() { return this.getData().getRank(); diff --git a/src/main/java/emu/lunarcore/game/challenge/ChallengeData.java b/src/main/java/emu/lunarcore/game/challenge/ChallengeData.java index df9b18c..f4d185e 100644 --- a/src/main/java/emu/lunarcore/game/challenge/ChallengeData.java +++ b/src/main/java/emu/lunarcore/game/challenge/ChallengeData.java @@ -5,6 +5,7 @@ import emu.lunarcore.data.config.GroupInfo; import emu.lunarcore.data.config.MonsterInfo; import emu.lunarcore.data.excel.ChallengeExcel; import emu.lunarcore.data.excel.NpcMonsterExcel; +import emu.lunarcore.game.avatar.GameAvatar; import emu.lunarcore.game.battle.Battle; import emu.lunarcore.game.player.Player; import emu.lunarcore.game.scene.Scene; @@ -28,11 +29,12 @@ public class ChallengeData { private final Position startPos; private final Position startRot; + private boolean hasAvatarDied; private int currentStage; private ExtraLineupType currentExtraLineup; private ChallengeStatus status; - @Setter private int roundsLimit; + @Setter private int roundsLeft; @Setter private int stars; public ChallengeData(Player player, ChallengeExcel excel) { @@ -42,7 +44,7 @@ public class ChallengeData { this.startPos = player.getPos().clone(); this.startRot = player.getRot().clone(); this.currentStage = 1; - this.roundsLimit = excel.getChallengeCountDown(); + this.roundsLeft = excel.getChallengeCountDown(); this.status = ChallengeStatus.CHALLENGE_DOING; this.currentExtraLineup = ExtraLineupType.LINEUP_CHALLENGE; @@ -107,8 +109,8 @@ public class ChallengeData { } } - private int getRoundCount() { - return getExcel().getChallengeCountDown() - this.roundsLimit; + private int getRoundsElapsed() { + return getExcel().getChallengeCountDown() - this.roundsLeft; } public boolean isWin() { @@ -116,11 +118,21 @@ public class ChallengeData { } public void onBattleStart(Battle battle) { - battle.setRoundsLimit(player.getChallengeData().getRoundsLimit()); + battle.setRoundsLimit(player.getChallengeData().getRoundsLeft()); } public void onBattleFinish(Battle battle, BattleEndStatus result, BattleStatistics stats) { if (result == BattleEndStatus.BATTLE_END_WIN) { + // Check if any avatar in the lineup has died + for (int avatarId : player.getCurrentLineup().getAvatars()) { + GameAvatar avatar = player.getAvatarById(avatarId); + if (avatar == null) continue; + + if (!avatar.isAlive()) { + this.hasAvatarDied = true; + } + } + // Get monster count in stage long monsters = player.getScene().getEntities().values().stream().filter(e -> e instanceof EntityMonster).count(); @@ -129,7 +141,7 @@ public class ChallengeData { if (this.currentStage >= excel.getStageNum()) { // Last stage this.status = ChallengeStatus.CHALLENGE_FINISH; - this.stars = 7; // TODO calculate the right amount stars + this.stars = this.calculateStars(); // Save history player.getChallengeManager().addHistory(this.getChallengeId(), this.getStars()); // Send challenge result data @@ -148,7 +160,7 @@ public class ChallengeData { } // Calculate rounds left - this.roundsLimit = Math.min(Math.max(this.roundsLimit - stats.getRoundCnt(), 0), this.roundsLimit); + this.roundsLeft = Math.min(Math.max(this.roundsLeft - stats.getRoundCnt(), 0), this.roundsLeft); } else { // Fail challenge this.status = ChallengeStatus.CHALLENGE_FAILED; @@ -162,11 +174,38 @@ public class ChallengeData { } } + public int calculateStars() { + int[] targets = getExcel().getChallengeTargetID(); + int stars = 0; + + for (int i = 0; i < targets.length; i++) { + var target = GameData.getChallengeTargetExcelMap().get(targets[i]); + if (target == null) continue; + + switch (target.getChallengeTargetType()) { + case ROUNDS_LEFT: + if (this.getRoundsLeft() >= target.getChallengeTargetParam1()) { + stars += (1 << i); + } + break; + case DEAD_AVATAR: + if (!this.hasAvatarDied) { + stars += (1 << i); + } + break; + default: + break; + } + } + + return Math.min(stars, 7); + } + public ChallengeInfo toProto() { var proto = ChallengeInfo.newInstance() .setChallengeId(this.getExcel().getId()) .setStatus(this.getStatus()) - .setRoundCount(this.getRoundCount()) + .setRoundCount(this.getRoundsElapsed()) .setExtraLineupType(this.getCurrentExtraLineup()); return proto;