veloren_common/
spot.rs

1use common_assets::{AssetCombined, AssetHandle, Ron};
2use lazy_static::lazy_static;
3
4use crate::terrain::BiomeKind;
5use strum::EnumIter;
6
7/// Spots are localised structures that spawn in the world. Conceptually, they
8/// fit somewhere between the tree generator and the site generator: an attempt
9/// to marry the simplicity of the former with the capability of the latter.
10/// They are not globally visible to the game: this means that they do not
11/// appear on the map, and cannot interact with rtsim (much).
12///
13/// To add a new spot, one must:
14///
15/// 1. Add a new variant to the [`Spot`] enum.
16/// 2. Add a new entry to [`veloren-world::layer::spot::SpotGenerate::generate`]
17///    that tells the system where to generate your new spot.
18/// 3. Add a new arm to the `match` expression in
19///    [`veloren-world::layer::spot::apply_spots_to`] that tells the generator
20///    how to generate a spot, including the base structure that composes the
21///    spot and the entities that should be spawned there.
22///
23/// Only add spots with randomly spawned NPCs here. Spots that only use
24/// EntitySpawner blocks can be added in assets/world/manifests/spots.ron
25#[derive(Copy, Clone, Debug, EnumIter, PartialEq)]
26pub enum Spot {
27    DwarvenGrave,
28    SaurokAltar,
29    MyrmidonTemple,
30    GnarlingTotem,
31    WitchHouse,
32    GnomeSpring,
33    WolfBurrow,
34    Igloo,
35    //BanditCamp,
36    //EnchantedRock,
37    //TowerRuin,
38    //WellOfLight,
39    //MerchantOutpost,
40    //RuinedHuntingCabin, <-- Bears!
41    // *Random world objects*
42    LionRock,
43    TreeStumpForest,
44    DesertBones,
45    Arch,
46    AirshipCrash,
47    FruitTree,
48    Shipwreck,
49    Shipwreck2,
50    FallenTree,
51    GraveSmall,
52    JungleTemple,
53    SaurokTotem,
54    JungleOutpost,
55    #[strum(disabled)]
56    RonFile(&'static SpotProperties),
57}
58
59#[derive(serde::Deserialize, Clone, Debug, PartialEq)]
60pub enum SpotCondition {
61    MaxGradient(f32),
62    Biome(Vec<BiomeKind>),
63    NearCliffs,
64    NearRiver,
65    IsWay,
66    IsUnderwater,
67
68    /// no cliffs, no river, no way
69    Typical,
70    /// implies IsUnderwater
71    MinWaterDepth(f32),
72
73    Not(Box<SpotCondition>),
74    All(Vec<SpotCondition>),
75    Any(Vec<SpotCondition>),
76}
77
78#[derive(serde::Deserialize, Clone, Debug, PartialEq)]
79pub struct SpotProperties {
80    pub base_structures: String,
81    pub freq: f32,
82    pub condition: SpotCondition,
83    pub spawn: bool,
84}
85
86pub type RonSpots = Ron<Vec<SpotProperties>>;
87
88lazy_static! {
89    pub static ref RON_SPOT_PROPERTIES: RonSpots = {
90        let spots: AssetHandle<RonSpots> =
91            RonSpots::load_expect_combined_static("world.manifests.spots");
92        Ron(spots.read().0.to_vec())
93    };
94}