diff --git a/CHANGELOG.md b/CHANGELOG.md index adbab4c8f9..cf2bf6b0ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,6 +80,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Made settings less likely to reset when the format changes - Adjusted some keybindings - Consumables can now trigger multiple effects and buffs +- Overhauled overworld spawns depending on chunk attributes ### Removed diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 699813ed61..88fca9a976 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -1569,13 +1569,8 @@ fn handle_debug_column( let sampler = server.world.sample_columns(); let mut wpos = Vec2::new(0, 0); if let Ok((x, y)) = scan_fmt!(&args, &action.arg_fmt(), i32, i32) { - //match server.state.read_component_copied::(target) wpos = Vec2::new(x, y); - } - /* let chunk_pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| { - e / sz as i32 - }); */ - else { + } else { match server.state.read_component_copied::(target) { Some(pos) => wpos = pos.0.xy().map(|x| x as i32), None => server.notify_client( @@ -1585,7 +1580,6 @@ fn handle_debug_column( } } let msg_generator = || { - // let sim_chunk = sim.get(chunk_pos)?; let alt = sim.get_interpolated(wpos, |chunk| chunk.alt)?; let basement = sim.get_interpolated(wpos, |chunk| chunk.basement)?; let water_alt = sim.get_interpolated(wpos, |chunk| chunk.water_alt)?; diff --git a/world/src/layer/wildlife.rs b/world/src/layer/wildlife.rs index acc2fbd9ec..d5552cfbe1 100644 --- a/world/src/layer/wildlife.rs +++ b/world/src/layer/wildlife.rs @@ -26,15 +26,17 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( chunk: &SimChunk, supplement: &mut ChunkSupplement, ) { - let scatter: &[( - fn(Vec3, &mut R) -> EntityInfo, // Entity - Range, // Group size range - bool, // Underwater? - fn(&SimChunk, &ColumnSample) -> f32, // Density - )] = &[ + struct Entry { + make_entity: fn(Vec3, &mut R) -> EntityInfo, // Entity + group_size: Range, // Group size range + is_underwater: bool, // Underwater? + get_density: fn(&SimChunk, &ColumnSample) -> f32, // Density + } + + let scatter: &[Entry] = &[ // Tundra pack ennemies - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 3) { 0 => quadruped_medium::Body::random_with( @@ -55,26 +57,26 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Enemy) }, - 1..4, - false, - |c, _col| close(c.temp, CONFIG.snow_temp, 0.3) * BASE_DENSITY * 1.0, - ), + group_size: 1..4, + is_underwater: false, + get_density: |c, _col| close(c.temp, CONFIG.snow_temp, 0.3) * BASE_DENSITY * 1.0, + }, // Tundra rare solitary ennemies - ( - |pos, rng| { + Entry { + make_entity: |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, - ), + group_size: 1..2, + is_underwater: false, + get_density: |c, _col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.1, + }, // Taiga pack ennemies - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body( quadruped_medium::Body::random_with(rng, &quadruped_medium::Species::Wolf) @@ -82,15 +84,15 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( ) .with_alignment(Alignment::Enemy) }, - 3..8, - false, - |c, col| { + group_size: 3..8, + is_underwater: false, + get_density: |c, col| { close(c.temp, CONFIG.snow_temp + 0.2, 0.6) * col.tree_density * BASE_DENSITY * 1.0 }, - ), + }, // Taiga pack wild - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body( quadruped_medium::Body::random_with( @@ -101,13 +103,13 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( ) .with_alignment(Alignment::Wild) }, - 1..4, - false, - |c, _col| close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * BASE_DENSITY * 1.0, - ), + group_size: 1..4, + is_underwater: false, + get_density: |c, _col| close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * BASE_DENSITY * 1.0, + }, // Taiga solitary wild - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 5) { 0 => { @@ -130,13 +132,13 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Wild) }, - 1..2, - false, - |c, _col| close(c.temp, CONFIG.snow_temp + 0.2, 0.6) * BASE_DENSITY * 5.0, - ), + group_size: 1..2, + is_underwater: false, + get_density: |c, _col| close(c.temp, CONFIG.snow_temp + 0.2, 0.6) * BASE_DENSITY * 5.0, + }, // Temperate pack ennemies - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 2) { 0 => quadruped_medium::Body::random_with( @@ -152,13 +154,13 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Enemy) }, - 1..2, - false, - |c, _col| close(c.temp, CONFIG.temperate_temp, 0.35) * BASE_DENSITY * 1.0, - ), + group_size: 1..2, + is_underwater: false, + get_density: |c, _col| close(c.temp, CONFIG.temperate_temp, 0.35) * BASE_DENSITY * 1.0, + }, // Temperate pack wild - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 11) { 0 => quadruped_medium::Body::random_with( @@ -212,19 +214,19 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Wild) }, - 1..8, - false, - |c, _col| { + group_size: 1..8, + is_underwater: false, + get_density: |c, _col| { close(c.temp, CONFIG.temperate_temp, 0.5) * close(c.humidity, CONFIG.forest_hum, 0.4) //* col.tree_density * BASE_DENSITY * 4.0 }, - ), + }, // Temperate solitary wild - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 15) { 0 => quadruped_small::Body { @@ -297,18 +299,18 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Wild) }, - 1..2, - false, - |c, _col| { + group_size: 1..2, + is_underwater: false, + get_density: |c, _col| { close(c.temp, CONFIG.temperate_temp, 0.5) * BASE_DENSITY * close(c.humidity, CONFIG.forest_hum, 0.4) * 8.0 }, - ), + }, // Rare temperate solitary enemies - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 4) { 0 => { @@ -324,13 +326,13 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Enemy) }, - 1..2, - false, - |c, _col| close(c.temp, CONFIG.temperate_temp, 0.8) * BASE_DENSITY * 0.1, - ), + group_size: 1..2, + is_underwater: false, + get_density: |c, _col| close(c.temp, CONFIG.temperate_temp, 0.8) * BASE_DENSITY * 0.1, + }, // Temperate river wildlife - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 3) { 0 => quadruped_small::Body::random_with( @@ -349,9 +351,9 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Wild) }, - 1..2, - false, - |_c, col| { + group_size: 1..2, + is_underwater: false, + get_density: |_c, col| { close(col.temp, CONFIG.temperate_temp, 0.6) * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { 0.003 @@ -359,10 +361,10 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( 0.0 } }, - ), + }, // Temperate river ennemies - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body( quadruped_low::Body::random_with(rng, &quadruped_low::Species::Hakulaq) @@ -370,9 +372,9 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( ) .with_alignment(Alignment::Enemy) }, - 1..2, - false, - |_c, col| { + group_size: 1..2, + is_underwater: false, + get_density: |_c, col| { close(col.temp, CONFIG.temperate_temp, 0.6) * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { 0.0001 @@ -380,10 +382,10 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( 0.0 } }, - ), + }, // Tropical rock solitary ennemies - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body( quadruped_small::Body::random_with( @@ -394,13 +396,15 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( ) .with_alignment(Alignment::Enemy) }, - 1..2, - false, - |c, col| close(c.temp, CONFIG.tropical_temp + 0.1, 0.5) * col.rock * BASE_DENSITY * 5.0, - ), + group_size: 1..2, + is_underwater: false, + get_density: |c, col| { + close(c.temp, CONFIG.tropical_temp + 0.1, 0.5) * col.rock * BASE_DENSITY * 5.0 + }, + }, // Jungle solitary ennemies - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 3) { 0 => { @@ -420,18 +424,18 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Enemy) }, - 1..2, - false, - |c, _col| { + group_size: 1..2, + is_underwater: false, + get_density: |c, _col| { close(c.temp, CONFIG.tropical_temp + 0.1, 0.4) * close(c.humidity, CONFIG.jungle_hum, 0.3) * BASE_DENSITY * 4.0 }, - ), + }, // Jungle solitary wild - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 3) { 0 => bird_medium::Body::random_with(rng, &bird_medium::Species::Parrot) @@ -447,18 +451,18 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Wild) }, - 1..2, - false, - |c, _col| { + group_size: 1..2, + is_underwater: false, + get_density: |c, _col| { close(c.temp, CONFIG.tropical_temp, 0.5) * close(c.humidity, CONFIG.jungle_hum, 0.3) * BASE_DENSITY * 8.0 }, - ), + }, // Tropical rare river enemy - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 2) { // WE GROW 'EM BIG 'ERE @@ -475,9 +479,9 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Enemy) }, - 1..3, - false, - |_c, col| { + group_size: 1..3, + is_underwater: false, + get_density: |_c, col| { close(col.temp, CONFIG.tropical_temp + 0.2, 0.5) * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { 0.0002 @@ -485,10 +489,10 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( 0.0 } }, - ), + }, // Tropical rare river wild - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 3) { 0 => { @@ -508,9 +512,9 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Wild) }, - 1..3, - false, - |_c, col| { + group_size: 1..3, + is_underwater: false, + get_density: |_c, col| { close(col.temp, CONFIG.tropical_temp, 0.5) * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { 0.001 @@ -518,10 +522,10 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( 0.0 } }, - ), + }, // Tropical pack enemies - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 2) { 0 => quadruped_medium::Body::random_with( @@ -537,18 +541,18 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Enemy) }, - 1..3, - false, - |c, _col| { + group_size: 1..3, + is_underwater: false, + get_density: |c, _col| { close(c.temp, CONFIG.tropical_temp + 0.1, 0.4) * close(c.humidity, CONFIG.desert_hum, 0.4) * BASE_DENSITY * 2.0 }, - ), + }, // Desert pack wild - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body( quadruped_medium::Body::random_with( @@ -559,18 +563,18 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( ) .with_alignment(Alignment::Wild) }, - 3..8, - false, - |c, _col| { + group_size: 3..8, + is_underwater: false, + get_density: |c, _col| { close(c.temp, CONFIG.tropical_temp + 0.1, 0.4) * close(c.humidity, CONFIG.desert_hum, 0.4) * BASE_DENSITY * 1.0 }, - ), + }, // Desert solitary enemies - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 2) { 0 => quadruped_medium::Body::random_with( @@ -586,18 +590,18 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Enemy) }, - 1..2, - false, - |c, _col| { + group_size: 1..2, + is_underwater: false, + get_density: |c, _col| { close(c.temp, CONFIG.desert_temp + 0.2, 0.3) * close(c.humidity, CONFIG.desert_hum, 0.5) * BASE_DENSITY * 1.5 }, - ), + }, // Desert solitary wild - ( - |pos, rng| { + Entry { + make_entity: |pos, rng| { EntityInfo::at(pos) .with_body(match rng.gen_range(0, 5) { 0 => quadruped_small::Body::random_with( @@ -627,10 +631,12 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Wild) }, - 1..2, - false, - |c, _col| close(c.temp, CONFIG.desert_temp + 0.2, 0.3) * BASE_DENSITY * 5.0, - ), + group_size: 1..2, + is_underwater: false, + get_density: |c, _col| { + close(c.temp, CONFIG.desert_temp + 0.2, 0.3) * BASE_DENSITY * 5.0 + }, + }, ]; for y in 0..vol.size_xy().y as i32 { @@ -649,8 +655,16 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( let underwater = col_sample.water_level > col_sample.alt; let entity_group = scatter.iter().enumerate().find_map( - |(_i, (make_entity, group_size, is_underwater, f))| { - let density = f(chunk, col_sample); + |( + _i, + Entry { + make_entity, + group_size, + is_underwater, + get_density, + }, + )| { + let density = get_density(chunk, col_sample); if density > 0.0 && dynamic_rng.gen::() < density && underwater == *is_underwater