mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
clifftown_relocation
This commit is contained in:
parent
659113830e
commit
daff899f37
@ -439,7 +439,7 @@ impl Civs {
|
|||||||
SiteKind::Dungeon => (8i32, 3.0),
|
SiteKind::Dungeon => (8i32, 3.0),
|
||||||
SiteKind::Castle => (16i32, 5.0),
|
SiteKind::Castle => (16i32, 5.0),
|
||||||
SiteKind::Refactor => (32i32, 10.0),
|
SiteKind::Refactor => (32i32, 10.0),
|
||||||
SiteKind::CliffTown => (64i32, 25.0),
|
SiteKind::CliffTown => (2i32, 1.0),
|
||||||
SiteKind::SavannahPit => (48i32, 25.0),
|
SiteKind::SavannahPit => (48i32, 25.0),
|
||||||
SiteKind::CoastalTown => (64i32, 35.0),
|
SiteKind::CoastalTown => (64i32, 35.0),
|
||||||
SiteKind::JungleRuin => (8i32, 3.0),
|
SiteKind::JungleRuin => (8i32, 3.0),
|
||||||
@ -546,6 +546,7 @@ impl Civs {
|
|||||||
},
|
},
|
||||||
SiteKind::CliffTown => WorldSite::cliff_town(site2::Site::generate_cliff_town(
|
SiteKind::CliffTown => WorldSite::cliff_town(site2::Site::generate_cliff_town(
|
||||||
&Land::from_sim(ctx.sim),
|
&Land::from_sim(ctx.sim),
|
||||||
|
index_ref,
|
||||||
&mut rng,
|
&mut rng,
|
||||||
wpos,
|
wpos,
|
||||||
)),
|
)),
|
||||||
@ -1793,6 +1794,7 @@ fn town_attributes_of_site(loc: Vec2<i32>, sim: &WorldSim) -> Option<TownSiteAtt
|
|||||||
let has_lake = lake_chunks > 1;
|
let has_lake = lake_chunks > 1;
|
||||||
let vegetation_implies_potable_water = chunk.tree_density > 0.4
|
let vegetation_implies_potable_water = chunk.tree_density > 0.4
|
||||||
&& !matches!(chunk.get_biome(), common::terrain::BiomeKind::Swamp);
|
&& !matches!(chunk.get_biome(), common::terrain::BiomeKind::Swamp);
|
||||||
|
let has_many_rocks = chunk.rockiness > 1.2;
|
||||||
let warm_or_firewood = chunk.temp > CONFIG.snow_temp || tree_chunks > 2;
|
let warm_or_firewood = chunk.temp > CONFIG.snow_temp || tree_chunks > 2;
|
||||||
let has_potable_water =
|
let has_potable_water =
|
||||||
{ has_river || (has_lake && chunk.alt > 100.0) || vegetation_implies_potable_water };
|
{ has_river || (has_lake && chunk.alt > 100.0) || vegetation_implies_potable_water };
|
||||||
@ -1825,6 +1827,7 @@ fn town_attributes_of_site(loc: Vec2<i32>, sim: &WorldSim) -> Option<TownSiteAtt
|
|||||||
heating: warm_or_firewood,
|
heating: warm_or_firewood,
|
||||||
potable_water: has_potable_water,
|
potable_water: has_potable_water,
|
||||||
building_materials: has_building_materials,
|
building_materials: has_building_materials,
|
||||||
|
aquifer: has_many_rocks,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1837,6 +1840,7 @@ pub struct TownSiteAttributes {
|
|||||||
heating: bool,
|
heating: bool,
|
||||||
potable_water: bool,
|
potable_water: bool,
|
||||||
building_materials: bool,
|
building_materials: bool,
|
||||||
|
aquifer: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TownSiteAttributes {
|
impl TownSiteAttributes {
|
||||||
@ -1942,7 +1946,8 @@ impl SiteKind {
|
|||||||
let suitable_for_town = || -> bool {
|
let suitable_for_town = || -> bool {
|
||||||
let attributes = town_attributes_of_site(loc, sim);
|
let attributes = town_attributes_of_site(loc, sim);
|
||||||
attributes.map_or(false, |attributes| {
|
attributes.map_or(false, |attributes| {
|
||||||
attributes.potable_water
|
// aquifer and has_many_rocks was added to make mesa clifftowns suitable for towns
|
||||||
|
(attributes.potable_water || (attributes.aquifer && matches!(self, SiteKind::CliffTown)))
|
||||||
&& attributes.building_materials
|
&& attributes.building_materials
|
||||||
&& attributes.heating
|
&& attributes.heating
|
||||||
// Because of how the algorithm for site2 towns work, they have to start on land.
|
// Because of how the algorithm for site2 towns work, they have to start on land.
|
||||||
@ -1971,9 +1976,9 @@ impl SiteKind {
|
|||||||
},
|
},
|
||||||
SiteKind::Citadel => true,
|
SiteKind::Citadel => true,
|
||||||
SiteKind::CliffTown => {
|
SiteKind::CliffTown => {
|
||||||
(-0.6..0.4).contains(&chunk.temp)
|
chunk.temp >= CONFIG.desert_temp
|
||||||
&& chunk.near_cliffs()
|
&& chunk.cliff_height > 40.0
|
||||||
&& !chunk.river.near_water()
|
&& chunk.rockiness > 1.2
|
||||||
&& suitable_for_town()
|
&& suitable_for_town()
|
||||||
},
|
},
|
||||||
SiteKind::SavannahPit => {
|
SiteKind::SavannahPit => {
|
||||||
|
@ -924,7 +924,12 @@ impl Site {
|
|||||||
site
|
site
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_cliff_town(land: &Land, rng: &mut impl Rng, origin: Vec2<i32>) -> Self {
|
pub fn generate_cliff_town(
|
||||||
|
land: &Land,
|
||||||
|
index: IndexRef,
|
||||||
|
rng: &mut impl Rng,
|
||||||
|
origin: Vec2<i32>,
|
||||||
|
) -> Self {
|
||||||
let mut rng = reseed(rng);
|
let mut rng = reseed(rng);
|
||||||
let mut site = Site {
|
let mut site = Site {
|
||||||
origin,
|
origin,
|
||||||
@ -935,13 +940,14 @@ impl Site {
|
|||||||
site.make_plaza(land, &mut rng);
|
site.make_plaza(land, &mut rng);
|
||||||
for _ in 0..30 {
|
for _ in 0..30 {
|
||||||
// CliffTower
|
// CliffTower
|
||||||
let size = (8.0 + rng.gen::<f32>().powf(5.0) * 1.0).round() as u32;
|
let size = (9.0 + rng.gen::<f32>().powf(5.0) * 1.0).round() as u32;
|
||||||
let campfire = campfires < 4;
|
let campfire = campfires < 4;
|
||||||
if let Some((aabr, door_tile, door_dir)) = attempt(32, || {
|
if let Some((aabr, door_tile, door_dir)) = attempt(32, || {
|
||||||
site.find_roadside_aabr(&mut rng, 8..(size + 1).pow(2), Extent2::broadcast(size))
|
site.find_roadside_aabr(&mut rng, 8..(size + 1).pow(2), Extent2::broadcast(size))
|
||||||
}) {
|
}) {
|
||||||
let cliff_tower = plot::CliffTower::generate(
|
let cliff_tower = plot::CliffTower::generate(
|
||||||
land,
|
land,
|
||||||
|
index,
|
||||||
&mut reseed(&mut rng),
|
&mut reseed(&mut rng),
|
||||||
&site,
|
&site,
|
||||||
door_tile,
|
door_tile,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
site2::util::gradient::WrapMode,
|
||||||
util::{RandomField, Sampler, DIAGONALS, LOCALITY},
|
util::{RandomField, Sampler, DIAGONALS, LOCALITY},
|
||||||
Land,
|
Land,
|
||||||
};
|
};
|
||||||
@ -8,7 +9,7 @@ use common::{
|
|||||||
terrain::{BlockKind, SpriteKind},
|
terrain::{BlockKind, SpriteKind},
|
||||||
};
|
};
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use std::{f32::consts::TAU, mem, sync::Arc};
|
use std::{f32::consts::TAU, mem};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
/// Represents house data generated by the `generate()` method
|
/// Represents house data generated by the `generate()` method
|
||||||
@ -21,11 +22,14 @@ pub struct CliffTower {
|
|||||||
pub(crate) alt: i32,
|
pub(crate) alt: i32,
|
||||||
campfire: bool,
|
campfire: bool,
|
||||||
door_dir: Vec2<i32>,
|
door_dir: Vec2<i32>,
|
||||||
|
surface_color: Rgb<f32>,
|
||||||
|
sub_surface_color: Rgb<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CliffTower {
|
impl CliffTower {
|
||||||
pub fn generate(
|
pub fn generate(
|
||||||
land: &Land,
|
land: &Land,
|
||||||
|
index: IndexRef,
|
||||||
_rng: &mut impl Rng,
|
_rng: &mut impl Rng,
|
||||||
site: &Site,
|
site: &Site,
|
||||||
door_tile: Vec2<i32>,
|
door_tile: Vec2<i32>,
|
||||||
@ -38,12 +42,20 @@ impl CliffTower {
|
|||||||
min: site.tile_wpos(tile_aabr.min),
|
min: site.tile_wpos(tile_aabr.min),
|
||||||
max: site.tile_wpos(tile_aabr.max),
|
max: site.tile_wpos(tile_aabr.max),
|
||||||
};
|
};
|
||||||
|
let (surface_color, sub_surface_color) =
|
||||||
|
if let Some(sample) = land.column_sample(bounds.center(), index) {
|
||||||
|
(sample.surface_color, sample.sub_surface_color)
|
||||||
|
} else {
|
||||||
|
(Rgb::new(161.0, 116.0, 86.0), Rgb::new(88.0, 64.0, 64.0))
|
||||||
|
};
|
||||||
Self {
|
Self {
|
||||||
door_tile: door_tile_pos,
|
door_tile: door_tile_pos,
|
||||||
bounds,
|
bounds,
|
||||||
alt: land.get_alt_approx(site.tile_center_wpos(door_tile + door_dir)) as i32,
|
alt: land.get_alt_approx(door_tile_pos) as i32,
|
||||||
campfire,
|
campfire,
|
||||||
door_dir,
|
door_dir,
|
||||||
|
surface_color,
|
||||||
|
sub_surface_color,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,9 +66,41 @@ impl Structure for CliffTower {
|
|||||||
|
|
||||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "render_clifftower")]
|
#[cfg_attr(feature = "be-dyn-lib", export_name = "render_clifftower")]
|
||||||
fn render_inner(&self, _site: &Site, _land: &Land, painter: &Painter) {
|
fn render_inner(&self, _site: &Site, _land: &Land, painter: &Painter) {
|
||||||
let base = self.alt + 1;
|
let base = self.alt;
|
||||||
let plot_center = self.bounds.center();
|
let plot_center = self.bounds.center();
|
||||||
let door_dir = self.door_dir;
|
let door_dir = self.door_dir;
|
||||||
|
|
||||||
|
let surface_color = self.surface_color.map(|e| (e * 255.0) as u8);
|
||||||
|
let sub_surface_color = self.sub_surface_color.map(|e| (e * 255.0) as u8);
|
||||||
|
let gradient_center = Vec3::new(
|
||||||
|
plot_center.x as f32,
|
||||||
|
plot_center.y as f32,
|
||||||
|
(base + 1) as f32,
|
||||||
|
);
|
||||||
|
let gradient_var_1 = RandomField::new(0).get(plot_center.with_z(base)) as i32 % 8;
|
||||||
|
let gradient_var_2 = RandomField::new(0).get(plot_center.with_z(base + 1)) as i32 % 10;
|
||||||
|
|
||||||
|
let brick = Fill::Gradient(
|
||||||
|
util::gradient::Gradient::new(
|
||||||
|
gradient_center,
|
||||||
|
8.0 + gradient_var_1 as f32,
|
||||||
|
util::gradient::Shape::Point,
|
||||||
|
(surface_color, sub_surface_color),
|
||||||
|
)
|
||||||
|
.with_repeat(if gradient_var_2 > 5 {
|
||||||
|
WrapMode::Repeat
|
||||||
|
} else {
|
||||||
|
WrapMode::PingPong
|
||||||
|
}),
|
||||||
|
BlockKind::Rock,
|
||||||
|
);
|
||||||
|
|
||||||
|
let wood = Fill::Brick(BlockKind::Wood, Rgb::new(106, 83, 51), 12);
|
||||||
|
let color = Fill::Block(Block::air(SpriteKind::CliffDecorBlock));
|
||||||
|
let window = Fill::Block(Block::air(SpriteKind::WindowArabic));
|
||||||
|
let window2 = Fill::Block(Block::air(SpriteKind::WindowArabic).with_ori(2).unwrap());
|
||||||
|
let rope = Fill::Block(Block::air(SpriteKind::Rope));
|
||||||
|
|
||||||
let tube_var = RandomField::new(0).get(plot_center.with_z(base)) as i32 % 6;
|
let tube_var = RandomField::new(0).get(plot_center.with_z(base)) as i32 % 6;
|
||||||
let radius = 10.0 + tube_var as f32;
|
let radius = 10.0 + tube_var as f32;
|
||||||
let tubes = 3.0 + tube_var as f32;
|
let tubes = 3.0 + tube_var as f32;
|
||||||
@ -77,39 +121,12 @@ impl Structure for CliffTower {
|
|||||||
let mut height = 18 + variant / 2;
|
let mut height = 18 + variant / 2;
|
||||||
let mut floor_level = base - 40;
|
let mut floor_level = base - 40;
|
||||||
let mut workshops = 0;
|
let mut workshops = 0;
|
||||||
let mut ground_entry = 0;
|
let mut ground_entries = 0;
|
||||||
let brick = Fill::Sampling(Arc::new(|variant_pos| {
|
for s in 0..storeys {
|
||||||
Some(
|
|
||||||
match (RandomField::new(0).get(Vec3::new(variant_pos.z, 0, 0))) % 15 {
|
|
||||||
0 => Block::new(BlockKind::Rock, Rgb::new(51, 89, 118)),
|
|
||||||
1 => Block::new(BlockKind::Rock, Rgb::new(57, 96, 126)),
|
|
||||||
2 => Block::new(BlockKind::Rock, Rgb::new(59, 103, 136)),
|
|
||||||
3 => Block::new(BlockKind::Rock, Rgb::new(61, 109, 145)),
|
|
||||||
4 => Block::new(BlockKind::Rock, Rgb::new(42, 66, 87)),
|
|
||||||
5 => Block::new(BlockKind::Rock, Rgb::new(47, 76, 101)),
|
|
||||||
6 => Block::new(BlockKind::Rock, Rgb::new(50, 84, 110)),
|
|
||||||
7 => Block::new(BlockKind::Rock, Rgb::new(52, 85, 112)),
|
|
||||||
8 => Block::new(BlockKind::Rock, Rgb::new(51, 60, 66)),
|
|
||||||
9 => Block::new(BlockKind::Rock, Rgb::new(58, 74, 87)),
|
|
||||||
10 => Block::new(BlockKind::Rock, Rgb::new(53, 104, 111)),
|
|
||||||
11 => Block::new(BlockKind::Rock, Rgb::new(52, 63, 72)),
|
|
||||||
12 => Block::new(BlockKind::Rock, Rgb::new(52, 63, 72)),
|
|
||||||
13 => Block::new(BlockKind::Rock, Rgb::new(74, 128, 168)),
|
|
||||||
_ => Block::new(BlockKind::Rock, Rgb::new(69, 123, 162)),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}));
|
|
||||||
let wood = Fill::Brick(BlockKind::Wood, Rgb::new(106, 83, 51), 12);
|
|
||||||
let color = Fill::Block(Block::air(SpriteKind::CliffDecorBlock));
|
|
||||||
let window = Fill::Block(Block::air(SpriteKind::WindowArabic));
|
|
||||||
let window2 = Fill::Block(Block::air(SpriteKind::WindowArabic).with_ori(2).unwrap());
|
|
||||||
let rope = Fill::Block(Block::air(SpriteKind::Rope));
|
|
||||||
for _ in 0..storeys {
|
|
||||||
let x_offset = RandomField::new(0).get((center - length).with_z(base)) as i32 % 10;
|
let x_offset = RandomField::new(0).get((center - length).with_z(base)) as i32 % 10;
|
||||||
let y_offset = RandomField::new(0).get((center + length).with_z(base)) as i32 % 10;
|
let y_offset = RandomField::new(0).get((center + length).with_z(base)) as i32 % 10;
|
||||||
let super_center =
|
let super_center =
|
||||||
Vec2::new(center.x - 3 + x_offset / 2, center.y - 3 + y_offset / 2);
|
Vec2::new(center.x - 3 + x_offset / 2, center.y - 3 + y_offset / 2);
|
||||||
|
|
||||||
// CliffTower Hoodoo Overlay
|
// CliffTower Hoodoo Overlay
|
||||||
painter
|
painter
|
||||||
.cubic_bezier(
|
.cubic_bezier(
|
||||||
@ -120,8 +137,52 @@ impl Structure for CliffTower {
|
|||||||
(length - 1) as f32,
|
(length - 1) as f32,
|
||||||
)
|
)
|
||||||
.fill(brick.clone());
|
.fill(brick.clone());
|
||||||
|
if s == (storeys - 1) {
|
||||||
|
for dir in LOCALITY {
|
||||||
|
let cone_pos = super_center + (dir * 2);
|
||||||
|
let cone_var =
|
||||||
|
4 + RandomField::new(0).get(cone_pos.with_z(base)) as i32 % 4;
|
||||||
|
painter
|
||||||
|
.cone_with_radius(
|
||||||
|
cone_pos.with_z(floor_level + (2 * height) + 5),
|
||||||
|
(length / 2) as f32,
|
||||||
|
(length + cone_var) as f32,
|
||||||
|
)
|
||||||
|
.fill(brick.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
// center tube with rooms
|
// center tube with rooms
|
||||||
if n == tubes as i32 {
|
if n == tubes as i32 {
|
||||||
|
// ground_entries
|
||||||
|
if ground_entries < 1 && floor_level > (base - 6) {
|
||||||
|
for dir in CARDINALS {
|
||||||
|
let entry_pos_inner = plot_center + (dir * (2 * length) - 4);
|
||||||
|
let entry_pos_outer = plot_center + (dir * (3 * length) + 4);
|
||||||
|
painter
|
||||||
|
.line(
|
||||||
|
entry_pos_inner.with_z(floor_level + 6),
|
||||||
|
entry_pos_outer.with_z(base + 35),
|
||||||
|
6.0,
|
||||||
|
)
|
||||||
|
.clear();
|
||||||
|
}
|
||||||
|
let door_start = plot_center + door_dir * ((3 * (length / 2)) + 1);
|
||||||
|
painter
|
||||||
|
.line(
|
||||||
|
door_start.with_z(floor_level + 2),
|
||||||
|
self.door_tile.with_z(base),
|
||||||
|
4.0,
|
||||||
|
)
|
||||||
|
.fill(wood.clone());
|
||||||
|
painter
|
||||||
|
.line(
|
||||||
|
door_start.with_z(floor_level + 7),
|
||||||
|
self.door_tile.with_z(base + 6),
|
||||||
|
7.0,
|
||||||
|
)
|
||||||
|
.clear();
|
||||||
|
ground_entries += 1;
|
||||||
|
}
|
||||||
painter
|
painter
|
||||||
.cubic_bezier(
|
.cubic_bezier(
|
||||||
plot_center.with_z(floor_level + (height / 2)),
|
plot_center.with_z(floor_level + (height / 2)),
|
||||||
@ -719,27 +780,6 @@ impl Structure for CliffTower {
|
|||||||
})
|
})
|
||||||
.fill(rope.clone());
|
.fill(rope.clone());
|
||||||
}
|
}
|
||||||
if floor_level > (base - 6) {
|
|
||||||
// ensure ground entry toward door_dir
|
|
||||||
if ground_entry < 1 {
|
|
||||||
let door_start = plot_center + door_dir * ((3 * (length / 2)) + 1);
|
|
||||||
let door_end = plot_center + door_dir * ((3 * length) - 1);
|
|
||||||
|
|
||||||
for n in 0..2 {
|
|
||||||
let door_stairs = painter.line(
|
|
||||||
door_start.with_z(floor_level + 1 + (n * 2)),
|
|
||||||
door_end.with_z(base + (n * 2)),
|
|
||||||
4.0 + (n as f32 / 2.0),
|
|
||||||
);
|
|
||||||
door_stairs.fill(wood.clone());
|
|
||||||
match n {
|
|
||||||
0 => door_stairs.fill(wood.clone()),
|
|
||||||
_ => door_stairs.clear(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
ground_entry += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// vary next storey
|
// vary next storey
|
||||||
length += -1;
|
length += -1;
|
||||||
|
Loading…
Reference in New Issue
Block a user