Implement monolith enhancement machines

This commit is contained in:
Melledy
2025-12-03 19:36:47 -08:00
parent 7ef7490c37
commit ef8846445c
13 changed files with 280 additions and 41 deletions

View File

@@ -34,7 +34,7 @@ public class GameConstants {
public static final int GEM_ITEM_ID = 2;
public static final int PREM_GEM_ITEM_ID = 3;
public static final int ENERGY_BUY_ITEM_ID = GEM_ITEM_ID;
public static final int STAR_TOWER_GOLD_ITEM_ID = 11;
public static final int STAR_TOWER_COIN_ITEM_ID = 11;
public static final int EXP_ITEM_ID = 21;
public static final int MAX_ENERGY = 240;

View File

@@ -19,6 +19,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.StarTowerStrengthenMachineCase;
import emu.nebula.game.tower.room.RoomType;
import emu.nebula.game.tower.room.StarTowerBaseRoom;
import emu.nebula.game.tower.room.StarTowerBattleRoom;
@@ -78,6 +79,9 @@ public class StarTowerGame {
// Sub note skill drop list
private IntList subNoteDropList;
// Modifiers
private StarTowerModifiers modifiers;
// Cached build
private transient StarTowerBuild build;
private transient ItemParamMap newInfos;
@@ -122,6 +126,9 @@ public class StarTowerGame {
// Melody skill drop list
this.subNoteDropList = new IntArrayList();
// Init modifiers
this.modifiers = new StarTowerModifiers(this);
// Init formation
for (int i = 0; i < 3; i++) {
int id = formation.getCharIdAt(i);
@@ -167,10 +174,10 @@ public class StarTowerGame {
this.subNoteDropList.add(id);
}
// Starting gold
int money = this.getStartingGold();
if (money > 0) {
this.getRes().add(GameConstants.STAR_TOWER_GOLD_ITEM_ID, money);
// Add starting coin directly
int coin = this.getModifiers().getStartingCoin();
if (coin > 0) {
this.getRes().add(GameConstants.STAR_TOWER_COIN_ITEM_ID, coin);
}
}
@@ -186,6 +193,10 @@ public class StarTowerGame {
return this.build;
}
public int getDifficulty() {
return this.getData().getDifficulty();
}
public int getRandomCharId() {
return Utils.randomElement(this.getCharIds());
}
@@ -250,20 +261,6 @@ public class StarTowerGame {
this.room.onEnter();
}
public int getStartingGold() {
int gold = 0;
if (this.getManager().hasGrowthNode(10103)) {
gold += 50;
} if (this.getManager().hasGrowthNode(10403)) {
gold += 100;
} if (this.getManager().hasGrowthNode(10702)) {
gold += 200;
}
return gold;
}
public void addExp(int amount) {
this.teamExp += amount;
}
@@ -322,12 +319,25 @@ public class StarTowerGame {
return this.getItems().get(id);
}
public int getResCount(int id) {
return this.getRes().get(id);
}
public PlayerChangeInfo addItem(int id, int count) {
return this.addItem(id, count, null);
}
public PlayerChangeInfo addItem(int id, int count, PlayerChangeInfo change) {
// Create changes if null
if (change == null) {
change = new PlayerChangeInfo();
}
// Sanity check
if (count == 0) {
return change;
}
// Get item data
var itemData = GameData.getItemDataTable().get(id);
if (itemData == null) {
@@ -431,6 +441,10 @@ public class StarTowerGame {
if (this.isOnFinalFloor()) {
// Create hawker case (shop)
cases.add(new StarTowerHawkerCase(this));
// Create strengthen machine
if (this.getModifiers().isEnableEndStrengthen()) {
cases.add(new StarTowerStrengthenMachineCase());
}
} else if (this.getRoom() instanceof StarTowerBattleRoom) {
// Create recovery npc
cases.add(new StarTowerNpcRecoveryHPCase());
@@ -503,6 +517,55 @@ public class StarTowerGame {
return new StarTowerPotentialCase(this.getTeamLevel(), selector);
}
public StarTowerBaseCase createStrengthenSelector() {
// Random potentials list
var potentials = new IntArrayList();
// Get upgradable potentials
for (var item : this.getPotentials()) {
// Get potential data
var potential = GameData.getPotentialDataTable().get(item.getIntKey());
if (potential == null) continue;
// Check max level
int level = item.getIntValue();
if (level >= potential.getMaxLevel()) {
continue;
}
// Add
potentials.add(potential.getId());
}
// Get up to 3 random potentials
IntList selector = new IntArrayList();
for (int i = 0; i < 3; i++) {
// Sanity check
if (potentials.isEmpty()) {
break;
}
// Get random potential id
int index = ThreadLocalRandom.current().nextInt(0, potentials.size());
int potentialId = potentials.getInt(index);
// Add to selector
selector.add(potentialId);
// Remove potential id from the selector
potentials.removeInt(index);
}
// Sanity check
if (selector.isEmpty()) {
return null;
}
// Creator potential selector case
return new StarTowerPotentialCase(this.getTeamLevel(), selector);
}
public void setPendingSubNotes(int amount) {
this.pendingSubNotes = amount;
}

View File

@@ -0,0 +1,56 @@
package emu.nebula.game.tower;
import lombok.Getter;
/**
* Data class to hold various modifiers for star tower.
*/
@Getter
public class StarTowerModifiers {
private StarTowerGame game;
// Strengthen machines
private boolean enableEndStrengthen;
private boolean enableShopStrengthen;
private boolean freeStrengthen;
private int strengthenDiscount;
public StarTowerModifiers(StarTowerGame game) {
this.game = game;
// Strengthen machines
this.enableEndStrengthen = this.hasGrowthNode(10601) && game.getDifficulty() >= 2;
this.enableShopStrengthen = this.hasGrowthNode(20301) && game.getDifficulty() >= 4;
this.freeStrengthen = this.hasGrowthNode(10801);
if (this.hasGrowthNode(30402)) {
this.strengthenDiscount += 60;
} else if (this.hasGrowthNode(30102)) {
this.strengthenDiscount += 30;
}
}
public boolean hasGrowthNode(int nodeId) {
return this.getGame().getManager().hasGrowthNode(nodeId);
}
public int getStartingCoin() {
int gold = 0;
if (this.hasGrowthNode(10103)) {
gold += 50;
} if (this.hasGrowthNode(10403)) {
gold += 100;
} if (this.hasGrowthNode(10702)) {
gold += 200;
}
return gold;
}
public void setFreeStrengthen(boolean b) {
this.freeStrengthen = b;
}
}

View File

@@ -1,6 +1,7 @@
package emu.nebula.game.tower.cases;
import emu.nebula.game.tower.StarTowerGame;
import emu.nebula.game.tower.StarTowerModifiers;
import emu.nebula.game.tower.room.StarTowerBaseRoom;
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
@@ -22,6 +23,10 @@ public abstract class StarTowerBaseCase {
public StarTowerBaseRoom getRoom() {
return this.getGame().getRoom();
}
public StarTowerModifiers getModifiers() {
return this.getGame().getModifiers();
}
public void register(StarTowerBaseRoom room) {
this.game = room.getGame();

View File

@@ -6,6 +6,7 @@ import emu.nebula.game.player.PlayerChangeInfo;
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
import lombok.Getter;
@Getter
@@ -78,10 +79,10 @@ public class StarTowerBattleCase extends StarTowerBaseCase {
.setLv(this.getGame().getTeamLevel())
.setBattleTime(this.getGame().getBattleTime());
// Add money
int money = this.getRoom().getStage().getInteriorCurrencyQuantity();
// Add coin
int coin = this.getRoom().getStage().getInteriorCurrencyQuantity();
this.getGame().addItem(GameConstants.STAR_TOWER_GOLD_ITEM_ID, money, change);
this.getGame().addItem(GameConstants.STAR_TOWER_COIN_ITEM_ID, coin, change);
// Handle pending potential selectors
var nextCases = this.getGame().handlePendingPotentialSelectors();

View File

@@ -42,15 +42,18 @@ public class StarTowerHawkerCase extends StarTowerBaseCase {
@Override
public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) {
// Set nil resp
// Set nil resp
rsp.getMutableNilResp();
// Get goods
var goods = this.getGoods().get(req.getHawkerReq().getSid());
if (goods == null) {
return rsp;
}
// Make sure we have enough currency
int gold = this.getGame().getRes().get(GameConstants.STAR_TOWER_GOLD_ITEM_ID);
if (gold < goods.getPrice() || goods.isSold()) {
int coin = this.getGame().getRes().get(GameConstants.STAR_TOWER_COIN_ITEM_ID);
if (coin < goods.getPrice() || goods.isSold()) {
return rsp;
}
@@ -61,7 +64,7 @@ public class StarTowerHawkerCase extends StarTowerBaseCase {
this.getGame().addCase(rsp.getMutableCases(), this.getGame().createPotentialSelector());
// Remove items
var change = this.getGame().addItem(GameConstants.STAR_TOWER_GOLD_ITEM_ID, -goods.getPrice(), null);
var change = this.getGame().addItem(GameConstants.STAR_TOWER_COIN_ITEM_ID, -goods.getPrice());
// Set change info
rsp.setChange(change.toProto());

View File

@@ -44,7 +44,7 @@ public class StarTowerPotentialCase extends StarTowerBaseCase {
}
// Add item
var change = this.getGame().addItem(id, 1, null);
var change = this.getGame().addItem(id, 1);
// Set change
rsp.setChange(change.toProto());

View File

@@ -0,0 +1,94 @@
package emu.nebula.game.tower.cases;
import emu.nebula.GameConstants;
import emu.nebula.game.tower.room.StarTowerBaseRoom;
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
import lombok.Getter;
@Getter
public class StarTowerStrengthenMachineCase extends StarTowerBaseCase {
private boolean free;
private int discount;
private int times;
@Override
public void register(StarTowerBaseRoom room) {
super.register(room);
// Also set strengthen price
this.free = this.getModifiers().isFreeStrengthen();
this.discount = this.getModifiers().getStrengthenDiscount();
}
public int getPrice() {
if (this.free) {
return 0;
}
int price = 120 + (this.times * 60) - this.discount;
return Math.max(price, 0);
}
public void increasePrice() {
if (this.free) {
this.free = false;
this.getModifiers().setFreeStrengthen(false);
} else {
this.times++;
}
}
@Override
public CaseType getType() {
return CaseType.StrengthenMachine;
}
@Override
public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) {
// Init case
StarTowerBaseCase towerCase = null;
// Check coin
int coin = getGame().getResCount(GameConstants.STAR_TOWER_COIN_ITEM_ID);
int price = this.getPrice();
if (coin >= price) {
towerCase = getGame().createStrengthenSelector();
}
if (towerCase != null) {
// Add enhancement selector case
this.getRoom().addCase(rsp.getMutableCases(), towerCase);
// Remove coins
var change = this.getGame().addItem(GameConstants.STAR_TOWER_COIN_ITEM_ID, -price);
// Set change info
rsp.setChange(change.toProto());
// Increment price
this.increasePrice();
}
// Set success result
rsp.getMutableStrengthenMachineResp()
.setBuySucceed(towerCase != null);
// Complete
return rsp;
}
// Proto
@Override
public void encodeProto(StarTowerRoomCase proto) {
// Set field in the proto
proto.getMutableStrengthenMachineCase()
.setFirstFree(this.isFree())
.setDiscount(this.getDiscount())
.setTimes(this.getTimes());
}
}

View File

@@ -5,6 +5,7 @@ import java.util.List;
import emu.nebula.data.resources.StarTowerStageDef;
import emu.nebula.game.tower.StarTowerGame;
import emu.nebula.game.tower.StarTowerModifiers;
import emu.nebula.game.tower.cases.CaseType;
import emu.nebula.game.tower.cases.StarTowerBaseCase;
import emu.nebula.game.tower.cases.StarTowerSyncHPCase;
@@ -48,6 +49,14 @@ public class StarTowerBaseRoom {
return this.hasDoor;
}
public StarTowerModifiers getModifiers() {
return this.getGame().getModifiers();
}
public StarTowerBaseCase createExit() {
return this.getGame().createExit();
}
// Map info
public void setMapInfo(StarTowerApplyReq req) {
@@ -105,11 +114,11 @@ public class StarTowerBaseRoom {
// Events
public void onEnter() {
// Create door case
this.getGame().createExit();
// Create sync hp case
this.getGame().addCase(new StarTowerSyncHPCase());
this.addCase(new StarTowerSyncHPCase());
// Create door case
this.createExit();
}
// Proto

View File

@@ -18,9 +18,9 @@ public class StarTowerBattleRoom extends StarTowerBaseRoom {
public void onEnter() {
// Create battle case
this.getGame().setPendingSubNotes(Utils.randomRange(1, 3));
this.getGame().addCase(new StarTowerBattleCase(this.getGame().getPendingSubNotes()));
this.addCase(new StarTowerBattleCase(this.getGame().getPendingSubNotes()));
// Create sync hp case
this.getGame().addCase(new StarTowerSyncHPCase());
this.addCase(new StarTowerSyncHPCase());
}
}

View File

@@ -15,10 +15,10 @@ public class StarTowerEventRoom extends StarTowerBaseRoom {
@Override
public void onEnter() {
// Create door case
this.getGame().createExit();
// Create sync hp case
this.getGame().addCase(new StarTowerSyncHPCase());
this.addCase(new StarTowerSyncHPCase());
// Create door case
this.createExit();
}
}

View File

@@ -3,6 +3,7 @@ package emu.nebula.game.tower.room;
import emu.nebula.data.resources.StarTowerStageDef;
import emu.nebula.game.tower.StarTowerGame;
import emu.nebula.game.tower.cases.StarTowerHawkerCase;
import emu.nebula.game.tower.cases.StarTowerStrengthenMachineCase;
import emu.nebula.game.tower.cases.StarTowerSyncHPCase;
import lombok.Getter;
@@ -16,12 +17,17 @@ public class StarTowerHawkerRoom extends StarTowerBaseRoom {
@Override
public void onEnter() {
// Create hawker case (shop)
this.getGame().addCase(new StarTowerHawkerCase(this.getGame()));
this.addCase(new StarTowerHawkerCase(this.getGame()));
// Create door case
this.getGame().createExit();
// Create strengthen machine
if (this.getModifiers().isEnableShopStrengthen()) {
this.addCase(new StarTowerStrengthenMachineCase());
}
// Create sync hp case
this.getGame().addCase(new StarTowerSyncHPCase());
this.addCase(new StarTowerSyncHPCase());
// Create door case
this.createExit();
}
}

View File

@@ -5,6 +5,7 @@ import emu.nebula.net.NetMsgId;
import emu.nebula.proto.StarTowerApply.StarTowerApplyReq;
import emu.nebula.proto.StarTowerApply.StarTowerApplyResp;
import emu.nebula.net.HandlerId;
import emu.nebula.GameConstants;
import emu.nebula.game.tower.StarTowerGame;
import emu.nebula.net.GameSession;
@@ -29,6 +30,7 @@ public class HandlerStarTowerApplyReq extends NetHandler {
// Create response
var rsp = StarTowerApplyResp.newInstance()
.setLastId(req.getId())
.setCoinQty(game.getResCount(GameConstants.STAR_TOWER_COIN_ITEM_ID))
.setInfo(game.toProto())
.setChange(change.toProto());