diff --git a/src/main/java/emu/nebula/GameConstants.java b/src/main/java/emu/nebula/GameConstants.java index 7884c29..30ccce3 100644 --- a/src/main/java/emu/nebula/GameConstants.java +++ b/src/main/java/emu/nebula/GameConstants.java @@ -49,6 +49,7 @@ public class GameConstants { public static final int MAX_SHOWCASE_IDS = 5; public static final int MAX_BUILDS = 100; public static final int MAX_PRESETS = 50; + public static final int MAX_VITA_PROJECTS = 5; public static final int MAX_FRIENDSHIPS = 50; public static final int MAX_PENDING_FRIENDSHIPS = 30; @@ -62,6 +63,14 @@ public class GameConstants { public static final int[] TOWER_EVENTS_IDS = new int[] { 101, 102, 104, 105, 106, 107, 108, 114, 115, 116, 126, 127, 128 }; + + // Star Tower Vita (auto decision) + public static final int VITA_ENERGY_ITEM_ID = 42; + public static final int VITA_ENERGY_MAX = 10_000; + public static final int VITA_ENERGY_PURCHASE_CURRENCY_ID = STELLANITE_DUST_ITEM_ID; + public static final int VITA_ENERGY_PURCHASE_PRICE = 10; + public static final int VITA_ENERGY_PURCHASE_VALUE = 3_000; + public static final int VITA_ENERGY_COST = 15; // Trace Hunt public static final int TRACE_HUNT_TOKEN_ID = 37; diff --git a/src/main/java/emu/nebula/data/GameData.java b/src/main/java/emu/nebula/data/GameData.java index 080b39e..ee2e6f0 100644 --- a/src/main/java/emu/nebula/data/GameData.java +++ b/src/main/java/emu/nebula/data/GameData.java @@ -120,6 +120,7 @@ public class GameData { @Getter private static DataTable StarTowerQuestDataTable = new DataTable<>(); @Getter private static DataTable StarTowerBuildRankDataTable = new DataTable<>(); @Getter private static DataTable StarTowerBookPotentialRewardDataTable = new DataTable<>(); + @Getter private static DataTable TowerVitaOptionDataTable = new DataTable<>(); @Getter private static DataTable SubNoteSkillPromoteGroupDataTable = new DataTable<>(); @Getter private static DataTable PotentialDataTable = new DataTable<>(); diff --git a/src/main/java/emu/nebula/data/resources/TowerVitaOptionDef.java b/src/main/java/emu/nebula/data/resources/TowerVitaOptionDef.java new file mode 100644 index 0000000..e8b228e --- /dev/null +++ b/src/main/java/emu/nebula/data/resources/TowerVitaOptionDef.java @@ -0,0 +1,33 @@ +package emu.nebula.data.resources; + +import emu.nebula.data.BaseDef; +import emu.nebula.data.ResourceType; +import lombok.Getter; + +@Getter +@ResourceType(name = "TowerVitaOption.json") +public class TowerVitaOptionDef extends BaseDef { + private int Id; + private int Categories; + private int Sort; + private int OptionType; + private int OptionGroup; + private String DefaultValue; + + @Override + public int getId() { + return Id; + } + + public boolean isSwitch() { + return this.OptionType == 1; + } + + public boolean isInteger() { + return this.OptionType >= 2 && this.OptionType <= 4; + } + + public boolean isList() { + return this.OptionType == 5; + } +} diff --git a/src/main/java/emu/nebula/game/inventory/Inventory.java b/src/main/java/emu/nebula/game/inventory/Inventory.java index c63d8e6..6f0b3a7 100644 --- a/src/main/java/emu/nebula/game/inventory/Inventory.java +++ b/src/main/java/emu/nebula/game/inventory/Inventory.java @@ -366,10 +366,19 @@ public class Inventory extends PlayerManager implements GameDatabaseObject { if (amount > 0) { // Add resource newAmount = Utils.safeAdd(oldAmount, amount); + + // Limits + if (id == GameConstants.VITA_ENERGY_ITEM_ID) { + newAmount = Math.min(newAmount, GameConstants.VITA_ENERGY_MAX); + } + + // Get diff diff = newAmount - oldAmount; // Set - this.resources.put(id, newAmount); + if (diff != 0) { + this.resources.put(id, newAmount); + } } else { // Remove resource newAmount = Utils.safeSubtract(oldAmount, Math.abs(amount)); diff --git a/src/main/java/emu/nebula/game/player/PlayerProgress.java b/src/main/java/emu/nebula/game/player/PlayerProgress.java index ecb9320..26eb189 100644 --- a/src/main/java/emu/nebula/game/player/PlayerProgress.java +++ b/src/main/java/emu/nebula/game/player/PlayerProgress.java @@ -10,6 +10,7 @@ import emu.nebula.Nebula; import emu.nebula.data.GameData; import emu.nebula.data.resources.InfinityTowerLevelDef; import emu.nebula.database.GameDatabaseObject; +import emu.nebula.game.tower.StarTowerVitaData; import emu.nebula.game.tutorial.TutorialLevelLog; import emu.nebula.game.vampire.VampireSurvivorLog; import emu.nebula.proto.PlayerData.PlayerInfo; @@ -36,6 +37,7 @@ public class PlayerProgress extends PlayerManager implements GameDatabaseObject private IntSet starTowerLog; private int[] starTowerGrowth; private int towerTickets; + private StarTowerVitaData towerVitaData; // Instances private Int2IntMap dailyInstanceLog; @@ -91,6 +93,9 @@ public class PlayerProgress extends PlayerManager implements GameDatabaseObject // Tutorials this.tutorialLog = new HashMap<>(); + // Star Tower Vita + this.towerVitaData = new StarTowerVitaData(this); + // Save to database this.save(); } @@ -328,6 +333,14 @@ public class PlayerProgress extends PlayerManager implements GameDatabaseObject shouldSave = true; } + // Set star tower vita data + if (this.towerVitaData == null) { + this.towerVitaData = new StarTowerVitaData(this); + shouldSave = true; + } else { + this.towerVitaData.setPlayerProgress(this); + } + // Carry over infinity tower progress if (this.infinityArenaLog != null) { for (int levelId : this.infinityArenaLog.values()) { diff --git a/src/main/java/emu/nebula/game/tower/StarTowerManager.java b/src/main/java/emu/nebula/game/tower/StarTowerManager.java index d661902..8d40a30 100644 --- a/src/main/java/emu/nebula/game/tower/StarTowerManager.java +++ b/src/main/java/emu/nebula/game/tower/StarTowerManager.java @@ -1,6 +1,8 @@ package emu.nebula.game.tower; +import java.util.Comparator; import java.util.HashSet; +import java.util.List; import emu.nebula.GameConstants; import emu.nebula.Nebula; @@ -13,6 +15,7 @@ import emu.nebula.game.player.PlayerChangeInfo; import emu.nebula.game.player.PlayerManager; import emu.nebula.game.player.PlayerProgress; import emu.nebula.game.quest.QuestCondition; +import emu.nebula.proto.Public.TowerVitaProject; import emu.nebula.proto.PublicStarTower.StarTowerBookCharPotential; import emu.nebula.proto.StarTowerApply.StarTowerApplyReq; @@ -375,6 +378,96 @@ public class StarTowerManager extends PlayerManager { return true; } + // Vita projects (auto decision plans) + + public StarTowerVitaData getVitaData() { + return this.getProgress().getTowerVitaData(); + } + + public List getVitaProjects() { + return this.getVitaData().getProjects().values().stream() + .sorted(Comparator.comparingInt(StarTowerVitaProject::getId)) + .toList(); + } + + public StarTowerVitaProject getVitaProject(int id) { + return this.getVitaData().getProject(id); + } + + public StarTowerVitaProject updateVitaProject(TowerVitaProject proto) { + // Sanity check + if (proto == null || proto.getId() < 1 || proto.getId() > GameConstants.MAX_VITA_PROJECTS) { + return null; + } + + // Get or create the project + var data = this.getVitaData(); + var project = data.getProject(proto.getId()); + + if (project == null) { + project = new StarTowerVitaProject(proto.getId()); + } + + // Update name + if (proto.hasName()) { + project.setName(proto.getName()); + } + + // The client only sends options that differ from the defaults, so replace the whole list + project.getOptions().clear(); + + for (var optionProto : proto.getOptions()) { + var option = StarTowerVitaOption.fromProto(optionProto); + + if (option != null) { + project.putOption(option); + } + } + + // Save project to database + data.putProject(project); + + // Success + return project; + } + + public StarTowerVitaProject renameVitaProject(int id, String name) { + // Sanity check + if (id < 1 || id > GameConstants.MAX_VITA_PROJECTS) { + return null; + } + + // Get or create the project + var data = this.getVitaData(); + var project = data.getProject(id); + + if (project == null) { + project = new StarTowerVitaProject(id); + } + + // Update name + project.setName(name); + + // Save project to database + data.putProject(project); + + // Success + return project; + } + + public boolean selectVitaProject(int id) { + // Sanity check + if (id < 1 || id > GameConstants.MAX_VITA_PROJECTS) { + return false; + } + + // Save selection to database + this.getVitaData().setSelectedProjectId(id); + + // Success + return true; + } + // Game public PlayerChangeInfo apply(StarTowerApplyReq req) { diff --git a/src/main/java/emu/nebula/game/tower/StarTowerVitaData.java b/src/main/java/emu/nebula/game/tower/StarTowerVitaData.java new file mode 100644 index 0000000..4d23cf6 --- /dev/null +++ b/src/main/java/emu/nebula/game/tower/StarTowerVitaData.java @@ -0,0 +1,134 @@ +package emu.nebula.game.tower; + +import java.util.HashMap; +import java.util.Map; + +import dev.morphia.annotations.Entity; +import emu.nebula.GameConstants; +import emu.nebula.Nebula; +import emu.nebula.game.player.PlayerChangeInfo; +import emu.nebula.game.player.PlayerProgress; +import lombok.Getter; + +@Getter +@Entity(useDiscriminator = false) +public class StarTowerVitaData { + private int selectedProjectId; + private Map projects; + + private transient PlayerProgress progress; + + @Deprecated // Morphia only + public StarTowerVitaData() { + + } + + public StarTowerVitaData(PlayerProgress progress) { + this.setPlayerProgress(progress); + this.selectedProjectId = 1; + this.projects = new HashMap<>(); + } + + public void setPlayerProgress(PlayerProgress progress) { + this.progress = progress; + } + + public StarTowerVitaProject getProject(int id) { + return this.getProjects().get(id); + } + + public void putProject(StarTowerVitaProject project) { + this.getProjects().put(project.getId(), project); + + // Save projects to the progress document + this.save("projects." + project.getId(), project); + } + + public int getSelectedProjectId() { + return this.selectedProjectId > 0 ? this.selectedProjectId : 1; + } + + public void setSelectedProjectId(int id) { + this.selectedProjectId = id; + + // Save selection to the progress document + this.save("selectedProjectId", id); + } + + // Vita energy + + public int getEnergy() { + if (this.progress == null) { + return 0; + } + + return this.progress.getPlayer().getInventory().getResourceCount(GameConstants.VITA_ENERGY_ITEM_ID); + } + + public int addEnergy(int amount, PlayerChangeInfo change) { + // Sanity check + if (amount <= 0 || this.progress == null) { + return 0; + } + + // Clamp to the energy cap + int gain = Math.min(amount, GameConstants.VITA_ENERGY_MAX - this.getEnergy()); + + if (gain <= 0) { + return 0; + } + + // Add energy + this.progress.getPlayer().getInventory().addItem(GameConstants.VITA_ENERGY_ITEM_ID, gain, change); + + // Return gained amount + return gain; + } + + public PlayerChangeInfo buyEnergy(int count) { + // Sanity check + if (count <= 0) { + return null; + } + + var inventory = this.getProgress().getPlayer().getInventory(); + + // Calculate cost + int cost = GameConstants.VITA_ENERGY_PURCHASE_PRICE * count; + + // Make sure we have enough currency + if (!inventory.hasItem(GameConstants.VITA_ENERGY_PURCHASE_CURRENCY_ID, cost)) { + return null; + } + + // Nothing to gain if we are already at the cap + if (this.getEnergy() >= GameConstants.VITA_ENERGY_MAX) { + return null; + } + + // Buy energy + var change = inventory.removeItem(GameConstants.VITA_ENERGY_PURCHASE_CURRENCY_ID, cost); + + // Add energy that we bought (addEnergy caps the amount at the max) + int amount = GameConstants.VITA_ENERGY_PURCHASE_VALUE * count; + inventory.addItem(GameConstants.VITA_ENERGY_ITEM_ID, amount, change); + + // Success + return change.setSuccess(true); + } + + // Database + + private void save(String field, Object value) { + if (this.progress == null) { + return; + } + + Nebula.getGameDatabase().update( + this.progress, + this.progress.getUid(), + "towerVitaData." + field, + value + ); + } +} diff --git a/src/main/java/emu/nebula/game/tower/StarTowerVitaOption.java b/src/main/java/emu/nebula/game/tower/StarTowerVitaOption.java new file mode 100644 index 0000000..d155606 --- /dev/null +++ b/src/main/java/emu/nebula/game/tower/StarTowerVitaOption.java @@ -0,0 +1,93 @@ +package emu.nebula.game.tower; + +import dev.morphia.annotations.Entity; +import emu.nebula.data.GameData; +import emu.nebula.proto.Public.TowerVitaOption; +import emu.nebula.proto.Public.UI32s; +import lombok.Getter; + +@Getter +@Entity(useDiscriminator = false) +public class StarTowerVitaOption { + private int id; + private int type; + + private Boolean booleanValue; + private Integer integerValue; + private int[] listValues; + + @Deprecated // Morphia only + public StarTowerVitaOption() { + + } + + private StarTowerVitaOption(int id, int type) { + this.id = id; + this.type = type; + } + + public static StarTowerVitaOption fromProto(TowerVitaOption proto) { + // Get option data so we know which value field to read + var data = GameData.getTowerVitaOptionDataTable().get(proto.getId()); + if (data == null) { + return null; + } + + var option = new StarTowerVitaOption(proto.getId(), data.getOptionType()); + + if (data.isSwitch()) { + if (!proto.hasBoolean()) { + return null; + } + + option.booleanValue = proto.getBoolean(); + } else if (data.isInteger()) { + if (!proto.hasInteger()) { + return null; + } + + option.integerValue = proto.getInteger(); + } else if (data.isList()) { + if (!proto.hasList()) { + return null; + } + + option.listValues = proto.getList().getValues().toArray(); + } else { + return null; + } + + return option; + } + + // Proto + + public TowerVitaOption toProto() { + var proto = TowerVitaOption.newInstance() + .setId(this.getId()); + + if (this.getType() == 1) { + if (this.getBooleanValue() == null) { + return null; + } + + proto.setBoolean(this.getBooleanValue()); + } else if (this.getType() >= 2 && this.getType() <= 4) { + if (this.getIntegerValue() == null) { + return null; + } + + proto.setInteger(this.getIntegerValue()); + } else if (this.getType() == 5) { + if (this.getListValues() == null) { + return null; + } + + proto.setList(UI32s.newInstance().addAllValues(this.getListValues())); + } else { + return null; + } + + return proto; + } +} diff --git a/src/main/java/emu/nebula/game/tower/StarTowerVitaProject.java b/src/main/java/emu/nebula/game/tower/StarTowerVitaProject.java new file mode 100644 index 0000000..4181db3 --- /dev/null +++ b/src/main/java/emu/nebula/game/tower/StarTowerVitaProject.java @@ -0,0 +1,64 @@ +package emu.nebula.game.tower; + +import java.util.HashMap; +import java.util.Map; + +import dev.morphia.annotations.Entity; +import emu.nebula.proto.Public.TowerVitaProject; +import lombok.Getter; + +@Getter +@Entity(useDiscriminator = false) +public class StarTowerVitaProject { + private int id; + private String name; + private Map options; + + @Deprecated // Morphia only + public StarTowerVitaProject() { + + } + + public StarTowerVitaProject(int id) { + this.id = id; + this.name = "Exploration Plan" + id; + this.options = new HashMap<>(); + } + + public void setName(String name) { + if (name == null) { + name = ""; + } + + // Clamp name length to prevent long names + if (name.length() > 32) { + name = name.substring(0, 31); + } + + this.name = name; + } + + public Map getOptions() { + return this.options; + } + + public void putOption(StarTowerVitaOption option) { + this.getOptions().put(option.getId(), option); + } + + public TowerVitaProject toProto() { + var proto = TowerVitaProject.newInstance() + .setId(this.getId()) + .setName(this.getName() == null ? "" : this.getName()); + + // Sort option ids so the response is deterministic + this.getOptions().keySet().stream().sorted().forEach(id -> { + var option = this.getOptions().get(id).toProto(); + if (option != null) { + proto.addOptions(option); + } + }); + + return proto; + } +} diff --git a/src/main/java/emu/nebula/game/tower/cases/StarTowerBaseCase.java b/src/main/java/emu/nebula/game/tower/cases/StarTowerBaseCase.java index 4b7900b..db12ebc 100644 --- a/src/main/java/emu/nebula/game/tower/cases/StarTowerBaseCase.java +++ b/src/main/java/emu/nebula/game/tower/cases/StarTowerBaseCase.java @@ -1,5 +1,6 @@ package emu.nebula.game.tower.cases; +import emu.nebula.game.player.Player; import emu.nebula.game.tower.StarTowerGame; import emu.nebula.game.tower.StarTowerModifiers; import emu.nebula.game.tower.room.StarTowerBaseRoom; @@ -20,6 +21,10 @@ public abstract class StarTowerBaseCase { } + public Player getPlayer() { + return this.getGame().getPlayer(); + } + public StarTowerBaseRoom getRoom() { return this.getGame().getRoom(); } diff --git a/src/main/java/emu/nebula/game/tower/cases/StarTowerHawkerCase.java b/src/main/java/emu/nebula/game/tower/cases/StarTowerHawkerCase.java index e7c7e37..a811d09 100644 --- a/src/main/java/emu/nebula/game/tower/cases/StarTowerHawkerCase.java +++ b/src/main/java/emu/nebula/game/tower/cases/StarTowerHawkerCase.java @@ -142,6 +142,12 @@ public class StarTowerHawkerCase extends StarTowerBaseCase { this.buy(hawker.getSid(), rsp); } + // Auto mode consumes vita energy + if (hawker.getAuto()) { + var change = this.getPlayer().getInventory().removeItem(GameConstants.VITA_ENERGY_ITEM_ID, GameConstants.VITA_ENERGY_COST); + rsp.setChange(change.toProto()); + } + // Success return rsp; } diff --git a/src/main/java/emu/nebula/game/tower/cases/StarTowerNpcEventCase.java b/src/main/java/emu/nebula/game/tower/cases/StarTowerNpcEventCase.java index 5cac46f..030205c 100644 --- a/src/main/java/emu/nebula/game/tower/cases/StarTowerNpcEventCase.java +++ b/src/main/java/emu/nebula/game/tower/cases/StarTowerNpcEventCase.java @@ -53,6 +53,11 @@ public class StarTowerNpcEventCase extends StarTowerBaseCase { return CaseType.NpcEvent; } + @Override + public boolean removeAfterInteract() { + return this.completed; + } + public int getOption(int index) { if (index < 0 || index >= this.getOptions().size()) { return 0; @@ -68,15 +73,18 @@ public class StarTowerNpcEventCase extends StarTowerBaseCase { return rsp; } + // Get select request + var select = req.getSelectReq(); + // Get option from selection index - int option = this.getOption(req.getSelectReq().getIndex()); + int option = this.getOption(select.getIndex()); // Get select response proto var selectRsp = rsp.getMutableSelectResp(); var success = selectRsp.getMutableResp(); var change = new PlayerChangeInfo(); - // Completed event flag + // Pre set completed event flag to true boolean completed = true; // Handle option id @@ -248,6 +256,11 @@ public class StarTowerNpcEventCase extends StarTowerBaseCase { } } + // Auto mode consumes vita energy + if (select.getAuto()) { + this.getPlayer().getInventory().removeItem(GameConstants.VITA_ENERGY_ITEM_ID, GameConstants.VITA_ENERGY_COST, change); + } + // Set change info rsp.setChange(change.toProto()); 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 44d388b..8223f50 100644 --- a/src/main/java/emu/nebula/game/tower/cases/StarTowerPotentialCase.java +++ b/src/main/java/emu/nebula/game/tower/cases/StarTowerPotentialCase.java @@ -66,15 +66,15 @@ public class StarTowerPotentialCase extends StarTowerBaseCase { // Handle select option if (select.hasReRoll()) { - this.reroll(rsp); + this.reroll(select.getAuto(), rsp); } else { - this.select(select.getIndex(), rsp); + this.select(select.getIndex(), select.getAuto(), rsp); } return rsp; } - private void reroll(StarTowerInteractResp rsp) { + private void reroll(boolean auto, StarTowerInteractResp rsp) { // Check if we can reroll if (!this.canReroll()) { return; @@ -116,13 +116,19 @@ public class StarTowerPotentialCase extends StarTowerBaseCase { // Subtract coins var change = this.getGame().addItem(GameConstants.TOWER_COIN_ITEM_ID, -price); + // Auto mode consumes vita energy + if (auto) { + this.getPlayer().getInventory().removeItem(GameConstants.VITA_ENERGY_ITEM_ID, GameConstants.VITA_ENERGY_COST, change); + } + + // Set change proto in response rsp.setChange(change.toProto()); // Achievement + Star Tower quests this.getGame().getPlayer().trigger(QuestCondition.TowerSpecificPotentialReRollTotal, 1); } - private void select(int index, StarTowerInteractResp rsp) { + private void select(int index, boolean auto, StarTowerInteractResp rsp) { // Get selected potential var potential = this.selectId(index); if (potential == null) { @@ -135,7 +141,12 @@ public class StarTowerPotentialCase extends StarTowerBaseCase { // Add potential var change = this.getGame().addItem(potential.getId(), potential.getLevel()); - // Set change + // Auto mode consumes vita energy + if (auto) { + this.getPlayer().getInventory().removeItem(GameConstants.VITA_ENERGY_ITEM_ID, GameConstants.VITA_ENERGY_COST, change); + } + + // Set change proto in response rsp.setChange(change.toProto()); // Handle pending potential selectors diff --git a/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaEnergyBuyReq.java b/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaEnergyBuyReq.java new file mode 100644 index 0000000..846490d --- /dev/null +++ b/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaEnergyBuyReq.java @@ -0,0 +1,37 @@ +package emu.nebula.server.handlers; + +import emu.nebula.net.NetHandler; +import emu.nebula.net.NetMsgId; +import emu.nebula.proto.Public.UI32; +import emu.nebula.proto.TowerVitaEnergyBuy.TowerVitaEnergyBuyResp; +import emu.nebula.net.HandlerId; +import emu.nebula.net.GameSession; + +@HandlerId(NetMsgId.tower_vita_energy_buy_req) +public class HandlerTowerVitaEnergyBuyReq extends NetHandler { + + @Override + public byte[] handle(GameSession session, byte[] message) throws Exception { + // Parse request + var req = UI32.parseFrom(message); + + // Get vita data + var data = session.getPlayer().getStarTowerManager().getVitaData(); + + // Buy energy + var change = data.buyEnergy(req.getValue()); + + if (change == null) { + return session.encodeMsg(NetMsgId.tower_vita_energy_buy_failed_ack); + } + + // Build response + var rsp = TowerVitaEnergyBuyResp.newInstance() + .setEnergy(data.getEnergy()) + .setChange(change.toProto()); + + // Encode and send + return session.encodeMsg(NetMsgId.tower_vita_energy_buy_succeed_ack, rsp); + } + +} diff --git a/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectListReq.java b/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectListReq.java index 153c04f..ed537f2 100644 --- a/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectListReq.java +++ b/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectListReq.java @@ -11,9 +11,18 @@ public class HandlerTowerVitaProjectListReq extends NetHandler { @Override public byte[] handle(GameSession session, byte[] message) throws Exception { + // Get manager + var manager = session.getPlayer().getStarTowerManager(); + // Build response - var rsp = TowerVitaProjectListResp.newInstance(); - + var rsp = TowerVitaProjectListResp.newInstance() + .setUseId(manager.getVitaData().getSelectedProjectId()); + + // Add projects + for (var project : manager.getVitaProjects()) { + rsp.addProjects(project.toProto()); + } + // Encode and send return session.encodeMsg(NetMsgId.tower_vita_project_list_succeed_ack, rsp); } diff --git a/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectNameUpdateReq.java b/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectNameUpdateReq.java new file mode 100644 index 0000000..39b0d6b --- /dev/null +++ b/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectNameUpdateReq.java @@ -0,0 +1,33 @@ +package emu.nebula.server.handlers; + +import emu.nebula.net.NetHandler; +import emu.nebula.net.NetMsgId; +import emu.nebula.proto.TowerVitaProjectNameUpdate.TowerVitaProjectNameUpdateRep; +import emu.nebula.net.HandlerId; +import emu.nebula.net.GameSession; + +@HandlerId(NetMsgId.tower_vita_project_name_update_req) +public class HandlerTowerVitaProjectNameUpdateReq extends NetHandler { + + @Override + public byte[] handle(GameSession session, byte[] message) throws Exception { + // Parse request + var req = TowerVitaProjectNameUpdateRep.parseFrom(message); + + // Sanity + if (!req.hasId()) { + return session.encodeMsg(NetMsgId.tower_vita_project_name_update_failed_ack); + } + + // Rename project + var project = session.getPlayer().getStarTowerManager().renameVitaProject(req.getId(), req.getName()); + + if (project == null) { + return session.encodeMsg(NetMsgId.tower_vita_project_name_update_failed_ack); + } + + // Encode and send + return session.encodeMsg(NetMsgId.tower_vita_project_name_update_succeed_ack); + } + +} diff --git a/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectSetReq.java b/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectSetReq.java new file mode 100644 index 0000000..e6ac324 --- /dev/null +++ b/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectSetReq.java @@ -0,0 +1,26 @@ +package emu.nebula.server.handlers; + +import emu.nebula.net.NetHandler; +import emu.nebula.net.NetMsgId; +import emu.nebula.proto.TowerVitaProjectSet.TowerVitaProjectSetRep; +import emu.nebula.net.HandlerId; +import emu.nebula.net.GameSession; + +@HandlerId(NetMsgId.tower_vita_project_set_req) +public class HandlerTowerVitaProjectSetReq extends NetHandler { + + @Override + public byte[] handle(GameSession session, byte[] message) throws Exception { + // Parse request + var req = TowerVitaProjectSetRep.parseFrom(message); + + // Sanity + if (!session.getPlayer().getStarTowerManager().selectVitaProject(req.getId())) { + return session.encodeMsg(NetMsgId.tower_vita_project_set_failed_ack); + } + + // Encode and send + return session.encodeMsg(NetMsgId.tower_vita_project_set_succeed_ack); + } + +} diff --git a/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectUpdateReq.java b/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectUpdateReq.java new file mode 100644 index 0000000..1195bd2 --- /dev/null +++ b/src/main/java/emu/nebula/server/handlers/HandlerTowerVitaProjectUpdateReq.java @@ -0,0 +1,37 @@ +package emu.nebula.server.handlers; + +import emu.nebula.net.NetHandler; +import emu.nebula.net.NetMsgId; +import emu.nebula.proto.TowerVitaProjectUpdate.TowerVitaProjectUpdateRep; +import emu.nebula.net.HandlerId; +import emu.nebula.net.GameSession; + +@HandlerId(NetMsgId.tower_vita_project_update_req) +public class HandlerTowerVitaProjectUpdateReq extends NetHandler { + + @Override + public byte[] handle(GameSession session, byte[] message) throws Exception { + // Parse request + var req = TowerVitaProjectUpdateRep.parseFrom(message); + + // Sanity + if (!req.hasProjects()) { + return session.encodeMsg(NetMsgId.tower_vita_project_update_failed_ack); + } + + // Update project + var project = session.getPlayer().getStarTowerManager().updateVitaProject(req.getProjects()); + + if (project == null) { + return session.encodeMsg(NetMsgId.tower_vita_project_update_failed_ack); + } + + // Build response + var rsp = TowerVitaProjectUpdateRep.newInstance() + .setProjects(project.toProto()); + + // Encode and send + return session.encodeMsg(NetMsgId.tower_vita_project_update_succeed_ack, rsp); + } + +}