From b7bf1fcdeb99594f5f7bb46b238b50ddab6c04e6 Mon Sep 17 00:00:00 2001 From: Melledy <121644117+Melledy@users.noreply.github.com> Date: Fri, 5 Dec 2025 23:01:37 -0800 Subject: [PATCH] Implement potential rerolling --- .../emu/nebula/game/tower/StarTowerGame.java | 17 ++-- .../nebula/game/tower/StarTowerModifiers.java | 31 ++++-- .../tower/cases/StarTowerPotentialCase.java | 98 ++++++++++++++++++- .../StarTowerSelectSpecialPotentialCase.java | 43 ++++++++ 4 files changed, 171 insertions(+), 18 deletions(-) create mode 100644 src/main/java/emu/nebula/game/tower/cases/StarTowerSelectSpecialPotentialCase.java diff --git a/src/main/java/emu/nebula/game/tower/StarTowerGame.java b/src/main/java/emu/nebula/game/tower/StarTowerGame.java index b2c6f21..f518942 100644 --- a/src/main/java/emu/nebula/game/tower/StarTowerGame.java +++ b/src/main/java/emu/nebula/game/tower/StarTowerGame.java @@ -21,6 +21,7 @@ import emu.nebula.game.tower.cases.StarTowerDoorCase; import emu.nebula.game.tower.cases.StarTowerHawkerCase; import emu.nebula.game.tower.cases.StarTowerNpcRecoveryHPCase; import emu.nebula.game.tower.cases.StarTowerPotentialCase; +import emu.nebula.game.tower.cases.StarTowerSelectSpecialPotentialCase; import emu.nebula.game.tower.cases.StarTowerStrengthenMachineCase; import emu.nebula.game.tower.room.RoomType; import emu.nebula.game.tower.room.StarTowerBaseRoom; @@ -489,18 +490,18 @@ public class StarTowerGame { /** * Creates a potential selector for a random character */ - public StarTowerBaseCase createPotentialSelector() { + public StarTowerPotentialCase createPotentialSelector() { return this.createPotentialSelector(0); } - public StarTowerBaseCase createPotentialSelector(int charId) { + public StarTowerPotentialCase createPotentialSelector(int charId) { return this.createPotentialSelector(charId, false); } /** * Creates a potential selector for the specified character */ - public StarTowerBaseCase createPotentialSelector(int charId, boolean rareOnly) { + public StarTowerPotentialCase createPotentialSelector(int charId, boolean rareOnly) { // Check character id if (charId <= 0) { charId = this.getRandomCharId(); @@ -595,10 +596,14 @@ public class StarTowerGame { } // Creator potential selector case - return new StarTowerPotentialCase(this.getTeamLevel(), selector); + if (rareOnly) { + return new StarTowerSelectSpecialPotentialCase(this, charId, selector); + } else { + return new StarTowerPotentialCase(this, charId, selector); + } } - public StarTowerBaseCase createStrengthenSelector() { + public StarTowerPotentialCase createStrengthenSelector() { // Random potentials list var potentials = new IntArrayList(); @@ -649,7 +654,7 @@ public class StarTowerGame { } // Creator potential selector case - return new StarTowerPotentialCase(this.getTeamLevel(), selector); + return new StarTowerPotentialCase(this, true, selector); } public void setPendingSubNotes(int amount) { diff --git a/src/main/java/emu/nebula/game/tower/StarTowerModifiers.java b/src/main/java/emu/nebula/game/tower/StarTowerModifiers.java index 4c5ab2c..8acec5c 100644 --- a/src/main/java/emu/nebula/game/tower/StarTowerModifiers.java +++ b/src/main/java/emu/nebula/game/tower/StarTowerModifiers.java @@ -29,11 +29,14 @@ public class StarTowerModifiers { private boolean shopDiscountTier2; private boolean shopDiscountTier3; - // Bonus potential levels + // Bonus potential level proc private double bonusStrengthenChance = 0; private double bonusPotentialChance = 0; private int bonusPotentialLevel = 0; + private int potentialRerollCount; + private int potentialRerollDiscount; + public StarTowerModifiers(StarTowerGame game) { this.game = game; @@ -43,11 +46,11 @@ public class StarTowerModifiers { this.freeStrengthen = this.hasGrowthNode(10801); + // Strengthen discount (Set Meal Agreement) if (this.hasGrowthNode(30402)) { - this.strengthenDiscount += 60; - } - if (this.hasGrowthNode(30102)) { - this.strengthenDiscount += 30; + this.strengthenDiscount = 60; + } else if (this.hasGrowthNode(30102)) { + this.strengthenDiscount = 30; } // Bonus potential max level (Ocean of Souls) @@ -57,7 +60,7 @@ public class StarTowerModifiers { this.bonusMaxPotentialLevel = 4; } - // Shop (Monolith Premium) + // Shop extra goods (Monolith Premium) if (this.hasGrowthNode(20702)) { this.shopGoodsCount = 8; } else if (this.hasGrowthNode(20402)) { @@ -84,7 +87,7 @@ public class StarTowerModifiers { this.shopDiscountTier2 = game.getDifficulty() >= 4 && this.hasGrowthNode(20502); this.shopDiscountTier3 = game.getDifficulty() >= 5 && this.hasGrowthNode(20802); - // Bonus potential levels (Potential Boost) + // Bonus potential enhancement level procs (Potential Boost) if (game.getDifficulty() >= 7 && this.hasGrowthNode(30802)) { this.bonusStrengthenChance = 0.3; } else if (game.getDifficulty() >= 6 && this.hasGrowthNode(30502)) { @@ -107,6 +110,20 @@ public class StarTowerModifiers { this.bonusPotentialChance = 0.05; this.bonusMaxPotentialLevel = 1; } + + // Potential reroll (Cloud Dice) + if (this.hasGrowthNode(20901)) { + this.potentialRerollCount += 1; + } + + // Potential reroll price discount (Destiny of Stars) + if (this.hasGrowthNode(30702)) { + this.potentialRerollDiscount = 60; + } else if (this.hasGrowthNode(30401)) { + this.potentialRerollDiscount = 40; + } else if (this.hasGrowthNode(30101)) { + this.potentialRerollDiscount = 30; + } } public boolean hasGrowthNode(int nodeId) { 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 21251eb..e5dadc6 100644 --- a/src/main/java/emu/nebula/game/tower/cases/StarTowerPotentialCase.java +++ b/src/main/java/emu/nebula/game/tower/cases/StarTowerPotentialCase.java @@ -2,6 +2,8 @@ package emu.nebula.game.tower.cases; import java.util.List; +import emu.nebula.GameConstants; +import emu.nebula.game.tower.StarTowerGame; import emu.nebula.game.tower.StarTowerPotentialInfo; import emu.nebula.proto.PublicStarTower.StarTowerRoomCase; import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq; @@ -12,10 +14,22 @@ import lombok.Getter; @Getter public class StarTowerPotentialCase extends StarTowerBaseCase { private int teamLevel; + private int charId; + private int reroll; + private int rerollPrice; + private boolean strengthen; private List potentials; - public StarTowerPotentialCase(int teamLevel, List potentials) { - this.teamLevel = teamLevel; + public StarTowerPotentialCase(StarTowerGame game, boolean strengthen, List potentials) { + this(game, 0, potentials); + this.strengthen = strengthen; + } + + public StarTowerPotentialCase(StarTowerGame game, int charId, List potentials) { + this.teamLevel = game.getTeamLevel(); + this.charId = charId; + this.reroll = game.getModifiers().getPotentialRerollCount(); + this.rerollPrice = 100 - game.getModifiers().getPotentialRerollDiscount(); this.potentials = potentials; } @@ -24,6 +38,18 @@ public class StarTowerPotentialCase extends StarTowerBaseCase { return CaseType.PotentialSelect; } + public boolean isRare() { + return false; + } + + public void setReroll(int count) { + this.reroll = count; + } + + public boolean canReroll() { + return this.reroll > 0; + } + public StarTowerPotentialInfo selectId(int index) { if (index < 0 || index >= this.getPotentials().size()) { return null; @@ -34,9 +60,66 @@ public class StarTowerPotentialCase extends StarTowerBaseCase { @Override public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) { - // Get selected potential - var index = req.getMutableSelectReq().getIndex(); + // Check + var select = req.getMutableSelectReq(); + if (select.hasReRoll()) { + return this.reroll(rsp); + } else { + return this.select(select.getIndex(), rsp); + } + } + + private StarTowerInteractResp reroll(StarTowerInteractResp rsp) { + // Check if we can reroll + if (!this.canReroll()) { + return rsp; + } + + // Check price + int coin = this.getGame().getResCount(GameConstants.TOWER_COIN_ITEM_ID); + int price = this.getRerollPrice(); + + if (coin < price) { + return rsp; + } + + // Subtract rerolls + int newReroll = this.reroll - 1; + + // Create reroll case + StarTowerPotentialCase rerollCase = null; + + if (this.isStrengthen()) { + rerollCase = this.getGame().createStrengthenSelector(); + } else { + rerollCase = this.getGame().createPotentialSelector(this.getCharId(), this.isRare()); + } + + if (rerollCase == null) { + return rsp; + } + + // Clear reroll count + rerollCase.setReroll(newReroll); + + // Add reroll case + this.getRoom().addCase(rsp.getMutableCases(), rerollCase); + + // Finish subtracting rerolls + this.reroll = newReroll; + + // Subtract coins + var change = this.getGame().addItem(GameConstants.TOWER_COIN_ITEM_ID, -price); + + rsp.setChange(change.toProto()); + + // Complete + return rsp; + } + + private StarTowerInteractResp select(int index, StarTowerInteractResp rsp) { + // Get selected potential var potential = this.selectId(index); if (potential == null) { return rsp; @@ -52,7 +135,7 @@ public class StarTowerPotentialCase extends StarTowerBaseCase { var nextCases = this.getGame().handlePendingPotentialSelectors(); for (var towerCase : nextCases) { - this.getGame().addCase(rsp.getMutableCases(), towerCase); + this.getRoom().addCase(rsp.getMutableCases(), towerCase); } // Complete @@ -69,5 +152,10 @@ public class StarTowerPotentialCase extends StarTowerBaseCase { for (var potential : this.getPotentials()) { select.addInfos(potential.toProto()); } + + if (this.canReroll()) { + select.setCanReRoll(true); + select.setReRollPrice(this.getRerollPrice()); + } } } diff --git a/src/main/java/emu/nebula/game/tower/cases/StarTowerSelectSpecialPotentialCase.java b/src/main/java/emu/nebula/game/tower/cases/StarTowerSelectSpecialPotentialCase.java new file mode 100644 index 0000000..4775c5c --- /dev/null +++ b/src/main/java/emu/nebula/game/tower/cases/StarTowerSelectSpecialPotentialCase.java @@ -0,0 +1,43 @@ +package emu.nebula.game.tower.cases; + +import java.util.List; + +import emu.nebula.game.tower.StarTowerGame; +import emu.nebula.game.tower.StarTowerPotentialInfo; +import emu.nebula.proto.PublicStarTower.StarTowerRoomCase; + +import lombok.Getter; + +@Getter +public class StarTowerSelectSpecialPotentialCase extends StarTowerPotentialCase { + + public StarTowerSelectSpecialPotentialCase(StarTowerGame game, int charId, List potentials) { + super(game, charId, potentials); + } + + @Override + public CaseType getType() { + return CaseType.SelectSpecialPotential; + } + + public boolean isRare() { + return true; + } + + // Proto + + @Override + public void encodeProto(StarTowerRoomCase proto) { + var select = proto.getMutableSelectSpecialPotentialCase() + .setTeamLevel(this.getTeamLevel()); + + for (var potential : this.getPotentials()) { + select.addIds(potential.getId()); + } + + if (this.canReroll()) { + select.setCanReRoll(true); + select.setReRollPrice(this.getRerollPrice()); + } + } +}