diff --git a/src/main/java/emu/nebula/data/GameData.java b/src/main/java/emu/nebula/data/GameData.java index d4aa271..ef4841d 100644 --- a/src/main/java/emu/nebula/data/GameData.java +++ b/src/main/java/emu/nebula/data/GameData.java @@ -103,6 +103,7 @@ public class GameData { // Vampire survivor @Getter private static DataTable VampireSurvivorDataTable = new DataTable<>(); + @Getter private static DataTable VampireTalentDataTable = new DataTable<>(); // Score boss @Getter private static DataTable ScoreBossControlDataTable = new DataTable<>(); diff --git a/src/main/java/emu/nebula/data/resources/VampireTalentDef.java b/src/main/java/emu/nebula/data/resources/VampireTalentDef.java new file mode 100644 index 0000000..9e35256 --- /dev/null +++ b/src/main/java/emu/nebula/data/resources/VampireTalentDef.java @@ -0,0 +1,18 @@ +package emu.nebula.data.resources; + +import emu.nebula.data.BaseDef; +import emu.nebula.data.ResourceType; +import lombok.Getter; + +@Getter +@ResourceType(name = "VampireTalent.json") +public class VampireTalentDef extends BaseDef { + private int Id; + private int[] Prev; + private int Point; + + @Override + public int getId() { + return Id; + } +} diff --git a/src/main/java/emu/nebula/game/vampire/VampireSurvivorManager.java b/src/main/java/emu/nebula/game/vampire/VampireSurvivorManager.java index 862cc6d..5db9cce 100644 --- a/src/main/java/emu/nebula/game/vampire/VampireSurvivorManager.java +++ b/src/main/java/emu/nebula/game/vampire/VampireSurvivorManager.java @@ -35,6 +35,74 @@ public class VampireSurvivorManager extends PlayerManager { return this.getProgress().getFateCards().size() * 5; } + public int getUsedTalentPoints() { + int amount = 0; + + for (var talent : GameData.getVampireTalentDataTable()) { + if (this.getTalents().isSet(talent.getId())) { + amount += talent.getPoint(); + } + } + + return amount; + } + + public boolean unlockTalent(int id) { + // Get talent data + var talent = GameData.getVampireTalentDataTable().get(id); + if (talent == null) { + return false; + } + + // Check to make sure talent isnt already set + if (this.getTalents().isSet(talent.getId())) { + return false; + } + + // Make sure any prerequisite talent is set + if (talent.getPrev() != null) { + boolean hasPrev = false; + + for (int prevTalent : talent.getPrev()) { + if (this.getTalents().isSet(prevTalent)) { + hasPrev = true; + } + } + + if (!hasPrev) { + return false; + } + } + + // Calculate available points + int points = this.getTalentPoints() - this.getUsedTalentPoints(); + + // Make sure we have enough points to unlock this talent + if (talent.getPoint() > points) { + return false; + } + + // Set & save in database + this.getTalents().setBit(talent.getId()); + Nebula.getGameDatabase().update(this.getProgress(), this.getPlayerUid(), "vampireTalents", this.getTalents()); + + // Success + return true; + } + + public void resetTalents() { + // Sanity check to prevent resetting empty talents + if (this.getTalents().isEmpty()) { + return; + } + + // Clear talents + this.getTalents().clear(); + + // Save in database + Nebula.getGameDatabase().update(this.getProgress(), this.getPlayerUid(), "vampireTalents", this.getTalents()); + } + public VampireSurvivorGame apply(int levelId, RepeatedLong builds) { // Get data var data = GameData.getVampireSurvivorDataTable().get(levelId); diff --git a/src/main/java/emu/nebula/server/handlers/HandlerVampireTalentResetReq.java b/src/main/java/emu/nebula/server/handlers/HandlerVampireTalentResetReq.java new file mode 100644 index 0000000..802fee9 --- /dev/null +++ b/src/main/java/emu/nebula/server/handlers/HandlerVampireTalentResetReq.java @@ -0,0 +1,20 @@ +package emu.nebula.server.handlers; + +import emu.nebula.net.NetHandler; +import emu.nebula.net.NetMsgId; +import emu.nebula.net.HandlerId; +import emu.nebula.net.GameSession; + +@HandlerId(NetMsgId.vampire_talent_reset_req) +public class HandlerVampireTalentResetReq extends NetHandler { + + @Override + public byte[] handle(GameSession session, byte[] message) throws Exception { + // Reset talents + session.getPlayer().getVampireSurvivorManager().resetTalents(); + + // Encode and send + return session.encodeMsg(NetMsgId.vampire_talent_reset_succeed_ack); + } + +} diff --git a/src/main/java/emu/nebula/server/handlers/HandlerVampireTalentUnlockReq.java b/src/main/java/emu/nebula/server/handlers/HandlerVampireTalentUnlockReq.java new file mode 100644 index 0000000..01b0609 --- /dev/null +++ b/src/main/java/emu/nebula/server/handlers/HandlerVampireTalentUnlockReq.java @@ -0,0 +1,24 @@ +package emu.nebula.server.handlers; + +import emu.nebula.net.NetHandler; +import emu.nebula.net.NetMsgId; +import emu.nebula.proto.Public.UI32; +import emu.nebula.net.HandlerId; +import emu.nebula.net.GameSession; + +@HandlerId(NetMsgId.vampire_talent_unlock_req) +public class HandlerVampireTalentUnlockReq extends NetHandler { + + @Override + public byte[] handle(GameSession session, byte[] message) throws Exception { + // Parse request + var req = UI32.parseFrom(message); + + // Unlock talent + boolean success = session.getPlayer().getVampireSurvivorManager().unlockTalent(req.getValue()); + + // Encode and send + return session.encodeMsg(success ? NetMsgId.vampire_talent_unlock_succeed_ack : NetMsgId.vampire_talent_unlock_failed_ack); + } + +} diff --git a/src/main/java/emu/nebula/util/Bitset.java b/src/main/java/emu/nebula/util/Bitset.java index f3758ad..5a2a880 100644 --- a/src/main/java/emu/nebula/util/Bitset.java +++ b/src/main/java/emu/nebula/util/Bitset.java @@ -13,6 +13,14 @@ public class Bitset { public Bitset(long[] longArray) { this.data = longArray; } + + public boolean isEmpty() { + return this.data.length == 1 && this.data[0] == 0L; + } + + public void clear() { + this.data = new long[1]; + } public boolean isSet(int index) { int longArrayOffset = (int) Math.floor((index - 1) / 64D);