mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Addressed feedback
This commit is contained in:
parent
49e8803ee0
commit
c77270b799
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -6656,7 +6656,6 @@ dependencies = [
|
||||
"fxhash",
|
||||
"hashbrown 0.11.2",
|
||||
"image",
|
||||
"inline_tweak",
|
||||
"itertools",
|
||||
"kiddo 0.2.1",
|
||||
"lazy_static",
|
||||
|
@ -700,6 +700,7 @@ impl Body {
|
||||
_ => 1000,
|
||||
},
|
||||
Body::Golem(golem) => match golem.species {
|
||||
golem::Species::WoodGolem => 200,
|
||||
golem::Species::ClayGolem => 450,
|
||||
_ => 1000,
|
||||
},
|
||||
@ -778,7 +779,14 @@ impl Body {
|
||||
_ => false,
|
||||
},
|
||||
BuffKind::Regeneration => {
|
||||
matches!(self, Body::Object(object::Body::GnarlingTotemGreen))
|
||||
matches!(
|
||||
self,
|
||||
Body::Object(
|
||||
object::Body::GnarlingTotemRed
|
||||
| object::Body::GnarlingTotemGreen
|
||||
| object::Body::GnarlingTotemWhite
|
||||
)
|
||||
)
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
|
@ -142,10 +142,24 @@ impl<'a> AgentData<'a> {
|
||||
..self.traversal_config
|
||||
},
|
||||
) {
|
||||
controller.inputs.move_dir =
|
||||
-bearing.xy().try_normalized().unwrap_or_else(Vec2::zero);
|
||||
if !self.char_state.is_attack() {
|
||||
controller.inputs.look_dir = -controller.inputs.look_dir;
|
||||
let flee_dir = -bearing.xy().try_normalized().unwrap_or_else(Vec2::zero);
|
||||
let pos = self.pos.0.xy().with_z(self.pos.0.z + 1.5);
|
||||
if read_data
|
||||
.terrain
|
||||
.ray(pos, pos + flee_dir * 2.0)
|
||||
.until(|b| b.is_solid() || b.get_sprite().is_none())
|
||||
.cast()
|
||||
.0
|
||||
> 1.0
|
||||
{
|
||||
// If able to flee, flee
|
||||
controller.inputs.move_dir = flee_dir;
|
||||
if !self.char_state.is_attack() {
|
||||
controller.inputs.look_dir = -controller.inputs.look_dir;
|
||||
}
|
||||
} else {
|
||||
// Otherwise, fight to the death
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
}
|
||||
}
|
||||
} else if attack_data.dist_sqrd < PREF_DIST.powi(2) {
|
||||
@ -2272,7 +2286,21 @@ impl<'a> AgentData<'a> {
|
||||
} else if agent.action_state.timer > TOTEM_TIMER {
|
||||
// If time to summon a totem, do it
|
||||
let input = rng.gen_range(1..=3);
|
||||
controller.push_basic_input(InputKind::Ability(input));
|
||||
let buff_kind = match input {
|
||||
2 => Some(BuffKind::Regeneration),
|
||||
3 => Some(BuffKind::Hastened),
|
||||
_ => None,
|
||||
};
|
||||
if buff_kind.map_or(true, |b| self.has_buff(read_data, b))
|
||||
&& matches!(self.char_state, CharacterState::Wielding { .. })
|
||||
{
|
||||
// If already under effects of buff from totem that would be summoned, don't
|
||||
// summon totem (doesn't work for red totems since that applies debuff to
|
||||
// enemies instead)
|
||||
agent.action_state.timer = 0.0;
|
||||
} else {
|
||||
controller.push_basic_input(InputKind::Ability(input));
|
||||
}
|
||||
} else if agent.action_state.counter > HEAVY_ATTACK_WAIT_TIME {
|
||||
// Else if time for a heavy attack
|
||||
if attack_data.in_min_range() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::sys::agent::ReadData;
|
||||
use crate::sys::agent::{AgentData, ReadData};
|
||||
use common::{
|
||||
comp::{buff::BuffKind, Alignment, Pos},
|
||||
consts::GRAVITY,
|
||||
@ -70,3 +70,12 @@ pub fn aim_projectile(speed: f32, pos: Vec3<f32>, tgt: Vec3<f32>) -> Option<Dir>
|
||||
pub fn get_entity_by_id(id: u64, read_data: &ReadData) -> Option<EcsEntity> {
|
||||
read_data.uid_allocator.retrieve_entity_internal(id)
|
||||
}
|
||||
|
||||
impl<'a> AgentData<'a> {
|
||||
pub fn has_buff(&self, read_data: &ReadData, buff: BuffKind) -> bool {
|
||||
read_data
|
||||
.buffs
|
||||
.get(*self.entity)
|
||||
.map_or(false, |b| b.kinds.contains_key(&buff))
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ packed_simd = { package = "packed_simd_2", version = "0.3.5", optional = true }
|
||||
rayon = "1.5"
|
||||
serde = { version = "1.0.110", features = ["derive"] }
|
||||
ron = { version = "0.7", default-features = false }
|
||||
inline_tweak = "1.0.2"
|
||||
# inline_tweak = "1.0.2"
|
||||
kiddo = "0.2"
|
||||
|
||||
# compression benchmarks
|
||||
|
@ -137,7 +137,7 @@ impl Civs {
|
||||
SiteKind::Refactor => (32i32, 10.0),
|
||||
SiteKind::Tree => (12i32, 8.0),
|
||||
SiteKind::GiantTree => (12i32, 8.0),
|
||||
SiteKind::Gnarling => (16i32, 5.0),
|
||||
SiteKind::Gnarling => (16i32, 10.0),
|
||||
};
|
||||
|
||||
let (raise, raise_dist, make_waypoint): (f32, i32, bool) = match &site.kind {
|
||||
|
@ -44,7 +44,7 @@ use crate::{
|
||||
column::ColumnGen,
|
||||
index::Index,
|
||||
layer::spot::Spot,
|
||||
site::SiteKind,
|
||||
site::{SiteKind, SpawnRules},
|
||||
util::{Grid, Sampler},
|
||||
};
|
||||
use common::{
|
||||
@ -410,7 +410,16 @@ impl World {
|
||||
};
|
||||
|
||||
if sim_chunk.contains_waypoint {
|
||||
supplement.add_entity(EntityInfo::at(gen_entity_pos(&mut dynamic_rng)).into_waypoint());
|
||||
let waypoint_pos = gen_entity_pos(&mut dynamic_rng);
|
||||
if sim_chunk
|
||||
.sites
|
||||
.iter()
|
||||
.map(|site| index.sites[*site].spawn_rules(waypoint_pos.xy().as_()))
|
||||
.fold(SpawnRules::default(), |a, b| a.combine(b))
|
||||
.waypoints
|
||||
{
|
||||
supplement.add_entity(EntityInfo::at(waypoint_pos).into_waypoint());
|
||||
}
|
||||
}
|
||||
|
||||
// Apply layer supplement
|
||||
|
@ -27,6 +27,7 @@ pub struct SpawnRules {
|
||||
pub trees: bool,
|
||||
pub max_warp: f32,
|
||||
pub paths: bool,
|
||||
pub waypoints: bool,
|
||||
}
|
||||
|
||||
impl SpawnRules {
|
||||
@ -37,6 +38,7 @@ impl SpawnRules {
|
||||
trees: self.trees && other.trees,
|
||||
max_warp: self.max_warp.min(other.max_warp),
|
||||
paths: self.paths && other.paths,
|
||||
waypoints: self.waypoints && other.waypoints,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -47,6 +49,7 @@ impl Default for SpawnRules {
|
||||
trees: true,
|
||||
max_warp: 1.0,
|
||||
paths: true,
|
||||
waypoints: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,11 +88,20 @@ impl Site {
|
||||
.min_by_key(|d2| *d2 as i32)
|
||||
.map(|d2| d2.sqrt() as f32 / TILE_SIZE as f32)
|
||||
.unwrap_or(1.0);
|
||||
SpawnRules {
|
||||
let base_spawn_rules = SpawnRules {
|
||||
trees: max_warp == 1.0,
|
||||
max_warp,
|
||||
paths: max_warp > std::f32::EPSILON,
|
||||
}
|
||||
waypoints: true,
|
||||
};
|
||||
self.plots
|
||||
.values()
|
||||
.filter_map(|plot| match &plot.kind {
|
||||
PlotKind::Dungeon(d) => Some(d.spawn_rules(wpos)),
|
||||
PlotKind::Gnarling(g) => Some(g.spawn_rules(wpos)),
|
||||
_ => None,
|
||||
})
|
||||
.fold(base_spawn_rules, |a, b| a.combine(b))
|
||||
}
|
||||
|
||||
pub fn bounds(&self) -> Aabr<i32> {
|
||||
|
@ -221,11 +221,15 @@ impl GnarlingFortification {
|
||||
+ corner_2.as_() * corner_2_weight)
|
||||
.as_();
|
||||
|
||||
// Check that structure not too close to another structure
|
||||
if structure_locations.iter().any(|(kind, loc, _door_dir)| {
|
||||
structure_center.distance_squared(loc.xy())
|
||||
< structure_kind.required_separation(kind).pow(2)
|
||||
}) {
|
||||
// Check that structure not in the water or too close to another structure
|
||||
if land
|
||||
.get_chunk_wpos(structure_center + origin)
|
||||
.map_or(false, |c| c.is_underwater())
|
||||
|| structure_locations.iter().any(|(kind, loc, _door_dir)| {
|
||||
structure_center.distance_squared(loc.xy())
|
||||
< structure_kind.required_separation(kind).pow(2)
|
||||
})
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some((
|
||||
@ -316,6 +320,15 @@ impl GnarlingFortification {
|
||||
|
||||
pub fn radius(&self) -> i32 { self.radius }
|
||||
|
||||
pub fn spawn_rules(&self, wpos: Vec2<i32>) -> SpawnRules {
|
||||
SpawnRules {
|
||||
trees: wpos.distance_squared(self.origin) > self.wall_radius.pow(2),
|
||||
waypoints: false,
|
||||
..SpawnRules::default()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Find a better way of spawning entities in site2
|
||||
pub fn apply_supplement<'a>(
|
||||
&'a self,
|
||||
// NOTE: Used only for dynamic elements like chests and entities!
|
||||
@ -362,47 +375,45 @@ impl GnarlingFortification {
|
||||
));
|
||||
}
|
||||
|
||||
for (loc, pos, ori) in &self.structure_locations {
|
||||
for (loc, pos, _ori) in &self.structure_locations {
|
||||
let wpos = *pos + self.origin;
|
||||
if area.contains_point(pos.xy()) {
|
||||
match loc {
|
||||
GnarlingStructure::Hut => {
|
||||
supplement.add_entity(random_gnarling(wpos, dynamic_rng));
|
||||
let num = dynamic_rng.gen_range(2..=3);
|
||||
for _ in 0..num {
|
||||
supplement.add_entity(random_gnarling(wpos, dynamic_rng));
|
||||
}
|
||||
},
|
||||
GnarlingStructure::VeloriteHut => {
|
||||
supplement.add_entity(random_gnarling(wpos, dynamic_rng));
|
||||
},
|
||||
GnarlingStructure::Banner => {
|
||||
supplement.add_entity(random_gnarling(wpos, dynamic_rng));
|
||||
let num = dynamic_rng.gen_range(2..=6);
|
||||
for _ in 0..num {
|
||||
supplement.add_entity(random_gnarling(
|
||||
wpos.xy().with_z(wpos.z + 12),
|
||||
dynamic_rng,
|
||||
));
|
||||
}
|
||||
},
|
||||
GnarlingStructure::Banner => {},
|
||||
GnarlingStructure::ChieftainHut => {
|
||||
supplement.add_entity(gnarling_chieftain(
|
||||
wpos.xy().with_z(wpos.z + 8),
|
||||
dynamic_rng,
|
||||
));
|
||||
let left_inner_guard_pos = wpos + ori.dir() * 8 + ori.cw().dir() * 2;
|
||||
supplement.add_entity(wood_golem(left_inner_guard_pos, dynamic_rng));
|
||||
let right_inner_guard_pos = wpos + ori.dir() * 8 + ori.ccw().dir() * 2;
|
||||
supplement.add_entity(wood_golem(right_inner_guard_pos, dynamic_rng));
|
||||
let left_outer_guard_pos = wpos + ori.dir() * 16 + ori.cw().dir() * 2;
|
||||
supplement.add_entity(random_gnarling(left_outer_guard_pos, dynamic_rng));
|
||||
let right_outer_guard_pos = wpos + ori.dir() * 16 + ori.ccw().dir() * 2;
|
||||
supplement.add_entity(random_gnarling(right_outer_guard_pos, dynamic_rng));
|
||||
let pos = wpos.xy().with_z(wpos.z + 8);
|
||||
supplement.add_entity(gnarling_chieftain(pos, dynamic_rng));
|
||||
for _ in 0..2 {
|
||||
supplement.add_entity(wood_golem(pos, dynamic_rng));
|
||||
}
|
||||
},
|
||||
GnarlingStructure::WatchTower => {
|
||||
supplement.add_entity(wood_golem(wpos, dynamic_rng));
|
||||
let spawn_pos = wpos.xy().with_z(wpos.z + 27);
|
||||
for _ in 0..4 {
|
||||
let num = dynamic_rng.gen_range(2..=4);
|
||||
for _ in 0..num {
|
||||
supplement.add_entity(gnarling_stalker(
|
||||
spawn_pos + Vec2::broadcast(4),
|
||||
dynamic_rng,
|
||||
));
|
||||
}
|
||||
},
|
||||
GnarlingStructure::Totem => {
|
||||
let spawn_pos = wpos + pos.xy().map(|x| x.signum() * -5);
|
||||
supplement.add_entity(wood_golem(spawn_pos, dynamic_rng));
|
||||
},
|
||||
GnarlingStructure::Totem => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -511,7 +522,7 @@ impl Structure for GnarlingFortification {
|
||||
|
||||
painter
|
||||
.segment_prism(start, end, wall_mid_thickness, wall_mid_height)
|
||||
.fill(darkwood.clone());
|
||||
.fill(darkwood);
|
||||
|
||||
let start = start_wpos
|
||||
.as_()
|
||||
@ -850,12 +861,7 @@ impl Structure for GnarlingFortification {
|
||||
painter: &Painter,
|
||||
wpos: Vec2<i32>,
|
||||
alt: i32,
|
||||
_door_dir: Ori,
|
||||
hut_radius: f32,
|
||||
_hut_wall_height: f32,
|
||||
_door_height: i32,
|
||||
roof_height: f32,
|
||||
_roof_overhang: f32,
|
||||
) {
|
||||
let darkwood = Fill::Brick(BlockKind::Wood, Rgb::new(55, 25, 8), 12);
|
||||
let lightwood = Fill::Brick(BlockKind::Wood, Rgb::new(71, 33, 11), 12);
|
||||
@ -1300,23 +1306,9 @@ impl Structure for GnarlingFortification {
|
||||
.fill(Fill::Prefab(Box::new(totem), totem_pos, self.seed));
|
||||
},
|
||||
GnarlingStructure::ChieftainHut => {
|
||||
let hut_radius = 5.0;
|
||||
let hut_wall_height = 15.0;
|
||||
let door_height = 3;
|
||||
let roof_height = 3.0;
|
||||
let roof_overhang = 1.0;
|
||||
|
||||
generate_chieftainhut(
|
||||
painter,
|
||||
wpos,
|
||||
alt,
|
||||
*door_dir,
|
||||
hut_radius,
|
||||
hut_wall_height,
|
||||
door_height,
|
||||
roof_height,
|
||||
roof_overhang,
|
||||
);
|
||||
generate_chieftainhut(painter, wpos, alt, roof_height);
|
||||
},
|
||||
|
||||
GnarlingStructure::Banner => {
|
||||
|
Loading…
Reference in New Issue
Block a user