Implement potential rerolling

This commit is contained in:
Melledy
2025-12-05 23:01:37 -08:00
parent 198d3aac4f
commit b7bf1fcdeb
4 changed files with 171 additions and 18 deletions

View File

@@ -21,6 +21,7 @@ import emu.nebula.game.tower.cases.StarTowerDoorCase;
import emu.nebula.game.tower.cases.StarTowerHawkerCase; import emu.nebula.game.tower.cases.StarTowerHawkerCase;
import emu.nebula.game.tower.cases.StarTowerNpcRecoveryHPCase; import emu.nebula.game.tower.cases.StarTowerNpcRecoveryHPCase;
import emu.nebula.game.tower.cases.StarTowerPotentialCase; 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.cases.StarTowerStrengthenMachineCase;
import emu.nebula.game.tower.room.RoomType; import emu.nebula.game.tower.room.RoomType;
import emu.nebula.game.tower.room.StarTowerBaseRoom; import emu.nebula.game.tower.room.StarTowerBaseRoom;
@@ -489,18 +490,18 @@ public class StarTowerGame {
/** /**
* Creates a potential selector for a random character * Creates a potential selector for a random character
*/ */
public StarTowerBaseCase createPotentialSelector() { public StarTowerPotentialCase createPotentialSelector() {
return this.createPotentialSelector(0); return this.createPotentialSelector(0);
} }
public StarTowerBaseCase createPotentialSelector(int charId) { public StarTowerPotentialCase createPotentialSelector(int charId) {
return this.createPotentialSelector(charId, false); return this.createPotentialSelector(charId, false);
} }
/** /**
* Creates a potential selector for the specified character * 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 // Check character id
if (charId <= 0) { if (charId <= 0) {
charId = this.getRandomCharId(); charId = this.getRandomCharId();
@@ -595,10 +596,14 @@ public class StarTowerGame {
} }
// Creator potential selector case // 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 // Random potentials list
var potentials = new IntArrayList(); var potentials = new IntArrayList();
@@ -649,7 +654,7 @@ public class StarTowerGame {
} }
// Creator potential selector case // Creator potential selector case
return new StarTowerPotentialCase(this.getTeamLevel(), selector); return new StarTowerPotentialCase(this, true, selector);
} }
public void setPendingSubNotes(int amount) { public void setPendingSubNotes(int amount) {

View File

@@ -29,11 +29,14 @@ public class StarTowerModifiers {
private boolean shopDiscountTier2; private boolean shopDiscountTier2;
private boolean shopDiscountTier3; private boolean shopDiscountTier3;
// Bonus potential levels // Bonus potential level proc
private double bonusStrengthenChance = 0; private double bonusStrengthenChance = 0;
private double bonusPotentialChance = 0; private double bonusPotentialChance = 0;
private int bonusPotentialLevel = 0; private int bonusPotentialLevel = 0;
private int potentialRerollCount;
private int potentialRerollDiscount;
public StarTowerModifiers(StarTowerGame game) { public StarTowerModifiers(StarTowerGame game) {
this.game = game; this.game = game;
@@ -43,11 +46,11 @@ public class StarTowerModifiers {
this.freeStrengthen = this.hasGrowthNode(10801); this.freeStrengthen = this.hasGrowthNode(10801);
// Strengthen discount (Set Meal Agreement)
if (this.hasGrowthNode(30402)) { if (this.hasGrowthNode(30402)) {
this.strengthenDiscount += 60; this.strengthenDiscount = 60;
} } else if (this.hasGrowthNode(30102)) {
if (this.hasGrowthNode(30102)) { this.strengthenDiscount = 30;
this.strengthenDiscount += 30;
} }
// Bonus potential max level (Ocean of Souls) // Bonus potential max level (Ocean of Souls)
@@ -57,7 +60,7 @@ public class StarTowerModifiers {
this.bonusMaxPotentialLevel = 4; this.bonusMaxPotentialLevel = 4;
} }
// Shop (Monolith Premium) // Shop extra goods (Monolith Premium)
if (this.hasGrowthNode(20702)) { if (this.hasGrowthNode(20702)) {
this.shopGoodsCount = 8; this.shopGoodsCount = 8;
} else if (this.hasGrowthNode(20402)) { } else if (this.hasGrowthNode(20402)) {
@@ -84,7 +87,7 @@ public class StarTowerModifiers {
this.shopDiscountTier2 = game.getDifficulty() >= 4 && this.hasGrowthNode(20502); this.shopDiscountTier2 = game.getDifficulty() >= 4 && this.hasGrowthNode(20502);
this.shopDiscountTier3 = game.getDifficulty() >= 5 && this.hasGrowthNode(20802); 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)) { if (game.getDifficulty() >= 7 && this.hasGrowthNode(30802)) {
this.bonusStrengthenChance = 0.3; this.bonusStrengthenChance = 0.3;
} else if (game.getDifficulty() >= 6 && this.hasGrowthNode(30502)) { } else if (game.getDifficulty() >= 6 && this.hasGrowthNode(30502)) {
@@ -107,6 +110,20 @@ public class StarTowerModifiers {
this.bonusPotentialChance = 0.05; this.bonusPotentialChance = 0.05;
this.bonusMaxPotentialLevel = 1; 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) { public boolean hasGrowthNode(int nodeId) {

View File

@@ -2,6 +2,8 @@ package emu.nebula.game.tower.cases;
import java.util.List; import java.util.List;
import emu.nebula.GameConstants;
import emu.nebula.game.tower.StarTowerGame;
import emu.nebula.game.tower.StarTowerPotentialInfo; import emu.nebula.game.tower.StarTowerPotentialInfo;
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase; import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq; import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
@@ -12,10 +14,22 @@ import lombok.Getter;
@Getter @Getter
public class StarTowerPotentialCase extends StarTowerBaseCase { public class StarTowerPotentialCase extends StarTowerBaseCase {
private int teamLevel; private int teamLevel;
private int charId;
private int reroll;
private int rerollPrice;
private boolean strengthen;
private List<StarTowerPotentialInfo> potentials; private List<StarTowerPotentialInfo> potentials;
public StarTowerPotentialCase(int teamLevel, List<StarTowerPotentialInfo> potentials) { public StarTowerPotentialCase(StarTowerGame game, boolean strengthen, List<StarTowerPotentialInfo> potentials) {
this.teamLevel = teamLevel; this(game, 0, potentials);
this.strengthen = strengthen;
}
public StarTowerPotentialCase(StarTowerGame game, int charId, List<StarTowerPotentialInfo> potentials) {
this.teamLevel = game.getTeamLevel();
this.charId = charId;
this.reroll = game.getModifiers().getPotentialRerollCount();
this.rerollPrice = 100 - game.getModifiers().getPotentialRerollDiscount();
this.potentials = potentials; this.potentials = potentials;
} }
@@ -24,6 +38,18 @@ public class StarTowerPotentialCase extends StarTowerBaseCase {
return CaseType.PotentialSelect; 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) { public StarTowerPotentialInfo selectId(int index) {
if (index < 0 || index >= this.getPotentials().size()) { if (index < 0 || index >= this.getPotentials().size()) {
return null; return null;
@@ -34,9 +60,66 @@ public class StarTowerPotentialCase extends StarTowerBaseCase {
@Override @Override
public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) { public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) {
// Get selected potential // Check
var index = req.getMutableSelectReq().getIndex(); 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); var potential = this.selectId(index);
if (potential == null) { if (potential == null) {
return rsp; return rsp;
@@ -52,7 +135,7 @@ public class StarTowerPotentialCase extends StarTowerBaseCase {
var nextCases = this.getGame().handlePendingPotentialSelectors(); var nextCases = this.getGame().handlePendingPotentialSelectors();
for (var towerCase : nextCases) { for (var towerCase : nextCases) {
this.getGame().addCase(rsp.getMutableCases(), towerCase); this.getRoom().addCase(rsp.getMutableCases(), towerCase);
} }
// Complete // Complete
@@ -69,5 +152,10 @@ public class StarTowerPotentialCase extends StarTowerBaseCase {
for (var potential : this.getPotentials()) { for (var potential : this.getPotentials()) {
select.addInfos(potential.toProto()); select.addInfos(potential.toProto());
} }
if (this.canReroll()) {
select.setCanReRoll(true);
select.setReRollPrice(this.getRerollPrice());
}
} }
} }

View File

@@ -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<StarTowerPotentialInfo> 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());
}
}
}