Block when pressing right click while looking at the attacker

This commit is contained in:
timokoesters 2019-08-24 18:38:59 +02:00
parent e42ffb362a
commit e7c61c30cc
No known key found for this signature in database
GPG Key ID: CD80BE9AAEE78097
8 changed files with 87 additions and 47 deletions

View File

@ -27,6 +27,7 @@ pub enum ActionState {
Idle,
Wield { time_left: Duration },
Attack { time_left: Duration, applied: bool },
Block { time_left: Duration },
//Carry,
}
@ -46,6 +47,14 @@ impl ActionState {
false
}
}
pub fn is_block(&self) -> bool {
if let Self::Block { .. } = self {
true
} else {
false
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]

View File

@ -7,6 +7,7 @@ pub struct Controller {
pub move_dir: Vec2<f32>,
pub jump: bool,
pub attack: bool,
pub block: bool,
pub roll: bool,
pub glide: bool,
pub respawn: bool,

View File

@ -41,6 +41,7 @@ impl<'a> System<'a> for Sys {
(false, Jump, Wield { .. }) => Animation::Cjump,
(_, Glide, Idle) => Animation::Gliding,
(_, _, Attack { .. }) => Animation::Attack,
(_, _, Block { .. }) => Animation::Gliding,
// Impossible animation (Caused by missing animations or syncing delays)
_ => Animation::Gliding,
};

View File

@ -35,22 +35,23 @@ impl<'a> System<'a> for Sys {
): Self::SystemData,
) {
// Attacks
for (entity, uid, pos, ori, mut character) in (
&entities,
&uids,
&positions,
&orientations,
&mut character_states,
)
.join()
{
for (entity, uid, pos, ori) in (&entities, &uids, &positions, &orientations).join() {
let mut todo_end = false;
// Go through all other entities
if let Attack { time_left, applied } = &mut character.action {
if let Some(Attack { time_left, applied }) =
&mut character_states.get(entity).map(|c| c.action)
{
if !*applied {
for (b, pos_b, mut vel_b, stat_b) in
(&entities, &positions, &mut velocities, &mut stats).join()
for (b, pos_b, ori_b, character_b, mut vel_b, stat_b) in (
&entities,
&positions,
&orientations,
&character_states,
&mut velocities,
&mut stats,
)
.join()
{
// Check if it is a hit
if entity != b
@ -58,33 +59,51 @@ impl<'a> System<'a> for Sys {
&& pos.0.distance_squared(pos_b.0) < 50.0
&& ori.0.angle_between(pos_b.0 - pos.0).to_degrees() < 90.0
{
let dmg = if character_b.action.is_block()
&& ori_b.0.angle_between(pos.0 - pos_b.0).to_degrees() < 90.0
{
1
} else {
10
};
// Deal damage
stat_b
.health
.change_by(-10, HealthSource::Attack { by: *uid }); // TODO: variable damage and weapon
.change_by(-dmg, HealthSource::Attack { by: *uid }); // TODO: variable damage and weapon
vel_b.0 += (pos_b.0 - pos.0).normalized() * 2.0;
vel_b.0.z = 2.0;
let _ = force_updates.insert(b, ForceUpdate);
}
}
*applied = true;
}
if *time_left == Duration::default() {
todo_end = true;
} else {
*time_left = time_left
.checked_sub(Duration::from_secs_f32(dt.0))
.unwrap_or_default();
if let Some(Attack { time_left, applied }) =
&mut character_states.get_mut(entity).map(|c| &mut c.action)
{
// Only attack once
*applied = true;
if *time_left == Duration::default() {
todo_end = true;
} else {
*time_left = time_left
.checked_sub(Duration::from_secs_f32(dt.0))
.unwrap_or_default();
}
}
}
if todo_end {
character.action = Wield {
time_left: Duration::default(),
};
if let Some(character) = &mut character_states.get_mut(entity) {
character.action = Wield {
time_left: Duration::default(),
};
}
}
if let Wield { time_left } = &mut character.action {
if let Some(Wield { time_left }) =
&mut character_states.get_mut(entity).map(|c| &mut c.action)
{
if *time_left != Duration::default() {
*time_left = time_left
.checked_sub(Duration::from_secs_f32(dt.0))

View File

@ -109,6 +109,19 @@ impl<'a> System<'a> for Sys {
}
}
// Block
if controller.block
&& (character.movement == Stand || character.movement == Run)
&& (character.action == Idle || character.action.is_wield())
{
character.action = Block {
time_left: Duration::from_secs(5),
};
} else if !controller.block && character.action.is_block() {
dbg!();
character.action = Idle;
}
// Roll
if controller.roll
&& (character.action == Idle || character.action.is_wield())

View File

@ -160,32 +160,29 @@ impl PlayState for SessionState {
}
}
Event::InputUpdate(GameInput::SecondAttack, state) => {
if state {
let mut client = self.client.borrow_mut();
if client
Event::InputUpdate(GameInput::Block, state) => {
let mut client = self.client.borrow_mut();
if state
&& client
.state()
.read_storage::<comp::CanBuild>()
.get(client.entity())
.is_some()
{
let (cam_dir, cam_pos) =
get_cam_data(&self.scene.camera(), &client);
{
let (cam_dir, cam_pos) = get_cam_data(&self.scene.camera(), &client);
let (d, b) = {
let terrain = client.state().terrain();
let ray =
terrain.ray(cam_pos, cam_pos + cam_dir * 100.0).cast();
(ray.0, if let Ok(Some(_)) = ray.1 { true } else { false })
};
let (d, b) = {
let terrain = client.state().terrain();
let ray = terrain.ray(cam_pos, cam_pos + cam_dir * 100.0).cast();
(ray.0, if let Ok(Some(_)) = ray.1 { true } else { false })
};
if b {
let pos = (cam_pos + cam_dir * d).map(|e| e.floor() as i32);
client.remove_block(pos);
}
} else {
// TODO: Handle secondary attack
if b {
let pos = (cam_pos + cam_dir * d).map(|e| e.floor() as i32);
client.remove_block(pos);
}
} else {
self.controller.block = state;
}
}
Event::InputUpdate(GameInput::Roll, state) => {

View File

@ -37,7 +37,7 @@ pub struct ControlSettings {
pub screenshot: KeyMouse,
pub toggle_ingame_ui: KeyMouse,
pub attack: KeyMouse,
pub second_attack: KeyMouse,
pub block: KeyMouse,
pub roll: KeyMouse,
pub interact: KeyMouse,
}
@ -69,7 +69,7 @@ impl Default for ControlSettings {
screenshot: KeyMouse::Key(VirtualKeyCode::F4),
toggle_ingame_ui: KeyMouse::Key(VirtualKeyCode::F6),
attack: KeyMouse::Mouse(MouseButton::Left),
second_attack: KeyMouse::Mouse(MouseButton::Right),
block: KeyMouse::Mouse(MouseButton::Right),
roll: KeyMouse::Mouse(MouseButton::Middle),
interact: KeyMouse::Key(VirtualKeyCode::E),
}

View File

@ -35,7 +35,7 @@ pub enum GameInput {
Screenshot,
ToggleIngameUi,
Attack,
SecondAttack,
Block,
Roll,
Respawn,
Interact,
@ -142,7 +142,7 @@ impl Window {
GameInput::ToggleIngameUi,
);
key_map.insert(settings.controls.attack, GameInput::Attack);
key_map.insert(settings.controls.second_attack, GameInput::SecondAttack);
key_map.insert(settings.controls.block, GameInput::Block);
key_map.insert(settings.controls.roll, GameInput::Roll);
key_map.insert(settings.controls.interact, GameInput::Interact);