mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fmt and clippy lints fixes
This commit is contained in:
parent
9cefaaa7af
commit
50a85853e3
@ -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!",
|
||||
|
@ -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::*;
|
||||
|
@ -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};
|
||||
|
@ -503,7 +503,7 @@ impl Inventory {
|
||||
}
|
||||
}
|
||||
|
||||
if missing.len() == 0 {
|
||||
if missing.is_empty() {
|
||||
Ok(slot_claims)
|
||||
} else {
|
||||
Err(missing)
|
||||
|
@ -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() }
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
}),
|
||||
)
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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));
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user