diff options
| author | mat <git@matdoes.dev> | 2023-08-26 18:08:13 -0500 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2023-08-26 18:08:13 -0500 |
| commit | dea717b68e2945777c68d44ce321639cf09ea226 (patch) | |
| tree | f3909a036730343def45978f0d59f0a82673b1c2 /azalea/src/pathfinder/moves/basic.rs | |
| parent | 5d7669f72b02c749a02bf034d382028e62509540 (diff) | |
| download | azalea-drasl-dea717b68e2945777c68d44ce321639cf09ea226.tar.xz | |
simplify pathfinder more
Diffstat (limited to 'azalea/src/pathfinder/moves/basic.rs')
| -rw-r--r-- | azalea/src/pathfinder/moves/basic.rs | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/azalea/src/pathfinder/moves/basic.rs b/azalea/src/pathfinder/moves/basic.rs new file mode 100644 index 00000000..2d0c47c2 --- /dev/null +++ b/azalea/src/pathfinder/moves/basic.rs @@ -0,0 +1,209 @@ +use azalea_client::{SprintDirection, StartSprintEvent}; +use azalea_core::{BlockPos, CardinalDirection}; +use azalea_world::Instance; + +use crate::{pathfinder::astar, JumpEvent, LookAtEvent}; + +use super::{ + fall_distance, is_block_passable, is_passable, is_standable, Edge, ExecuteCtx, MoveData, + FALL_ONE_BLOCK_COST, JUMP_COST, WALK_ONE_BLOCK_COST, +}; + +pub fn basic_move(world: &Instance, node: BlockPos) -> Vec<Edge> { + let mut edges = Vec::new(); + edges.extend(forward_move(world, node)); + edges.extend(ascend_move(world, node)); + edges.extend(descend_move(world, node)); + edges.extend(diagonal_move(world, node)); + edges +} + +fn forward_move(world: &Instance, pos: BlockPos) -> Vec<Edge> { + let mut edges = Vec::new(); + for dir in CardinalDirection::iter() { + let offset = BlockPos::new(dir.x(), 0, dir.z()); + + if !is_standable(&(pos + offset), world) { + continue; + } + + let cost = WALK_ONE_BLOCK_COST; + + edges.push(Edge { + movement: astar::Movement { + target: pos + offset, + data: MoveData { + execute: &execute_forward_move, + }, + }, + cost, + }) + } + + edges +} + +fn execute_forward_move( + ExecuteCtx { + entity, + target, + look_at_events, + sprint_events, + .. + }: ExecuteCtx, +) { + let center = target.center(); + look_at_events.send(LookAtEvent { + entity, + position: center, + }); + sprint_events.send(StartSprintEvent { + entity, + direction: SprintDirection::Forward, + }); +} + +fn ascend_move(world: &Instance, pos: BlockPos) -> Vec<Edge> { + let mut edges = Vec::new(); + for dir in CardinalDirection::iter() { + let offset = BlockPos::new(dir.x(), 1, dir.z()); + + if !is_block_passable(&pos.up(2), world) || !is_standable(&(pos + offset), world) { + continue; + } + + let cost = WALK_ONE_BLOCK_COST + JUMP_COST; + + edges.push(Edge { + movement: astar::Movement { + target: pos + offset, + data: MoveData { + execute: &execute_ascend_move, + }, + }, + cost, + }) + } + edges +} +fn execute_ascend_move( + ExecuteCtx { + entity, + target, + look_at_events, + sprint_events, + jump_events, + .. + }: ExecuteCtx, +) { + let center = target.center(); + look_at_events.send(LookAtEvent { + entity, + position: center, + }); + jump_events.send(JumpEvent { entity }); + sprint_events.send(StartSprintEvent { + entity, + direction: SprintDirection::Forward, + }); +} +fn descend_move(world: &Instance, pos: BlockPos) -> Vec<Edge> { + let mut edges = Vec::new(); + for dir in CardinalDirection::iter() { + let new_horizontal_position = pos + BlockPos::new(dir.x(), 0, dir.z()); + let fall_distance = fall_distance(&new_horizontal_position, world); + if fall_distance == 0 || fall_distance > 3 { + continue; + } + let new_position = new_horizontal_position.down(fall_distance as i32); + + // check whether 3 blocks vertically forward are passable + if !is_passable(&new_horizontal_position, world) { + continue; + } + + let cost = WALK_ONE_BLOCK_COST + FALL_ONE_BLOCK_COST * fall_distance as f32; + + edges.push(Edge { + movement: astar::Movement { + target: new_position, + data: MoveData { + execute: &execute_descend_move, + }, + }, + cost, + }) + } + edges +} +fn execute_descend_move( + ExecuteCtx { + entity, + target, + look_at_events, + sprint_events, + .. + }: ExecuteCtx, +) { + let center = target.center(); + look_at_events.send(LookAtEvent { + entity, + position: center, + }); + sprint_events.send(StartSprintEvent { + entity, + direction: SprintDirection::Forward, + }); +} + +fn diagonal_move(world: &Instance, pos: BlockPos) -> Vec<Edge> { + let mut edges = Vec::new(); + for dir in CardinalDirection::iter() { + let right = dir.right(); + let offset = BlockPos::new(dir.x() + right.x(), 0, dir.z() + right.z()); + + if !is_passable( + &BlockPos::new(pos.x + dir.x(), pos.y, pos.z + dir.z()), + world, + ) && !is_passable( + &BlockPos::new(pos.x + dir.right().x(), pos.y, pos.z + dir.right().z()), + world, + ) { + continue; + } + if !is_standable(&(pos + offset), world) { + continue; + } + let cost = WALK_ONE_BLOCK_COST * 1.4; + + edges.push(Edge { + movement: astar::Movement { + target: pos + offset, + data: MoveData { + execute: &execute_diagonal_move, + }, + }, + cost, + }) + } + edges +} +fn execute_diagonal_move( + ExecuteCtx { + entity, + target, + look_at_events, + sprint_events, + .. + }: ExecuteCtx, +) { + let center = target.center(); + look_at_events.send(LookAtEvent { + entity, + position: center, + }); + sprint_events.send(StartSprintEvent { + entity, + direction: SprintDirection::Forward, + }); +} |
