mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Block when pressing right click while looking at the attacker
This commit is contained in:
parent
e42ffb362a
commit
e7c61c30cc
@ -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)]
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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))
|
||||
|
@ -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())
|
||||
|
@ -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) => {
|
||||
|
@ -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),
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user