From 080d3459810b3931e14145f151d02dd0d3310c93 Mon Sep 17 00:00:00 2001 From: Melledy <121644117+Melledy@users.noreply.github.com> Date: Tue, 11 Nov 2025 05:16:47 -0800 Subject: [PATCH] Implement character showcase --- .../java/emu/nebula/game/player/Player.java | 54 +++++++++++++++++++ .../handlers/HandlerPlayerCharsShowReq.java | 24 +++++++++ 2 files changed, 78 insertions(+) create mode 100644 src/main/java/emu/nebula/server/handlers/HandlerPlayerCharsShowReq.java diff --git a/src/main/java/emu/nebula/game/player/Player.java b/src/main/java/emu/nebula/game/player/Player.java index babc48b..a121aa0 100644 --- a/src/main/java/emu/nebula/game/player/Player.java +++ b/src/main/java/emu/nebula/game/player/Player.java @@ -30,6 +30,7 @@ import emu.nebula.net.NetMsgPacket; import emu.nebula.proto.PlayerData.DictionaryEntry; import emu.nebula.proto.PlayerData.DictionaryTab; import emu.nebula.proto.PlayerData.PlayerInfo; +import emu.nebula.proto.Public.CharShow; import emu.nebula.proto.Public.Energy; import emu.nebula.proto.Public.NewbieInfo; import emu.nebula.proto.Public.QuestType; @@ -61,6 +62,7 @@ public class Player implements GameDatabaseObject { private int titleSuffix; private int level; private int exp; + private int[] showChars; private int[] boards; private int energy; @@ -127,6 +129,7 @@ public class Player implements GameDatabaseObject { this.level = 1; this.energy = 240; this.energyLastUpdate = this.createTime; + this.showChars = new int[3]; this.boards = new int[] {410301}; // Setup inventory @@ -265,6 +268,36 @@ public class Player implements GameDatabaseObject { return true; } + public boolean setShowChars(RepeatedInt charIds) { + // Sanity check + if (charIds.length() > this.getShowChars().length) { + return false; + } + + // Verify that we have the correct characters + for (int id : charIds) { + if (id != 0 && !this.getCharacters().hasCharacter(id)) { + return false; + } + } + + // Clear + this.showChars[0] = 0; + this.showChars[1] = 0; + this.showChars[2] = 0; + + // Set + for (int i = 0; i < charIds.length(); i++) { + this.showChars[i] = charIds.get(i); + } + + // Update in database + Nebula.getGameDatabase().update(this, this.getUid(), "showChars", this.getShowChars()); + + // Success + return true; + } + public boolean setBoard(RepeatedInt ids) { // Length check if (ids.length() <= 0 || ids.length() > GameConstants.MAX_SHOWCASE_IDS) { @@ -499,6 +532,12 @@ public class Player implements GameDatabaseObject { this.progress = this.loadManagerFromDatabase(PlayerProgress.class); this.storyManager = this.loadManagerFromDatabase(StoryManager.class); this.questManager = this.loadManagerFromDatabase(QuestManager.class); + + // Database fixes + if (this.showChars == null) { + this.showChars = new int[3]; + this.save(); + } } public void onLogin() { @@ -538,6 +577,21 @@ public class Player implements GameDatabaseObject { .setTitleSuffix(this.getTitleSuffix()) .setCreateTime(this.getCreateTime()); + // Set showcase character + for (int charId : this.getShowChars()) { + var info = CharShow.newInstance(); + var character = this.getCharacters().getCharacterById(charId); + + if (character != null) { + info.setCharId(character.getCharId()) + .setLevel(character.getLevel()) + .setSkin(character.getSkin()); + } + + acc.addChars(info); + } + + // Set world class proto.getMutableWorldClass() .setCur(this.getLevel()) .setLastExp(this.getExp()); diff --git a/src/main/java/emu/nebula/server/handlers/HandlerPlayerCharsShowReq.java b/src/main/java/emu/nebula/server/handlers/HandlerPlayerCharsShowReq.java new file mode 100644 index 0000000..febf179 --- /dev/null +++ b/src/main/java/emu/nebula/server/handlers/HandlerPlayerCharsShowReq.java @@ -0,0 +1,24 @@ +package emu.nebula.server.handlers; + +import emu.nebula.net.NetHandler; +import emu.nebula.net.NetMsgId; +import emu.nebula.proto.PlayerCharsShow.PlayerCharsShowReq; +import emu.nebula.net.HandlerId; +import emu.nebula.net.GameSession; + +@HandlerId(NetMsgId.player_chars_show_req) +public class HandlerPlayerCharsShowReq extends NetHandler { + + @Override + public byte[] handle(GameSession session, byte[] message) throws Exception { + // Parse req + var req = PlayerCharsShowReq.parseFrom(message); + + // Set + boolean success = session.getPlayer().setShowChars(req.getCharIds()); + + // Encode and send + return session.encodeMsg(success ? NetMsgId.player_chars_show_succeed_ack : NetMsgId.player_chars_show_failed_ack); + } + +}