mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added labour value to economy, castle improvements
This commit is contained in:
parent
bdb39b8e7f
commit
1763693f5f
@ -1 +0,0 @@
|
||||
,joshua,archbox.localdomain,17.06.2020 16:07,file:///home/joshua/.config/libreoffice/4;
|
@ -15,7 +15,7 @@ use common::{
|
||||
sync::{Uid, WorldSyncExt},
|
||||
terrain::{Block, BlockKind, TerrainChunkSize},
|
||||
util::Dir,
|
||||
vol::{RectVolSize, WriteVol},
|
||||
vol::RectVolSize,
|
||||
LoadoutBuilder,
|
||||
};
|
||||
use rand::Rng;
|
||||
|
@ -127,7 +127,7 @@ impl Civs {
|
||||
let wpos = site.center * TerrainChunkSize::RECT_SIZE.map(|e: u32| e as i32);
|
||||
|
||||
let flatten_radius = match &site.kind {
|
||||
SiteKind::Settlement => 8.0,
|
||||
SiteKind::Settlement => 10.0,
|
||||
SiteKind::Dungeon => 2.0,
|
||||
SiteKind::Castle => 5.0,
|
||||
};
|
||||
@ -148,9 +148,10 @@ impl Civs {
|
||||
0.0
|
||||
}; // Raise the town centre up a little
|
||||
let pos = site.center + offs;
|
||||
let factor = (1.0
|
||||
let factor = ((1.0
|
||||
- (site.center - pos).map(|e| e as f32).magnitude() / flatten_radius)
|
||||
* 0.8;
|
||||
* 1.25)
|
||||
.min(1.0);
|
||||
ctx.sim
|
||||
.get_mut(pos)
|
||||
// Don't disrupt chunks that are near water
|
||||
@ -170,9 +171,11 @@ impl Civs {
|
||||
let mut cnt = 0;
|
||||
for sim_site in this.sites.values() {
|
||||
cnt += 1;
|
||||
let wpos = sim_site.center.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| {
|
||||
e * sz as i32 + sz as i32 / 2
|
||||
});
|
||||
let wpos = sim_site
|
||||
.center
|
||||
.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| {
|
||||
e * sz as i32 + sz as i32 / 2
|
||||
});
|
||||
|
||||
let mut rng = ctx.reseed().rng;
|
||||
let site = index.sites.insert(match &sim_site.kind {
|
||||
|
@ -26,6 +26,7 @@ pub use self::{
|
||||
use crate::{
|
||||
all::ForestKind,
|
||||
civ::Place,
|
||||
column::{ColumnGen, ColumnSample},
|
||||
site::Site,
|
||||
util::{seed_expan, FastNoise, RandomField, StructureGen2d, LOCALITY, NEIGHBORS},
|
||||
Index, CONFIG,
|
||||
@ -1699,8 +1700,9 @@ impl WorldSim {
|
||||
Some(z0 + z1 + z2 + z3)
|
||||
}
|
||||
|
||||
/// Return the distance to the nearest path in blocks, along with the closest point on the
|
||||
/// path, the path metadata, and the tangent vector of that path.
|
||||
/// Return the distance to the nearest path in blocks, along with the
|
||||
/// closest point on the path, the path metadata, and the tangent vector
|
||||
/// of that path.
|
||||
pub fn get_nearest_path(&self, wpos: Vec2<i32>) -> Option<(f32, Vec2<f32>, Path, Vec2<f32>)> {
|
||||
let chunk_pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| {
|
||||
e.div_euclid(sz as i32)
|
||||
|
@ -23,7 +23,7 @@ pub fn simulate(index: &mut Index, world: &mut WorldSim) {
|
||||
write!(f, "{:?} Value,", g).unwrap();
|
||||
}
|
||||
for g in Good::list() {
|
||||
write!(f, "{:?} Price,", g).unwrap();
|
||||
write!(f, "{:?} LaborVal,", g).unwrap();
|
||||
}
|
||||
for g in Good::list() {
|
||||
write!(f, "{:?} Stock,", g).unwrap();
|
||||
@ -37,6 +37,9 @@ pub fn simulate(index: &mut Index, world: &mut WorldSim) {
|
||||
for l in Labor::list() {
|
||||
write!(f, "{:?} Productivity,", l).unwrap();
|
||||
}
|
||||
for l in Labor::list() {
|
||||
write!(f, "{:?} Yields,", l).unwrap();
|
||||
}
|
||||
writeln!(f, "").unwrap();
|
||||
|
||||
for i in 0..(HISTORY_DAYS / TICK_PERIOD) as i32 {
|
||||
@ -53,7 +56,7 @@ pub fn simulate(index: &mut Index, world: &mut WorldSim) {
|
||||
write!(f, "{:?},", site.economy.values[*g].unwrap_or(-1.0)).unwrap();
|
||||
}
|
||||
for g in Good::list() {
|
||||
write!(f, "{:?},", site.economy.prices[*g]).unwrap();
|
||||
write!(f, "{:?},", site.economy.labor_values[*g]).unwrap();
|
||||
}
|
||||
for g in Good::list() {
|
||||
write!(f, "{:?},", site.economy.stocks[*g]).unwrap();
|
||||
@ -67,6 +70,9 @@ pub fn simulate(index: &mut Index, world: &mut WorldSim) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
@ -144,11 +150,6 @@ pub fn tick_site_economy(index: &mut Index, site: Id<Site>, dt: f32) {
|
||||
};
|
||||
});
|
||||
|
||||
site.economy.prices = site.economy.stocks.clone().map(|g, stock| {
|
||||
// Price rationalisation
|
||||
demand[g] / (supply[g] + stocks[g])
|
||||
});
|
||||
|
||||
// Update export targets based on relative values
|
||||
let value_avg = values
|
||||
.iter()
|
||||
@ -169,7 +170,8 @@ pub fn tick_site_economy(index: &mut Index, site: Id<Site>, dt: f32) {
|
||||
|
||||
// Redistribute workforce according to relative good values
|
||||
let labor_ratios = productivity.clone().map(|labor, (output_good, _)| {
|
||||
site.economy.values[output_good].unwrap_or(0.0) * site.economy.productivity[labor]
|
||||
site.economy.values[output_good].unwrap_or(0.0) * site.economy.yields[labor]
|
||||
//(site.economy.prices[output_good] - site.economy.material_costs[output_good]) * site.economy.yields[labor]
|
||||
//* demand[output_good] / supply[output_good].max(0.001)
|
||||
});
|
||||
let labor_ratio_sum = labor_ratios.iter().map(|(_, r)| *r).sum::<f32>().max(0.01);
|
||||
@ -182,6 +184,7 @@ pub fn tick_site_economy(index: &mut Index, site: Id<Site>, dt: f32) {
|
||||
|
||||
// Production
|
||||
let stocks_before = site.economy.stocks.clone();
|
||||
site.economy.labor_values = Default::default();
|
||||
for (labor, orders) in orders.iter() {
|
||||
let scale = if let Some(labor) = labor {
|
||||
site.economy.labors[*labor]
|
||||
@ -207,12 +210,16 @@ pub fn tick_site_economy(index: &mut Index, site: Id<Site>, dt: f32) {
|
||||
.min_by(|a, b| a.partial_cmp(b).unwrap())
|
||||
.unwrap_or_else(|| panic!("Industry {:?} requires at least one input order", labor));
|
||||
|
||||
let mut total_materials_cost = 0.0;
|
||||
for (good, amount) in orders {
|
||||
// What quantity is this order requesting?
|
||||
let quantity = *amount * scale;
|
||||
// What amount gets actually used in production?
|
||||
let used = quantity * labor_productivity;
|
||||
|
||||
// Material cost of each factor of production
|
||||
total_materials_cost += used * site.economy.labor_values[*good];
|
||||
|
||||
// Deplete stocks accordingly
|
||||
site.economy.stocks[*good] = (site.economy.stocks[*good] - used).max(0.0);
|
||||
}
|
||||
@ -222,10 +229,19 @@ pub fn tick_site_economy(index: &mut Index, site: Id<Site>, dt: f32) {
|
||||
let (stock, rate) = productivity[*labor];
|
||||
let workers = site.economy.labors[*labor] * site.economy.pop;
|
||||
let final_rate = rate;
|
||||
let yield_per_worker = labor_productivity * final_rate;
|
||||
let yield_per_worker = labor_productivity * final_rate * (1.0 + workers / 100.0);
|
||||
site.economy.yields[*labor] = yield_per_worker;
|
||||
site.economy.productivity[*labor] = labor_productivity;
|
||||
site.economy.stocks[stock] += yield_per_worker * workers.powf(1.1);
|
||||
let total_output = yield_per_worker * workers;
|
||||
site.economy.stocks[stock] += total_output;
|
||||
|
||||
// Materials cost per unit
|
||||
let material_cost_per_unit = total_materials_cost / total_output.max(0.001);
|
||||
site.economy.material_costs[stock] = material_cost_per_unit;
|
||||
site.economy.labor_values[stock] += material_cost_per_unit;
|
||||
// Labor costs
|
||||
let wages = 1.0;
|
||||
site.economy.labor_values[stock] += workers * wages / total_output.max(0.001);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,19 +69,6 @@ impl Castle {
|
||||
|
||||
let radius = 150;
|
||||
|
||||
// Adjust ground
|
||||
if let Some(sim) = ctx.sim.as_mut() {
|
||||
for rpos in Spiral2d::new()
|
||||
.radius((radius as f32 * 0.7) as i32 / TerrainChunkSize::RECT_SIZE.x as i32)
|
||||
{
|
||||
sim.get_mut(wpos / TerrainChunkSize::RECT_SIZE.map(|e| e as i32) + rpos)
|
||||
.map(|chunk| {
|
||||
chunk.surface_veg = 0.0;
|
||||
chunk.path.clear();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let this = Self {
|
||||
origin: wpos,
|
||||
alt: ctx
|
||||
@ -157,6 +144,23 @@ impl Castle {
|
||||
this
|
||||
}
|
||||
|
||||
pub fn contains_point(&self, wpos: Vec2<i32>) -> bool {
|
||||
let lpos = wpos - self.origin;
|
||||
for i in 0..self.towers.len() {
|
||||
let tower0 = &self.towers[i];
|
||||
let tower1 = &self.towers[(i + 1) % self.towers.len()];
|
||||
|
||||
if lpos.determine_side(Vec2::zero(), tower0.offset) > 0
|
||||
&& lpos.determine_side(Vec2::zero(), tower1.offset) <= 0
|
||||
&& lpos.determine_side(tower0.offset, tower1.offset) > 0
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub fn get_origin(&self) -> Vec2<i32> { self.origin }
|
||||
|
||||
pub fn radius(&self) -> f32 { 1200.0 }
|
||||
@ -182,13 +186,38 @@ impl Castle {
|
||||
let wpos2d = wpos2d + offs;
|
||||
let rpos = wpos2d - self.origin;
|
||||
|
||||
// Apply the dungeon entrance
|
||||
if rpos.magnitude_squared() > (self.radius + 64).pow(2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let col_sample = if let Some(col) = get_column(offs) {
|
||||
col
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Inner ground
|
||||
if self.contains_point(wpos2d) {
|
||||
let surface_z = col_sample.alt as i32;
|
||||
for z in -5..3 {
|
||||
let pos = Vec3::new(offs.x, offs.y, surface_z + z);
|
||||
|
||||
if z >= 0 {
|
||||
if vol.get(pos).unwrap().kind() != BlockKind::Water {
|
||||
let _ = vol.set(pos, Block::empty());
|
||||
}
|
||||
} else {
|
||||
let _ = vol.set(
|
||||
pos,
|
||||
Block::new(
|
||||
BlockKind::Normal,
|
||||
col_sample.sub_surface_color.map(|e| (e * 255.0) as u8),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (wall_dist, wall_pos, wall_alt, wall_ori, towers) = (0..self.towers.len())
|
||||
.map(|i| {
|
||||
let tower0 = &self.towers[i];
|
||||
|
@ -35,7 +35,9 @@ pub struct Economy {
|
||||
pub surplus: MapVec<Good, f32>,
|
||||
pub marginal_surplus: MapVec<Good, f32>,
|
||||
pub values: MapVec<Good, Option<f32>>,
|
||||
pub prices: MapVec<Good, f32>,
|
||||
|
||||
pub labor_values: MapVec<Good, f32>,
|
||||
pub material_costs: MapVec<Good, f32>,
|
||||
|
||||
pub labors: MapVec<Labor, f32>,
|
||||
pub yields: MapVec<Labor, f32>,
|
||||
@ -51,7 +53,9 @@ impl Default for Economy {
|
||||
surplus: Default::default(),
|
||||
marginal_surplus: Default::default(),
|
||||
values: Default::default(),
|
||||
prices: Default::default(),
|
||||
|
||||
labor_values: Default::default(),
|
||||
material_costs: Default::default(),
|
||||
|
||||
labors: Default::default(),
|
||||
yields: Default::default(),
|
||||
|
@ -12,28 +12,60 @@ use common::{
|
||||
use rand::prelude::*;
|
||||
use vek::*;
|
||||
|
||||
const COLOR_THEMES: [Rgb<u8>; 17] = [
|
||||
Rgb::new(0x1D, 0x4D, 0x45),
|
||||
Rgb::new(0xB3, 0x7D, 0x60),
|
||||
Rgb::new(0xAC, 0x5D, 0x26),
|
||||
Rgb::new(0x32, 0x46, 0x6B),
|
||||
Rgb::new(0x2B, 0x19, 0x0F),
|
||||
Rgb::new(0x93, 0x78, 0x51),
|
||||
Rgb::new(0x92, 0x57, 0x24),
|
||||
Rgb::new(0x4A, 0x4E, 0x4E),
|
||||
Rgb::new(0x2F, 0x32, 0x47),
|
||||
Rgb::new(0x8F, 0x35, 0x43),
|
||||
Rgb::new(0x6D, 0x1E, 0x3A),
|
||||
Rgb::new(0x6D, 0xA7, 0x80),
|
||||
Rgb::new(0x4F, 0xA0, 0x95),
|
||||
Rgb::new(0xE2, 0xB9, 0x99),
|
||||
Rgb::new(0x7A, 0x30, 0x22),
|
||||
Rgb::new(0x4A, 0x06, 0x08),
|
||||
Rgb::new(0x8E, 0xB4, 0x57),
|
||||
pub struct ColorTheme {
|
||||
roof: Rgb<u8>,
|
||||
wall: Rgb<u8>,
|
||||
support: Rgb<u8>,
|
||||
}
|
||||
|
||||
const ROOF_COLORS: &[Rgb<u8>] = &[
|
||||
// Rgb::new(0x1D, 0x4D, 0x45),
|
||||
// Rgb::new(0xB3, 0x7D, 0x60),
|
||||
// Rgb::new(0xAC, 0x5D, 0x26),
|
||||
// Rgb::new(0x32, 0x46, 0x6B),
|
||||
// Rgb::new(0x2B, 0x19, 0x0F),
|
||||
// Rgb::new(0x93, 0x78, 0x51),
|
||||
// Rgb::new(0x92, 0x57, 0x24),
|
||||
// Rgb::new(0x4A, 0x4E, 0x4E),
|
||||
// Rgb::new(0x2F, 0x32, 0x47),
|
||||
// Rgb::new(0x8F, 0x35, 0x43),
|
||||
// Rgb::new(0x6D, 0x1E, 0x3A),
|
||||
// Rgb::new(0x6D, 0xA7, 0x80),
|
||||
// Rgb::new(0x4F, 0xA0, 0x95),
|
||||
// Rgb::new(0xE2, 0xB9, 0x99),
|
||||
// Rgb::new(0x7A, 0x30, 0x22),
|
||||
// Rgb::new(0x4A, 0x06, 0x08),
|
||||
// Rgb::new(0x8E, 0xB4, 0x57),
|
||||
Rgb::new(0x99, 0x5E, 0x54),
|
||||
Rgb::new(0x43, 0x63, 0x64),
|
||||
Rgb::new(0x76, 0x6D, 0x68),
|
||||
Rgb::new(0x7B, 0x41, 0x61),
|
||||
Rgb::new(0x52, 0x20, 0x20),
|
||||
Rgb::new(0x1A, 0x4A, 0x59),
|
||||
Rgb::new(0xCC, 0x76, 0x4E),
|
||||
];
|
||||
|
||||
const WALL_COLORS: &[Rgb<u8>] = &[
|
||||
Rgb::new(200, 180, 150),
|
||||
Rgb::new(0xB8, 0xB4, 0xA4),
|
||||
Rgb::new(0x76, 0x6D, 0x68),
|
||||
Rgb::new(0xF3, 0xC9, 0x8F),
|
||||
Rgb::new(0xD3, 0xB7, 0x99),
|
||||
Rgb::new(0xE1, 0xAB, 0x91),
|
||||
Rgb::new(0x82, 0x57, 0x4C),
|
||||
Rgb::new(0xB9, 0x96, 0x77),
|
||||
Rgb::new(0x6E, 0x4D, 0x3C),
|
||||
];
|
||||
|
||||
const SUPPORT_COLORS: &[Rgb<u8>] = &[
|
||||
Rgb::new(60, 45, 30),
|
||||
Rgb::new(0x65, 0x55, 0x56),
|
||||
Rgb::new(0x53, 0x33, 0x13),
|
||||
Rgb::new(0x58, 0x42, 0x33),
|
||||
];
|
||||
|
||||
pub struct House {
|
||||
pub roof_color: Rgb<u8>,
|
||||
pub colors: ColorTheme,
|
||||
pub noise: RandomField,
|
||||
pub roof_ribbing: bool,
|
||||
pub roof_ribbing_diagonal: bool,
|
||||
@ -126,6 +158,7 @@ impl Archetype for House {
|
||||
let len = rng.gen_range(-8, 24).clamped(0, 20);
|
||||
let locus = 6 + rng.gen_range(0, 5);
|
||||
let branches_per_side = 1 + len as usize / 20;
|
||||
let levels = rng.gen_range(1, 3);
|
||||
let skel = Skeleton {
|
||||
offset: -rng.gen_range(0, len + 7).clamped(0, len),
|
||||
ori: if rng.gen() { Ori::East } else { Ori::North },
|
||||
@ -139,7 +172,7 @@ impl Archetype for House {
|
||||
1 => Pillar::Tower(5 + rng.gen_range(1, 5)),
|
||||
_ => Pillar::None,
|
||||
},
|
||||
levels: rng.gen_range(1, 4),
|
||||
levels,
|
||||
..Attr::generate(rng, locus)
|
||||
},
|
||||
locus,
|
||||
@ -154,7 +187,10 @@ impl Archetype for House {
|
||||
i as i32 * len / (branches_per_side - 1).max(1) as i32,
|
||||
Branch {
|
||||
len: rng.gen_range(8, 16) * flip,
|
||||
attr: Attr::generate(rng, locus),
|
||||
attr: Attr {
|
||||
levels: rng.gen_range(1, 4).min(levels),
|
||||
..Attr::generate(rng, locus)
|
||||
},
|
||||
locus: (6 + rng.gen_range(0, 3)).min(locus),
|
||||
border: 4,
|
||||
children: Vec::new(),
|
||||
@ -169,7 +205,11 @@ impl Archetype for House {
|
||||
};
|
||||
|
||||
let this = Self {
|
||||
roof_color: *COLOR_THEMES.choose(rng).unwrap(),
|
||||
colors: ColorTheme {
|
||||
roof: *ROOF_COLORS.choose(rng).unwrap(),
|
||||
wall: *WALL_COLORS.choose(rng).unwrap(),
|
||||
support: *SUPPORT_COLORS.choose(rng).unwrap(),
|
||||
},
|
||||
noise: RandomField::new(rng.gen()),
|
||||
roof_ribbing: rng.gen(),
|
||||
roof_ribbing_diagonal: rng.gen(),
|
||||
@ -205,7 +245,7 @@ impl Archetype for House {
|
||||
)
|
||||
};
|
||||
|
||||
let make_block = |r, g, b| {
|
||||
let make_block = |(r, g, b)| {
|
||||
let nz = self
|
||||
.noise
|
||||
.get(Vec3::new(center_offset.x, center_offset.y, z * 8));
|
||||
@ -225,12 +265,11 @@ impl Archetype for House {
|
||||
let foundation_layer = internal_layer + 1;
|
||||
let floor_layer = foundation_layer + 1;
|
||||
|
||||
let foundation = make_block(100, 100, 100).with_priority(foundation_layer);
|
||||
let log = make_block(60, 45, 30);
|
||||
let floor = make_block(100, 75, 50);
|
||||
let wall = make_block(200, 180, 150).with_priority(facade_layer);
|
||||
let roof = make_block(self.roof_color.r, self.roof_color.g, self.roof_color.b)
|
||||
.with_priority(facade_layer - 1);
|
||||
let foundation = make_block((100, 100, 100)).with_priority(foundation_layer);
|
||||
let log = make_block(self.colors.support.into_tuple());
|
||||
let floor = make_block((100, 75, 50));
|
||||
let wall = make_block(self.colors.wall.into_tuple()).with_priority(facade_layer);
|
||||
let roof = make_block(self.colors.roof.into_tuple()).with_priority(facade_layer - 1);
|
||||
let empty = BlockMask::nothing();
|
||||
let internal = BlockMask::new(Block::empty(), internal_layer);
|
||||
let end_window = BlockMask::new(
|
||||
|
@ -2,15 +2,15 @@ pub mod archetype;
|
||||
pub mod skeleton;
|
||||
|
||||
// Reexports
|
||||
pub use self::{archetype::Archetype, skeleton::*};
|
||||
pub use self::{
|
||||
archetype::{house::House, keep::Keep, Archetype},
|
||||
skeleton::*,
|
||||
};
|
||||
|
||||
use common::terrain::Block;
|
||||
use rand::prelude::*;
|
||||
use vek::*;
|
||||
|
||||
pub type HouseBuilding = Building<archetype::house::House>;
|
||||
pub type KeepBuilding = Building<archetype::keep::Keep>;
|
||||
|
||||
pub struct Building<A: Archetype> {
|
||||
skel: Skeleton<A::Attr>,
|
||||
archetype: A,
|
||||
|
@ -2,7 +2,7 @@ pub mod building;
|
||||
mod town;
|
||||
|
||||
use self::{
|
||||
building::{HouseBuilding, KeepBuilding},
|
||||
building::{Building, House, Keep},
|
||||
town::{District, Town},
|
||||
};
|
||||
use super::SpawnRules;
|
||||
@ -86,8 +86,8 @@ const AREA_SIZE: u32 = 32;
|
||||
fn to_tile(e: i32) -> i32 { ((e as f32).div_euclid(AREA_SIZE as f32)).floor() as i32 }
|
||||
|
||||
pub enum StructureKind {
|
||||
House(HouseBuilding),
|
||||
Keep(KeepBuilding),
|
||||
House(Building<House>),
|
||||
Keep(Building<Keep>),
|
||||
}
|
||||
|
||||
pub struct Structure {
|
||||
@ -403,12 +403,12 @@ impl Settlement {
|
||||
|
||||
let structure = Structure {
|
||||
kind: if tile == town_center && i == 0 {
|
||||
StructureKind::Keep(KeepBuilding::generate(
|
||||
StructureKind::Keep(Building::<Keep>::generate(
|
||||
ctx.rng,
|
||||
Vec3::new(house_pos.x, house_pos.y, alt),
|
||||
))
|
||||
} else {
|
||||
StructureKind::House(HouseBuilding::generate(
|
||||
StructureKind::House(Building::<House>::generate(
|
||||
ctx.rng,
|
||||
Vec3::new(house_pos.x, house_pos.y, alt),
|
||||
))
|
||||
@ -671,94 +671,79 @@ impl Settlement {
|
||||
}))
|
||||
},
|
||||
Some(Plot::Field { seed, crop, .. }) => {
|
||||
if let Some(color) = col_sample.path.and_then(|(dist, _, path, _)| {
|
||||
if dist < path.width {
|
||||
Some(path.surface_color(
|
||||
col_sample.sub_surface_color.map(|e| (e * 255.0) as u8),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
Some(color)
|
||||
} else {
|
||||
let furrow_dirs = [
|
||||
Vec2::new(1, 0),
|
||||
Vec2::new(0, 1),
|
||||
Vec2::new(1, 1),
|
||||
Vec2::new(-1, 1),
|
||||
];
|
||||
let furrow_dir = furrow_dirs[*seed as usize % furrow_dirs.len()];
|
||||
let in_furrow = (wpos2d * furrow_dir).sum().rem_euclid(5) < 2;
|
||||
let furrow_dirs = [
|
||||
Vec2::new(1, 0),
|
||||
Vec2::new(0, 1),
|
||||
Vec2::new(1, 1),
|
||||
Vec2::new(-1, 1),
|
||||
];
|
||||
let furrow_dir = furrow_dirs[*seed as usize % furrow_dirs.len()];
|
||||
let in_furrow = (wpos2d * furrow_dir).sum().rem_euclid(5) < 2;
|
||||
|
||||
let dirt = Rgb::new(80, 55, 35).map(|e| {
|
||||
e + (self.noise.get(Vec3::broadcast((seed % 4096 + 0) as i32))
|
||||
let dirt = Rgb::new(80, 55, 35).map(|e| {
|
||||
e + (self.noise.get(Vec3::broadcast((seed % 4096 + 0) as i32)) % 32)
|
||||
as u8
|
||||
});
|
||||
let mound =
|
||||
Rgb::new(70, 80, 30).map(|e| e + roll(0, 8) as u8).map(|e| {
|
||||
e + (self.noise.get(Vec3::broadcast((seed % 4096 + 1) as i32))
|
||||
% 32) as u8
|
||||
});
|
||||
let mound =
|
||||
Rgb::new(70, 80, 30).map(|e| e + roll(0, 8) as u8).map(|e| {
|
||||
e + (self
|
||||
.noise
|
||||
.get(Vec3::broadcast((seed % 4096 + 1) as i32))
|
||||
% 32) as u8
|
||||
});
|
||||
|
||||
if in_furrow {
|
||||
if roll(0, 5) == 0 {
|
||||
surface_block = match crop {
|
||||
Crop::Corn => Some(BlockKind::Corn),
|
||||
Crop::Wheat if roll(1, 2) == 0 => {
|
||||
Some(BlockKind::WheatYellow)
|
||||
},
|
||||
Crop::Wheat => Some(BlockKind::WheatGreen),
|
||||
Crop::Cabbage if roll(2, 2) == 0 => {
|
||||
Some(BlockKind::Cabbage)
|
||||
},
|
||||
Crop::Pumpkin if roll(3, 2) == 0 => {
|
||||
Some(BlockKind::Pumpkin)
|
||||
},
|
||||
Crop::Flax if roll(4, 2) == 0 => Some(BlockKind::Flax),
|
||||
Crop::Carrot if roll(5, 2) == 0 => {
|
||||
Some(BlockKind::Carrot)
|
||||
},
|
||||
Crop::Tomato if roll(6, 2) == 0 => {
|
||||
Some(BlockKind::Tomato)
|
||||
},
|
||||
Crop::Radish if roll(7, 2) == 0 => {
|
||||
Some(BlockKind::Radish)
|
||||
},
|
||||
Crop::Turnip if roll(8, 2) == 0 => {
|
||||
Some(BlockKind::Turnip)
|
||||
},
|
||||
Crop::Sunflower => Some(BlockKind::Sunflower),
|
||||
_ => None,
|
||||
}
|
||||
.or_else(|| {
|
||||
if roll(9, 400) == 0 {
|
||||
Some(BlockKind::Scarecrow)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|kind| Block::new(kind, Rgb::white()));
|
||||
if in_furrow {
|
||||
if roll(0, 5) == 0 {
|
||||
surface_block = match crop {
|
||||
Crop::Corn => Some(BlockKind::Corn),
|
||||
Crop::Wheat if roll(1, 2) == 0 => {
|
||||
Some(BlockKind::WheatYellow)
|
||||
},
|
||||
Crop::Wheat => Some(BlockKind::WheatGreen),
|
||||
Crop::Cabbage if roll(2, 2) == 0 => {
|
||||
Some(BlockKind::Cabbage)
|
||||
},
|
||||
Crop::Pumpkin if roll(3, 2) == 0 => {
|
||||
Some(BlockKind::Pumpkin)
|
||||
},
|
||||
Crop::Flax if roll(4, 2) == 0 => Some(BlockKind::Flax),
|
||||
Crop::Carrot if roll(5, 2) == 0 => Some(BlockKind::Carrot),
|
||||
Crop::Tomato if roll(6, 2) == 0 => Some(BlockKind::Tomato),
|
||||
Crop::Radish if roll(7, 2) == 0 => Some(BlockKind::Radish),
|
||||
Crop::Turnip if roll(8, 2) == 0 => Some(BlockKind::Turnip),
|
||||
Crop::Sunflower => Some(BlockKind::Sunflower),
|
||||
_ => None,
|
||||
}
|
||||
} else if roll(0, 20) == 0 {
|
||||
surface_block =
|
||||
Some(Block::new(BlockKind::ShortGrass, Rgb::white()));
|
||||
} else if roll(1, 30) == 0 {
|
||||
surface_block =
|
||||
Some(Block::new(BlockKind::MediumGrass, Rgb::white()));
|
||||
.or_else(|| {
|
||||
if roll(9, 400) == 0 {
|
||||
Some(BlockKind::Scarecrow)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|kind| Block::new(kind, Rgb::white()));
|
||||
}
|
||||
|
||||
Some(if in_furrow { dirt } else { mound })
|
||||
} else if roll(0, 20) == 0 {
|
||||
surface_block =
|
||||
Some(Block::new(BlockKind::ShortGrass, Rgb::white()));
|
||||
} else if roll(1, 30) == 0 {
|
||||
surface_block =
|
||||
Some(Block::new(BlockKind::MediumGrass, Rgb::white()));
|
||||
}
|
||||
|
||||
Some(if in_furrow { dirt } else { mound })
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(color) = color {
|
||||
if col_sample.water_dist.map(|dist| dist > 2.0).unwrap_or(true) {
|
||||
let is_path = col_sample
|
||||
.path
|
||||
.map(|(dist, _, path, _)| dist < path.width)
|
||||
.unwrap_or(false);
|
||||
|
||||
if col_sample.water_dist.map(|dist| dist > 2.0).unwrap_or(true) && !is_path
|
||||
{
|
||||
let diff = (surface_z - land_surface_z).abs();
|
||||
|
||||
for z in -8 - diff..3 + diff {
|
||||
let pos = Vec3::new(offs.x, offs.y, surface_z + z);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user