mirror of
https://github.com/Melledy/Nebula.git
synced 2025-12-18 07:14:49 +01:00
Implement daily activity missions
This commit is contained in:
@@ -1,20 +1,25 @@
|
||||
package emu.nebula.game.quest;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
|
||||
import emu.nebula.data.resources.DailyQuestDef;
|
||||
import emu.nebula.proto.Public.Quest;
|
||||
import emu.nebula.proto.Public.QuestProgress;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Entity(useDiscriminator = false)
|
||||
public class GameQuest {
|
||||
private int id;
|
||||
private int type;
|
||||
private int cond;
|
||||
|
||||
private int curProgress;
|
||||
private int maxProgress;
|
||||
|
||||
@Setter
|
||||
private boolean claimed;
|
||||
|
||||
@Deprecated
|
||||
public GameQuest() {
|
||||
|
||||
@@ -23,11 +28,50 @@ public class GameQuest {
|
||||
public GameQuest(DailyQuestDef data) {
|
||||
this.id = data.getId();
|
||||
this.type = QuestType.Daily;
|
||||
this.cond = data.getCompleteCond();
|
||||
this.maxProgress = data.getCompleteCondParams()[0];
|
||||
}
|
||||
|
||||
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(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
|
||||
@@ -40,6 +84,7 @@ public class GameQuest {
|
||||
var proto = Quest.newInstance()
|
||||
.setId(this.getId())
|
||||
.setTypeValue(this.getType())
|
||||
.setStatus(this.getStatus())
|
||||
.addProgress(progress);
|
||||
|
||||
return proto;
|
||||
|
||||
144
src/main/java/emu/nebula/game/quest/QuestCondType.java
Normal file
144
src/main/java/emu/nebula/game/quest/QuestCondType.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,22 @@
|
||||
package emu.nebula.game.quest;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import dev.morphia.annotations.Id;
|
||||
import emu.nebula.Nebula;
|
||||
import emu.nebula.data.GameData;
|
||||
import emu.nebula.database.GameDatabaseObject;
|
||||
import emu.nebula.game.inventory.ItemParamMap;
|
||||
import emu.nebula.game.player.Player;
|
||||
import emu.nebula.game.player.PlayerChangeInfo;
|
||||
import emu.nebula.game.player.PlayerManager;
|
||||
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;
|
||||
|
||||
@Getter
|
||||
@@ -19,6 +25,11 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
|
||||
@Id
|
||||
private int uid;
|
||||
|
||||
// Daily activity missions
|
||||
private int activity;
|
||||
private IntSet claimedActiveIds;
|
||||
|
||||
// Quests
|
||||
private Map<Integer, GameQuest> quests;
|
||||
|
||||
@Deprecated // Morphia only
|
||||
@@ -29,6 +40,7 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
|
||||
public QuestManager(Player player) {
|
||||
super(player);
|
||||
this.uid = player.getUid();
|
||||
this.claimedActiveIds = new IntOpenHashSet();
|
||||
this.quests = new HashMap<>();
|
||||
|
||||
this.resetDailyQuests();
|
||||
@@ -36,7 +48,7 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
|
||||
this.save();
|
||||
}
|
||||
|
||||
public void resetDailyQuests() {
|
||||
public synchronized void resetDailyQuests() {
|
||||
// Reset daily quests
|
||||
for (var data : GameData.getDailyQuestDataTable()) {
|
||||
// Get quest
|
||||
@@ -45,17 +57,142 @@ public class QuestManager extends PlayerManager implements GameDatabaseObject {
|
||||
// Reset progress
|
||||
quest.resetProgress();
|
||||
|
||||
// Update to player
|
||||
if (getPlayer().hasSession()) {
|
||||
getPlayer().addNextPackage(
|
||||
NetMsgId.quest_change_notify,
|
||||
quest.toProto()
|
||||
);
|
||||
}
|
||||
// Sync quest with player client
|
||||
this.syncQuest(quest);
|
||||
}
|
||||
|
||||
// Reset activity
|
||||
this.activity = 0;
|
||||
this.claimedActiveIds.clear();
|
||||
|
||||
// Persist to database
|
||||
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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user