QuestManager.java 5.87 KB
Newer Older
Melledy's avatar
Melledy committed
1
2
package emu.grasscutter.game.quest;

Akka's avatar
Akka committed
3
import java.util.*;
Melledy's avatar
Melledy committed
4
import java.util.function.Consumer;
Akka's avatar
Akka committed
5
import java.util.stream.Collectors;
Melledy's avatar
Melledy committed
6

Akka's avatar
Akka committed
7
import emu.grasscutter.Grasscutter;
Melledy's avatar
Melledy committed
8
import emu.grasscutter.data.GameData;
Akka's avatar
Akka committed
9
import emu.grasscutter.data.binout.MainQuestData;
Melledy's avatar
Melledy committed
10
11
import emu.grasscutter.data.excels.QuestData;
import emu.grasscutter.data.excels.QuestData.QuestCondition;
Melledy's avatar
Melledy committed
12
import emu.grasscutter.database.DatabaseHelper;
Melledy's avatar
Melledy committed
13
import emu.grasscutter.game.player.BasePlayerManager;
Melledy's avatar
Melledy committed
14
import emu.grasscutter.game.player.Player;
Akka's avatar
Akka committed
15
import emu.grasscutter.game.quest.enums.ParentQuestState;
Melledy's avatar
Melledy committed
16
import emu.grasscutter.game.quest.enums.QuestTrigger;
17
import emu.grasscutter.game.quest.enums.LogicType;
Melledy's avatar
Melledy committed
18
import emu.grasscutter.game.quest.enums.QuestState;
Akka's avatar
Akka committed
19
import emu.grasscutter.server.packet.send.*;
Melledy's avatar
Melledy committed
20
21
22
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;

Melledy's avatar
Melledy committed
23
public class QuestManager extends BasePlayerManager {
Melledy's avatar
Melledy committed
24
	private final Int2ObjectMap<GameMainQuest> quests;
Akka's avatar
Akka committed
25

Melledy's avatar
Melledy committed
26
	public QuestManager(Player player) {
Melledy's avatar
Melledy committed
27
		super(player);
Melledy's avatar
Melledy committed
28
29
30
31
32
33
34
35
36
37
38
39
		this.quests = new Int2ObjectOpenHashMap<>();
	}

	public Int2ObjectMap<GameMainQuest> getQuests() {
		return quests;
	}
	
	public GameMainQuest getMainQuestById(int mainQuestId) {
		return getQuests().get(mainQuestId);
	}
	
	public GameQuest getQuestById(int questId) {
Melledy's avatar
Melledy committed
40
		QuestData questConfig = GameData.getQuestDataMap().get(questId);
Melledy's avatar
Melledy committed
41
42
43
44
		if (questConfig == null) {
			return null;
		}
		
Melledy's avatar
Melledy committed
45
		GameMainQuest mainQuest = getQuests().get(questConfig.getMainId());
Melledy's avatar
Melledy committed
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
		
		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);
			}
		}
	}
61
62
63
64
65
66

	public void forEachMainQuest(Consumer<GameMainQuest> callback) {
		for (GameMainQuest mainQuest : getQuests().values()) {
			callback.accept(mainQuest);
		}
	}
Melledy's avatar
Melledy committed
67
	
68
69
70
71
72
73
74
75
76
77
78
	// 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);
				}
			}
		}
	}
	
Melledy's avatar
Melledy committed
79
80
	public GameMainQuest addMainQuest(QuestData questConfig) {
		GameMainQuest mainQuest = new GameMainQuest(getPlayer(), questConfig.getMainId());
Melledy's avatar
Melledy committed
81
82
83
84
85
86
87
88
		getQuests().put(mainQuest.getParentQuestId(), mainQuest);

		getPlayer().sendPacket(new PacketFinishedParentQuestUpdateNotify(mainQuest));
		
		return mainQuest;
	}
	
	public GameQuest addQuest(int questId) {
Melledy's avatar
Melledy committed
89
		QuestData questConfig = GameData.getQuestDataMap().get(questId);
Melledy's avatar
Melledy committed
90
91
92
93
94
		if (questConfig == null) {
			return null;
		}
		
		// Main quest
Melledy's avatar
Melledy committed
95
		GameMainQuest mainQuest = this.getMainQuestById(questConfig.getMainId());
Melledy's avatar
Melledy committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
		
		// 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 PacketQuestListUpdateNotify(quest));

		return quest;
	}
Akka's avatar
Akka committed
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
    public void startMainQuest(int mainQuestId){
        var mainQuestData = GameData.getMainQuestDataMap().get(mainQuestId);

        if (mainQuestData == null){
            return;
        }

        Arrays.stream(mainQuestData.getSubQuests())
            .min(Comparator.comparingInt(MainQuestData.SubQuestData::getOrder))
            .map(MainQuestData.SubQuestData::getSubId)
            .ifPresent(this::addQuest);
    }
    public void triggerEvent(QuestTrigger condType, int... params) {
        triggerEvent(condType, "", params);
    }

	public void triggerEvent(QuestTrigger condType, String paramStr, int... params) {
        Grasscutter.getLogger().debug("Trigger Event {}, {}, {}", condType, paramStr, params);
138
		Set<GameQuest> changedQuests = new HashSet<>();
Akka's avatar
Akka committed
139

140
		this.forEachActiveQuest(quest -> {
Melledy's avatar
Melledy committed
141
			QuestData data = quest.getData();
Akka's avatar
Akka committed
142
143
144

			for (int i = 0; i < data.getFinishCond().size(); i++) {
				if (quest.getFinishProgressList() == null
145
146
					|| quest.getFinishProgressList().length == 0
					|| quest.getFinishProgressList()[i] == 1) {
147
148
					continue;
				}
Akka's avatar
Akka committed
149
150
151

				QuestCondition condition = data.getFinishCond().get(i);

152
153
154
				if (condition.getType() != condType) {
					continue;
				}
Akka's avatar
Akka committed
155
156
157

				boolean result = getPlayer().getServer().getQuestHandler().triggerContent(quest, condition, paramStr, params);

158
159
				if (result) {
					quest.getFinishProgressList()[i] = 1;
Akka's avatar
Akka committed
160

161
162
163
164
					changedQuests.add(quest);
				}
			}
		});
Akka's avatar
Akka committed
165

166
		for (GameQuest quest : changedQuests) {
Melledy's avatar
Melledy committed
167
			LogicType logicType = quest.getData().getFailCondComb();
168
			int[] progress = quest.getFinishProgressList();
Akka's avatar
Akka committed
169

170
171
172
173
174
175
176
177
178
179
180
181
			// Handle logical comb
			boolean finish = LogicType.calculate(logicType, progress);

			// Finish
			if (finish) {
				quest.finish();
			} else {
				getPlayer().sendPacket(new PacketQuestProgressUpdateNotify(quest));
				quest.save();
			}
		}
	}
Melledy's avatar
Melledy committed
182

Akka's avatar
Akka committed
183
184
185
186
187
188
189
190
191
    public List<QuestGroupSuite> getSceneGroupSuite(int sceneId) {
        return getQuests().values().stream()
            .filter(i -> i.getState() != ParentQuestState.PARENT_QUEST_STATE_FINISHED)
            .map(GameMainQuest::getQuestGroupSuites)
            .filter(Objects::nonNull)
            .flatMap(Collection::stream)
            .filter(i -> i.getScene() == sceneId)
            .toList();
    }
Melledy's avatar
Melledy committed
192
193
194
195
196
197
198
199
	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);
Melledy's avatar
Melledy committed
200
				quest.setConfig(GameData.getQuestDataMap().get(quest.getQuestId()));
Melledy's avatar
Melledy committed
201
202
203
204
205
206
			}
			
			this.getQuests().put(mainQuest.getParentQuestId(), mainQuest);
		}
	}
}