1use rakata_core::ResRef;
4use rakata_formats::{
5 gff_schema::{AbsentDefault, FieldLife, FieldSchema, GffType},
6 GffStruct, GffValue,
7};
8
9use super::object_id_or_invalid;
10use crate::gff_helpers::{get_f32, get_resref, upsert_field};
11use crate::shared::ObjectId;
12
13#[derive(Debug, Clone, PartialEq, Default)]
15pub struct GitEncounterPoint {
16 pub x: f32,
18 pub y: f32,
20 pub z: f32,
22}
23
24impl GitEncounterPoint {
25 pub(crate) fn from_gff_struct(s: &GffStruct) -> Self {
26 Self {
27 x: get_f32(s, "X").unwrap_or(0.0),
28 y: get_f32(s, "Y").unwrap_or(0.0),
29 z: get_f32(s, "Z").unwrap_or(0.0),
30 }
31 }
32
33 pub(crate) fn to_gff_struct(&self) -> GffStruct {
34 let mut s = GffStruct::new(0);
35 upsert_field(&mut s, "X", GffValue::Single(self.x));
36 upsert_field(&mut s, "Y", GffValue::Single(self.y));
37 upsert_field(&mut s, "Z", GffValue::Single(self.z));
38 s
39 }
40}
41
42#[derive(Debug, Clone, PartialEq, Default)]
44pub struct GitSpawnPoint {
45 pub x: f32,
47 pub y: f32,
49 pub z: f32,
51 pub orientation: f32,
53}
54
55impl GitSpawnPoint {
56 pub(crate) fn from_gff_struct(s: &GffStruct) -> Self {
57 Self {
58 x: get_f32(s, "X").unwrap_or(0.0),
59 y: get_f32(s, "Y").unwrap_or(0.0),
60 z: get_f32(s, "Z").unwrap_or(0.0),
61 orientation: get_f32(s, "Orientation").unwrap_or(0.0),
62 }
63 }
64
65 pub(crate) fn to_gff_struct(&self) -> GffStruct {
66 let mut s = GffStruct::new(0);
67 upsert_field(&mut s, "X", GffValue::Single(self.x));
68 upsert_field(&mut s, "Y", GffValue::Single(self.y));
69 upsert_field(&mut s, "Z", GffValue::Single(self.z));
70 upsert_field(&mut s, "Orientation", GffValue::Single(self.orientation));
71 s
72 }
73}
74
75#[derive(Debug, Clone, PartialEq, Default)]
77pub struct GitEncounter {
78 pub template_resref: ResRef,
80 pub x_position: f32,
82 pub y_position: f32,
84 pub z_position: f32,
86 pub geometry: Vec<GitEncounterPoint>,
88 pub spawn_points: Vec<GitSpawnPoint>,
90 pub object_id: ObjectId,
92}
93
94impl GitEncounter {
95 pub(crate) fn from_gff_struct(s: &GffStruct) -> Self {
96 let geometry = match s.field("Geometry") {
97 Some(GffValue::List(elements)) => elements
98 .iter()
99 .map(GitEncounterPoint::from_gff_struct)
100 .collect(),
101 _ => Vec::new(),
102 };
103
104 let spawn_points = match s.field("SpawnPointList") {
105 Some(GffValue::List(elements)) => elements
106 .iter()
107 .map(GitSpawnPoint::from_gff_struct)
108 .collect(),
109 _ => Vec::new(),
110 };
111
112 Self {
113 template_resref: get_resref(s, "TemplateResRef").unwrap_or_default(),
114 x_position: get_f32(s, "XPosition").unwrap_or(0.0),
115 y_position: get_f32(s, "YPosition").unwrap_or(0.0),
116 z_position: get_f32(s, "ZPosition").unwrap_or(0.0),
117 geometry,
118 spawn_points,
119 object_id: object_id_or_invalid(s),
120 }
121 }
122
123 pub(crate) fn to_gff_struct(&self) -> GffStruct {
124 let mut s = GffStruct::new(7);
125 upsert_field(
126 &mut s,
127 "TemplateResRef",
128 GffValue::ResRef(self.template_resref),
129 );
130 upsert_field(&mut s, "XPosition", GffValue::Single(self.x_position));
131 upsert_field(&mut s, "YPosition", GffValue::Single(self.y_position));
132 upsert_field(&mut s, "ZPosition", GffValue::Single(self.z_position));
133 let geom_structs: Vec<GffStruct> =
134 self.geometry.iter().map(|p| p.to_gff_struct()).collect();
135 upsert_field(&mut s, "Geometry", GffValue::List(geom_structs));
136 let spawn_structs: Vec<GffStruct> = self
137 .spawn_points
138 .iter()
139 .map(|sp| sp.to_gff_struct())
140 .collect();
141 upsert_field(&mut s, "SpawnPointList", GffValue::List(spawn_structs));
142 upsert_field(&mut s, "ObjectId", GffValue::UInt32(self.object_id.get()));
143 s
144 }
145}
146
147pub(crate) static ENCOUNTER_GEOMETRY_CHILDREN: &[FieldSchema] = &[
149 FieldSchema {
150 label: "X",
151 expected_type: GffType::Single,
152 life: FieldLife::Live,
153 required: false,
154 absent: AbsentDefault::Unverified,
155 children: None,
156 constraint: None,
157 },
158 FieldSchema {
159 label: "Y",
160 expected_type: GffType::Single,
161 life: FieldLife::Live,
162 required: false,
163 absent: AbsentDefault::Unverified,
164 children: None,
165 constraint: None,
166 },
167 FieldSchema {
168 label: "Z",
169 expected_type: GffType::Single,
170 life: FieldLife::Live,
171 required: false,
172 absent: AbsentDefault::Unverified,
173 children: None,
174 constraint: None,
175 },
176];
177
178pub(crate) static ENCOUNTER_SPAWN_POINT_CHILDREN: &[FieldSchema] = &[
180 FieldSchema {
181 label: "X",
182 expected_type: GffType::Single,
183 life: FieldLife::Live,
184 required: false,
185 absent: AbsentDefault::Unverified,
186 children: None,
187 constraint: None,
188 },
189 FieldSchema {
190 label: "Y",
191 expected_type: GffType::Single,
192 life: FieldLife::Live,
193 required: false,
194 absent: AbsentDefault::Unverified,
195 children: None,
196 constraint: None,
197 },
198 FieldSchema {
199 label: "Z",
200 expected_type: GffType::Single,
201 life: FieldLife::Live,
202 required: false,
203 absent: AbsentDefault::Unverified,
204 children: None,
205 constraint: None,
206 },
207 FieldSchema {
208 label: "Orientation",
209 expected_type: GffType::Single,
210 life: FieldLife::Live,
211 required: false,
212 absent: AbsentDefault::Unverified,
213 children: None,
214 constraint: None,
215 },
216];
217
218pub(crate) static ENCOUNTER_LIST_CHILDREN: &[FieldSchema] = &[
220 FieldSchema {
221 label: "ObjectId",
222 expected_type: GffType::UInt32,
223 life: FieldLife::Live,
224 required: false,
225 absent: AbsentDefault::Unverified,
226 children: None,
227 constraint: None,
228 },
229 FieldSchema {
230 label: "TemplateResRef",
231 expected_type: GffType::ResRef,
232 life: FieldLife::Live,
233 required: false,
234 absent: AbsentDefault::Unverified,
235 children: None,
236 constraint: None,
237 },
238 FieldSchema {
239 label: "XPosition",
240 expected_type: GffType::Single,
241 life: FieldLife::Live,
242 required: false,
243 absent: AbsentDefault::Unverified,
244 children: None,
245 constraint: None,
246 },
247 FieldSchema {
248 label: "YPosition",
249 expected_type: GffType::Single,
250 life: FieldLife::Live,
251 required: false,
252 absent: AbsentDefault::Unverified,
253 children: None,
254 constraint: None,
255 },
256 FieldSchema {
257 label: "ZPosition",
258 expected_type: GffType::Single,
259 life: FieldLife::Live,
260 required: false,
261 absent: AbsentDefault::Unverified,
262 children: None,
263 constraint: None,
264 },
265 FieldSchema {
266 label: "Geometry",
267 expected_type: GffType::List,
268 life: FieldLife::Live,
269 required: false,
270 absent: AbsentDefault::Unverified,
271 children: Some(ENCOUNTER_GEOMETRY_CHILDREN),
272 constraint: None,
273 },
274 FieldSchema {
275 label: "SpawnPointList",
276 expected_type: GffType::List,
277 life: FieldLife::Live,
278 required: false,
279 absent: AbsentDefault::Unverified,
280 children: Some(ENCOUNTER_SPAWN_POINT_CHILDREN),
281 constraint: None,
282 },
283];