Implement basic quest stuff

This commit is contained in:
Melledy
2025-11-06 20:16:38 -08:00
parent 7d62f24530
commit 7785c0d65f
6 changed files with 187 additions and 1 deletions

View File

@@ -62,6 +62,8 @@ public class GameData {
@Getter private static DataTable<StoryDef> StoryDataTable = new DataTable<>(); @Getter private static DataTable<StoryDef> StoryDataTable = new DataTable<>();
@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<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<>();
@Getter private static DataTable<PotentialDef> PotentialDataTable = new DataTable<>(); @Getter private static DataTable<PotentialDef> PotentialDataTable = new DataTable<>();

View File

@@ -0,0 +1,43 @@
package emu.nebula.data.resources;
import java.util.Arrays;
import emu.nebula.data.BaseDef;
import emu.nebula.data.ResourceType;
import emu.nebula.data.ResourceType.LoadPriority;
import lombok.Getter;
@Getter
@ResourceType(name = "DailyQuest.json", loadPriority = LoadPriority.LOW)
public class DailyQuestDef extends BaseDef {
private int Id;
private boolean Apear;
private int Active;
private int ItemTid;
private int ItemQty;
private int CompleteCond;
private int CompleteCondClient;
private String CompleteCondParams;
private transient int[] condParams;
@Override
public int getId() {
return Id;
}
public int[] getCompleteCondParams() {
return this.condParams;
}
@Override
public void onLoad() {
this.condParams = Arrays.stream(this.CompleteCondParams.split("[\\[,\\]]"))
.filter(s -> !s.isEmpty())
.mapToInt(Integer::parseInt)
.toArray();
this.CompleteCondParams = null;
}
}

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.QuestManager;
import emu.nebula.game.story.StoryManager; import emu.nebula.game.story.StoryManager;
import emu.nebula.game.tower.StarTowerManager; import emu.nebula.game.tower.StarTowerManager;
import emu.nebula.net.GameSession; import emu.nebula.net.GameSession;
@@ -72,6 +73,7 @@ public class Player implements GameDatabaseObject {
private transient StarTowerManager starTowerManager; private transient StarTowerManager starTowerManager;
private transient InstanceManager instanceManager; private transient InstanceManager instanceManager;
private transient StoryManager storyManager; private transient StoryManager storyManager;
private transient QuestManager questManager;
// Next packages // Next packages
private transient Stack<NetMsgPacket> nextPackages; private transient Stack<NetMsgPacket> nextPackages;
@@ -145,6 +147,10 @@ public class Player implements GameDatabaseObject {
Nebula.getGameContext().getPlayerModule().removeFromCache(this); Nebula.getGameContext().getPlayerModule().removeFromCache(this);
} }
public boolean hasSession() {
return this.session != null;
}
public boolean getGender() { public boolean getGender() {
return this.gender; return this.gender;
} }
@@ -412,6 +418,9 @@ public class Player implements GameDatabaseObject {
return manager; return manager;
} }
/**
* Called when the player is loaded from the database
*/
public void onLoad() { public void onLoad() {
// Load from database // Load from database
this.getCharacters().loadFromDatabase(); this.getCharacters().loadFromDatabase();
@@ -428,6 +437,7 @@ public class Player implements GameDatabaseObject {
this.starTowerManager = this.loadManagerFromDatabase(StarTowerManager.class); this.starTowerManager = this.loadManagerFromDatabase(StarTowerManager.class);
this.instanceManager = this.loadManagerFromDatabase(InstanceManager.class); this.instanceManager = this.loadManagerFromDatabase(InstanceManager.class);
this.storyManager = this.loadManagerFromDatabase(StoryManager.class); this.storyManager = this.loadManagerFromDatabase(StoryManager.class);
this.questManager = this.loadManagerFromDatabase(QuestManager.class);
} }
// Next packages // Next packages
@@ -535,6 +545,12 @@ public class Player implements GameDatabaseObject {
proto.addBoard(boardId); proto.addBoard(boardId);
} }
// Quests
var quests = proto.getMutableQuests();
for (var quest : this.getQuestManager().getQuests().values()) {
quests.addList(quest.toProto());
}
// Add dictionary tabs // Add dictionary tabs
for (var dictionaryData : GameData.getDictionaryTabDataTable()) { for (var dictionaryData : GameData.getDictionaryTabDataTable()) {
var dictionaryProto = DictionaryTab.newInstance() var dictionaryProto = DictionaryTab.newInstance()
@@ -567,7 +583,6 @@ public class Player implements GameDatabaseObject {
proto.getMutableVampireSurvivorRecord() proto.getMutableVampireSurvivorRecord()
.getMutableSeason(); .getMutableSeason();
proto.getMutableQuests();
proto.getMutableAgent(); proto.getMutableAgent();
proto.getMutablePhone(); proto.getMutablePhone();
@@ -585,4 +600,5 @@ public class Player implements GameDatabaseObject {
return proto; return proto;
} }
} }

View File

@@ -0,0 +1,47 @@
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;
@Getter
@Entity(useDiscriminator = false)
public class GameQuest {
private int id;
private int type;
private int curProgress;
private int maxProgress;
@Deprecated
public GameQuest() {
}
public GameQuest(DailyQuestDef data) {
this.id = data.getId();
this.type = QuestType.Daily;
this.maxProgress = data.getCompleteCondParams()[0];
}
public void resetProgress() {
this.curProgress = 0;
}
// Proto
public Quest toProto() {
var progress = QuestProgress.newInstance()
.setCur(this.getCurProgress())
.setMax(this.getMaxProgress());
var proto = Quest.newInstance()
.setId(this.getId())
.setTypeValue(this.getType())
.addProgress(progress);
return proto;
}
}

View File

@@ -0,0 +1,61 @@
package emu.nebula.game.quest;
import java.util.HashMap;
import java.util.Map;
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import emu.nebula.data.GameData;
import emu.nebula.database.GameDatabaseObject;
import emu.nebula.game.player.Player;
import emu.nebula.game.player.PlayerManager;
import emu.nebula.net.NetMsgId;
import lombok.Getter;
@Getter
@Entity(value = "quests", useDiscriminator = false)
public class QuestManager extends PlayerManager implements GameDatabaseObject {
@Id
private int uid;
private Map<Integer, GameQuest> quests;
@Deprecated // Morphia only
public QuestManager() {
}
public QuestManager(Player player) {
super(player);
this.uid = player.getUid();
this.quests = new HashMap<>();
this.resetDailyQuests();
this.save();
}
public void resetDailyQuests() {
// Reset daily quests
for (var data : GameData.getDailyQuestDataTable()) {
// Get quest
var quest = getQuests().computeIfAbsent(data.getId(), i -> new GameQuest(data));
// Reset progress
quest.resetProgress();
// Update to player
if (getPlayer().hasSession()) {
getPlayer().addNextPackage(
NetMsgId.quest_change_notify,
quest.toProto()
);
}
}
// Persist to database
this.save();
}
}

View File

@@ -0,0 +1,17 @@
package emu.nebula.game.quest;
public class QuestType {
public static final int UnknownQuest = 0;
public static final int TourGuide = 1;
public static final int Daily = 2;
public static final int TravelerDuel = 3;
public static final int TravelerDuelChallenge = 4;
public static final int Affinity = 5;
public static final int BattlePassDaily = 6;
public static final int BattlePassWeekly = 7;
public static final int VampireSurvivorNormal = 8;
public static final int VampireSurvivorSeason = 9;
public static final int Tower = 10;
public static final int Demon = 11;
public static final int TowerEvent = 12;
}