Fmt and clippy lints fixes

This commit is contained in:
Joshua Barretto 2020-08-12 15:10:12 +01:00
parent 9cefaaa7af
commit 50a85853e3
27 changed files with 352 additions and 255 deletions

View File

@ -150,7 +150,7 @@ impl Client {
recipe_book,
} => {
// TODO: Display that versions don't match in Voxygen
if &server_info.git_hash != *common::util::GIT_HASH {
if server_info.git_hash != *common::util::GIT_HASH {
warn!(
"Server is running {}[{}], you are running {}[{}], versions \
might be incompatible!",

View File

@ -1,4 +1,4 @@
use crate::{path::Chaser, sync::Uid, comp::Body};
use crate::{comp::Body, path::Chaser, sync::Uid};
use specs::{Component, Entity as EcsEntity};
use specs_idvs::IdvStorage;
use vek::*;

View File

@ -7,8 +7,8 @@ pub use tool::{Hands, Tool, ToolCategory, ToolKind};
use crate::{
assets::{self, Asset},
effect::Effect,
terrain::{Block, BlockKind},
lottery::Lottery,
terrain::{Block, BlockKind},
};
use serde::{Deserialize, Serialize};
use specs::{Component, FlaggedStorage};

View File

@ -503,7 +503,7 @@ impl Inventory {
}
}
if missing.len() == 0 {
if missing.is_empty() {
Ok(slot_claims)
} else {
Err(missing)

View File

@ -1,6 +1,6 @@
use crate::assets::{self, Asset};
use rand::prelude::*;
use serde::{Deserialize, Serialize, de::DeserializeOwned};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::{fs::File, io::BufReader};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -40,9 +40,7 @@ impl<T> Lottery<T> {
.1
}
pub fn choose(&self) -> &T {
self.choose_seeded(thread_rng().gen())
}
pub fn choose(&self) -> &T { self.choose_seeded(thread_rng().gen()) }
pub fn iter(&self) -> impl Iterator<Item = &(f32, T)> { self.items.iter() }
}

View File

@ -100,9 +100,7 @@ impl Route {
{
let (next0, next1, next_tgt, be_precise) = loop {
// If we've reached the end of the path, stop
if self.next(0).is_none() {
return None;
}
self.next(0)?;
let next0 = self
.next(0)
@ -115,10 +113,11 @@ impl Route {
}
let be_precise = DIAGONALS.iter().any(|pos| {
(-1..2)
.all(|z| vol.get(next0 + Vec3::new(pos.x, pos.y, z))
(-1..2).all(|z| {
vol.get(next0 + Vec3::new(pos.x, pos.y, z))
.map(|b| !b.is_solid())
.unwrap_or(false))
.unwrap_or(false)
})
});
let next_tgt = next0.map(|e| e as f32) + Vec3::new(0.5, 0.5, 0.0);
@ -331,7 +330,8 @@ impl Chaser {
let pos_to_tgt = pos.distance(tgt);
// If we're already close to the target then there's nothing to do
let end = self.route
let end = self
.route
.as_ref()
.and_then(|(r, _)| r.path.end().copied())
.map(|e| e.map(|e| e as f32 + 0.5))
@ -343,7 +343,8 @@ impl Chaser {
return None;
}
let bearing = if let Some((end, complete)) = self.route
let bearing = if let Some((end, complete)) = self
.route
.as_ref()
.and_then(|(r, complete)| Some((r.path().end().copied()?, *complete)))
{
@ -354,7 +355,9 @@ impl Chaser {
// theory this shouldn't happen, but in practice the world is full
// of unpredictable obstacles that are more than willing to mess up
// our day. TODO: Come up with a better heuristic for this
if (end_to_tgt > pos_to_tgt * 0.3 + 5.0 && complete) || thread_rng().gen::<f32>() < 0.001 {
if (end_to_tgt > pos_to_tgt * 0.3 + 5.0 && complete)
|| thread_rng().gen::<f32>() < 0.001
{
None
} else {
self.route
@ -388,20 +391,31 @@ impl Chaser {
let start_index = path
.iter()
.enumerate()
.min_by_key(|(_, node)| node.xy().map(|e| e as f32).distance_squared(pos.xy() + tgt_dir) as i32)
.min_by_key(|(_, node)| {
node.xy()
.map(|e| e as f32)
.distance_squared(pos.xy() + tgt_dir)
as i32
})
.map(|(idx, _)| idx);
(Route {
path,
next_idx: start_index.unwrap_or(0),
}, complete)
(
Route {
path,
next_idx: start_index.unwrap_or(0),
},
complete,
)
});
}
let walking_towards_edge = (-3..2)
.all(|z| vol.get((pos + Vec3::<f32>::from(tgt_dir) * 2.5).map(|e| e as i32) + Vec3::unit_z() * z)
.map(|b| !b.is_solid())
.unwrap_or(false));
let walking_towards_edge = (-3..2).all(|z| {
vol.get(
(pos + Vec3::<f32>::from(tgt_dir) * 2.5).map(|e| e as i32) + Vec3::unit_z() * z,
)
.map(|b| !b.is_solid())
.unwrap_or(false)
});
if !walking_towards_edge {
Some(((tgt - pos) * Vec3::new(1.0, 1.0, 0.0), 0.75))
@ -430,8 +444,8 @@ where
.unwrap_or(true)
}
/// Attempt to search for a path to a target, returning the path (if one was found)
/// and whether it is complete (reaches the target)
/// Attempt to search for a path to a target, returning the path (if one was
/// found) and whether it is complete (reaches the target)
fn find_path<V>(
astar: &mut Option<Astar<Vec3<i32>, DefaultHashBuilder>>,
vol: &V,

View File

@ -21,7 +21,7 @@ impl Spiral2d {
impl Iterator for Spiral2d {
type Item = Vec2<i32>;
#[allow(clippy::erasing_op)]
#[allow(clippy::erasing_op, clippy::identity_op)]
fn next(&mut self) -> Option<Self::Item> {
let layer_size = (self.layer * 8 + 4 * self.layer.min(1) - 4).max(1);
if self.i >= layer_size {

View File

@ -24,7 +24,12 @@ impl CharacterBehavior for Data {
update.character = CharacterState::GlideWield;
return update;
}
if data.physics.in_fluid.map(|depth| depth > 0.5).unwrap_or(false) {
if data
.physics
.in_fluid
.map(|depth| depth > 0.5)
.unwrap_or(false)
{
update.character = CharacterState::Idle;
}
// If there is a wall in front of character and they are trying to climb go to

View File

@ -19,7 +19,12 @@ impl CharacterBehavior for Data {
if !data.physics.on_ground {
update.character = CharacterState::Glide;
}
if data.physics.in_fluid.map(|depth| depth > 0.5).unwrap_or(false) {
if data
.physics
.in_fluid
.map(|depth| depth > 0.5)
.unwrap_or(false)
{
update.character = CharacterState::Idle;
}

View File

@ -119,8 +119,9 @@ fn swim_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32, depth:
// Swim
if data.inputs.swimup.is_pressed() {
update.vel.0.z =
(update.vel.0.z + data.dt.0 * GRAVITY * 4.0 * depth.clamped(0.0, 1.0).powf(3.0)).min(BASE_HUMANOID_WATER_SPEED);
update.vel.0.z = (update.vel.0.z
+ data.dt.0 * GRAVITY * 4.0 * depth.clamped(0.0, 1.0).powf(3.0))
.min(BASE_HUMANOID_WATER_SPEED);
}
// Swim
if data.inputs.swimdown.is_pressed() {
@ -192,14 +193,28 @@ pub fn attempt_swap_loadout(data: &JoinData, update: &mut StateUpdate) {
/// Checks that player can wield the glider and updates `CharacterState` if so
pub fn attempt_glide_wield(data: &JoinData, update: &mut StateUpdate) {
if data.physics.on_ground && !data.physics.in_fluid.map(|depth| depth > 1.0).unwrap_or(false) && data.body.is_humanoid() {
if data.physics.on_ground
&& !data
.physics
.in_fluid
.map(|depth| depth > 1.0)
.unwrap_or(false)
&& data.body.is_humanoid()
{
update.character = CharacterState::GlideWield;
}
}
/// Checks that player can jump and sends jump event if so
pub fn handle_jump(data: &JoinData, update: &mut StateUpdate) {
if data.inputs.jump.is_pressed() && data.physics.on_ground && !data.physics.in_fluid.map(|depth| depth > 1.0).unwrap_or(false) {
if data.inputs.jump.is_pressed()
&& data.physics.on_ground
&& !data
.physics
.in_fluid
.map(|depth| depth > 1.0)
.unwrap_or(false)
{
update
.local_events
.push_front(LocalEvent::Jump(data.entity));

View File

@ -317,9 +317,11 @@ impl<'a> System<'a> for Sys {
pos.0,
vel.0,
// Away from the target (ironically)
pos.0 + (pos.0 - tgt_pos.0)
.try_normalized()
.unwrap_or_else(Vec3::unit_y) * 8.0,
pos.0
+ (pos.0 - tgt_pos.0)
.try_normalized()
.unwrap_or_else(Vec3::unit_y)
* 8.0,
TraversalConfig {
node_tolerance,
slow_factor,
@ -483,8 +485,11 @@ impl<'a> System<'a> for Sys {
Activity::Attack { target, .. } if target == attacker => {},
_ => {
if agent.can_speak {
let msg = "npc.speech.villager_under_attack".to_string();
event_bus.emit_now(ServerEvent::Chat(UnresolvedChatMsg::npc(*uid, msg)));
let msg =
"npc.speech.villager_under_attack".to_string();
event_bus.emit_now(ServerEvent::Chat(
UnresolvedChatMsg::npc(*uid, msg),
));
}
agent.activity = Activity::Attack {

View File

@ -12,8 +12,8 @@ use crate::{
use specs::{
saveload::MarkerAllocator, Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage,
};
use vek::*;
use std::ops::Range;
use vek::*;
pub const GRAVITY: f32 = 9.81 * 5.0;
const BOUYANCY: f32 = 1.0;
@ -135,7 +135,11 @@ impl<'a> System<'a> for Sys {
.is_some();
let downward_force = if !in_loaded_chunk {
0.0 // No gravity in unloaded chunks
} else if physics_state.in_fluid.map(|depth| depth > 0.75).unwrap_or(false) {
} else if physics_state
.in_fluid
.map(|depth| depth > 0.75)
.unwrap_or(false)
{
(1.0 - BOUYANCY) * GRAVITY
} else {
GRAVITY
@ -159,9 +163,9 @@ impl<'a> System<'a> for Sys {
z_max,
} => {
// Scale collider
let radius = *radius;// * scale;
let z_min = *z_min;// * scale;
let z_max = *z_max;// * scale;
let radius = *radius; // * scale;
let z_min = *z_min; // * scale;
let z_max = *z_max; // * scale;
// Probe distances
let hdist = radius.ceil() as i32;
@ -177,47 +181,46 @@ impl<'a> System<'a> for Sys {
.flatten()
.flatten();
// Function for iterating over the blocks the player at a specific position collides
// with
// Function for iterating over the blocks the player at a specific position
// collides with
fn collision_iter<'a>(
pos: Vec3<f32>,
terrain: &'a TerrainGrid,
hit: &'a dyn Fn(&Block) -> bool,
near_iter: impl Iterator<Item=(i32, i32, i32)> + 'a,
near_iter: impl Iterator<Item = (i32, i32, i32)> + 'a,
radius: f32,
z_range: Range<f32>,
) -> impl Iterator<Item=Aabb<f32>> + 'a {
near_iter
.filter_map(move |(i, j, k)| {
let block_pos = pos.map(|e| e.floor() as i32) + Vec3::new(i, j, k);
) -> impl Iterator<Item = Aabb<f32>> + 'a {
near_iter.filter_map(move |(i, j, k)| {
let block_pos = pos.map(|e| e.floor() as i32) + Vec3::new(i, j, k);
if let Some(block) = terrain.get(block_pos).ok().copied().filter(hit) {
let player_aabb = Aabb {
min: pos + Vec3::new(-radius, -radius, z_range.start),
max: pos + Vec3::new(radius, radius, z_range.end),
};
let block_aabb = Aabb {
min: block_pos.map(|e| e as f32),
max: block_pos.map(|e| e as f32)
+ Vec3::new(1.0, 1.0, block.get_height()),
};
if let Some(block) = terrain.get(block_pos).ok().copied().filter(hit) {
let player_aabb = Aabb {
min: pos + Vec3::new(-radius, -radius, z_range.start),
max: pos + Vec3::new(radius, radius, z_range.end),
};
let block_aabb = Aabb {
min: block_pos.map(|e| e as f32),
max: block_pos.map(|e| e as f32)
+ Vec3::new(1.0, 1.0, block.get_height()),
};
if player_aabb.collides_with_aabb(block_aabb) {
return Some(block_aabb);
}
if player_aabb.collides_with_aabb(block_aabb) {
return Some(block_aabb);
}
}
None
})
None
})
};
// Function for determining whether the player at a specific position collides
// with blocks with the given criteria
let collision_with = |pos: Vec3<f32>,
hit: &dyn Fn(&Block) -> bool,
near_iter|
{
collision_iter(pos, &terrain, hit, near_iter, radius, z_min..z_max).count() > 0
hit: &dyn Fn(&Block) -> bool,
near_iter| {
collision_iter(pos, &terrain, hit, near_iter, radius, z_min..z_max).count()
> 0
};
let was_on_ground = physics_state.on_ground;
@ -418,9 +421,16 @@ impl<'a> System<'a> for Sys {
}
// Figure out if we're in water
physics_state.in_fluid = collision_iter(pos.0, &terrain, &|block| block.is_fluid(), near_iter.clone(), radius, z_min..z_max)
.max_by_key(|block_aabb| (block_aabb.max.z * 100.0) as i32)
.map(|block_aabb| block_aabb.max.z - pos.0.z);
physics_state.in_fluid = collision_iter(
pos.0,
&terrain,
&|block| block.is_fluid(),
near_iter.clone(),
radius,
z_min..z_max,
)
.max_by_key(|block_aabb| (block_aabb.max.z * 100.0) as i32)
.map(|block_aabb| block_aabb.max.z - pos.0.z);
},
Collider::Point => {
let (dist, block) = terrain.ray(pos.0, pos.0 + pos_delta).ignore_error().cast();

View File

@ -209,12 +209,13 @@ impl BlockKind {
}
pub fn get_glow(&self) -> Option<u8> {
match self {
// TODO: When we have proper volumetric lighting
//BlockKind::StreetLamp | BlockKind::StreetLampTall => Some(20),
//BlockKind::Velorite | BlockKind::VeloriteFrag => Some(10),
_ => None,
}
// TODO: When we have proper volumetric lighting
// match self {
// BlockKind::StreetLamp | BlockKind::StreetLampTall => Some(20),
// BlockKind::Velorite | BlockKind::VeloriteFrag => Some(10),
// _ => None,
// }
None
}
pub fn is_opaque(&self) -> bool {

View File

@ -2,9 +2,10 @@ use crate::{client::Client, Server, SpawnPoint, StateExt};
use common::{
assets,
comp::{
self, object, Alignment, Body, Damage, DamageSource, Group,
HealthChange, HealthSource, Player, Pos, Stats,
self, object, Alignment, Body, Damage, DamageSource, Group, HealthChange, HealthSource,
Player, Pos, Stats,
},
lottery::Lottery,
msg::{PlayerListUpdate, ServerMsg},
outcome::Outcome,
state::BlockChange,
@ -12,7 +13,6 @@ use common::{
sys::combat::BLOCK_ANGLE,
terrain::{Block, TerrainGrid},
vol::{ReadVol, Vox},
lottery::Lottery,
};
use specs::{join::Join, saveload::MarkerAllocator, Entity as EcsEntity, WorldExt};
use tracing::error;

View File

@ -12,7 +12,6 @@ impl Animation for BetaAnimation {
const UPDATE_FN: &'static [u8] = b"character_beta\0";
#[cfg_attr(feature = "be-dyn-lib", export_name = "character_beta")]
#[allow(clippy::unnested_or_patterns)] // TODO: Pending review in #587
fn update_skeleton_inner(
skeleton: &Self::Skeleton,
(active_tool_kind, second_tool_kind, _velocity, _global_time): Self::Dependency,

View File

@ -16,7 +16,6 @@ impl Animation for SpinAnimation {
const UPDATE_FN: &'static [u8] = b"character_spin\0";
#[cfg_attr(feature = "be-dyn-lib", export_name = "character_spin")]
#[allow(clippy::unnested_or_patterns)] // TODO: Pending review in #587
fn update_skeleton_inner(
skeleton: &Self::Skeleton,
(active_tool_kind, second_tool_kind, _global_time): Self::Dependency,

View File

@ -581,7 +581,7 @@ impl FigureMgr {
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid.is_some(), // In water
physics.in_fluid.is_some(), // In water
) {
// Standing
(true, false, false) => anim::character::StandAnimation::update_skeleton(
@ -949,7 +949,7 @@ impl FigureMgr {
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid.is_some(), // In water
physics.in_fluid.is_some(), // In water
) {
// Standing
(true, false, false) => {
@ -1047,7 +1047,7 @@ impl FigureMgr {
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid.is_some(), // In water
physics.in_fluid.is_some(), // In water
) {
// Standing
(true, false, false) => {
@ -1143,7 +1143,7 @@ impl FigureMgr {
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid.is_some(), // In water
physics.in_fluid.is_some(), // In water
) {
// Standing
(true, false, false) => {
@ -1237,7 +1237,7 @@ impl FigureMgr {
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid.is_some(), // In water
physics.in_fluid.is_some(), // In water
) {
// Standing
(true, false, false) => anim::bird_medium::IdleAnimation::update_skeleton(
@ -1329,7 +1329,7 @@ impl FigureMgr {
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid.is_some(), // In water
physics.in_fluid.is_some(), // In water
) {
// Standing
(true, false, false) => anim::fish_medium::IdleAnimation::update_skeleton(
@ -1404,7 +1404,7 @@ impl FigureMgr {
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid.is_some(), // In water
physics.in_fluid.is_some(), // In water
) {
// Standing
(true, false, false) => anim::dragon::IdleAnimation::update_skeleton(
@ -1478,7 +1478,7 @@ impl FigureMgr {
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid.is_some(), // In water
physics.in_fluid.is_some(), // In water
) {
// Standing
(true, false, false) => anim::critter::IdleAnimation::update_skeleton(
@ -1553,7 +1553,7 @@ impl FigureMgr {
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid.is_some(), // In water
physics.in_fluid.is_some(), // In water
) {
// Standing
(true, false, false) => anim::bird_small::IdleAnimation::update_skeleton(
@ -1628,7 +1628,7 @@ impl FigureMgr {
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid.is_some(), // In water
physics.in_fluid.is_some(), // In water
) {
// Standing
(true, false, false) => anim::fish_small::IdleAnimation::update_skeleton(
@ -1703,7 +1703,7 @@ impl FigureMgr {
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid.is_some(), // In water
physics.in_fluid.is_some(), // In water
) {
// Standing
(true, false, false) => anim::biped_large::IdleAnimation::update_skeleton(
@ -1795,7 +1795,7 @@ impl FigureMgr {
let target_base = match (
physics.on_ground,
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
physics.in_fluid.is_some(), // In water
physics.in_fluid.is_some(), // In water
) {
// Standing
(true, false, false) => anim::golem::IdleAnimation::update_skeleton(

View File

@ -3,7 +3,7 @@ mod natural;
use crate::{
column::{ColumnGen, ColumnSample},
util::{RandomField, Sampler, SmallCache},
Index, CONFIG,
Index,
};
use common::{
terrain::{structure::StructureBlock, Block, BlockKind, Structure},
@ -31,7 +31,9 @@ impl<'a> BlockGen<'a> {
wpos: Vec2<i32>,
index: &Index,
) -> Option<&'b ColumnSample<'a>> {
cache.get(wpos, |wpos| column_gen.get((wpos, index))).as_ref()
cache
.get(wpos, |wpos| column_gen.get((wpos, index)))
.as_ref()
}
fn get_cliff_height(
@ -48,7 +50,7 @@ impl<'a> BlockGen<'a> {
|max_height, (cliff_pos, seed)| match Self::sample_column(
column_gen,
cache,
Vec2::from(*cliff_pos),
*cliff_pos,
index,
) {
Some(cliff_sample) if cliff_sample.is_cliffs && cliff_sample.spawn_rate > 0.5 => {
@ -164,14 +166,14 @@ impl<'a> BlockGen<'a> {
//tree_density,
//forest_kind,
//close_structures,
marble,
marble_small,
// marble,
// marble_small,
rock,
//cliffs,
cliff_hill,
close_cliffs,
temp,
humidity,
// temp,
// humidity,
stone_col,
..
} = sample;
@ -181,7 +183,7 @@ impl<'a> BlockGen<'a> {
let wposf = wpos.map(|e| e as f64);
let (block, _height) = if !only_structures {
let (_definitely_underground, height, on_cliff, basement_height, water_height) =
let (_definitely_underground, height, _on_cliff, basement_height, water_height) =
if (wposf.z as f32) < alt - 64.0 * chaos {
// Shortcut warping
(true, alt, false, basement, water_level)
@ -276,83 +278,84 @@ impl<'a> BlockGen<'a> {
},
col.map(|e| (e * 255.0) as u8),
))
} else if (wposf.z as f32) < height + 0.9
&& temp < CONFIG.desert_temp
&& (wposf.z as f32 > water_height + 3.0)
&& marble > 0.6
&& marble_small > 0.55
&& (marble * 3173.7).fract() < 0.6
&& humidity > CONFIG.desert_hum
&& false
{
let treasures = [BlockKind::Chest, BlockKind::Velorite];
// } else if (wposf.z as f32) < height + 0.9
// && temp < CONFIG.desert_temp
// && (wposf.z as f32 > water_height + 3.0)
// && marble > 0.6
// && marble_small > 0.55
// && (marble * 3173.7).fract() < 0.6
// && humidity > CONFIG.desert_hum
// && false
// {
// let treasures = [BlockKind::Chest, BlockKind::Velorite];
let flowers = [
BlockKind::BlueFlower,
BlockKind::PinkFlower,
BlockKind::PurpleFlower,
BlockKind::RedFlower,
BlockKind::WhiteFlower,
BlockKind::YellowFlower,
BlockKind::Sunflower,
BlockKind::Mushroom, //TODO: Better spawnrules
BlockKind::LeafyPlant,
BlockKind::Blueberry,
BlockKind::LingonBerry,
BlockKind::Fern,
/*BlockKind::Twigs, // TODO: Better spawnrules
*BlockKind::Stones, // TODO: Better spawnrules
*BlockKind::ShinyGem, // TODO: Better spawnrules */
];
let grasses = [
BlockKind::LongGrass,
BlockKind::MediumGrass,
BlockKind::ShortGrass,
];
// let flowers = [
// BlockKind::BlueFlower,
// BlockKind::PinkFlower,
// BlockKind::PurpleFlower,
// BlockKind::RedFlower,
// BlockKind::WhiteFlower,
// BlockKind::YellowFlower,
// BlockKind::Sunflower,
// BlockKind::Mushroom, //TODO: Better spawnrules
// BlockKind::LeafyPlant,
// BlockKind::Blueberry,
// BlockKind::LingonBerry,
// BlockKind::Fern,
// /*BlockKind::Twigs, // TODO: Better spawnrules
// *BlockKind::Stones, // TODO: Better spawnrules
// *BlockKind::ShinyGem, // TODO: Better spawnrules */
// ];
// let grasses = [
// BlockKind::LongGrass,
// BlockKind::MediumGrass,
// BlockKind::ShortGrass,
// ];
Some(Block::new(
if on_cliff && (height * 1271.0).fract() < 0.015 {
treasures[(height * 731.3) as usize % treasures.len()]
} else if (height * 1271.0).fract() < 0.1 {
flowers[(height * 0.2) as usize % flowers.len()]
} else {
grasses[(height * 103.3) as usize % grasses.len()]
},
Rgb::broadcast(0),
))
} else if (wposf.z as f32) < height + 0.9
&& temp > CONFIG.desert_temp
&& (marble * 4423.5).fract() < 0.0005
&& false
{
let large_cacti = [
BlockKind::LargeCactus,
BlockKind::MedFlatCactus,
BlockKind::Welwitch,
];
// Some(Block::new(
// if on_cliff && (height * 1271.0).fract() < 0.015 {
// treasures[(height * 731.3) as usize % treasures.len()]
// } else if (height * 1271.0).fract() < 0.1 {
// flowers[(height * 0.2) as usize % flowers.len()]
// } else {
// grasses[(height * 103.3) as usize % grasses.len()]
// },
// Rgb::broadcast(0),
// ))
// } else if (wposf.z as f32) < height + 0.9
// && temp > CONFIG.desert_temp
// && (marble * 4423.5).fract() < 0.0005
// && false
// {
// let large_cacti = [
// BlockKind::LargeCactus,
// BlockKind::MedFlatCactus,
// BlockKind::Welwitch,
// ];
let small_cacti = [
BlockKind::BarrelCactus,
BlockKind::RoundCactus,
BlockKind::ShortCactus,
BlockKind::ShortFlatCactus,
BlockKind::DeadBush,
];
// let small_cacti = [
// BlockKind::BarrelCactus,
// BlockKind::RoundCactus,
// BlockKind::ShortCactus,
// BlockKind::ShortFlatCactus,
// BlockKind::DeadBush,
// ];
Some(Block::new(
if (height * 1271.0).fract() < 0.5 {
large_cacti[(height * 0.2) as usize % large_cacti.len()]
} else {
small_cacti[(height * 0.3) as usize % small_cacti.len()]
},
Rgb::broadcast(0),
))
// Some(Block::new(
// if (height * 1271.0).fract() < 0.5 {
// large_cacti[(height * 0.2) as usize % large_cacti.len()]
// } else {
// small_cacti[(height * 0.3) as usize % small_cacti.len()]
// },
// Rgb::broadcast(0),
// ))
} else {
None
}
.or_else(|| {
// Rocks
if (height + 2.5 - wposf.z as f32).div(7.5).abs().powf(2.0) < rock {
#[allow(clippy::identity_op)]
let field0 = RandomField::new(world.seed + 0);
let field1 = RandomField::new(world.seed + 1);
let field2 = RandomField::new(world.seed + 2);
@ -536,7 +539,7 @@ pub fn block_from_structure(
structure_seed: u32,
sample: &ColumnSample,
) -> Option<Block> {
let field = RandomField::new(structure_seed + 0);
let field = RandomField::new(structure_seed);
let lerp = ((field.get(Vec3::from(structure_pos)).rem_euclid(256)) as f32 / 255.0) * 0.85
+ ((field.get(pos + std::i32::MAX / 2).rem_euclid(256)) as f32 / 255.0) * 0.15;

View File

@ -681,7 +681,6 @@ fn loc_suitable_for_site(sim: &WorldSim, loc: Vec2<i32>) -> bool {
}
/// Attempt to search for a location that's suitable for site construction
#[allow(clippy::useless_conversion)] // TODO: Pending review in #587
#[allow(clippy::or_fun_call)] // TODO: Pending review in #587
fn find_site_loc(
ctx: &mut GenCtx<impl Rng>,
@ -716,7 +715,7 @@ fn find_site_loc(
loc = ctx.sim.get(test_loc).and_then(|c| {
Some(
c.downhill?
.map2(Vec2::from(TerrainChunkSize::RECT_SIZE), |e, sz: u32| {
.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| {
e / (sz as i32)
}),
)

View File

@ -179,7 +179,6 @@ where
#[allow(clippy::if_same_then_else)] // TODO: Pending review in #587
#[allow(clippy::nonminimal_bool)] // TODO: Pending review in #587
#[allow(clippy::single_match)] // TODO: Pending review in #587
#[allow(clippy::bind_instead_of_map)] // TODO: Pending review in #587
fn get(&self, (wpos, index): Self::Index) -> Option<ColumnSample<'a>> {
let wposf = wpos.map(|e| e as f64);
let chunk_pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| e / sz as i32);

View File

@ -26,6 +26,7 @@ pub struct Noise {
}
impl Noise {
#[allow(clippy::identity_op)]
fn new(seed: u32) -> Self {
Self {
cave_nz: SuperSimplex::new().set_seed(seed + 0),

View File

@ -31,6 +31,7 @@ pub fn apply_scatter_to<'a>(
chunk: &SimChunk,
) {
use BlockKind::*;
#[allow(clippy::type_complexity)]
let scatter: &[(_, bool, fn(&SimChunk) -> (f32, Option<(f32, f32)>))] = &[
// (density, Option<(wavelen, threshold)>)
(BlueFlower, false, |c| {
@ -103,8 +104,7 @@ pub fn apply_scatter_to<'a>(
.enumerate()
.find_map(|(i, (bk, is_underwater, f))| {
let (density, patch) = f(chunk);
if density <= 0.0
|| patch
let is_patch = patch
.map(|(wavelen, threshold)| {
index.noise.scatter_nz.get(
wpos2d
@ -112,7 +112,9 @@ pub fn apply_scatter_to<'a>(
.into_array(),
) < threshold as f64
})
.unwrap_or(false)
.unwrap_or(false);
if density <= 0.0
|| is_patch
|| !RandomField::new(i as u32)
.chance(Vec3::new(wpos2d.x, wpos2d.y, 0), density)
|| underwater != *is_underwater
@ -398,6 +400,7 @@ pub fn apply_caves_supplement<'a>(
comp::critter::Body::random_with(rng, &species).into()
},
4 => {
#[allow(clippy::match_single_binding)]
let species = match rng.gen_range(0, 1) {
_ => comp::golem::Species::StoneGolem,
};

View File

@ -2,10 +2,10 @@ use vek::*;
#[derive(Copy, Clone, Debug, Default)]
pub struct Way {
/// Offset from chunk center in blocks (no more than half chunk width)
pub offset: Vec2<i8>,
/// Neighbor connections, one bit each
pub neighbors: u8,
/// Offset from chunk center in blocks (no more than half chunk width)
pub offset: Vec2<i8>,
/// Neighbor connections, one bit each
pub neighbors: u8,
}
impl Way {
@ -20,23 +20,23 @@ pub struct Path {
}
impl Default for Path {
fn default() -> Self {
Self { width: 5.0 }
}
fn default() -> Self { Self { width: 5.0 } }
}
impl Lerp for Path {
type Output = Self;
fn lerp_unclamped(from: Self, to: Self, factor: f32) -> Self::Output {
Self { width: Lerp::lerp(from.width, to.width, factor) }
Self {
width: Lerp::lerp(from.width, to.width, factor),
}
}
}
impl Path {
/// Return the number of blocks of headspace required at the given path
/// distance
/// TODO: make this generic over width
/// TODO: make this generic over width
pub fn head_space(&self, dist: f32) -> i32 {
(8 - (dist * 0.25).powf(6.0).round() as i32).max(1)
}
@ -48,7 +48,7 @@ impl Path {
#[derive(Copy, Clone, Debug)]
pub struct Cave {
pub width: f32, // Actually radius
pub alt: f32, // Actually radius
pub alt: f32, // Actually radius
}
impl Default for Cave {

View File

@ -15,32 +15,39 @@ const YEAR: f32 = 12.0 * MONTH;
const TICK_PERIOD: f32 = 3.0 * MONTH; // 3 months
const HISTORY_DAYS: f32 = 500.0 * YEAR; // 500 years
const GENERATE_CSV: bool = false;
pub fn simulate(index: &mut Index, world: &mut WorldSim) {
use std::io::Write;
let mut f = std::fs::File::create("economy.csv").unwrap();
write!(f, "Population,").unwrap();
for g in Good::list() {
write!(f, "{:?} Value,", g).unwrap();
}
for g in Good::list() {
write!(f, "{:?} LaborVal,", g).unwrap();
}
for g in Good::list() {
write!(f, "{:?} Stock,", g).unwrap();
}
for g in Good::list() {
write!(f, "{:?} Surplus,", g).unwrap();
}
for l in Labor::list() {
write!(f, "{:?} Labor,", l).unwrap();
}
for l in Labor::list() {
write!(f, "{:?} Productivity,", l).unwrap();
}
for l in Labor::list() {
write!(f, "{:?} Yields,", l).unwrap();
}
writeln!(f, "").unwrap();
let mut f = if GENERATE_CSV {
let mut f = std::fs::File::create("economy.csv").unwrap();
write!(f, "Population,").unwrap();
for g in Good::list() {
write!(f, "{:?} Value,", g).unwrap();
}
for g in Good::list() {
write!(f, "{:?} LaborVal,", g).unwrap();
}
for g in Good::list() {
write!(f, "{:?} Stock,", g).unwrap();
}
for g in Good::list() {
write!(f, "{:?} Surplus,", g).unwrap();
}
for l in Labor::list() {
write!(f, "{:?} Labor,", l).unwrap();
}
for l in Labor::list() {
write!(f, "{:?} Productivity,", l).unwrap();
}
for l in Labor::list() {
write!(f, "{:?} Yields,", l).unwrap();
}
writeln!(f).unwrap();
Some(f)
} else {
None
};
for i in 0..(HISTORY_DAYS / TICK_PERIOD) as i32 {
if (index.time / YEAR) as i32 % 50 == 0 && (index.time % YEAR) as i32 == 0 {
@ -49,31 +56,33 @@ pub fn simulate(index: &mut Index, world: &mut WorldSim) {
tick(index, world, TICK_PERIOD);
if i % 5 == 0 {
let site = index.sites.values().next().unwrap();
write!(f, "{},", site.economy.pop).unwrap();
for g in Good::list() {
write!(f, "{:?},", site.economy.values[*g].unwrap_or(-1.0)).unwrap();
if let Some(f) = f.as_mut() {
if i % 5 == 0 {
let site = index.sites.values().next().unwrap();
write!(f, "{},", site.economy.pop).unwrap();
for g in Good::list() {
write!(f, "{:?},", site.economy.values[*g].unwrap_or(-1.0)).unwrap();
}
for g in Good::list() {
write!(f, "{:?},", site.economy.labor_values[*g].unwrap_or(-1.0)).unwrap();
}
for g in Good::list() {
write!(f, "{:?},", site.economy.stocks[*g]).unwrap();
}
for g in Good::list() {
write!(f, "{:?},", site.economy.marginal_surplus[*g]).unwrap();
}
for l in Labor::list() {
write!(f, "{:?},", site.economy.labors[*l] * site.economy.pop).unwrap();
}
for l in Labor::list() {
write!(f, "{:?},", site.economy.productivity[*l]).unwrap();
}
for l in Labor::list() {
write!(f, "{:?},", site.economy.yields[*l]).unwrap();
}
writeln!(f).unwrap();
}
for g in Good::list() {
write!(f, "{:?},", site.economy.labor_values[*g].unwrap_or(-1.0)).unwrap();
}
for g in Good::list() {
write!(f, "{:?},", site.economy.stocks[*g]).unwrap();
}
for g in Good::list() {
write!(f, "{:?},", site.economy.marginal_surplus[*g]).unwrap();
}
for l in Labor::list() {
write!(f, "{:?},", site.economy.labors[*l] * site.economy.pop).unwrap();
}
for l in Labor::list() {
write!(f, "{:?},", site.economy.productivity[*l]).unwrap();
}
for l in Labor::list() {
write!(f, "{:?},", site.economy.yields[*l]).unwrap();
}
writeln!(f, "").unwrap();
}
}
}
@ -204,8 +213,7 @@ pub fn tick_site_economy(index: &mut Index, site: Id<Site>, dt: f32) {
// What quantity is this order requesting?
let _quantity = *amount * scale;
// What proportion of this order is the economy able to satisfy?
let satisfaction = (stocks_before[*good] / demand[*good]).min(1.0);
satisfaction
(stocks_before[*good] / demand[*good]).min(1.0)
})
.min_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap_or_else(|| panic!("Industry {:?} requires at least one input order", labor));

View File

@ -479,7 +479,8 @@ impl Floor {
.reduce_and()
})
.unwrap_or(false);
let boss_spawn_tile = boss_spawn_tile + if boss_tile_is_pillar { 1 } else { 0 };
let boss_spawn_tile =
boss_spawn_tile + if boss_tile_is_pillar { 1 } else { 0 };
if tile_pos == boss_spawn_tile && tile_wcenter.xy() == wpos2d {
let entity = EntityInfo::at(tile_wcenter.map(|e| e as f32))
@ -641,7 +642,8 @@ impl Floor {
move |z| match self.tiles.get(tile_pos) {
Some(Tile::Solid) => BlockMask::nothing(),
Some(Tile::Tunnel) => {
if dist_to_wall >= wall_thickness && (z as f32) < tunnel_height * (1.0 - tunnel_dist.powf(4.0))
if dist_to_wall >= wall_thickness
&& (z as f32) < tunnel_height * (1.0 - tunnel_dist.powf(4.0))
{
if z == 0 { floor_sprite } else { empty }
} else {

View File

@ -294,10 +294,16 @@ impl Archetype for House {
let edge_ori = if bound_offset.x.abs() > bound_offset.y.abs() {
if center_offset.x > 0 { 6 } else { 2 }
} else if (center_offset.y > 0) ^ (ori == Ori::East) {
0
} else {
if (center_offset.y > 0) ^ (ori == Ori::East) { 0 } else { 4 }
4
};
let edge_ori = if ori == Ori::East {
(edge_ori + 2) % 8
} else {
edge_ori
};
let edge_ori = if ori == Ori::East { (edge_ori + 2) % 8 } else { edge_ori };
if let Pillar::Chimney(chimney_height) = attr.pillar {
let chimney_top = roof_top + chimney_height;
@ -491,9 +497,16 @@ impl Archetype for House {
} else if dist == width - 1
&& center_offset.sum() % 2 == 0
&& profile.y == floor_height + 1
&& self.noise.chance(Vec3::new(center_offset.x, center_offset.y, z), 0.2)
&& self
.noise
.chance(Vec3::new(center_offset.x, center_offset.y, z), 0.2)
{
let furniture = match self.noise.get(Vec3::new(center_offset.x, center_offset.y, z + 100)) % 11 {
let furniture = match self.noise.get(Vec3::new(
center_offset.x,
center_offset.y,
z + 100,
)) % 11
{
0 => BlockKind::Planter,
1 => BlockKind::ChairSingle,
2 => BlockKind::ChairDouble,
@ -506,7 +519,10 @@ impl Archetype for House {
_ => BlockKind::Pot,
};
return Some(BlockMask::new(Block::new(furniture, Rgb::new(edge_ori, 0, 0)), internal_layer));
return Some(BlockMask::new(
Block::new(furniture, Rgb::new(edge_ori, 0, 0)),
internal_layer,
));
} else {
return Some(internal);
}
@ -516,16 +532,26 @@ impl Archetype for House {
if dist == width + 1
&& center_offset.map(|e| e.abs()).reduce_min() == 0
&& profile.y == floor_height + 3
&& self.noise.chance(Vec3::new(center_offset.x, center_offset.y, z), 0.35)
&& self
.noise
.chance(Vec3::new(center_offset.x, center_offset.y, z), 0.35)
&& attr.storey_fill.has_lower()
{
let ornament = match self.noise.get(Vec3::new(center_offset.x, center_offset.y, z + 100)) % 4 {
0 => BlockKind::HangingSign,
1 | 2 | 3 => BlockKind::HangingBasket,
_ => BlockKind::DungeonWallDecor,
};
let ornament =
match self
.noise
.get(Vec3::new(center_offset.x, center_offset.y, z + 100))
% 4
{
0 => BlockKind::HangingSign,
1 | 2 | 3 => BlockKind::HangingBasket,
_ => BlockKind::DungeonWallDecor,
};
return Some(BlockMask::new(Block::new(ornament, Rgb::new((edge_ori + 4) % 8, 0, 0)), internal_layer));
Some(BlockMask::new(
Block::new(ornament, Rgb::new((edge_ori + 4) % 8, 0, 0)),
internal_layer,
))
} else {
None
}

View File

@ -208,9 +208,14 @@ impl Archetype for Keep {
if profile.y > roof_height
&& (min_dist < rampart_width - 1 || (attr.is_tower && min_dist < rampart_width))
{
if attr.is_tower && attr.flag && center_offset == Vec2::zero() && profile.y < roof_height + 16 {
if attr.is_tower
&& attr.flag
&& center_offset == Vec2::zero()
&& profile.y < roof_height + 16
{
pole
} else if attr.is_tower && attr.flag
} else if attr.is_tower
&& attr.flag
&& center_offset.x == 0
&& center_offset.y > 0
&& center_offset.y < 8