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:
@ -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)]
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
@ -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,33 +59,51 @@ 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 *time_left == Duration::default() {
|
if let Some(Attack { time_left, applied }) =
|
||||||
todo_end = true;
|
&mut character_states.get_mut(entity).map(|c| &mut c.action)
|
||||||
} else {
|
{
|
||||||
*time_left = time_left
|
// Only attack once
|
||||||
.checked_sub(Duration::from_secs_f32(dt.0))
|
*applied = true;
|
||||||
.unwrap_or_default();
|
|
||||||
|
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 {
|
if todo_end {
|
||||||
character.action = Wield {
|
if let Some(character) = &mut character_states.get_mut(entity) {
|
||||||
time_left: Duration::default(),
|
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() {
|
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))
|
||||||
|
@ -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())
|
||||||
|
@ -160,32 +160,29 @@ 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 state
|
||||||
if client
|
&& 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 })
|
};
|
||||||
};
|
|
||||||
|
|
||||||
if b {
|
if b {
|
||||||
let pos = (cam_pos + cam_dir * d).map(|e| e.floor() as i32);
|
let pos = (cam_pos + cam_dir * d).map(|e| e.floor() as i32);
|
||||||
client.remove_block(pos);
|
client.remove_block(pos);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// TODO: Handle secondary attack
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
self.controller.block = state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::InputUpdate(GameInput::Roll, state) => {
|
Event::InputUpdate(GameInput::Roll, state) => {
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user