Added simple distance check for sprite interaction.

This commit is contained in:
Sam 2021-08-29 19:46:36 -04:00
parent 018f9ae53f
commit 21f75f31a2
2 changed files with 52 additions and 41 deletions

View File

@ -1,5 +1,5 @@
// The limit on distance between the entity and a collectible (squared) // The limit on distance between the entity and a collectible (squared)
pub const MAX_PICKUP_RANGE: f32 = 8.0; pub const MAX_PICKUP_RANGE: f32 = 5.0;
pub const MAX_MOUNT_RANGE: f32 = 14.0; pub const MAX_MOUNT_RANGE: f32 = 14.0;
pub const GRAVITY: f32 = 25.0; pub const GRAVITY: f32 = 25.0;

View File

@ -9,7 +9,7 @@ use crate::{
theropod, Body, CharacterAbility, CharacterState, Density, InputAttr, InputKind, theropod, Body, CharacterAbility, CharacterState, Density, InputAttr, InputKind,
InventoryAction, StateUpdate, InventoryAction, StateUpdate,
}, },
consts::{FRIC_GROUND, GRAVITY}, consts::{FRIC_GROUND, GRAVITY, MAX_PICKUP_RANGE},
event::{LocalEvent, ServerEvent}, event::{LocalEvent, ServerEvent},
states::{behavior::JoinData, *}, states::{behavior::JoinData, *},
util::Dir, util::Dir,
@ -355,12 +355,12 @@ pub fn handle_orientation(
efficiency: f32, efficiency: f32,
dir_override: Option<Dir>, dir_override: Option<Dir>,
) { ) {
let dir = dir_override.unwrap_or_else(|| let dir = dir_override.unwrap_or_else(|| {
(is_strafing(data, update) || update.character.is_attack()) (is_strafing(data, update) || update.character.is_attack())
.then(|| data.inputs.look_dir.to_horizontal().unwrap_or_default()) .then(|| data.inputs.look_dir.to_horizontal().unwrap_or_default())
.or_else(|| Dir::from_unnormalized(data.inputs.move_dir.into())) .or_else(|| Dir::from_unnormalized(data.inputs.move_dir.into()))
.unwrap_or_else(|| data.ori.to_horizontal().look_dir()), .unwrap_or_else(|| data.ori.to_horizontal().look_dir())
); });
let rate = { let rate = {
let angle = update.ori.look_dir().angle_between(*dir); let angle = update.ori.look_dir().angle_between(*dir);
data.body.base_ori_rate() * efficiency * std::f32::consts::PI / angle data.body.base_ori_rate() * efficiency * std::f32::consts::PI / angle
@ -626,45 +626,56 @@ pub fn handle_manipulate_loadout(
.push_front(ServerEvent::InventoryManip(data.entity, inv_action.into())); .push_front(ServerEvent::InventoryManip(data.entity, inv_action.into()));
} }
}, },
InventoryAction::Collect(pos) => { InventoryAction::Collect(sprite_pos) => {
// First, get sprite data for position, if there is a sprite // CLosure to check if distance between a point and the sprite is less than
use sprite_interact::SpriteInteractKind; // MAX_PICKUP_RANGE
let sprite_at_pos = data let sprite_range_check = |pos: Vec3<f32>| {
.terrain (sprite_pos.map(|x| x as f32) - pos).magnitude_squared()
.get(pos) < MAX_PICKUP_RANGE.powi(2)
.ok() };
.copied() // Checks if player's feet or head is near to sprite
.and_then(|b| b.get_sprite()); let close_to_sprite = sprite_range_check(data.pos.0)
|| sprite_range_check(data.pos.0 + Vec3::new(0.0, 0.0, data.body.height()));
if close_to_sprite {
// First, get sprite data for position, if there is a sprite
use sprite_interact::SpriteInteractKind;
let sprite_at_pos = data
.terrain
.get(sprite_pos)
.ok()
.copied()
.and_then(|b| b.get_sprite());
// Checks if position has a collectible sprite as wella s what sprite is at the // Checks if position has a collectible sprite as wella s what sprite is at the
// position // position
let sprite_interact = sprite_at_pos.and_then(Option::<SpriteInteractKind>::from); let sprite_interact = sprite_at_pos.and_then(Option::<SpriteInteractKind>::from);
if let Some(sprite_interact) = sprite_interact { if let Some(sprite_interact) = sprite_interact {
// If the sprite is collectible, enter the sprite interaction character state // If the sprite is collectible, enter the sprite interaction character state
// TODO: Handle cases for sprite being interactible, but not collectible (none // TODO: Handle cases for sprite being interactible, but not collectible (none
// currently exist) // currently exist)
let (buildup_duration, use_duration, recover_duration) = let (buildup_duration, use_duration, recover_duration) =
sprite_interact.durations(); sprite_interact.durations();
update.character = CharacterState::SpriteInteract(sprite_interact::Data { update.character = CharacterState::SpriteInteract(sprite_interact::Data {
static_data: sprite_interact::StaticData { static_data: sprite_interact::StaticData {
buildup_duration, buildup_duration,
use_duration, use_duration,
recover_duration, recover_duration,
sprite_pos: pos, sprite_pos,
sprite_kind: sprite_interact, sprite_kind: sprite_interact,
was_wielded: matches!(data.character, CharacterState::Wielding), was_wielded: matches!(data.character, CharacterState::Wielding),
was_sneak: matches!(data.character, CharacterState::Sneak), was_sneak: matches!(data.character, CharacterState::Sneak),
}, },
timer: Duration::default(), timer: Duration::default(),
stage_section: StageSection::Buildup, stage_section: StageSection::Buildup,
}) })
} else { } else {
// Otherwise send server event immediately // Otherwise send server event immediately
update update
.server_events .server_events
.push_front(ServerEvent::InventoryManip(data.entity, inv_action.into())); .push_front(ServerEvent::InventoryManip(data.entity, inv_action.into()));
}
} }
}, },
_ => { _ => {