diff --git a/src/main/java/emu/nebula/data/resources/InfinityTowerLevelDef.java b/src/main/java/emu/nebula/data/resources/InfinityTowerLevelDef.java index 9dda7eb..f80de18 100644 --- a/src/main/java/emu/nebula/data/resources/InfinityTowerLevelDef.java +++ b/src/main/java/emu/nebula/data/resources/InfinityTowerLevelDef.java @@ -15,6 +15,7 @@ import lombok.Getter; @ResourceType(name = "InfinityTowerLevel.json") public class InfinityTowerLevelDef extends BaseDef { private int Id; + private int DifficultyId; private String BaseAwardPreview; private transient List rewards; diff --git a/src/main/java/emu/nebula/game/infinitytower/InfinityTowerManager.java b/src/main/java/emu/nebula/game/infinitytower/InfinityTowerManager.java index bfe3b06..c931768 100644 --- a/src/main/java/emu/nebula/game/infinitytower/InfinityTowerManager.java +++ b/src/main/java/emu/nebula/game/infinitytower/InfinityTowerManager.java @@ -1,6 +1,7 @@ package emu.nebula.game.infinitytower; import emu.nebula.data.GameData; +import emu.nebula.data.resources.InfinityTowerLevelDef; import emu.nebula.game.player.Player; import emu.nebula.game.player.PlayerChangeInfo; import emu.nebula.game.player.PlayerManager; @@ -9,7 +10,9 @@ import lombok.Getter; @Getter public class InfinityTowerManager extends PlayerManager { + private InfinityTowerLevelDef levelData; private int levelId; + private long buildId; public InfinityTowerManager(Player player) { @@ -28,6 +31,7 @@ public class InfinityTowerManager extends PlayerManager { } // Set level id + this.levelData = data; this.levelId = levelId; // Set build id @@ -41,21 +45,21 @@ public class InfinityTowerManager extends PlayerManager { public PlayerChangeInfo settle(int value) { // Verify level data - var data = GameData.getInfinityTowerLevelDataTable().get(this.getLevelId()); - if (data == null) { + if (this.getLevelData() == null) { return null; } // Init change info var change = new PlayerChangeInfo(); - // TODO + // Check if the player has won or not TODO if (value != 1) { + // Player lost, so we return nothing return change; } // Calculate rewards - var rewards = data.generateRewards(); + var rewards = this.getLevelData().generateRewards(); // Add items this.getPlayer().getInventory().addItems(rewards, change); @@ -63,6 +67,9 @@ public class InfinityTowerManager extends PlayerManager { // Set in change info change.setExtraData(rewards); + // Log in player progress + this.getPlayer().getProgress().addInfinityArenaLog(this.getLevelId()); + // Success return change.setSuccess(true); } diff --git a/src/main/java/emu/nebula/game/player/Player.java b/src/main/java/emu/nebula/game/player/Player.java index afb295d..babc48b 100644 --- a/src/main/java/emu/nebula/game/player/Player.java +++ b/src/main/java/emu/nebula/game/player/Player.java @@ -37,7 +37,7 @@ import emu.nebula.proto.Public.Story; import emu.nebula.proto.Public.WorldClass; import emu.nebula.proto.Public.WorldClassRewardState; import emu.nebula.proto.Public.Title; -import emu.nebula.proto.Public.VampireSurvivorLevel; + import lombok.Getter; import us.hebi.quickbuf.ProtoMessage; import us.hebi.quickbuf.RepeatedInt; @@ -656,25 +656,6 @@ public class Player implements GameDatabaseObject { proto.addHandbook(this.getCharacters().getCharacterHandbook()); proto.addHandbook(this.getCharacters().getDiscHandbook()); - // Force unlock all monoliths - for (var towerData : GameData.getStarTowerDataTable()) { - proto.addRglPassedIds(towerData.getId()); - } - - // Force unlock all vampire survivor records - var vsProto = proto.getMutableVampireSurvivorRecord(); - - vsProto.getMutableSeason(); - - for (var vsData : GameData.getVampireSurvivorDataTable()) { - var level = VampireSurvivorLevel.newInstance() - .setId(vsData.getId()) - .setScore(0) - .setPassed(true); - - vsProto.addRecords(level); - } - // Extra proto.getMutableAgent(); proto.getMutablePhone(); diff --git a/src/main/java/emu/nebula/game/player/PlayerProgress.java b/src/main/java/emu/nebula/game/player/PlayerProgress.java index 06093c2..fc43e15 100644 --- a/src/main/java/emu/nebula/game/player/PlayerProgress.java +++ b/src/main/java/emu/nebula/game/player/PlayerProgress.java @@ -10,9 +10,12 @@ import emu.nebula.proto.Public.CharGemInstance; import emu.nebula.proto.Public.DailyInstance; import emu.nebula.proto.Public.RegionBossLevel; import emu.nebula.proto.Public.SkillInstance; +import emu.nebula.proto.Public.VampireSurvivorLevel; import emu.nebula.proto.Public.WeekBossLevel; import it.unimi.dsi.fastutil.ints.Int2IntMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; import lombok.Getter; @Getter @@ -21,11 +24,20 @@ public class PlayerProgress extends PlayerManager implements GameDatabaseObject @Id private int uid; + // Star Tower + private IntSet starTowerLog; + + // Instances private Int2IntMap dailyInstanceLog; private Int2IntMap regionBossLog; private Int2IntMap skillInstanceLog; private Int2IntMap charGemLog; private Int2IntMap weekBossLog; + + // Infinite Arena + private Int2IntMap infinityArenaLog; + + // Vampire Survivors TODO @Deprecated // Morphia only public PlayerProgress() { @@ -37,6 +49,7 @@ public class PlayerProgress extends PlayerManager implements GameDatabaseObject this.uid = player.getUid(); // Star Tower + this.starTowerLog = new IntOpenHashSet(); // Instances this.dailyInstanceLog = new Int2IntOpenHashMap(); @@ -46,6 +59,7 @@ public class PlayerProgress extends PlayerManager implements GameDatabaseObject this.weekBossLog = new Int2IntOpenHashMap(); // Infinity Arena + this.infinityArenaLog = new Int2IntOpenHashMap(); // Vampire Survivor @@ -53,6 +67,31 @@ public class PlayerProgress extends PlayerManager implements GameDatabaseObject this.save(); } + public void addStarTowerLog(int id) { + // Sanity check + if (this.getStarTowerLog().contains(id)) { + return; + } + + // Add & Save to database + this.getStarTowerLog().add(id); + Nebula.getGameDatabase().addToList(this, this.getUid(), "starTowerLog", id); + } + + public void addInfinityArenaLog(int levelId) { + // Calculate arena id + int id = (int) Math.floor(levelId / 10000D); + + // Check highest clear + int highestClearId = this.getInfinityArenaLog().get(id); + + // Add & Save to database + if (levelId > highestClearId) { + this.getInfinityArenaLog().put(id, levelId); + Nebula.getGameDatabase().update(this, this.getUid(), "infinityArenaLog." + id, levelId); + } + } + public void saveInstanceLog(Int2IntMap log, String logName, int id, int newStar) { // Get current star int star = log.get(id); @@ -70,13 +109,23 @@ public class PlayerProgress extends PlayerManager implements GameDatabaseObject // Proto public void toProto(PlayerInfo proto) { - // Init - int minStars = 0; + // Check if we want to unlock all instances + boolean unlockAll = Nebula.getConfig().getServerOptions().unlockInstances; + + // Star tower + if (unlockAll) { + // Force unlock all monoliths + for (var towerData : GameData.getStarTowerDataTable()) { + proto.addRglPassedIds(towerData.getId()); + } + } else { + for (var towerId : this.getStarTowerLog()) { + proto.addRglPassedIds(towerId); + } + } // Simple hack to unlock all instances - if (Nebula.getConfig().getServerOptions().unlockInstances) { - minStars = 1; - } + int minStars = unlockAll ? 1 : 0; // Daily instance for (var data : GameData.getDailyInstanceDataTable()) { @@ -130,5 +179,19 @@ public class PlayerProgress extends PlayerManager implements GameDatabaseObject proto.addWeekBossLevels(p); } + + // Force unlock all vampire survivor records + var vsProto = proto.getMutableVampireSurvivorRecord(); + + vsProto.getMutableSeason(); + + for (var vsData : GameData.getVampireSurvivorDataTable()) { + var level = VampireSurvivorLevel.newInstance() + .setId(vsData.getId()) + .setScore(0) + .setPassed(true); + + vsProto.addRecords(level); + } } } diff --git a/src/main/java/emu/nebula/game/tower/StarTowerGame.java b/src/main/java/emu/nebula/game/tower/StarTowerGame.java index 7d2bd75..e9a9f65 100644 --- a/src/main/java/emu/nebula/game/tower/StarTowerGame.java +++ b/src/main/java/emu/nebula/game/tower/StarTowerGame.java @@ -630,6 +630,9 @@ public class StarTowerGame { // Mark change info settle.getMutableChange(); + // Log victory + this.getManager().getPlayer().getProgress().addStarTowerLog(this.getId()); + // Complete return rsp; } diff --git a/src/main/java/emu/nebula/server/handlers/HandlerInfinityTowerInfoReq.java b/src/main/java/emu/nebula/server/handlers/HandlerInfinityTowerInfoReq.java index 2d4f3f6..1699ea1 100644 --- a/src/main/java/emu/nebula/server/handlers/HandlerInfinityTowerInfoReq.java +++ b/src/main/java/emu/nebula/server/handlers/HandlerInfinityTowerInfoReq.java @@ -3,9 +3,14 @@ package emu.nebula.server.handlers; import emu.nebula.net.NetHandler; import emu.nebula.net.NetMsgId; import emu.nebula.proto.InfinityTowerInfo.InfinityTowerInfoResp; +import emu.nebula.proto.Public.InfinityTowerLevelInfo; import emu.nebula.net.HandlerId; +import emu.nebula.Nebula; +import emu.nebula.data.GameData; import emu.nebula.net.GameSession; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + @HandlerId(NetMsgId.infinity_tower_info_req) public class HandlerInfinityTowerInfoReq extends NetHandler { @@ -15,6 +20,38 @@ public class HandlerInfinityTowerInfoReq extends NetHandler { var rsp = InfinityTowerInfoResp.newInstance() .setBountyLevel(0); + // Add unlocked levels + if (Nebula.getConfig().getServerOptions().unlockInstances) { + // Force unlock every level + var levels = new Int2ObjectOpenHashMap(); + + for (var data : GameData.getInfinityTowerLevelDataTable()) { + int id = (int) Math.floor(data.getId() / 10000D); + + var info = levels.computeIfAbsent( + id, + diff -> InfinityTowerLevelInfo.newInstance().setId(id) + ); + + if (data.getId() > info.getLevelId()) { + info.setLevelId(data.getId()); + } + } + + for (var info : levels.values()) { + rsp.addInfos(info); + } + } else { + // Get infinite arena log from player progress + for (var entry : session.getPlayer().getProgress().getInfinityArenaLog().int2IntEntrySet()) { + var info = InfinityTowerLevelInfo.newInstance() + .setId(entry.getIntKey()) + .setLevelId(entry.getIntValue()); + + rsp.addInfos(info); + } + } + // Encode and send return session.encodeMsg(NetMsgId.infinity_tower_info_succeed_ack, rsp); }