Implement new event

This commit is contained in:
Melledy
2025-12-08 22:28:47 -08:00
parent 80a181680b
commit c5f339c8be
20 changed files with 1020 additions and 8 deletions

View File

@@ -155,4 +155,16 @@ public class GameData {
// Activity: Trials // Activity: Trials
@Getter private static DataTable<TrialControlDef> TrialControlDataTable = new DataTable<>(); @Getter private static DataTable<TrialControlDef> TrialControlDataTable = new DataTable<>();
@Getter private static DataTable<TrialGroupDef> TrialGroupDataTable = new DataTable<>(); @Getter private static DataTable<TrialGroupDef> TrialGroupDataTable = new DataTable<>();
// Activity: Levels
@Getter private static DataTable<ActivityLevelsLevelDef> ActivityLevelsLevelDataTable = new DataTable<>();
// Activity: Task
@Getter private static DataTable<ActivityTaskDef> ActivityTaskDataTable = new DataTable<>();
@Getter private static DataTable<ActivityTaskGroupDef> ActivityTaskGroupDataTable = new DataTable<>();
// Activity: Shop
@Getter private static DataTable<ActivityShopDef> ActivityShopDataTable = new DataTable<>();
@Getter private static DataTable<ActivityShopControlDef> ActivityShopControlDataTable = new DataTable<>();
@Getter private static DataTable<ActivityGoodsDef> ActivityGoodsDataTable = new DataTable<>();
} }

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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<ActivityGoodsDef> goods;
@Override
public int getId() {
return Id;
}
@Override
public void onLoad() {
this.goods = new Int2ObjectOpenHashMap<>();
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -109,9 +109,13 @@ public class ActivityManager extends PlayerManager implements GameDatabaseObject
return null; return null;
} }
// TODO improve activity creation
GameActivity activity = switch (data.getType()) { GameActivity activity = switch (data.getType()) {
case Trial -> new TrialActivity(this, data);
case TowerDefense -> new TowerDefenseActivity(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; default -> null;
}; };

View File

@@ -15,12 +15,20 @@ public class ActivityModule extends GameContextModule {
this.activities = new IntArrayList(); this.activities = new IntArrayList();
// Hardcode these activities for now // Hardcode these activities for now
this.activities.add(700102); // TODO make an activity json file to read activity ids from
this.activities.add(700103);
// Trial activities
this.activities.add(700104); this.activities.add(700104);
this.activities.add(700107); 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(101002);
//this.activities.add(101003); //this.activities.add(101003);

View File

@@ -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;
}
}

View File

@@ -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<Integer, ActivityLevelInfo> 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<ItemParamMap>();
// 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;
}
}
}

View File

@@ -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<Integer, ActivityShopInfo> 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;
}
}
}

View File

@@ -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<Integer, ActivityTaskQuest> 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());
}
}
}

View File

@@ -17,6 +17,10 @@ public class InstanceSettleData {
} }
public void generateRewards(InstanceData data) {
this.generateRewards(data, 0);
}
public void generateRewards(InstanceData data, int rewardType) { public void generateRewards(InstanceData data, int rewardType) {
if (this.isFirst) { if (this.isFirst) {
this.firstRewards = data.getFirstRewards(rewardType).generate(); this.firstRewards = data.getFirstRewards(rewardType).generate();

View File

@@ -10,7 +10,7 @@ public class Handler extends NetHandler {
@Override @Override
public byte[] handle(GameSession session, byte[] message) throws Exception { public byte[] handle(GameSession session, byte[] message) throws Exception {
// Template hanlder // Template handler
// Encode and send // Encode and send
return session.encodeMsg(NetMsgId.none); return session.encodeMsg(NetMsgId.none);

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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<ItemParamMap>) 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);
}
}

View File

@@ -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);
}
}

View File

@@ -28,7 +28,7 @@ public class HandlerCharGemInstanceSettleReq extends NetHandler {
var req = CharGemInstanceSettleReq.parseFrom(message); var req = CharGemInstanceSettleReq.parseFrom(message);
// Settle instance // Settle instance
var changes = player.getInstanceManager().settleInstance( var change = player.getInstanceManager().settleInstance(
data, data,
QuestCondition.CharGemInstanceClearTotal, QuestCondition.CharGemInstanceClearTotal,
player.getProgress().getCharGemLog(), player.getProgress().getCharGemLog(),
@@ -36,7 +36,7 @@ public class HandlerCharGemInstanceSettleReq extends NetHandler {
req.getStar() req.getStar()
); );
var settleData = (InstanceSettleData) changes.getExtraData(); var settleData = (InstanceSettleData) change.getExtraData();
// Handle client events for achievements // Handle client events for achievements
session.getPlayer().getAchievementManager().handleClientEvents(req.getEvents()); session.getPlayer().getAchievementManager().handleClientEvents(req.getEvents());
@@ -45,7 +45,7 @@ public class HandlerCharGemInstanceSettleReq extends NetHandler {
var rsp = CharGemInstanceSettleResp.newInstance() var rsp = CharGemInstanceSettleResp.newInstance()
.setExp(settleData.getExp()) .setExp(settleData.getExp())
.setThreeStar(req.getStar() == 7) .setThreeStar(req.getStar() == 7)
.setChange(changes.toProto()); .setChange(change.toProto());
// Add reward items // Add reward items
if (settleData.getRewards() != null) { if (settleData.getRewards() != null) {