mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Implemented Flight
This commit is contained in:
parent
9e905b297a
commit
6331ad9455
@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Added Dutch translations
|
- Added Dutch translations
|
||||||
- Buff system
|
- Buff system
|
||||||
- Sneaking lets you be closer to enemies without being detected
|
- Sneaking lets you be closer to enemies without being detected
|
||||||
|
- Flight
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ https://account.veloren.net."#,
|
|||||||
"hud.chat.pvp_explosion_kill_msg": "[{attacker}] blew up [{victim}]",
|
"hud.chat.pvp_explosion_kill_msg": "[{attacker}] blew up [{victim}]",
|
||||||
"hud.chat.pvp_energy_kill_msg": "[{attacker}] killed [{victim}] with magic",
|
"hud.chat.pvp_energy_kill_msg": "[{attacker}] killed [{victim}] with magic",
|
||||||
"hud.chat.pvp_buff_kill_msg": "[{attacker}] killed [{victim}]",
|
"hud.chat.pvp_buff_kill_msg": "[{attacker}] killed [{victim}]",
|
||||||
|
|
||||||
|
|
||||||
"hud.chat.npc_melee_kill_msg": "{attacker} killed [{victim}]",
|
"hud.chat.npc_melee_kill_msg": "{attacker} killed [{victim}]",
|
||||||
"hud.chat.npc_ranged_kill_msg": "{attacker} shot [{victim}]",
|
"hud.chat.npc_ranged_kill_msg": "{attacker} shot [{victim}]",
|
||||||
@ -460,6 +460,7 @@ magically infused items?"#,
|
|||||||
"gameinput.acceptgroupinvite": "Accept Group Invite",
|
"gameinput.acceptgroupinvite": "Accept Group Invite",
|
||||||
"gameinput.declinegroupinvite": "Decline Group Invite",
|
"gameinput.declinegroupinvite": "Decline Group Invite",
|
||||||
"gameinput.crafting": "Crafting",
|
"gameinput.crafting": "Crafting",
|
||||||
|
"gameinput.fly": "Fly",
|
||||||
"gameinput.sneak": "Sneak",
|
"gameinput.sneak": "Sneak",
|
||||||
"gameinput.swimdown": "Swim downwards",
|
"gameinput.swimdown": "Swim downwards",
|
||||||
"gameinput.swimup": "Swim upwards",
|
"gameinput.swimup": "Swim upwards",
|
||||||
@ -515,13 +516,13 @@ Protection
|
|||||||
|
|
||||||
/// Buffs and Debuffs
|
/// Buffs and Debuffs
|
||||||
"buff.remove": "Click to remove",
|
"buff.remove": "Click to remove",
|
||||||
"buff.title.missing": "Missing Title",
|
"buff.title.missing": "Missing Title",
|
||||||
"buff.desc.missing": "Missing Description",
|
"buff.desc.missing": "Missing Description",
|
||||||
// Buffs
|
// Buffs
|
||||||
"buff.title.heal_test": "Heal Test",
|
"buff.title.heal_test": "Heal Test",
|
||||||
"buff.desc.heal_test": "This is a test buff to test healing.",
|
"buff.desc.heal_test": "This is a test buff to test healing.",
|
||||||
// Debuffs
|
// Debuffs
|
||||||
"debuff.title.bleed_test": "Bleeding",
|
"debuff.title.bleed_test": "Bleeding",
|
||||||
"debuff.desc.bleed_test": "Inflicts regular damage.",
|
"debuff.desc.bleed_test": "Inflicts regular damage.",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -175,12 +175,13 @@ pub struct ControllerInputs {
|
|||||||
pub jump: Input,
|
pub jump: Input,
|
||||||
pub roll: Input,
|
pub roll: Input,
|
||||||
pub glide: Input,
|
pub glide: Input,
|
||||||
|
pub fly: Input, // Flying entities only
|
||||||
pub wall_leap: Input,
|
pub wall_leap: Input,
|
||||||
pub charge: Input,
|
pub charge: Input,
|
||||||
pub climb: Option<Climb>,
|
pub climb: Option<Climb>,
|
||||||
pub swimup: Input,
|
|
||||||
pub swimdown: Input,
|
|
||||||
pub move_dir: Vec2<f32>,
|
pub move_dir: Vec2<f32>,
|
||||||
|
pub move_z: f32, /* z axis (not combined with move_dir because they may have independent
|
||||||
|
* limits) */
|
||||||
pub look_dir: Dir,
|
pub look_dir: Dir,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,10 +202,9 @@ impl ControllerInputs {
|
|||||||
self.jump.tick(dt);
|
self.jump.tick(dt);
|
||||||
self.roll.tick(dt);
|
self.roll.tick(dt);
|
||||||
self.glide.tick(dt);
|
self.glide.tick(dt);
|
||||||
|
self.fly.tick(dt);
|
||||||
self.wall_leap.tick(dt);
|
self.wall_leap.tick(dt);
|
||||||
self.charge.tick(dt);
|
self.charge.tick(dt);
|
||||||
self.swimup.tick(dt);
|
|
||||||
self.swimdown.tick(dt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick_freshness(&mut self) {
|
pub fn tick_freshness(&mut self) {
|
||||||
@ -214,10 +214,9 @@ impl ControllerInputs {
|
|||||||
self.jump.tick_freshness();
|
self.jump.tick_freshness();
|
||||||
self.roll.tick_freshness();
|
self.roll.tick_freshness();
|
||||||
self.glide.tick_freshness();
|
self.glide.tick_freshness();
|
||||||
|
self.fly.tick_freshness();
|
||||||
self.wall_leap.tick_freshness();
|
self.wall_leap.tick_freshness();
|
||||||
self.charge.tick_freshness();
|
self.charge.tick_freshness();
|
||||||
self.swimup.tick_freshness();
|
|
||||||
self.swimdown.tick_freshness();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates Controller inputs with new version received from the client
|
/// Updates Controller inputs with new version received from the client
|
||||||
@ -228,12 +227,12 @@ impl ControllerInputs {
|
|||||||
self.jump.update_with_new(new.jump);
|
self.jump.update_with_new(new.jump);
|
||||||
self.roll.update_with_new(new.roll);
|
self.roll.update_with_new(new.roll);
|
||||||
self.glide.update_with_new(new.glide);
|
self.glide.update_with_new(new.glide);
|
||||||
|
self.fly.update_with_new(new.fly);
|
||||||
self.wall_leap.update_with_new(new.wall_leap);
|
self.wall_leap.update_with_new(new.wall_leap);
|
||||||
self.charge.update_with_new(new.charge);
|
self.charge.update_with_new(new.charge);
|
||||||
self.climb = new.climb;
|
self.climb = new.climb;
|
||||||
self.swimup.update_with_new(new.swimup);
|
|
||||||
self.swimdown.update_with_new(new.swimdown);
|
|
||||||
self.move_dir = new.move_dir;
|
self.move_dir = new.move_dir;
|
||||||
|
self.move_z = new.move_z;
|
||||||
self.look_dir = new.look_dir;
|
self.look_dir = new.look_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ impl Route {
|
|||||||
vol: &V,
|
vol: &V,
|
||||||
pos: Vec3<f32>,
|
pos: Vec3<f32>,
|
||||||
vel: Vec3<f32>,
|
vel: Vec3<f32>,
|
||||||
traversal_cfg: TraversalConfig,
|
traversal_cfg: &TraversalConfig,
|
||||||
) -> Option<(Vec3<f32>, f32)>
|
) -> Option<(Vec3<f32>, f32)>
|
||||||
where
|
where
|
||||||
V: BaseVol<Vox = Block> + ReadVol,
|
V: BaseVol<Vox = Block> + ReadVol,
|
||||||
@ -364,7 +364,7 @@ impl Chaser {
|
|||||||
} else {
|
} else {
|
||||||
self.route
|
self.route
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.and_then(|(r, _)| r.traverse(vol, pos, vel, traversal_cfg))
|
.and_then(|(r, _)| r.traverse(vol, pos, vel, &traversal_cfg))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -14,6 +14,7 @@ use vek::*;
|
|||||||
|
|
||||||
pub const MOVEMENT_THRESHOLD_VEL: f32 = 3.0;
|
pub const MOVEMENT_THRESHOLD_VEL: f32 = 3.0;
|
||||||
const BASE_HUMANOID_AIR_ACCEL: f32 = 8.0;
|
const BASE_HUMANOID_AIR_ACCEL: f32 = 8.0;
|
||||||
|
const BASE_FLIGHT_ACCEL: f32 = 16.0;
|
||||||
const BASE_HUMANOID_WATER_ACCEL: f32 = 150.0;
|
const BASE_HUMANOID_WATER_ACCEL: f32 = 150.0;
|
||||||
const BASE_HUMANOID_WATER_SPEED: f32 = 180.0;
|
const BASE_HUMANOID_WATER_SPEED: f32 = 180.0;
|
||||||
// const BASE_HUMANOID_CLIMB_ACCEL: f32 = 10.0;
|
// const BASE_HUMANOID_CLIMB_ACCEL: f32 = 10.0;
|
||||||
@ -65,12 +66,23 @@ impl Body {
|
|||||||
Body::QuadrupedLow(_) => 12.0,
|
Body::QuadrupedLow(_) => 12.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn can_fly(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Body::BirdMedium(_) => true,
|
||||||
|
Body::Dragon(_) => true,
|
||||||
|
Body::BirdSmall(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles updating `Components` to move player based on state of `JoinData`
|
/// Handles updating `Components` to move player based on state of `JoinData`
|
||||||
pub fn handle_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) {
|
pub fn handle_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) {
|
||||||
if let Some(depth) = data.physics.in_fluid {
|
if let Some(depth) = data.physics.in_fluid {
|
||||||
swim_move(data, update, efficiency, depth);
|
swim_move(data, update, efficiency, depth);
|
||||||
|
} else if data.inputs.fly.is_pressed() && !data.physics.on_ground && data.body.can_fly() {
|
||||||
|
fly_move(data, update, efficiency);
|
||||||
} else {
|
} else {
|
||||||
basic_move(data, update, efficiency);
|
basic_move(data, update, efficiency);
|
||||||
}
|
}
|
||||||
@ -171,16 +183,31 @@ fn swim_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32, depth:
|
|||||||
handle_orientation(data, update, if data.physics.on_ground { 9.0 } else { 2.0 });
|
handle_orientation(data, update, if data.physics.on_ground { 9.0 } else { 2.0 });
|
||||||
|
|
||||||
// Swim
|
// Swim
|
||||||
if data.inputs.swimup.is_pressed() {
|
update.vel.0.z = (update.vel.0.z
|
||||||
update.vel.0.z = (update.vel.0.z
|
+ data.dt.0
|
||||||
+ data.dt.0 * GRAVITY * 4.0 * depth.clamped(0.0, 1.0).powf(3.0))
|
* GRAVITY
|
||||||
.min(BASE_HUMANOID_WATER_SPEED);
|
* 4.0
|
||||||
}
|
* data
|
||||||
// Swim
|
.inputs
|
||||||
if data.inputs.swimdown.is_pressed() {
|
.move_z
|
||||||
update.vel.0.z =
|
.clamped(-1.0, depth.clamped(0.0, 1.0).powf(3.0)))
|
||||||
(update.vel.0.z + data.dt.0 * GRAVITY * -3.5).min(BASE_HUMANOID_WATER_SPEED);
|
.min(BASE_HUMANOID_WATER_SPEED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Updates components to move entity as if it's flying
|
||||||
|
fn fly_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) {
|
||||||
|
// Update velocity (counteract gravity with lift)
|
||||||
|
// TODO: Do this better
|
||||||
|
update.vel.0 += Vec3::unit_z() * data.dt.0 * GRAVITY
|
||||||
|
+ Vec3::new(
|
||||||
|
data.inputs.move_dir.x,
|
||||||
|
data.inputs.move_dir.y,
|
||||||
|
data.inputs.move_z,
|
||||||
|
) * data.dt.0
|
||||||
|
* BASE_FLIGHT_ACCEL
|
||||||
|
* efficiency;
|
||||||
|
|
||||||
|
handle_orientation(data, update, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// First checks whether `primary`, `secondary` or `ability3` input is pressed,
|
/// First checks whether `primary`, `secondary` or `ability3` input is pressed,
|
||||||
|
@ -283,8 +283,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
bearing.xy().try_normalized().unwrap_or(Vec2::zero())
|
bearing.xy().try_normalized().unwrap_or(Vec2::zero())
|
||||||
* speed.min(0.2 + (dist - AVG_FOLLOW_DIST) / 8.0);
|
* speed.min(0.2 + (dist - AVG_FOLLOW_DIST) / 8.0);
|
||||||
inputs.jump.set_state(bearing.z > 1.5);
|
inputs.jump.set_state(bearing.z > 1.5);
|
||||||
inputs.swimup.set_state(bearing.z > 0.5);
|
inputs.move_z = bearing.z;
|
||||||
inputs.swimdown.set_state(bearing.z < 0.5);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
do_idle = true;
|
do_idle = true;
|
||||||
@ -388,8 +387,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
* speed
|
* speed
|
||||||
* 0.2; //Let small/slow animals flee slower than the player
|
* 0.2; //Let small/slow animals flee slower than the player
|
||||||
inputs.jump.set_state(bearing.z > 1.5);
|
inputs.jump.set_state(bearing.z > 1.5);
|
||||||
inputs.swimup.set_state(bearing.z > 0.5);
|
inputs.move_z = bearing.z;
|
||||||
inputs.swimdown.set_state(bearing.z < 0.5);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
do_idle = true;
|
do_idle = true;
|
||||||
@ -530,8 +528,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
bearing.xy().try_normalized().unwrap_or(Vec2::zero())
|
bearing.xy().try_normalized().unwrap_or(Vec2::zero())
|
||||||
* speed;
|
* speed;
|
||||||
inputs.jump.set_state(bearing.z > 1.5);
|
inputs.jump.set_state(bearing.z > 1.5);
|
||||||
inputs.swimup.set_state(bearing.z > 0.5);
|
inputs.move_z = bearing.z;
|
||||||
inputs.swimdown.set_state(bearing.z < 0.5);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ use specs::{
|
|||||||
saveload::{Marker, MarkerAllocator},
|
saveload::{Marker, MarkerAllocator},
|
||||||
Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage,
|
Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage,
|
||||||
};
|
};
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
// const CHARGE_COST: i32 = 200;
|
// const CHARGE_COST: i32 = 200;
|
||||||
// const ROLL_COST: i32 = 30;
|
// const ROLL_COST: i32 = 30;
|
||||||
@ -72,6 +73,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
} else {
|
} else {
|
||||||
inputs.move_dir
|
inputs.move_dir
|
||||||
};
|
};
|
||||||
|
inputs.move_z = inputs.move_z.clamped(-1.0, 1.0);
|
||||||
|
|
||||||
// Process other controller events
|
// Process other controller events
|
||||||
for event in controller.events.drain(..) {
|
for event in controller.events.drain(..) {
|
||||||
|
@ -7,6 +7,9 @@ pub struct KeyState {
|
|||||||
pub down: bool,
|
pub down: bool,
|
||||||
pub climb_up: bool,
|
pub climb_up: bool,
|
||||||
pub climb_down: bool,
|
pub climb_down: bool,
|
||||||
|
pub swim_up: bool,
|
||||||
|
pub swim_down: bool,
|
||||||
|
pub fly: bool,
|
||||||
pub toggle_wield: bool,
|
pub toggle_wield: bool,
|
||||||
pub toggle_glide: bool,
|
pub toggle_glide: bool,
|
||||||
pub toggle_lantern: bool,
|
pub toggle_lantern: bool,
|
||||||
@ -29,6 +32,9 @@ impl Default for KeyState {
|
|||||||
down: false,
|
down: false,
|
||||||
climb_up: false,
|
climb_up: false,
|
||||||
climb_down: false,
|
climb_down: false,
|
||||||
|
swim_up: false,
|
||||||
|
swim_down: false,
|
||||||
|
fly: false,
|
||||||
toggle_wield: false,
|
toggle_wield: false,
|
||||||
toggle_glide: false,
|
toggle_glide: false,
|
||||||
toggle_lantern: false,
|
toggle_lantern: false,
|
||||||
|
@ -356,10 +356,10 @@ impl PlayState for SessionState {
|
|||||||
self.inputs.jump.set_state(state);
|
self.inputs.jump.set_state(state);
|
||||||
},
|
},
|
||||||
Event::InputUpdate(GameInput::SwimUp, state) => {
|
Event::InputUpdate(GameInput::SwimUp, state) => {
|
||||||
self.inputs.swimup.set_state(state);
|
self.key_state.swim_up = state;
|
||||||
},
|
},
|
||||||
Event::InputUpdate(GameInput::SwimDown, state) => {
|
Event::InputUpdate(GameInput::SwimDown, state) => {
|
||||||
self.inputs.swimdown.set_state(state);
|
self.key_state.swim_down = state;
|
||||||
},
|
},
|
||||||
Event::InputUpdate(GameInput::Sit, state)
|
Event::InputUpdate(GameInput::Sit, state)
|
||||||
if state != self.key_state.toggle_sit =>
|
if state != self.key_state.toggle_sit =>
|
||||||
@ -421,6 +421,9 @@ impl PlayState for SessionState {
|
|||||||
self.client.borrow_mut().toggle_glide();
|
self.client.borrow_mut().toggle_glide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Event::InputUpdate(GameInput::Fly, state) => {
|
||||||
|
self.key_state.fly ^= state;
|
||||||
|
},
|
||||||
Event::InputUpdate(GameInput::Climb, state) => {
|
Event::InputUpdate(GameInput::Climb, state) => {
|
||||||
self.key_state.climb_up = state;
|
self.key_state.climb_up = state;
|
||||||
},
|
},
|
||||||
@ -656,6 +659,9 @@ impl PlayState for SessionState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.inputs.climb = self.key_state.climb();
|
self.inputs.climb = self.key_state.climb();
|
||||||
|
self.inputs.fly.set_state(self.key_state.fly);
|
||||||
|
self.inputs.move_z =
|
||||||
|
self.key_state.swim_up as i32 as f32 - self.key_state.swim_down as i32 as f32;
|
||||||
|
|
||||||
let mut outcomes = Vec::new();
|
let mut outcomes = Vec::new();
|
||||||
|
|
||||||
|
@ -136,6 +136,7 @@ impl ControlSettings {
|
|||||||
GameInput::ClimbDown => KeyMouse::Key(VirtualKeyCode::LControl),
|
GameInput::ClimbDown => KeyMouse::Key(VirtualKeyCode::LControl),
|
||||||
GameInput::SwimUp => KeyMouse::Key(VirtualKeyCode::Space),
|
GameInput::SwimUp => KeyMouse::Key(VirtualKeyCode::Space),
|
||||||
GameInput::SwimDown => KeyMouse::Key(VirtualKeyCode::LShift),
|
GameInput::SwimDown => KeyMouse::Key(VirtualKeyCode::LShift),
|
||||||
|
GameInput::Fly => KeyMouse::Key(VirtualKeyCode::F),
|
||||||
GameInput::Sneak => KeyMouse::Key(VirtualKeyCode::LControl),
|
GameInput::Sneak => KeyMouse::Key(VirtualKeyCode::LControl),
|
||||||
//GameInput::WallLeap => MIDDLE_CLICK_KEY,
|
//GameInput::WallLeap => MIDDLE_CLICK_KEY,
|
||||||
GameInput::ToggleLantern => KeyMouse::Key(VirtualKeyCode::G),
|
GameInput::ToggleLantern => KeyMouse::Key(VirtualKeyCode::G),
|
||||||
@ -203,6 +204,7 @@ impl Default for ControlSettings {
|
|||||||
GameInput::ClimbDown,
|
GameInput::ClimbDown,
|
||||||
GameInput::SwimUp,
|
GameInput::SwimUp,
|
||||||
GameInput::SwimDown,
|
GameInput::SwimDown,
|
||||||
|
GameInput::Fly,
|
||||||
GameInput::Sneak,
|
GameInput::Sneak,
|
||||||
//GameInput::WallLeap,
|
//GameInput::WallLeap,
|
||||||
GameInput::ToggleLantern,
|
GameInput::ToggleLantern,
|
||||||
|
@ -44,6 +44,7 @@ pub enum GameInput {
|
|||||||
ClimbDown,
|
ClimbDown,
|
||||||
SwimUp,
|
SwimUp,
|
||||||
SwimDown,
|
SwimDown,
|
||||||
|
Fly,
|
||||||
Sneak,
|
Sneak,
|
||||||
//WallLeap,
|
//WallLeap,
|
||||||
ToggleLantern,
|
ToggleLantern,
|
||||||
@ -95,6 +96,7 @@ impl GameInput {
|
|||||||
GameInput::ClimbDown => "gameinput.climbdown",
|
GameInput::ClimbDown => "gameinput.climbdown",
|
||||||
GameInput::SwimUp => "gameinput.swimup",
|
GameInput::SwimUp => "gameinput.swimup",
|
||||||
GameInput::SwimDown => "gameinput.swimdown",
|
GameInput::SwimDown => "gameinput.swimdown",
|
||||||
|
GameInput::Fly => "gameinput.fly",
|
||||||
GameInput::Sneak => "gameinput.sneak",
|
GameInput::Sneak => "gameinput.sneak",
|
||||||
//GameInput::WallLeap => "gameinput.wallleap",
|
//GameInput::WallLeap => "gameinput.wallleap",
|
||||||
GameInput::ToggleLantern => "gameinput.togglelantern",
|
GameInput::ToggleLantern => "gameinput.togglelantern",
|
||||||
@ -156,6 +158,7 @@ impl GameInput {
|
|||||||
GameInput::ClimbDown,
|
GameInput::ClimbDown,
|
||||||
GameInput::SwimUp,
|
GameInput::SwimUp,
|
||||||
GameInput::SwimDown,
|
GameInput::SwimDown,
|
||||||
|
GameInput::Fly,
|
||||||
GameInput::Sneak,
|
GameInput::Sneak,
|
||||||
GameInput::ToggleLantern,
|
GameInput::ToggleLantern,
|
||||||
GameInput::Mount,
|
GameInput::Mount,
|
||||||
|
Loading…
Reference in New Issue
Block a user