Agent adjustments, better dungeon stairwells

This commit is contained in:
Joshua Barretto 2020-04-19 16:34:23 +01:00
parent cf986e75dc
commit 708f15915a
2 changed files with 54 additions and 47 deletions

View File

@ -154,7 +154,7 @@ impl<'a> System<'a> for Sys {
}
// Sometimes try searching for new targets
if thread_rng().gen::<f32>() < 0.05 {
if thread_rng().gen::<f32>() < 0.1 {
choose_target = true;
}
},
@ -240,7 +240,7 @@ impl<'a> System<'a> for Sys {
inputs.roll.set_state(true);
}
} else if dist_sqrd < MAX_CHASE_DIST.powf(2.0)
|| (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close)
|| (dist_sqrd < SIGHT_DIST.powf(2.0) && (!*been_close || !matches!(tactic, Tactic::Melee)))
{
let can_see_tgt = terrain
.ray(pos.0 + Vec3::unit_z(), tgt_pos.0 + Vec3::unit_z())
@ -264,10 +264,10 @@ impl<'a> System<'a> for Sys {
inputs.secondary.set_state(true);
}
}
if dist_sqrd < MAX_CHASE_DIST.powf(2.0) {
*been_close = true;
}
if dist_sqrd < MAX_CHASE_DIST.powf(2.0) {
*been_close = true;
}
// Long-range chase
@ -280,8 +280,9 @@ impl<'a> System<'a> for Sys {
inputs.jump.set_state(bearing.z > 1.0);
}
if dist_sqrd < (MAX_CHASE_DIST * 0.65).powf(2.0)
&& thread_rng().gen::<f32>() < 0.01
if dist_sqrd < 16.0f32.powf(2.0)
&& matches!(tactic, Tactic::Melee)
&& thread_rng().gen::<f32>() < 0.02
{
inputs.roll.set_state(true);
}
@ -307,8 +308,11 @@ impl<'a> System<'a> for Sys {
let closest_entity = (&entities, &positions, &stats, alignments.maybe())
.join()
.filter(|(e, e_pos, e_stats, e_alignment)| {
((e_pos.0.distance_squared(pos.0) < SEARCH_DIST.powf(2.0) && (e_pos.0 - pos.0).try_normalized().map(|v| v.dot(*inputs.look_dir) > 0.3).unwrap_or(true))
|| e_pos.0.distance_squared(pos.0) < LISTEN_DIST.powf(2.0))
((e_pos.0.distance_squared(pos.0) < SEARCH_DIST.powf(2.0) &&
// Within our view
(e_pos.0 - pos.0).try_normalized().map(|v| v.dot(*inputs.look_dir) > 0.15).unwrap_or(true))
// Within listen distance
|| e_pos.0.distance_squared(pos.0) < LISTEN_DIST.powf(2.0))
&& *e != entity
&& !e_stats.is_dead
&& alignment

View File

@ -104,9 +104,10 @@ impl Dungeon {
let mut z = self.alt;
for floor in &self.floors {
let mut sampler = floor.col_sampler(rpos);
z -= floor.total_depth();
let mut sampler = floor.col_sampler(rpos, z);
for rz in 0..floor.total_depth() {
if let Some(block) = sampler(rz).finish() {
vol.set(Vec3::new(offs.x, offs.y, z + rz), block);
@ -182,7 +183,6 @@ impl Tile {
pub struct Room {
seed: u32,
enemies: bool,
loot_density: f32,
enemy_density: f32,
area: Rect<i32, i32>,
@ -206,7 +206,7 @@ impl Floor {
level: i32,
) -> (Self, Vec2<i32>) {
let new_stair_tile = std::iter::from_fn(|| {
Some(FLOOR_SIZE.map(|sz| ctx.rng.gen_range(-sz / 2 + 1, sz / 2)))
Some(FLOOR_SIZE.map(|sz| ctx.rng.gen_range(-sz / 2 + 2, sz / 2 - 1)))
})
.filter(|pos| *pos != stair_tile)
.take(8)
@ -222,28 +222,46 @@ impl Floor {
hollow_depth: 13,
stair_tile: new_stair_tile - tile_offset,
};
this.create_rooms(ctx, level, 10);
// Create rooms for entrance and exit
this.create_room(Room {
seed: ctx.rng.gen(),
loot_density: 0.0,
enemy_density: 0.0,
area: Rect::from((stair_tile - tile_offset - 1, Extent2::broadcast(3))),
});
this.tiles.set(stair_tile - tile_offset, Tile::UpStair);
this.create_room(Room {
seed: ctx.rng.gen(),
loot_density: 0.0,
enemy_density: 0.0,
area: Rect::from((new_stair_tile - tile_offset - 1, Extent2::broadcast(3))),
});
this.tiles.set(new_stair_tile - tile_offset, Tile::DownStair);
this.create_rooms(ctx, level, 7);
// Create routes between all rooms
let room_areas = this.rooms.iter().map(|r| r.area).collect::<Vec<_>>();
for a in room_areas.iter() {
for b in room_areas.iter() {
this.create_route(ctx, a.center(), b.center(), true);
this.create_route(ctx, a.center(), b.center());
}
}
this.create_route(
ctx,
stair_tile - tile_offset,
new_stair_tile - tile_offset,
false,
);
this.tiles.set(stair_tile - tile_offset, Tile::UpStair);
this.tiles
.set(new_stair_tile - tile_offset, Tile::DownStair);
(this, new_stair_tile)
}
fn create_room(&mut self, room: Room) -> Id<Room> {
let area = room.area;
let id = self.rooms.insert(room);
for x in 0..area.extent().w {
for y in 0..area.extent().h {
self.tiles.set(area.position() + Vec2::new(x, y), Tile::Room(id));
}
}
id
}
fn create_rooms(&mut self, ctx: &mut GenCtx<impl Rng>, level: i32, n: usize) {
let dim_limits = (3, 6);
@ -258,31 +276,23 @@ impl Floor {
// Ensure no overlap
if self.rooms.iter().any(|r| {
r.area.collides_with_rect(area_border) || r.area.contains_point(self.stair_tile)
r.area.collides_with_rect(area_border)
}) {
return None;
}
Some(area)
}) {
Some(room) => room,
Some(area) => area,
None => return,
};
let room = self.rooms.insert(Room {
self.create_room(Room {
seed: ctx.rng.gen(),
enemies: ctx.rng.gen(),
loot_density: 0.00005 + level as f32 * 0.00015,
enemy_density: 0.0005 + level as f32 * 0.00015,
area,
});
for x in 0..area.extent().w {
for y in 0..area.extent().h {
self.tiles
.set(area.position() + Vec2::new(x, y), Tile::Room(room));
}
}
}
}
@ -291,16 +301,9 @@ impl Floor {
ctx: &mut GenCtx<impl Rng>,
a: Vec2<i32>,
b: Vec2<i32>,
optimise_longest: bool,
) {
let sim = &ctx.sim;
let heuristic = move |l: &Vec2<i32>| {
if optimise_longest {
(l.distance_squared(b) as f32).sqrt()
} else {
100.0 - (l.distance_squared(b) as f32).sqrt()
}
};
let heuristic = move |l: &Vec2<i32>| (l - b).map(|e| e.abs()).reduce_max() as f32;
let neighbors = |l: &Vec2<i32>| {
let l = *l;
CARDINALS
@ -364,7 +367,7 @@ impl Floor {
for y in 0..TILE_SIZE {
let pos = tile_pos * TILE_SIZE + Vec2::new(x, y);
if room.enemies && (pos.x + pos.y * TILE_SIZE * FLOOR_SIZE.x).rem_euclid(room.enemy_density.recip() as i32) == 0 {
if (pos.x + pos.y * TILE_SIZE * FLOOR_SIZE.x).rem_euclid(room.enemy_density.recip() as i32) == 0 {
// Bad
let entity = EntityInfo::at(
(origin
@ -421,7 +424,7 @@ impl Floor {
.min_by_key(|nearest| rpos.distance_squared(*nearest))
}
pub fn col_sampler(&self, pos: Vec2<i32>) -> impl FnMut(i32) -> BlockMask + '_ {
pub fn col_sampler(&self, pos: Vec2<i32>, floor_z: i32) -> impl FnMut(i32) -> BlockMask + '_ {
let rpos = pos - self.tile_offset * TILE_SIZE;
let tile_pos = rpos.map(|e| e.div_euclid(TILE_SIZE));
let tile_center = tile_pos * TILE_SIZE + TILE_SIZE / 2;
@ -436,7 +439,7 @@ impl Floor {
stone
} else if (pos.xy().magnitude_squared() as f32) < radius.powf(2.0) {
if ((pos.x as f32).atan2(pos.y as f32) / (f32::consts::PI * 2.0) * stretch
+ pos.z as f32)
+ (floor_z + pos.z) as f32)
.rem_euclid(stretch)
< 1.5
{