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 generation;
|
||||
pub mod loadout_builder;
|
||||
pub mod lottery;
|
||||
pub mod msg;
|
||||
pub mod npc;
|
||||
pub mod outcome;
|
||||
@ -39,6 +40,5 @@ pub mod terrain;
|
||||
pub mod util;
|
||||
pub mod vol;
|
||||
pub mod volumes;
|
||||
pub mod lottery;
|
||||
|
||||
pub use loadout_builder::LoadoutBuilder;
|
||||
|
@ -151,6 +151,7 @@ impl<'a> System<'a> for Sys {
|
||||
const SEARCH_DIST: f32 = 48.0;
|
||||
const SIGHT_DIST: f32 = 128.0;
|
||||
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);
|
||||
|
||||
@ -306,27 +307,31 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
// Flee
|
||||
if 1.0 - agent.psyche.aggro > damage {
|
||||
if let Some((bearing, speed)) = chaser.chase(
|
||||
&*terrain,
|
||||
pos.0,
|
||||
vel.0,
|
||||
// Away from the target (ironically)
|
||||
tgt_pos.0 + (pos.0 - tgt_pos.0)
|
||||
.try_normalized()
|
||||
.unwrap_or_else(Vec3::unit_y) * 32.0,
|
||||
TraversalConfig {
|
||||
node_tolerance,
|
||||
slow_factor,
|
||||
on_ground: physics_state.on_ground,
|
||||
min_tgt_dist: 1.25,
|
||||
},
|
||||
) {
|
||||
inputs.move_dir = Vec2::from(bearing)
|
||||
.try_normalized()
|
||||
.unwrap_or(Vec2::zero())
|
||||
* speed;
|
||||
inputs.jump.set_state(bearing.z > 1.5);
|
||||
inputs.swim.set_state(bearing.z > 0.5);
|
||||
if dist_sqrd < MAX_FLEE_DIST.powf(2.0) {
|
||||
if let Some((bearing, speed)) = chaser.chase(
|
||||
&*terrain,
|
||||
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,
|
||||
TraversalConfig {
|
||||
node_tolerance,
|
||||
slow_factor,
|
||||
on_ground: physics_state.on_ground,
|
||||
min_tgt_dist: 1.25,
|
||||
},
|
||||
) {
|
||||
inputs.move_dir = Vec2::from(bearing)
|
||||
.try_normalized()
|
||||
.unwrap_or(Vec2::zero())
|
||||
* speed;
|
||||
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) {
|
||||
// Close-range attack
|
||||
|
@ -157,9 +157,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;
|
||||
|
@ -319,12 +319,12 @@ impl<'a> System<'a> for Sys {
|
||||
pos: Pos(entity.pos),
|
||||
stats,
|
||||
loadout,
|
||||
body,
|
||||
agent: if entity.has_agency {
|
||||
Some(comp::Agent::new(entity.pos, can_speak))
|
||||
Some(comp::Agent::new(entity.pos, can_speak, &body))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
body,
|
||||
alignment,
|
||||
scale: comp::Scale(scale),
|
||||
drop_item: entity.loot_drop,
|
||||
|
@ -4,13 +4,16 @@ use crate::{
|
||||
Index,
|
||||
};
|
||||
use common::{
|
||||
assets,
|
||||
lottery::Lottery,
|
||||
terrain::{Block, BlockKind},
|
||||
vol::{BaseVol, ReadVol, RectSizedVol, Vox, WriteVol},
|
||||
lottery::Lottery,
|
||||
assets,
|
||||
};
|
||||
use noise::NoiseFn;
|
||||
use std::{f32, ops::{Sub, Mul}};
|
||||
use std::{
|
||||
f32,
|
||||
ops::{Mul, Sub},
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
let stalagtites = index.noise.cave_nz
|
||||
.get(wpos2d.map(|e| e as f64 * 0.1).into_array())
|
||||
.sub(0.6)
|
||||
let stalagtites = index
|
||||
.noise
|
||||
.cave_nz
|
||||
.get(wpos2d.map(|e| e as f64 * 0.125).into_array())
|
||||
.sub(0.5)
|
||||
.max(0.0)
|
||||
.mul((col_sample.alt - cave_roof as f32 - 5.0).mul(0.15).clamped(0.0, 1.0) as f64)
|
||||
.mul(40.0) as i32;
|
||||
.mul(
|
||||
(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 {
|
||||
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
|
||||
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")
|
||||
.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 {
|
||||
offset: Vec2<i32>,
|
||||
locus: i32,
|
||||
height: i32,
|
||||
storeys: i32,
|
||||
is_tower: bool,
|
||||
alt: i32,
|
||||
}
|
||||
@ -123,12 +123,12 @@ impl Castle {
|
||||
|
||||
let locus = ctx.rng.gen_range(20, 26);
|
||||
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 {
|
||||
offset,
|
||||
locus,
|
||||
height,
|
||||
storeys,
|
||||
is_tower: true,
|
||||
alt: ctx
|
||||
.sim
|
||||
@ -301,7 +301,7 @@ impl Castle {
|
||||
4,
|
||||
0,
|
||||
&Attr {
|
||||
height: 16,
|
||||
storeys: 1,
|
||||
is_tower: false,
|
||||
ridged: false,
|
||||
rounded: true,
|
||||
@ -336,7 +336,7 @@ impl Castle {
|
||||
tower_locus,
|
||||
0,
|
||||
&Attr {
|
||||
height: 28,
|
||||
storeys: 2,
|
||||
is_tower: true,
|
||||
ridged: false,
|
||||
rounded: self.rounded_towers,
|
||||
@ -371,7 +371,7 @@ impl Castle {
|
||||
keep.locus,
|
||||
0,
|
||||
&Attr {
|
||||
height: keep.height,
|
||||
storeys: keep.storeys,
|
||||
is_tower: keep.is_tower,
|
||||
ridged: true,
|
||||
rounded: self.rounded_towers,
|
||||
|
@ -408,10 +408,12 @@ impl Floor {
|
||||
* FLOOR_SIZE.x as f32
|
||||
/ 2.0
|
||||
- 8.0;
|
||||
supplement.add_entity(
|
||||
EntityInfo::at((origin + stair_rcenter).map(|e| e as f32) + Vec3::from(offs))
|
||||
.into_waypoint(),
|
||||
);
|
||||
if !self.final_level {
|
||||
supplement.add_entity(
|
||||
EntityInfo::at((origin + stair_rcenter).map(|e| e as f32) + Vec3::from(offs))
|
||||
.into_waypoint(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for x in area.min.x..area.max.x {
|
||||
|
@ -1,5 +1,8 @@
|
||||
use super::{super::skeleton::*, Archetype};
|
||||
use crate::site::BlockMask;
|
||||
use crate::{
|
||||
site::BlockMask,
|
||||
util::{RandomField, Sampler},
|
||||
};
|
||||
use common::{
|
||||
terrain::{Block, BlockKind},
|
||||
vol::Vox,
|
||||
@ -12,7 +15,7 @@ pub struct Keep {
|
||||
}
|
||||
|
||||
pub struct Attr {
|
||||
pub height: i32,
|
||||
pub storeys: i32,
|
||||
pub is_tower: bool,
|
||||
pub ridged: bool,
|
||||
pub rounded: bool,
|
||||
@ -29,7 +32,7 @@ impl Archetype for Keep {
|
||||
root: Branch {
|
||||
len,
|
||||
attr: Attr {
|
||||
height: rng.gen_range(12, 16),
|
||||
storeys: 1,
|
||||
is_tower: false,
|
||||
ridged: false,
|
||||
rounded: true,
|
||||
@ -43,12 +46,12 @@ impl Archetype for Keep {
|
||||
Branch {
|
||||
len: 0,
|
||||
attr: Attr {
|
||||
height: rng.gen_range(20, 28),
|
||||
storeys: 2,
|
||||
is_tower: true,
|
||||
ridged: false,
|
||||
rounded: true,
|
||||
},
|
||||
locus: 4 + rng.gen_range(0, 5),
|
||||
locus: 6 + rng.gen_range(0, 3),
|
||||
border: 3,
|
||||
children: Vec::new(),
|
||||
},
|
||||
@ -93,8 +96,10 @@ impl Archetype for Keep {
|
||||
)
|
||||
};
|
||||
|
||||
let foundation = make_block(100, 100, 100);
|
||||
let wall = make_block(100, 100, 110);
|
||||
let brick_tex_pos = (pos + Vec3::new(pos.z, pos.z, 0)) / Vec3::new(2, 2, 1);
|
||||
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(
|
||||
80 + (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 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) {
|
||||
pos.y
|
||||
} else {
|
||||
@ -114,15 +139,16 @@ impl Archetype for Keep {
|
||||
};
|
||||
|
||||
let width = locus
|
||||
+ if edge_pos % 4 == 0 && attr.ridged && !attr.rounded {
|
||||
+ if (edge_pos + 1000) % 8 < 4 && attr.ridged && !attr.rounded {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
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 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 {
|
||||
bound_offset.map(|e| e.pow(2) as f32).sum().powf(0.5) as i32
|
||||
} else {
|
||||
@ -132,31 +158,32 @@ impl Archetype for Keep {
|
||||
if profile.y <= 0 - (min_dist - width - 1).max(0) && min_dist < width + 3 {
|
||||
// Foundations
|
||||
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 }
|
||||
} else if !attr.is_tower
|
||||
&& bound_offset.x.abs() == 4
|
||||
&& min_dist == width + 1
|
||||
&& profile.y < ceil_height
|
||||
&& profile.y < roof_height
|
||||
{
|
||||
wall
|
||||
} else if bound_offset.x.abs() < 3
|
||||
&& profile.y < door_height - bound_offset.x.abs()
|
||||
&& profile.y > 0
|
||||
&& min_dist >= width - 2
|
||||
{
|
||||
internal
|
||||
} else if min_dist == width && profile.y <= ceil_height {
|
||||
} else if min_dist == width && profile.y <= roof_height {
|
||||
wall
|
||||
} else if profile.y >= ceil_height {
|
||||
if profile.y > ceil_height && min_dist < rampart_width {
|
||||
if attr.is_tower && center_offset == Vec2::zero() && profile.y < ceil_height + 16 {
|
||||
} else if profile.y >= roof_height {
|
||||
if profile.y > roof_height && min_dist < rampart_width {
|
||||
if attr.is_tower && center_offset == Vec2::zero() && profile.y < roof_height + 16 {
|
||||
pole
|
||||
} else if attr.is_tower
|
||||
&& center_offset.x == 0
|
||||
&& center_offset.y > 0
|
||||
&& center_offset.y < 8
|
||||
&& profile.y > ceil_height + 8
|
||||
&& profile.y < ceil_height + 14
|
||||
&& profile.y > roof_height + 8
|
||||
&& profile.y < roof_height + 14
|
||||
{
|
||||
flag
|
||||
} else {
|
||||
@ -171,10 +198,20 @@ impl Archetype for Keep {
|
||||
} else {
|
||||
empty
|
||||
}
|
||||
} else if profile.y < ceil_height && min_dist < width {
|
||||
} else if profile.y < roof_height && min_dist < width {
|
||||
internal
|
||||
} else {
|
||||
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