build is working. to add and remove blocks.

This commit is contained in:
anomaluridae 2021-08-10 22:11:55 -07:00
parent 48cc5d3b08
commit 84f19b408f
2 changed files with 40 additions and 22 deletions

View File

@ -488,13 +488,15 @@ impl PlayState for SessionState {
match input {
GameInput::Primary => {
if is_mining && is_nearest_target(mine_target) {
self.inputs.select_pos = mine_target.map(|t| t.position);
entity_event_handler!(InputKind::Primary, state);
} else if state && can_build && is_nearest_target(build_target) {
// mine and build targets can be the same block. make building take
// precedence.
if state && can_build && is_nearest_target(build_target) {
self.inputs.select_pos = build_target.map(|t| t.position);
let mut client = self.client.borrow_mut();
client.remove_block(build_target.unwrap().position_int());
} else if is_mining && is_nearest_target(mine_target) {
self.inputs.select_pos = mine_target.map(|t| t.position);
entity_event_handler!(InputKind::Primary, state);
} else {
entity_event_handler!(InputKind::Primary, state);
}
@ -504,10 +506,11 @@ impl PlayState for SessionState {
if let Some(build_target) = build_target {
self.inputs.select_pos = Some(build_target.position);
let mut client = self.client.borrow_mut();
client.place_block(
build_target.position_int(),
self.selected_block,
);
if let Some(pos) =
build_target.build_above_position(&client)
{
client.place_block(pos, self.selected_block);
};
}
} else {
entity_event_handler!(InputKind::Secondary, state);

View File

@ -16,7 +16,7 @@ use common_base::span;
#[derive(Clone, Copy, Debug)]
pub enum TargetType {
Build(Vec3<f32>),
Build,
Collectable,
Entity(specs::Entity),
Mine,
@ -32,6 +32,26 @@ pub struct Target {
impl Target {
pub fn position_int(self) -> Vec3<i32> { self.position.map(|p| p.floor() as i32) }
pub fn build_above_position(self, client: &Client) -> Option<Vec3<i32>> {
match self.typed {
TargetType::Build => {
let mut pos_above = self.position;
pos_above.z += 1.0;
let pos_above = pos_above.map(|p| p.floor() as i32);
if let Ok(block) = client.state().terrain().get(pos_above) {
if block.is_air() {
Some(pos_above)
} else {
None
}
} else {
None
}
},
_ => None,
}
}
pub fn make_interactable(self, client: &Client) -> Option<Interactable> {
match self.typed {
TargetType::Collectable => client
@ -49,7 +69,7 @@ impl Target {
.ok()
.copied()
.map(|b| Interactable::Block(b, self.position_int(), None)),
TargetType::Build(_) => None,
TargetType::Build => None,
}
}
}
@ -99,7 +119,6 @@ pub(super) fn targets_under_cursor(
) -> impl FnMut(
fn(Block) -> bool,
) -> (
Option<Vec3<f32>>,
Option<Vec3<f32>>,
(f32, Result<Option<Block>, VolGrid2dError<TerrainChunk>>),
) + 'a {
@ -117,23 +136,19 @@ pub(super) fn targets_under_cursor(
cam_ray.1,
Ok(Some(_)) if player_cylinder.min_distance(*cam_pos + *cam_dir * (cam_dist + 0.01)) <= MAX_PICKUP_RANGE
) {
(
Some(*cam_pos + *cam_dir * cam_dist),
Some(*cam_pos + *cam_dir * (cam_dist - 0.01)),
cam_ray,
)
(Some(*cam_pos + *cam_dir * cam_dist), cam_ray)
} else {
(None, None, cam_ray)
(None, cam_ray)
}
}
}
let mut find_pos = curry_find_pos(client, &cam_pos, &cam_dir, &player_cylinder);
let (collect_pos, _, cam_ray_0) = find_pos(|b: Block| b.is_collectible());
let (mine_pos, _, cam_ray_1) = find_pos(|b: Block| b.mine_tool().is_some());
let (collect_pos, cam_ray_0) = find_pos(|b: Block| b.is_collectible());
let (mine_pos, cam_ray_1) = find_pos(|b: Block| b.mine_tool().is_some());
// FIXME: the `solid_pos` is used in the remove_block(). is this correct?
let (solid_pos, build_pos, cam_ray_2) = find_pos(|b: Block| b.is_solid());
let (solid_pos, cam_ray_2) = find_pos(|b: Block| b.is_solid());
// find shortest cam_dist of non-entity targets
// note that some of these targets can technically be in Air, such as the
@ -224,9 +239,9 @@ pub(super) fn targets_under_cursor(
} else { None }
});
let build_target = if let (true, Some(position), Some(bp)) = (can_build, solid_pos, build_pos) {
let build_target = if let (true, Some(position)) = (can_build, solid_pos) {
Some(Target {
typed: TargetType::Build(bp),
typed: TargetType::Build,
distance: cam_ray_2.0,
position,
})