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
8 changed files with 87 additions and 47 deletions

View File

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

View File

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

View File

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

View File

@ -35,22 +35,23 @@ impl<'a> System<'a> for Sys {
): Self::SystemData, ): Self::SystemData,
) { ) {
// Attacks // Attacks
for (entity, uid, pos, ori, mut character) in ( for (entity, uid, pos, ori) in (&entities, &uids, &positions, &orientations).join() {
&entities,
&uids,
&positions,
&orientations,
&mut character_states,
)
.join()
{
let mut todo_end = false; let mut todo_end = false;
// Go through all other entities // 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 { if !*applied {
for (b, pos_b, mut vel_b, stat_b) in for (b, pos_b, ori_b, character_b, mut vel_b, stat_b) in (
(&entities, &positions, &mut velocities, &mut stats).join() &entities,
&positions,
&orientations,
&character_states,
&mut velocities,
&mut stats,
)
.join()
{ {
// Check if it is a hit // Check if it is a hit
if entity != b if entity != b
@ -58,18 +59,31 @@ impl<'a> System<'a> for Sys {
&& pos.0.distance_squared(pos_b.0) < 50.0 && pos.0.distance_squared(pos_b.0) < 50.0
&& ori.0.angle_between(pos_b.0 - pos.0).to_degrees() < 90.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 // Deal damage
stat_b stat_b
.health .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 += (pos_b.0 - pos.0).normalized() * 2.0;
vel_b.0.z = 2.0; vel_b.0.z = 2.0;
let _ = force_updates.insert(b, ForceUpdate); let _ = force_updates.insert(b, ForceUpdate);
} }
} }
*applied = true;
} }
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() { if *time_left == Duration::default() {
todo_end = true; todo_end = true;
} else { } else {
@ -78,13 +92,18 @@ impl<'a> System<'a> for Sys {
.unwrap_or_default(); .unwrap_or_default();
} }
} }
}
if todo_end { if todo_end {
if let Some(character) = &mut character_states.get_mut(entity) {
character.action = Wield { character.action = Wield {
time_left: Duration::default(), 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() { if *time_left != Duration::default() {
*time_left = time_left *time_left = time_left
.checked_sub(Duration::from_secs_f32(dt.0)) .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 // Roll
if controller.roll if controller.roll
&& (character.action == Idle || character.action.is_wield()) && (character.action == Idle || character.action.is_wield())

View File

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

View File

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

View File

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