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}