mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Began adding castles
This commit is contained in:
parent
1f4cec773b
commit
d6cdb0c433
@ -298,6 +298,11 @@ impl ChatCommand {
|
||||
"View the server description",
|
||||
NoAdmin,
|
||||
),
|
||||
ChatCommand::MakeBlock => cmd(
|
||||
vec![Enum("block", BLOCK_KINDS.clone(), Required)],
|
||||
"Make a block",
|
||||
Admin,
|
||||
),
|
||||
ChatCommand::Object => cmd(
|
||||
vec![Enum("object", OBJECTS.clone(), Required)],
|
||||
"Spawn an object",
|
||||
|
@ -1,13 +1,8 @@
|
||||
use crate::vol::Vox;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
ops::Deref,
|
||||
convert::TryFrom,
|
||||
collections::HashMap,
|
||||
fmt,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use enum_iterator::IntoEnumIterator;
|
||||
use lazy_static::lazy_static;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{collections::HashMap, convert::TryFrom, fmt, ops::Deref};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize, IntoEnumIterator)]
|
||||
@ -96,9 +91,7 @@ pub enum BlockKind {
|
||||
}
|
||||
|
||||
impl fmt::Display for BlockKind {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self) }
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
@ -110,9 +103,7 @@ lazy_static! {
|
||||
impl<'a> TryFrom<&'a str> for BlockKind {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(s: &'a str) -> Result<Self, Self::Error> {
|
||||
BLOCK_KINDS.get(s).copied().ok_or(())
|
||||
}
|
||||
fn try_from(s: &'a str) -> Result<Self, Self::Error> { BLOCK_KINDS.get(s).copied().ok_or(()) }
|
||||
}
|
||||
|
||||
impl BlockKind {
|
||||
|
@ -13,16 +13,16 @@ use common::{
|
||||
npc::{self, get_npc_name},
|
||||
state::TimeOfDay,
|
||||
sync::{Uid, WorldSyncExt},
|
||||
terrain::{TerrainChunkSize, Block, BlockKind},
|
||||
terrain::{Block, BlockKind, TerrainChunkSize},
|
||||
util::Dir,
|
||||
vol::{RectVolSize, WriteVol},
|
||||
LoadoutBuilder,
|
||||
};
|
||||
use rand::Rng;
|
||||
use specs::{Builder, Entity as EcsEntity, Join, WorldExt};
|
||||
use std::convert::TryFrom;
|
||||
use vek::*;
|
||||
use world::util::Sampler;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use scan_fmt::{scan_fmt, scan_fmt_some};
|
||||
use tracing::error;
|
||||
|
@ -5,7 +5,7 @@ mod econ;
|
||||
use self::{Occupation::*, Stock::*};
|
||||
use crate::{
|
||||
sim::WorldSim,
|
||||
site::{Dungeon, Settlement, Site as WorldSite},
|
||||
site::{Dungeon, Settlement, Castle, Site as WorldSite},
|
||||
util::{attempt, seed_expan, MapVec, CARDINALS, NEIGHBORS},
|
||||
Index,
|
||||
};
|
||||
@ -86,9 +86,13 @@ impl Civs {
|
||||
|
||||
for _ in 0..INITIAL_CIV_COUNT * 3 {
|
||||
attempt(5, || {
|
||||
let loc = find_site_loc(&mut ctx, None)?;
|
||||
let (kind, size) = match ctx.rng.gen_range(0, 2) {
|
||||
0 => (SiteKind::Dungeon, 0),
|
||||
_ => (SiteKind::Castle, 3),
|
||||
};
|
||||
let loc = find_site_loc(&mut ctx, None, size)?;
|
||||
this.establish_site(&mut ctx.reseed(), loc, |place| Site {
|
||||
kind: SiteKind::Dungeon,
|
||||
kind,
|
||||
center: loc,
|
||||
place,
|
||||
|
||||
@ -125,10 +129,12 @@ impl Civs {
|
||||
let flatten_radius = match &site.kind {
|
||||
SiteKind::Settlement => 8.0,
|
||||
SiteKind::Dungeon => 2.0,
|
||||
SiteKind::Castle => 5.0,
|
||||
};
|
||||
|
||||
let (raise, raise_dist): (f32, i32) = match &site.kind {
|
||||
SiteKind::Settlement => (10.0, 6),
|
||||
SiteKind::Castle => (0.0, 6),
|
||||
_ => (0.0, 0),
|
||||
};
|
||||
|
||||
@ -176,6 +182,9 @@ impl Civs {
|
||||
SiteKind::Dungeon => {
|
||||
WorldSite::dungeon(Dungeon::generate(wpos, Some(ctx.sim), &mut rng))
|
||||
},
|
||||
SiteKind::Castle => {
|
||||
WorldSite::castle(Castle::generate(wpos, Some(ctx.sim), &mut rng))
|
||||
},
|
||||
});
|
||||
let site_ref = &index.sites[site];
|
||||
|
||||
@ -272,7 +281,7 @@ impl Civs {
|
||||
|
||||
fn birth_civ(&mut self, ctx: &mut GenCtx<impl Rng>) -> Option<Id<Civ>> {
|
||||
let site = attempt(5, || {
|
||||
let loc = find_site_loc(ctx, None)?;
|
||||
let loc = find_site_loc(ctx, None, 1)?;
|
||||
self.establish_site(ctx, loc, |place| Site {
|
||||
kind: SiteKind::Settlement,
|
||||
center: loc,
|
||||
@ -367,7 +376,7 @@ impl Civs {
|
||||
loc: Vec2<i32>,
|
||||
site_fn: impl FnOnce(Id<Place>) -> Site,
|
||||
) -> Option<Id<Site>> {
|
||||
const SITE_AREA: Range<usize> = 64..256;
|
||||
const SITE_AREA: Range<usize> = 1..4;//64..256;
|
||||
|
||||
let place = match ctx.sim.get(loc).and_then(|site| site.place) {
|
||||
Some(place) => place,
|
||||
@ -381,12 +390,13 @@ impl Civs {
|
||||
let mut nearby = self
|
||||
.sites
|
||||
.iter()
|
||||
.filter(|(_, p)| matches!(p.kind, SiteKind::Settlement | SiteKind::Castle))
|
||||
.map(|(id, p)| (id, (p.center.distance_squared(loc) as f32).sqrt()))
|
||||
.filter(|(_, dist)| *dist < MAX_NEIGHBOR_DISTANCE)
|
||||
.collect::<Vec<_>>();
|
||||
nearby.sort_by_key(|(_, dist)| *dist as i32);
|
||||
|
||||
if let SiteKind::Settlement = self.sites[site].kind {
|
||||
if let SiteKind::Settlement | SiteKind::Castle = self.sites[site].kind {
|
||||
for (nearby, _) in nearby.into_iter().take(5) {
|
||||
// Find a novel path
|
||||
if let Some((path, cost)) = find_path(ctx, loc, self.sites.get(nearby).center) {
|
||||
@ -589,6 +599,7 @@ fn loc_suitable_for_site(sim: &WorldSim, loc: Vec2<i32>) -> bool {
|
||||
if let Some(chunk) = sim.get(loc) {
|
||||
!chunk.river.is_ocean()
|
||||
&& !chunk.river.is_lake()
|
||||
&& !chunk.river.is_river()
|
||||
&& sim
|
||||
.get_gradient_approx(loc)
|
||||
.map(|grad| grad < 1.0)
|
||||
@ -601,7 +612,7 @@ 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>, near: Option<(Vec2<i32>, f32)>) -> Option<Vec2<i32>> {
|
||||
fn find_site_loc(ctx: &mut GenCtx<impl Rng>, near: Option<(Vec2<i32>, f32)>, size: i32) -> Option<Vec2<i32>> {
|
||||
const MAX_ATTEMPTS: usize = 100;
|
||||
let mut loc = None;
|
||||
for _ in 0..MAX_ATTEMPTS {
|
||||
@ -621,8 +632,10 @@ fn find_site_loc(ctx: &mut GenCtx<impl Rng>, near: Option<(Vec2<i32>, f32)>) ->
|
||||
),
|
||||
});
|
||||
|
||||
if loc_suitable_for_site(&ctx.sim, test_loc) {
|
||||
return Some(test_loc);
|
||||
for offset in Spiral2d::new().take((size * 2 + 1).pow(2) as usize) {
|
||||
if loc_suitable_for_site(&ctx.sim, test_loc + offset) {
|
||||
return Some(test_loc);
|
||||
}
|
||||
}
|
||||
|
||||
loc = ctx.sim.get(test_loc).and_then(|c| {
|
||||
@ -723,10 +736,7 @@ pub struct Site {
|
||||
|
||||
impl fmt::Display for Site {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.kind {
|
||||
SiteKind::Settlement => writeln!(f, "Settlement")?,
|
||||
SiteKind::Dungeon => writeln!(f, "Dungeon")?,
|
||||
}
|
||||
writeln!(f, "{:?}", self.kind)?;
|
||||
writeln!(f, "- population: {}", self.population.floor() as u32)?;
|
||||
writeln!(f, "- coin: {}", self.coin.floor() as u32)?;
|
||||
writeln!(f, "Stocks")?;
|
||||
@ -766,6 +776,7 @@ impl fmt::Display for Site {
|
||||
pub enum SiteKind {
|
||||
Settlement,
|
||||
Dungeon,
|
||||
Castle,
|
||||
}
|
||||
|
||||
impl Site {
|
||||
|
244
world/src/site/castle/mod.rs
Normal file
244
world/src/site/castle/mod.rs
Normal file
@ -0,0 +1,244 @@
|
||||
use super::SpawnRules;
|
||||
use crate::{
|
||||
block::block_from_structure,
|
||||
column::ColumnSample,
|
||||
sim::WorldSim,
|
||||
site::{
|
||||
BlockMask,
|
||||
settlement::building::{Archetype, Ori, Branch, archetype::keep::{Keep, Attr}},
|
||||
},
|
||||
util::{attempt, Grid, RandomField, Sampler, CARDINALS, DIRS},
|
||||
};
|
||||
use common::{
|
||||
assets,
|
||||
astar::Astar,
|
||||
comp,
|
||||
generation::{ChunkSupplement, EntityInfo},
|
||||
npc,
|
||||
store::{Id, Store},
|
||||
terrain::{Block, BlockKind, Structure, TerrainChunkSize},
|
||||
vol::{BaseVol, ReadVol, RectSizedVol, RectVolSize, Vox, WriteVol},
|
||||
};
|
||||
use core::{f32, hash::BuildHasherDefault};
|
||||
use fxhash::FxHasher64;
|
||||
use lazy_static::lazy_static;
|
||||
use rand::prelude::*;
|
||||
use std::sync::Arc;
|
||||
use vek::*;
|
||||
|
||||
struct Segment {
|
||||
offset: Vec2<i32>,
|
||||
locus: i32,
|
||||
height: i32,
|
||||
is_tower: bool,
|
||||
}
|
||||
|
||||
struct Tower {
|
||||
offset: Vec2<i32>,
|
||||
alt: i32,
|
||||
}
|
||||
|
||||
pub struct Castle {
|
||||
origin: Vec2<i32>,
|
||||
alt: i32,
|
||||
seed: u32,
|
||||
towers: Vec<Tower>,
|
||||
segments: Vec<Segment>,
|
||||
}
|
||||
|
||||
pub struct GenCtx<'a, R: Rng> {
|
||||
sim: Option<&'a WorldSim>,
|
||||
rng: &'a mut R,
|
||||
}
|
||||
|
||||
impl Castle {
|
||||
#[allow(clippy::let_and_return)] // TODO: Pending review in #587
|
||||
pub fn generate(wpos: Vec2<i32>, sim: Option<&WorldSim>, rng: &mut impl Rng) -> Self {
|
||||
let mut ctx = GenCtx { sim, rng };
|
||||
|
||||
let boundary_towers = ctx.rng.gen_range(5, 10);
|
||||
|
||||
let this = Self {
|
||||
origin: wpos,
|
||||
alt: ctx
|
||||
.sim
|
||||
.and_then(|sim| sim.get_alt_approx(wpos))
|
||||
.unwrap_or(0.0) as i32
|
||||
+ 6,
|
||||
seed: ctx.rng.gen(),
|
||||
|
||||
towers: (0..boundary_towers)
|
||||
.map(|i| {
|
||||
let angle = (i as f32 / boundary_towers as f32) * f32::consts::PI * 2.0;
|
||||
let dir = Vec2::new(
|
||||
angle.cos(),
|
||||
angle.sin(),
|
||||
);
|
||||
let dist = ctx.rng.gen_range(45.0, 190.0).clamped(75.0, 135.0);
|
||||
|
||||
let offset = (dir * dist).map(|e| e as i32);
|
||||
|
||||
Tower {
|
||||
offset,
|
||||
alt: ctx
|
||||
.sim
|
||||
.and_then(|sim| sim.get_alt_approx(wpos + offset))
|
||||
.unwrap_or(0.0) as i32 + 2,
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
|
||||
segments: (0..0)//rng.gen_range(18, 24))
|
||||
.map(|_| {
|
||||
let dir = Vec2::new(
|
||||
rng.gen_range(-1.0, 1.0),
|
||||
rng.gen_range(-1.0, 1.0),
|
||||
).normalized();
|
||||
let dist = 16.0 + rng.gen_range(0.0f32, 1.0).powf(0.5) * 64.0;
|
||||
let height = 48.0 - (dist / 64.0).powf(2.0) * 32.0;
|
||||
|
||||
Segment {
|
||||
offset: (dir * dist).map(|e| e as i32),
|
||||
locus: rng.gen_range(6, 26),
|
||||
height: height as i32,
|
||||
is_tower: height > 36.0,
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
this
|
||||
}
|
||||
|
||||
pub fn get_origin(&self) -> Vec2<i32> { self.origin }
|
||||
|
||||
pub fn radius(&self) -> f32 { 1200.0 }
|
||||
|
||||
#[allow(clippy::needless_update)] // TODO: Pending review in #587
|
||||
pub fn spawn_rules(&self, wpos: Vec2<i32>) -> SpawnRules {
|
||||
SpawnRules {
|
||||
trees: wpos.distance_squared(self.origin) > 64i32.pow(2),
|
||||
..SpawnRules::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_to<'a>(
|
||||
&'a self,
|
||||
wpos2d: Vec2<i32>,
|
||||
mut get_column: impl FnMut(Vec2<i32>) -> Option<&'a ColumnSample<'a>>,
|
||||
vol: &mut (impl BaseVol<Vox = Block> + RectSizedVol + ReadVol + WriteVol),
|
||||
) {
|
||||
for y in 0..vol.size_xy().y as i32 {
|
||||
for x in 0..vol.size_xy().x as i32 {
|
||||
let offs = Vec2::new(x, y);
|
||||
|
||||
let wpos2d = wpos2d + offs;
|
||||
let rpos = wpos2d - self.origin;
|
||||
|
||||
// Apply the dungeon entrance
|
||||
let col_sample = if let Some(col) = get_column(offs) {
|
||||
col
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let (wall_dist, wall_pos, wall_alt) = (0..self.towers.len())
|
||||
.map(|i| {
|
||||
let tower0 = &self.towers[i];
|
||||
let tower1 = &self.towers[(i + 1) % self.towers.len()];
|
||||
|
||||
let wall = LineSegment2 {
|
||||
start: tower0.offset.map(|e| e as f32),
|
||||
end: tower1.offset.map(|e| e as f32),
|
||||
};
|
||||
|
||||
let projected = wall.projected_point(rpos.map(|e| e as f32)).map(|e| e as i32);
|
||||
|
||||
let tower0_dist = tower0.offset.map(|e| e as f32).distance(projected.map(|e| e as f32));
|
||||
let tower1_dist = tower1.offset.map(|e| e as f32).distance(projected.map(|e| e as f32));
|
||||
let tower_lerp = tower0_dist / (tower0_dist + tower1_dist);
|
||||
|
||||
(
|
||||
wall.distance_to_point(rpos.map(|e| e as f32)) as i32,
|
||||
projected,
|
||||
Lerp::lerp(tower0.alt as f32, tower1.alt as f32, tower_lerp) as i32,
|
||||
)
|
||||
})
|
||||
.min_by_key(|x| x.0)
|
||||
.unwrap();
|
||||
|
||||
for z in -10..64 {
|
||||
let wpos = Vec3::new(
|
||||
wpos2d.x,
|
||||
wpos2d.y,
|
||||
col_sample.alt as i32 + z,
|
||||
);
|
||||
|
||||
// Boundary
|
||||
let border_pos = (wall_pos - rpos).map(|e| e.abs());
|
||||
let mut mask = Keep.draw(
|
||||
Vec3::from(rpos) + Vec3::unit_z() * wpos.z - wall_alt,
|
||||
wall_dist,
|
||||
Vec2::new(border_pos.reduce_max(), border_pos.reduce_min()),
|
||||
rpos - wall_pos,
|
||||
wpos.z - wall_alt,
|
||||
Ori::North,
|
||||
&Branch {
|
||||
len: 0,
|
||||
attr: Attr {
|
||||
height: 16,
|
||||
is_tower: false,
|
||||
},
|
||||
locus: 4,
|
||||
border: 0,
|
||||
children: Vec::new(),
|
||||
}
|
||||
);
|
||||
for tower in &self.towers {
|
||||
let tower_wpos = Vec3::new(
|
||||
self.origin.x + tower.offset.x,
|
||||
self.origin.y + tower.offset.y,
|
||||
tower.alt,
|
||||
);
|
||||
let tower_locus = 10;
|
||||
|
||||
let border_pos = (tower_wpos - wpos).xy().map(|e| e.abs());
|
||||
mask = mask.resolve_with(Keep.draw(
|
||||
wpos - tower_wpos,
|
||||
border_pos.reduce_max() - tower_locus,
|
||||
Vec2::new(border_pos.reduce_max(), border_pos.reduce_min()),
|
||||
(wpos - tower_wpos).xy(),
|
||||
wpos.z - tower.alt,
|
||||
Ori::North,
|
||||
&Branch {
|
||||
len: 0,
|
||||
attr: Attr {
|
||||
height: 28,
|
||||
is_tower: true,
|
||||
},
|
||||
locus: tower_locus,
|
||||
border: 0,
|
||||
children: Vec::new(),
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(block) = mask.finish() {
|
||||
let _ = vol.set(Vec3::new(offs.x, offs.y, wpos.z), block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::or_fun_call)] // TODO: Pending review in #587
|
||||
pub fn apply_supplement<'a>(
|
||||
&'a self,
|
||||
rng: &mut impl Rng,
|
||||
wpos2d: Vec2<i32>,
|
||||
_get_column: impl FnMut(Vec2<i32>) -> Option<&'a ColumnSample<'a>>,
|
||||
supplement: &mut ChunkSupplement,
|
||||
) {
|
||||
// TODO
|
||||
}
|
||||
}
|
@ -23,19 +23,6 @@ use rand::prelude::*;
|
||||
use std::sync::Arc;
|
||||
use vek::*;
|
||||
|
||||
impl WorldSim {
|
||||
#[allow(dead_code)]
|
||||
fn can_host_dungeon(&self, pos: Vec2<i32>) -> bool {
|
||||
self.get(pos)
|
||||
.map(|chunk| !chunk.near_cliffs && !chunk.river.is_river() && !chunk.river.is_lake())
|
||||
.unwrap_or(false)
|
||||
&& self
|
||||
.get_gradient_approx(pos)
|
||||
.map(|grad| grad > 0.25 && grad < 1.5)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Dungeon {
|
||||
origin: Vec2<i32>,
|
||||
alt: i32,
|
||||
|
@ -1,10 +1,17 @@
|
||||
mod block_mask;
|
||||
mod dungeon;
|
||||
mod castle;
|
||||
pub mod economy;
|
||||
mod settlement;
|
||||
|
||||
// Reexports
|
||||
pub use self::{block_mask::BlockMask, dungeon::Dungeon, economy::Economy, settlement::Settlement};
|
||||
pub use self::{
|
||||
block_mask::BlockMask,
|
||||
dungeon::Dungeon,
|
||||
economy::Economy,
|
||||
settlement::Settlement,
|
||||
castle::Castle,
|
||||
};
|
||||
|
||||
use crate::column::ColumnSample;
|
||||
use common::{
|
||||
@ -32,6 +39,7 @@ pub struct Site {
|
||||
pub enum SiteKind {
|
||||
Settlement(Settlement),
|
||||
Dungeon(Dungeon),
|
||||
Castle(Castle),
|
||||
}
|
||||
|
||||
impl Site {
|
||||
@ -49,10 +57,18 @@ impl Site {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn castle(c: Castle) -> Self {
|
||||
Self {
|
||||
kind: SiteKind::Castle(c),
|
||||
economy: Economy::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn radius(&self) -> f32 {
|
||||
match &self.kind {
|
||||
SiteKind::Settlement(settlement) => settlement.radius(),
|
||||
SiteKind::Dungeon(dungeon) => dungeon.radius(),
|
||||
SiteKind::Settlement(s) => s.radius(),
|
||||
SiteKind::Dungeon(d) => d.radius(),
|
||||
SiteKind::Castle(c) => c.radius(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,6 +76,7 @@ impl Site {
|
||||
match &self.kind {
|
||||
SiteKind::Settlement(s) => s.get_origin(),
|
||||
SiteKind::Dungeon(d) => d.get_origin(),
|
||||
SiteKind::Castle(c) => c.get_origin(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,6 +84,7 @@ impl Site {
|
||||
match &self.kind {
|
||||
SiteKind::Settlement(s) => s.spawn_rules(wpos),
|
||||
SiteKind::Dungeon(d) => d.spawn_rules(wpos),
|
||||
SiteKind::Castle(c) => c.spawn_rules(wpos),
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,8 +95,9 @@ impl Site {
|
||||
vol: &mut (impl BaseVol<Vox = Block> + RectSizedVol + ReadVol + WriteVol),
|
||||
) {
|
||||
match &self.kind {
|
||||
SiteKind::Settlement(settlement) => settlement.apply_to(wpos2d, get_column, vol),
|
||||
SiteKind::Dungeon(dungeon) => dungeon.apply_to(wpos2d, get_column, vol),
|
||||
SiteKind::Settlement(s) => s.apply_to(wpos2d, get_column, vol),
|
||||
SiteKind::Dungeon(d) => d.apply_to(wpos2d, get_column, vol),
|
||||
SiteKind::Castle(c) => c.apply_to(wpos2d, get_column, vol),
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,12 +109,9 @@ impl Site {
|
||||
supplement: &mut ChunkSupplement,
|
||||
) {
|
||||
match &self.kind {
|
||||
SiteKind::Settlement(settlement) => {
|
||||
settlement.apply_supplement(rng, wpos2d, get_column, supplement)
|
||||
},
|
||||
SiteKind::Dungeon(dungeon) => {
|
||||
dungeon.apply_supplement(rng, wpos2d, get_column, supplement)
|
||||
},
|
||||
SiteKind::Settlement(s) => s.apply_supplement(rng, wpos2d, get_column, supplement),
|
||||
SiteKind::Dungeon(d) => d.apply_supplement(rng, wpos2d, get_column, supplement),
|
||||
SiteKind::Castle(c) => c.apply_supplement(rng, wpos2d, get_column, supplement),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ use vek::*;
|
||||
pub struct Keep;
|
||||
|
||||
pub struct Attr {
|
||||
height: i32,
|
||||
is_tower: bool,
|
||||
pub height: i32,
|
||||
pub is_tower: bool,
|
||||
}
|
||||
|
||||
impl Archetype for Keep {
|
||||
@ -91,9 +91,9 @@ impl Archetype for Keep {
|
||||
let ceil_height = branch.attr.height;
|
||||
let door_height = 6;
|
||||
let edge_pos = if (bound_offset.x == rampart_width) ^ (ori == Ori::East) {
|
||||
pos.y
|
||||
pos.y + pos.x
|
||||
} else {
|
||||
pos.x
|
||||
pos.x + pos.y
|
||||
};
|
||||
let rampart_height = ceil_height + if edge_pos % 2 == 0 { 3 } else { 4 };
|
||||
let inner = Clamp::clamp(
|
||||
@ -143,7 +143,7 @@ impl Archetype for Keep {
|
||||
if profile.y < rampart_height {
|
||||
wall
|
||||
} else {
|
||||
internal
|
||||
empty
|
||||
}
|
||||
} else {
|
||||
empty
|
||||
|
@ -1,10 +1,10 @@
|
||||
mod archetype;
|
||||
mod skeleton;
|
||||
pub mod archetype;
|
||||
pub mod skeleton;
|
||||
|
||||
// Reexports
|
||||
pub use self::archetype::Archetype;
|
||||
pub use self::skeleton::*;
|
||||
|
||||
use self::skeleton::*;
|
||||
use common::terrain::Block;
|
||||
use rand::prelude::*;
|
||||
use vek::*;
|
||||
|
@ -1,4 +1,4 @@
|
||||
mod building;
|
||||
pub mod building;
|
||||
mod town;
|
||||
|
||||
use self::{
|
||||
|
Loading…
Reference in New Issue
Block a user