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_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            // TODO: Support one plot being many things?
269            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/// # Syntax
321/// ```ignore
322/// foreach_plot!(expr, plot => plot.something())
323/// ```
324#[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;