From 30e73735dea737eaa1f8c5dc7ccba14768ece0a7 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 8 May 2022 12:37:29 +0100 Subject: [PATCH] Added SpawnMode to allow for ice and water column spawning of wildlife --- assets/voxygen/shaders/lod-terrain-frag.glsl | 2 +- assets/world/wildlife/spawn/arctic/ocean.ron | 20 +++ .../calendar/christmas/taiga/core_forest.ron | 4 +- .../spawn/calendar/christmas/tundra/core.ron | 4 +- .../calendar/christmas/tundra/forest.ron | 4 +- .../spawn/calendar/christmas/tundra/snow.ron | 4 +- assets/world/wildlife/spawn/desert/area.ron | 2 +- assets/world/wildlife/spawn/desert/hot.ron | 4 +- assets/world/wildlife/spawn/desert/river.ron | 2 +- .../world/wildlife/spawn/desert/wasteland.ron | 2 +- .../wildlife/spawn/jungle/rainforest.ron | 4 +- .../wildlife/spawn/jungle/rainforest_area.ron | 4 +- assets/world/wildlife/spawn/taiga/area.ron | 2 +- assets/world/wildlife/spawn/taiga/core.ron | 2 +- .../wildlife/spawn/taiga/core_forest.ron | 2 +- assets/world/wildlife/spawn/taiga/forest.ron | 2 +- assets/world/wildlife/spawn/taiga/water.ron | 2 +- .../wildlife/spawn/temperate/rainforest.ron | 4 +- .../world/wildlife/spawn/temperate/rare.ron | 2 +- .../world/wildlife/spawn/temperate/river.ron | 2 +- .../world/wildlife/spawn/temperate/water.ron | 2 +- .../world/wildlife/spawn/temperate/wood.ron | 2 +- .../world/wildlife/spawn/tropical/ocean.ron | 2 +- .../wildlife/spawn/tropical/rainforest.ron | 2 +- .../world/wildlife/spawn/tropical/river.ron | 2 +- .../wildlife/spawn/tropical/river_rare.ron | 2 +- assets/world/wildlife/spawn/tropical/rock.ron | 2 +- assets/world/wildlife/spawn/tundra/core.ron | 2 +- assets/world/wildlife/spawn/tundra/forest.ron | 2 +- assets/world/wildlife/spawn/tundra/rock.ron | 2 +- assets/world/wildlife/spawn/tundra/snow.ron | 2 +- world/src/layer/wildlife.rs | 128 ++++++++++-------- 32 files changed, 129 insertions(+), 95 deletions(-) create mode 100644 assets/world/wildlife/spawn/arctic/ocean.ron diff --git a/assets/voxygen/shaders/lod-terrain-frag.glsl b/assets/voxygen/shaders/lod-terrain-frag.glsl index 221671651b..c1b0e74677 100644 --- a/assets/voxygen/shaders/lod-terrain-frag.glsl +++ b/assets/voxygen/shaders/lod-terrain-frag.glsl @@ -342,7 +342,7 @@ void main() { float side_factor = 1.0 - my_norm.z; // min(dot(vec3(0, -sign(cam_dir.y), 0), -cam_dir), dot(vec3(-sign(cam_dir.x), 0, 0), -cam_dir)) if (max(abs(my_norm.x), abs(my_norm.y)) < 0.01 || fract(my_alt) * clamp(dot(normalize(vec3(cam_dir.xy, 0)), side_norm), 0, 1) < cam_dir.z / my_norm.z) { - f_ao *= mix(1.0, clamp(fract(my_alt) / length(my_norm.xy) + clamp(dot(side_norm, -cam_dir), 0, 1), 0, 1), voxelize_factor); + //f_ao *= mix(1.0, clamp(fract(my_alt) / length(my_norm.xy) + clamp(dot(side_norm, -cam_dir), 0, 1), 0, 1), voxelize_factor); voxel_norm = top_norm; } else { f_ao *= mix(1.0, clamp(pow(fract(my_alt), 0.5), 0, 1), voxelize_factor); diff --git a/assets/world/wildlife/spawn/arctic/ocean.ron b/assets/world/wildlife/spawn/arctic/ocean.ron new file mode 100644 index 0000000000..b47d668c8e --- /dev/null +++ b/assets/world/wildlife/spawn/arctic/ocean.ron @@ -0,0 +1,20 @@ +SpawnEntry ( + name: "Arctic ocean water wildlife.", + note: "Arctic ocean inhabitants", + rules: [ + Pack( + groups: [ + (4, (1, 3, "common.entity.wild.aggressive.icepike")), + ], + spawn_mode: Water, + day_period: [Night, Morning, Noon, Evening], + ), + Pack( + groups: [ + (2, (4, 12, "common.entity.wild.peaceful.penguin")), + ], + spawn_mode: Ice, + day_period: [Night, Morning, Noon, Evening], + ), + ], +) diff --git a/assets/world/wildlife/spawn/calendar/christmas/taiga/core_forest.ron b/assets/world/wildlife/spawn/calendar/christmas/taiga/core_forest.ron index 0ef64cad9a..be512b35aa 100644 --- a/assets/world/wildlife/spawn/calendar/christmas/taiga/core_forest.ron +++ b/assets/world/wildlife/spawn/calendar/christmas/taiga/core_forest.ron @@ -8,9 +8,9 @@ SpawnEntry ( (9, (1, 1, "common.entity.wild.aggressive.dreadhorn")), (1, (1, 1, "common.entity.calendar.christmas.aggressive.yeti")), ], - is_underwater: false, + spawn_mode: Land, calendar_events: Some([Christmas]), day_period: [Night, Morning, Noon, Evening], ), ], -) \ No newline at end of file +) diff --git a/assets/world/wildlife/spawn/calendar/christmas/tundra/core.ron b/assets/world/wildlife/spawn/calendar/christmas/tundra/core.ron index f3e5d9f189..9706ece4c2 100644 --- a/assets/world/wildlife/spawn/calendar/christmas/tundra/core.ron +++ b/assets/world/wildlife/spawn/calendar/christmas/tundra/core.ron @@ -10,9 +10,9 @@ SpawnEntry ( (1, (1, 1, "common.entity.wild.aggressive.mountain_troll")), (1, (1, 1, "common.entity.calendar.christmas.aggressive.yeti")), ], - is_underwater: false, + spawn_mode: Land, calendar_events: Some([Christmas]), day_period: [Night, Morning, Noon, Evening], ), ], -) \ No newline at end of file +) diff --git a/assets/world/wildlife/spawn/calendar/christmas/tundra/forest.ron b/assets/world/wildlife/spawn/calendar/christmas/tundra/forest.ron index d924f6d4b2..8364adc41e 100644 --- a/assets/world/wildlife/spawn/calendar/christmas/tundra/forest.ron +++ b/assets/world/wildlife/spawn/calendar/christmas/tundra/forest.ron @@ -10,9 +10,9 @@ SpawnEntry ( (4, (1, 1, "common.entity.wild.aggressive.grolgar")), (1, (1, 1, "common.entity.calendar.christmas.aggressive.yeti")), ], - is_underwater: false, + spawn_mode: Land, calendar_events: Some([Christmas]), day_period: [Night, Morning, Noon, Evening], ), ], -) \ No newline at end of file +) diff --git a/assets/world/wildlife/spawn/calendar/christmas/tundra/snow.ron b/assets/world/wildlife/spawn/calendar/christmas/tundra/snow.ron index 4e873b7b4b..1069cf478a 100644 --- a/assets/world/wildlife/spawn/calendar/christmas/tundra/snow.ron +++ b/assets/world/wildlife/spawn/calendar/christmas/tundra/snow.ron @@ -9,9 +9,9 @@ SpawnEntry ( (6, (1, 3, "common.entity.wild.aggressive.roshwalr")), (1, (1, 1, "common.entity.calendar.christmas.aggressive.yeti")), ], - is_underwater: false, + spawn_mode: Land, calendar_events: Some([Christmas]), day_period: [Night, Morning, Noon, Evening], ), ], -) \ No newline at end of file +) diff --git a/assets/world/wildlife/spawn/desert/area.ron b/assets/world/wildlife/spawn/desert/area.ron index 2c3aca95e5..a176a4c794 100644 --- a/assets/world/wildlife/spawn/desert/area.ron +++ b/assets/world/wildlife/spawn/desert/area.ron @@ -7,7 +7,7 @@ SpawnEntry ( (1, (3, 6, "common.entity.wild.peaceful.zebra")), (1, (3, 6, "common.entity.wild.peaceful.antelope")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/desert/hot.ron b/assets/world/wildlife/spawn/desert/hot.ron index f0b031a76f..b474214731 100644 --- a/assets/world/wildlife/spawn/desert/hot.ron +++ b/assets/world/wildlife/spawn/desert/hot.ron @@ -12,7 +12,7 @@ SpawnEntry ( // Rare (1, (1, 1, "common.entity.wild.peaceful.crawler_sand")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Morning, Noon, Evening], ), Pack( @@ -21,7 +21,7 @@ SpawnEntry ( (1, (1, 1, "common.entity.wild.peaceful.porcupine")), (1, (1, 1, "common.entity.wild.peaceful.pangolin")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night], ), ], diff --git a/assets/world/wildlife/spawn/desert/river.ron b/assets/world/wildlife/spawn/desert/river.ron index a032786de7..a0e07abeb2 100644 --- a/assets/world/wildlife/spawn/desert/river.ron +++ b/assets/world/wildlife/spawn/desert/river.ron @@ -6,7 +6,7 @@ SpawnEntry ( groups: [ (1, (1, 1, "common.entity.wild.aggressive.crocodile")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/desert/wasteland.ron b/assets/world/wildlife/spawn/desert/wasteland.ron index 40ff714ac6..427f7cc3cd 100644 --- a/assets/world/wildlife/spawn/desert/wasteland.ron +++ b/assets/world/wildlife/spawn/desert/wasteland.ron @@ -18,7 +18,7 @@ SpawnEntry ( // Ultra_rare (1, (1, 1, "common.entity.wild.aggressive.roshwalr_boss")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/jungle/rainforest.ron b/assets/world/wildlife/spawn/jungle/rainforest.ron index 45f70e6dfc..6e21e62331 100644 --- a/assets/world/wildlife/spawn/jungle/rainforest.ron +++ b/assets/world/wildlife/spawn/jungle/rainforest.ron @@ -15,7 +15,7 @@ SpawnEntry ( (1, (1, 1, "common.entity.wild.aggressive.occult_saurok")), (1, (1, 1, "common.entity.wild.aggressive.sly_saurok")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Morning, Noon, Evening], ), Pack( @@ -24,7 +24,7 @@ SpawnEntry ( (1, (1, 1, "common.entity.wild.aggressive.maneater")), (1, (1, 1, "common.entity.wild.aggressive.cockatrice")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night], ), ], diff --git a/assets/world/wildlife/spawn/jungle/rainforest_area.ron b/assets/world/wildlife/spawn/jungle/rainforest_area.ron index e335f734fd..f939269428 100644 --- a/assets/world/wildlife/spawn/jungle/rainforest_area.ron +++ b/assets/world/wildlife/spawn/jungle/rainforest_area.ron @@ -14,7 +14,7 @@ SpawnEntry ( (1, (1, 1, "common.entity.wild.aggressive.stag_beetle")), (1, (1, 1, "common.entity.wild.peaceful.crawler_moss")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Morning, Noon, Evening], ), Pack( @@ -22,7 +22,7 @@ SpawnEntry ( (5, (1, 1, "common.entity.wild.peaceful.quokka")), (1, (1, 1, "common.entity.wild.peaceful.tortoise")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night], ), ], diff --git a/assets/world/wildlife/spawn/taiga/area.ron b/assets/world/wildlife/spawn/taiga/area.ron index e9400a0988..d0af2a01d4 100644 --- a/assets/world/wildlife/spawn/taiga/area.ron +++ b/assets/world/wildlife/spawn/taiga/area.ron @@ -11,7 +11,7 @@ SpawnEntry ( (1, (1, 1, "common.entity.wild.peaceful.arctic_hare")), (1, (1, 1, "common.entity.wild.peaceful.tuskram")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/taiga/core.ron b/assets/world/wildlife/spawn/taiga/core.ron index 1604fa4171..53ea62b7d5 100644 --- a/assets/world/wildlife/spawn/taiga/core.ron +++ b/assets/world/wildlife/spawn/taiga/core.ron @@ -10,7 +10,7 @@ SpawnEntry ( (1, (1, 3, "common.entity.wild.peaceful.alpaca")), (1, (1, 3, "common.entity.wild.peaceful.highland")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/taiga/core_forest.ron b/assets/world/wildlife/spawn/taiga/core_forest.ron index 673d1579dc..8bed92578b 100644 --- a/assets/world/wildlife/spawn/taiga/core_forest.ron +++ b/assets/world/wildlife/spawn/taiga/core_forest.ron @@ -7,7 +7,7 @@ SpawnEntry ( (1, (1, 1, "common.entity.wild.aggressive.wendigo")), (1, (1, 1, "common.entity.wild.aggressive.dreadhorn")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/taiga/forest.ron b/assets/world/wildlife/spawn/taiga/forest.ron index a6731694e2..525567aef7 100644 --- a/assets/world/wildlife/spawn/taiga/forest.ron +++ b/assets/world/wildlife/spawn/taiga/forest.ron @@ -6,7 +6,7 @@ SpawnEntry ( groups: [ (1, (3, 7, "common.entity.wild.aggressive.wolf")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/taiga/water.ron b/assets/world/wildlife/spawn/taiga/water.ron index 8ad83b0baa..309145dfa6 100644 --- a/assets/world/wildlife/spawn/taiga/water.ron +++ b/assets/world/wildlife/spawn/taiga/water.ron @@ -6,7 +6,7 @@ SpawnEntry ( groups: [ (1, (1, 2, "common.entity.wild.aggressive.icepike")), ], - is_underwater: true, + spawn_mode: Water, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/temperate/rainforest.ron b/assets/world/wildlife/spawn/temperate/rainforest.ron index 9f29254041..2e441dc34e 100644 --- a/assets/world/wildlife/spawn/temperate/rainforest.ron +++ b/assets/world/wildlife/spawn/temperate/rainforest.ron @@ -33,7 +33,7 @@ SpawnEntry ( (2, (1, 1, "common.entity.wild.peaceful.leaf_beetle")), (2, (1, 1, "common.entity.wild.aggressive.weevil")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Morning, Noon, Evening], ), Pack( @@ -46,7 +46,7 @@ SpawnEntry ( (5, (1, 3, "common.entity.wild.peaceful.rat")), (5, (1, 3, "common.entity.wild.peaceful.squirrel")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night], ), ], diff --git a/assets/world/wildlife/spawn/temperate/rare.ron b/assets/world/wildlife/spawn/temperate/rare.ron index 00e53c1ac3..e1bd3da4ed 100644 --- a/assets/world/wildlife/spawn/temperate/rare.ron +++ b/assets/world/wildlife/spawn/temperate/rare.ron @@ -8,7 +8,7 @@ SpawnEntry ( (1, (1, 1, "common.entity.wild.aggressive.swamp_troll")), (1, (1, 1, "common.entity.wild.aggressive.cyclops")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/temperate/river.ron b/assets/world/wildlife/spawn/temperate/river.ron index e8a7a4a146..0f5b8a382c 100644 --- a/assets/world/wildlife/spawn/temperate/river.ron +++ b/assets/world/wildlife/spawn/temperate/river.ron @@ -10,7 +10,7 @@ SpawnEntry ( (1, (1, 1, "common.entity.wild.peaceful.kelpie")), (1, (1, 1, "common.entity.wild.aggressive.hakulaq")), ], - is_underwater: false, + spawn_mode: Water, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/temperate/water.ron b/assets/world/wildlife/spawn/temperate/water.ron index 9906d3fa64..43c07ae278 100644 --- a/assets/world/wildlife/spawn/temperate/water.ron +++ b/assets/world/wildlife/spawn/temperate/water.ron @@ -8,7 +8,7 @@ SpawnEntry ( (1, (3, 4, "common.entity.wild.peaceful.piranha")), (1, (3, 4, "common.entity.wild.peaceful.clownfish")), ], - is_underwater: true, + spawn_mode: Water, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/temperate/wood.ron b/assets/world/wildlife/spawn/temperate/wood.ron index 2ae2419103..389619727f 100644 --- a/assets/world/wildlife/spawn/temperate/wood.ron +++ b/assets/world/wildlife/spawn/temperate/wood.ron @@ -12,7 +12,7 @@ SpawnEntry ( (1, (1, 1, "common.entity.wild.aggressive.weevil")), (1, (1, 1, "common.entity.wild.peaceful.leaf_beetle")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/tropical/ocean.ron b/assets/world/wildlife/spawn/tropical/ocean.ron index f9bbf49434..16ad227e4e 100644 --- a/assets/world/wildlife/spawn/tropical/ocean.ron +++ b/assets/world/wildlife/spawn/tropical/ocean.ron @@ -6,7 +6,7 @@ SpawnEntry ( groups: [ (1, (1, 3, "common.entity.wild.aggressive.sea_crocodile")), ], - is_underwater: true, + spawn_mode: Water, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/tropical/rainforest.ron b/assets/world/wildlife/spawn/tropical/rainforest.ron index 4bdabd1625..7ab5c6dda1 100644 --- a/assets/world/wildlife/spawn/tropical/rainforest.ron +++ b/assets/world/wildlife/spawn/tropical/rainforest.ron @@ -7,7 +7,7 @@ SpawnEntry ( (1, (1, 2, "common.entity.wild.aggressive.male_lion")), (1, (1, 3, "common.entity.wild.aggressive.hyena")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/tropical/river.ron b/assets/world/wildlife/spawn/tropical/river.ron index c26932d6ac..36f0cf3e5b 100644 --- a/assets/world/wildlife/spawn/tropical/river.ron +++ b/assets/world/wildlife/spawn/tropical/river.ron @@ -8,7 +8,7 @@ SpawnEntry ( (1, (1, 2, "common.entity.wild.peaceful.axolotl")), (1, (1, 2, "common.entity.wild.peaceful.fungome")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/tropical/river_rare.ron b/assets/world/wildlife/spawn/tropical/river_rare.ron index efdc77a4f7..758476a0fd 100644 --- a/assets/world/wildlife/spawn/tropical/river_rare.ron +++ b/assets/world/wildlife/spawn/tropical/river_rare.ron @@ -6,7 +6,7 @@ SpawnEntry ( groups: [ (1, (1, 2, "common.entity.wild.aggressive.alligator")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/tropical/rock.ron b/assets/world/wildlife/spawn/tropical/rock.ron index 6a54b8b5a3..1a5c848147 100644 --- a/assets/world/wildlife/spawn/tropical/rock.ron +++ b/assets/world/wildlife/spawn/tropical/rock.ron @@ -6,7 +6,7 @@ SpawnEntry ( groups: [ (1, (1, 1, "common.entity.wild.aggressive.dodarock")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/tundra/core.ron b/assets/world/wildlife/spawn/tundra/core.ron index 12315b9318..5c7cebec47 100644 --- a/assets/world/wildlife/spawn/tundra/core.ron +++ b/assets/world/wildlife/spawn/tundra/core.ron @@ -9,7 +9,7 @@ SpawnEntry ( (1, (1, 1, "common.entity.wild.aggressive.mammoth")), (1, (1, 1, "common.entity.wild.aggressive.mountain_troll")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/tundra/forest.ron b/assets/world/wildlife/spawn/tundra/forest.ron index eb652f8e42..10fcb73c10 100644 --- a/assets/world/wildlife/spawn/tundra/forest.ron +++ b/assets/world/wildlife/spawn/tundra/forest.ron @@ -9,7 +9,7 @@ SpawnEntry ( (1, (1, 1, "common.entity.wild.aggressive.yale")), (1, (1, 1, "common.entity.wild.aggressive.grolgar")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/tundra/rock.ron b/assets/world/wildlife/spawn/tundra/rock.ron index 79353d8f0d..f723581e55 100644 --- a/assets/world/wildlife/spawn/tundra/rock.ron +++ b/assets/world/wildlife/spawn/tundra/rock.ron @@ -6,7 +6,7 @@ SpawnEntry ( groups: [ (1, (1, 1, "common.entity.wild.aggressive.rocksnapper")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/assets/world/wildlife/spawn/tundra/snow.ron b/assets/world/wildlife/spawn/tundra/snow.ron index cfeb9a8987..bc14011061 100644 --- a/assets/world/wildlife/spawn/tundra/snow.ron +++ b/assets/world/wildlife/spawn/tundra/snow.ron @@ -11,7 +11,7 @@ SpawnEntry ( (1, (1, 3, "common.entity.wild.aggressive.roshwalr")), (5, (5, 20, "common.entity.wild.peaceful.penguin")), ], - is_underwater: false, + spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], ), ], diff --git a/world/src/layer/wildlife.rs b/world/src/layer/wildlife.rs index 58307485ff..1e8af5aadf 100644 --- a/world/src/layer/wildlife.rs +++ b/world/src/layer/wildlife.rs @@ -43,7 +43,8 @@ impl SpawnEntry { &self, requested_period: DayPeriod, calendar: Option<&Calendar>, - underwater: bool, + is_underwater: bool, + is_ice: bool, ) -> Option { self.rules .iter() @@ -59,8 +60,13 @@ impl SpawnEntry { } else { false }; - let water_match = pack.is_underwater == underwater; - time_match && calendar_match && water_match + let mode_match = match pack.spawn_mode { + SpawnMode::Land => !is_underwater, + SpawnMode::Ice => is_ice, + SpawnMode::Water | SpawnMode::Underwater => is_underwater, + SpawnMode::Air(_) => true, + }; + time_match && calendar_match && mode_match }) .cloned() } @@ -77,7 +83,7 @@ impl SpawnEntry { /// (1, (1, 1, "common.entity.wild.aggressive.yale")), /// (1, (1, 1, "common.entity.wild.aggressive.grolgar")), /// ], -/// is_underwater: false, +/// spawn_mode: Land, /// day_period: [Night, Morning, Noon, Evening], /// ), /// ``` @@ -95,9 +101,13 @@ impl SpawnEntry { /// to `assets/common/entity/wild/aggressive/frostfang.ron` file with /// EntityConfig /// -/// Underwater: -/// `is_underwater: false` means mobs from this pack can't be spawned underwater -/// in rivers, lakes or ocean +/// Spawn mode: +/// `spawn_mode: Land` means mobs spawn on land at the surface (i.e: cows) +/// `spawn_mode: means mobs spawn on the surface of water ice +/// `spawn_mode: Water` means mobs spawn *in* water at a random depth (i.e: +/// fish) `spawn_mode: Underwater` means mobs spawn at the bottom of a body of +/// water (i.e: crabs) `spawn_mode: Air(32)` means mobs spawn in the air above +/// either land or water, with a maximum altitude of 32 /// /// Day period: /// `day_period: [Night, Morning, Noon, Evening]` @@ -106,13 +116,22 @@ impl SpawnEntry { #[derive(Clone, Debug, Deserialize)] pub struct Pack { pub groups: Vec<(Weight, (Min, Max, String))>, - pub is_underwater: bool, + pub spawn_mode: SpawnMode, pub day_period: Vec, #[serde(default)] pub calendar_events: Option>, /* None implies that the group isn't * limited by calendar events */ } +#[derive(Copy, Clone, Debug, Deserialize)] +pub enum SpawnMode { + Land, + Ice, + Water, + Underwater, + Air(f32), +} + impl Pack { pub fn generate(&self, pos: Vec3, dynamic_rng: &mut impl Rng) -> (EntityInfo, u8) { let (_, (from, to, entity_asset)) = self @@ -273,6 +292,15 @@ pub fn spawn_manifest() -> Vec<(&'static str, DensityFn)> { 0.0 } }), + // Arctic ocean animals + ("world.wildlife.spawn.arctic.ocean", |_c, col| { + close(col.temp, 0.0, 0.25) / 10.0 + * if matches!(col.chunk.get_biome(), BiomeKind::Ocean) { + 0.001 + } else { + 0.0 + } + }), // Rainforest area animals ("world.wildlife.spawn.tropical.rainforest", |c, _col| { close(c.temp, CONFIG.tropical_temp + 0.1, 0.4) @@ -343,7 +371,8 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( continue; }; - let underwater = col_sample.water_level > col_sample.alt; + let is_underwater = col_sample.water_level > col_sample.alt; + let is_ice = col_sample.ice_depth > 0.5 && is_underwater; let (current_day_period, calendar) = if let Some((time, calendar)) = time { (DayPeriod::from(time.0), Some(calendar)) } else { @@ -353,13 +382,13 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( let entity_group = scatter .iter() .enumerate() - .find_map(|(_i, (entry, get_density))| { + .filter_map(|(_i, (entry, get_density))| { let density = get_density(chunk, col_sample) * wildlife_density_modifier; (density > 0.0) .then(|| { entry .read() - .request(current_day_period, calendar, underwater) + .request(current_day_period, calendar, is_underwater, is_ice) .and_then(|pack| { (dynamic_rng.gen::() < density * col_sample.spawn_rate && col_sample.gradient < Some(1.3)) @@ -367,13 +396,26 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) }) .flatten() - }); - - let alt = col_sample.alt as i32; + }) + .collect::>() // TODO: Don't allocate + .choose(dynamic_rng) + .cloned(); if let Some(pack) = entity_group { + let desired_alt = match pack.spawn_mode { + SpawnMode::Land | SpawnMode::Underwater => col_sample.alt, + SpawnMode::Ice => col_sample.water_level + 1.0 + col_sample.ice_depth, + SpawnMode::Water => dynamic_rng.gen_range( + col_sample.alt..col_sample.water_level.max(col_sample.alt + 0.1), + ), + SpawnMode::Air(height) => { + col_sample.alt.max(col_sample.water_level) + + dynamic_rng.gen::() * height + }, + }; + let (entity, group_size) = pack.generate( - (wpos2d.map(|e| e as f32) + 0.5).with_z(alt as f32), + (wpos2d.map(|e| e as f32) + 0.5).with_z(desired_alt), dynamic_rng, ); for e in 0..group_size { @@ -390,15 +432,22 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( // Find the intersection between ground and air, if there is one near the // surface - if let Some(solid_end) = (-8..8).find(|z| { - (0..2).all(|z2| { - vol.get(Vec3::new(offs.x, offs.y, alt) + offs_wpos2d.with_z(z + z2)) + let z_offset = (0..16) + .map(|z| if z % 2 == 0 { z } else { -z } / 2) + .find(|z| { + (0..2).all(|z2| { + vol.get( + Vec3::new(offs.x, offs.y, desired_alt as i32) + + offs_wpos2d.with_z(z + z2), + ) .map(|b| !b.is_solid()) .unwrap_or(true) - }) - }) { + }) + }); + + if let Some(z_offset) = z_offset { let mut entity = entity.clone(); - entity.pos += offs_wpos2d.with_z(solid_end).map(|e| e as f32); + entity.pos += offs_wpos2d.with_z(z_offset).map(|e| e as f32); supplement.add_entity(entity); } } @@ -410,7 +459,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( #[cfg(test)] mod tests { use super::*; - use hashbrown::{HashMap, HashSet}; + use hashbrown::HashMap; // Checks that each entry in spawn manifest is loadable #[test] @@ -434,41 +483,6 @@ mod tests { } } - // Checks that day_period aren't overlapping - // Quite strict rule, but otherwise may produce unexpected behaviour - #[test] - fn test_check_day_periods() { - let scatter = spawn_manifest(); - for (entry, _) in scatter.into_iter() { - let mut day_periods = HashSet::with_capacity(4); - let SpawnEntry { rules, .. } = SpawnEntry::from(entry); - for pack in rules { - let Pack { - day_period, - is_underwater, - .. - } = pack; - for period in day_period { - if !day_periods.insert((period, is_underwater)) { - panic!( - r#" - == {}: == - Found rules with duplicated `day_period` and `is_underwater` - If you have two of such entries, - there are big chances that second rule will be unreachable. - - If you want some animals spawned in different Packs - with same day_period, add those animals to both Packs - and choose day_period to not overlap. -"#, - entry - ) - } - } - } - } - } - // Checks that each entity is loadable #[test] fn test_load_entities() {