mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Various improvements to castles, dungeons and more
This commit is contained in:
parent
0bad704719
commit
9bb10a6d00
@ -22,6 +22,7 @@ pub mod event;
|
|||||||
pub mod figure;
|
pub mod figure;
|
||||||
pub mod generation;
|
pub mod generation;
|
||||||
pub mod loadout_builder;
|
pub mod loadout_builder;
|
||||||
|
pub mod lottery;
|
||||||
pub mod msg;
|
pub mod msg;
|
||||||
pub mod npc;
|
pub mod npc;
|
||||||
pub mod outcome;
|
pub mod outcome;
|
||||||
@ -39,6 +40,5 @@ pub mod terrain;
|
|||||||
pub mod util;
|
pub mod util;
|
||||||
pub mod vol;
|
pub mod vol;
|
||||||
pub mod volumes;
|
pub mod volumes;
|
||||||
pub mod lottery;
|
|
||||||
|
|
||||||
pub use loadout_builder::LoadoutBuilder;
|
pub use loadout_builder::LoadoutBuilder;
|
||||||
|
@ -151,6 +151,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
const SEARCH_DIST: f32 = 48.0;
|
const SEARCH_DIST: f32 = 48.0;
|
||||||
const SIGHT_DIST: f32 = 128.0;
|
const SIGHT_DIST: f32 = 128.0;
|
||||||
const MIN_ATTACK_DIST: f32 = 3.5;
|
const MIN_ATTACK_DIST: f32 = 3.5;
|
||||||
|
const MAX_FLEE_DIST: f32 = 32.0;
|
||||||
|
|
||||||
let scale = scales.get(entity).map(|s| s.0).unwrap_or(1.0);
|
let scale = scales.get(entity).map(|s| s.0).unwrap_or(1.0);
|
||||||
|
|
||||||
@ -306,27 +307,31 @@ impl<'a> System<'a> for Sys {
|
|||||||
|
|
||||||
// Flee
|
// Flee
|
||||||
if 1.0 - agent.psyche.aggro > damage {
|
if 1.0 - agent.psyche.aggro > damage {
|
||||||
if let Some((bearing, speed)) = chaser.chase(
|
if dist_sqrd < MAX_FLEE_DIST.powf(2.0) {
|
||||||
&*terrain,
|
if let Some((bearing, speed)) = chaser.chase(
|
||||||
pos.0,
|
&*terrain,
|
||||||
vel.0,
|
pos.0,
|
||||||
// Away from the target (ironically)
|
vel.0,
|
||||||
tgt_pos.0 + (pos.0 - tgt_pos.0)
|
// Away from the target (ironically)
|
||||||
.try_normalized()
|
pos.0 + (pos.0 - tgt_pos.0)
|
||||||
.unwrap_or_else(Vec3::unit_y) * 32.0,
|
.try_normalized()
|
||||||
TraversalConfig {
|
.unwrap_or_else(Vec3::unit_y) * 8.0,
|
||||||
node_tolerance,
|
TraversalConfig {
|
||||||
slow_factor,
|
node_tolerance,
|
||||||
on_ground: physics_state.on_ground,
|
slow_factor,
|
||||||
min_tgt_dist: 1.25,
|
on_ground: physics_state.on_ground,
|
||||||
},
|
min_tgt_dist: 1.25,
|
||||||
) {
|
},
|
||||||
inputs.move_dir = Vec2::from(bearing)
|
) {
|
||||||
.try_normalized()
|
inputs.move_dir = Vec2::from(bearing)
|
||||||
.unwrap_or(Vec2::zero())
|
.try_normalized()
|
||||||
* speed;
|
.unwrap_or(Vec2::zero())
|
||||||
inputs.jump.set_state(bearing.z > 1.5);
|
* speed;
|
||||||
inputs.swim.set_state(bearing.z > 0.5);
|
inputs.jump.set_state(bearing.z > 1.5);
|
||||||
|
inputs.swim.set_state(bearing.z > 0.5);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
do_idle = true;
|
||||||
}
|
}
|
||||||
} else if dist_sqrd < (MIN_ATTACK_DIST * scale).powf(2.0) {
|
} else if dist_sqrd < (MIN_ATTACK_DIST * scale).powf(2.0) {
|
||||||
// Close-range attack
|
// Close-range attack
|
||||||
|
@ -157,9 +157,9 @@ impl<'a> System<'a> for Sys {
|
|||||||
z_max,
|
z_max,
|
||||||
} => {
|
} => {
|
||||||
// Scale collider
|
// Scale collider
|
||||||
let radius = *radius * scale;
|
let radius = *radius;// * scale;
|
||||||
let z_min = *z_min * scale;
|
let z_min = *z_min;// * scale;
|
||||||
let z_max = *z_max * scale;
|
let z_max = *z_max;// * scale;
|
||||||
|
|
||||||
// Probe distances
|
// Probe distances
|
||||||
let hdist = radius.ceil() as i32;
|
let hdist = radius.ceil() as i32;
|
||||||
|
@ -319,12 +319,12 @@ impl<'a> System<'a> for Sys {
|
|||||||
pos: Pos(entity.pos),
|
pos: Pos(entity.pos),
|
||||||
stats,
|
stats,
|
||||||
loadout,
|
loadout,
|
||||||
body,
|
|
||||||
agent: if entity.has_agency {
|
agent: if entity.has_agency {
|
||||||
Some(comp::Agent::new(entity.pos, can_speak))
|
Some(comp::Agent::new(entity.pos, can_speak, &body))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
body,
|
||||||
alignment,
|
alignment,
|
||||||
scale: comp::Scale(scale),
|
scale: comp::Scale(scale),
|
||||||
drop_item: entity.loot_drop,
|
drop_item: entity.loot_drop,
|
||||||
|
@ -4,13 +4,16 @@ use crate::{
|
|||||||
Index,
|
Index,
|
||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
|
assets,
|
||||||
|
lottery::Lottery,
|
||||||
terrain::{Block, BlockKind},
|
terrain::{Block, BlockKind},
|
||||||
vol::{BaseVol, ReadVol, RectSizedVol, Vox, WriteVol},
|
vol::{BaseVol, ReadVol, RectSizedVol, Vox, WriteVol},
|
||||||
lottery::Lottery,
|
|
||||||
assets,
|
|
||||||
};
|
};
|
||||||
use noise::NoiseFn;
|
use noise::NoiseFn;
|
||||||
use std::{f32, ops::{Sub, Mul}};
|
use std::{
|
||||||
|
f32,
|
||||||
|
ops::{Mul, Sub},
|
||||||
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
pub fn apply_paths_to<'a>(
|
pub fn apply_paths_to<'a>(
|
||||||
@ -136,28 +139,49 @@ pub fn apply_caves_to<'a>(
|
|||||||
let cave_roof = (cave.alt + cave_height) as i32;
|
let cave_roof = (cave.alt + cave_height) as i32;
|
||||||
|
|
||||||
for z in cave_base..cave_roof {
|
for z in cave_base..cave_roof {
|
||||||
let _ = vol.set(Vec3::new(offs.x, offs.y, z), Block::empty());
|
if cave_x < 0.95
|
||||||
|
|| index.noise.cave_nz.get(
|
||||||
|
Vec3::new(wpos2d.x, wpos2d.y, z)
|
||||||
|
.map(|e| e as f64 * 0.15)
|
||||||
|
.into_array(),
|
||||||
|
) < 0.0
|
||||||
|
{
|
||||||
|
let _ = vol.set(Vec3::new(offs.x, offs.y, z), Block::empty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stalagtites
|
// Stalagtites
|
||||||
let stalagtites = index.noise.cave_nz
|
let stalagtites = index
|
||||||
.get(wpos2d.map(|e| e as f64 * 0.1).into_array())
|
.noise
|
||||||
.sub(0.6)
|
.cave_nz
|
||||||
|
.get(wpos2d.map(|e| e as f64 * 0.125).into_array())
|
||||||
|
.sub(0.5)
|
||||||
.max(0.0)
|
.max(0.0)
|
||||||
.mul((col_sample.alt - cave_roof as f32 - 5.0).mul(0.15).clamped(0.0, 1.0) as f64)
|
.mul(
|
||||||
.mul(40.0) as i32;
|
(col_sample.alt - cave_roof as f32 - 5.0)
|
||||||
|
.mul(0.15)
|
||||||
|
.clamped(0.0, 1.0) as f64,
|
||||||
|
)
|
||||||
|
.mul(45.0) as i32;
|
||||||
|
|
||||||
for z in cave_roof - stalagtites..cave_roof {
|
for z in cave_roof - stalagtites..cave_roof {
|
||||||
let _ = vol.set(Vec3::new(offs.x, offs.y, z), Block::new(BlockKind::Normal, Rgb::broadcast(200)));
|
let _ = vol.set(
|
||||||
|
Vec3::new(offs.x, offs.y, z),
|
||||||
|
Block::new(BlockKind::Rock, Rgb::broadcast(200)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scatter things in caves
|
// Scatter things in caves
|
||||||
if RandomField::new(index.seed).chance(wpos2d.into(), 0.001) && cave_base < surface_z as i32 - 25 {
|
if RandomField::new(index.seed).chance(wpos2d.into(), 0.001)
|
||||||
|
&& cave_base < surface_z as i32 - 25
|
||||||
|
{
|
||||||
let kind = *assets::load_expect::<Lottery<BlockKind>>("common.cave_scatter")
|
let kind = *assets::load_expect::<Lottery<BlockKind>>("common.cave_scatter")
|
||||||
.choose_seeded(RandomField::new(index.seed + 1).get(wpos2d.into()));
|
.choose_seeded(RandomField::new(index.seed + 1).get(wpos2d.into()));
|
||||||
let _ = vol.set(Vec3::new(offs.x, offs.y, cave_base), Block::new(kind, Rgb::zero()));
|
let _ = vol.set(
|
||||||
|
Vec3::new(offs.x, offs.y, cave_base),
|
||||||
|
Block::new(kind, Rgb::zero()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ use vek::*;
|
|||||||
struct Keep {
|
struct Keep {
|
||||||
offset: Vec2<i32>,
|
offset: Vec2<i32>,
|
||||||
locus: i32,
|
locus: i32,
|
||||||
height: i32,
|
storeys: i32,
|
||||||
is_tower: bool,
|
is_tower: bool,
|
||||||
alt: i32,
|
alt: i32,
|
||||||
}
|
}
|
||||||
@ -123,12 +123,12 @@ impl Castle {
|
|||||||
|
|
||||||
let locus = ctx.rng.gen_range(20, 26);
|
let locus = ctx.rng.gen_range(20, 26);
|
||||||
let offset = (dir * dist).map(|e| e as i32);
|
let offset = (dir * dist).map(|e| e as i32);
|
||||||
let height = ctx.rng.gen_range(25, 70).clamped(30, 48);
|
let storeys = ctx.rng.gen_range(1, 5).clamped(2, 3);
|
||||||
|
|
||||||
Keep {
|
Keep {
|
||||||
offset,
|
offset,
|
||||||
locus,
|
locus,
|
||||||
height,
|
storeys,
|
||||||
is_tower: true,
|
is_tower: true,
|
||||||
alt: ctx
|
alt: ctx
|
||||||
.sim
|
.sim
|
||||||
@ -301,7 +301,7 @@ impl Castle {
|
|||||||
4,
|
4,
|
||||||
0,
|
0,
|
||||||
&Attr {
|
&Attr {
|
||||||
height: 16,
|
storeys: 1,
|
||||||
is_tower: false,
|
is_tower: false,
|
||||||
ridged: false,
|
ridged: false,
|
||||||
rounded: true,
|
rounded: true,
|
||||||
@ -336,7 +336,7 @@ impl Castle {
|
|||||||
tower_locus,
|
tower_locus,
|
||||||
0,
|
0,
|
||||||
&Attr {
|
&Attr {
|
||||||
height: 28,
|
storeys: 2,
|
||||||
is_tower: true,
|
is_tower: true,
|
||||||
ridged: false,
|
ridged: false,
|
||||||
rounded: self.rounded_towers,
|
rounded: self.rounded_towers,
|
||||||
@ -371,7 +371,7 @@ impl Castle {
|
|||||||
keep.locus,
|
keep.locus,
|
||||||
0,
|
0,
|
||||||
&Attr {
|
&Attr {
|
||||||
height: keep.height,
|
storeys: keep.storeys,
|
||||||
is_tower: keep.is_tower,
|
is_tower: keep.is_tower,
|
||||||
ridged: true,
|
ridged: true,
|
||||||
rounded: self.rounded_towers,
|
rounded: self.rounded_towers,
|
||||||
|
@ -408,10 +408,12 @@ impl Floor {
|
|||||||
* FLOOR_SIZE.x as f32
|
* FLOOR_SIZE.x as f32
|
||||||
/ 2.0
|
/ 2.0
|
||||||
- 8.0;
|
- 8.0;
|
||||||
supplement.add_entity(
|
if !self.final_level {
|
||||||
EntityInfo::at((origin + stair_rcenter).map(|e| e as f32) + Vec3::from(offs))
|
supplement.add_entity(
|
||||||
.into_waypoint(),
|
EntityInfo::at((origin + stair_rcenter).map(|e| e as f32) + Vec3::from(offs))
|
||||||
);
|
.into_waypoint(),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for x in area.min.x..area.max.x {
|
for x in area.min.x..area.max.x {
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use super::{super::skeleton::*, Archetype};
|
use super::{super::skeleton::*, Archetype};
|
||||||
use crate::site::BlockMask;
|
use crate::{
|
||||||
|
site::BlockMask,
|
||||||
|
util::{RandomField, Sampler},
|
||||||
|
};
|
||||||
use common::{
|
use common::{
|
||||||
terrain::{Block, BlockKind},
|
terrain::{Block, BlockKind},
|
||||||
vol::Vox,
|
vol::Vox,
|
||||||
@ -12,7 +15,7 @@ pub struct Keep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Attr {
|
pub struct Attr {
|
||||||
pub height: i32,
|
pub storeys: i32,
|
||||||
pub is_tower: bool,
|
pub is_tower: bool,
|
||||||
pub ridged: bool,
|
pub ridged: bool,
|
||||||
pub rounded: bool,
|
pub rounded: bool,
|
||||||
@ -29,7 +32,7 @@ impl Archetype for Keep {
|
|||||||
root: Branch {
|
root: Branch {
|
||||||
len,
|
len,
|
||||||
attr: Attr {
|
attr: Attr {
|
||||||
height: rng.gen_range(12, 16),
|
storeys: 1,
|
||||||
is_tower: false,
|
is_tower: false,
|
||||||
ridged: false,
|
ridged: false,
|
||||||
rounded: true,
|
rounded: true,
|
||||||
@ -43,12 +46,12 @@ impl Archetype for Keep {
|
|||||||
Branch {
|
Branch {
|
||||||
len: 0,
|
len: 0,
|
||||||
attr: Attr {
|
attr: Attr {
|
||||||
height: rng.gen_range(20, 28),
|
storeys: 2,
|
||||||
is_tower: true,
|
is_tower: true,
|
||||||
ridged: false,
|
ridged: false,
|
||||||
rounded: true,
|
rounded: true,
|
||||||
},
|
},
|
||||||
locus: 4 + rng.gen_range(0, 5),
|
locus: 6 + rng.gen_range(0, 3),
|
||||||
border: 3,
|
border: 3,
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
},
|
},
|
||||||
@ -93,8 +96,10 @@ impl Archetype for Keep {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let foundation = make_block(100, 100, 100);
|
let brick_tex_pos = (pos + Vec3::new(pos.z, pos.z, 0)) / Vec3::new(2, 2, 1);
|
||||||
let wall = make_block(100, 100, 110);
|
let brick_tex = RandomField::new(0).get(brick_tex_pos) as u8 % 24;
|
||||||
|
let foundation = make_block(80 + brick_tex, 80 + brick_tex, 80 + brick_tex);
|
||||||
|
let wall = make_block(100 + brick_tex, 100 + brick_tex, 110 + brick_tex);
|
||||||
let floor = make_block(
|
let floor = make_block(
|
||||||
80 + (pos.y.abs() % 2) as u8 * 15,
|
80 + (pos.y.abs() % 2) as u8 * 15,
|
||||||
60 + (pos.y.abs() % 2) as u8 * 15,
|
60 + (pos.y.abs() % 2) as u8 * 15,
|
||||||
@ -107,6 +112,26 @@ impl Archetype for Keep {
|
|||||||
let internal = BlockMask::new(Block::empty(), internal_layer);
|
let internal = BlockMask::new(Block::empty(), internal_layer);
|
||||||
let empty = BlockMask::nothing();
|
let empty = BlockMask::nothing();
|
||||||
|
|
||||||
|
let make_staircase = move |pos: Vec3<i32>, radius: f32, inner_radius: f32, stretch: f32| {
|
||||||
|
let stone = BlockMask::new(Block::new(BlockKind::Normal, Rgb::new(150, 150, 175)), 5);
|
||||||
|
|
||||||
|
if (pos.xy().magnitude_squared() as f32) < inner_radius.powf(2.0) {
|
||||||
|
stone
|
||||||
|
} else if (pos.xy().magnitude_squared() as f32) < radius.powf(2.0) {
|
||||||
|
if ((pos.x as f32).atan2(pos.y as f32) / (std::f32::consts::PI * 2.0) * stretch
|
||||||
|
+ pos.z as f32)
|
||||||
|
.rem_euclid(stretch)
|
||||||
|
< 1.5
|
||||||
|
{
|
||||||
|
stone
|
||||||
|
} else {
|
||||||
|
internal
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
BlockMask::nothing()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let edge_pos = if (bound_offset.x.abs() > bound_offset.y.abs()) ^ (ori == Ori::East) {
|
let edge_pos = if (bound_offset.x.abs() > bound_offset.y.abs()) ^ (ori == Ori::East) {
|
||||||
pos.y
|
pos.y
|
||||||
} else {
|
} else {
|
||||||
@ -114,15 +139,16 @@ impl Archetype for Keep {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let width = locus
|
let width = locus
|
||||||
+ if edge_pos % 4 == 0 && attr.ridged && !attr.rounded {
|
+ if (edge_pos + 1000) % 8 < 4 && attr.ridged && !attr.rounded {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
let rampart_width = 2 + width;
|
let rampart_width = 2 + width;
|
||||||
let ceil_height = attr.height;
|
let storey_height = 16;
|
||||||
|
let roof_height = attr.storeys * storey_height;
|
||||||
let door_height = 6;
|
let door_height = 6;
|
||||||
let rampart_height = ceil_height + if edge_pos % 2 == 0 { 3 } else { 4 };
|
let rampart_height = roof_height + if edge_pos % 2 == 0 { 3 } else { 4 };
|
||||||
let min_dist = if attr.rounded {
|
let min_dist = if attr.rounded {
|
||||||
bound_offset.map(|e| e.pow(2) as f32).sum().powf(0.5) as i32
|
bound_offset.map(|e| e.pow(2) as f32).sum().powf(0.5) as i32
|
||||||
} else {
|
} else {
|
||||||
@ -132,31 +158,32 @@ impl Archetype for Keep {
|
|||||||
if profile.y <= 0 - (min_dist - width - 1).max(0) && min_dist < width + 3 {
|
if profile.y <= 0 - (min_dist - width - 1).max(0) && min_dist < width + 3 {
|
||||||
// Foundations
|
// Foundations
|
||||||
foundation
|
foundation
|
||||||
} else if profile.y == ceil_height && min_dist < rampart_width {
|
} else if (0..=roof_height).contains(&profile.y) && profile.y % storey_height == 0 && min_dist < rampart_width {
|
||||||
if min_dist < width { floor } else { wall }
|
if min_dist < width { floor } else { wall }
|
||||||
} else if !attr.is_tower
|
} else if !attr.is_tower
|
||||||
&& bound_offset.x.abs() == 4
|
&& bound_offset.x.abs() == 4
|
||||||
&& min_dist == width + 1
|
&& min_dist == width + 1
|
||||||
&& profile.y < ceil_height
|
&& profile.y < roof_height
|
||||||
{
|
{
|
||||||
wall
|
wall
|
||||||
} else if bound_offset.x.abs() < 3
|
} else if bound_offset.x.abs() < 3
|
||||||
&& profile.y < door_height - bound_offset.x.abs()
|
&& profile.y < door_height - bound_offset.x.abs()
|
||||||
&& profile.y > 0
|
&& profile.y > 0
|
||||||
|
&& min_dist >= width - 2
|
||||||
{
|
{
|
||||||
internal
|
internal
|
||||||
} else if min_dist == width && profile.y <= ceil_height {
|
} else if min_dist == width && profile.y <= roof_height {
|
||||||
wall
|
wall
|
||||||
} else if profile.y >= ceil_height {
|
} else if profile.y >= roof_height {
|
||||||
if profile.y > ceil_height && min_dist < rampart_width {
|
if profile.y > roof_height && min_dist < rampart_width {
|
||||||
if attr.is_tower && center_offset == Vec2::zero() && profile.y < ceil_height + 16 {
|
if attr.is_tower && center_offset == Vec2::zero() && profile.y < roof_height + 16 {
|
||||||
pole
|
pole
|
||||||
} else if attr.is_tower
|
} else if attr.is_tower
|
||||||
&& center_offset.x == 0
|
&& center_offset.x == 0
|
||||||
&& center_offset.y > 0
|
&& center_offset.y > 0
|
||||||
&& center_offset.y < 8
|
&& center_offset.y < 8
|
||||||
&& profile.y > ceil_height + 8
|
&& profile.y > roof_height + 8
|
||||||
&& profile.y < ceil_height + 14
|
&& profile.y < roof_height + 14
|
||||||
{
|
{
|
||||||
flag
|
flag
|
||||||
} else {
|
} else {
|
||||||
@ -171,10 +198,20 @@ impl Archetype for Keep {
|
|||||||
} else {
|
} else {
|
||||||
empty
|
empty
|
||||||
}
|
}
|
||||||
} else if profile.y < ceil_height && min_dist < width {
|
} else if profile.y < roof_height && min_dist < width {
|
||||||
internal
|
internal
|
||||||
} else {
|
} else {
|
||||||
empty
|
empty
|
||||||
}
|
}
|
||||||
|
.resolve_with(if attr.is_tower && profile.y > 0 && profile.y <= roof_height {
|
||||||
|
make_staircase(
|
||||||
|
Vec3::new(center_offset.x, center_offset.y, pos.z),
|
||||||
|
7.0f32.min(width as f32 - 1.0),
|
||||||
|
0.5,
|
||||||
|
9.0,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
BlockMask::nothing()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user