diff --git a/src/main/java/emu/nebula/GameConstants.java b/src/main/java/emu/nebula/GameConstants.java index ebda2be..6dae41e 100644 --- a/src/main/java/emu/nebula/GameConstants.java +++ b/src/main/java/emu/nebula/GameConstants.java @@ -37,6 +37,12 @@ public class GameConstants { public static final int MAX_FRIENDSHIPS = 50; public static final int MAX_PENDING_FRIENDSHIPS = 30; + public static int[][] VAMPIRE_SURVIVOR_BONUS_POWER = new int[][] { + new int[] {100, 120}, + new int[] {200, 150}, + new int[] {300, 200} + }; + // Daily gifts (Custom) public static final WeightedList DAILY_GIFTS = new WeightedList<>(); diff --git a/src/main/java/emu/nebula/data/resources/VampireSurvivorDef.java b/src/main/java/emu/nebula/data/resources/VampireSurvivorDef.java index 4009dc4..8411b88 100644 --- a/src/main/java/emu/nebula/data/resources/VampireSurvivorDef.java +++ b/src/main/java/emu/nebula/data/resources/VampireSurvivorDef.java @@ -12,6 +12,18 @@ public class VampireSurvivorDef extends BaseDef { private int NeedWorldClass; private int[] FateCardBundle; + private int NormalScore1; + private int EliteScore1; + private int BossScore1; + private int TimeScore1; + private int TimeLimit1; + + private int NormalScore2; + private int EliteScore2; + private int BossScore2; + private int TimeScore2; + private int TimeLimit2; + @Override public int getId() { return Id; diff --git a/src/main/java/emu/nebula/game/vampire/VampireSurvivorArea.java b/src/main/java/emu/nebula/game/vampire/VampireSurvivorArea.java new file mode 100644 index 0000000..95f93b0 --- /dev/null +++ b/src/main/java/emu/nebula/game/vampire/VampireSurvivorArea.java @@ -0,0 +1,82 @@ +package emu.nebula.game.vampire; + +import java.util.stream.IntStream; + +import emu.nebula.GameConstants; +import emu.nebula.data.resources.VampireSurvivorDef; +import emu.nebula.proto.VampireSurvivorSettle.VampireSurvivorAreaInfo; +import lombok.Getter; + +@Getter +public class VampireSurvivorArea { + private final VampireSurvivorGame game; + + private int time; + private int score; + + private int[] killCount; + private int[] killScore; + + public VampireSurvivorArea(VampireSurvivorGame game, int time, int[] killCount) { + this.game = game; + this.time = time; + + this.calcScore(killCount); + } + + private VampireSurvivorDef getData() { + return this.getGame().getData(); + } + + private void calcScore(int[] killCount) { + // Set kill count/score + this.killCount = killCount; + this.killScore = new int[killCount.length]; + + // Check size for kill counter array + int maxSize = 4 + (GameConstants.VAMPIRE_SURVIVOR_BONUS_POWER.length * 2); + + if (killCount.length < maxSize) { + return; + } + + // Calculate + killScore[0] = killCount[0] * this.getData().getNormalScore1(); // Monster + killScore[1] = killCount[1] * this.getData().getEliteScore1(); // Elite monster + killScore[2] = killCount[2] * this.getData().getEliteScore1(); // Lord + killScore[3] = this.getData().getBossScore1(); // Boss + + int offset = 4; + + for (int i = 0; i < GameConstants.VAMPIRE_SURVIVOR_BONUS_POWER.length; i++, offset++) { + int bonusKill = killCount[offset]; + int bonusPower = GameConstants.VAMPIRE_SURVIVOR_BONUS_POWER[i][1]; + double mod = (bonusPower - 100) / 100D; + + killScore[offset] = (int) (bonusKill * mod * this.getData().getNormalScore1()); + } + + for (int i = 0; i < GameConstants.VAMPIRE_SURVIVOR_BONUS_POWER.length; i++, offset++) { + int bonusKill = killCount[offset]; + int bonusPower = GameConstants.VAMPIRE_SURVIVOR_BONUS_POWER[i][1]; + double mod = (bonusPower - 100) / 100D; + + killScore[offset] = (int) (bonusKill * mod * this.getData().getEliteScore1()); + } + + // Get final score + this.score = IntStream.of(killScore).sum(); + } + + // Proto + + public VampireSurvivorAreaInfo toProto() { + var proto = VampireSurvivorAreaInfo.newInstance() + .setBossTime(this.getTime()) + .setScore(this.getScore()) + .addAllKillCount(this.getKillCount()) + .addAllKillScore(this.getKillScore()); + + return proto; + } +} diff --git a/src/main/java/emu/nebula/game/vampire/VampireSurvivorGame.java b/src/main/java/emu/nebula/game/vampire/VampireSurvivorGame.java index 7c9a349..89ff05d 100644 --- a/src/main/java/emu/nebula/game/vampire/VampireSurvivorGame.java +++ b/src/main/java/emu/nebula/game/vampire/VampireSurvivorGame.java @@ -1,5 +1,6 @@ package emu.nebula.game.vampire; +import java.util.List; import java.util.Set; import emu.nebula.data.GameData; @@ -8,10 +9,12 @@ import emu.nebula.data.resources.VampireSurvivorDef; import emu.nebula.proto.Public.CardInfo; import emu.nebula.proto.Public.VampireSurvivorLevelReward; import emu.nebula.util.WeightedList; + import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import lombok.Getter; @@ -27,6 +30,9 @@ public class VampireSurvivorGame { private int rewardLevel; private IntList rewards; + // Areas + private List areas; + // Cache private Set randomCards; @@ -37,6 +43,7 @@ public class VampireSurvivorGame { this.cards = new IntOpenHashSet(); this.rewards = new IntArrayList(); + this.areas = new ObjectArrayList<>(); // Cache fate cards from bundles this.cacheRandomCards(); @@ -48,6 +55,16 @@ public class VampireSurvivorGame { public int getId() { return this.getData().getId(); } + + public int getTotalScore() { + int score = 0; + + for (var area : this.getAreas()) { + score += area.getScore(); + } + + return score; + } public boolean isNewCard(int id) { return !this.getManager().getProgress().getFateCards().contains(id); @@ -147,6 +164,17 @@ public class VampireSurvivorGame { return chest; } + public VampireSurvivorArea settleArea(int time, int[] killCount) { + // Create area + var area = new VampireSurvivorArea(this, time, killCount); + + // Add to areas list + this.getAreas().add(area); + + // Success + return area; + } + // Proto public VampireSurvivorLevelReward getRewardProto() { diff --git a/src/main/java/emu/nebula/server/handlers/HandlerVampireSurvivorAreaChangeReq.java b/src/main/java/emu/nebula/server/handlers/HandlerVampireSurvivorAreaChangeReq.java index 1e1d89b..44c14e9 100644 --- a/src/main/java/emu/nebula/server/handlers/HandlerVampireSurvivorAreaChangeReq.java +++ b/src/main/java/emu/nebula/server/handlers/HandlerVampireSurvivorAreaChangeReq.java @@ -2,6 +2,7 @@ package emu.nebula.server.handlers; import emu.nebula.net.NetHandler; import emu.nebula.net.NetMsgId; +import emu.nebula.proto.VampireSurvivorAreaChange.VampireSurvivorAreaChangeReq; import emu.nebula.net.HandlerId; import emu.nebula.net.GameSession; @@ -10,6 +11,19 @@ public class HandlerVampireSurvivorAreaChangeReq extends NetHandler { @Override public byte[] handle(GameSession session, byte[] message) throws Exception { + // Parse req + var req = VampireSurvivorAreaChangeReq.parseFrom(message); + + // Get vampire survivor game + var game = session.getPlayer().getVampireSurvivorManager().getGame(); + + if (game == null) { + session.encodeMsg(NetMsgId.vampire_survivor_area_change_failed_ack); + } + + // Calculate score for area + game.settleArea(req.getTime(), req.getKillCount().toArray()); + // Encode and send return session.encodeMsg(NetMsgId.vampire_survivor_area_change_succeed_ack); } diff --git a/src/main/java/emu/nebula/server/handlers/HandlerVampireSurvivorSettleReq.java b/src/main/java/emu/nebula/server/handlers/HandlerVampireSurvivorSettleReq.java index 4d6539d..7925ba7 100644 --- a/src/main/java/emu/nebula/server/handlers/HandlerVampireSurvivorSettleReq.java +++ b/src/main/java/emu/nebula/server/handlers/HandlerVampireSurvivorSettleReq.java @@ -2,7 +2,6 @@ package emu.nebula.server.handlers; import emu.nebula.net.NetHandler; import emu.nebula.net.NetMsgId; -import emu.nebula.proto.VampireSurvivorSettle.VampireSurvivorAreaInfo; import emu.nebula.proto.VampireSurvivorSettle.VampireSurvivorSettleReq; import emu.nebula.proto.VampireSurvivorSettle.VampireSurvivorSettleResp; import emu.nebula.net.HandlerId; @@ -16,40 +15,35 @@ public class HandlerVampireSurvivorSettleReq extends NetHandler { // Parse request var req = VampireSurvivorSettleReq.parseFrom(message); - // Sanity check + // Get vampire survivor game var game = session.getPlayer().getVampireSurvivorManager().getGame(); if (game == null) { session.encodeMsg(NetMsgId.vampire_survivor_settle_failed_ack); } - // Calculate victory + score + // Calculate victory boolean victory = !req.getDefeat(); - int score = 1; - // Settle - session.getPlayer().getVampireSurvivorManager().settle(victory, score); + // Settle area + var area = game.settleArea(req.getTime(), req.getKillCount().toArray()); + + // Settle game + session.getPlayer().getVampireSurvivorManager().settle(victory, area.getScore()); // Build response var rsp = VampireSurvivorSettleResp.newInstance(); if (victory) { - var areaInfo = VampireSurvivorAreaInfo.newInstance() - .setBossTime(1) - .setScore(score); - - // TODO - for (int i : req.getKillCount()) { - areaInfo.addKillCount(i); - areaInfo.addKillScore(0); - } - rsp.getMutableVictory() - .setFinalScore(score) - .addInfos(areaInfo); + .setFinalScore(game.getTotalScore()); + + for (var a : game.getAreas()) { + rsp.getMutableVictory().addInfos(a.toProto()); + } } else { rsp.getMutableDefeat() - .setFinalScore(score); + .setFinalScore(game.getTotalScore()); } // Encode and send