2022-05-11 18:56:40 +08:00
|
|
|
package emu.grasscutter.game.quest;
|
|
|
|
|
2022-05-12 17:30:34 +08:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.HashSet;
|
2022-05-11 18:56:40 +08:00
|
|
|
import java.util.List;
|
2022-05-12 17:30:34 +08:00
|
|
|
import java.util.Set;
|
2022-05-11 18:56:40 +08:00
|
|
|
import java.util.function.Consumer;
|
|
|
|
import java.util.function.Function;
|
|
|
|
|
|
|
|
import emu.grasscutter.data.GameData;
|
2022-05-13 18:12:25 +08:00
|
|
|
import emu.grasscutter.data.def.QuestData;
|
|
|
|
import emu.grasscutter.data.def.QuestData.QuestCondition;
|
2022-05-11 18:56:40 +08:00
|
|
|
import emu.grasscutter.database.DatabaseHelper;
|
|
|
|
import emu.grasscutter.game.player.Player;
|
2022-05-13 18:12:25 +08:00
|
|
|
import emu.grasscutter.game.quest.enums.QuestTrigger;
|
2022-05-12 17:30:34 +08:00
|
|
|
import emu.grasscutter.game.quest.enums.LogicType;
|
2022-05-11 18:56:40 +08:00
|
|
|
import emu.grasscutter.game.quest.enums.QuestState;
|
|
|
|
import emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify;
|
|
|
|
import emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify;
|
2022-05-12 17:30:34 +08:00
|
|
|
import emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify;
|
2022-05-11 18:56:40 +08:00
|
|
|
import emu.grasscutter.server.packet.send.PacketServerCondMeetQuestListUpdateNotify;
|
|
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|
|
|
|
|
|
|
public class QuestManager {
|
|
|
|
private final Player player;
|
|
|
|
private final Int2ObjectMap<GameMainQuest> quests;
|
|
|
|
|
|
|
|
public QuestManager(Player player) {
|
|
|
|
this.player = player;
|
|
|
|
this.quests = new Int2ObjectOpenHashMap<>();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Player getPlayer() {
|
|
|
|
return player;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Int2ObjectMap<GameMainQuest> getQuests() {
|
|
|
|
return quests;
|
|
|
|
}
|
|
|
|
|
|
|
|
public GameMainQuest getMainQuestById(int mainQuestId) {
|
|
|
|
return getQuests().get(mainQuestId);
|
|
|
|
}
|
|
|
|
|
|
|
|
public GameQuest getQuestById(int questId) {
|
2022-05-13 18:12:25 +08:00
|
|
|
QuestData questConfig = GameData.getQuestDataMap().get(questId);
|
2022-05-11 18:56:40 +08:00
|
|
|
if (questConfig == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2022-05-13 18:12:25 +08:00
|
|
|
GameMainQuest mainQuest = getQuests().get(questConfig.getMainId());
|
2022-05-11 18:56:40 +08:00
|
|
|
|
|
|
|
if (mainQuest == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mainQuest.getChildQuests().get(questId);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void forEachQuest(Consumer<GameQuest> callback) {
|
|
|
|
for (GameMainQuest mainQuest : getQuests().values()) {
|
|
|
|
for (GameQuest quest : mainQuest.getChildQuests().values()) {
|
|
|
|
callback.accept(quest);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-12 17:30:34 +08:00
|
|
|
// TODO
|
|
|
|
public void forEachActiveQuest(Consumer<GameQuest> callback) {
|
|
|
|
for (GameMainQuest mainQuest : getQuests().values()) {
|
|
|
|
for (GameQuest quest : mainQuest.getChildQuests().values()) {
|
|
|
|
if (quest.getState() != QuestState.QUEST_STATE_FINISHED) {
|
|
|
|
callback.accept(quest);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-13 18:12:25 +08:00
|
|
|
public GameMainQuest addMainQuest(QuestData questConfig) {
|
|
|
|
GameMainQuest mainQuest = new GameMainQuest(getPlayer(), questConfig.getMainId());
|
2022-05-11 18:56:40 +08:00
|
|
|
getQuests().put(mainQuest.getParentQuestId(), mainQuest);
|
|
|
|
|
|
|
|
getPlayer().sendPacket(new PacketFinishedParentQuestUpdateNotify(mainQuest));
|
|
|
|
|
|
|
|
return mainQuest;
|
|
|
|
}
|
|
|
|
|
|
|
|
public GameQuest addQuest(int questId) {
|
2022-05-13 18:12:25 +08:00
|
|
|
QuestData questConfig = GameData.getQuestDataMap().get(questId);
|
2022-05-11 18:56:40 +08:00
|
|
|
if (questConfig == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Main quest
|
2022-05-13 18:12:25 +08:00
|
|
|
GameMainQuest mainQuest = this.getMainQuestById(questConfig.getMainId());
|
2022-05-11 18:56:40 +08:00
|
|
|
|
|
|
|
// Create main quest if it doesnt exist
|
|
|
|
if (mainQuest == null) {
|
|
|
|
mainQuest = addMainQuest(questConfig);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sub quest
|
|
|
|
GameQuest quest = mainQuest.getChildQuestById(questId);
|
|
|
|
|
|
|
|
if (quest != null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create
|
|
|
|
quest = new GameQuest(mainQuest, questConfig);
|
|
|
|
|
|
|
|
// Save main quest
|
|
|
|
mainQuest.save();
|
|
|
|
|
|
|
|
// Send packet
|
|
|
|
getPlayer().sendPacket(new PacketServerCondMeetQuestListUpdateNotify(quest));
|
|
|
|
getPlayer().sendPacket(new PacketQuestListUpdateNotify(quest));
|
|
|
|
|
|
|
|
return quest;
|
|
|
|
}
|
2022-05-12 17:30:34 +08:00
|
|
|
|
2022-05-13 18:12:25 +08:00
|
|
|
public void triggerEvent(QuestTrigger condType, int... params) {
|
2022-05-12 17:30:34 +08:00
|
|
|
Set<GameQuest> changedQuests = new HashSet<>();
|
|
|
|
|
|
|
|
this.forEachActiveQuest(quest -> {
|
2022-05-13 18:12:25 +08:00
|
|
|
QuestData data = quest.getData();
|
2022-05-12 17:30:34 +08:00
|
|
|
|
|
|
|
for (int i = 0; i < data.getFinishCond().length; i++) {
|
2022-05-13 21:24:50 +08:00
|
|
|
if (quest.getFinishProgressList() == null || quest.getFinishProgressList()[i] == 1) {
|
2022-05-12 17:30:34 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
QuestCondition condition = data.getFinishCond()[i];
|
|
|
|
|
|
|
|
if (condition.getType() != condType) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean result = getPlayer().getServer().getQuestHandler().triggerContent(quest, condition, params);
|
|
|
|
|
|
|
|
if (result) {
|
|
|
|
quest.getFinishProgressList()[i] = 1;
|
|
|
|
|
|
|
|
changedQuests.add(quest);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
for (GameQuest quest : changedQuests) {
|
2022-05-13 18:12:25 +08:00
|
|
|
LogicType logicType = quest.getData().getFailCondComb();
|
2022-05-12 17:30:34 +08:00
|
|
|
int[] progress = quest.getFinishProgressList();
|
|
|
|
|
|
|
|
// Handle logical comb
|
|
|
|
boolean finish = LogicType.calculate(logicType, progress);
|
|
|
|
|
|
|
|
// Finish
|
|
|
|
if (finish) {
|
|
|
|
quest.finish();
|
|
|
|
} else {
|
|
|
|
getPlayer().sendPacket(new PacketQuestProgressUpdateNotify(quest));
|
|
|
|
quest.save();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-05-11 18:56:40 +08:00
|
|
|
|
|
|
|
public void loadFromDatabase() {
|
|
|
|
List<GameMainQuest> quests = DatabaseHelper.getAllQuests(getPlayer());
|
|
|
|
|
|
|
|
for (GameMainQuest mainQuest : quests) {
|
|
|
|
mainQuest.setOwner(this.getPlayer());
|
|
|
|
|
|
|
|
for (GameQuest quest : mainQuest.getChildQuests().values()) {
|
|
|
|
quest.setMainQuest(mainQuest);
|
2022-05-13 18:12:25 +08:00
|
|
|
quest.setConfig(GameData.getQuestDataMap().get(quest.getQuestId()));
|
2022-05-11 18:56:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
this.getQuests().put(mainQuest.getParentQuestId(), mainQuest);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|