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