Implement daily activity missions

This commit is contained in:
Melledy
2025-11-07 05:29:57 -08:00
parent 67029b7094
commit ad538d59ed
26 changed files with 513 additions and 18 deletions

View File

@@ -63,6 +63,7 @@ public class GameData {
@Getter private static DataTable<StorySetSectionDef> StorySetSectionDataTable = new DataTable<>(); @Getter private static DataTable<StorySetSectionDef> StorySetSectionDataTable = new DataTable<>();
@Getter private static DataTable<DailyQuestDef> DailyQuestDataTable = new DataTable<>(); @Getter private static DataTable<DailyQuestDef> DailyQuestDataTable = new DataTable<>();
@Getter private static DataTable<DailyQuestActiveDef> DailyQuestActiveDataTable = new DataTable<>();
@Getter private static DataTable<StarTowerDef> StarTowerDataTable = new DataTable<>(); @Getter private static DataTable<StarTowerDef> StarTowerDataTable = new DataTable<>();
@Getter private static DataTable<StarTowerStageDef> StarTowerStageDataTable = new DataTable<>(); @Getter private static DataTable<StarTowerStageDef> StarTowerStageDataTable = new DataTable<>();

View File

@@ -0,0 +1,37 @@
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 = "DailyQuestActive.json")
public class DailyQuestActiveDef extends BaseDef {
private int Id;
private int Active;
private int ItemTid1;
private int Number1;
private int ItemTid2;
private int Number2;
private transient ItemParamMap rewards;
@Override
public int getId() {
return Id;
}
@Override
public void onLoad() {
this.rewards = new ItemParamMap();
if (this.ItemTid1 > 0 && this.Number1 > 0) {
this.rewards.add(this.ItemTid1, this.Number1);
}
if (this.ItemTid2 > 0 && this.Number2 > 0) {
this.rewards.add(this.ItemTid2, this.Number2);
}
}
}

View File

@@ -4,11 +4,10 @@ import java.util.Arrays;
import emu.nebula.data.BaseDef; import emu.nebula.data.BaseDef;
import emu.nebula.data.ResourceType; import emu.nebula.data.ResourceType;
import emu.nebula.data.ResourceType.LoadPriority;
import lombok.Getter; import lombok.Getter;
@Getter @Getter
@ResourceType(name = "DailyQuest.json", loadPriority = LoadPriority.LOW) @ResourceType(name = "DailyQuest.json")
public class DailyQuestDef extends BaseDef { public class DailyQuestDef extends BaseDef {
private int Id; private int Id;
private boolean Apear; private boolean Apear;

View File

@@ -17,6 +17,7 @@ import emu.nebula.database.GameDatabaseObject;
import emu.nebula.game.inventory.ItemParamMap; 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.quest.QuestCondType;
import emu.nebula.net.NetMsgId; import emu.nebula.net.NetMsgId;
import emu.nebula.proto.Notify.Skin; import emu.nebula.proto.Notify.Skin;
import emu.nebula.proto.Notify.SkinChange; import emu.nebula.proto.Notify.SkinChange;
@@ -117,6 +118,7 @@ public class Character implements GameDatabaseObject {
public void addExp(int amount) { public void addExp(int amount) {
// Setup // Setup
int expRequired = this.getMaxExp(); int expRequired = this.getMaxExp();
int oldLevel = this.getLevel();
// Add exp // Add exp
this.exp += amount; this.exp += amount;
@@ -134,6 +136,12 @@ public class Character implements GameDatabaseObject {
this.exp = 0; this.exp = 0;
} }
// Check if we leveled up
if (this.level > oldLevel) {
// Trigger quest
this.getPlayer().getQuestManager().triggerQuest(QuestCondType.CharacterUpTotal, this.level - oldLevel);
}
// Save to database // Save to database
this.save(); this.save();
} }

View File

@@ -14,6 +14,7 @@ import emu.nebula.database.GameDatabaseObject;
import emu.nebula.game.inventory.ItemParamMap; 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.quest.QuestCondType;
import emu.nebula.proto.Public.Disc; import emu.nebula.proto.Public.Disc;
import emu.nebula.proto.PublicStarTower.StarTowerDisc; import emu.nebula.proto.PublicStarTower.StarTowerDisc;
@@ -109,6 +110,7 @@ public class GameDisc implements GameDatabaseObject {
public void addExp(int amount) { public void addExp(int amount) {
// Setup // Setup
int expRequired = this.getMaxExp(); int expRequired = this.getMaxExp();
int oldLevel = this.getLevel();
// Add exp // Add exp
this.exp += amount; this.exp += amount;
@@ -126,6 +128,12 @@ public class GameDisc implements GameDatabaseObject {
this.exp = 0; this.exp = 0;
} }
// Check if we leveled up
if (this.level > oldLevel) {
// Trigger quest
this.getPlayer().getQuestManager().triggerQuest(QuestCondType.DiscStrengthenTotal, this.level - oldLevel);
}
// Save to database // Save to database
this.save(); this.save();
} }

View File

@@ -9,6 +9,7 @@ import emu.nebula.database.GameDatabaseObject;
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.QuestCondType;
import emu.nebula.proto.PlayerData.PlayerInfo; import emu.nebula.proto.PlayerData.PlayerInfo;
import emu.nebula.proto.Public.CharGemInstance; import emu.nebula.proto.Public.CharGemInstance;
import emu.nebula.proto.Public.DailyInstance; import emu.nebula.proto.Public.DailyInstance;
@@ -75,7 +76,7 @@ public class InstanceManager extends PlayerManager implements GameDatabaseObject
Nebula.getGameDatabase().update(this, this.getUid(), logName + "." + id, newStar); Nebula.getGameDatabase().update(this, this.getUid(), logName + "." + id, newStar);
} }
public PlayerChangeInfo settleInstance(InstanceData data, Int2IntMap log, String logName, int star) { public PlayerChangeInfo settleInstance(InstanceData data, QuestCondType questCondition, Int2IntMap log, String logName, int star) {
// Calculate settle data // Calculate settle data
var settleData = new InstanceSettleData(); var settleData = new InstanceSettleData();
@@ -104,6 +105,10 @@ public class InstanceManager extends PlayerManager implements GameDatabaseObject
// Log // Log
this.saveInstanceLog(log, logName, data.getId(), star); this.saveInstanceLog(log, logName, data.getId(), star);
// Quest triggers
this.getPlayer().getQuestManager().triggerQuest(questCondition, 1);
this.getPlayer().getQuestManager().triggerQuest(QuestCondType.BattleTotal, 1);
} }
// Set extra data // Set extra data
@@ -113,7 +118,7 @@ public class InstanceManager extends PlayerManager implements GameDatabaseObject
return change.setSuccess(true); return change.setSuccess(true);
} }
public PlayerChangeInfo sweepInstance(InstanceData data, Int2IntMap log, int rewardType, int count) { public PlayerChangeInfo sweepInstance(InstanceData data, QuestCondType questCondition, Int2IntMap log, int rewardType, int count) {
// Sanity check count // Sanity check count
if (count <= 0) { if (count <= 0) {
return null; return null;
@@ -151,6 +156,10 @@ public class InstanceManager extends PlayerManager implements GameDatabaseObject
getPlayer().getInventory().addItem(GameConstants.EXP_ITEM_ID, energyCost, change); getPlayer().getInventory().addItem(GameConstants.EXP_ITEM_ID, energyCost, change);
getPlayer().getInventory().addItems(data.getRewards(rewardType).mulitply(count), change); getPlayer().getInventory().addItems(data.getRewards(rewardType).mulitply(count), change);
// Quest triggers
this.getPlayer().getQuestManager().triggerQuest(questCondition, count);
this.getPlayer().getQuestManager().triggerQuest(QuestCondType.BattleTotal, count);
// Success // Success
return change.setSuccess(true); return change.setSuccess(true);
} }

View File

@@ -17,6 +17,7 @@ import emu.nebula.game.gacha.GachaManager;
import emu.nebula.game.instance.InstanceManager; import emu.nebula.game.instance.InstanceManager;
import emu.nebula.game.inventory.Inventory; import emu.nebula.game.inventory.Inventory;
import emu.nebula.game.mail.Mailbox; import emu.nebula.game.mail.Mailbox;
import emu.nebula.game.quest.QuestCondType;
import emu.nebula.game.quest.QuestManager; import emu.nebula.game.quest.QuestManager;
import emu.nebula.game.scoreboss.ScoreBossManager; import emu.nebula.game.scoreboss.ScoreBossManager;
import emu.nebula.game.story.StoryManager; import emu.nebula.game.story.StoryManager;
@@ -366,8 +367,14 @@ public class Player implements GameDatabaseObject {
return change == null ? new PlayerChangeInfo() : change; return change == null ? new PlayerChangeInfo() : change;
} }
// Consume energy
change = modifyEnergy(-amount, change);
// Trigger quest
this.getQuestManager().triggerQuest(QuestCondType.EnergyDeplete, amount);
// Complete // Complete
return modifyEnergy(-amount, change); return change;
} }
private PlayerChangeInfo modifyEnergy(int amount, PlayerChangeInfo change) { private PlayerChangeInfo modifyEnergy(int amount, PlayerChangeInfo change) {
@@ -445,6 +452,10 @@ public class Player implements GameDatabaseObject {
this.questManager = this.loadManagerFromDatabase(QuestManager.class); this.questManager = this.loadManagerFromDatabase(QuestManager.class);
} }
public void onLogin() {
this.getQuestManager().triggerQuest(QuestCondType.LoginTotal, 1);
}
// Next packages // Next packages
public void addNextPackage(int msgId, ProtoMessage<?> proto) { public void addNextPackage(int msgId, ProtoMessage<?> proto) {
@@ -556,6 +567,10 @@ public class Player implements GameDatabaseObject {
quests.addList(quest.toProto()); quests.addList(quest.toProto());
} }
for (int id : this.getQuestManager().getClaimedActiveIds()) {
proto.addDailyActiveIds(id);
}
// Add dictionary tabs // Add dictionary tabs
for (var dictionaryData : GameData.getDictionaryTabDataTable()) { for (var dictionaryData : GameData.getDictionaryTabDataTable()) {
var dictionaryProto = DictionaryTab.newInstance() var dictionaryProto = DictionaryTab.newInstance()

View File

@@ -1,20 +1,25 @@
package emu.nebula.game.quest; package emu.nebula.game.quest;
import dev.morphia.annotations.Entity; import dev.morphia.annotations.Entity;
import emu.nebula.data.resources.DailyQuestDef; import emu.nebula.data.resources.DailyQuestDef;
import emu.nebula.proto.Public.Quest; import emu.nebula.proto.Public.Quest;
import emu.nebula.proto.Public.QuestProgress; import emu.nebula.proto.Public.QuestProgress;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
@Getter @Getter
@Entity(useDiscriminator = false) @Entity(useDiscriminator = false)
public class GameQuest { public class GameQuest {
private int id; private int id;
private int type; private int type;
private int cond;
private int curProgress; private int curProgress;
private int maxProgress; private int maxProgress;
@Setter
private boolean claimed;
@Deprecated @Deprecated
public GameQuest() { public GameQuest() {
@@ -23,11 +28,50 @@ public class GameQuest {
public GameQuest(DailyQuestDef data) { public GameQuest(DailyQuestDef data) {
this.id = data.getId(); this.id = data.getId();
this.type = QuestType.Daily; this.type = QuestType.Daily;
this.cond = data.getCompleteCond();
this.maxProgress = data.getCompleteCondParams()[0]; this.maxProgress = data.getCompleteCondParams()[0];
} }
public void resetProgress() { public void resetProgress() {
this.curProgress = 0; 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(QuestCondType condition, int param) {
// Sanity check
if (this.isComplete()) {
return false;
}
// Skip if not the correct condition
if (this.cond != condition.getValue()) {
return false;
}
// Get new progress
int newProgress = Math.min(this.curProgress + param, this.maxProgress);
// Set
if (this.curProgress != newProgress) {
this.curProgress = newProgress;
return true;
}
return false;
} }
// Proto // Proto
@@ -40,6 +84,7 @@ public class GameQuest {
var proto = Quest.newInstance() var proto = Quest.newInstance()
.setId(this.getId()) .setId(this.getId())
.setTypeValue(this.getType()) .setTypeValue(this.getType())
.setStatus(this.getStatus())
.addProgress(progress); .addProgress(progress);
return proto; return proto;

View File

@@ -0,0 +1,144 @@
package emu.nebula.game.quest;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import lombok.Getter;
public enum QuestCondType {
BattleTotal (3),
BattlesTotalWithPartner (4),
CharacterAcquireQuantityRarityAndAdvancement (6),
CharacterAdvanceTotal (7),
CharacterSkillUpTotal (8),
CharacterSkillWithSpecificUpTotal (9),
CharacterUpTotal (12),
CharacterWithSpecificAdvance (13),
CharacterWithSpecificUpLevel (15),
CharactersWithSpecificNumberLevelAndAttributes (17),
CharactersWithSpecificQuantityAdvancementCountAndAttribute (19),
CharactersWithSpecificQuantityRarityAndLevel (22),
ChatTotal (23),
DailyInstanceClearSpecificDifficultyAndTotal (24),
DailyInstanceClearSpecificTypeAndTotal (25),
DailyInstanceClearTotal (26),
DiscAcquireQuantityLevelAndRarity (30),
DiscAcquireQuantityPhaseAndRarity (31),
DiscAcquireQuantityStarAndRarity (32),
DiscLimitBreakTotal (33),
DiscPromoteTotal (34),
DiscStrengthenTotal (35),
DiscWithSpecificQuantityLevelAndRarity (36),
DiscWithSpecificQuantityPhaseAndRarity (37),
DiscWithSpecificQuantityStarAndRarity (38),
EnergyDeplete (39),
GachaTotal (44),
GiftGiveTotal (45),
InfinityTowerClearSpecificFloor (46),
InfinityTowerClearTotal (47),
ItemsAdd (48),
ItemsDeplete (49),
ItemsProductTotal (50),
LoginTotal (51),
QuestTravelerDuelChallengeTotal (52),
QuestTourGuideSpecific (53),
QuestTravelerDuelSpecific (54),
QuestWithSpecificType (55),
RegionBossClearSpecificFullStarWithBossIdAndDifficulty (56),
RegionBossClearSpecificLevelWithDifficultyAndTotal (57),
RegionBossClearSpecificTotal (58),
RegionBossClearTotal (59),
SkillsWithSpecificQuantityAndLevel (60),
StageClearSpecificStars (62),
StoryClear (63),
TravelerDuelChallengeSpecificBoosLevelWithDifficultyAndTotal (64),
TravelerDuelClearBossTotal (65),
TravelerDuelClearSpecificBossIdAndDifficulty (66),
TravelerDuelChallengeClearSpecificBossLevelAndAffix (67),
TravelerDuelClearSpecificBossLevelWithDifficultyAndTotal (68),
TravelerDuelClearSpecificBossTotal (69),
TravelerDuelChallengeRankUploadTotal (70),
WorldClassSpecific (71),
RegionBossClearSpecificTypeWithTotal (72),
CharactersWithSpecificDatingCount (73),
CharactersDatingTotal (74),
VampireSurvivorPassedSpecificLevel (77),
CharacterParticipateTowerNumber (78),
CharacterAllSkillReachSpecificLevel (79),
TravelerDuelPlayTotal (80),
VampireClearTotal (81),
VampireWithSpecificClearTotal (82),
AgentFinishTotal (83),
AgentWithSpecificFinishTotal (84),
ActivityMiningEnterLayer (86),
ActivityMiningDestroyGrid (87),
BossRushTotalStars (88),
InfinityTowerClearSpecificDifficultyAndTotal (89),
SkillInstanceClearTotal (90),
VampireSurvivorSpecificPassedLevel (91),
WeekBoosClearSpecificDifficultyAndTotal (92),
NpcAffinityWithSpecificLevel (93),
CharacterPassedWithSpecificTowerAndCount (94),
ActivityCookieLevelAccPackage (96),
ActivityCookieLevelScore (97),
ActivityCookieTypeAccPackage (98),
ActivityCookieTypeAccPackCookie (99),
ActivityCookieTypeAccRhythm (100),
ActivityCookieTypeChallenge (101),
CharGemInstanceClearTotal (104),
DailyShopReceiveShopTotal (105),
AgentApplyTotal (106),
ActivityScore (107),
ActivityTypeAvgReadWithSpecificIdAndLevelId (108),
ActivityTypeLevelPassedWithSpecificIdAndLevelId (109),
ActivityTypeLevel3StarPassedWithSpecificIdAndLevelId (110),
ActivityTypeLevelStarWithSpecificIdAndLevelTypeTotal (111),
ActivityTypeLevelPassedWithSpecificIdAndLevelIdAndSpecificPositionAndCharElem (112),
ActivityTypeLevelPassedSpecificIdTotal (113),
ClientReport (200),
TowerBuildSpecificScoreWithTotal (504),
TowerClearSpecificLevelWithDifficultyAndTotal (507),
TowerEnterTotal (510),
TowerSpecificDifficultyShopBuyTimes (514),
TowerGrowthSpecificNote (515),
TowerClearSpecificLevelWithDifficultyAndTotalHistory (516),
TowerBookWithSpecificEvent (517),
TowerBookWithSpecificFateCard (518),
TowerBookWithSpecificPotential (520),
TowerBuildSpecificDifficultyAndScoreWithTotal (521),
TowerSpecificDifficultyStrengthenMachineTotal (522),
TowerSpecificDifficultyKillBossTotal (524),
TowerBookSpecificCharWithPotentialTotal (525),
TowerBuildSpecificCharSpecificScoreWithTotal (526),
TowerGrowthWithSpecificNote (527),
TowerSpecificFateCardReRollTotal (528),
TowerSpecificPotentialReRollTotal (529),
TowerSpecificShopReRollTotal (530),
TowerSpecificNoteActivateTotal (531),
TowerSpecificNoteLevelTotal (532),
TowerSpecificPotentialBonusTotal (533),
TowerSpecificPotentialLuckyTotal (534),
TowerSpecificShopBuyDiscountTotal (535),
TowerSpecificSecondarySkillActivateTotal (536),
TowerSpecificGetExtraNoteLvTotal (537),
TowerEnterFloor (538),
TowerSweepTimes (539),
TowerSweepTotal (540);
@Getter
private final int value;
private final static Int2ObjectMap<QuestCondType> map = new Int2ObjectOpenHashMap<>();
static {
for (QuestCondType type : QuestCondType.values()) {
map.put(type.getValue(), type);
}
}
private QuestCondType(int value) {
this.value = value;
}
public static QuestCondType getByValue(int value) {
return map.get(value);
}
}

View File

@@ -1,16 +1,22 @@
package emu.nebula.game.quest; package emu.nebula.game.quest;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import dev.morphia.annotations.Entity; import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id; import dev.morphia.annotations.Id;
import emu.nebula.Nebula;
import emu.nebula.data.GameData; import emu.nebula.data.GameData;
import emu.nebula.database.GameDatabaseObject; import emu.nebula.database.GameDatabaseObject;
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.PlayerManager; import emu.nebula.game.player.PlayerManager;
import emu.nebula.net.NetMsgId; import emu.nebula.net.NetMsgId;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import lombok.Getter; import lombok.Getter;
@Getter @Getter
@@ -19,6 +25,11 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
@Id @Id
private int uid; private int uid;
// Daily activity missions
private int activity;
private IntSet claimedActiveIds;
// Quests
private Map<Integer, GameQuest> quests; private Map<Integer, GameQuest> quests;
@Deprecated // Morphia only @Deprecated // Morphia only
@@ -29,6 +40,7 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
public QuestManager(Player player) { public QuestManager(Player player) {
super(player); super(player);
this.uid = player.getUid(); this.uid = player.getUid();
this.claimedActiveIds = new IntOpenHashSet();
this.quests = new HashMap<>(); this.quests = new HashMap<>();
this.resetDailyQuests(); this.resetDailyQuests();
@@ -36,7 +48,7 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
this.save(); this.save();
} }
public void resetDailyQuests() { public synchronized void resetDailyQuests() {
// Reset daily quests // Reset daily quests
for (var data : GameData.getDailyQuestDataTable()) { for (var data : GameData.getDailyQuestDataTable()) {
// Get quest // Get quest
@@ -45,17 +57,142 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
// Reset progress // Reset progress
quest.resetProgress(); quest.resetProgress();
// Update to player // Sync quest with player client
if (getPlayer().hasSession()) { this.syncQuest(quest);
getPlayer().addNextPackage(
NetMsgId.quest_change_notify,
quest.toProto()
);
}
} }
// Reset activity
this.activity = 0;
this.claimedActiveIds.clear();
// Persist to database // Persist to database
this.save(); this.save();
} }
public synchronized void triggerQuest(QuestCondType condition, int param) {
for (var quest : getQuests().values()) {
// Try to trigger quest
boolean result = quest.trigger(condition, param);
// Skip if quest progress wasn't changed
if (!result) {
continue;
}
// Sync quest with player client
this.syncQuest(quest);
// Update in database
Nebula.getGameDatabase().update(this, this.getUid(), "quests." + quest.getId(), quest);
}
}
public PlayerChangeInfo receiveReward(int questId) {
// Get received quests
var claimList = new HashSet<GameQuest>();
if (questId > 0) {
// Claim specific quest
var quest = this.getQuests().get(questId);
if (quest != null && !quest.isClaimed()) {
claimList.add(quest);
}
} else {
// Claim all
for (var quest : this.getQuests().values()) {
if (!quest.isComplete() || quest.isClaimed()) {
continue;
}
claimList.add(quest);
}
}
// Sanity check
if (claimList.isEmpty()) {
return null;
}
// Create change info
var change = new PlayerChangeInfo();
// Claim
for (var quest : claimList) {
// Get data
var data = GameData.getDailyQuestDataTable().get(quest.getId());
if (data != null) {
// Add reward data
this.getPlayer().getInventory().addItem(data.getItemTid(), data.getItemQty(), change);
// Add activity
this.activity += data.getActive();
}
// Set claimed
quest.setClaimed(true);
// Update in database
Nebula.getGameDatabase().update(this, this.getUid(), "quests." + quest.getId(), quest);
}
// Update in database
Nebula.getGameDatabase().update(this, this.getUid(), "activity", this.getActivity());
// Success
return change;
}
public PlayerChangeInfo claimActiveRewards() {
// Init
var claimList = new IntArrayList();
var rewards = new ItemParamMap();
// Get claimable
for (var data : GameData.getDailyQuestActiveDataTable()) {
if (this.getClaimedActiveIds().contains(data.getId())) {
continue;
}
if (this.getActivity() >= data.getActive()) {
// Add rewards
rewards.add(data.getRewards());
// Add to claimed activity list
claimList.add(data.getId());
}
}
// Sanity check
if (claimList.isEmpty()) {
return null;
}
// Add rewards
var change = this.getPlayer().getInventory().addItems(rewards);
// Set claimed list
change.setExtraData(claimList);
// Update in database
this.getClaimedActiveIds().addAll(claimList);
Nebula.getGameDatabase().update(this, this.getUid(), "claimedActiveIds", this.getClaimedActiveIds());
// Success
return change;
}
/**
* Update this quest on the player client
*/
private void syncQuest(GameQuest quest) {
if (!getPlayer().hasSession()) {
return;
}
getPlayer().addNextPackage(
NetMsgId.quest_change_notify,
quest.toProto()
);
}
} }

View File

@@ -520,7 +520,7 @@ public class StarTowerGame {
if (this.roomType <= StarTowerRoomType.FinalBossRoom.getValue()) { if (this.roomType <= StarTowerRoomType.FinalBossRoom.getValue()) {
var battleCase = new StarTowerCase(CaseType.Battle); var battleCase = new StarTowerCase(CaseType.Battle);
battleCase.setSubNoteSkillNum(Utils.randomRange(1, 3)); battleCase.setSubNoteSkillNum(Utils.randomRange(1, 3));
this.addCase(room.getMutableCases(), battleCase); this.addCase(room.getMutableCases(), battleCase);
} else if (this.roomType == StarTowerRoomType.EventRoom.getValue()) { } else if (this.roomType == StarTowerRoomType.EventRoom.getValue()) {

View File

@@ -8,6 +8,7 @@ import emu.nebula.database.GameDatabaseObject;
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.QuestCondType;
import emu.nebula.proto.StarTowerApply.StarTowerApplyReq; import emu.nebula.proto.StarTowerApply.StarTowerApplyReq;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
@@ -73,6 +74,9 @@ public class StarTowerManager extends PlayerManager implements GameDatabaseObjec
// Create game // Create game
this.game = new StarTowerGame(this, data, formation, req); this.game = new StarTowerGame(this, data, formation, req);
// Trigger quest
this.getPlayer().getQuestManager().triggerQuest(QuestCondType.TowerEnterFloor, 1);
// Success // Success
return this.game; return this.game;
} }

View File

@@ -46,6 +46,7 @@ public class GameSession {
public synchronized void setPlayer(Player player) { public synchronized void setPlayer(Player player) {
this.player = player; this.player = player;
this.player.setSession(this); this.player.setSession(this);
this.player.onLogin();
} }
public synchronized void clearPlayer() { public synchronized void clearPlayer() {

View File

@@ -7,6 +7,7 @@ import emu.nebula.proto.CharGemInstanceSettle.CharGemInstanceSettleResp;
import emu.nebula.net.HandlerId; import emu.nebula.net.HandlerId;
import emu.nebula.data.GameData; import emu.nebula.data.GameData;
import emu.nebula.game.instance.InstanceSettleData; import emu.nebula.game.instance.InstanceSettleData;
import emu.nebula.game.quest.QuestCondType;
import emu.nebula.net.GameSession; import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.char_gem_instance_settle_req) @HandlerId(NetMsgId.char_gem_instance_settle_req)
@@ -29,6 +30,7 @@ public class HandlerCharGemInstanceSettleReq extends NetHandler {
// Settle instance // Settle instance
var changes = player.getInstanceManager().settleInstance( var changes = player.getInstanceManager().settleInstance(
data, data,
QuestCondType.CharGemInstanceClearTotal,
player.getInstanceManager().getCharGemLog(), player.getInstanceManager().getCharGemLog(),
"charGemLog", "charGemLog",
req.getStar() req.getStar()

View File

@@ -7,6 +7,7 @@ import emu.nebula.proto.CharGemInstanceSweep.CharGemInstanceSweepResp;
import emu.nebula.proto.CharGemInstanceSweep.CharGemInstanceSweepReward; import emu.nebula.proto.CharGemInstanceSweep.CharGemInstanceSweepReward;
import emu.nebula.net.HandlerId; import emu.nebula.net.HandlerId;
import emu.nebula.data.GameData; import emu.nebula.data.GameData;
import emu.nebula.game.quest.QuestCondType;
import emu.nebula.net.GameSession; import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.char_gem_instance_sweep_req) @HandlerId(NetMsgId.char_gem_instance_sweep_req)
@@ -26,6 +27,7 @@ public class HandlerCharGemInstanceSweepReq extends NetHandler {
// Sweep // Sweep
var change = session.getPlayer().getInstanceManager().sweepInstance( var change = session.getPlayer().getInstanceManager().sweepInstance(
data, data,
QuestCondType.CharGemInstanceClearTotal,
session.getPlayer().getInstanceManager().getCharGemLog(), session.getPlayer().getInstanceManager().getCharGemLog(),
0, 0,
req.getTimes() req.getTimes()

View File

@@ -2,7 +2,9 @@ package emu.nebula.server.handlers;
import emu.nebula.net.NetHandler; import emu.nebula.net.NetHandler;
import emu.nebula.net.NetMsgId; import emu.nebula.net.NetMsgId;
import emu.nebula.proto.Public.Nil;
import emu.nebula.net.HandlerId; import emu.nebula.net.HandlerId;
import emu.nebula.game.quest.QuestCondType;
import emu.nebula.net.GameSession; import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.client_event_report_req) @HandlerId(NetMsgId.client_event_report_req)
@@ -10,7 +12,11 @@ public class HandlerClientEventReportReq extends NetHandler {
@Override @Override
public byte[] handle(GameSession session, byte[] message) throws Exception { public byte[] handle(GameSession session, byte[] message) throws Exception {
return session.encodeMsg(NetMsgId.client_event_report_succeed_ack); // Interact
session.getPlayer().getQuestManager().triggerQuest(QuestCondType.ClientReport, 1);
// Encode response
return session.encodeMsg(NetMsgId.client_event_report_succeed_ack, Nil.newInstance());
} }
} }

View File

@@ -7,6 +7,7 @@ import emu.nebula.proto.DailyInstanceRaid.DailyInstanceRaidResp;
import emu.nebula.proto.DailyInstanceRaid.DailyInstanceReward; import emu.nebula.proto.DailyInstanceRaid.DailyInstanceReward;
import emu.nebula.net.HandlerId; import emu.nebula.net.HandlerId;
import emu.nebula.data.GameData; import emu.nebula.data.GameData;
import emu.nebula.game.quest.QuestCondType;
import emu.nebula.net.GameSession; import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.daily_instance_raid_req) @HandlerId(NetMsgId.daily_instance_raid_req)
@@ -31,6 +32,7 @@ public class HandlerDailyInstanceRaidReq extends NetHandler {
// Sweep // Sweep
var change = session.getPlayer().getInstanceManager().sweepInstance( var change = session.getPlayer().getInstanceManager().sweepInstance(
data, data,
QuestCondType.DailyInstanceClearTotal,
session.getPlayer().getInstanceManager().getDailyInstanceLog(), session.getPlayer().getInstanceManager().getDailyInstanceLog(),
req.getRewardType(), req.getRewardType(),
req.getTimes() req.getTimes()

View File

@@ -7,6 +7,7 @@ import emu.nebula.proto.DailyInstanceSettle.DailyInstanceSettleResp;
import emu.nebula.net.HandlerId; import emu.nebula.net.HandlerId;
import emu.nebula.data.GameData; import emu.nebula.data.GameData;
import emu.nebula.game.instance.InstanceSettleData; import emu.nebula.game.instance.InstanceSettleData;
import emu.nebula.game.quest.QuestCondType;
import emu.nebula.net.GameSession; import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.daily_instance_settle_req) @HandlerId(NetMsgId.daily_instance_settle_req)
@@ -29,6 +30,7 @@ public class HandlerDailyInstanceSettleReq extends NetHandler {
// Settle instance // Settle instance
var changes = player.getInstanceManager().settleInstance( var changes = player.getInstanceManager().settleInstance(
data, data,
QuestCondType.DailyInstanceClearTotal,
player.getInstanceManager().getDailyInstanceLog(), player.getInstanceManager().getDailyInstanceLog(),
"dailyInstanceLog", "dailyInstanceLog",
req.getStar() req.getStar()

View File

@@ -13,6 +13,7 @@ public class HandlerGachaNewbieInfoReq extends NetHandler {
@Override @Override
public byte[] handle(GameSession session, byte[] message) throws Exception { public byte[] handle(GameSession session, byte[] message) throws Exception {
var rsp = GachaNewbieInfoResp.newInstance(); var rsp = GachaNewbieInfoResp.newInstance();
var info = GachaNewbieInfo.newInstance() var info = GachaNewbieInfo.newInstance()
.setId(5) .setId(5)
.setReceive(true); .setReceive(true);

View File

@@ -0,0 +1,34 @@
package emu.nebula.server.handlers;
import emu.nebula.net.NetHandler;
import emu.nebula.net.NetMsgId;
import emu.nebula.proto.QuestDailyActiveRewardRecevie.QuestDailyActiveRewardReceiveResp;
import it.unimi.dsi.fastutil.ints.IntList;
import emu.nebula.net.HandlerId;
import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.quest_daily_active_reward_receive_req)
public class HandlerQuestDailyActiveRewardReceiveReq extends NetHandler {
@Override
public byte[] handle(GameSession session, byte[] message) throws Exception {
// Receive rewards
var change = session.getPlayer().getQuestManager().claimActiveRewards();
if (change == null) {
return session.encodeMsg(NetMsgId.quest_daily_active_reward_receive_failed_ack);
}
// Build response
var rsp = QuestDailyActiveRewardReceiveResp.newInstance()
.setChange(change.toProto());
if (change.getExtraData() != null && change.getExtraData() instanceof IntList ids) {
ids.forEach(rsp::addActiveIds);
}
// Encode and send
return session.encodeMsg(NetMsgId.quest_daily_active_reward_receive_succeed_ack, rsp);
}
}

View File

@@ -0,0 +1,28 @@
package emu.nebula.server.handlers;
import emu.nebula.net.NetHandler;
import emu.nebula.net.NetMsgId;
import emu.nebula.proto.Public.UI32;
import emu.nebula.net.HandlerId;
import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.quest_daily_reward_receive_req)
public class HandlerQuestDailyRewardReceiveReq extends NetHandler {
@Override
public byte[] handle(GameSession session, byte[] message) throws Exception {
// Parse request
var req = UI32.parseFrom(message);
// Receive rewards
var change = session.getPlayer().getQuestManager().receiveReward(req.getValue());
if (change == null) {
return session.encodeMsg(NetMsgId.quest_daily_reward_receive_failed_ack);
}
// Template
return session.encodeMsg(NetMsgId.quest_daily_reward_receive_succeed_ack, change.toProto());
}
}

View File

@@ -7,6 +7,7 @@ import emu.nebula.proto.RegionBossLevelSettle.RegionBossLevelSettleResp;
import emu.nebula.net.HandlerId; import emu.nebula.net.HandlerId;
import emu.nebula.data.GameData; import emu.nebula.data.GameData;
import emu.nebula.game.instance.InstanceSettleData; import emu.nebula.game.instance.InstanceSettleData;
import emu.nebula.game.quest.QuestCondType;
import emu.nebula.net.GameSession; import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.region_boss_level_settle_req) @HandlerId(NetMsgId.region_boss_level_settle_req)
@@ -29,6 +30,7 @@ public class HandlerRegionBossLevelSettleReq extends NetHandler {
// Settle instance // Settle instance
var changes = player.getInstanceManager().settleInstance( var changes = player.getInstanceManager().settleInstance(
data, data,
QuestCondType.RegionBossClearTotal,
player.getInstanceManager().getRegionBossLog(), player.getInstanceManager().getRegionBossLog(),
"regionBossLog", "regionBossLog",
req.getStar() req.getStar()

View File

@@ -7,6 +7,7 @@ import emu.nebula.proto.RegionBossLevelSweep.RegionBossLevelSweepResp;
import emu.nebula.proto.RegionBossLevelSweep.RegionBossLevelSweepRewards; import emu.nebula.proto.RegionBossLevelSweep.RegionBossLevelSweepRewards;
import emu.nebula.net.HandlerId; import emu.nebula.net.HandlerId;
import emu.nebula.data.GameData; import emu.nebula.data.GameData;
import emu.nebula.game.quest.QuestCondType;
import emu.nebula.net.GameSession; import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.region_boss_level_sweep_req) @HandlerId(NetMsgId.region_boss_level_sweep_req)
@@ -26,6 +27,7 @@ public class HandlerRegionBossLevelSweepReq extends NetHandler {
// Sweep // Sweep
var change = session.getPlayer().getInstanceManager().sweepInstance( var change = session.getPlayer().getInstanceManager().sweepInstance(
data, data,
QuestCondType.RegionBossClearTotal,
session.getPlayer().getInstanceManager().getRegionBossLog(), session.getPlayer().getInstanceManager().getRegionBossLog(),
0, 0,
req.getTimes() req.getTimes()

View File

@@ -7,6 +7,7 @@ import emu.nebula.proto.SkillInstanceSettle.SkillInstanceSettleResp;
import emu.nebula.net.HandlerId; import emu.nebula.net.HandlerId;
import emu.nebula.data.GameData; import emu.nebula.data.GameData;
import emu.nebula.game.instance.InstanceSettleData; import emu.nebula.game.instance.InstanceSettleData;
import emu.nebula.game.quest.QuestCondType;
import emu.nebula.net.GameSession; import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.skill_instance_settle_req) @HandlerId(NetMsgId.skill_instance_settle_req)
@@ -29,6 +30,7 @@ public class HandlerSkillInstanceSettleReq extends NetHandler {
// Settle instance // Settle instance
var changes = player.getInstanceManager().settleInstance( var changes = player.getInstanceManager().settleInstance(
data, data,
QuestCondType.SkillInstanceClearTotal,
player.getInstanceManager().getSkillInstanceLog(), player.getInstanceManager().getSkillInstanceLog(),
"skillInstanceLog", "skillInstanceLog",
req.getStar() req.getStar()
@@ -42,7 +44,7 @@ public class HandlerSkillInstanceSettleReq extends NetHandler {
.setThreeStar(req.getStar() == 7) .setThreeStar(req.getStar() == 7)
.setChange(changes.toProto()); .setChange(changes.toProto());
// Add reward items // Add reward items to proto
if (settleData.isWin()) { if (settleData.isWin()) {
data.getRewards().toItemTemplateStream().forEach(rsp::addAwardItems); data.getRewards().toItemTemplateStream().forEach(rsp::addAwardItems);

View File

@@ -7,6 +7,7 @@ import emu.nebula.proto.SkillInstanceSweep.SkillInstanceSweepResp;
import emu.nebula.proto.SkillInstanceSweep.SkillInstanceSweepRewards; import emu.nebula.proto.SkillInstanceSweep.SkillInstanceSweepRewards;
import emu.nebula.net.HandlerId; import emu.nebula.net.HandlerId;
import emu.nebula.data.GameData; import emu.nebula.data.GameData;
import emu.nebula.game.quest.QuestCondType;
import emu.nebula.net.GameSession; import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.skill_instance_sweep_req) @HandlerId(NetMsgId.skill_instance_sweep_req)
@@ -26,6 +27,7 @@ public class HandlerSkillInstanceSweepReq extends NetHandler {
// Sweep // Sweep
var change = session.getPlayer().getInstanceManager().sweepInstance( var change = session.getPlayer().getInstanceManager().sweepInstance(
data, data,
QuestCondType.SkillInstanceClearTotal,
session.getPlayer().getInstanceManager().getSkillInstanceLog(), session.getPlayer().getInstanceManager().getSkillInstanceLog(),
0, 0,
req.getTimes() req.getTimes()

View File

@@ -7,6 +7,7 @@ import emu.nebula.proto.WeekBossSettle.WeekBossSettleReq;
import emu.nebula.net.HandlerId; import emu.nebula.net.HandlerId;
import emu.nebula.data.GameData; import emu.nebula.data.GameData;
import emu.nebula.game.instance.InstanceSettleData; import emu.nebula.game.instance.InstanceSettleData;
import emu.nebula.game.quest.QuestCondType;
import emu.nebula.net.GameSession; import emu.nebula.net.GameSession;
@HandlerId(NetMsgId.week_boss_settle_req) @HandlerId(NetMsgId.week_boss_settle_req)
@@ -29,6 +30,7 @@ public class HandlerWeekBossSettleReq extends NetHandler {
// Settle instance // Settle instance
var changes = player.getInstanceManager().settleInstance( var changes = player.getInstanceManager().settleInstance(
data, data,
QuestCondType.WeekBoosClearSpecificDifficultyAndTotal,
player.getInstanceManager().getWeekBossLog(), player.getInstanceManager().getWeekBossLog(),
"weekBossLog", "weekBossLog",
req.getResult() ? 1 : 0 req.getResult() ? 1 : 0