From c5f339c8be81f0d2965cb58c9c8128dcfcd585db Mon Sep 17 00:00:00 2001 From: Melledy <121644117+Melledy@users.noreply.github.com> Date: Mon, 8 Dec 2025 22:28:47 -0800 Subject: [PATCH] Implement new event --- src/main/java/emu/nebula/data/GameData.java | 12 + .../data/resources/ActivityGoodsDef.java | 38 ++++ .../resources/ActivityLevelsLevelDef.java | 65 ++++++ .../resources/ActivityShopControlDef.java | 18 ++ .../data/resources/ActivityShopDef.java | 28 +++ .../data/resources/ActivityTaskDef.java | 40 ++++ .../data/resources/ActivityTaskGroupDef.java | 57 +++++ .../nebula/game/activity/ActivityManager.java | 6 +- .../nebula/game/activity/ActivityModule.java | 14 +- .../game/activity/ActivityTaskQuest.java | 93 ++++++++ .../game/activity/type/LevelsActivity.java | 209 ++++++++++++++++++ .../game/activity/type/ShopActivity.java | 152 +++++++++++++ .../game/activity/type/TaskActivity.java | 72 ++++++ .../game/instance/InstanceSettleData.java | 4 + .../emu/nebula/server/handlers/Handler.java | 2 +- .../HandlerActivityLevelsApplyReq.java | 36 +++ .../HandlerActivityLevelsSettleReq.java | 56 +++++ .../HandlerActivityLevelsSweepReq.java | 70 ++++++ .../HandlerActivityShopPurchaseReq.java | 50 +++++ .../HandlerCharGemInstanceSettleReq.java | 6 +- 20 files changed, 1020 insertions(+), 8 deletions(-) create mode 100644 src/main/java/emu/nebula/data/resources/ActivityGoodsDef.java create mode 100644 src/main/java/emu/nebula/data/resources/ActivityLevelsLevelDef.java create mode 100644 src/main/java/emu/nebula/data/resources/ActivityShopControlDef.java create mode 100644 src/main/java/emu/nebula/data/resources/ActivityShopDef.java create mode 100644 src/main/java/emu/nebula/data/resources/ActivityTaskDef.java create mode 100644 src/main/java/emu/nebula/data/resources/ActivityTaskGroupDef.java create mode 100644 src/main/java/emu/nebula/game/activity/ActivityTaskQuest.java create mode 100644 src/main/java/emu/nebula/game/activity/type/LevelsActivity.java create mode 100644 src/main/java/emu/nebula/game/activity/type/ShopActivity.java create mode 100644 src/main/java/emu/nebula/game/activity/type/TaskActivity.java create mode 100644 src/main/java/emu/nebula/server/handlers/HandlerActivityLevelsApplyReq.java create mode 100644 src/main/java/emu/nebula/server/handlers/HandlerActivityLevelsSettleReq.java create mode 100644 src/main/java/emu/nebula/server/handlers/HandlerActivityLevelsSweepReq.java create mode 100644 src/main/java/emu/nebula/server/handlers/HandlerActivityShopPurchaseReq.java diff --git a/src/main/java/emu/nebula/data/GameData.java b/src/main/java/emu/nebula/data/GameData.java index f961f85..1079902 100644 --- a/src/main/java/emu/nebula/data/GameData.java +++ b/src/main/java/emu/nebula/data/GameData.java @@ -155,4 +155,16 @@ public class GameData { // Activity: Trials @Getter private static DataTable TrialControlDataTable = new DataTable<>(); @Getter private static DataTable TrialGroupDataTable = new DataTable<>(); + + // Activity: Levels + @Getter private static DataTable ActivityLevelsLevelDataTable = new DataTable<>(); + + // Activity: Task + @Getter private static DataTable ActivityTaskDataTable = new DataTable<>(); + @Getter private static DataTable ActivityTaskGroupDataTable = new DataTable<>(); + + // Activity: Shop + @Getter private static DataTable ActivityShopDataTable = new DataTable<>(); + @Getter private static DataTable ActivityShopControlDataTable = new DataTable<>(); + @Getter private static DataTable ActivityGoodsDataTable = new DataTable<>(); } \ No newline at end of file diff --git a/src/main/java/emu/nebula/data/resources/ActivityGoodsDef.java b/src/main/java/emu/nebula/data/resources/ActivityGoodsDef.java new file mode 100644 index 0000000..4c448cf --- /dev/null +++ b/src/main/java/emu/nebula/data/resources/ActivityGoodsDef.java @@ -0,0 +1,38 @@ +package emu.nebula.data.resources; + +import emu.nebula.data.BaseDef; +import emu.nebula.data.GameData; +import emu.nebula.data.ResourceType; +import emu.nebula.data.ResourceType.LoadPriority; +import emu.nebula.game.inventory.ItemParamMap; +import lombok.Getter; + +@Getter +@ResourceType(name = "ActivityGoods.json", loadPriority = LoadPriority.LOW) +public class ActivityGoodsDef extends BaseDef { + private int Id; + private int ShopId; + + private int ItemId; + private int ItemQuantity; + private int MaximumLimit; + private int Price; + + private transient ItemParamMap items; + + @Override + public int getId() { + return Id; + } + + @Override + public void onLoad() { + var shop = GameData.getActivityShopDataTable().get(this.getShopId()); + if (shop != null) { + shop.getGoods().put(this.getId(), this); + } + + this.items = new ItemParamMap(); + this.items.add(this.ItemId, this.ItemQuantity); + } +} diff --git a/src/main/java/emu/nebula/data/resources/ActivityLevelsLevelDef.java b/src/main/java/emu/nebula/data/resources/ActivityLevelsLevelDef.java new file mode 100644 index 0000000..7104264 --- /dev/null +++ b/src/main/java/emu/nebula/data/resources/ActivityLevelsLevelDef.java @@ -0,0 +1,65 @@ +package emu.nebula.data.resources; + +import emu.nebula.data.BaseDef; +import emu.nebula.data.ResourceType; +import emu.nebula.game.instance.InstanceData; +import emu.nebula.game.inventory.ItemRewardList; +import emu.nebula.game.inventory.ItemRewardParam; +import emu.nebula.util.JsonUtils; + +import lombok.Getter; + +@Getter +@ResourceType(name = "ActivityLevelsLevel.json") +public class ActivityLevelsLevelDef extends BaseDef implements InstanceData { + private int Id; + private int ActivityId; + private int EnergyConsume; + private String CompleteRewardPreview; + + private transient ItemRewardList firstRewards; + private transient ItemRewardList rewards; + + @Override + public int getId() { + return Id; + } + + @Override + public int getNeedWorldClass() { + return 0; + } + + @Override + public void onLoad() { + // Init reward lists + this.firstRewards = new ItemRewardList(); + this.rewards = new ItemRewardList(); + + // Parse rewards + var awards = JsonUtils.decodeList(this.CompleteRewardPreview, int[].class); + if (awards == null) { + return; + } + + for (int[] award : awards) { + int itemId = award[0]; + int min = award[1]; + int max = award.length >= 4 ? award[2] : min; + boolean isFirst = award[award.length - 1] == 1; + + if (min == -1) { + min = 0; + max = 1; + } + + var reward = new ItemRewardParam(itemId, min, max); + + if (isFirst) { + this.firstRewards.add(reward); + } else { + this.rewards.add(reward); + } + } + } +} diff --git a/src/main/java/emu/nebula/data/resources/ActivityShopControlDef.java b/src/main/java/emu/nebula/data/resources/ActivityShopControlDef.java new file mode 100644 index 0000000..43a25b5 --- /dev/null +++ b/src/main/java/emu/nebula/data/resources/ActivityShopControlDef.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 = "ActivityShopControl.json") +public class ActivityShopControlDef extends BaseDef { + private int Id; + private int[] ShopIds; + + @Override + public int getId() { + return Id; + } +} diff --git a/src/main/java/emu/nebula/data/resources/ActivityShopDef.java b/src/main/java/emu/nebula/data/resources/ActivityShopDef.java new file mode 100644 index 0000000..f6764f7 --- /dev/null +++ b/src/main/java/emu/nebula/data/resources/ActivityShopDef.java @@ -0,0 +1,28 @@ +package emu.nebula.data.resources; + +import emu.nebula.data.BaseDef; +import emu.nebula.data.ResourceType; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import lombok.Getter; + +@Getter +@ResourceType(name = "ActivityShop.json") +public class ActivityShopDef extends BaseDef { + private int Id; + private int CurrencyItemId; + private int ExchangeItemId; + private double Rate; + + private Int2ObjectMap goods; + + @Override + public int getId() { + return Id; + } + + @Override + public void onLoad() { + this.goods = new Int2ObjectOpenHashMap<>(); + } +} diff --git a/src/main/java/emu/nebula/data/resources/ActivityTaskDef.java b/src/main/java/emu/nebula/data/resources/ActivityTaskDef.java new file mode 100644 index 0000000..a986d29 --- /dev/null +++ b/src/main/java/emu/nebula/data/resources/ActivityTaskDef.java @@ -0,0 +1,40 @@ +package emu.nebula.data.resources; + +import emu.nebula.data.BaseDef; +import emu.nebula.data.ResourceType; +import emu.nebula.game.inventory.ItemParamMap; +import lombok.Getter; + +@Getter +@ResourceType(name = "ActivityTask.json") +public class ActivityTaskDef extends BaseDef { + private int Id; + private int ActivityTaskGroupId; + + private int CompleteCond; + private int AimNumShow; + + private int Tid1; + private int Qty1; + private int Tid2; + private int Qty2; + + private transient ItemParamMap rewards; + + @Override + public int getId() { + return Id; + } + + @Override + public void onLoad() { + this.rewards = new ItemParamMap(); + + if (this.Tid1 > 0) { + this.rewards.add(this.Tid1, this.Qty1); + } + if (this.Tid2 > 0) { + this.rewards.add(this.Tid2, this.Qty2); + } + } +} diff --git a/src/main/java/emu/nebula/data/resources/ActivityTaskGroupDef.java b/src/main/java/emu/nebula/data/resources/ActivityTaskGroupDef.java new file mode 100644 index 0000000..a8e6afe --- /dev/null +++ b/src/main/java/emu/nebula/data/resources/ActivityTaskGroupDef.java @@ -0,0 +1,57 @@ +package emu.nebula.data.resources; + +import emu.nebula.data.BaseDef; +import emu.nebula.data.ResourceType; +import emu.nebula.game.inventory.ItemParamMap; +import lombok.Getter; + +@Getter +@ResourceType(name = "ActivityTaskGroup.json") +public class ActivityTaskGroupDef extends BaseDef { + private int Id; + private int ActivityId; + + private int Reward1; + private int RewardQty1; + private int Reward2; + private int RewardQty2; + private int Reward3; + private int RewardQty3; + private int Reward4; + private int RewardQty4; + private int Reward5; + private int RewardQty5; + private int Reward6; + private int RewardQty6; + + private transient ItemParamMap rewards; + + @Override + public int getId() { + return Id; + } + + @Override + public void onLoad() { + this.rewards = new ItemParamMap(); + + if (this.Reward1 > 0) { + this.rewards.add(this.Reward1, this.RewardQty1); + } + if (this.Reward2 > 0) { + this.rewards.add(this.Reward2, this.RewardQty2); + } + if (this.Reward3 > 0) { + this.rewards.add(this.Reward3, this.RewardQty3); + } + if (this.Reward4 > 0) { + this.rewards.add(this.Reward4, this.RewardQty4); + } + if (this.Reward5 > 0) { + this.rewards.add(this.Reward5, this.RewardQty5); + } + if (this.Reward6 > 0) { + this.rewards.add(this.Reward6, this.RewardQty6); + } + } +} diff --git a/src/main/java/emu/nebula/game/activity/ActivityManager.java b/src/main/java/emu/nebula/game/activity/ActivityManager.java index da3243e..3ba906b 100644 --- a/src/main/java/emu/nebula/game/activity/ActivityManager.java +++ b/src/main/java/emu/nebula/game/activity/ActivityManager.java @@ -109,9 +109,13 @@ public class ActivityManager extends PlayerManager implements GameDatabaseObject return null; } + // TODO improve activity creation GameActivity activity = switch (data.getType()) { - case Trial -> new TrialActivity(this, data); case TowerDefense -> new TowerDefenseActivity(this, data); + case Trial -> new TrialActivity(this, data); + case Levels -> new LevelsActivity(this, data); + case Task -> new TaskActivity(this, data); + case Shop -> new ShopActivity(this, data); default -> null; }; diff --git a/src/main/java/emu/nebula/game/activity/ActivityModule.java b/src/main/java/emu/nebula/game/activity/ActivityModule.java index ab54cbc..3c37072 100644 --- a/src/main/java/emu/nebula/game/activity/ActivityModule.java +++ b/src/main/java/emu/nebula/game/activity/ActivityModule.java @@ -15,12 +15,20 @@ public class ActivityModule extends GameContextModule { this.activities = new IntArrayList(); // Hardcode these activities for now - this.activities.add(700102); - this.activities.add(700103); + // TODO make an activity json file to read activity ids from + + // Trial activities this.activities.add(700104); this.activities.add(700107); + this.activities.add(700108); - this.activities.add(102001); // Tower defense activity + // Tower defense activity + this.activities.add(102001); + + // + this.activities.add(1010201); + this.activities.add(1010203); + this.activities.add(1010204); //this.activities.add(101002); //this.activities.add(101003); diff --git a/src/main/java/emu/nebula/game/activity/ActivityTaskQuest.java b/src/main/java/emu/nebula/game/activity/ActivityTaskQuest.java new file mode 100644 index 0000000..f8c5386 --- /dev/null +++ b/src/main/java/emu/nebula/game/activity/ActivityTaskQuest.java @@ -0,0 +1,93 @@ +package emu.nebula.game.activity; + +import dev.morphia.annotations.Entity; + +import emu.nebula.data.resources.ActivityTaskDef; +import emu.nebula.proto.Public.Quest; +import emu.nebula.proto.Public.QuestProgress; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Entity(useDiscriminator = false) +public class ActivityTaskQuest { + private int id; + private int cond; + + private int curProgress; + private int maxProgress; + + @Setter + private boolean claimed; + + @Deprecated + public ActivityTaskQuest() { + + } + + public ActivityTaskQuest(ActivityTaskDef data) { + this.id = data.getId(); + this.cond = data.getCompleteCond(); + this.maxProgress = data.getAimNumShow(); + } + + public void resetProgress() { + this.curProgress = 0; + this.claimed = false; + } + + public boolean isComplete() { + return this.curProgress >= this.maxProgress; + } + + private int getStatus() { + if (this.isClaimed()) { + return 2; + } else if (this.isComplete()) { + return 1; + } + + return 0; + } + + public boolean trigger(int condition, int progress, int param1, int param2) { + // Sanity check + if (this.isComplete()) { + return false; + } + + // Skip if not the correct condition + if (this.cond != condition) { + return false; + } + + // Check quest param TODO + + // Get new progress + int newProgress = Math.min(this.curProgress + progress, this.maxProgress); + + // Set + if (this.curProgress != newProgress) { + this.curProgress = newProgress; + return true; + } + + return false; + } + + // Proto + + public Quest toProto() { + var progress = QuestProgress.newInstance() + .setCur(this.getCurProgress()) + .setMax(this.getMaxProgress()); + + var proto = Quest.newInstance() + .setId(this.getId()) + .setStatus(this.getStatus()) + .addProgress(progress); + + return proto; + } +} diff --git a/src/main/java/emu/nebula/game/activity/type/LevelsActivity.java b/src/main/java/emu/nebula/game/activity/type/LevelsActivity.java new file mode 100644 index 0000000..a681f65 --- /dev/null +++ b/src/main/java/emu/nebula/game/activity/type/LevelsActivity.java @@ -0,0 +1,209 @@ +package emu.nebula.game.activity.type; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import dev.morphia.annotations.Entity; + +import emu.nebula.GameConstants; +import emu.nebula.data.GameData; +import emu.nebula.data.resources.ActivityDef; +import emu.nebula.data.resources.ActivityLevelsLevelDef; +import emu.nebula.game.activity.ActivityManager; +import emu.nebula.game.activity.GameActivity; +import emu.nebula.game.instance.InstanceSettleData; +import emu.nebula.game.inventory.ItemParamMap; +import emu.nebula.game.player.PlayerChangeInfo; +import emu.nebula.game.quest.QuestCondition; +import emu.nebula.proto.ActivityDetail.ActivityMsg; +import emu.nebula.proto.Public.ActivityLevel; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Entity +public class LevelsActivity extends GameActivity { + private Map levels; + + // Apply level data + private transient ActivityLevelsLevelDef level; + private transient long buildId; + + @Deprecated // Morphia only + public LevelsActivity() { + + } + + public LevelsActivity(ActivityManager manager, ActivityDef data) { + super(manager, data); + this.levels = new HashMap<>(); + } + + public boolean apply(int levelId, long buildId) { + // Verify level + var level = GameData.getActivityLevelsLevelDataTable().get(levelId); + + if (level == null || level.getActivityId() != this.getId()) { + return false; + } + + // Verify build + var build = this.getPlayer().getStarTowerManager().getBuildById(buildId); + + if (build == null) { + return false; + } + + // Set + this.level = level; + this.buildId = buildId; + + // Success + return true; + } + + public PlayerChangeInfo settle(int star) { + // Check energy + if (!this.getLevel().hasEnergy(this.getPlayer(), 1)) { + return null; + } + + // Calculate settle data + var settleData = new InstanceSettleData(); + + settleData.setWin(star > 0); + settleData.setFirst(settleData.isWin() && !this.getLevels().containsKey(this.getLevel().getId())); + + // Init player change info + var change = new PlayerChangeInfo(); + + // Handle win + if (settleData.isWin()) { + // Calculate energy and exp + settleData.setExp(this.getLevel().getEnergyConsume()); + getPlayer().consumeEnergy(settleData.getExp(), change); + + // Calculate rewards + settleData.generateRewards(this.getLevel()); + + // Add to inventory + getPlayer().getInventory().addItem(GameConstants.EXP_ITEM_ID, settleData.getExp(), change); + getPlayer().getInventory().addItems(settleData.getRewards(), change); + getPlayer().getInventory().addItems(settleData.getFirstRewards(), change); + + // Log + var level = getLevels().computeIfAbsent(this.getLevel().getId(), i -> new ActivityLevelInfo()); + + level.setStar(star); + level.setBuildId(this.getBuildId()); + + // Save to database + this.save(); + + // Quest triggers + this.getPlayer().trigger(QuestCondition.BattleTotal, 1); + } + + // Set extra data + change.setExtraData(settleData); + + // Success + return change; + } + + public PlayerChangeInfo sweep(ActivityLevelsLevelDef data, int count) { + // Sanity check count + if (count <= 0) { + return null; + } + + // Check if we have 3 starred this instance + var level = this.getLevels().get(data.getId()); + + if (level == null || level.getStar() != 3) { + return null; + } + + // Check energy cost + int energyCost = data.getEnergyConsume() * count; + + if (this.getPlayer().getEnergy() < energyCost) { + return null; + } + + // Init variables + var change = new PlayerChangeInfo(); + var list = new ArrayList(); + + // Consume exp + getPlayer().consumeEnergy(energyCost, change); + getPlayer().getInventory().addItem(GameConstants.EXP_ITEM_ID, energyCost, change); + + // Calculate total rewards + var totalRewards = new ItemParamMap(); + + for (int i = 0; i < count; i++) { + // Generate rewards for each settle count + var rewards = data.getRewards().generate(); + + // Add to reward list + list.add(rewards); + + // Add to total rewards + totalRewards.add(rewards); + } + + // Add total rewards to inventory + getPlayer().getInventory().addItems(totalRewards, change); + + // Set reward list in change info so we can serialize it in the response proto later + change.setExtraData(list); + + // Quest triggers + this.getPlayer().trigger(QuestCondition.BattleTotal, count); + + // Success + return change.setSuccess(true); + } + + // Proto + + @Override + public void encodeActivityMsg(ActivityMsg msg) { + var proto = msg.getMutableLevels(); + + for (var entry : this.getLevels().entrySet()) { + int id = entry.getKey(); + var level = entry.getValue(); + + var info = level.toProto() + .setId(id); + + proto.addLevels(info); + } + } + + @Setter + @Getter + @Entity(useDiscriminator = false) + public static class ActivityLevelInfo { + private int star; + private long buildId; + + public ActivityLevelInfo() { + + } + + // Proto + + public ActivityLevel toProto() { + var proto = ActivityLevel.newInstance() + .setStar(this.getStar()) + .setBuildId(this.getBuildId()); + + return proto; + } + } +} diff --git a/src/main/java/emu/nebula/game/activity/type/ShopActivity.java b/src/main/java/emu/nebula/game/activity/type/ShopActivity.java new file mode 100644 index 0000000..642e5a1 --- /dev/null +++ b/src/main/java/emu/nebula/game/activity/type/ShopActivity.java @@ -0,0 +1,152 @@ +package emu.nebula.game.activity.type; + +import java.util.HashMap; +import java.util.Map; + +import dev.morphia.annotations.Entity; + +import emu.nebula.data.GameData; +import emu.nebula.data.resources.ActivityDef; +import emu.nebula.data.resources.ActivityShopControlDef; +import emu.nebula.data.resources.ActivityShopDef; +import emu.nebula.game.activity.ActivityManager; +import emu.nebula.game.activity.GameActivity; +import emu.nebula.game.inventory.ItemParamMap; +import emu.nebula.game.player.PlayerChangeInfo; +import emu.nebula.proto.ActivityDetail.ActivityMsg; +import emu.nebula.proto.Public.BoughtGoods; +import emu.nebula.proto.Public.ResidentShop; + +import lombok.Getter; + +@Getter +@Entity +public class ShopActivity extends GameActivity { + private Map shops; + + @Deprecated // Morphia only + public ShopActivity() { + + } + + public ShopActivity(ActivityManager manager, ActivityDef data) { + super(manager, data); + this.shops = new HashMap<>(); + + // Load shops + var control = GameData.getActivityShopControlDataTable().get(data.getId()); + if (control != null) { + this.initShops(control); + } + } + + private void initShops(ActivityShopControlDef control) { + for (int id : control.getShopIds()) { + var data = GameData.getActivityShopDataTable().get(id); + if (data == null) { + continue; + } + + // Create resident shop + var shop = new ActivityShopInfo(data); + + // Add + this.getShops().put(data.getId(), shop); + } + } + + public PlayerChangeInfo buy(int shopId, int goodsId, int count) { + // Get shop + var shop = this.getShops().get(shopId); + if (shop == null) return null; + + // Get shop data + var data = GameData.getActivityShopDataTable().get(shopId); + if (data == null) return null; + + // Get goods + var goods = data.getGoods().get(goodsId); + if (goods == null) return null; + + // Check limit + if (goods.getMaximumLimit() > 0) { + var limit = goods.getMaximumLimit() - shop.getBoughtCount(goodsId); + + if (count > limit) { + return null; + } + } + + // Purchase + var change = getPlayer().getInventory().buyItem(data.getCurrencyItemId(), goods.getPrice(), goods.getItems(), count); + + // Purchase failed + if (change == null) { + return null; + } + + // Set log + shop.getBoughtGoods().add(goodsId, count); + + // Save + this.save(); + + // Set extra data + change.setExtraData(shop); + + // Success + return change; + } + + // Proto + + @Override + public void encodeActivityMsg(ActivityMsg msg) { + var proto = msg.getMutableShop(); + + for (var entry : this.getShops().entrySet()) { + var id = entry.getKey(); + var shop = entry.getValue(); + + var info = shop.toProto() + .setId(id); + + proto.addShops(info); + } + } + + @Getter + @Entity(useDiscriminator = false) + public static class ActivityShopInfo { + private ItemParamMap boughtGoods; + + @Deprecated // Morphia only + public ActivityShopInfo() { + + } + + public ActivityShopInfo(ActivityShopDef data) { + this.boughtGoods = new ItemParamMap(); + } + + public int getBoughtCount(int goodsId) { + return this.getBoughtGoods().get(goodsId); + } + + // Proto + + public ResidentShop toProto() { + var proto = ResidentShop.newInstance(); + + for (var item : this.getBoughtGoods().int2IntEntrySet()) { + var info = BoughtGoods.newInstance() + .setId(item.getIntKey()) + .setNumber(item.getIntValue()); + + proto.addInfos(info); + } + + return proto; + } + } +} diff --git a/src/main/java/emu/nebula/game/activity/type/TaskActivity.java b/src/main/java/emu/nebula/game/activity/type/TaskActivity.java new file mode 100644 index 0000000..225a93f --- /dev/null +++ b/src/main/java/emu/nebula/game/activity/type/TaskActivity.java @@ -0,0 +1,72 @@ +package emu.nebula.game.activity.type; + +import java.util.HashMap; +import java.util.Map; + +import dev.morphia.annotations.Entity; +import emu.nebula.data.GameData; +import emu.nebula.data.resources.ActivityDef; +import emu.nebula.game.activity.ActivityManager; +import emu.nebula.game.activity.ActivityTaskQuest; +import emu.nebula.game.activity.GameActivity; +import emu.nebula.proto.ActivityDetail.ActivityMsg; + +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; + +import lombok.Getter; + +@Getter +@Entity +public class TaskActivity extends GameActivity { + private Map quests; + private IntSet completedGroups; + + @Deprecated // Morphia only + public TaskActivity() { + + } + + public TaskActivity(ActivityManager manager, ActivityDef data) { + super(manager, data); + this.quests = new HashMap<>(); + this.completedGroups = new IntOpenHashSet(); + + var groupSet = new IntOpenHashSet(); + for (var group : GameData.getActivityTaskGroupDataTable()) { + if (group.getActivityId() != this.getId()) { + continue; + } + + groupSet.add(group.getId()); + } + + for (var task : GameData.getActivityTaskDataTable()) { + if (!groupSet.contains(task.getActivityTaskGroupId())) { + continue; + } + + var quest = new ActivityTaskQuest(task); + + this.getQuests().put(quest.getId(), quest); + } + } + + // Proto + + @Override + public void encodeActivityMsg(ActivityMsg msg) { + var proto = msg.getMutableTask(); + + for (int id : this.getCompletedGroups()) { + proto.addGroupIds(id); + } + + var tasks = proto.getMutableActivityTasks(); + + for (var quest : this.getQuests().values()) { + tasks.addList(quest.toProto()); + } + } + +} diff --git a/src/main/java/emu/nebula/game/instance/InstanceSettleData.java b/src/main/java/emu/nebula/game/instance/InstanceSettleData.java index 7690be1..8f41b16 100644 --- a/src/main/java/emu/nebula/game/instance/InstanceSettleData.java +++ b/src/main/java/emu/nebula/game/instance/InstanceSettleData.java @@ -17,6 +17,10 @@ public class InstanceSettleData { } + public void generateRewards(InstanceData data) { + this.generateRewards(data, 0); + } + public void generateRewards(InstanceData data, int rewardType) { if (this.isFirst) { this.firstRewards = data.getFirstRewards(rewardType).generate(); diff --git a/src/main/java/emu/nebula/server/handlers/Handler.java b/src/main/java/emu/nebula/server/handlers/Handler.java index b07c380..43a57dd 100644 --- a/src/main/java/emu/nebula/server/handlers/Handler.java +++ b/src/main/java/emu/nebula/server/handlers/Handler.java @@ -10,7 +10,7 @@ public class Handler extends NetHandler { @Override public byte[] handle(GameSession session, byte[] message) throws Exception { - // Template hanlder + // Template handler // Encode and send return session.encodeMsg(NetMsgId.none); diff --git a/src/main/java/emu/nebula/server/handlers/HandlerActivityLevelsApplyReq.java b/src/main/java/emu/nebula/server/handlers/HandlerActivityLevelsApplyReq.java new file mode 100644 index 0000000..3d26df0 --- /dev/null +++ b/src/main/java/emu/nebula/server/handlers/HandlerActivityLevelsApplyReq.java @@ -0,0 +1,36 @@ +package emu.nebula.server.handlers; + +import emu.nebula.net.NetHandler; +import emu.nebula.net.NetMsgId; +import emu.nebula.proto.ActivityLevelsApply.ActivityLevelsApplyReq; +import emu.nebula.net.HandlerId; +import emu.nebula.game.activity.type.LevelsActivity; +import emu.nebula.net.GameSession; + +@HandlerId(NetMsgId.activity_levels_apply_req) +public class HandlerActivityLevelsApplyReq extends NetHandler { + + @Override + public byte[] handle(GameSession session, byte[] message) throws Exception { + // Parse req + var req = ActivityLevelsApplyReq.parseFrom(message); + + // Get activity + var activity = session.getPlayer().getActivityManager().getActivity(LevelsActivity.class, req.getActivityId()); + + if (activity == null) { + return session.encodeMsg(NetMsgId.activity_levels_apply_failed_ack); + } + + // Apply + boolean success = activity.apply(req.getLevelId(), req.getBuildId()); + + if (success == false) { + return session.encodeMsg(NetMsgId.activity_levels_apply_failed_ack); + } + + // Encode and send + return session.encodeMsg(NetMsgId.activity_levels_apply_succeed_ack); + } + +} diff --git a/src/main/java/emu/nebula/server/handlers/HandlerActivityLevelsSettleReq.java b/src/main/java/emu/nebula/server/handlers/HandlerActivityLevelsSettleReq.java new file mode 100644 index 0000000..739afff --- /dev/null +++ b/src/main/java/emu/nebula/server/handlers/HandlerActivityLevelsSettleReq.java @@ -0,0 +1,56 @@ +package emu.nebula.server.handlers; + +import emu.nebula.net.NetHandler; +import emu.nebula.net.NetMsgId; +import emu.nebula.proto.ActivityLevelsSettle.ActivityLevelsSettleReq; +import emu.nebula.proto.ActivityLevelsSettle.ActivityLevelsSettleResp; +import emu.nebula.net.HandlerId; +import emu.nebula.game.activity.type.LevelsActivity; +import emu.nebula.game.instance.InstanceSettleData; +import emu.nebula.net.GameSession; + +@HandlerId(NetMsgId.activity_levels_settle_req) +public class HandlerActivityLevelsSettleReq extends NetHandler { + + @Override + public byte[] handle(GameSession session, byte[] message) throws Exception { + // Parse request + var req = ActivityLevelsSettleReq.parseFrom(message); + + // Get activity + var activity = session.getPlayer().getActivityManager().getActivity(LevelsActivity.class, req.getActivityId()); + + if (activity == null || activity.getLevel() == null) { + return session.encodeMsg(NetMsgId.activity_levels_settle_failed_ack); + } + + // Settle + var change = activity.settle(req.getStar()); + + if (change == null) { + return session.encodeMsg(NetMsgId.activity_levels_settle_failed_ack); + } + + var settleData = (InstanceSettleData) change.getExtraData(); + + // Handle client events for achievements + session.getPlayer().getAchievementManager().handleClientEvents(req.getEvents()); + + // Build response + var rsp = ActivityLevelsSettleResp.newInstance() + .setExp(settleData.getExp()) + .setChangeInfo(change.toProto()); + + // Add reward items + if (settleData.getRewards() != null) { + settleData.getRewards().toItemTemplateStream().forEach(rsp::addFixed); + } + if (settleData.getFirstRewards() != null) { + settleData.getFirstRewards().toItemTemplateStream().forEach(rsp::addFirst); + } + + // Encode and send + return session.encodeMsg(NetMsgId.activity_levels_settle_succeed_ack, rsp); + } + +} diff --git a/src/main/java/emu/nebula/server/handlers/HandlerActivityLevelsSweepReq.java b/src/main/java/emu/nebula/server/handlers/HandlerActivityLevelsSweepReq.java new file mode 100644 index 0000000..b16c470 --- /dev/null +++ b/src/main/java/emu/nebula/server/handlers/HandlerActivityLevelsSweepReq.java @@ -0,0 +1,70 @@ +package emu.nebula.server.handlers; + +import emu.nebula.net.NetHandler; +import emu.nebula.net.NetMsgId; +import emu.nebula.proto.ActivityLevelsSweep.ActivityLevelsSweepReq; +import emu.nebula.proto.ActivityLevelsSweep.ActivityLevelsSweepResp; +import emu.nebula.proto.ActivityLevelsSweep.ActivityLevelsSweepReward; +import emu.nebula.net.HandlerId; +import emu.nebula.data.GameData; +import emu.nebula.game.activity.type.LevelsActivity; +import emu.nebula.game.inventory.ItemParamMap; +import emu.nebula.net.GameSession; + +import java.util.List; + +@HandlerId(NetMsgId.activity_levels_sweep_req) +public class HandlerActivityLevelsSweepReq extends NetHandler { + + @Override + public byte[] handle(GameSession session, byte[] message) throws Exception { + // Parse request + var req = ActivityLevelsSweepReq.parseFrom(message); + + // Get activity + var activity = session.getPlayer().getActivityManager().getActivity(LevelsActivity.class, req.getActivityId()); + + if (activity == null) { + return session.encodeMsg(NetMsgId.activity_levels_sweep_failed_ack); + } + + // Get level data + var data = GameData.getActivityLevelsLevelDataTable().get(req.getLevelId()); + if (data == null) { + return session.encodeMsg(NetMsgId.activity_levels_sweep_failed_ack); + } + + // Settle + var change = activity.sweep(data, req.getTimes()); + + if (change == null) { + return session.encodeMsg(NetMsgId.activity_levels_sweep_failed_ack); + } + + // Handle client events for achievements + session.getPlayer().getAchievementManager().handleClientEvents(req.getEvents()); + + // Build response + var rsp = ActivityLevelsSweepResp.newInstance() + .setChangeInfo(change.toProto()); + + // Add reward list to response + if (change.getExtraData() != null) { + @SuppressWarnings("unchecked") + var list = (List) change.getExtraData(); + + for (var rewards : list) { + var reward = ActivityLevelsSweepReward.newInstance() + .setExp(data.getEnergyConsume()); + + rewards.toItemTemplateStream().forEach(reward::addAwardItems); + + rsp.addRewards(reward); + } + } + + // Encode and send + return session.encodeMsg(NetMsgId.activity_levels_sweep_succeed_ack, rsp); + } + +} diff --git a/src/main/java/emu/nebula/server/handlers/HandlerActivityShopPurchaseReq.java b/src/main/java/emu/nebula/server/handlers/HandlerActivityShopPurchaseReq.java new file mode 100644 index 0000000..3515e4d --- /dev/null +++ b/src/main/java/emu/nebula/server/handlers/HandlerActivityShopPurchaseReq.java @@ -0,0 +1,50 @@ +package emu.nebula.server.handlers; + +import emu.nebula.net.NetHandler; +import emu.nebula.net.NetMsgId; +import emu.nebula.proto.ActivityShopPurchase.ActivityShopPurchaseReq; +import emu.nebula.proto.ActivityShopPurchase.ActivityShopPurchaseResp; +import emu.nebula.net.HandlerId; +import emu.nebula.game.activity.type.ShopActivity; +import emu.nebula.game.activity.type.ShopActivity.ActivityShopInfo; +import emu.nebula.net.GameSession; + +@HandlerId(NetMsgId.activity_shop_purchase_req) +public class HandlerActivityShopPurchaseReq extends NetHandler { + + @Override + public byte[] handle(GameSession session, byte[] message) throws Exception { + // Parse request + var req = ActivityShopPurchaseReq.parseFrom(message); + + // Get activity + var activity = session.getPlayer().getActivityManager().getActivity(ShopActivity.class, req.getActivityId()); + + if (activity == null) { + return session.encodeMsg(NetMsgId.activity_shop_purchase_failed_ack); + } + + // Buy + var change = activity.buy(req.getShopId(), req.getGoodsId(), req.getNumber()); + + if (change == null) { + return session.encodeMsg(NetMsgId.activity_shop_purchase_failed_ack); + } + + // Build response + var rsp = ActivityShopPurchaseResp.newInstance() + .setChange(change.toProto()) + .setPurchasedNumber(req.getNumber()); + + // Set shop info + var shop = (ActivityShopInfo) change.getExtraData(); + var shopInfo = shop.toProto() + .setId(req.getShopId()); + + rsp.setShop(shopInfo); + + // Encode and send + return session.encodeMsg(NetMsgId.activity_shop_purchase_succeed_ack, rsp); + } + +} diff --git a/src/main/java/emu/nebula/server/handlers/HandlerCharGemInstanceSettleReq.java b/src/main/java/emu/nebula/server/handlers/HandlerCharGemInstanceSettleReq.java index 6ef3212..637b930 100644 --- a/src/main/java/emu/nebula/server/handlers/HandlerCharGemInstanceSettleReq.java +++ b/src/main/java/emu/nebula/server/handlers/HandlerCharGemInstanceSettleReq.java @@ -28,7 +28,7 @@ public class HandlerCharGemInstanceSettleReq extends NetHandler { var req = CharGemInstanceSettleReq.parseFrom(message); // Settle instance - var changes = player.getInstanceManager().settleInstance( + var change = player.getInstanceManager().settleInstance( data, QuestCondition.CharGemInstanceClearTotal, player.getProgress().getCharGemLog(), @@ -36,7 +36,7 @@ public class HandlerCharGemInstanceSettleReq extends NetHandler { req.getStar() ); - var settleData = (InstanceSettleData) changes.getExtraData(); + var settleData = (InstanceSettleData) change.getExtraData(); // Handle client events for achievements session.getPlayer().getAchievementManager().handleClientEvents(req.getEvents()); @@ -45,7 +45,7 @@ public class HandlerCharGemInstanceSettleReq extends NetHandler { var rsp = CharGemInstanceSettleResp.newInstance() .setExp(settleData.getExp()) .setThreeStar(req.getStar() == 7) - .setChange(changes.toProto()); + .setChange(change.toProto()); // Add reward items if (settleData.getRewards() != null) {