1mod adlet;
2mod airship_dock;
3mod barn;
4mod bridge;
5mod camp;
6mod castle;
7mod citadel;
8mod cliff_tower;
9mod cliff_town_airship_dock;
10mod coastal_airship_dock;
11mod coastal_house;
12mod coastal_workshop;
13mod cultist;
14mod desert_city_airship_dock;
15mod desert_city_arena;
16mod desert_city_multiplot;
17mod desert_city_temple;
18mod dwarven_mine;
19mod farm_field;
20mod giant_tree;
21mod glider_finish;
22mod glider_platform;
23mod glider_ring;
24mod gnarling;
25mod haniwa;
26mod house;
27mod jungle_ruin;
28mod myrmidon_arena;
29mod myrmidon_house;
30mod pirate_hideout;
31mod plaza;
32mod road;
33mod rock_circle;
34mod sahagin;
35mod savannah_airship_dock;
36mod savannah_hut;
37mod savannah_workshop;
38mod sea_chapel;
39pub mod tavern;
40mod terracotta_house;
41mod terracotta_palace;
42mod terracotta_yard;
43mod troll_cave;
44mod vampire_castle;
45mod workshop;
46
47pub use self::{
48 adlet::AdletStronghold,
49 airship_dock::AirshipDock,
50 barn::Barn,
51 bridge::Bridge,
52 camp::Camp,
53 castle::Castle,
54 citadel::Citadel,
55 cliff_tower::CliffTower,
56 cliff_town_airship_dock::CliffTownAirshipDock,
57 coastal_airship_dock::CoastalAirshipDock,
58 coastal_house::CoastalHouse,
59 coastal_workshop::CoastalWorkshop,
60 cultist::Cultist,
61 desert_city_airship_dock::DesertCityAirshipDock,
62 desert_city_arena::DesertCityArena,
63 desert_city_multiplot::DesertCityMultiPlot,
64 desert_city_temple::DesertCityTemple,
65 dwarven_mine::DwarvenMine,
66 farm_field::FarmField,
67 giant_tree::GiantTree,
68 glider_finish::GliderFinish,
69 glider_platform::GliderPlatform,
70 glider_ring::GliderRing,
71 gnarling::GnarlingFortification,
72 haniwa::Haniwa,
73 house::House,
74 jungle_ruin::JungleRuin,
75 myrmidon_arena::MyrmidonArena,
76 myrmidon_house::MyrmidonHouse,
77 pirate_hideout::PirateHideout,
78 plaza::Plaza,
79 road::{Road, RoadKind, RoadLights, RoadMaterial},
80 rock_circle::RockCircle,
81 sahagin::Sahagin,
82 savannah_airship_dock::SavannahAirshipDock,
83 savannah_hut::SavannahHut,
84 savannah_workshop::SavannahWorkshop,
85 sea_chapel::SeaChapel,
86 tavern::Tavern,
87 terracotta_house::TerracottaHouse,
88 terracotta_palace::TerracottaPalace,
89 terracotta_yard::TerracottaYard,
90 troll_cave::TrollCave,
91 vampire_castle::VampireCastle,
92 workshop::Workshop,
93};
94
95use super::*;
96use crate::util::DHashSet;
97use common::path::Path;
98use vek::*;
99
100pub struct Plot {
101 pub(crate) kind: PlotKind,
102 pub(crate) root_tile: Vec2<i32>,
103 pub(crate) tiles: DHashSet<Vec2<i32>>,
104}
105
106impl Plot {
107 pub fn find_bounds(&self) -> Aabr<i32> {
108 self.tiles
109 .iter()
110 .fold(Aabr::new_empty(self.root_tile), |b, t| {
111 b.expanded_to_contain_point(*t)
112 })
113 }
114
115 pub fn z_range(&self) -> Option<Range<i32>> {
116 match &self.kind {
117 PlotKind::House(house) => Some(house.z_range()),
118 _ => None,
119 }
120 }
121
122 pub fn kind(&self) -> &PlotKind { &self.kind }
123
124 pub fn meta(&self) -> Option<PlotKindMeta> { self.kind.meta() }
125
126 pub fn root_tile(&self) -> Vec2<i32> { self.root_tile }
127
128 pub fn tiles(&self) -> impl ExactSizeIterator<Item = Vec2<i32>> + '_ {
129 self.tiles.iter().copied()
130 }
131}
132
133#[derive(Debug, Clone)]
134pub enum PlotKindMeta<'plot> {
135 AirshipDock {
136 door_tile: Vec2<i32>,
137 center: Vec2<i32>,
138 docking_positions: &'plot Vec<Vec3<i32>>,
139 },
140 Workshop {
141 door_tile: Option<Vec2<i32>>,
142 },
143 House {
144 door_tile: Vec2<i32>,
145 },
146 Other {
147 door_tile: Vec2<i32>,
148 },
149 Dungeon,
150}
151
152impl PlotKindMeta<'_> {
153 pub fn door_tile(&self) -> Option<Vec2<i32>> {
154 match self {
155 PlotKindMeta::AirshipDock { door_tile, .. }
156 | PlotKindMeta::House { door_tile }
157 | PlotKindMeta::Other { door_tile } => Some(*door_tile),
158 PlotKindMeta::Workshop { door_tile } => *door_tile,
159 PlotKindMeta::Dungeon => None,
160 }
161 }
162}
163
164pub enum PlotKind {
165 House(House),
166 AirshipDock(AirshipDock),
167 GliderRing(GliderRing),
168 GliderPlatform(GliderPlatform),
169 GliderFinish(GliderFinish),
170 Tavern(Tavern),
171 CoastalAirshipDock(CoastalAirshipDock),
172 CoastalHouse(CoastalHouse),
173 CoastalWorkshop(CoastalWorkshop),
174 Workshop(Workshop),
175 DesertCityMultiPlot(DesertCityMultiPlot),
176 DesertCityTemple(DesertCityTemple),
177 DesertCityArena(DesertCityArena),
178 DesertCityAirshipDock(DesertCityAirshipDock),
179 SeaChapel(SeaChapel),
180 JungleRuin(JungleRuin),
181 Plaza(Plaza),
182 Castle(Castle),
183 Cultist(Cultist),
184 Road(Road),
185 Gnarling(GnarlingFortification),
186 Adlet(AdletStronghold),
187 Haniwa(Haniwa),
188 GiantTree(GiantTree),
189 CliffTower(CliffTower),
190 CliffTownAirshipDock(CliffTownAirshipDock),
191 Sahagin(Sahagin),
192 Citadel(Citadel),
193 SavannahAirshipDock(SavannahAirshipDock),
194 SavannahHut(SavannahHut),
195 SavannahWorkshop(SavannahWorkshop),
196 Barn(Barn),
197 Bridge(Bridge),
198 PirateHideout(PirateHideout),
199 RockCircle(RockCircle),
200 TrollCave(TrollCave),
201 Camp(Camp),
202 DwarvenMine(DwarvenMine),
203 TerracottaPalace(TerracottaPalace),
204 TerracottaHouse(TerracottaHouse),
205 TerracottaYard(TerracottaYard),
206 FarmField(FarmField),
207 VampireCastle(VampireCastle),
208 MyrmidonArena(MyrmidonArena),
209 MyrmidonHouse(MyrmidonHouse),
210}
211
212impl PlotKind {
213 pub fn render_ordering(&self) -> u32 {
214 match self {
215 PlotKind::Bridge(_) => 1,
216 PlotKind::Road(_) | PlotKind::Plaza(_) => 2,
217 _ => 0,
218 }
219 }
220
221 pub fn meta(&self) -> Option<PlotKindMeta<'_>> {
222 match self {
223 PlotKind::SavannahAirshipDock(d) => Some(PlotKindMeta::AirshipDock {
224 door_tile: d.door_tile,
225 docking_positions: &d.docking_positions,
226 center: d.center,
227 }),
228 PlotKind::AirshipDock(d) => Some(PlotKindMeta::AirshipDock {
229 door_tile: d.door_tile,
230 docking_positions: &d.docking_positions,
231 center: d.center,
232 }),
233 PlotKind::CoastalAirshipDock(d) => Some(PlotKindMeta::AirshipDock {
234 door_tile: d.door_tile,
235 docking_positions: &d.docking_positions,
236 center: d.center,
237 }),
238 PlotKind::DesertCityAirshipDock(d) => Some(PlotKindMeta::AirshipDock {
239 door_tile: d.door_tile,
240 docking_positions: &d.docking_positions,
241 center: d.center,
242 }),
243 PlotKind::CliffTownAirshipDock(d) => Some(PlotKindMeta::AirshipDock {
244 door_tile: d.door_tile,
245 docking_positions: &d.docking_positions,
246 center: d.center,
247 }),
248 PlotKind::House(h) => Some(PlotKindMeta::House {
249 door_tile: h.door_tile,
250 }),
251 PlotKind::CoastalHouse(h) => Some(PlotKindMeta::House {
252 door_tile: h.door_tile,
253 }),
254 PlotKind::DesertCityTemple(h) => Some(PlotKindMeta::House {
255 door_tile: h.door_tile,
256 }),
257 PlotKind::Sahagin(_) => Some(PlotKindMeta::Dungeon),
258 PlotKind::SavannahHut(h) => Some(PlotKindMeta::House {
259 door_tile: h.door_tile,
260 }),
261 PlotKind::CoastalWorkshop(w) => Some(PlotKindMeta::Workshop {
262 door_tile: Some(w.door_tile),
263 }),
264 PlotKind::Workshop(_) => Some(PlotKindMeta::Workshop { door_tile: None }),
265 PlotKind::SavannahWorkshop(w) => Some(PlotKindMeta::Workshop {
266 door_tile: Some(w.door_tile),
267 }),
268 PlotKind::DesertCityMultiPlot(plot) => match &plot.plot_kind {
270 desert_city_multiplot::PlotKind::MarketHall { .. } => None,
271 desert_city_multiplot::PlotKind::Multiple { subplots } => {
272 subplots.iter().find_map(|p| match &p.0 {
273 desert_city_multiplot::SubPlotKind::WorkshopHouse { .. } => {
274 Some(PlotKindMeta::Workshop { door_tile: None })
275 },
276 desert_city_multiplot::SubPlotKind::Library => None,
277 desert_city_multiplot::SubPlotKind::WatchTower(_) => None,
278 desert_city_multiplot::SubPlotKind::PalmTree => None,
279 desert_city_multiplot::SubPlotKind::AnimalShed => None,
280 })
281 },
282 },
283 PlotKind::Tavern(t) => Some(PlotKindMeta::Other {
284 door_tile: t.door_tile,
285 }),
286 PlotKind::SeaChapel(_) => Some(PlotKindMeta::Dungeon),
287 PlotKind::Cultist(_) => Some(PlotKindMeta::Dungeon),
288 PlotKind::Gnarling(_) => Some(PlotKindMeta::Dungeon),
289 PlotKind::Adlet(_) => Some(PlotKindMeta::Dungeon),
290 PlotKind::Haniwa(_) => Some(PlotKindMeta::Dungeon),
291 PlotKind::DwarvenMine(_) => Some(PlotKindMeta::Dungeon),
292 PlotKind::TerracottaPalace(_) => Some(PlotKindMeta::Dungeon),
293 PlotKind::VampireCastle(_) => Some(PlotKindMeta::Dungeon),
294 PlotKind::MyrmidonArena(_) => Some(PlotKindMeta::Dungeon),
295 PlotKind::GliderRing(_)
296 | PlotKind::GliderPlatform(_)
297 | PlotKind::GliderFinish(_)
298 | PlotKind::JungleRuin(_)
299 | PlotKind::DesertCityArena(_)
300 | PlotKind::Plaza(_)
301 | PlotKind::Castle(_)
302 | PlotKind::Road(_)
303 | PlotKind::GiantTree(_)
304 | PlotKind::CliffTower(_)
305 | PlotKind::Citadel(_)
306 | PlotKind::Barn(_)
307 | PlotKind::Bridge(_)
308 | PlotKind::PirateHideout(_)
309 | PlotKind::RockCircle(_)
310 | PlotKind::TrollCave(_)
311 | PlotKind::Camp(_)
312 | PlotKind::TerracottaHouse(_)
313 | PlotKind::TerracottaYard(_)
314 | PlotKind::FarmField(_)
315 | PlotKind::MyrmidonHouse(_) => None,
316 }
317 }
318}
319
320#[macro_export]
325macro_rules! foreach_plot {
326 ($p:expr, $x:ident => $y:expr $(,)?) => {
327 match $p {
328 PlotKind::House($x) => $y,
329 PlotKind::AirshipDock($x) => $y,
330 PlotKind::CoastalAirshipDock($x) => $y,
331 PlotKind::CoastalHouse($x) => $y,
332 PlotKind::CoastalWorkshop($x) => $y,
333 PlotKind::Workshop($x) => $y,
334 PlotKind::DesertCityAirshipDock($x) => $y,
335 PlotKind::DesertCityMultiPlot($x) => $y,
336 PlotKind::DesertCityTemple($x) => $y,
337 PlotKind::DesertCityArena($x) => $y,
338 PlotKind::SeaChapel($x) => $y,
339 PlotKind::JungleRuin($x) => $y,
340 PlotKind::Plaza($x) => $y,
341 PlotKind::Castle($x) => $y,
342 PlotKind::Road($x) => $y,
343 PlotKind::Gnarling($x) => $y,
344 PlotKind::Adlet($x) => $y,
345 PlotKind::GiantTree($x) => $y,
346 PlotKind::CliffTower($x) => $y,
347 PlotKind::CliffTownAirshipDock($x) => $y,
348 PlotKind::Citadel($x) => $y,
349 PlotKind::SavannahAirshipDock($x) => $y,
350 PlotKind::SavannahHut($x) => $y,
351 PlotKind::SavannahWorkshop($x) => $y,
352 PlotKind::Barn($x) => $y,
353 PlotKind::Bridge($x) => $y,
354 PlotKind::PirateHideout($x) => $y,
355 PlotKind::Tavern($x) => $y,
356 PlotKind::Cultist($x) => $y,
357 PlotKind::Haniwa($x) => $y,
358 PlotKind::Sahagin($x) => $y,
359 PlotKind::RockCircle($x) => $y,
360 PlotKind::TrollCave($x) => $y,
361 PlotKind::Camp($x) => $y,
362 PlotKind::DwarvenMine($x) => $y,
363 PlotKind::TerracottaPalace($x) => $y,
364 PlotKind::TerracottaHouse($x) => $y,
365 PlotKind::TerracottaYard($x) => $y,
366 PlotKind::FarmField($x) => $y,
367 PlotKind::VampireCastle($x) => $y,
368 PlotKind::GliderRing($x) => $y,
369 PlotKind::GliderPlatform($x) => $y,
370 PlotKind::GliderFinish($x) => $y,
371 PlotKind::MyrmidonArena($x) => $y,
372 PlotKind::MyrmidonHouse($x) => $y,
373 }
374 };
375}
376
377pub use foreach_plot;