1use super::{
2 BlockPos, ChunkPos, ChunkStorage, DesertPyramidPieceData, FortressPieceData, IVec3,
3 JigsawJunction, JigsawPieceData, JungleTemplePieceData, MineshaftPieceKind,
4 MineshaftPiecePayload, OceanMonumentChildPiece, OceanMonumentChildPieceKind,
5 OceanMonumentPieceData, OceanMonumentRoomData, PackedChunkPos, PersistentBoundingBox,
6 PersistentDesertPyramidPieceData, PersistentJigsawJunction, PersistentJigsawPieceData,
7 PersistentJungleTemplePieceData, PersistentMineshaftPieceData, PersistentMineshaftPieceKind,
8 PersistentNetherFortressPieceData, PersistentOceanMonumentChildPiece,
9 PersistentOceanMonumentChildPieceKind, PersistentOceanMonumentPieceData,
10 PersistentOceanMonumentRoomData, PersistentPoolElement, PersistentProceduralPieceData,
11 PersistentProcessorList, PersistentStrongholdPieceData, PersistentStrongholdSmallDoorType,
12 PersistentStructurePiece, PersistentStructurePiecePayload, PersistentStructureReference,
13 PersistentStructureStart, PersistentSwampHutPieceData, PersistentTemplatePieceData,
14 PersistentTemplateProcessorList, PoolElement, ProceduralPieceData, ProcessorList, REGISTRY,
15 RegistryExt, RuinedPortalProperties, StrongholdPieceData, StrongholdSmallDoorType,
16 StructurePiece, StructurePiecePayload, StructureReferenceMap, StructureStart,
17 StructureStartMap, SwampHutPieceData, TemplatePieceData, TemplateProcessorList,
18 TerrainAdjustment, block_ignore_from_persistent, block_ignore_to_persistent,
19 compare_identifiers, direction_from_2d, direction_to_2d, liquid_settings_from_persistent,
20 liquid_settings_to_persistent, marker_handling_from_persistent, marker_handling_to_persistent,
21 mineshaft_type_from_persistent, mineshaft_type_to_persistent, mirror_from_persistent,
22 mirror_to_persistent, ocean_ruin_biome_temp_from_persistent,
23 ocean_ruin_biome_temp_to_persistent, placement_adjustment_from_persistent,
24 placement_adjustment_to_persistent, placement_clip_from_persistent,
25 placement_clip_to_persistent, post_process_from_persistent, post_process_to_persistent,
26 projection_from_persistent, projection_to_persistent, required_direction_from_2d,
27 required_projection_from_persistent, rotation_from_persistent, rotation_to_persistent,
28 ruined_portal_placement_from_persistent, ruined_portal_placement_to_persistent,
29};
30
31impl ChunkStorage {
32 pub(super) fn jigsaw_piece_data_to_persistent(
33 data: &JigsawPieceData,
34 ) -> PersistentJigsawPieceData {
35 PersistentJigsawPieceData {
36 pool_element: Self::pool_element_to_persistent(&data.pool_element),
37 position: [data.position.x, data.position.y, data.position.z],
38 rotation: rotation_to_persistent(data.rotation),
39 liquid_settings: liquid_settings_to_persistent(data.liquid_settings),
40 }
41 }
42
43 pub(super) fn persistent_to_jigsaw_piece_data(
44 data: &PersistentJigsawPieceData,
45 ) -> JigsawPieceData {
46 JigsawPieceData {
47 pool_element: Self::persistent_to_pool_element(&data.pool_element),
48 position: IVec3::new(data.position[0], data.position[1], data.position[2]),
49 rotation: rotation_from_persistent(data.rotation),
50 liquid_settings: liquid_settings_from_persistent(data.liquid_settings),
51 }
52 }
53
54 pub(super) fn procedural_piece_data_to_persistent(
55 data: &ProceduralPieceData,
56 ) -> PersistentProceduralPieceData {
57 match data {
58 ProceduralPieceData::Unimplemented => PersistentProceduralPieceData::Unimplemented,
59 ProceduralPieceData::BuriedTreasure => PersistentProceduralPieceData::BuriedTreasure,
60 ProceduralPieceData::DesertPyramid(data) => {
61 PersistentProceduralPieceData::DesertPyramid(PersistentDesertPyramidPieceData {
62 height_position: data.height_position.unwrap_or(-1),
63 has_placed_chest: data.has_placed_chest,
64 })
65 }
66 ProceduralPieceData::JungleTemple(data) => {
67 PersistentProceduralPieceData::JungleTemple(PersistentJungleTemplePieceData {
68 height_position: data.height_position.unwrap_or(-1),
69 placed_main_chest: data.placed_main_chest,
70 placed_hidden_chest: data.placed_hidden_chest,
71 placed_trap1: data.placed_trap1,
72 placed_trap2: data.placed_trap2,
73 })
74 }
75 ProceduralPieceData::Mineshaft(data) => {
76 PersistentProceduralPieceData::Mineshaft(PersistentMineshaftPieceData {
77 mineshaft_type: mineshaft_type_to_persistent(data.mineshaft_type),
78 kind: Self::mineshaft_kind_to_persistent(&data.kind),
79 })
80 }
81 ProceduralPieceData::NetherFortress(data) => {
82 PersistentProceduralPieceData::NetherFortress(
83 Self::fortress_piece_data_to_persistent(*data),
84 )
85 }
86 ProceduralPieceData::OceanMonument(data) => {
87 PersistentProceduralPieceData::OceanMonument(
88 Self::ocean_monument_data_to_persistent(data),
89 )
90 }
91 ProceduralPieceData::Stronghold(data) => PersistentProceduralPieceData::Stronghold(
92 Self::stronghold_piece_data_to_persistent(*data),
93 ),
94 ProceduralPieceData::SwampHut(data) => {
95 PersistentProceduralPieceData::SwampHut(PersistentSwampHutPieceData {
96 height_position: data.height_position.unwrap_or(-1),
97 spawned_witch: data.spawned_witch,
98 spawned_cat: data.spawned_cat,
99 })
100 }
101 }
102 }
103
104 pub(super) fn persistent_to_procedural_piece_data(
105 data: &PersistentProceduralPieceData,
106 ) -> ProceduralPieceData {
107 match data {
108 PersistentProceduralPieceData::Unimplemented => ProceduralPieceData::Unimplemented,
109 PersistentProceduralPieceData::BuriedTreasure => ProceduralPieceData::BuriedTreasure,
110 PersistentProceduralPieceData::DesertPyramid(data) => {
111 ProceduralPieceData::DesertPyramid(DesertPyramidPieceData {
112 height_position: (data.height_position >= 0).then_some(data.height_position),
113 has_placed_chest: data.has_placed_chest,
114 potential_suspicious_sand_world_positions: Vec::new(),
115 random_collapsed_roof_pos: BlockPos::new(0, 0, 0),
116 })
117 }
118 PersistentProceduralPieceData::JungleTemple(data) => {
119 ProceduralPieceData::JungleTemple(JungleTemplePieceData {
120 height_position: (data.height_position >= 0).then_some(data.height_position),
121 placed_main_chest: data.placed_main_chest,
122 placed_hidden_chest: data.placed_hidden_chest,
123 placed_trap1: data.placed_trap1,
124 placed_trap2: data.placed_trap2,
125 })
126 }
127 PersistentProceduralPieceData::Mineshaft(data) => {
128 ProceduralPieceData::Mineshaft(MineshaftPiecePayload {
129 mineshaft_type: mineshaft_type_from_persistent(data.mineshaft_type),
130 kind: Self::persistent_to_mineshaft_kind(&data.kind),
131 })
132 }
133 PersistentProceduralPieceData::NetherFortress(data) => {
134 ProceduralPieceData::NetherFortress(Self::persistent_to_fortress_piece_data(data))
135 }
136 PersistentProceduralPieceData::OceanMonument(data) => {
137 ProceduralPieceData::OceanMonument(Self::persistent_to_ocean_monument_data(data))
138 }
139 PersistentProceduralPieceData::Stronghold(data) => {
140 ProceduralPieceData::Stronghold(Self::persistent_to_stronghold_piece_data(data))
141 }
142 PersistentProceduralPieceData::SwampHut(data) => {
143 ProceduralPieceData::SwampHut(SwampHutPieceData {
144 height_position: (data.height_position >= 0).then_some(data.height_position),
145 spawned_witch: data.spawned_witch,
146 spawned_cat: data.spawned_cat,
147 })
148 }
149 }
150 }
151
152 pub(super) fn ocean_monument_data_to_persistent(
153 data: &OceanMonumentPieceData,
154 ) -> PersistentOceanMonumentPieceData {
155 PersistentOceanMonumentPieceData {
156 child_pieces: data
157 .child_pieces
158 .iter()
159 .map(Self::ocean_monument_child_to_persistent)
160 .collect(),
161 }
162 }
163
164 pub(super) fn persistent_to_ocean_monument_data(
165 data: &PersistentOceanMonumentPieceData,
166 ) -> OceanMonumentPieceData {
167 OceanMonumentPieceData {
168 child_pieces: data
169 .child_pieces
170 .iter()
171 .map(Self::persistent_to_ocean_monument_child)
172 .collect(),
173 }
174 }
175
176 const fn ocean_monument_child_to_persistent(
177 child: &OceanMonumentChildPiece,
178 ) -> PersistentOceanMonumentChildPiece {
179 PersistentOceanMonumentChildPiece {
180 bounding_box: PersistentBoundingBox::from_bounding_box(child.bounding_box),
181 kind: Self::ocean_monument_child_kind_to_persistent(&child.kind),
182 }
183 }
184
185 const fn persistent_to_ocean_monument_child(
186 child: &PersistentOceanMonumentChildPiece,
187 ) -> OceanMonumentChildPiece {
188 OceanMonumentChildPiece {
189 bounding_box: child.bounding_box.to_bounding_box(),
190 kind: Self::persistent_to_ocean_monument_child_kind(&child.kind),
191 }
192 }
193
194 const fn ocean_monument_child_kind_to_persistent(
195 kind: &OceanMonumentChildPieceKind,
196 ) -> PersistentOceanMonumentChildPieceKind {
197 match kind {
198 OceanMonumentChildPieceKind::EntryRoom { room } => {
199 PersistentOceanMonumentChildPieceKind::EntryRoom {
200 room: Self::ocean_monument_room_to_persistent(*room),
201 }
202 }
203 OceanMonumentChildPieceKind::CoreRoom => {
204 PersistentOceanMonumentChildPieceKind::CoreRoom
205 }
206 OceanMonumentChildPieceKind::DoubleXRoom { west, east } => {
207 PersistentOceanMonumentChildPieceKind::DoubleXRoom {
208 west: Self::ocean_monument_room_to_persistent(*west),
209 east: Self::ocean_monument_room_to_persistent(*east),
210 }
211 }
212 OceanMonumentChildPieceKind::DoubleXYRoom {
213 west,
214 east,
215 west_up,
216 east_up,
217 } => PersistentOceanMonumentChildPieceKind::DoubleXYRoom {
218 west: Self::ocean_monument_room_to_persistent(*west),
219 east: Self::ocean_monument_room_to_persistent(*east),
220 west_up: Self::ocean_monument_room_to_persistent(*west_up),
221 east_up: Self::ocean_monument_room_to_persistent(*east_up),
222 },
223 OceanMonumentChildPieceKind::DoubleYRoom { room, above } => {
224 PersistentOceanMonumentChildPieceKind::DoubleYRoom {
225 room: Self::ocean_monument_room_to_persistent(*room),
226 above: Self::ocean_monument_room_to_persistent(*above),
227 }
228 }
229 OceanMonumentChildPieceKind::DoubleYZRoom {
230 south,
231 north,
232 south_up,
233 north_up,
234 } => PersistentOceanMonumentChildPieceKind::DoubleYZRoom {
235 south: Self::ocean_monument_room_to_persistent(*south),
236 north: Self::ocean_monument_room_to_persistent(*north),
237 south_up: Self::ocean_monument_room_to_persistent(*south_up),
238 north_up: Self::ocean_monument_room_to_persistent(*north_up),
239 },
240 OceanMonumentChildPieceKind::DoubleZRoom { south, north } => {
241 PersistentOceanMonumentChildPieceKind::DoubleZRoom {
242 south: Self::ocean_monument_room_to_persistent(*south),
243 north: Self::ocean_monument_room_to_persistent(*north),
244 }
245 }
246 OceanMonumentChildPieceKind::SimpleRoom { room, main_design } => {
247 PersistentOceanMonumentChildPieceKind::SimpleRoom {
248 room: Self::ocean_monument_room_to_persistent(*room),
249 main_design: *main_design,
250 }
251 }
252 OceanMonumentChildPieceKind::SimpleTopRoom { room } => {
253 PersistentOceanMonumentChildPieceKind::SimpleTopRoom {
254 room: Self::ocean_monument_room_to_persistent(*room),
255 }
256 }
257 OceanMonumentChildPieceKind::WingRoom { main_design } => {
258 PersistentOceanMonumentChildPieceKind::WingRoom {
259 main_design: *main_design,
260 }
261 }
262 OceanMonumentChildPieceKind::Penthouse => {
263 PersistentOceanMonumentChildPieceKind::Penthouse
264 }
265 }
266 }
267
268 const fn persistent_to_ocean_monument_child_kind(
269 kind: &PersistentOceanMonumentChildPieceKind,
270 ) -> OceanMonumentChildPieceKind {
271 match kind {
272 PersistentOceanMonumentChildPieceKind::EntryRoom { room } => {
273 OceanMonumentChildPieceKind::EntryRoom {
274 room: Self::persistent_to_ocean_monument_room(room),
275 }
276 }
277 PersistentOceanMonumentChildPieceKind::CoreRoom => {
278 OceanMonumentChildPieceKind::CoreRoom
279 }
280 PersistentOceanMonumentChildPieceKind::DoubleXRoom { west, east } => {
281 OceanMonumentChildPieceKind::DoubleXRoom {
282 west: Self::persistent_to_ocean_monument_room(west),
283 east: Self::persistent_to_ocean_monument_room(east),
284 }
285 }
286 PersistentOceanMonumentChildPieceKind::DoubleXYRoom {
287 west,
288 east,
289 west_up,
290 east_up,
291 } => OceanMonumentChildPieceKind::DoubleXYRoom {
292 west: Self::persistent_to_ocean_monument_room(west),
293 east: Self::persistent_to_ocean_monument_room(east),
294 west_up: Self::persistent_to_ocean_monument_room(west_up),
295 east_up: Self::persistent_to_ocean_monument_room(east_up),
296 },
297 PersistentOceanMonumentChildPieceKind::DoubleYRoom { room, above } => {
298 OceanMonumentChildPieceKind::DoubleYRoom {
299 room: Self::persistent_to_ocean_monument_room(room),
300 above: Self::persistent_to_ocean_monument_room(above),
301 }
302 }
303 PersistentOceanMonumentChildPieceKind::DoubleYZRoom {
304 south,
305 north,
306 south_up,
307 north_up,
308 } => OceanMonumentChildPieceKind::DoubleYZRoom {
309 south: Self::persistent_to_ocean_monument_room(south),
310 north: Self::persistent_to_ocean_monument_room(north),
311 south_up: Self::persistent_to_ocean_monument_room(south_up),
312 north_up: Self::persistent_to_ocean_monument_room(north_up),
313 },
314 PersistentOceanMonumentChildPieceKind::DoubleZRoom { south, north } => {
315 OceanMonumentChildPieceKind::DoubleZRoom {
316 south: Self::persistent_to_ocean_monument_room(south),
317 north: Self::persistent_to_ocean_monument_room(north),
318 }
319 }
320 PersistentOceanMonumentChildPieceKind::SimpleRoom { room, main_design } => {
321 OceanMonumentChildPieceKind::SimpleRoom {
322 room: Self::persistent_to_ocean_monument_room(room),
323 main_design: *main_design,
324 }
325 }
326 PersistentOceanMonumentChildPieceKind::SimpleTopRoom { room } => {
327 OceanMonumentChildPieceKind::SimpleTopRoom {
328 room: Self::persistent_to_ocean_monument_room(room),
329 }
330 }
331 PersistentOceanMonumentChildPieceKind::WingRoom { main_design } => {
332 OceanMonumentChildPieceKind::WingRoom {
333 main_design: *main_design,
334 }
335 }
336 PersistentOceanMonumentChildPieceKind::Penthouse => {
337 OceanMonumentChildPieceKind::Penthouse
338 }
339 }
340 }
341
342 const fn ocean_monument_room_to_persistent(
343 room: OceanMonumentRoomData,
344 ) -> PersistentOceanMonumentRoomData {
345 PersistentOceanMonumentRoomData {
346 index: room.index,
347 has_opening: room.has_opening,
348 has_up_connection: room.has_up_connection,
349 }
350 }
351
352 const fn persistent_to_ocean_monument_room(
353 room: &PersistentOceanMonumentRoomData,
354 ) -> OceanMonumentRoomData {
355 OceanMonumentRoomData {
356 index: room.index,
357 has_opening: room.has_opening,
358 has_up_connection: room.has_up_connection,
359 }
360 }
361
362 const fn fortress_piece_data_to_persistent(
363 data: FortressPieceData,
364 ) -> PersistentNetherFortressPieceData {
365 match data {
366 FortressPieceData::BridgeCrossing => PersistentNetherFortressPieceData::BridgeCrossing,
367 FortressPieceData::BridgeEndFiller { self_seed } => {
368 PersistentNetherFortressPieceData::BridgeEndFiller { self_seed }
369 }
370 FortressPieceData::BridgeStraight => PersistentNetherFortressPieceData::BridgeStraight,
371 FortressPieceData::CastleCorridorStairs => {
372 PersistentNetherFortressPieceData::CastleCorridorStairs
373 }
374 FortressPieceData::CastleCorridorTBalcony => {
375 PersistentNetherFortressPieceData::CastleCorridorTBalcony
376 }
377 FortressPieceData::CastleEntrance => PersistentNetherFortressPieceData::CastleEntrance,
378 FortressPieceData::CastleSmallCorridorCrossing => {
379 PersistentNetherFortressPieceData::CastleSmallCorridorCrossing
380 }
381 FortressPieceData::CastleSmallCorridorLeftTurn { is_needing_chest } => {
382 PersistentNetherFortressPieceData::CastleSmallCorridorLeftTurn { is_needing_chest }
383 }
384 FortressPieceData::CastleSmallCorridor => {
385 PersistentNetherFortressPieceData::CastleSmallCorridor
386 }
387 FortressPieceData::CastleSmallCorridorRightTurn { is_needing_chest } => {
388 PersistentNetherFortressPieceData::CastleSmallCorridorRightTurn { is_needing_chest }
389 }
390 FortressPieceData::CastleStalkRoom => {
391 PersistentNetherFortressPieceData::CastleStalkRoom
392 }
393 FortressPieceData::MonsterThrone { has_placed_spawner } => {
394 PersistentNetherFortressPieceData::MonsterThrone { has_placed_spawner }
395 }
396 FortressPieceData::RoomCrossing => PersistentNetherFortressPieceData::RoomCrossing,
397 FortressPieceData::StairsRoom => PersistentNetherFortressPieceData::StairsRoom,
398 }
399 }
400
401 const fn persistent_to_fortress_piece_data(
402 data: &PersistentNetherFortressPieceData,
403 ) -> FortressPieceData {
404 match data {
405 PersistentNetherFortressPieceData::BridgeCrossing => FortressPieceData::BridgeCrossing,
406 PersistentNetherFortressPieceData::BridgeEndFiller { self_seed } => {
407 FortressPieceData::BridgeEndFiller {
408 self_seed: *self_seed,
409 }
410 }
411 PersistentNetherFortressPieceData::BridgeStraight => FortressPieceData::BridgeStraight,
412 PersistentNetherFortressPieceData::CastleCorridorStairs => {
413 FortressPieceData::CastleCorridorStairs
414 }
415 PersistentNetherFortressPieceData::CastleCorridorTBalcony => {
416 FortressPieceData::CastleCorridorTBalcony
417 }
418 PersistentNetherFortressPieceData::CastleEntrance => FortressPieceData::CastleEntrance,
419 PersistentNetherFortressPieceData::CastleSmallCorridorCrossing => {
420 FortressPieceData::CastleSmallCorridorCrossing
421 }
422 PersistentNetherFortressPieceData::CastleSmallCorridorLeftTurn { is_needing_chest } => {
423 FortressPieceData::CastleSmallCorridorLeftTurn {
424 is_needing_chest: *is_needing_chest,
425 }
426 }
427 PersistentNetherFortressPieceData::CastleSmallCorridor => {
428 FortressPieceData::CastleSmallCorridor
429 }
430 PersistentNetherFortressPieceData::CastleSmallCorridorRightTurn {
431 is_needing_chest,
432 } => FortressPieceData::CastleSmallCorridorRightTurn {
433 is_needing_chest: *is_needing_chest,
434 },
435 PersistentNetherFortressPieceData::CastleStalkRoom => {
436 FortressPieceData::CastleStalkRoom
437 }
438 PersistentNetherFortressPieceData::MonsterThrone { has_placed_spawner } => {
439 FortressPieceData::MonsterThrone {
440 has_placed_spawner: *has_placed_spawner,
441 }
442 }
443 PersistentNetherFortressPieceData::RoomCrossing => FortressPieceData::RoomCrossing,
444 PersistentNetherFortressPieceData::StairsRoom => FortressPieceData::StairsRoom,
445 }
446 }
447
448 const fn stronghold_door_to_persistent(
449 door: StrongholdSmallDoorType,
450 ) -> PersistentStrongholdSmallDoorType {
451 match door {
452 StrongholdSmallDoorType::Opening => PersistentStrongholdSmallDoorType::Opening,
453 StrongholdSmallDoorType::WoodDoor => PersistentStrongholdSmallDoorType::WoodDoor,
454 StrongholdSmallDoorType::Grates => PersistentStrongholdSmallDoorType::Grates,
455 StrongholdSmallDoorType::IronDoor => PersistentStrongholdSmallDoorType::IronDoor,
456 }
457 }
458
459 const fn persistent_to_stronghold_door(
460 door: &PersistentStrongholdSmallDoorType,
461 ) -> StrongholdSmallDoorType {
462 match door {
463 PersistentStrongholdSmallDoorType::Opening => StrongholdSmallDoorType::Opening,
464 PersistentStrongholdSmallDoorType::WoodDoor => StrongholdSmallDoorType::WoodDoor,
465 PersistentStrongholdSmallDoorType::Grates => StrongholdSmallDoorType::Grates,
466 PersistentStrongholdSmallDoorType::IronDoor => StrongholdSmallDoorType::IronDoor,
467 }
468 }
469
470 const fn stronghold_piece_data_to_persistent(
471 data: StrongholdPieceData,
472 ) -> PersistentStrongholdPieceData {
473 match data {
474 StrongholdPieceData::Straight {
475 entry_door,
476 left_child,
477 right_child,
478 } => PersistentStrongholdPieceData::Straight {
479 entry_door: Self::stronghold_door_to_persistent(entry_door),
480 left_child,
481 right_child,
482 },
483 StrongholdPieceData::PrisonHall { entry_door } => {
484 PersistentStrongholdPieceData::PrisonHall {
485 entry_door: Self::stronghold_door_to_persistent(entry_door),
486 }
487 }
488 StrongholdPieceData::LeftTurn { entry_door } => {
489 PersistentStrongholdPieceData::LeftTurn {
490 entry_door: Self::stronghold_door_to_persistent(entry_door),
491 }
492 }
493 StrongholdPieceData::RightTurn { entry_door } => {
494 PersistentStrongholdPieceData::RightTurn {
495 entry_door: Self::stronghold_door_to_persistent(entry_door),
496 }
497 }
498 StrongholdPieceData::RoomCrossing {
499 entry_door,
500 crossing_type,
501 } => PersistentStrongholdPieceData::RoomCrossing {
502 entry_door: Self::stronghold_door_to_persistent(entry_door),
503 crossing_type,
504 },
505 StrongholdPieceData::StraightStairsDown { entry_door } => {
506 PersistentStrongholdPieceData::StraightStairsDown {
507 entry_door: Self::stronghold_door_to_persistent(entry_door),
508 }
509 }
510 StrongholdPieceData::StairsDown {
511 entry_door,
512 is_source,
513 } => PersistentStrongholdPieceData::StairsDown {
514 entry_door: Self::stronghold_door_to_persistent(entry_door),
515 is_source,
516 },
517 StrongholdPieceData::FiveCrossing {
518 entry_door,
519 left_low,
520 left_high,
521 right_low,
522 right_high,
523 } => PersistentStrongholdPieceData::FiveCrossing {
524 entry_door: Self::stronghold_door_to_persistent(entry_door),
525 left_low,
526 left_high,
527 right_low,
528 right_high,
529 },
530 StrongholdPieceData::ChestCorridor {
531 entry_door,
532 has_placed_chest,
533 } => PersistentStrongholdPieceData::ChestCorridor {
534 entry_door: Self::stronghold_door_to_persistent(entry_door),
535 has_placed_chest,
536 },
537 StrongholdPieceData::Library {
538 entry_door,
539 is_tall,
540 } => PersistentStrongholdPieceData::Library {
541 entry_door: Self::stronghold_door_to_persistent(entry_door),
542 is_tall,
543 },
544 StrongholdPieceData::PortalRoom { has_placed_spawner } => {
545 PersistentStrongholdPieceData::PortalRoom { has_placed_spawner }
546 }
547 StrongholdPieceData::FillerCorridor { steps } => {
548 PersistentStrongholdPieceData::FillerCorridor { steps }
549 }
550 }
551 }
552
553 const fn persistent_to_stronghold_piece_data(
554 data: &PersistentStrongholdPieceData,
555 ) -> StrongholdPieceData {
556 match data {
557 PersistentStrongholdPieceData::Straight {
558 entry_door,
559 left_child,
560 right_child,
561 } => StrongholdPieceData::Straight {
562 entry_door: Self::persistent_to_stronghold_door(entry_door),
563 left_child: *left_child,
564 right_child: *right_child,
565 },
566 PersistentStrongholdPieceData::PrisonHall { entry_door } => {
567 StrongholdPieceData::PrisonHall {
568 entry_door: Self::persistent_to_stronghold_door(entry_door),
569 }
570 }
571 PersistentStrongholdPieceData::LeftTurn { entry_door } => {
572 StrongholdPieceData::LeftTurn {
573 entry_door: Self::persistent_to_stronghold_door(entry_door),
574 }
575 }
576 PersistentStrongholdPieceData::RightTurn { entry_door } => {
577 StrongholdPieceData::RightTurn {
578 entry_door: Self::persistent_to_stronghold_door(entry_door),
579 }
580 }
581 PersistentStrongholdPieceData::RoomCrossing {
582 entry_door,
583 crossing_type,
584 } => StrongholdPieceData::RoomCrossing {
585 entry_door: Self::persistent_to_stronghold_door(entry_door),
586 crossing_type: *crossing_type,
587 },
588 PersistentStrongholdPieceData::StraightStairsDown { entry_door } => {
589 StrongholdPieceData::StraightStairsDown {
590 entry_door: Self::persistent_to_stronghold_door(entry_door),
591 }
592 }
593 PersistentStrongholdPieceData::StairsDown {
594 entry_door,
595 is_source,
596 } => StrongholdPieceData::StairsDown {
597 entry_door: Self::persistent_to_stronghold_door(entry_door),
598 is_source: *is_source,
599 },
600 PersistentStrongholdPieceData::FiveCrossing {
601 entry_door,
602 left_low,
603 left_high,
604 right_low,
605 right_high,
606 } => StrongholdPieceData::FiveCrossing {
607 entry_door: Self::persistent_to_stronghold_door(entry_door),
608 left_low: *left_low,
609 left_high: *left_high,
610 right_low: *right_low,
611 right_high: *right_high,
612 },
613 PersistentStrongholdPieceData::ChestCorridor {
614 entry_door,
615 has_placed_chest,
616 } => StrongholdPieceData::ChestCorridor {
617 entry_door: Self::persistent_to_stronghold_door(entry_door),
618 has_placed_chest: *has_placed_chest,
619 },
620 PersistentStrongholdPieceData::Library {
621 entry_door,
622 is_tall,
623 } => StrongholdPieceData::Library {
624 entry_door: Self::persistent_to_stronghold_door(entry_door),
625 is_tall: *is_tall,
626 },
627 PersistentStrongholdPieceData::PortalRoom { has_placed_spawner } => {
628 StrongholdPieceData::PortalRoom {
629 has_placed_spawner: *has_placed_spawner,
630 }
631 }
632 PersistentStrongholdPieceData::FillerCorridor { steps } => {
633 StrongholdPieceData::FillerCorridor { steps: *steps }
634 }
635 }
636 }
637
638 pub(super) fn mineshaft_kind_to_persistent(
639 kind: &MineshaftPieceKind,
640 ) -> PersistentMineshaftPieceKind {
641 match kind {
642 MineshaftPieceKind::Room {
643 child_entrance_boxes,
644 } => PersistentMineshaftPieceKind::Room {
645 child_entrance_boxes: child_entrance_boxes
646 .iter()
647 .map(|&b| PersistentBoundingBox::from_bounding_box(b))
648 .collect(),
649 },
650 MineshaftPieceKind::Corridor {
651 has_rails,
652 spider_corridor,
653 has_placed_spider,
654 num_sections,
655 } => PersistentMineshaftPieceKind::Corridor {
656 has_rails: *has_rails,
657 spider_corridor: *spider_corridor,
658 has_placed_spider: *has_placed_spider,
659 num_sections: *num_sections,
660 },
661 MineshaftPieceKind::Crossing {
662 direction,
663 is_two_floored,
664 } => PersistentMineshaftPieceKind::Crossing {
665 direction: direction_to_2d(Some(*direction)),
666 is_two_floored: *is_two_floored,
667 },
668 MineshaftPieceKind::Stairs => PersistentMineshaftPieceKind::Stairs,
669 }
670 }
671
672 pub(super) fn persistent_to_mineshaft_kind(
673 kind: &PersistentMineshaftPieceKind,
674 ) -> MineshaftPieceKind {
675 match kind {
676 PersistentMineshaftPieceKind::Room {
677 child_entrance_boxes,
678 } => MineshaftPieceKind::Room {
679 child_entrance_boxes: child_entrance_boxes
680 .iter()
681 .map(|b| b.to_bounding_box())
682 .collect(),
683 },
684 PersistentMineshaftPieceKind::Corridor {
685 has_rails,
686 spider_corridor,
687 has_placed_spider,
688 num_sections,
689 } => MineshaftPieceKind::Corridor {
690 has_rails: *has_rails,
691 spider_corridor: *spider_corridor,
692 has_placed_spider: *has_placed_spider,
693 num_sections: *num_sections,
694 },
695 PersistentMineshaftPieceKind::Crossing {
696 direction,
697 is_two_floored,
698 } => MineshaftPieceKind::Crossing {
699 direction: required_direction_from_2d(*direction),
700 is_two_floored: *is_two_floored,
701 },
702 PersistentMineshaftPieceKind::Stairs => MineshaftPieceKind::Stairs,
703 }
704 }
705
706 pub(super) fn structure_piece_payload_to_persistent(
707 payload: &StructurePiecePayload,
708 ) -> PersistentStructurePiecePayload {
709 match payload {
710 StructurePiecePayload::Jigsaw(data) => {
711 PersistentStructurePiecePayload::Jigsaw(Self::jigsaw_piece_data_to_persistent(data))
712 }
713 StructurePiecePayload::Template(data) => {
714 PersistentStructurePiecePayload::Template(PersistentTemplatePieceData {
715 template_id: data.template_id.clone(),
716 template_position: [
717 data.template_position.x,
718 data.template_position.y,
719 data.template_position.z,
720 ],
721 rotation: rotation_to_persistent(data.rotation),
722 mirror: mirror_to_persistent(data.mirror),
723 rotation_pivot: [
724 data.rotation_pivot.x,
725 data.rotation_pivot.y,
726 data.rotation_pivot.z,
727 ],
728 block_ignore: block_ignore_to_persistent(data.block_ignore),
729 late_block_ignore: block_ignore_to_persistent(data.late_block_ignore),
730 processors: Self::template_processors_to_persistent(&data.processors),
731 liquid_settings: liquid_settings_to_persistent(data.liquid_settings),
732 marker_handling: marker_handling_to_persistent(data.marker_handling),
733 placement_adjustment: placement_adjustment_to_persistent(
734 data.placement_adjustment,
735 ),
736 placement_clip: placement_clip_to_persistent(data.placement_clip),
737 post_process: post_process_to_persistent(data.post_process),
738 })
739 }
740 StructurePiecePayload::Procedural(data) => PersistentStructurePiecePayload::Procedural(
741 Self::procedural_piece_data_to_persistent(data),
742 ),
743 }
744 }
745
746 pub(super) fn persistent_to_structure_piece_payload(
747 payload: &PersistentStructurePiecePayload,
748 ) -> StructurePiecePayload {
749 match payload {
750 PersistentStructurePiecePayload::Jigsaw(data) => {
751 StructurePiecePayload::Jigsaw(Self::persistent_to_jigsaw_piece_data(data))
752 }
753 PersistentStructurePiecePayload::Template(data) => {
754 StructurePiecePayload::Template(TemplatePieceData {
755 template_id: data.template_id.clone(),
756 template_position: IVec3::new(
757 data.template_position[0],
758 data.template_position[1],
759 data.template_position[2],
760 ),
761 rotation: rotation_from_persistent(data.rotation),
762 mirror: mirror_from_persistent(data.mirror),
763 rotation_pivot: IVec3::new(
764 data.rotation_pivot[0],
765 data.rotation_pivot[1],
766 data.rotation_pivot[2],
767 ),
768 block_ignore: block_ignore_from_persistent(data.block_ignore),
769 late_block_ignore: block_ignore_from_persistent(data.late_block_ignore),
770 processors: Self::persistent_to_template_processors(&data.processors),
771 liquid_settings: liquid_settings_from_persistent(data.liquid_settings),
772 marker_handling: marker_handling_from_persistent(data.marker_handling),
773 placement_adjustment: placement_adjustment_from_persistent(
774 &data.placement_adjustment,
775 ),
776 placement_clip: placement_clip_from_persistent(data.placement_clip),
777 post_process: post_process_from_persistent(data.post_process),
778 })
779 }
780 PersistentStructurePiecePayload::Procedural(data) => {
781 StructurePiecePayload::Procedural(Self::persistent_to_procedural_piece_data(data))
782 }
783 }
784 }
785
786 pub(super) fn pool_element_to_persistent(element: &PoolElement) -> PersistentPoolElement {
787 match element {
788 PoolElement::Single {
789 location,
790 processors,
791 projection,
792 } => PersistentPoolElement::Single {
793 location: location.clone(),
794 processors: Self::processors_to_persistent(processors),
795 projection: projection_to_persistent(Some(*projection)),
796 },
797 PoolElement::LegacySingle {
798 location,
799 processors,
800 projection,
801 } => PersistentPoolElement::LegacySingle {
802 location: location.clone(),
803 processors: Self::processors_to_persistent(processors),
804 projection: projection_to_persistent(Some(*projection)),
805 },
806 PoolElement::Empty => PersistentPoolElement::Empty,
807 PoolElement::Feature {
808 feature,
809 projection,
810 } => PersistentPoolElement::Feature {
811 feature: feature.clone(),
812 projection: projection_to_persistent(Some(*projection)),
813 },
814 PoolElement::List {
815 elements,
816 projection,
817 } => PersistentPoolElement::List {
818 elements: elements
819 .iter()
820 .map(Self::pool_element_to_persistent)
821 .collect(),
822 projection: projection_to_persistent(Some(*projection)),
823 },
824 }
825 }
826
827 pub(super) fn persistent_to_pool_element(element: &PersistentPoolElement) -> PoolElement {
828 match element {
829 PersistentPoolElement::Single {
830 location,
831 processors,
832 projection,
833 } => PoolElement::Single {
834 location: location.clone(),
835 processors: Self::persistent_to_processors(processors),
836 projection: required_projection_from_persistent(*projection),
837 },
838 PersistentPoolElement::LegacySingle {
839 location,
840 processors,
841 projection,
842 } => PoolElement::LegacySingle {
843 location: location.clone(),
844 processors: Self::persistent_to_processors(processors),
845 projection: required_projection_from_persistent(*projection),
846 },
847 PersistentPoolElement::Empty => PoolElement::Empty,
848 PersistentPoolElement::Feature {
849 feature,
850 projection,
851 } => PoolElement::Feature {
852 feature: feature.clone(),
853 projection: required_projection_from_persistent(*projection),
854 },
855 PersistentPoolElement::List {
856 elements,
857 projection,
858 } => PoolElement::List {
859 elements: elements
860 .iter()
861 .map(Self::persistent_to_pool_element)
862 .collect(),
863 projection: required_projection_from_persistent(*projection),
864 },
865 }
866 }
867
868 pub(super) fn processors_to_persistent(processors: &ProcessorList) -> PersistentProcessorList {
869 match processors {
870 ProcessorList::Empty => PersistentProcessorList::Empty,
871 ProcessorList::Registry(id) => PersistentProcessorList::Registry(id.clone()),
872 }
873 }
874
875 pub(super) fn persistent_to_processors(processors: &PersistentProcessorList) -> ProcessorList {
876 match processors {
877 PersistentProcessorList::Empty => ProcessorList::Empty,
878 PersistentProcessorList::Registry(id) => ProcessorList::Registry(id.clone()),
879 }
880 }
881
882 pub(super) fn template_processors_to_persistent(
883 processors: &TemplateProcessorList,
884 ) -> PersistentTemplateProcessorList {
885 match processors {
886 TemplateProcessorList::Empty => PersistentTemplateProcessorList::Empty,
887 TemplateProcessorList::Registry(id) => {
888 PersistentTemplateProcessorList::Registry(id.clone())
889 }
890 TemplateProcessorList::OceanRuin {
891 biome_temp,
892 integrity,
893 } => PersistentTemplateProcessorList::OceanRuin {
894 biome_temp: ocean_ruin_biome_temp_to_persistent(*biome_temp),
895 integrity: *integrity,
896 },
897 TemplateProcessorList::RuinedPortal {
898 vertical_placement,
899 properties,
900 } => PersistentTemplateProcessorList::RuinedPortal {
901 vertical_placement: ruined_portal_placement_to_persistent(*vertical_placement),
902 cold: properties.cold,
903 mossiness: properties.mossiness,
904 air_pocket: properties.air_pocket,
905 overgrown: properties.overgrown,
906 vines: properties.vines,
907 replace_with_blackstone: properties.replace_with_blackstone,
908 },
909 }
910 }
911
912 pub(super) fn persistent_to_template_processors(
913 processors: &PersistentTemplateProcessorList,
914 ) -> TemplateProcessorList {
915 match processors {
916 PersistentTemplateProcessorList::Empty => TemplateProcessorList::Empty,
917 PersistentTemplateProcessorList::Registry(id) => {
918 TemplateProcessorList::Registry(id.clone())
919 }
920 PersistentTemplateProcessorList::OceanRuin {
921 biome_temp,
922 integrity,
923 } => TemplateProcessorList::OceanRuin {
924 biome_temp: ocean_ruin_biome_temp_from_persistent(*biome_temp),
925 integrity: *integrity,
926 },
927 PersistentTemplateProcessorList::RuinedPortal {
928 vertical_placement,
929 cold,
930 mossiness,
931 air_pocket,
932 overgrown,
933 vines,
934 replace_with_blackstone,
935 } => TemplateProcessorList::RuinedPortal {
936 vertical_placement: ruined_portal_placement_from_persistent(*vertical_placement),
937 properties: RuinedPortalProperties {
938 cold: *cold,
939 mossiness: *mossiness,
940 air_pocket: *air_pocket,
941 overgrown: *overgrown,
942 vines: *vines,
943 replace_with_blackstone: *replace_with_blackstone,
944 },
945 },
946 }
947 }
948
949 pub(super) fn structure_starts_to_persistent(
951 starts: &StructureStartMap,
952 ) -> Vec<PersistentStructureStart> {
953 let mut persistent: Vec<_> = starts
954 .values()
955 .filter(|start| !start.pieces.is_empty())
956 .map(|start| PersistentStructureStart {
957 structure: start.structure.clone(),
958 chunk_x: start.chunk_pos.0.x,
959 chunk_z: start.chunk_pos.0.y,
960 references: start.references,
961 pieces: start
962 .pieces
963 .iter()
964 .map(|piece| PersistentStructurePiece {
965 piece_type: piece.piece_type.clone(),
966 bounding_box: PersistentBoundingBox::from_bounding_box(piece.bounding_box),
967 gen_depth: piece.gen_depth,
968 orientation: direction_to_2d(piece.orientation),
969 payload: Self::structure_piece_payload_to_persistent(&piece.payload),
970 ground_level_delta: piece.ground_level_delta,
971 projection: projection_to_persistent(piece.projection),
972 junctions: piece
973 .junctions
974 .iter()
975 .map(|junction| PersistentJigsawJunction {
976 source_x: junction.source_pos.x,
977 source_ground_y: junction.source_pos.y,
978 source_z: junction.source_pos.z,
979 delta_y: junction.delta_y,
980 dest_projection: projection_to_persistent(Some(
981 junction.dest_projection,
982 )),
983 })
984 .collect(),
985 })
986 .collect(),
987 })
988 .collect();
989
990 persistent.sort_by(|a, b| compare_identifiers(&a.structure, &b.structure));
991 persistent
992 }
993
994 pub(super) fn structure_references_to_persistent(
996 refs: &StructureReferenceMap,
997 ) -> Vec<PersistentStructureReference> {
998 let mut persistent: Vec<_> = refs
999 .iter()
1000 .filter(|(_, positions)| !positions.is_empty())
1001 .map(|(structure, positions)| PersistentStructureReference {
1002 structure: structure.clone(),
1003 references: {
1004 let packed: Vec<_> = positions
1005 .insertion_order_iter()
1006 .copied()
1007 .map(PackedChunkPos::from)
1008 .collect();
1009 packed
1010 },
1011 })
1012 .collect();
1013
1014 persistent.sort_by(|a, b| compare_identifiers(&a.structure, &b.structure));
1015 persistent
1016 }
1017
1018 pub(super) fn persistent_to_structure_starts(
1020 persistent: &[PersistentStructureStart],
1021 ) -> StructureStartMap {
1022 persistent
1023 .iter()
1024 .map(|ps| {
1025 let pieces = ps
1026 .pieces
1027 .iter()
1028 .map(|pp| StructurePiece {
1029 piece_type: pp.piece_type.clone(),
1030 bounding_box: pp.bounding_box.to_bounding_box(),
1031 gen_depth: pp.gen_depth,
1032 orientation: direction_from_2d(pp.orientation),
1033 payload: Self::persistent_to_structure_piece_payload(&pp.payload),
1034 ground_level_delta: pp.ground_level_delta,
1035 junctions: pp
1036 .junctions
1037 .iter()
1038 .map(|junction| JigsawJunction {
1039 source_pos: IVec3::new(
1040 junction.source_x,
1041 junction.source_ground_y,
1042 junction.source_z,
1043 ),
1044 delta_y: junction.delta_y,
1045 dest_projection: required_projection_from_persistent(
1046 junction.dest_projection,
1047 ),
1048 })
1049 .collect(),
1050 projection: projection_from_persistent(pp.projection),
1051 })
1052 .collect();
1053
1054 let terrain_adjustment = REGISTRY
1055 .structures
1056 .by_key(&ps.structure)
1057 .map_or(TerrainAdjustment::None, |structure| {
1058 structure.terrain_adjustment
1059 });
1060 let mut start = StructureStart::new(
1061 ps.structure.clone(),
1062 ChunkPos::new(ps.chunk_x, ps.chunk_z),
1063 pieces,
1064 terrain_adjustment,
1065 );
1066 start.references = ps.references;
1067 (ps.structure.clone(), start)
1068 })
1069 .collect()
1070 }
1071
1072 pub(super) fn persistent_to_structure_references(
1074 persistent: &[PersistentStructureReference],
1075 ) -> StructureReferenceMap {
1076 persistent
1077 .iter()
1078 .map(|pr| {
1079 let positions = pr
1080 .references
1081 .iter()
1082 .map(|&packed| packed.to_chunk_pos())
1083 .collect();
1084 (pr.structure.clone(), positions)
1085 })
1086 .collect()
1087 }
1088}