mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Split staff into 3 abilities
This commit is contained in:
parent
7a4f0fa9ac
commit
99e7e1f785
@ -83,8 +83,9 @@ impl CharacterAbility {
|
||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
|
||||
pub struct ItemConfig {
|
||||
pub item: Item,
|
||||
pub primary_ability: Option<CharacterAbility>,
|
||||
pub secondary_ability: Option<CharacterAbility>,
|
||||
pub ability1: Option<CharacterAbility>,
|
||||
pub ability2: Option<CharacterAbility>,
|
||||
pub ability3: Option<CharacterAbility>,
|
||||
pub block_ability: Option<CharacterAbility>,
|
||||
pub dodge_ability: Option<CharacterAbility>,
|
||||
}
|
||||
|
@ -114,6 +114,7 @@ impl Default for Input {
|
||||
pub struct ControllerInputs {
|
||||
pub primary: Input,
|
||||
pub secondary: Input,
|
||||
pub ability3: Input,
|
||||
pub sit: Input,
|
||||
pub jump: Input,
|
||||
pub roll: Input,
|
||||
@ -141,6 +142,7 @@ impl ControllerInputs {
|
||||
pub fn tick(&mut self, dt: Duration) {
|
||||
self.primary.tick(dt);
|
||||
self.secondary.tick(dt);
|
||||
self.ability3.tick(dt);
|
||||
self.sit.tick(dt);
|
||||
self.jump.tick(dt);
|
||||
self.roll.tick(dt);
|
||||
@ -153,6 +155,10 @@ impl ControllerInputs {
|
||||
self.swap_loadout.tick(dt);
|
||||
self.charge.tick(dt);
|
||||
}
|
||||
|
||||
pub fn holding_ability_key(&self) -> bool {
|
||||
self.primary.is_pressed() || self.secondary.is_pressed() || self.ability3.is_pressed()
|
||||
}
|
||||
}
|
||||
|
||||
impl Controller {
|
||||
|
@ -121,10 +121,28 @@ impl ToolData {
|
||||
BasicMelee {
|
||||
buildup_duration: Duration::from_millis(0),
|
||||
recover_duration: Duration::from_millis(300),
|
||||
base_damage: 3,
|
||||
base_damage: 1,
|
||||
range: 10.0,
|
||||
max_angle: 45.0,
|
||||
},
|
||||
BasicRanged {
|
||||
projectile: Projectile {
|
||||
hit_ground: vec![projectile::Effect::Vanish],
|
||||
hit_wall: vec![projectile::Effect::Vanish],
|
||||
hit_entity: vec![
|
||||
projectile::Effect::Damage(HealthChange {
|
||||
// TODO: This should not be fixed (?)
|
||||
amount: -2,
|
||||
cause: HealthSource::Projectile { owner: None },
|
||||
}),
|
||||
projectile::Effect::Vanish,
|
||||
],
|
||||
time_left: Duration::from_secs(20),
|
||||
owner: None,
|
||||
},
|
||||
projectile_body: Body::Object(object::Body::BoltFire),
|
||||
recover_duration: Duration::from_millis(500),
|
||||
},
|
||||
CastFireball {
|
||||
projectile: Projectile {
|
||||
hit_ground: vec![
|
||||
|
@ -31,12 +31,7 @@ impl Inventory {
|
||||
pub fn len(&self) -> usize { self.slots.len() }
|
||||
|
||||
pub fn recount_items(&mut self) {
|
||||
self.amount = 0;
|
||||
for item in self.slots.iter() {
|
||||
if let Some(item) = item {
|
||||
self.amount += 1;
|
||||
}
|
||||
}
|
||||
self.amount = self.slots.iter().filter(|i| i.is_some()).count() as u32;
|
||||
}
|
||||
|
||||
/// Adds a new item to the first fitting group of the inventory or starts a
|
||||
|
@ -27,9 +27,7 @@ impl CharacterBehavior for Data {
|
||||
handle_move(data, &mut update);
|
||||
handle_jump(data, &mut update);
|
||||
|
||||
if !self.exhausted
|
||||
&& (data.inputs.primary.is_pressed() | data.inputs.secondary.is_pressed())
|
||||
{
|
||||
if !self.exhausted && data.inputs.holding_ability_key() {
|
||||
// Prepare (draw the bow)
|
||||
update.character = CharacterState::BasicRanged(Data {
|
||||
prepare_timer: self.prepare_timer + Duration::from_secs_f32(data.dt.0),
|
||||
|
@ -27,10 +27,8 @@ impl CharacterBehavior for Data {
|
||||
handle_move(data, &mut update);
|
||||
handle_jump(data, &mut update);
|
||||
|
||||
if !self.exhausted
|
||||
&& (data.inputs.primary.is_pressed() | data.inputs.secondary.is_pressed())
|
||||
{
|
||||
// Prepare (draw the bow)
|
||||
if !self.exhausted && data.inputs.holding_ability_key() {
|
||||
// Prepare
|
||||
update.character = CharacterState::CastFireball(Data {
|
||||
prepare_timer: self.prepare_timer + Duration::from_secs_f32(data.dt.0),
|
||||
recover_duration: self.recover_duration,
|
||||
|
@ -170,15 +170,14 @@ pub fn handle_jump(data: &JoinData, update: &mut StateUpdate) {
|
||||
}
|
||||
}
|
||||
|
||||
/// If `inputs.primary` is pressed and in `Wielding` state,
|
||||
/// will attempt to go into `loadout.active_item.primary_ability`
|
||||
pub fn handle_primary_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
/// Will attempt to go into `loadout.active_item.ability1`
|
||||
pub fn handle_ability1_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
if data.inputs.primary.is_pressed() {
|
||||
if let Some(ability) = data
|
||||
.loadout
|
||||
.active_item
|
||||
.as_ref()
|
||||
.and_then(|i| i.primary_ability.as_ref())
|
||||
.and_then(|i| i.ability1.as_ref())
|
||||
.filter(|ability| ability.requirements_paid(data, update))
|
||||
{
|
||||
update.character = ability.into();
|
||||
@ -186,15 +185,29 @@ pub fn handle_primary_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
}
|
||||
}
|
||||
|
||||
/// If `inputs.secondary` is pressed and in `Wielding` state,
|
||||
/// will attempt to go into `loadout.active_item.secondary_ability`
|
||||
pub fn handle_secondary_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
/// Will attempt to go into `loadout.active_item.ability2`
|
||||
pub fn handle_ability2_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
if data.inputs.secondary.is_pressed() {
|
||||
if let Some(ability) = data
|
||||
.loadout
|
||||
.active_item
|
||||
.as_ref()
|
||||
.and_then(|i| i.secondary_ability.as_ref())
|
||||
.and_then(|i| i.ability2.as_ref())
|
||||
.filter(|ability| ability.requirements_paid(data, update))
|
||||
{
|
||||
update.character = ability.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Will attempt to go into `loadout.active_item.ability3`
|
||||
pub fn handle_ability3_input(data: &JoinData, update: &mut StateUpdate) {
|
||||
if data.inputs.ability3.is_pressed() {
|
||||
if let Some(ability) = data
|
||||
.loadout
|
||||
.active_item
|
||||
.as_ref()
|
||||
.and_then(|i| i.ability3.as_ref())
|
||||
.filter(|ability| ability.requirements_paid(data, update))
|
||||
{
|
||||
update.character = ability.into();
|
||||
|
@ -17,8 +17,9 @@ impl CharacterBehavior for Data {
|
||||
handle_glide(&data, &mut update);
|
||||
handle_unwield(&data, &mut update);
|
||||
handle_swap_loadout(&data, &mut update);
|
||||
handle_primary_input(&data, &mut update);
|
||||
handle_secondary_input(&data, &mut update);
|
||||
handle_ability1_input(&data, &mut update);
|
||||
handle_ability2_input(&data, &mut update);
|
||||
handle_ability3_input(&data, &mut update);
|
||||
handle_dodge_input(&data, &mut update);
|
||||
|
||||
update
|
||||
|
@ -86,10 +86,13 @@ pub fn handle_possess(server: &Server, possessor_uid: Uid, possesse_uid: Uid) {
|
||||
|
||||
let item = assets::load_expect_cloned::<comp::Item>("common.items.debug.possess");
|
||||
if let comp::ItemKind::Tool(tool) = item.kind {
|
||||
let mut abilities = tool.get_abilities();
|
||||
let mut ability_drain = abilities.drain(..);
|
||||
loadout.active_item = Some(comp::ItemConfig {
|
||||
item,
|
||||
primary_ability: tool.get_abilities().get(0).cloned(),
|
||||
secondary_ability: None,
|
||||
ability1: ability_drain.next(),
|
||||
ability2: ability_drain.next(),
|
||||
ability3: ability_drain.next(),
|
||||
block_ability: None,
|
||||
dodge_ability: None,
|
||||
});
|
||||
|
@ -111,8 +111,9 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
let mut ability_drain = abilities.drain(..);
|
||||
let active_item = comp::ItemConfig {
|
||||
item,
|
||||
primary_ability: ability_drain.next(),
|
||||
secondary_ability: ability_drain.next(),
|
||||
ability1: ability_drain.next(),
|
||||
ability2: ability_drain.next(),
|
||||
ability3: ability_drain.next(),
|
||||
block_ability: Some(comp::CharacterAbility::BasicBlock),
|
||||
dodge_ability: Some(comp::CharacterAbility::Roll),
|
||||
};
|
||||
|
@ -169,8 +169,9 @@ impl StateExt for State {
|
||||
comp::Loadout {
|
||||
active_item: main.map(|item| comp::ItemConfig {
|
||||
item,
|
||||
primary_ability: ability_drain.next(),
|
||||
secondary_ability: ability_drain.next(),
|
||||
ability1: ability_drain.next(),
|
||||
ability2: ability_drain.next(),
|
||||
ability3: ability_drain.next(),
|
||||
block_ability: Some(comp::CharacterAbility::BasicBlock),
|
||||
dodge_ability: Some(comp::CharacterAbility::Roll),
|
||||
}),
|
||||
|
@ -196,8 +196,9 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
main.map(|item| comp::ItemConfig {
|
||||
item,
|
||||
primary_ability: ability_drain.next(),
|
||||
secondary_ability: ability_drain.next(),
|
||||
ability1: ability_drain.next(),
|
||||
ability2: ability_drain.next(),
|
||||
ability3: ability_drain.next(),
|
||||
block_ability: None,
|
||||
dodge_ability: Some(comp::CharacterAbility::Roll),
|
||||
})
|
||||
@ -205,14 +206,15 @@ impl<'a> System<'a> for Sys {
|
||||
Some(ItemConfig {
|
||||
// We need the empty item so npcs can attack
|
||||
item: Item::empty(),
|
||||
primary_ability: Some(CharacterAbility::BasicMelee {
|
||||
ability1: Some(CharacterAbility::BasicMelee {
|
||||
buildup_duration: Duration::from_millis(0),
|
||||
recover_duration: Duration::from_millis(300),
|
||||
base_damage: 2,
|
||||
range: 3.5,
|
||||
max_angle: 60.0,
|
||||
}),
|
||||
secondary_ability: None,
|
||||
ability2: None,
|
||||
ability3: None,
|
||||
block_ability: None,
|
||||
dodge_ability: None,
|
||||
})
|
||||
@ -300,14 +302,15 @@ impl<'a> System<'a> for Sys {
|
||||
item: assets::load_expect_cloned(
|
||||
"common.items.weapons.zweihander_sword_0",
|
||||
),
|
||||
primary_ability: Some(CharacterAbility::BasicMelee {
|
||||
ability1: Some(CharacterAbility::BasicMelee {
|
||||
buildup_duration: Duration::from_millis(800),
|
||||
recover_duration: Duration::from_millis(200),
|
||||
base_damage: 13,
|
||||
range: 3.5,
|
||||
max_angle: 60.0,
|
||||
}),
|
||||
secondary_ability: None,
|
||||
ability2: None,
|
||||
ability3: None,
|
||||
block_ability: None,
|
||||
dodge_ability: None,
|
||||
}),
|
||||
|
@ -339,8 +339,9 @@ impl CharSelectionUi {
|
||||
Mode::Create { loadout, tool, .. } => {
|
||||
loadout.active_item = tool.map(|tool| comp::ItemConfig {
|
||||
item: (*load_expect::<comp::Item>(tool)).clone(),
|
||||
primary_ability: None,
|
||||
secondary_ability: None,
|
||||
ability1: None,
|
||||
ability2: None,
|
||||
ability3: None,
|
||||
block_ability: None,
|
||||
dodge_ability: None,
|
||||
});
|
||||
|
@ -275,6 +275,10 @@ impl PlayState for SessionState {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Event::InputUpdate(GameInput::Ability3, state) => {
|
||||
self.inputs.ability3.set_state(state);
|
||||
},
|
||||
Event::InputUpdate(GameInput::Roll, state) => {
|
||||
let client = self.client.borrow();
|
||||
if client
|
||||
|
@ -18,6 +18,7 @@ use std::{fs, io::prelude::*, path::PathBuf};
|
||||
pub struct ControlSettings {
|
||||
pub primary: KeyMouse,
|
||||
pub secondary: KeyMouse,
|
||||
pub ability3: KeyMouse,
|
||||
pub toggle_cursor: KeyMouse,
|
||||
pub escape: KeyMouse,
|
||||
pub enter: KeyMouse,
|
||||
@ -69,6 +70,7 @@ impl Default for ControlSettings {
|
||||
Self {
|
||||
primary: KeyMouse::Mouse(MouseButton::Left),
|
||||
secondary: KeyMouse::Mouse(MouseButton::Right),
|
||||
ability3: KeyMouse::Key(VirtualKeyCode::Key1),
|
||||
toggle_cursor: KeyMouse::Key(VirtualKeyCode::Tab),
|
||||
escape: KeyMouse::Key(VirtualKeyCode::Escape),
|
||||
enter: KeyMouse::Key(VirtualKeyCode::Return),
|
||||
|
@ -16,6 +16,7 @@ use vek::*;
|
||||
pub enum GameInput {
|
||||
Primary,
|
||||
Secondary,
|
||||
Ability3,
|
||||
ToggleCursor,
|
||||
MoveForward,
|
||||
MoveBack,
|
||||
@ -360,6 +361,9 @@ impl Window {
|
||||
map.entry(settings.controls.secondary)
|
||||
.or_default()
|
||||
.push(GameInput::Secondary);
|
||||
map.entry(settings.controls.ability3)
|
||||
.or_default()
|
||||
.push(GameInput::Ability3);
|
||||
map.entry(settings.controls.toggle_cursor)
|
||||
.or_default()
|
||||
.push(GameInput::ToggleCursor);
|
||||
|
Loading…
Reference in New Issue
Block a user