mirror of
https://github.com/Melledy/Nebula.git
synced 2026-11-04 21:36:51 +01:00
Implement dorm quests
This commit is contained in:
1 parent
1b745a5cc5
commit
4a2ab5cd48
9 files changed
+616
-14
No files matched your search
@@ -0,0 +1,31 @@
|
|||||||
|
package emu.nebula.data.custom;
|
||||||
|
|
||||||
|
import emu.nebula.data.BaseDef;
|
||||||
|
import emu.nebula.data.GameData;
|
||||||
|
import emu.nebula.data.ResourceType;
|
||||||
|
import emu.nebula.data.ResourceType.LoadPriority;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@ResourceType(name = "DormQuestParam.json", useInternal = true, loadPriority = LoadPriority.LOW)
|
||||||
|
public class DormQuestParamDef extends BaseDef {
|
||||||
|
private int Id;
|
||||||
|
|
||||||
|
private int CompleteCond;
|
||||||
|
private int[] CondParams;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
var quest = GameData.getDormQuestDataTable().get(this.Id);
|
||||||
|
if (quest == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
quest.setParams(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,15 @@ package emu.nebula.data.resources;
|
|||||||
|
|
||||||
import emu.nebula.data.BaseDef;
|
import emu.nebula.data.BaseDef;
|
||||||
import emu.nebula.data.ResourceType;
|
import emu.nebula.data.ResourceType;
|
||||||
|
import emu.nebula.data.custom.DormQuestParamDef;
|
||||||
|
import emu.nebula.game.inventory.ItemParamMap;
|
||||||
|
import emu.nebula.game.quest.QuestData;
|
||||||
|
import emu.nebula.game.quest.QuestType;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@ResourceType(name = "DormQuest.json")
|
@ResourceType(name = "DormQuest.json")
|
||||||
public class DormQuestDef extends BaseDef {
|
public class DormQuestDef extends BaseDef implements QuestData {
|
||||||
private int Id;
|
private int Id;
|
||||||
private int DormQuestGroup;
|
private int DormQuestGroup;
|
||||||
private String Title;
|
private String Title;
|
||||||
@@ -15,8 +19,56 @@ public class DormQuestDef extends BaseDef {
|
|||||||
private int Reward2;
|
private int Reward2;
|
||||||
private int RewardQty2;
|
private int RewardQty2;
|
||||||
|
|
||||||
|
// Cached rewards
|
||||||
|
private transient ItemParamMap rewards;
|
||||||
|
|
||||||
|
// Custom params (loaded from defs/DormQuestParam.json)
|
||||||
|
private transient int completeCond;
|
||||||
|
private transient int[] condParams;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return Id;
|
return Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getQuestType() {
|
||||||
|
return QuestType.Dorm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCompleteCond() {
|
||||||
|
return this.completeCond;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int[] getCompleteCondParams() {
|
||||||
|
if (this.condParams == null) {
|
||||||
|
this.condParams = new int[] { 1 };
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.condParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the condition params from the internal defs file.
|
||||||
|
*/
|
||||||
|
public void setParams(DormQuestParamDef params) {
|
||||||
|
this.completeCond = params.getCompleteCond();
|
||||||
|
this.condParams = params.getCondParams();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
// Cache rewards into an item param map
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package emu.nebula.data.resources;
|
|||||||
|
|
||||||
import emu.nebula.data.BaseDef;
|
import emu.nebula.data.BaseDef;
|
||||||
import emu.nebula.data.ResourceType;
|
import emu.nebula.data.ResourceType;
|
||||||
|
import emu.nebula.game.inventory.ItemParamMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@@ -17,8 +18,29 @@ public class DormQuestGroupDef extends BaseDef {
|
|||||||
private int Item3;
|
private int Item3;
|
||||||
private int Qty3;
|
private int Qty3;
|
||||||
|
|
||||||
|
// Cached rewards
|
||||||
|
private transient ItemParamMap rewards;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return Id;
|
return Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
// Cache rewards into an item param map
|
||||||
|
this.rewards = new ItemParamMap();
|
||||||
|
|
||||||
|
if (this.Item1 > 0) {
|
||||||
|
this.rewards.add(this.Item1, this.Qty1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.Item2 > 0) {
|
||||||
|
this.rewards.add(this.Item2, this.Qty2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.Item3 > 0) {
|
||||||
|
this.rewards.add(this.Item3, this.Qty3);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ package emu.nebula.data.resources;
|
|||||||
import emu.nebula.data.BaseDef;
|
import emu.nebula.data.BaseDef;
|
||||||
import emu.nebula.data.ResourceType;
|
import emu.nebula.data.ResourceType;
|
||||||
import emu.nebula.data.custom.StarTowerQuestParamDef;
|
import emu.nebula.data.custom.StarTowerQuestParamDef;
|
||||||
|
import emu.nebula.game.inventory.ItemParamMap;
|
||||||
import emu.nebula.game.quest.QuestData;
|
import emu.nebula.game.quest.QuestData;
|
||||||
import emu.nebula.game.quest.QuestType;
|
import emu.nebula.game.quest.QuestType;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -21,6 +22,9 @@ public class StarTowerQuestDef extends BaseDef implements QuestData {
|
|||||||
private int Reward2;
|
private int Reward2;
|
||||||
private int RewardQty2;
|
private int RewardQty2;
|
||||||
|
|
||||||
|
// Cached rewards
|
||||||
|
private transient ItemParamMap rewards;
|
||||||
|
|
||||||
// Custom params (loaded from defs/StarTowerQuestParam.json)
|
// Custom params (loaded from defs/StarTowerQuestParam.json)
|
||||||
private transient int completeCond;
|
private transient int completeCond;
|
||||||
private transient int aim;
|
private transient int aim;
|
||||||
@@ -74,5 +78,16 @@ public class StarTowerQuestDef extends BaseDef implements QuestData {
|
|||||||
if (this.PreTowerQuestIds == null) {
|
if (this.PreTowerQuestIds == null) {
|
||||||
this.PreTowerQuestIds = new int[0];
|
this.PreTowerQuestIds = new int[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cache rewards into an item param map
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@ import dev.morphia.annotations.Id;
|
|||||||
import emu.nebula.GameConstants;
|
import emu.nebula.GameConstants;
|
||||||
import emu.nebula.Nebula;
|
import emu.nebula.Nebula;
|
||||||
import emu.nebula.data.GameData;
|
import emu.nebula.data.GameData;
|
||||||
|
import emu.nebula.data.resources.DormQuestDef;
|
||||||
import emu.nebula.data.resources.DormRoomDef;
|
import emu.nebula.data.resources.DormRoomDef;
|
||||||
import emu.nebula.data.resources.DropPkgDef;
|
import emu.nebula.data.resources.DropPkgDef;
|
||||||
import emu.nebula.database.GameDatabaseObject;
|
import emu.nebula.database.GameDatabaseObject;
|
||||||
@@ -19,7 +20,9 @@ import emu.nebula.game.inventory.ItemParamMap;
|
|||||||
import emu.nebula.game.player.Player;
|
import emu.nebula.game.player.Player;
|
||||||
import emu.nebula.game.player.PlayerChangeInfo;
|
import emu.nebula.game.player.PlayerChangeInfo;
|
||||||
import emu.nebula.game.player.PlayerManager;
|
import emu.nebula.game.player.PlayerManager;
|
||||||
|
import emu.nebula.game.quest.GameQuest;
|
||||||
import emu.nebula.game.quest.QuestCondition;
|
import emu.nebula.game.quest.QuestCondition;
|
||||||
|
import emu.nebula.game.quest.QuestType;
|
||||||
import emu.nebula.net.NetMsgId;
|
import emu.nebula.net.NetMsgId;
|
||||||
import emu.nebula.proto.DormInfo.DormInfoListResp;
|
import emu.nebula.proto.DormInfo.DormInfoListResp;
|
||||||
import emu.nebula.proto.Public;
|
import emu.nebula.proto.Public;
|
||||||
@@ -74,6 +77,12 @@ public class DormManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
private Int2IntMap dailyAffinityGiftCounts;
|
private Int2IntMap dailyAffinityGiftCounts;
|
||||||
private int dailyAffinityGiftTotal;
|
private int dailyAffinityGiftTotal;
|
||||||
|
|
||||||
|
// Quests
|
||||||
|
private int questGroup;
|
||||||
|
private int questGroupState;
|
||||||
|
private int interactionTotal;
|
||||||
|
private int rewardClaimTotal;
|
||||||
|
|
||||||
private transient boolean queueSave;
|
private transient boolean queueSave;
|
||||||
|
|
||||||
@Deprecated // Morphia only
|
@Deprecated // Morphia only
|
||||||
@@ -98,6 +107,9 @@ public class DormManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
this.dailyAffinityGiftCounts = new Int2IntOpenHashMap();
|
this.dailyAffinityGiftCounts = new Int2IntOpenHashMap();
|
||||||
this.lastResetDay = Utils.getResetEpochDay();
|
this.lastResetDay = Utils.getResetEpochDay();
|
||||||
|
|
||||||
|
// Add the quests of the first dorm quest group
|
||||||
|
this.initQuests();
|
||||||
|
|
||||||
this.save();
|
this.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,6 +132,7 @@ public class DormManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
this.dailyAffinityGiftCounts.clear();
|
this.dailyAffinityGiftCounts.clear();
|
||||||
this.dailyAffinityGiftTotal = 0;
|
this.dailyAffinityGiftTotal = 0;
|
||||||
this.dayVisitNum = 0;
|
this.dayVisitNum = 0;
|
||||||
|
this.receivedRewardIds.clear();
|
||||||
this.lastResetDay = currentDay;
|
this.lastResetDay = currentDay;
|
||||||
this.queueSave = true;
|
this.queueSave = true;
|
||||||
}
|
}
|
||||||
@@ -184,7 +197,7 @@ public class DormManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
this.getOrCreateRoom(roomId);
|
this.getOrCreateRoom(roomId);
|
||||||
|
|
||||||
if (change != null) {
|
if (change != null) {
|
||||||
this.getPlayer().trigger(QuestCondition.DormUnlockRoom, 1);
|
this.getPlayer().trigger(QuestCondition.DormUnlockRoom, 1, roomId);
|
||||||
|
|
||||||
if (this.getPlayer().hasSession()) {
|
if (this.getPlayer().hasSession()) {
|
||||||
var proto = DormRoomUnlock.newInstance()
|
var proto = DormRoomUnlock.newInstance()
|
||||||
@@ -204,8 +217,15 @@ public class DormManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
* Adds furniture to the collection
|
* Adds furniture to the collection
|
||||||
*/
|
*/
|
||||||
public synchronized void addFurniture(int id, int amount) {
|
public synchronized void addFurniture(int id, int amount) {
|
||||||
this.furnitureCollection.put(id, this.furnitureCollection.get(id) + amount);
|
int oldCount = this.furnitureCollection.get(id);
|
||||||
|
|
||||||
|
this.furnitureCollection.put(id, oldCount + amount);
|
||||||
this.queueSave = true;
|
this.queueSave = true;
|
||||||
|
|
||||||
|
// New furniture types count towards collection quests
|
||||||
|
if (oldCount <= 0 && amount > 0) {
|
||||||
|
this.getPlayer().trigger(QuestCondition.DormFurnitureCollect, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -291,8 +311,16 @@ public class DormManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
room.setFurnitureList(new ArrayList<>(furnitureList));
|
room.setFurnitureList(new ArrayList<>(furnitureList));
|
||||||
this.queueSave = true;
|
this.queueSave = true;
|
||||||
|
|
||||||
this.getPlayer().trigger(QuestCondition.DormPlaceFurniture, furnitureList.size());
|
// Trigger furniture quests for each different furniture that is placed
|
||||||
this.getPlayer().trigger(QuestCondition.DormSaveRoom, 1);
|
var placedFurniture = new IntOpenHashSet();
|
||||||
|
|
||||||
|
for (var furniture : furnitureList) {
|
||||||
|
if (placedFurniture.add(furniture.getFurnitureId())) {
|
||||||
|
this.getPlayer().trigger(QuestCondition.DormPlaceFurniture, 1, furniture.getFurnitureId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getPlayer().trigger(QuestCondition.DormSaveRoom, 1, roomId);
|
||||||
|
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
@@ -551,6 +579,11 @@ public class DormManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.addInteractionRole(roleId);
|
this.addInteractionRole(roleId);
|
||||||
|
|
||||||
|
// Track total interactions for quests
|
||||||
|
this.interactionTotal++;
|
||||||
|
this.queueSave = true;
|
||||||
|
|
||||||
this.getPlayer().trigger(QuestCondition.DormRoleInteractionReward, 1);
|
this.getPlayer().trigger(QuestCondition.DormRoleInteractionReward, 1);
|
||||||
|
|
||||||
return dropItemId;
|
return dropItemId;
|
||||||
@@ -849,6 +882,9 @@ public class DormManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
// Queue a save call for the dorm
|
// Queue a save call for the dorm
|
||||||
this.queueSave = true;
|
this.queueSave = true;
|
||||||
|
|
||||||
|
// Track the total amount of claimed dorm daily gifts for quests
|
||||||
|
this.rewardClaimTotal++;
|
||||||
|
|
||||||
// Trigger quest
|
// Trigger quest
|
||||||
this.getPlayer().trigger(QuestCondition.DormDailyReceiveReward, 1);
|
this.getPlayer().trigger(QuestCondition.DormDailyReceiveReward, 1);
|
||||||
|
|
||||||
@@ -934,6 +970,312 @@ public class DormManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
return proto;
|
return proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quests
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the dorm quest group state and adds the quests of the current
|
||||||
|
* group. Also used to add quests for players that don't have them yet.
|
||||||
|
*
|
||||||
|
* @return true if the dorm quest state changed
|
||||||
|
*/
|
||||||
|
public synchronized boolean initQuests() {
|
||||||
|
var player = this.getPlayer();
|
||||||
|
|
||||||
|
if (player == null || player.getQuestManager() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean changed = false;
|
||||||
|
|
||||||
|
// Start the first group for players that haven't started the quest chain
|
||||||
|
if (this.questGroup <= 0 && this.questGroupState == 0) {
|
||||||
|
int firstGroupId = this.getFirstQuestGroupId();
|
||||||
|
|
||||||
|
if (firstGroupId <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.questGroup = firstGroupId;
|
||||||
|
this.questGroupState = 0;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the quests of the current group
|
||||||
|
if (this.questGroup > 0 && this.addQuestGroup(this.questGroup)) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the quests of the given group to the quest manager.
|
||||||
|
*
|
||||||
|
* @return true if any quest was added
|
||||||
|
*/
|
||||||
|
private synchronized boolean addQuestGroup(int groupId) {
|
||||||
|
var questManager = this.getPlayer().getQuestManager();
|
||||||
|
boolean changed = false;
|
||||||
|
|
||||||
|
for (var data : GameData.getDormQuestDataTable()) {
|
||||||
|
if (data.getDormQuestGroup() != groupId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip quests that already exist
|
||||||
|
if (questManager.getQuest(QuestType.Dorm, data.getId()) != null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the quest
|
||||||
|
var quest = questManager.addQuest(new GameQuest(data));
|
||||||
|
|
||||||
|
// Initialize the progress from the current dorm state
|
||||||
|
int progress = this.getQuestProgress(data);
|
||||||
|
if (progress > 0) {
|
||||||
|
quest.setProgress(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync the quest with the client
|
||||||
|
questManager.syncQuest(quest);
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
questManager.save();
|
||||||
|
this.queueSave = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the initial progress of a dorm quest based on the current dorm
|
||||||
|
* state. Dorm quest goals are absolute totals, so quests that are added later
|
||||||
|
* start with the progress the player has already made.
|
||||||
|
*/
|
||||||
|
private int getQuestProgress(DormQuestDef data) {
|
||||||
|
int[] params = data.getCompleteCondParams();
|
||||||
|
int goal = params.length > 0 ? Math.max(params[0], 0) : 0;
|
||||||
|
int param = params.length > 1 ? params[1] : 0;
|
||||||
|
int cond = data.getCompleteCond();
|
||||||
|
|
||||||
|
if (cond == QuestCondition.DormUnlockRoom.getValue()) {
|
||||||
|
return this.isRoomUnlocked(param) ? goal : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cond == QuestCondition.DormPlaceFurniture.getValue()) {
|
||||||
|
return this.isFurniturePlaced(param) ? goal : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cond == QuestCondition.DormFurnitureCollect.getValue()) {
|
||||||
|
return Math.min(this.getDistinctFurnitureCount(), goal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cond == QuestCondition.DormRoleInteractionReward.getValue()) {
|
||||||
|
return Math.min(this.interactionTotal, goal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cond == QuestCondition.DormDailyReceiveReward.getValue()) {
|
||||||
|
return Math.min(this.rewardClaimTotal, goal);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the amount of different furniture types the player has collected.
|
||||||
|
*/
|
||||||
|
public int getDistinctFurnitureCount() {
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
for (var entry : this.furnitureCollection.int2IntEntrySet()) {
|
||||||
|
if (entry.getIntValue() > 0) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given furniture is placed in one of the player's rooms.
|
||||||
|
*/
|
||||||
|
public boolean isFurniturePlaced(int furnitureId) {
|
||||||
|
if (furnitureId <= 0 || this.rooms == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var room : this.rooms.values()) {
|
||||||
|
if (room.getFurnitureList() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var furniture : room.getFurnitureList()) {
|
||||||
|
if (furniture.getFurnitureId() == furnitureId) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the id of the first dorm quest group.
|
||||||
|
*/
|
||||||
|
private int getFirstQuestGroupId() {
|
||||||
|
int firstId = 0;
|
||||||
|
|
||||||
|
for (var group : GameData.getDormQuestGroupDataTable()) {
|
||||||
|
// The first group has no prerequisite group
|
||||||
|
if (group.getPreGroup() != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstId == 0 || group.getId() < firstId) {
|
||||||
|
firstId = group.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return firstId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the id of the quest group that follows the given group.
|
||||||
|
*/
|
||||||
|
private int getNextQuestGroupId(int groupId) {
|
||||||
|
int nextId = 0;
|
||||||
|
|
||||||
|
for (var group : GameData.getDormQuestGroupDataTable()) {
|
||||||
|
if (group.getPreGroup() != groupId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextId == 0 || group.getId() < nextId) {
|
||||||
|
nextId = group.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives dorm quest or quest group rewards.
|
||||||
|
*
|
||||||
|
* @param type 0 = quest, 1 = quest group
|
||||||
|
* @param id the quest id, or 0 to claim all claimable quests; the group id for group rewards
|
||||||
|
* @return the reward changes, or null if nothing was claimed
|
||||||
|
*/
|
||||||
|
public synchronized PlayerChangeInfo receiveQuestRewards(int type, int id) {
|
||||||
|
if (type == 1) {
|
||||||
|
return this.receiveQuestGroupReward(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.receiveQuestReward(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized PlayerChangeInfo receiveQuestReward(int questId) {
|
||||||
|
var questManager = this.getPlayer().getQuestManager();
|
||||||
|
var claimList = new ArrayList<DormQuestDef>();
|
||||||
|
|
||||||
|
if (questId > 0) {
|
||||||
|
// Claim a specific quest
|
||||||
|
var data = GameData.getDormQuestDataTable().get(questId);
|
||||||
|
|
||||||
|
if (data != null && data.getDormQuestGroup() == this.questGroup) {
|
||||||
|
var quest = questManager.getQuest(QuestType.Dorm, questId);
|
||||||
|
|
||||||
|
if (quest != null && quest.canClaim()) {
|
||||||
|
claimList.add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Claim all claimable quests of the current group
|
||||||
|
for (var data : GameData.getDormQuestDataTable()) {
|
||||||
|
if (data.getDormQuestGroup() != this.questGroup) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var quest = questManager.getQuest(QuestType.Dorm, data.getId());
|
||||||
|
|
||||||
|
if (quest != null && quest.canClaim()) {
|
||||||
|
claimList.add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (claimList.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add rewards
|
||||||
|
var rewards = new ItemParamMap();
|
||||||
|
|
||||||
|
for (var data : claimList) {
|
||||||
|
var quest = questManager.getQuest(QuestType.Dorm, data.getId());
|
||||||
|
|
||||||
|
// Add rewards
|
||||||
|
rewards.add(data.getRewards());
|
||||||
|
|
||||||
|
// Mark the quest as claimed
|
||||||
|
quest.setClaimed(true);
|
||||||
|
questManager.saveQuest(quest);
|
||||||
|
questManager.syncQuest(quest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getPlayer().getInventory().addItems(rewards);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized PlayerChangeInfo receiveQuestGroupReward(int groupId) {
|
||||||
|
// Only the current group's reward can be received
|
||||||
|
if (groupId <= 0 || groupId != this.questGroup || this.questGroupState != 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var groupData = GameData.getDormQuestGroupDataTable().get(groupId);
|
||||||
|
if (groupData == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure all quests of the group have been claimed
|
||||||
|
var questManager = this.getPlayer().getQuestManager();
|
||||||
|
|
||||||
|
for (var data : GameData.getDormQuestDataTable()) {
|
||||||
|
if (data.getDormQuestGroup() != groupId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var quest = questManager.getQuest(QuestType.Dorm, data.getId());
|
||||||
|
|
||||||
|
if (quest == null || !quest.isClaimed()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add rewards
|
||||||
|
var rewards = groupData.getRewards();
|
||||||
|
|
||||||
|
// Advance to the next quest group
|
||||||
|
int nextGroupId = this.getNextQuestGroupId(groupId);
|
||||||
|
|
||||||
|
if (nextGroupId > 0) {
|
||||||
|
this.questGroup = nextGroupId;
|
||||||
|
this.questGroupState = 0;
|
||||||
|
|
||||||
|
this.addQuestGroup(nextGroupId);
|
||||||
|
} else {
|
||||||
|
// All dorm quest groups have been completed
|
||||||
|
this.questGroup = 0;
|
||||||
|
this.questGroupState = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.queueSave = true;
|
||||||
|
|
||||||
|
return this.getPlayer().getInventory().addItems(rewards);
|
||||||
|
}
|
||||||
|
|
||||||
// Social
|
// Social
|
||||||
|
|
||||||
public boolean hasLikedFriend(int uid) {
|
public boolean hasLikedFriend(int uid) {
|
||||||
@@ -993,7 +1335,11 @@ public class DormManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
.setDayVisitNum(this.dayVisitNum)
|
.setDayVisitNum(this.dayVisitNum)
|
||||||
.setVisitTotalNum(this.visitTotalNum)
|
.setVisitTotalNum(this.visitTotalNum)
|
||||||
.setRestNameTime(this.dormNameRestTime)
|
.setRestNameTime(this.dormNameRestTime)
|
||||||
.setTaskGroup(Public.UI32V.newInstance().setValue(0).setVersion(0));
|
.setTaskGroup(
|
||||||
|
Public.UI32V.newInstance()
|
||||||
|
.setValue(this.questGroupState)
|
||||||
|
.setVersion(this.questGroup)
|
||||||
|
);
|
||||||
|
|
||||||
var rewardIds = new ArrayList<>(this.getClaimableRewardIds());
|
var rewardIds = new ArrayList<>(this.getClaimableRewardIds());
|
||||||
rewardIds.sort(Integer::compareTo);
|
rewardIds.sort(Integer::compareTo);
|
||||||
@@ -1037,6 +1383,14 @@ public class DormManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
|
|
||||||
// Database
|
// Database
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() {
|
||||||
|
// Add any missing dorm quests
|
||||||
|
if (this.initQuests()) {
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save() {
|
public void save() {
|
||||||
Nebula.getGameDatabase().save(this);
|
Nebula.getGameDatabase().save(this);
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
/**
|
/**
|
||||||
* Update this quest on the player client
|
* Update this quest on the player client
|
||||||
*/
|
*/
|
||||||
private void syncQuest(GameQuest quest) {
|
public void syncQuest(GameQuest quest) {
|
||||||
if (!getPlayer().hasSession()) {
|
if (!getPlayer().hasSession()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -333,13 +333,7 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
|
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
// Add rewards
|
// Add rewards
|
||||||
if (data.getReward1() > 0 && data.getRewardQty1() > 0) {
|
this.getPlayer().getInventory().addItems(data.getRewards(), change);
|
||||||
this.getPlayer().getInventory().addItem(data.getReward1(), data.getRewardQty1(), change);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.getReward2() > 0 && data.getRewardQty2() > 0) {
|
|
||||||
this.getPlayer().getInventory().addItem(data.getReward2(), data.getRewardQty2(), change);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set claimed
|
// Set claimed
|
||||||
@@ -730,6 +724,13 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persists a single quest to the database
|
||||||
|
*/
|
||||||
|
public void saveQuest(GameQuest quest) {
|
||||||
|
Nebula.getGameDatabase().update(this, this.getUid(), "list." + quest.getKey(), quest);
|
||||||
|
}
|
||||||
|
|
||||||
// Serialization
|
// Serialization
|
||||||
|
|
||||||
public void encodePlayerInfo(PlayerInfo proto) {
|
public void encodePlayerInfo(PlayerInfo proto) {
|
||||||
|
|||||||
@@ -17,4 +17,5 @@ public class QuestType {
|
|||||||
public static final int TowerEvent = 12;
|
public static final int TowerEvent = 12;
|
||||||
public static final int Weekly = 13;
|
public static final int Weekly = 13;
|
||||||
public static final int Assist = 14;
|
public static final int Assist = 14;
|
||||||
|
public static final int Dorm = 15;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package emu.nebula.server.handlers;
|
||||||
|
|
||||||
|
import emu.nebula.net.GameSession;
|
||||||
|
import emu.nebula.net.HandlerId;
|
||||||
|
import emu.nebula.net.NetHandler;
|
||||||
|
import emu.nebula.net.NetMsgId;
|
||||||
|
import emu.nebula.proto.Public.UI32V;
|
||||||
|
import emu.nebula.proto.QuestDormRewardRecevie.QuestDormRewardReceiveSucceedAck;
|
||||||
|
|
||||||
|
@HandlerId(NetMsgId.quest_dorm_reward_receive_req)
|
||||||
|
public class HandlerQuestDormRewardReceiveReq extends NetHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] handle(GameSession session, byte[] message) throws Exception {
|
||||||
|
// Parse request
|
||||||
|
var req = UI32V.parseFrom(message);
|
||||||
|
|
||||||
|
// Receive rewards
|
||||||
|
var dorm = session.getPlayer().getDormManager();
|
||||||
|
var change = dorm.receiveQuestRewards(req.getVersion(), req.getValue());
|
||||||
|
|
||||||
|
if (change == null) {
|
||||||
|
return session.encodeMsg(NetMsgId.quest_dorm_reward_receive_failed_ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build response
|
||||||
|
var rsp = QuestDormRewardReceiveSucceedAck.newInstance()
|
||||||
|
.setChangeInfo(change.toProto())
|
||||||
|
.setTaskGroup(
|
||||||
|
UI32V.newInstance()
|
||||||
|
.setValue(dorm.getQuestGroupState())
|
||||||
|
.setVersion(dorm.getQuestGroup())
|
||||||
|
);
|
||||||
|
|
||||||
|
// Encode and send
|
||||||
|
return session.encodeMsg(NetMsgId.quest_dorm_reward_receive_succeed_ack, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"Id": 500010,
|
||||||
|
"CompleteCond": 163,
|
||||||
|
"CondParams": [1, 701001]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500011,
|
||||||
|
"CompleteCond": 164,
|
||||||
|
"CondParams": [1, 700003]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500012,
|
||||||
|
"CompleteCond": 171,
|
||||||
|
"CondParams": [1]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500013,
|
||||||
|
"CompleteCond": 165,
|
||||||
|
"CondParams": [1]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500014,
|
||||||
|
"CompleteCond": 177,
|
||||||
|
"CondParams": [1, 701001]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500015,
|
||||||
|
"CompleteCond": 166,
|
||||||
|
"CondParams": [8]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500016,
|
||||||
|
"CompleteCond": 164,
|
||||||
|
"CondParams": [1, 700001]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500017,
|
||||||
|
"CompleteCond": 171,
|
||||||
|
"CondParams": [3]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500018,
|
||||||
|
"CompleteCond": 165,
|
||||||
|
"CondParams": [5]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500019,
|
||||||
|
"CompleteCond": 177,
|
||||||
|
"CondParams": [1, 701001]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500020,
|
||||||
|
"CompleteCond": 166,
|
||||||
|
"CondParams": [15]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500021,
|
||||||
|
"CompleteCond": 163,
|
||||||
|
"CondParams": [1, 701002]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500022,
|
||||||
|
"CompleteCond": 164,
|
||||||
|
"CondParams": [1, 700002]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500023,
|
||||||
|
"CompleteCond": 171,
|
||||||
|
"CondParams": [7]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500024,
|
||||||
|
"CompleteCond": 165,
|
||||||
|
"CondParams": [15]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500025,
|
||||||
|
"CompleteCond": 177,
|
||||||
|
"CondParams": [1, 701002]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": 500026,
|
||||||
|
"CompleteCond": 166,
|
||||||
|
"CondParams": [30]
|
||||||
|
}
|
||||||
|
]
|
||||||
Reference in new issue
Block a user