Implement basic quest condition handling

Quests that require talking to npcs now work.
This commit is contained in:
Melledy
2022-05-12 02:30:34 -07:00
parent 7befebe37f
commit 1231802192
17 changed files with 566 additions and 187 deletions

View File

@@ -1,16 +1,25 @@
package emu.grasscutter.game.quest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.custom.QuestConfig;
import emu.grasscutter.data.custom.QuestConfigData.QuestCondition;
import emu.grasscutter.data.custom.QuestConfigData.SubQuestConfigData;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.enums.QuestTriggerType;
import emu.grasscutter.game.quest.enums.LogicType;
import emu.grasscutter.game.quest.enums.QuestState;
import emu.grasscutter.server.packet.send.PacketFinishedParentQuestUpdateNotify;
import emu.grasscutter.server.packet.send.PacketQuestListUpdateNotify;
import emu.grasscutter.server.packet.send.PacketQuestProgressUpdateNotify;
import emu.grasscutter.server.packet.send.PacketServerCondMeetQuestListUpdateNotify;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
@@ -59,6 +68,17 @@ public class QuestManager {
}
}
// 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);
}
}
}
}
public GameMainQuest addMainQuest(QuestConfig questConfig) {
GameMainQuest mainQuest = new GameMainQuest(getPlayer(), questConfig.getMainQuest().getId());
getQuests().put(mainQuest.getParentQuestId(), mainQuest);
@@ -101,6 +121,50 @@ public class QuestManager {
return quest;
}
public void triggerEvent(QuestTriggerType condType, int... params) {
Set<GameQuest> changedQuests = new HashSet<>();
this.forEachActiveQuest(quest -> {
SubQuestConfigData data = quest.getConfig().getSubQuest();
for (int i = 0; i < data.getFinishCond().length; i++) {
if (quest.getFinishProgressList()[i] == 1) {
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) {
LogicType logicType = quest.getConfig().getSubQuest().getFailCondComb();
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();
}
}
}
public void loadFromDatabase() {
List<GameMainQuest> quests = DatabaseHelper.getAllQuests(getPlayer());