oxygengine_overworld/resources/
quests.rs1use crate::resources::market::{Currency, MarketItemId};
2use oxygengine_core::id::ID;
3use std::collections::{HashMap, HashSet};
4
5pub type ObjectiveId = ID<Objective<()>>;
6pub type QuestId = ID<Quest<(), ()>>;
7
8#[derive(Debug, Clone)]
9pub struct Objective<T>
10where
11 T: std::fmt::Debug + Clone + Send + Sync,
12{
13 pub data: T,
14}
15
16impl<T> Default for Objective<T>
17where
18 T: std::fmt::Debug + Default + Clone + Send + Sync,
19{
20 fn default() -> Self {
21 Self {
22 data: Default::default(),
23 }
24 }
25}
26
27#[derive(Debug, Clone)]
28pub enum QuestReward<V>
29where
30 V: Currency + std::fmt::Debug + Clone + Send + Sync,
31{
32 MarketItem(MarketItemId),
33 Currency(V),
34}
35
36#[derive(Debug, Clone)]
37pub struct Quest<T, V>
38where
39 T: std::fmt::Debug + Clone + Send + Sync,
40 V: Currency + std::fmt::Debug + Clone + Send + Sync,
41{
42 pub data: T,
43 pub objectives: HashSet<ObjectiveId>,
44 pub rewards: Vec<QuestReward<V>>,
45}
46
47impl<T, V> Default for Quest<T, V>
48where
49 T: std::fmt::Debug + Default + Clone + Send + Sync,
50 V: Currency + std::fmt::Debug + Clone + Send + Sync,
51{
52 fn default() -> Self {
53 Self {
54 data: Default::default(),
55 objectives: Default::default(),
56 rewards: Default::default(),
57 }
58 }
59}
60
61impl<T, V> Quest<T, V>
62where
63 T: std::fmt::Debug + Clone + Send + Sync,
64 V: Currency + std::fmt::Debug + Clone + Send + Sync,
65{
66 pub fn new(data: T) -> Self {
67 Self {
68 data,
69 objectives: Default::default(),
70 rewards: Default::default(),
71 }
72 }
73
74 pub fn with_objective(mut self, id: ObjectiveId) -> Self {
75 self.objectives.insert(id);
76 self
77 }
78
79 pub fn with_reward(mut self, reward: QuestReward<V>) -> Self {
80 self.rewards.push(reward);
81 self
82 }
83}
84
85#[derive(Debug, Clone)]
86pub struct QuestsDatabase<Q, B, V>
87where
88 Q: std::fmt::Debug + Clone + Send + Sync,
89 B: std::fmt::Debug + Clone + Send + Sync,
90 V: Currency + std::fmt::Debug + Clone + Send + Sync,
91{
92 objectives: HashMap<ObjectiveId, Objective<B>>,
93 quests: HashMap<QuestId, Quest<Q, V>>,
94}
95
96impl<Q, B, V> Default for QuestsDatabase<Q, B, V>
97where
98 Q: std::fmt::Debug + Clone + Send + Sync,
99 B: std::fmt::Debug + Clone + Send + Sync,
100 V: Currency + std::fmt::Debug + Clone + Send + Sync,
101{
102 fn default() -> Self {
103 Self {
104 objectives: Default::default(),
105 quests: Default::default(),
106 }
107 }
108}
109
110impl<Q, B, V> QuestsDatabase<Q, B, V>
111where
112 Q: std::fmt::Debug + Clone + Send + Sync,
113 B: std::fmt::Debug + Clone + Send + Sync,
114 V: Currency + std::fmt::Debug + Clone + Send + Sync,
115{
116 pub fn register_objective(&mut self, item: Objective<B>) -> ObjectiveId {
117 let id = ObjectiveId::new();
118 self.objectives.insert(id, item);
119 id
120 }
121
122 pub fn register_many_objectives<'a>(
123 &'a mut self,
124 iter: impl Iterator<Item = Objective<B>> + 'a,
125 ) -> impl Iterator<Item = ObjectiveId> + 'a {
126 let reserve = iter.size_hint();
127 let reserve = reserve.1.unwrap_or(reserve.0);
128 self.objectives.reserve(reserve);
129 iter.map(|item| self.register_objective(item))
130 }
131
132 pub fn unregister_objective(&mut self, id: ObjectiveId) -> Option<Objective<B>> {
133 if let Some(objective) = self.objectives.remove(&id) {
134 for quest in self.quests.values_mut() {
135 quest.objectives.remove(&id);
136 }
137 return Some(objective);
138 }
139 None
140 }
141
142 pub fn unregister_many_objectives<'a>(
143 &'a mut self,
144 iter: impl Iterator<Item = ObjectiveId> + 'a,
145 ) -> impl Iterator<Item = Objective<B>> + 'a {
146 iter.filter_map(|id| self.unregister_objective(id))
147 }
148
149 pub fn objectives(&self) -> impl Iterator<Item = (ObjectiveId, &Objective<B>)> {
150 self.objectives
151 .iter()
152 .map(|(id, objective)| (*id, objective))
153 }
154
155 pub fn objective(&self, id: ObjectiveId) -> Option<&Objective<B>> {
156 self.objectives.get(&id)
157 }
158
159 pub fn objective_mut(&mut self, id: ObjectiveId) -> Option<&mut Objective<B>> {
160 self.objectives.get_mut(&id)
161 }
162
163 pub fn find_objectives(
164 &self,
165 iter: impl Iterator<Item = ObjectiveId>,
166 ) -> impl Iterator<Item = (ObjectiveId, &Objective<B>)> {
167 iter.filter_map(|id| self.objective(id).map(|objective| (id, objective)))
168 }
169
170 pub fn contains_objective(&self, id: ObjectiveId) -> bool {
171 self.objectives.contains_key(&id)
172 }
173
174 pub fn objective_id(&self, data: &B) -> Option<ObjectiveId>
175 where
176 B: PartialEq,
177 {
178 self.objectives
179 .iter()
180 .find(|(_, objective)| &objective.data == data)
181 .map(|(id, _)| *id)
182 }
183
184 pub fn register_quest(&mut self, item: Quest<Q, V>) -> QuestId {
185 let id = QuestId::new();
186 self.quests.insert(id, item);
187 id
188 }
189
190 pub fn register_many_quests<'a>(
191 &'a mut self,
192 iter: impl Iterator<Item = Quest<Q, V>> + 'a,
193 ) -> impl Iterator<Item = QuestId> + 'a {
194 let reserve = iter.size_hint();
195 let reserve = reserve.1.unwrap_or(reserve.0);
196 self.quests.reserve(reserve);
197 iter.map(|item| self.register_quest(item))
198 }
199
200 pub fn unregister_quest(&mut self, id: QuestId) -> Option<Quest<Q, V>> {
201 self.quests.remove(&id)
202 }
203
204 pub fn unregister_many_quests<'a>(
205 &'a mut self,
206 iter: impl Iterator<Item = QuestId> + 'a,
207 ) -> impl Iterator<Item = Quest<Q, V>> + 'a {
208 iter.filter_map(|id| self.unregister_quest(id))
209 }
210
211 pub fn quests(&self) -> impl Iterator<Item = (QuestId, &Quest<Q, V>)> {
212 self.quests.iter().map(|(id, quest)| (*id, quest))
213 }
214
215 pub fn quest(&self, id: QuestId) -> Option<&Quest<Q, V>> {
216 self.quests.get(&id)
217 }
218
219 pub fn quest_mut(&mut self, id: QuestId) -> Option<&mut Quest<Q, V>> {
220 self.quests.get_mut(&id)
221 }
222
223 pub fn find_quests(
224 &self,
225 iter: impl Iterator<Item = QuestId>,
226 ) -> impl Iterator<Item = (QuestId, &Quest<Q, V>)> {
227 iter.filter_map(|id| self.quest(id).map(|quest| (id, quest)))
228 }
229
230 pub fn contains_quest(&self, id: QuestId) -> bool {
231 self.quests.contains_key(&id)
232 }
233
234 pub fn quest_id(&self, data: &Q) -> Option<QuestId>
235 where
236 Q: PartialEq,
237 {
238 self.quests
239 .iter()
240 .find(|(_, quest)| &quest.data == data)
241 .map(|(id, _)| *id)
242 }
243}