From febe79e60237d6922a86fa6394ea44a3bbb40a79 Mon Sep 17 00:00:00 2001 From: Snowram Date: Wed, 14 Oct 2020 23:02:48 +0200 Subject: [PATCH] Added remaining creature spawns --- server/src/lib.rs | 4 +- server/src/state_ext.rs | 16 +- world/src/layer/wildlife.rs | 375 +++++++++++++++++++++++++++++++++--- 3 files changed, 364 insertions(+), 31 deletions(-) diff --git a/server/src/lib.rs b/server/src/lib.rs index caef411514..81a949f9ba 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -532,7 +532,9 @@ impl Server { // despawning if the entity walks outside of a valid chunk // briefly. If the entity isn't even near a loaded chunk then we get // rid of it. - Spiral2d::new().take(9).all(|offs| terrain.get_key(chunk_key + offs).is_none()) + Spiral2d::new() + .take(9) + .all(|offs| terrain.get_key(chunk_key + offs).is_none()) }) .map(|(entity, _, _)| entity) .collect::>() diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index ee7e52dc69..b3dc3ead64 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -11,13 +11,13 @@ use common::{ sync::{Uid, UidAllocator, WorldSyncExt}, util::Dir, }; +use rand::prelude::*; use specs::{ saveload::MarkerAllocator, Builder, Entity as EcsEntity, EntityBuilder as EcsEntityBuilder, Join, WorldExt, }; use tracing::warn; use vek::*; -use rand::prelude::*; pub trait StateExt { /// Updates a component associated with the entity based on the `Effect` @@ -122,11 +122,15 @@ impl StateExt for State { .create_entity_synced() .with(pos) .with(comp::Vel(Vec3::zero())) - .with(comp::Ori(Dir::new(Vec3::new( - thread_rng().gen_range(-1.0, 1.0), - thread_rng().gen_range(-1.0, 1.0), - 0.0, - ).try_normalized().unwrap_or_default()))) + .with(comp::Ori(Dir::new( + Vec3::new( + thread_rng().gen_range(-1.0, 1.0), + thread_rng().gen_range(-1.0, 1.0), + 0.0, + ) + .try_normalized() + .unwrap_or_default(), + ))) .with(comp::Collider::Box { radius: body.radius(), z_min: 0.0, diff --git a/world/src/layer/wildlife.rs b/world/src/layer/wildlife.rs index ad20178fec..e16670ff1f 100644 --- a/world/src/layer/wildlife.rs +++ b/world/src/layer/wildlife.rs @@ -1,6 +1,6 @@ use crate::{column::ColumnSample, sim::SimChunk, util::RandomField, IndexRef, CONFIG}; use common::{ - comp::{quadruped_low, quadruped_medium, quadruped_small, Alignment}, + comp::{biped_large, bird_medium, quadruped_low, quadruped_medium, quadruped_small, Alignment}, generation::{ChunkSupplement, EntityInfo}, terrain::{Block, SpriteKind}, vol::{BaseVol, ReadVol, RectSizedVol, WriteVol}, @@ -33,7 +33,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( bool, // Underwater? fn(&SimChunk, &ColumnSample) -> f32, // Density )] = &[ - // Wolves + // Taiga pack ennemies ( |pos, rng| { EntityInfo::at(pos) @@ -45,43 +45,104 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }, 3..8, false, - |c, col| close(c.temp, CONFIG.snow_temp, 0.7) * col.tree_density * BASE_DENSITY * 0.3, + |c, col| { + close(c.temp, CONFIG.snow_temp + 0.2, 0.7) * col.tree_density * BASE_DENSITY * 0.05 + }, ), - // Frostfang + // Taiga pack wild ( |pos, rng| { EntityInfo::at(pos) .with_body( quadruped_medium::Body::random_with( + rng, + &quadruped_medium::Species::Mouflon, + ) + .into(), + ) + .with_alignment(Alignment::Wild) + }, + 1..4, + false, + |c, col| close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * BASE_DENSITY * 0.1, + ), + // Taiga solitary wild + ( + |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 4) { + 0 => { + bird_medium::Body::random_with(rng, &bird_medium::Species::Eagle).into() + }, + 1 => quadruped_low::Body::random_with(rng, &quadruped_low::Species::Asp) + .into(), + 2 => bird_medium::Body::random_with(rng, &bird_medium::Species::Snowyowl) + .into(), + _ => quadruped_medium::Body::random_with( + rng, + &quadruped_medium::Species::Tuskram, + ) + .into(), + }) + .with_alignment(Alignment::Enemy) + }, + 1..2, + false, + |c, col| close(c.temp, CONFIG.snow_temp + 0.2, 0.7) * BASE_DENSITY * 0.3, + ), + // Tundra pack ennemies + ( + |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 2) { + 0 => quadruped_medium::Body::random_with( rng, &quadruped_medium::Species::Frostfang, ) .into(), - ) + _ => quadruped_medium::Body::random_with( + rng, + &quadruped_medium::Species::Grolgar, + ) + .into(), + }) .with_alignment(Alignment::Enemy) }, 1..4, false, - |c, col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.15, + |c, col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.2, ), - // Bonerattler + // Tundra solitary ennemies + ( + |pos, rng| { + EntityInfo::at(pos) + .with_body( + biped_large::Body::random_with(rng, &biped_large::Species::Wendigo).into(), + ) + .with_alignment(Alignment::Enemy) + }, + 1..2, + false, + |c, col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.1, + ), + // Tundra solitary wild ( |pos, rng| { EntityInfo::at(pos) .with_body( quadruped_medium::Body::random_with( rng, - &quadruped_medium::Species::Bonerattler, + &quadruped_medium::Species::Tarasque, ) .into(), ) - .with_alignment(Alignment::Enemy) + .with_alignment(Alignment::Wild) }, - 1..3, + 1..2, false, - |c, col| close(c.humidity, CONFIG.desert_hum, 0.3) * BASE_DENSITY * 0.5, + |c, col| close(c.temp, CONFIG.temperate_temp, 0.15) * BASE_DENSITY * 0.1, ), - // Forest herd (Deer, Hirdrasil, etc.) + // Forest pack wild ( |pos, rng| { EntityInfo::at(pos) @@ -91,11 +152,10 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( &quadruped_medium::Species::Deer, ) .into(), - 1 => quadruped_medium::Body::random_with( - rng, - &quadruped_medium::Species::Hirdrasil, - ) - .into(), + 1 => { + quadruped_small::Body::random_with(rng, &quadruped_small::Species::Rat) + .into() + }, 2 => quadruped_small::Body::random_with( rng, &quadruped_small::Species::Rabbit, @@ -129,21 +189,108 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( &quadruped_small::Species::Squirrel, ) .into(), - _ => quadruped_small::Body::random_with( + _ => bird_medium::Body::random_with(rng, &bird_medium::Species::Chicken) + .into(), + }) + .with_alignment(Alignment::Wild) + }, + 1..8, + false, + |c, col| { + close(c.temp, CONFIG.temperate_temp, 0.7) * col.tree_density * BASE_DENSITY * 6.0 + }, + ), + // Temperate solitary wild + ( + |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 12) { + 0 => { + quadruped_small::Body::random_with(rng, &quadruped_small::Species::Fox) + .into() + }, + 1 => quadruped_small::Body::random_with( + rng, + &quadruped_small::Species::Quokka, + ) + .into(), + 2 => { + bird_medium::Body::random_with(rng, &bird_medium::Species::Goose).into() + }, + 3 => bird_medium::Body::random_with(rng, &bird_medium::Species::Peacock) + .into(), + 4 => quadruped_small::Body::random_with( rng, &quadruped_small::Species::Porcupine, ) .into(), + 5 => quadruped_small::Body::random_with( + rng, + &quadruped_small::Species::Skunk, + ) + .into(), + 6 => quadruped_small::Body::random_with( + rng, + &quadruped_small::Species::Raccoon, + ) + .into(), + 7 => bird_medium::Body::random_with(rng, &bird_medium::Species::Cockatrice) + .into(), + 8 => quadruped_medium::Body::random_with( + rng, + &quadruped_medium::Species::Catoblepas, + ) + .into(), + 9 => quadruped_small::Body::random_with( + rng, + &quadruped_small::Species::Turtle, + ) + .into(), + 10 => quadruped_medium::Body::random_with( + rng, + &quadruped_medium::Species::Hirdrasil, + ) + .into(), + _ => quadruped_small::Body::random_with( + rng, + &quadruped_small::Species::Batfox, + ) + .into(), }) .with_alignment(Alignment::Wild) }, - 3..8, + 1..2, false, - |c, col| { - close(c.temp, CONFIG.temperate_temp, 0.7) * col.tree_density * BASE_DENSITY * 1.5 - }, + |c, col| close(c.temp, CONFIG.temperate_temp, 0.15) * BASE_DENSITY * 10.0, ), - // Amphibians (Frog, Axolotl, Crocodile, etc.) + // Rare temperate solitary enemies + ( + |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 12) { + 0 => { + biped_large::Body::random_with(rng, &biped_large::Species::Ogre).into() + }, + 1 => { + biped_large::Body::random_with(rng, &biped_large::Species::Troll).into() + }, + 2 => biped_large::Body::random_with(rng, &biped_large::Species::Dullahan) + .into(), + 3 => biped_large::Body::random_with(rng, &biped_large::Species::Cyclops) + .into(), + _ => quadruped_small::Body::random_with( + rng, + &quadruped_small::Species::Batfox, + ) + .into(), + }) + .with_alignment(Alignment::Wild) + }, + 1..2, + false, + |c, col| close(c.temp, CONFIG.temperate_temp, 0.8) * BASE_DENSITY * 0.3, + ), + // Temperate rare river wildlife ( |pos, rng| { EntityInfo::at(pos) @@ -184,7 +331,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( 1..3, false, |c, col| { - close(col.temp, CONFIG.tropical_temp, 0.8) + close(col.temp, CONFIG.tropical_temp, 0.3) * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { 0.001 } else { @@ -192,6 +339,186 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( } }, ), + // Temperate common river wildlife + ( + |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 3) { + 0 => quadruped_small::Body::random_with( + rng, + &quadruped_small::Species::Beaver, + ) + .into(), + _ => { + bird_medium::Body::random_with(rng, &bird_medium::Species::Duck).into() + }, + }) + .with_alignment(Alignment::Wild) + }, + 1..3, + false, + |c, col| { + close(col.temp, CONFIG.temperate_temp, 0.6) + * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { + 0.001 + } else { + 0.0 + } + }, + ), + // Tropical rock solitary ennemies + ( + |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 8) { + 0 => quadruped_small::Body::random_with( + rng, + &quadruped_small::Species::Dodarock, + ) + .into(), + _ => quadruped_low::Body::random_with( + rng, + &quadruped_low::Species::Rocksnapper, + ) + .into(), + }) + .with_alignment(Alignment::Wild) + }, + 1..2, + false, + |c, col| close(c.temp, CONFIG.tropical_temp, 0.3) * col.rock * BASE_DENSITY * 5.0, + ), + // Jungle solitary ennemies + ( + |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 3) { + 0 => { + quadruped_low::Body::random_with(rng, &quadruped_low::Species::Maneater) + .into() + }, + 1 => quadruped_medium::Body::random_with( + rng, + &quadruped_medium::Species::Tiger, + ) + .into(), + _ => quadruped_low::Body::random_with( + rng, + &quadruped_low::Species::Rocksnapper, + ) + .into(), + }) + .with_alignment(Alignment::Enemy) + }, + 1..2, + false, + |c, col| { + close(c.temp, CONFIG.tropical_temp, 0.3) + * close(c.humidity, CONFIG.jungle_hum, 0.3) + * BASE_DENSITY + * 5.0 + }, + ), + // Jungle solitary wild + ( + |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 4) { + 0 => bird_medium::Body::random_with(rng, &bird_medium::Species::Parrot) + .into(), + 1 => { + quadruped_low::Body::random_with(rng, &quadruped_low::Species::Monitor) + .into() + }, + _ => { + quadruped_low::Body::random_with(rng, &quadruped_low::Species::Tortoise) + .into() + }, + }) + .with_alignment(Alignment::Wild) + }, + 1..2, + false, + |c, col| { + close(c.temp, CONFIG.tropical_temp, 0.3) + * close(c.humidity, CONFIG.jungle_hum, 0.3) + * BASE_DENSITY + * 5.0 + }, + ), + // Tropical pack enemies + ( + |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 3) { + 0 => quadruped_medium::Body::random_with( + rng, + &quadruped_medium::Species::Lion, + ) + .into(), + 1 => quadruped_small::Body::random_with( + rng, + &quadruped_small::Species::Hyena, + ) + .into(), + _ => quadruped_medium::Body::random_with( + rng, + &quadruped_medium::Species::Saber, + ) + .into(), + }) + .with_alignment(Alignment::Enemy) + }, + 1..3, + false, + |c, col| close(c.temp, CONFIG.tropical_temp, 0.15) * BASE_DENSITY * 0.4, + ), + // Desert solitary enemies + ( + |pos, rng| { + EntityInfo::at(pos) + .with_body( + quadruped_medium::Body::random_with( + rng, + &quadruped_medium::Species::Bonerattler, + ) + .into(), + ) + .with_alignment(Alignment::Enemy) + }, + 1..2, + false, + |c, col| close(c.humidity, CONFIG.desert_hum, 0.3) * BASE_DENSITY * 0.3, + ), + // Desert solitary wild + ( + |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 3) { + 0 => { + bird_medium::Body::random_with(rng, &bird_medium::Species::Eagle).into() + }, + 1 => { + quadruped_low::Body::random_with(rng, &quadruped_low::Species::Pangolin) + .into() + }, + 2 => quadruped_small::Body::random_with( + rng, + &quadruped_small::Species::Holladon, + ) + .into(), + _ => quadruped_small::Body::random_with( + rng, + &quadruped_small::Species::Gecko, + ) + .into(), + }) + .with_alignment(Alignment::Enemy) + }, + 1..2, + false, + |c, col| close(c.temp, CONFIG.desert_temp + 0.2, 0.7) * BASE_DENSITY * 0.4, + ), ]; for y in 0..vol.size_xy().y as i32 {