From dfb93cae4bd62526bc45de482c65aa27dfc75284 Mon Sep 17 00:00:00 2001 From: Melledy <121644117+Melledy@users.noreply.github.com> Date: Sat, 6 Dec 2025 02:01:57 -0800 Subject: [PATCH] Implement some tower achievements --- .../game/achievement/AchievementHelper.java | 62 ++++++++++++++----- .../game/achievement/AchievementManager.java | 8 +++ .../emu/nebula/game/tower/StarTowerGame.java | 52 ++++++++++++++++ .../game/tower/cases/StarTowerHawkerCase.java | 7 +++ .../tower/cases/StarTowerNpcEventCase.java | 6 ++ .../tower/cases/StarTowerPotentialCase.java | 29 ++++----- .../cases/StarTowerStrengthenMachineCase.java | 4 ++ 7 files changed, 140 insertions(+), 28 deletions(-) diff --git a/src/main/java/emu/nebula/game/achievement/AchievementHelper.java b/src/main/java/emu/nebula/game/achievement/AchievementHelper.java index d1dc38e..522db4f 100644 --- a/src/main/java/emu/nebula/game/achievement/AchievementHelper.java +++ b/src/main/java/emu/nebula/game/achievement/AchievementHelper.java @@ -5,6 +5,7 @@ import java.util.List; import emu.nebula.GameConstants; import emu.nebula.data.GameData; import emu.nebula.data.resources.AchievementDef; +import emu.nebula.game.tower.room.RoomType; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; @@ -34,7 +35,7 @@ public class AchievementHelper { public static void init() { // Cache total achievements for (var condition : AchievementCondition.values()) { - if (condition.name().endsWith("Total")) { + if (condition.name().endsWith("Total") || condition.name().endsWith("Times")) { incrementalAchievementSet.add(condition.getValue()); } } @@ -44,12 +45,15 @@ public class AchievementHelper { incrementalAchievementSet.add(AchievementCondition.ItemsAdd.getValue()); incrementalAchievementSet.add(AchievementCondition.ItemsDeplete.getValue()); + incrementalAchievementSet.add(AchievementCondition.TowerItemsGet.getValue()); + incrementalAchievementSet.add(AchievementCondition.TowerEnterRoom.getValue()); + // Fix params fixParams(); } private static void fixParams() { - // Monolith + // Star Tower TODO addParam(78, 0, 2); addParam(79, 0, 4); addParam(498, 0, 1); @@ -73,20 +77,44 @@ public class AchievementHelper { } // Character count - addParam(393, 1, 0); - addParam(394, 1, 0); - addParam(395, 1, 0); - addParam(396, 1, 0); - addParam(397, 1, 0); - addParam(398, 1, 0); + addParams(393, 398, 1, 0); // Disc count - addParam(382, 1, 0); - addParam(383, 1, 0); - addParam(384, 1, 0); - addParam(385, 1, 0); - addParam(386, 1, 0); - addParam(387, 1, 0); + addParams(382, 387, 1, 0); + + // Star Tower team clear + addParams(95, 98, 1, 0); // Aqua team clear + addParams(99, 102, 2, 0); // Fire team clear + addParams(103, 106, 3, 0); // Earth team clear + addParams(107, 110, 4, 0); // Wind team clear + addParams(111, 114, 5, 0); // Light team clear + addParams(115, 118, 6, 0); // Dark team clear + + // Star tower items + addParams(139, 144, GameConstants.TOWER_COIN_ITEM_ID, 0); + + addParams(145, 149, 90011, 0); + addParams(150, 154, 90012, 0); + addParams(155, 159, 90013, 0); + addParams(160, 164, 90014, 0); + addParams(165, 169, 90015, 0); + addParams(170, 174, 90016, 0); + addParams(175, 179, 90017, 0); + + addParams(180, 184, 90018, 0); + addParams(185, 189, 90019, 0); + addParams(190, 194, 90020, 0); + addParams(195, 199, 90021, 0); + addParams(200, 204, 90022, 0); + addParams(205, 209, 90023, 0); + + // Star tower rooms + addParams(210, 216, RoomType.BattleRoom.getValue() + 1, 0); + addParams(217, 223, RoomType.EliteBattleRoom.getValue() + 1, 0); + addParams(224, 230, RoomType.BossRoom.getValue() + 1, 0); + addParams(231, 237, RoomType.FinalBossRoom.getValue() + 1, 0); + addParams(238, 244, RoomType.ShopRoom.getValue() + 1, 0); + addParams(245, 251, RoomType.EventRoom.getValue() + 1, 0); } private static void addParam(int achievementId, int param1, int param2) { @@ -95,4 +123,10 @@ public class AchievementHelper { data.setParams(param1, param2); } + + private static void addParams(int start, int end, int param1, int param2) { + for (int id = start; id <= end; id++) { + addParam(id, param1, param2); + } + } } diff --git a/src/main/java/emu/nebula/game/achievement/AchievementManager.java b/src/main/java/emu/nebula/game/achievement/AchievementManager.java index f49f3ae..cda3f7e 100644 --- a/src/main/java/emu/nebula/game/achievement/AchievementManager.java +++ b/src/main/java/emu/nebula/game/achievement/AchievementManager.java @@ -138,6 +138,14 @@ public class AchievementManager extends PlayerManager implements GameDatabaseObj } } + public synchronized void trigger(AchievementCondition condition, int progress) { + this.trigger(condition.getValue(), progress, 0, 0); + } + + public synchronized void trigger(AchievementCondition condition, int progress, int param1, int param2) { + this.trigger(condition.getValue(), progress, param1, param2); + } + public synchronized void trigger(int condition, int progress, int param1, int param2) { // Sanity check if (progress <= 0) { diff --git a/src/main/java/emu/nebula/game/tower/StarTowerGame.java b/src/main/java/emu/nebula/game/tower/StarTowerGame.java index 049db47..77322f0 100644 --- a/src/main/java/emu/nebula/game/tower/StarTowerGame.java +++ b/src/main/java/emu/nebula/game/tower/StarTowerGame.java @@ -10,6 +10,9 @@ import emu.nebula.data.GameData; import emu.nebula.data.resources.SecondarySkillDef; import emu.nebula.data.resources.StarTowerDef; import emu.nebula.data.resources.StarTowerStageDef; +import emu.nebula.game.achievement.AchievementCondition; +import emu.nebula.game.achievement.AchievementManager; +import emu.nebula.game.character.ElementType; import emu.nebula.game.character.GameCharacter; import emu.nebula.game.character.GameDisc; import emu.nebula.game.formation.Formation; @@ -187,6 +190,10 @@ public class StarTowerGame { return this.manager.getPlayer(); } + public AchievementManager getAchievementManager() { + return this.getPlayer().getAchievementManager(); + } + public StarTowerBuild getBuild() { if (this.build == null) { this.build = new StarTowerBuild(this); @@ -199,6 +206,31 @@ public class StarTowerGame { return this.getData().getDifficulty(); } + /** + * Gets the team element, if the team has 2+ or more elements, then returns null + */ + public ElementType getTeamElement() { + ElementType type = null; + + for (int id : this.getCharIds()) { + var character = this.getPlayer().getCharacters().getCharacterById(id); + if (character == null) { + return null; + } + + if (type == null) { + type = character.getData().getElementType(); + continue; + } + + if (type != character.getData().getElementType()) { + return null; + } + } + + return type; + } + public GameCharacter getCharByIndex(int index) { if (index < 0 || index >= this.getCharIds().length) { return null; @@ -277,6 +309,9 @@ public class StarTowerGame { this.room = new StarTowerBaseRoom(this, stage); } + // Trigger achievement + this.getAchievementManager().trigger(AchievementCondition.TowerEnterRoom, 1, stage.getRoomType() + 1, 0); + // Create cases for the room this.room.onEnter(); } @@ -409,6 +444,11 @@ public class StarTowerGame { // Add to new infos this.getNewInfos().add(id, count); + + // Achievment + if (count > 0) { + this.getAchievementManager().trigger(AchievementCondition.TowerItemsGet, count, id, 0); + } } case Res -> { // Sanity check to make sure we dont remove more than what we have @@ -425,6 +465,11 @@ public class StarTowerGame { .setQty(count); change.add(info); + + // Achievment + if (count > 0) { + this.getAchievementManager().trigger(AchievementCondition.TowerItemsGet, count, id, 0); + } } default -> { // Ignored @@ -775,7 +820,14 @@ public class StarTowerGame { // Log victory if (isWin) { + // Add star tower history this.getManager().getPlayer().getProgress().addStarTowerLog(this.getId()); + + // Trigger achievement + var elementType = this.getTeamElement(); + if (elementType != null) { + this.getAchievementManager().trigger(AchievementCondition.TowerClearSpecificCharacterTypeWithTotal, 1, elementType.getValue(), 0); + } } // Complete diff --git a/src/main/java/emu/nebula/game/tower/cases/StarTowerHawkerCase.java b/src/main/java/emu/nebula/game/tower/cases/StarTowerHawkerCase.java index fef6137..9e7eb15 100644 --- a/src/main/java/emu/nebula/game/tower/cases/StarTowerHawkerCase.java +++ b/src/main/java/emu/nebula/game/tower/cases/StarTowerHawkerCase.java @@ -5,6 +5,7 @@ import java.util.Map; import java.util.stream.Collectors; import emu.nebula.GameConstants; +import emu.nebula.game.achievement.AchievementCondition; import emu.nebula.game.player.PlayerChangeInfo; import emu.nebula.game.tower.StarTowerShopGoods; import emu.nebula.proto.PublicStarTower.HawkerCaseData; @@ -169,6 +170,9 @@ public class StarTowerHawkerCase extends StarTowerBaseCase { // Set change info rsp.setChange(change.toProto()); + + // Achievement + this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificShopReRollTotal, 1); } private void buy(int sid, StarTowerInteractResp rsp) { @@ -205,6 +209,9 @@ public class StarTowerHawkerCase extends StarTowerBaseCase { // Remove coins this.getGame().addItem(GameConstants.TOWER_COIN_ITEM_ID, -price, change); + // Achievement + this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificDifficultyShopBuyTimes, 1); + // Set change info rsp.setChange(change.toProto()); } diff --git a/src/main/java/emu/nebula/game/tower/cases/StarTowerNpcEventCase.java b/src/main/java/emu/nebula/game/tower/cases/StarTowerNpcEventCase.java index 7099a34..d8a35ba 100644 --- a/src/main/java/emu/nebula/game/tower/cases/StarTowerNpcEventCase.java +++ b/src/main/java/emu/nebula/game/tower/cases/StarTowerNpcEventCase.java @@ -4,6 +4,7 @@ import java.util.Collections; import emu.nebula.GameConstants; import emu.nebula.data.resources.StarTowerEventDef; +import emu.nebula.game.achievement.AchievementCondition; import emu.nebula.game.player.PlayerChangeInfo; import emu.nebula.proto.PublicStarTower.NPCAffinityInfo; import emu.nebula.proto.PublicStarTower.StarTowerRoomCase; @@ -254,6 +255,11 @@ public class StarTowerNpcEventCase extends StarTowerBaseCase { success.setOptionsResult(completed); this.completed = completed; + // Achievment + if (completed) { + this.getGame().getAchievementManager().trigger(AchievementCondition.TowerEventTimes, 1); + } + // Complete return rsp; } diff --git a/src/main/java/emu/nebula/game/tower/cases/StarTowerPotentialCase.java b/src/main/java/emu/nebula/game/tower/cases/StarTowerPotentialCase.java index e5dadc6..f70e1e9 100644 --- a/src/main/java/emu/nebula/game/tower/cases/StarTowerPotentialCase.java +++ b/src/main/java/emu/nebula/game/tower/cases/StarTowerPotentialCase.java @@ -3,6 +3,7 @@ package emu.nebula.game.tower.cases; import java.util.List; import emu.nebula.GameConstants; +import emu.nebula.game.achievement.AchievementCondition; import emu.nebula.game.tower.StarTowerGame; import emu.nebula.game.tower.StarTowerPotentialInfo; import emu.nebula.proto.PublicStarTower.StarTowerRoomCase; @@ -60,20 +61,23 @@ public class StarTowerPotentialCase extends StarTowerBaseCase { @Override public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) { - // Check + // Get select req var select = req.getMutableSelectReq(); + // Handle select option if (select.hasReRoll()) { - return this.reroll(rsp); + this.reroll(rsp); } else { - return this.select(select.getIndex(), rsp); + this.select(select.getIndex(), rsp); } + + return rsp; } - private StarTowerInteractResp reroll(StarTowerInteractResp rsp) { + private void reroll(StarTowerInteractResp rsp) { // Check if we can reroll if (!this.canReroll()) { - return rsp; + return; } // Check price @@ -81,7 +85,7 @@ public class StarTowerPotentialCase extends StarTowerBaseCase { int price = this.getRerollPrice(); if (coin < price) { - return rsp; + return; } // Subtract rerolls @@ -97,7 +101,7 @@ public class StarTowerPotentialCase extends StarTowerBaseCase { } if (rerollCase == null) { - return rsp; + return; } // Clear reroll count @@ -114,15 +118,15 @@ public class StarTowerPotentialCase extends StarTowerBaseCase { rsp.setChange(change.toProto()); - // Complete - return rsp; + // Achievement + this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificPotentialReRollTotal, 1); } - private StarTowerInteractResp select(int index, StarTowerInteractResp rsp) { + private void select(int index, StarTowerInteractResp rsp) { // Get selected potential var potential = this.selectId(index); if (potential == null) { - return rsp; + return; } // Add potential @@ -137,9 +141,6 @@ public class StarTowerPotentialCase extends StarTowerBaseCase { for (var towerCase : nextCases) { this.getRoom().addCase(rsp.getMutableCases(), towerCase); } - - // Complete - return rsp; } // Proto diff --git a/src/main/java/emu/nebula/game/tower/cases/StarTowerStrengthenMachineCase.java b/src/main/java/emu/nebula/game/tower/cases/StarTowerStrengthenMachineCase.java index ad7095b..7ea3c50 100644 --- a/src/main/java/emu/nebula/game/tower/cases/StarTowerStrengthenMachineCase.java +++ b/src/main/java/emu/nebula/game/tower/cases/StarTowerStrengthenMachineCase.java @@ -1,6 +1,7 @@ package emu.nebula.game.tower.cases; import emu.nebula.GameConstants; +import emu.nebula.game.achievement.AchievementCondition; import emu.nebula.proto.PublicStarTower.StarTowerRoomCase; import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq; import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp; @@ -69,6 +70,9 @@ public class StarTowerStrengthenMachineCase extends StarTowerBaseCase { // Increment price this.increasePrice(); + + // Achievement + this.getGame().getAchievementManager().trigger(AchievementCondition.TowerSpecificDifficultyStrengthenMachineTotal, 1); } // Set success result