mirror of
https://github.com/Melledy/Nebula.git
synced 2025-12-12 20:34:36 +01:00
Compare commits
5 Commits
33b1cf55d4
...
e3d34bfa48
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3d34bfa48 | ||
|
|
65250b07bf | ||
|
|
b38f4f0957 | ||
|
|
e4dc85a50f | ||
|
|
893b23b50d |
@@ -114,9 +114,11 @@ public class GameData {
|
||||
@Getter private static DataTable<StarTowerGrowthNodeDef> StarTowerGrowthNodeDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<StarTowerFloorExpDef> StarTowerFloorExpDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<StarTowerTeamExpDef> StarTowerTeamExpDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<PotentialDef> PotentialDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<SubNoteSkillPromoteGroupDef> SubNoteSkillPromoteGroupDataTable = new DataTable<>();
|
||||
|
||||
@Getter private static DataTable<PotentialDef> PotentialDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<CharPotentialDef> CharPotentialDataTable = new DataTable<>();
|
||||
|
||||
@Getter private static DataTable<StarTowerBookFateCardBundleDef> StarTowerBookFateCardBundleDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<StarTowerBookFateCardQuestDef> StarTowerBookFateCardQuestDataTable = new DataTable<>();
|
||||
@Getter private static DataTable<StarTowerBookFateCardDef> StarTowerBookFateCardDataTable = new DataTable<>();
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package emu.nebula.data.resources;
|
||||
|
||||
import emu.nebula.data.BaseDef;
|
||||
import emu.nebula.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "CharPotential.json")
|
||||
public class CharPotentialDef extends BaseDef {
|
||||
private int Id;
|
||||
|
||||
private int[] MasterSpecificPotentialIds;
|
||||
private int[] AssistSpecificPotentialIds;
|
||||
private int[] CommonPotentialIds;
|
||||
private int[] MasterNormalPotentialIds;
|
||||
private int[] AssistNormalPotentialIds;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return Id;
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,8 @@ public class StarTowerDef extends BaseDef {
|
||||
return Id;
|
||||
}
|
||||
|
||||
public int getMaxFloor(int stage) {
|
||||
int index = stage - 1;
|
||||
public int getMaxFloor(int stageNum) {
|
||||
int index = stageNum - 1;
|
||||
|
||||
if (index < 0 || index >= this.FloorNum.length) {
|
||||
return 0;
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
package emu.nebula.game.tower;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import emu.nebula.proto.PublicStarTower.HawkerGoods;
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class StarTowerCase {
|
||||
private int id;
|
||||
|
||||
@Setter(AccessLevel.NONE)
|
||||
private CaseType type;
|
||||
|
||||
// Extra data
|
||||
private int teamLevel;
|
||||
private int subNoteSkillNum;
|
||||
|
||||
private int floorId;
|
||||
private int roomType;
|
||||
|
||||
private int eventId;
|
||||
private int npcId;
|
||||
|
||||
// Selector
|
||||
private IntList ids;
|
||||
|
||||
// Hawker
|
||||
private Map<Integer, StarTowerShopGoods> goodsList;
|
||||
|
||||
public StarTowerCase(CaseType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void addId(int id) {
|
||||
if (this.ids == null) {
|
||||
this.ids = new IntArrayList();
|
||||
}
|
||||
|
||||
this.ids.add(id);
|
||||
}
|
||||
|
||||
public int selectId(int index) {
|
||||
if (this.getIds() == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= this.getIds().size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this.getIds().getInt(index);
|
||||
}
|
||||
|
||||
public void addGoods(StarTowerShopGoods goods) {
|
||||
if (this.goodsList == null) {
|
||||
this.goodsList = new HashMap<>();
|
||||
}
|
||||
|
||||
this.getGoodsList().put(getGoodsList().size() + 1, goods);
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public StarTowerRoomCase toProto() {
|
||||
var proto = StarTowerRoomCase.newInstance()
|
||||
.setId(this.getId());
|
||||
|
||||
switch (this.type) {
|
||||
case Battle -> {
|
||||
proto.getMutableBattleCase()
|
||||
.setSubNoteSkillNum(this.getSubNoteSkillNum());
|
||||
}
|
||||
case OpenDoor -> {
|
||||
proto.getMutableDoorCase()
|
||||
.setFloor(this.getFloorId())
|
||||
.setType(this.getRoomType());
|
||||
}
|
||||
case SyncHP, RecoveryHP -> {
|
||||
proto.getMutableSyncHPCase();
|
||||
}
|
||||
case SelectSpecialPotential -> {
|
||||
proto.getMutableSelectSpecialPotentialCase()
|
||||
.setTeamLevel(this.getTeamLevel())
|
||||
.addAllIds(this.getIds().toIntArray());
|
||||
}
|
||||
case PotentialSelect -> {
|
||||
proto.getMutableSelectPotentialCase();
|
||||
}
|
||||
case NpcEvent -> {
|
||||
proto.getMutableSelectOptionsEventCase()
|
||||
.setEvtId(this.getEventId())
|
||||
.setNPCId(this.getNpcId())
|
||||
.addAllOptions(this.getIds().toIntArray());
|
||||
}
|
||||
case Hawker -> {
|
||||
var hawker = proto.getMutableHawkerCase();
|
||||
|
||||
for (var entry : getGoodsList().entrySet()) {
|
||||
var sid = entry.getKey();
|
||||
var goods = entry.getValue();
|
||||
|
||||
var info = HawkerGoods.newInstance()
|
||||
.setIdx(goods.getGoodsId())
|
||||
.setSid(sid)
|
||||
.setType(goods.getType())
|
||||
.setGoodsId(102) // ?
|
||||
.setPrice(goods.getPrice())
|
||||
.setTag(1);
|
||||
|
||||
hawker.addList(info);
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
@@ -2,18 +2,26 @@ package emu.nebula.game.tower;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.data.resources.PotentialDef;
|
||||
import emu.nebula.data.resources.StarTowerDef;
|
||||
import emu.nebula.data.resources.StarTowerStageDef;
|
||||
import emu.nebula.game.formation.Formation;
|
||||
import emu.nebula.game.inventory.ItemParamMap;
|
||||
import emu.nebula.game.player.Player;
|
||||
import emu.nebula.game.player.PlayerChangeInfo;
|
||||
import emu.nebula.game.tower.cases.StarTowerBaseCase;
|
||||
import emu.nebula.game.tower.cases.StarTowerDoorCase;
|
||||
import emu.nebula.game.tower.cases.StarTowerPotentialCase;
|
||||
import emu.nebula.game.tower.room.RoomType;
|
||||
import emu.nebula.game.tower.room.StarTowerBaseRoom;
|
||||
import emu.nebula.game.tower.room.StarTowerBattleRoom;
|
||||
import emu.nebula.game.tower.room.StarTowerEventRoom;
|
||||
import emu.nebula.game.tower.room.StarTowerHawkerRoom;
|
||||
import emu.nebula.proto.PublicStarTower.*;
|
||||
import emu.nebula.proto.StarTowerApply.StarTowerApplyReq;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
|
||||
@@ -21,14 +29,11 @@ import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
|
||||
import emu.nebula.util.Snowflake;
|
||||
import emu.nebula.util.Utils;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import us.hebi.quickbuf.RepeatedMessage;
|
||||
|
||||
@Getter
|
||||
@@ -40,15 +45,13 @@ public class StarTowerGame {
|
||||
// Tower id
|
||||
private int id;
|
||||
|
||||
// Room
|
||||
// Tower floor count
|
||||
private int floorCount;
|
||||
private int stageNum;
|
||||
private int stageFloor;
|
||||
private int floor;
|
||||
private int mapId;
|
||||
private int mapTableId;
|
||||
private String mapParam;
|
||||
private int paramId;
|
||||
private int roomType;
|
||||
|
||||
// Tower room
|
||||
private StarTowerBaseRoom room;
|
||||
|
||||
// Team
|
||||
private int formationId;
|
||||
@@ -58,16 +61,12 @@ public class StarTowerGame {
|
||||
private int nextLevelExp;
|
||||
private int charHp;
|
||||
private int battleTime;
|
||||
private int battleCount;
|
||||
private List<StarTowerChar> chars;
|
||||
private List<StarTowerDisc> discs;
|
||||
private IntList charIds;
|
||||
|
||||
// Case
|
||||
private int lastCaseId = 0;
|
||||
private List<StarTowerCase> cases;
|
||||
private Int2IntMap cachedCases;
|
||||
private int pendingPotentialCases = 0;
|
||||
private int pendingSubNotes = 0;
|
||||
|
||||
// Bag
|
||||
private ItemParamMap items;
|
||||
@@ -91,37 +90,34 @@ public class StarTowerGame {
|
||||
}
|
||||
|
||||
public StarTowerGame(StarTowerManager manager, StarTowerDef data, Formation formation, StarTowerApplyReq req) {
|
||||
// Set manager and cache resource data
|
||||
this.manager = manager;
|
||||
this.data = data;
|
||||
|
||||
// Set tower id
|
||||
this.id = req.getId();
|
||||
|
||||
this.mapId = req.getMapId();
|
||||
this.mapTableId = req.getMapTableId();
|
||||
this.mapParam = req.getMapParam();
|
||||
this.paramId = req.getParamId();
|
||||
// Setup room
|
||||
this.enterNextRoom();
|
||||
this.getRoom().setMapInfo(req);
|
||||
|
||||
// Setup team
|
||||
this.formationId = req.getFormationId();
|
||||
this.buildId = Snowflake.newUid();
|
||||
this.teamLevel = 1;
|
||||
this.teamExp = 0;
|
||||
this.nextLevelExp = GameData.getStarTowerTeamExpDataTable().get(2).getNeedExp();
|
||||
this.stageNum = 1;
|
||||
this.stageFloor = 1;
|
||||
this.floor = 1;
|
||||
this.charHp = -1;
|
||||
this.chars = new ArrayList<>();
|
||||
this.discs = new ArrayList<>();
|
||||
this.charIds = new IntArrayList();
|
||||
|
||||
this.cases = new ArrayList<>();
|
||||
this.cachedCases = new Int2IntOpenHashMap();
|
||||
|
||||
this.items = new ItemParamMap();
|
||||
this.res = new ItemParamMap();
|
||||
this.potentials = new ItemParamMap();
|
||||
this.newInfos = new ItemParamMap();
|
||||
|
||||
// Melody skill drop list
|
||||
this.subNoteDropList = new IntArrayList();
|
||||
|
||||
// Init formation
|
||||
@@ -174,10 +170,6 @@ public class StarTowerGame {
|
||||
if (money > 0) {
|
||||
this.getRes().add(GameConstants.STAR_TOWER_GOLD_ITEM_ID, money);
|
||||
}
|
||||
|
||||
// Add cases
|
||||
this.addCase(new StarTowerCase(CaseType.Battle));
|
||||
this.addCase(new StarTowerCase(CaseType.SyncHP));
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
@@ -196,14 +188,14 @@ public class StarTowerGame {
|
||||
return Utils.randomElement(this.getCharIds());
|
||||
}
|
||||
|
||||
public StarTowerStageDef getStageData(int stage, int floor) {
|
||||
var stageId = (this.getId() * 10000) + (stage * 100) + floor;
|
||||
public StarTowerStageDef getStageData(int stageNum, int stageFloor) {
|
||||
var stageId = (this.getId() * 10000) + (stageNum * 100) + stageFloor;
|
||||
return GameData.getStarTowerStageDataTable().get(stageId);
|
||||
}
|
||||
|
||||
public StarTowerStageDef getNextStageData() {
|
||||
int stage = this.stageNum;
|
||||
int floor = this.stageFloor + 1;
|
||||
int stage = this.getStageNum();
|
||||
int floor = this.getStageFloor() + 1;
|
||||
|
||||
if (floor >= this.getData().getMaxFloor(this.getStageNum())) {
|
||||
floor = 1;
|
||||
@@ -213,6 +205,49 @@ public class StarTowerGame {
|
||||
return getStageData(stage, floor);
|
||||
}
|
||||
|
||||
public boolean isOnFinalFloor() {
|
||||
int nextFloor = this.getFloorCount() + 1;
|
||||
return nextFloor > this.getData().getMaxFloors();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void enterNextRoom() {
|
||||
// Increment total floor count
|
||||
this.floorCount++;
|
||||
|
||||
// Calculate stage num/floor
|
||||
int nextStageFloor = this.stageFloor + 1;
|
||||
|
||||
if (this.stageFloor >= this.getData().getMaxFloor(this.stageNum)) {
|
||||
this.stageNum++;
|
||||
this.stageFloor = 1;
|
||||
} else {
|
||||
this.stageFloor = nextStageFloor;
|
||||
}
|
||||
|
||||
// Get stage data
|
||||
var stage = this.getStageData(this.stageNum, this.stageFloor);
|
||||
if (stage == null) {
|
||||
throw new RuntimeException("No stage data for stage " + this.stageNum + "-" + this.stageFloor + " found");
|
||||
}
|
||||
|
||||
// Create room
|
||||
int roomType = stage.getRoomType();
|
||||
|
||||
if (roomType <= RoomType.FinalBossRoom.getValue()) {
|
||||
this.room = new StarTowerBattleRoom(this, stage);
|
||||
} else if (roomType == RoomType.EventRoom.getValue()) {
|
||||
this.room = new StarTowerEventRoom(this, stage);
|
||||
} else if (roomType == RoomType.ShopRoom.getValue()) {
|
||||
this.room = new StarTowerHawkerRoom(this, stage);
|
||||
} else {
|
||||
this.room = new StarTowerBaseRoom(this, stage);
|
||||
}
|
||||
|
||||
// Create cases for the room
|
||||
this.room.onEnter();
|
||||
}
|
||||
|
||||
public int getStartingGold() {
|
||||
int gold = 0;
|
||||
|
||||
@@ -226,6 +261,10 @@ public class StarTowerGame {
|
||||
|
||||
return gold;
|
||||
}
|
||||
|
||||
public void addExp(int amount) {
|
||||
this.teamExp += amount;
|
||||
}
|
||||
|
||||
public int levelUp(int picks) {
|
||||
if (this.teamExp >= this.nextLevelExp && this.nextLevelExp != Integer.MAX_VALUE) {
|
||||
@@ -261,50 +300,18 @@ public class StarTowerGame {
|
||||
return this.levelUp(potentialPicks);
|
||||
}
|
||||
|
||||
public void addBattleTime(int amount) {
|
||||
this.battleTime += amount;
|
||||
}
|
||||
|
||||
// Cases
|
||||
|
||||
public StarTowerCase getCase(CaseType type) {
|
||||
// Check if we have any cached case for this case type
|
||||
if (!this.getCachedCases().containsKey(type.getValue())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get index of cached case
|
||||
int index = this.getCachedCases().get(type.getValue());
|
||||
|
||||
// Sanity check just in case
|
||||
if (index < 0 || index >= this.getCases().size()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.getCases().get(index);
|
||||
public StarTowerBaseCase addCase(StarTowerBaseCase towerCase) {
|
||||
return this.getRoom().addCase(towerCase);
|
||||
}
|
||||
|
||||
public void cacheCaseIndex(StarTowerCase towerCase) {
|
||||
this.getCachedCases().put(towerCase.getType().getValue(), this.getCases().size() - 1);
|
||||
}
|
||||
|
||||
public StarTowerCase addCase(StarTowerCase towerCase) {
|
||||
return this.addCase(null, towerCase);
|
||||
}
|
||||
|
||||
public StarTowerCase addCase(RepeatedMessage<StarTowerRoomCase> cases, StarTowerCase towerCase) {
|
||||
// Add to cases list
|
||||
this.getCases().add(towerCase);
|
||||
|
||||
// Increment id
|
||||
towerCase.setId(++this.lastCaseId);
|
||||
|
||||
// Set proto
|
||||
if (cases != null) {
|
||||
cases.add(towerCase.toProto());
|
||||
}
|
||||
|
||||
// Cache case index
|
||||
this.cacheCaseIndex(towerCase);
|
||||
|
||||
// Complete
|
||||
return towerCase;
|
||||
public StarTowerBaseCase addCase(RepeatedMessage<StarTowerRoomCase> cases, StarTowerBaseCase towerCase) {
|
||||
return this.getRoom().addCase(cases, towerCase);
|
||||
}
|
||||
|
||||
// Items
|
||||
@@ -388,26 +395,91 @@ public class StarTowerGame {
|
||||
|
||||
// Potentials/Sub notes
|
||||
|
||||
private StarTowerCase createPotentialSelector(int charId) {
|
||||
// Add potential selector
|
||||
var potentialCase = new StarTowerCase(CaseType.SelectSpecialPotential);
|
||||
potentialCase.setTeamLevel(this.getTeamLevel());
|
||||
|
||||
// Get random potentials
|
||||
List<PotentialDef> potentials = new ArrayList<>();
|
||||
|
||||
for (var potentialData : GameData.getPotentialDataTable()) {
|
||||
if (potentialData.getCharId() == charId) {
|
||||
potentials.add(potentialData);
|
||||
}
|
||||
/**
|
||||
* Adds random potential selector cases for the client
|
||||
*/
|
||||
public void addPotentialSelectors(int amount) {
|
||||
this.pendingPotentialCases += amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a potential selector for the client if there are any potential selectors avaliable.
|
||||
* If there are none, then return null.
|
||||
*/
|
||||
public StarTowerBaseCase handlePendingPotentialSelectors() {
|
||||
if (this.pendingPotentialCases > 0) {
|
||||
this.pendingPotentialCases--;
|
||||
return this.createPotentialSelector();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a potential selector for a random character
|
||||
*/
|
||||
public StarTowerBaseCase createPotentialSelector() {
|
||||
int charId = this.getRandomCharId();
|
||||
return this.createPotentialSelector(charId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a potential selector for the specified character
|
||||
*/
|
||||
public StarTowerBaseCase createPotentialSelector(int charId) {
|
||||
// Get character potentials
|
||||
var data = GameData.getCharPotentialDataTable().get(charId);
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Random potentials list
|
||||
var potentials = new IntArrayList();
|
||||
|
||||
// Add potentials based on character role
|
||||
boolean isMainCharacter = this.getCharIds().getInt(0) == charId;
|
||||
|
||||
if (isMainCharacter) {
|
||||
potentials.addElements(0, data.getMasterSpecificPotentialIds());
|
||||
potentials.addElements(0, data.getMasterNormalPotentialIds());
|
||||
} else {
|
||||
potentials.addElements(0, data.getAssistSpecificPotentialIds());
|
||||
potentials.addElements(0, data.getAssistNormalPotentialIds());
|
||||
}
|
||||
|
||||
potentials.addElements(0, data.getCommonPotentialIds());
|
||||
|
||||
// Get up to 3 random potentials
|
||||
IntList selector = new IntArrayList();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
var potentialData = Utils.randomElement(potentials);
|
||||
potentialCase.addId(potentialData.getId());
|
||||
// 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);
|
||||
}
|
||||
|
||||
return potentialCase;
|
||||
// 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;
|
||||
}
|
||||
|
||||
private PlayerChangeInfo addRandomSubNoteSkills(PlayerChangeInfo change) {
|
||||
@@ -419,7 +491,7 @@ public class StarTowerGame {
|
||||
return change;
|
||||
}
|
||||
|
||||
private PlayerChangeInfo addRandomSubNoteSkills(int count, PlayerChangeInfo change) {
|
||||
public PlayerChangeInfo addRandomSubNoteSkills(int count, PlayerChangeInfo change) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
this.addRandomSubNoteSkills(change);
|
||||
}
|
||||
@@ -427,22 +499,34 @@ public class StarTowerGame {
|
||||
return change;
|
||||
}
|
||||
|
||||
// Door case
|
||||
|
||||
public StarTowerBaseCase createExit() {
|
||||
return this.createExit(null);
|
||||
}
|
||||
|
||||
public StarTowerBaseCase createExit(RepeatedMessage<StarTowerRoomCase> cases) {
|
||||
return this.getRoom().addCase(
|
||||
cases,
|
||||
new StarTowerDoorCase(this.getFloorCount() + 1, this.getNextStageData())
|
||||
);
|
||||
}
|
||||
|
||||
// Handlers
|
||||
|
||||
public StarTowerInteractResp handleInteract(StarTowerInteractReq req) {
|
||||
// Build response proto
|
||||
var rsp = StarTowerInteractResp.newInstance()
|
||||
.setId(req.getId());
|
||||
|
||||
if (req.hasBattleEndReq()) {
|
||||
rsp = this.onBattleEnd(req, rsp);
|
||||
} else if (req.hasRecoveryHPReq()) {
|
||||
rsp = this.onRecoveryHP(req, rsp);
|
||||
} else if (req.hasSelectReq()) {
|
||||
rsp = this.onSelect(req, rsp);
|
||||
} else if (req.hasEnterReq()) {
|
||||
rsp = this.onEnterReq(req, rsp);
|
||||
} else if (req.hasHawkerReq()) {
|
||||
rsp = this.onHawkerReq(req, rsp);
|
||||
|
||||
// Get tower case
|
||||
var towerCase = this.getRoom().getCase(req.getId());
|
||||
|
||||
// Handle interaction with tower case
|
||||
if (towerCase != null) {
|
||||
rsp = towerCase.interact(req, rsp);
|
||||
} else {
|
||||
rsp.getMutableNilResp();
|
||||
}
|
||||
|
||||
// Add any items
|
||||
@@ -465,291 +549,13 @@ public class StarTowerGame {
|
||||
// Set these protos
|
||||
rsp.getMutableChange();
|
||||
|
||||
// Return response proto
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Interact events
|
||||
|
||||
@SneakyThrows
|
||||
public StarTowerInteractResp onBattleEnd(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
// Parse battle end
|
||||
var proto = req.getBattleEndReq();
|
||||
|
||||
// Init change
|
||||
var change = new PlayerChangeInfo();
|
||||
|
||||
// Handle victory/defeat
|
||||
if (proto.hasVictory()) {
|
||||
// Handle leveling up
|
||||
|
||||
// Get relevant floor exp data
|
||||
// fishiatee: THERE'S NO LINQ IN JAVAAAAAAAAAAAAA
|
||||
var floorExpData = GameData.getStarTowerFloorExpDataTable().stream()
|
||||
.filter(f -> f.getStarTowerId() == this.getId())
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
int expReward = 0;
|
||||
|
||||
// Determine appropriate exp reward
|
||||
switch (this.getRoomType()) {
|
||||
// Regular battle room
|
||||
case 0:
|
||||
expReward = floorExpData.getNormalExp();
|
||||
break;
|
||||
// Elite battle room
|
||||
case 1:
|
||||
expReward = floorExpData.getEliteExp();
|
||||
break;
|
||||
// Non-final boss room
|
||||
case 2:
|
||||
expReward = floorExpData.getBossExp();
|
||||
break;
|
||||
// Final room
|
||||
case 3:
|
||||
expReward = floorExpData.getFinalBossExp();
|
||||
break;
|
||||
}
|
||||
|
||||
// Level up
|
||||
this.teamExp += expReward;
|
||||
this.pendingPotentialCases += this.levelUp();
|
||||
|
||||
// Add clear time
|
||||
this.battleTime += proto.getVictory().getTime();
|
||||
|
||||
// Handle victory
|
||||
rsp.getMutableBattleEndResp()
|
||||
.getMutableVictory()
|
||||
.setLv(this.getTeamLevel())
|
||||
.setBattleTime(this.getBattleTime());
|
||||
|
||||
// Add money
|
||||
int money = this.getStageData(this.getStageNum(), this.getStageFloor()).getInteriorCurrencyQuantity();
|
||||
|
||||
this.addItem(GameConstants.STAR_TOWER_GOLD_ITEM_ID, money, change);
|
||||
|
||||
// Handle pending potential selectors
|
||||
if (this.pendingPotentialCases > 0) {
|
||||
// Create potential selector
|
||||
var potentialCase = this.createPotentialSelector(this.getRandomCharId());
|
||||
this.addCase(rsp.getMutableCases(), potentialCase);
|
||||
|
||||
this.pendingPotentialCases--;
|
||||
}
|
||||
else {
|
||||
// Add door case here
|
||||
var doorCase = this.addCase(new StarTowerCase(CaseType.OpenDoor));
|
||||
doorCase.setFloorId(this.getStageFloor() + 1);
|
||||
|
||||
var nextStage = this.getNextStageData();
|
||||
if (nextStage != null) {
|
||||
doorCase.setRoomType(nextStage.getRoomType());
|
||||
}
|
||||
|
||||
this.addCase(rsp.getMutableCases(), doorCase);
|
||||
}
|
||||
|
||||
// Add sub note skills
|
||||
var battleCase = this.getCase(CaseType.Battle);
|
||||
if (battleCase != null) {
|
||||
int subNoteSkills = battleCase.getSubNoteSkillNum();
|
||||
this.addRandomSubNoteSkills(subNoteSkills, change);
|
||||
}
|
||||
|
||||
// Handle client events for achievements
|
||||
getPlayer().getAchievementManager().handleClientEvents(proto.getVictory().getEvents());
|
||||
} else {
|
||||
// Handle defeat
|
||||
// TODO
|
||||
}
|
||||
|
||||
// Increment battle count
|
||||
this.battleCount++;
|
||||
|
||||
// Set change
|
||||
rsp.setChange(change.toProto());
|
||||
|
||||
// Return response for the player
|
||||
return rsp;
|
||||
}
|
||||
|
||||
public StarTowerInteractResp onSelect(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
var index = req.getMutableSelectReq().getIndex();
|
||||
|
||||
var selectorCase = this.getCase(CaseType.SelectSpecialPotential);
|
||||
if (selectorCase == null) {
|
||||
return rsp;
|
||||
}
|
||||
|
||||
int id = selectorCase.selectId(index);
|
||||
if (id <= 0) {
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Add item
|
||||
var change = this.addItem(id, 1, null);
|
||||
|
||||
// Set change
|
||||
rsp.setChange(change.toProto());
|
||||
|
||||
// Handle pending potential selectors
|
||||
if (this.pendingPotentialCases > 0) {
|
||||
// Create potential selector
|
||||
var potentialCase = this.createPotentialSelector(this.getRandomCharId());
|
||||
this.addCase(rsp.getMutableCases(), potentialCase);
|
||||
|
||||
this.pendingPotentialCases--;
|
||||
}
|
||||
else {
|
||||
// Add door case
|
||||
var doorCase = this.addCase(new StarTowerCase(CaseType.OpenDoor));
|
||||
doorCase.setFloorId(this.getStageFloor() + 1);
|
||||
|
||||
var nextStage = this.getNextStageData();
|
||||
if (nextStage != null) {
|
||||
doorCase.setRoomType(nextStage.getRoomType());
|
||||
}
|
||||
|
||||
this.addCase(rsp.getMutableCases(), doorCase);
|
||||
}
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
public StarTowerInteractResp onEnterReq(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
// Get proto
|
||||
var proto = req.getEnterReq();
|
||||
|
||||
// Set
|
||||
this.mapId = proto.getMapId();
|
||||
this.mapTableId = proto.getMapTableId();
|
||||
this.mapParam = proto.getMapParam();
|
||||
this.paramId = proto.getParamId();
|
||||
this.floor++;
|
||||
|
||||
// Check if we need to settle
|
||||
if (this.floor > this.getData().getMaxFloors()) {
|
||||
return this.settle(rsp);
|
||||
}
|
||||
|
||||
// Next floor
|
||||
int nextFloor = this.stageFloor + 1;
|
||||
|
||||
if (this.stageFloor >= this.getData().getMaxFloor(this.getStageNum())) {
|
||||
this.stageFloor = 1;
|
||||
this.stageNum++;
|
||||
} else {
|
||||
this.stageFloor = nextFloor;
|
||||
}
|
||||
|
||||
// Calculate stage
|
||||
var stageData = this.getStageData(this.getStageNum(), this.getStageFloor());
|
||||
|
||||
if (stageData != null) {
|
||||
this.roomType = stageData.getRoomType();
|
||||
} else {
|
||||
this.roomType = 0;
|
||||
}
|
||||
|
||||
// Clear cases
|
||||
this.lastCaseId = 0;
|
||||
this.cases.clear();
|
||||
this.cachedCases.clear();
|
||||
|
||||
// Add cases
|
||||
var syncHpCase = new StarTowerCase(CaseType.SyncHP);
|
||||
|
||||
// Room proto
|
||||
var room = rsp.getMutableEnterResp().getMutableRoom();
|
||||
room.setData(this.toRoomDataProto());
|
||||
|
||||
// Handle room type TODO
|
||||
if (this.roomType <= StarTowerRoomType.FinalBossRoom.getValue()) {
|
||||
var battleCase = new StarTowerCase(CaseType.Battle);
|
||||
battleCase.setSubNoteSkillNum(Utils.randomRange(1, 3));
|
||||
|
||||
this.addCase(room.getMutableCases(), battleCase);
|
||||
} else if (this.roomType == StarTowerRoomType.EventRoom.getValue()) {
|
||||
|
||||
} else if (this.roomType == StarTowerRoomType.ShopRoom.getValue()) {
|
||||
var hawkerCase = new StarTowerCase(CaseType.Hawker);
|
||||
|
||||
// TODO
|
||||
for (int i = 0; i < 8; i++) {
|
||||
hawkerCase.addGoods(new StarTowerShopGoods(1, 1, 200));
|
||||
}
|
||||
|
||||
this.addCase(room.getMutableCases(), hawkerCase);
|
||||
}
|
||||
|
||||
// Add cases
|
||||
this.addCase(room.getMutableCases(), syncHpCase);
|
||||
|
||||
// Add door to next floor if current floor is choice/shop domains
|
||||
if (this.roomType == 6 | this.roomType == 7) {
|
||||
var doorCase = new StarTowerCase(CaseType.OpenDoor);
|
||||
doorCase.setFloorId(this.getFloor() + 1);
|
||||
|
||||
// Set room type of next room
|
||||
var nextStage = this.getNextStageData();
|
||||
if (nextStage != null) {
|
||||
doorCase.setRoomType(nextStage.getRoomType());
|
||||
}
|
||||
|
||||
// Add case
|
||||
this.addCase(room.getMutableCases(), doorCase);
|
||||
}
|
||||
|
||||
// Done
|
||||
return rsp;
|
||||
}
|
||||
|
||||
public StarTowerInteractResp onRecoveryHP(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
// Add case
|
||||
this.addCase(rsp.getMutableCases(), new StarTowerCase(CaseType.RecoveryHP));
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
private StarTowerInteractResp onHawkerReq(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
// Set this proto
|
||||
rsp.getMutableNilResp();
|
||||
|
||||
// Get hawker case
|
||||
var shop = this.getCase(CaseType.Hawker);
|
||||
if (shop == null || shop.getGoodsList() == null) {
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Get goods
|
||||
var goods = shop.getGoodsList().get(req.getHawkerReq().getSid());
|
||||
|
||||
// Make sure we have enough currency
|
||||
if (this.getRes().get(GameConstants.STAR_TOWER_GOLD_ITEM_ID) < goods.getPrice() || goods.isSold()) {
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Mark goods as sold
|
||||
goods.markAsSold();
|
||||
|
||||
// Add case
|
||||
int charId = this.getRandomCharId();
|
||||
var potentialCase = this.createPotentialSelector(charId);
|
||||
this.addCase(rsp.getMutableCases(), potentialCase);
|
||||
|
||||
// Remove items
|
||||
var change = this.addItem(GameConstants.STAR_TOWER_GOLD_ITEM_ID, -goods.getPrice(), null);
|
||||
|
||||
// Set change info
|
||||
rsp.setChange(change.toProto());
|
||||
|
||||
// Success
|
||||
return rsp;
|
||||
}
|
||||
|
||||
public StarTowerInteractResp settle(StarTowerInteractResp rsp) {
|
||||
public StarTowerInteractResp settle(StarTowerInteractResp rsp, boolean isWin) {
|
||||
// End game
|
||||
this.getManager().endGame(true);
|
||||
this.getManager().endGame(isWin);
|
||||
|
||||
// Settle info
|
||||
var settle = rsp.getMutableSettle()
|
||||
@@ -760,7 +566,9 @@ public class StarTowerGame {
|
||||
settle.getMutableChange();
|
||||
|
||||
// Log victory
|
||||
this.getManager().getPlayer().getProgress().addStarTowerLog(this.getId());
|
||||
if (isWin) {
|
||||
this.getManager().getPlayer().getProgress().addStarTowerLog(this.getId());
|
||||
}
|
||||
|
||||
// Complete
|
||||
return rsp;
|
||||
@@ -781,12 +589,8 @@ public class StarTowerGame {
|
||||
this.getChars().forEach(proto.getMutableMeta()::addChars);
|
||||
this.getDiscs().forEach(proto.getMutableMeta()::addDiscs);
|
||||
|
||||
proto.getMutableRoom().setData(this.toRoomDataProto());
|
||||
|
||||
// Cases
|
||||
for (var starTowerCase : this.getCases()) {
|
||||
proto.getMutableRoom().addCases(starTowerCase.toProto());
|
||||
}
|
||||
// Set room data
|
||||
proto.setRoom(this.getRoom().toProto());
|
||||
|
||||
// Set up bag
|
||||
var bag = proto.getMutableBag();
|
||||
@@ -817,23 +621,5 @@ public class StarTowerGame {
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
public StarTowerRoomData toRoomDataProto() {
|
||||
var proto = StarTowerRoomData.newInstance()
|
||||
.setFloor(this.getStageFloor())
|
||||
.setMapId(this.getMapId())
|
||||
.setRoomType(this.getRoomType())
|
||||
.setMapTableId(this.getMapTableId());
|
||||
|
||||
if (this.getMapParam() != null && !this.getMapParam().isEmpty()) {
|
||||
proto.setMapParam(this.getMapParam());
|
||||
}
|
||||
|
||||
if (this.getParamId() != 0) {
|
||||
proto.setParamId(this.getParamId());
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -205,7 +205,12 @@ public class StarTowerManager extends PlayerManager {
|
||||
}
|
||||
|
||||
// Create game
|
||||
this.game = new StarTowerGame(this, data, formation, req);
|
||||
try {
|
||||
this.game = new StarTowerGame(this, data, formation, req);
|
||||
} catch (Exception e) {
|
||||
Nebula.getLogger().error("Could not create star tower game", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Trigger quest
|
||||
this.getPlayer().trigger(QuestCondition.TowerEnterFloor, 1);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package emu.nebula.game.tower;
|
||||
package emu.nebula.game.tower.cases;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
@@ -0,0 +1,47 @@
|
||||
package emu.nebula.game.tower.cases;
|
||||
|
||||
import emu.nebula.game.tower.StarTowerGame;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Base class for star tower cases
|
||||
*/
|
||||
@Getter
|
||||
public abstract class StarTowerBaseCase {
|
||||
private transient StarTowerGame game;
|
||||
private int id;
|
||||
|
||||
public StarTowerBaseCase() {
|
||||
|
||||
}
|
||||
|
||||
public StarTowerBaseRoom getRoom() {
|
||||
return this.getGame().getRoom();
|
||||
}
|
||||
|
||||
public void register(StarTowerBaseRoom room) {
|
||||
this.game = room.getGame();
|
||||
this.id = room.getNextCaseId();
|
||||
}
|
||||
|
||||
public abstract CaseType getType();
|
||||
|
||||
public abstract StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp);
|
||||
|
||||
// Proto
|
||||
|
||||
public StarTowerRoomCase toProto() {
|
||||
var proto = StarTowerRoomCase.newInstance()
|
||||
.setId(this.getId());
|
||||
|
||||
this.encodeProto(proto);
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
public abstract void encodeProto(StarTowerRoomCase proto);
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package emu.nebula.game.tower.cases;
|
||||
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.game.player.PlayerChangeInfo;
|
||||
import emu.nebula.game.tower.room.StarTowerBattleRoom;
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class StarTowerBattleCase extends StarTowerBaseCase {
|
||||
private int subNoteSkillNum;
|
||||
|
||||
public StarTowerBattleCase() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
public StarTowerBattleCase(int subNoteSkillNum) {
|
||||
this.subNoteSkillNum = subNoteSkillNum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseType getType() {
|
||||
return CaseType.Battle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
// Parse battle end
|
||||
var proto = req.getBattleEndReq();
|
||||
|
||||
// Init change
|
||||
var change = new PlayerChangeInfo();
|
||||
|
||||
// Handle victory/defeat
|
||||
if (proto.hasVictory()) {
|
||||
// Handle leveling up
|
||||
|
||||
// Get relevant floor exp data
|
||||
// fishiatee: THERE'S NO LINQ IN JAVAAAAAAAAAAAAA
|
||||
var floorExpData = GameData.getStarTowerFloorExpDataTable().stream()
|
||||
.filter(f -> f.getStarTowerId() == this.getGame().getId())
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
int expReward = 0;
|
||||
|
||||
// Determine appropriate exp reward
|
||||
switch (this.getRoom().getType()) {
|
||||
// Regular battle room
|
||||
case 0:
|
||||
expReward = floorExpData.getNormalExp();
|
||||
break;
|
||||
// Elite battle room
|
||||
case 1:
|
||||
expReward = floorExpData.getEliteExp();
|
||||
break;
|
||||
// Non-final boss room
|
||||
case 2:
|
||||
expReward = floorExpData.getBossExp();
|
||||
break;
|
||||
// Final room
|
||||
case 3:
|
||||
expReward = floorExpData.getFinalBossExp();
|
||||
break;
|
||||
}
|
||||
|
||||
// Level up
|
||||
this.getGame().addExp(expReward);
|
||||
this.getGame().addPotentialSelectors(this.getGame().levelUp());
|
||||
|
||||
// Add clear time
|
||||
this.getGame().addBattleTime(proto.getVictory().getTime());
|
||||
|
||||
// Handle victory
|
||||
rsp.getMutableBattleEndResp()
|
||||
.getMutableVictory()
|
||||
.setLv(this.getGame().getTeamLevel())
|
||||
.setBattleTime(this.getGame().getBattleTime());
|
||||
|
||||
// Add money
|
||||
int money = this.getRoom().getStage().getInteriorCurrencyQuantity();
|
||||
|
||||
this.getGame().addItem(GameConstants.STAR_TOWER_GOLD_ITEM_ID, money, change);
|
||||
|
||||
// Handle pending potential selectors
|
||||
var potentialCase = this.getGame().handlePendingPotentialSelectors();
|
||||
if (potentialCase != null) {
|
||||
// Create potential selector
|
||||
this.getGame().addCase(rsp.getMutableCases(), potentialCase);
|
||||
} else if (!this.getRoom().hasDoor()) {
|
||||
// Add door case here if door hasn't opened yet
|
||||
this.getGame().createExit(rsp.getMutableCases());
|
||||
// Create recovery npc
|
||||
if (this.getRoom() instanceof StarTowerBattleRoom) {
|
||||
this.getRoom().addCase(rsp.getMutableCases(), new StarTowerNpcRecoveryHPCase());
|
||||
}
|
||||
}
|
||||
|
||||
// Add sub note skills
|
||||
this.getGame().addRandomSubNoteSkills(this.getGame().getPendingSubNotes(), change);
|
||||
|
||||
// Handle client events for achievements
|
||||
this.getGame().getPlayer().getAchievementManager().handleClientEvents(proto.getVictory().getEvents());
|
||||
} else {
|
||||
// Handle defeat
|
||||
// TODO
|
||||
return this.getGame().settle(rsp, false);
|
||||
}
|
||||
|
||||
// Set change
|
||||
rsp.setChange(change.toProto());
|
||||
|
||||
// Return response for the player
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
@Override
|
||||
public void encodeProto(StarTowerRoomCase proto) {
|
||||
proto.getMutableBattleCase()
|
||||
.setSubNoteSkillNum(this.getSubNoteSkillNum());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package emu.nebula.game.tower.cases;
|
||||
|
||||
import emu.nebula.data.resources.StarTowerStageDef;
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class StarTowerDoorCase extends StarTowerBaseCase {
|
||||
private int floorNum;
|
||||
private int roomType;
|
||||
|
||||
public StarTowerDoorCase(int floor, StarTowerStageDef data) {
|
||||
this.floorNum = floor;
|
||||
|
||||
if (data != null) {
|
||||
this.roomType = data.getRoomType();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseType getType() {
|
||||
return CaseType.OpenDoor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
// Get request
|
||||
var proto = req.getEnterReq();
|
||||
|
||||
// Check if we need to settle on the last floor
|
||||
if (this.getGame().isOnFinalFloor()) {
|
||||
return this.getGame().settle(rsp, true);
|
||||
}
|
||||
|
||||
// Enter next room
|
||||
this.getGame().enterNextRoom();
|
||||
this.getGame().getRoom().setMapInfo(proto);
|
||||
|
||||
// Set room proto
|
||||
rsp.getMutableEnterResp()
|
||||
.setRoom(this.getRoom().toProto());
|
||||
|
||||
// Done
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
@Override
|
||||
public void encodeProto(StarTowerRoomCase proto) {
|
||||
proto.getMutableDoorCase()
|
||||
.setFloor(this.getFloorNum())
|
||||
.setType(this.getRoomType());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package emu.nebula.game.tower.cases;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import emu.nebula.GameConstants;
|
||||
import emu.nebula.game.tower.StarTowerShopGoods;
|
||||
import emu.nebula.proto.PublicStarTower.HawkerGoods;
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class StarTowerHawkerCase extends StarTowerBaseCase {
|
||||
private Map<Integer, StarTowerShopGoods> goods;
|
||||
|
||||
public StarTowerHawkerCase() {
|
||||
this.goods = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseType getType() {
|
||||
return CaseType.Hawker;
|
||||
}
|
||||
|
||||
public void addGoods(StarTowerShopGoods goods) {
|
||||
this.getGoods().put(getGoods().size() + 1, goods);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
// Set nil resp
|
||||
rsp.getMutableNilResp();
|
||||
|
||||
// Get goods
|
||||
var goods = this.getGoods().get(req.getHawkerReq().getSid());
|
||||
|
||||
// Make sure we have enough currency
|
||||
int gold = this.getGame().getRes().get(GameConstants.STAR_TOWER_GOLD_ITEM_ID);
|
||||
if (gold < goods.getPrice() || goods.isSold()) {
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Mark goods as sold
|
||||
goods.markAsSold();
|
||||
|
||||
// Add case
|
||||
this.getGame().addCase(rsp.getMutableCases(), this.getGame().createPotentialSelector());
|
||||
|
||||
// Remove items
|
||||
var change = this.getGame().addItem(GameConstants.STAR_TOWER_GOLD_ITEM_ID, -goods.getPrice(), null);
|
||||
|
||||
// Set change info
|
||||
rsp.setChange(change.toProto());
|
||||
|
||||
// Success
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
@Override
|
||||
public void encodeProto(StarTowerRoomCase proto) {
|
||||
var hawker = proto.getMutableHawkerCase();
|
||||
|
||||
for (var entry : this.getGoods().entrySet()) {
|
||||
var sid = entry.getKey();
|
||||
var goods = entry.getValue();
|
||||
|
||||
var info = HawkerGoods.newInstance()
|
||||
.setIdx(goods.getGoodsId())
|
||||
.setSid(sid)
|
||||
.setType(goods.getType())
|
||||
.setGoodsId(102) // ?
|
||||
.setPrice(goods.getPrice())
|
||||
.setTag(1);
|
||||
|
||||
hawker.addList(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package emu.nebula.game.tower.cases;
|
||||
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class StarTowerNpcEventCase extends StarTowerBaseCase {
|
||||
private int npcId;
|
||||
private int eventId;
|
||||
private IntList options;
|
||||
|
||||
public StarTowerNpcEventCase(int npcId, int eventId) {
|
||||
this.npcId = npcId;
|
||||
this.eventId = eventId;
|
||||
this.options = new IntArrayList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseType getType() {
|
||||
return CaseType.NpcEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
@Override
|
||||
public void encodeProto(StarTowerRoomCase proto) {
|
||||
proto.getMutableSelectOptionsEventCase()
|
||||
.setEvtId(this.getEventId())
|
||||
.setNPCId(this.getNpcId())
|
||||
.addAllOptions(this.getOptions().toIntArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package emu.nebula.game.tower.cases;
|
||||
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class StarTowerNpcRecoveryHPCase extends StarTowerBaseCase {
|
||||
private int effectId;
|
||||
|
||||
public StarTowerNpcRecoveryHPCase() {
|
||||
this(989970); // Restore Hp/Energy by 50%
|
||||
}
|
||||
|
||||
public StarTowerNpcRecoveryHPCase(int effectId) {
|
||||
this.effectId = effectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseType getType() {
|
||||
return CaseType.NpcRecoveryHP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
@Override
|
||||
public void encodeProto(StarTowerRoomCase proto) {
|
||||
// Set case info
|
||||
proto.getMutableNpcRecoveryHPCase()
|
||||
.setEffectId(this.getEffectId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package emu.nebula.game.tower.cases;
|
||||
|
||||
import emu.nebula.game.tower.room.StarTowerBattleRoom;
|
||||
import emu.nebula.proto.PublicStarTower.PotentialInfo;
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class StarTowerPotentialCase extends StarTowerBaseCase {
|
||||
private int teamLevel;
|
||||
private IntList potentialIds;
|
||||
|
||||
public StarTowerPotentialCase(int teamLevel, IntList potentialIds) {
|
||||
this.teamLevel = teamLevel;
|
||||
this.potentialIds = potentialIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaseType getType() {
|
||||
return CaseType.PotentialSelect;
|
||||
}
|
||||
|
||||
public int selectId(int index) {
|
||||
if (this.getPotentialIds() == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= this.getPotentialIds().size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this.getPotentialIds().getInt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
var index = req.getMutableSelectReq().getIndex();
|
||||
|
||||
int id = this.selectId(index);
|
||||
if (id <= 0) {
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Add item
|
||||
var change = this.getGame().addItem(id, 1, null);
|
||||
|
||||
// Set change
|
||||
rsp.setChange(change.toProto());
|
||||
|
||||
// Handle pending potential selectors
|
||||
var potentialCase = this.getGame().handlePendingPotentialSelectors();
|
||||
if (potentialCase != null) {
|
||||
// Create potential selector
|
||||
this.getGame().addCase(rsp.getMutableCases(), potentialCase);
|
||||
} else if (!this.getRoom().hasDoor()) {
|
||||
// Add door case here if door hasn't opened yet
|
||||
this.getGame().createExit(rsp.getMutableCases());
|
||||
// Create recovery npc
|
||||
if (this.getRoom() instanceof StarTowerBattleRoom) {
|
||||
this.getRoom().addCase(rsp.getMutableCases(), new StarTowerNpcRecoveryHPCase());
|
||||
}
|
||||
}
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
@Override
|
||||
public void encodeProto(StarTowerRoomCase proto) {
|
||||
var select = proto.getMutableSelectPotentialCase()
|
||||
.setTeamLevel(this.getTeamLevel());
|
||||
|
||||
for (int id : this.getPotentialIds()) {
|
||||
var info = PotentialInfo.newInstance()
|
||||
.setTid(id)
|
||||
.setLevel(1);
|
||||
|
||||
select.addInfos(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package emu.nebula.game.tower.cases;
|
||||
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class StarTowerRecoveryHPCase extends StarTowerBaseCase {
|
||||
|
||||
@Override
|
||||
public CaseType getType() {
|
||||
return CaseType.RecoveryHP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
// Set nil resp
|
||||
rsp.getMutableNilResp();
|
||||
|
||||
// Add sync hp case
|
||||
this.getGame().addCase(rsp.getMutableCases(), new StarTowerSyncHPCase());
|
||||
|
||||
// Return
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
@Override
|
||||
public void encodeProto(StarTowerRoomCase proto) {
|
||||
// Set field in the proto
|
||||
proto.getMutableRecoveryHPCase();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package emu.nebula.game.tower.cases;
|
||||
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq;
|
||||
import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class StarTowerSyncHPCase extends StarTowerBaseCase {
|
||||
|
||||
@Override
|
||||
public CaseType getType() {
|
||||
return CaseType.SyncHP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) {
|
||||
return rsp;
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
@Override
|
||||
public void encodeProto(StarTowerRoomCase proto) {
|
||||
// Set field in the proto
|
||||
proto.getMutableSyncHPCase();
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
package emu.nebula.game.tower;
|
||||
package emu.nebula.game.tower.room;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
|
||||
public enum StarTowerRoomType {
|
||||
public enum RoomType {
|
||||
BattleRoom (0),
|
||||
EliteBattleRoom (1),
|
||||
BossRoom (2),
|
||||
@@ -17,19 +17,19 @@ public enum StarTowerRoomType {
|
||||
|
||||
@Getter
|
||||
private final int value;
|
||||
private final static Int2ObjectMap<StarTowerRoomType> map = new Int2ObjectOpenHashMap<>();
|
||||
private final static Int2ObjectMap<RoomType> map = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
static {
|
||||
for (StarTowerRoomType type : StarTowerRoomType.values()) {
|
||||
for (RoomType type : RoomType.values()) {
|
||||
map.put(type.getValue(), type);
|
||||
}
|
||||
}
|
||||
|
||||
private StarTowerRoomType(int value) {
|
||||
private RoomType(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static StarTowerRoomType getByValue(int value) {
|
||||
public static RoomType getByValue(int value) {
|
||||
return map.get(value);
|
||||
}
|
||||
}
|
||||
145
src/main/java/emu/nebula/game/tower/room/StarTowerBaseRoom.java
Normal file
145
src/main/java/emu/nebula/game/tower/room/StarTowerBaseRoom.java
Normal file
@@ -0,0 +1,145 @@
|
||||
package emu.nebula.game.tower.room;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import emu.nebula.data.resources.StarTowerStageDef;
|
||||
import emu.nebula.game.tower.StarTowerGame;
|
||||
import emu.nebula.game.tower.cases.CaseType;
|
||||
import emu.nebula.game.tower.cases.StarTowerBaseCase;
|
||||
import emu.nebula.game.tower.cases.StarTowerSyncHPCase;
|
||||
import emu.nebula.proto.PublicStarTower.InteractEnterReq;
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomCase;
|
||||
import emu.nebula.proto.PublicStarTower.StarTowerRoomData;
|
||||
import emu.nebula.proto.StarTowerApply.StarTowerApplyReq;
|
||||
import lombok.Getter;
|
||||
import us.hebi.quickbuf.RepeatedMessage;
|
||||
|
||||
@Getter
|
||||
public class StarTowerBaseRoom {
|
||||
// Game
|
||||
private transient StarTowerGame game;
|
||||
private transient StarTowerStageDef stage;
|
||||
|
||||
// Map info
|
||||
private int mapId;
|
||||
private int mapTableId;
|
||||
private String mapParam;
|
||||
private int paramId;
|
||||
|
||||
// Cases
|
||||
private int lastCaseId = 0;
|
||||
private List<StarTowerBaseCase> cases;
|
||||
|
||||
// Misc
|
||||
private boolean hasDoor;
|
||||
|
||||
public StarTowerBaseRoom(StarTowerGame game, StarTowerStageDef stage) {
|
||||
this.game = game;
|
||||
this.stage = stage;
|
||||
this.cases = new ArrayList<>();
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return stage.getRoomType();
|
||||
}
|
||||
|
||||
public boolean hasDoor() {
|
||||
return this.hasDoor;
|
||||
}
|
||||
|
||||
// Map info
|
||||
|
||||
public void setMapInfo(StarTowerApplyReq req) {
|
||||
this.mapId = req.getMapId();
|
||||
this.mapTableId = req.getMapTableId();
|
||||
this.mapParam = req.getMapParam();
|
||||
this.paramId = req.getParamId();
|
||||
}
|
||||
|
||||
public void setMapInfo(InteractEnterReq req) {
|
||||
this.mapId = req.getMapId();
|
||||
this.mapTableId = req.getMapTableId();
|
||||
this.mapParam = req.getMapParam();
|
||||
this.paramId = req.getParamId();
|
||||
}
|
||||
|
||||
// Cases
|
||||
|
||||
public int getNextCaseId() {
|
||||
return ++this.lastCaseId;
|
||||
}
|
||||
|
||||
public StarTowerBaseCase getCase(int id) {
|
||||
return this.getCases().stream()
|
||||
.filter(c -> c.getId() == id)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public StarTowerBaseCase addCase(StarTowerBaseCase towerCase) {
|
||||
return this.addCase(null, towerCase);
|
||||
}
|
||||
|
||||
public StarTowerBaseCase addCase(RepeatedMessage<StarTowerRoomCase> cases, StarTowerBaseCase towerCase) {
|
||||
// Add to cases list
|
||||
this.getCases().add(towerCase);
|
||||
|
||||
// Set game for tower case
|
||||
towerCase.register(this);
|
||||
|
||||
// Add case to proto
|
||||
if (cases != null) {
|
||||
cases.add(towerCase.toProto());
|
||||
}
|
||||
|
||||
// Check if door case
|
||||
if (towerCase.getType() == CaseType.OpenDoor) {
|
||||
this.hasDoor = true;
|
||||
}
|
||||
|
||||
// Complete
|
||||
return towerCase;
|
||||
}
|
||||
|
||||
// Events
|
||||
|
||||
public void onEnter() {
|
||||
// Create door case
|
||||
this.getGame().createExit();
|
||||
|
||||
// Create sync hp case
|
||||
this.getGame().addCase(new StarTowerSyncHPCase());
|
||||
}
|
||||
|
||||
// Proto
|
||||
|
||||
public emu.nebula.proto.PublicStarTower.StarTowerRoom toProto() {
|
||||
var proto = emu.nebula.proto.PublicStarTower.StarTowerRoom.newInstance()
|
||||
.setData(this.getDataProto());
|
||||
|
||||
for (var towerCase : this.getCases()) {
|
||||
proto.addCases(towerCase.toProto());
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
private StarTowerRoomData getDataProto() {
|
||||
var proto = StarTowerRoomData.newInstance()
|
||||
.setFloor(this.getGame().getFloorCount())
|
||||
.setMapId(this.getMapId())
|
||||
.setRoomType(this.getType())
|
||||
.setMapTableId(this.getMapTableId());
|
||||
|
||||
if (this.getMapParam() != null && !this.getMapParam().isEmpty()) {
|
||||
proto.setMapParam(this.getMapParam());
|
||||
}
|
||||
|
||||
if (this.getParamId() != 0) {
|
||||
proto.setParamId(this.getParamId());
|
||||
}
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package emu.nebula.game.tower.room;
|
||||
|
||||
import emu.nebula.data.resources.StarTowerStageDef;
|
||||
import emu.nebula.game.tower.StarTowerGame;
|
||||
import emu.nebula.game.tower.cases.StarTowerBattleCase;
|
||||
import emu.nebula.game.tower.cases.StarTowerSyncHPCase;
|
||||
import emu.nebula.util.Utils;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class StarTowerBattleRoom extends StarTowerBaseRoom {
|
||||
|
||||
public StarTowerBattleRoom(StarTowerGame game, StarTowerStageDef stage) {
|
||||
super(game, stage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnter() {
|
||||
// Create battle case
|
||||
this.getGame().setPendingSubNotes(Utils.randomRange(1, 3));
|
||||
this.getGame().addCase(new StarTowerBattleCase(this.getGame().getPendingSubNotes()));
|
||||
|
||||
// Create sync hp case
|
||||
this.getGame().addCase(new StarTowerSyncHPCase());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package emu.nebula.game.tower.room;
|
||||
|
||||
import emu.nebula.data.resources.StarTowerStageDef;
|
||||
import emu.nebula.game.tower.StarTowerGame;
|
||||
import emu.nebula.game.tower.cases.StarTowerSyncHPCase;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class StarTowerEventRoom extends StarTowerBaseRoom {
|
||||
|
||||
public StarTowerEventRoom(StarTowerGame game, StarTowerStageDef stage) {
|
||||
super(game, stage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnter() {
|
||||
// Create door case
|
||||
this.getGame().createExit();
|
||||
|
||||
// Create sync hp case
|
||||
this.getGame().addCase(new StarTowerSyncHPCase());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package emu.nebula.game.tower.room;
|
||||
|
||||
import emu.nebula.data.resources.StarTowerStageDef;
|
||||
import emu.nebula.game.tower.StarTowerGame;
|
||||
import emu.nebula.game.tower.StarTowerShopGoods;
|
||||
import emu.nebula.game.tower.cases.StarTowerHawkerCase;
|
||||
import emu.nebula.game.tower.cases.StarTowerSyncHPCase;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class StarTowerHawkerRoom extends StarTowerBaseRoom {
|
||||
|
||||
public StarTowerHawkerRoom(StarTowerGame game, StarTowerStageDef stage) {
|
||||
super(game, stage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnter() {
|
||||
// Create hawker case
|
||||
var hawker = new StarTowerHawkerCase();
|
||||
|
||||
// TODO
|
||||
for (int i = 0; i < 8; i++) {
|
||||
hawker.addGoods(new StarTowerShopGoods(1, 1, 200));
|
||||
}
|
||||
|
||||
this.getGame().addCase(hawker);
|
||||
|
||||
// Create door case
|
||||
this.getGame().createExit();
|
||||
|
||||
// Create sync hp case
|
||||
this.getGame().addCase(new StarTowerSyncHPCase());
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ public class HandlerStarTowerGiveUpReq extends NetHandler {
|
||||
// Build response
|
||||
var rsp = StarTowerGiveUpResp.newInstance()
|
||||
.setBuild(game.getBuild().toProto())
|
||||
.setFloor(game.getFloor());
|
||||
.setFloor(game.getFloorCount());
|
||||
|
||||
rsp.getMutableChange();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user