veloren_world/site/plot/
mod.rs

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            // TODO: Support one plot being many things?
273            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/// # Syntax
325/// ```ignore
326/// foreach_plot!(expr, plot => plot.something())
327/// ```
328#[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;