mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Implemented bow skill tree.
This commit is contained in:
parent
4dfe14c103
commit
662a08defc
@ -5,7 +5,7 @@ BasicRanged(
|
|||||||
projectile: Arrow(
|
projectile: Arrow(
|
||||||
damage: 80.0,
|
damage: 80.0,
|
||||||
knockback: 5.0,
|
knockback: 5.0,
|
||||||
energy_regen: 100,
|
energy_regen: 50,
|
||||||
),
|
),
|
||||||
projectile_body: Object(Arrow),
|
projectile_body: Object(Arrow),
|
||||||
projectile_light: None,
|
projectile_light: None,
|
||||||
|
@ -14,4 +14,5 @@ ChargedRanged(
|
|||||||
projectile_gravity: Some(Gravity(0.2)),
|
projectile_gravity: Some(Gravity(0.2)),
|
||||||
initial_projectile_speed: 100.0,
|
initial_projectile_speed: 100.0,
|
||||||
scaled_projectile_speed: 400.0,
|
scaled_projectile_speed: 400.0,
|
||||||
|
move_speed: 0.3,
|
||||||
)
|
)
|
||||||
|
@ -14,5 +14,5 @@ RepeaterRanged(
|
|||||||
projectile_light: None,
|
projectile_light: None,
|
||||||
projectile_gravity: Some(Gravity(0.2)),
|
projectile_gravity: Some(Gravity(0.2)),
|
||||||
projectile_speed: 100.0,
|
projectile_speed: 100.0,
|
||||||
reps_remaining: 5,
|
reps_remaining: 3,
|
||||||
)
|
)
|
@ -3,7 +3,7 @@ ItemDef(
|
|||||||
description: "Shouldn't this be a hammer?",
|
description: "Shouldn't this be a hammer?",
|
||||||
kind: Tool(
|
kind: Tool(
|
||||||
(
|
(
|
||||||
kind: Hammer,
|
kind: Bow,
|
||||||
stats: (
|
stats: (
|
||||||
equip_time_millis: 0,
|
equip_time_millis: 0,
|
||||||
power: 1000.0,
|
power: 1000.0,
|
||||||
|
@ -34,4 +34,16 @@
|
|||||||
Hammer(LDistance): Some(2),
|
Hammer(LDistance): Some(2),
|
||||||
Hammer(LKnockback): Some(2),
|
Hammer(LKnockback): Some(2),
|
||||||
Hammer(LRange): Some(2),
|
Hammer(LRange): Some(2),
|
||||||
|
Bow(ProjSpeed): Some(2),
|
||||||
|
Bow(BDamage): Some(3),
|
||||||
|
Bow(BRegen): Some(2),
|
||||||
|
Bow(CDamage): Some(3),
|
||||||
|
Bow(CKnockback): Some(2),
|
||||||
|
Bow(CProjSpeed): Some(2),
|
||||||
|
Bow(CDrain): Some(2),
|
||||||
|
Bow(CSpeed): Some(2),
|
||||||
|
Bow(CMove): Some(2),
|
||||||
|
Bow(RDamage): Some(2),
|
||||||
|
Bow(RArrows): Some(2),
|
||||||
|
Bow(RCost): Some(2),
|
||||||
})
|
})
|
@ -39,4 +39,14 @@
|
|||||||
Hammer(LDistance): {Hammer(LUnlockLeap): None},
|
Hammer(LDistance): {Hammer(LUnlockLeap): None},
|
||||||
Hammer(LKnockback): {Hammer(LUnlockLeap): None},
|
Hammer(LKnockback): {Hammer(LUnlockLeap): None},
|
||||||
Hammer(LRange): {Hammer(LUnlockLeap): None},
|
Hammer(LRange): {Hammer(LUnlockLeap): None},
|
||||||
|
Bow(BRegen): {Bow(BDamage): Some(1)},
|
||||||
|
Bow(CKnockback): {Bow(CDamage): Some(1)},
|
||||||
|
Bow(CProjSpeed): {Bow(CDamage): Some(1)},
|
||||||
|
Bow(CDrain): {Bow(CDamage): Some(1)},
|
||||||
|
Bow(CSpeed): {Bow(CDamage): Some(1)},
|
||||||
|
Bow(CMove): {Bow(CDamage): Some(1)},
|
||||||
|
Bow(RDamage): {Bow(UnlockRepeater): None},
|
||||||
|
Bow(RLeap): {Bow(UnlockRepeater): None},
|
||||||
|
Bow(RArrows): {Bow(UnlockRepeater): None},
|
||||||
|
Bow(RCost): {Bow(UnlockRepeater): None},
|
||||||
})
|
})
|
@ -59,7 +59,20 @@
|
|||||||
Hammer(LRange),
|
Hammer(LRange),
|
||||||
],
|
],
|
||||||
Weapon(Bow): [
|
Weapon(Bow): [
|
||||||
|
Bow(ProjSpeed),
|
||||||
|
Bow(BDamage),
|
||||||
|
Bow(BRegen),
|
||||||
|
Bow(CDamage),
|
||||||
|
Bow(CKnockback),
|
||||||
|
Bow(CProjSpeed),
|
||||||
|
Bow(CDrain),
|
||||||
|
Bow(CSpeed),
|
||||||
|
Bow(CMove),
|
||||||
Bow(UnlockRepeater),
|
Bow(UnlockRepeater),
|
||||||
|
Bow(RDamage),
|
||||||
|
Bow(RLeap),
|
||||||
|
Bow(RArrows),
|
||||||
|
Bow(RCost),
|
||||||
],
|
],
|
||||||
Weapon(Staff): [
|
Weapon(Staff): [
|
||||||
Staff(UnlockShockwave),
|
Staff(UnlockShockwave),
|
||||||
|
@ -1186,6 +1186,64 @@ impl Client {
|
|||||||
SkillGroupType::Weapon(Bow),
|
SkillGroupType::Weapon(Bow),
|
||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
|
"@unlock bow proj speed" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(
|
||||||
|
BowSkill::ProjSpeed,
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
"@unlock bow basic damage" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(
|
||||||
|
BowSkill::BDamage,
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
"@unlock bow basic regen" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(BowSkill::BRegen)));
|
||||||
|
},
|
||||||
|
"@unlock bow charged damage" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(
|
||||||
|
BowSkill::CDamage,
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
"@unlock bow charged knockback" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(
|
||||||
|
BowSkill::CKnockback,
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
"@unlock bow charged proj speed" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(
|
||||||
|
BowSkill::CProjSpeed,
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
"@unlock bow charged drain" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(BowSkill::CDrain)));
|
||||||
|
},
|
||||||
|
"@unlock bow charged speed" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(BowSkill::CSpeed)));
|
||||||
|
},
|
||||||
|
"@unlock bow charged move" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(BowSkill::CMove)));
|
||||||
|
},
|
||||||
|
"@unlock bow repeater" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(
|
||||||
|
BowSkill::UnlockRepeater,
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
"@unlock bow repeater damage" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(
|
||||||
|
BowSkill::RDamage,
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
"@unlock bow repeater leap" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(BowSkill::RLeap)));
|
||||||
|
},
|
||||||
|
"@unlock bow repeater arrows" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(
|
||||||
|
BowSkill::RArrows,
|
||||||
|
)));
|
||||||
|
},
|
||||||
|
"@unlock bow repeater cost" => {
|
||||||
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::Bow(BowSkill::RCost)));
|
||||||
|
},
|
||||||
"@unlock staff" => {
|
"@unlock staff" => {
|
||||||
self.send_msg(ClientGeneral::UnlockSkill(Skill::UnlockGroup(
|
self.send_msg(ClientGeneral::UnlockSkill(Skill::UnlockGroup(
|
||||||
SkillGroupType::Weapon(Staff),
|
SkillGroupType::Weapon(Staff),
|
||||||
|
@ -87,9 +87,9 @@ impl Damage {
|
|||||||
},
|
},
|
||||||
DamageSource::Projectile => {
|
DamageSource::Projectile => {
|
||||||
// Critical hit
|
// Critical hit
|
||||||
if rand::random() {
|
/*if rand::random() {
|
||||||
damage *= 1.2;
|
damage *= 1.2;
|
||||||
}
|
}*/
|
||||||
// Armor
|
// Armor
|
||||||
damage *= 1.0 - damage_reduction;
|
damage *= 1.0 - damage_reduction;
|
||||||
|
|
||||||
|
@ -189,6 +189,7 @@ pub enum CharacterAbility {
|
|||||||
projectile_gravity: Option<Gravity>,
|
projectile_gravity: Option<Gravity>,
|
||||||
initial_projectile_speed: f32,
|
initial_projectile_speed: f32,
|
||||||
scaled_projectile_speed: f32,
|
scaled_projectile_speed: f32,
|
||||||
|
move_speed: f32,
|
||||||
},
|
},
|
||||||
Shockwave {
|
Shockwave {
|
||||||
energy_cost: u32,
|
energy_cost: u32,
|
||||||
@ -335,7 +336,7 @@ impl CharacterAbility {
|
|||||||
} => {
|
} => {
|
||||||
*buildup_duration = (*buildup_duration as f32 / speed) as u64;
|
*buildup_duration = (*buildup_duration as f32 / speed) as u64;
|
||||||
*recover_duration = (*recover_duration as f32 / speed) as u64;
|
*recover_duration = (*recover_duration as f32 / speed) as u64;
|
||||||
*projectile = projectile.modified_projectile(power);
|
*projectile = projectile.modified_projectile(power, 1_f32);
|
||||||
},
|
},
|
||||||
RepeaterRanged {
|
RepeaterRanged {
|
||||||
ref mut movement_duration,
|
ref mut movement_duration,
|
||||||
@ -349,7 +350,7 @@ impl CharacterAbility {
|
|||||||
*buildup_duration = (*buildup_duration as f32 / speed) as u64;
|
*buildup_duration = (*buildup_duration as f32 / speed) as u64;
|
||||||
*shoot_duration = (*shoot_duration as f32 / speed) as u64;
|
*shoot_duration = (*shoot_duration as f32 / speed) as u64;
|
||||||
*recover_duration = (*recover_duration as f32 / speed) as u64;
|
*recover_duration = (*recover_duration as f32 / speed) as u64;
|
||||||
*projectile = projectile.modified_projectile(power);
|
*projectile = projectile.modified_projectile(power, 1_f32);
|
||||||
},
|
},
|
||||||
Boost {
|
Boost {
|
||||||
ref mut movement_duration,
|
ref mut movement_duration,
|
||||||
@ -810,6 +811,90 @@ impl CharacterAbility {
|
|||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
ToolKind::Bow => {
|
||||||
|
use skills::BowSkill::*;
|
||||||
|
match self {
|
||||||
|
BasicRanged {
|
||||||
|
ref mut projectile,
|
||||||
|
ref mut projectile_speed,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
if let Some(level) = skills.get(&Bow(ProjSpeed)).copied().flatten() {
|
||||||
|
*projectile_speed *= 1.5_f32.powi(level.into());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let damage_level =
|
||||||
|
skills.get(&Bow(BDamage)).copied().flatten().unwrap_or(0);
|
||||||
|
let regen_level =
|
||||||
|
skills.get(&Bow(BRegen)).copied().flatten().unwrap_or(0);
|
||||||
|
let power = 1.3_f32.powi(damage_level.into());
|
||||||
|
let regen = 1.5_f32.powi(regen_level.into());
|
||||||
|
*projectile = projectile.modified_projectile(power, regen);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ChargedRanged {
|
||||||
|
ref mut scaled_damage,
|
||||||
|
ref mut scaled_knockback,
|
||||||
|
ref mut energy_drain,
|
||||||
|
ref mut speed,
|
||||||
|
ref mut initial_projectile_speed,
|
||||||
|
ref mut scaled_projectile_speed,
|
||||||
|
ref mut move_speed,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
if let Some(level) = skills.get(&Bow(ProjSpeed)).copied().flatten() {
|
||||||
|
*initial_projectile_speed *= 1.5_f32.powi(level.into());
|
||||||
|
}
|
||||||
|
if let Some(level) = skills.get(&Bow(CDamage)).copied().flatten() {
|
||||||
|
*scaled_damage =
|
||||||
|
(*scaled_damage as f32 * 1.25_f32.powi(level.into())) as u32;
|
||||||
|
}
|
||||||
|
if let Some(level) = skills.get(&Bow(CKnockback)).copied().flatten() {
|
||||||
|
*scaled_knockback *= 1.5_f32.powi(level.into());
|
||||||
|
}
|
||||||
|
if let Some(level) = skills.get(&Bow(CProjSpeed)).copied().flatten() {
|
||||||
|
*scaled_projectile_speed *= 1.2_f32.powi(level.into());
|
||||||
|
}
|
||||||
|
if let Some(level) = skills.get(&Bow(CDrain)).copied().flatten() {
|
||||||
|
*energy_drain =
|
||||||
|
(*energy_drain as f32 * 0.75_f32.powi(level.into())) as u32;
|
||||||
|
}
|
||||||
|
if let Some(level) = skills.get(&Bow(CSpeed)).copied().flatten() {
|
||||||
|
*speed *= 1.25_f32.powi(level.into());
|
||||||
|
}
|
||||||
|
if let Some(level) = skills.get(&Bow(CMove)).copied().flatten() {
|
||||||
|
*move_speed *= 1.25_f32.powi(level.into());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RepeaterRanged {
|
||||||
|
ref mut energy_cost,
|
||||||
|
ref mut leap,
|
||||||
|
ref mut projectile,
|
||||||
|
ref mut reps_remaining,
|
||||||
|
ref mut projectile_speed,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
if let Some(level) = skills.get(&Bow(ProjSpeed)).copied().flatten() {
|
||||||
|
*projectile_speed *= 1.5_f32.powi(level.into());
|
||||||
|
}
|
||||||
|
if let Some(level) = skills.get(&Bow(RDamage)).copied().flatten() {
|
||||||
|
let power = 1.3_f32.powi(level.into());
|
||||||
|
*projectile = projectile.modified_projectile(power, 1_f32);
|
||||||
|
}
|
||||||
|
if !skills.contains_key(&Bow(RLeap)) {
|
||||||
|
*leap = None;
|
||||||
|
}
|
||||||
|
if let Some(level) = skills.get(&Bow(RArrows)).copied().flatten() {
|
||||||
|
*reps_remaining += level as u32;
|
||||||
|
}
|
||||||
|
if let Some(level) = skills.get(&Bow(RCost)).copied().flatten() {
|
||||||
|
*energy_cost =
|
||||||
|
(*energy_cost as f32 * 0.75_f32.powi(level.into())) as u32;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1085,6 +1170,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
|||||||
projectile_gravity,
|
projectile_gravity,
|
||||||
initial_projectile_speed,
|
initial_projectile_speed,
|
||||||
scaled_projectile_speed,
|
scaled_projectile_speed,
|
||||||
|
move_speed,
|
||||||
} => CharacterState::ChargedRanged(charged_ranged::Data {
|
} => CharacterState::ChargedRanged(charged_ranged::Data {
|
||||||
static_data: charged_ranged::StaticData {
|
static_data: charged_ranged::StaticData {
|
||||||
buildup_duration: Duration::from_millis(*buildup_duration),
|
buildup_duration: Duration::from_millis(*buildup_duration),
|
||||||
@ -1101,6 +1187,7 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
|||||||
projectile_gravity: *projectile_gravity,
|
projectile_gravity: *projectile_gravity,
|
||||||
initial_projectile_speed: *initial_projectile_speed,
|
initial_projectile_speed: *initial_projectile_speed,
|
||||||
scaled_projectile_speed: *scaled_projectile_speed,
|
scaled_projectile_speed: *scaled_projectile_speed,
|
||||||
|
move_speed: *move_speed,
|
||||||
ability_key: key,
|
ability_key: key,
|
||||||
},
|
},
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
|
@ -203,11 +203,16 @@ impl ProjectileConstructor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn modified_projectile(mut self, power: f32) -> Self {
|
pub fn modified_projectile(mut self, power: f32, regen: f32) -> Self {
|
||||||
use ProjectileConstructor::*;
|
use ProjectileConstructor::*;
|
||||||
match self {
|
match self {
|
||||||
Arrow { ref mut damage, .. } => {
|
Arrow {
|
||||||
|
ref mut damage,
|
||||||
|
ref mut energy_regen,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
*damage *= power;
|
*damage *= power;
|
||||||
|
*energy_regen = (*energy_regen as f32 * regen) as u32;
|
||||||
},
|
},
|
||||||
Fireball { ref mut damage, .. } => {
|
Fireball { ref mut damage, .. } => {
|
||||||
*damage *= power;
|
*damage *= power;
|
||||||
|
@ -142,7 +142,24 @@ pub enum HammerSkill {
|
|||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum BowSkill {
|
pub enum BowSkill {
|
||||||
|
// Passives
|
||||||
|
ProjSpeed,
|
||||||
|
// Basic ranged upgrades
|
||||||
|
BDamage,
|
||||||
|
BRegen,
|
||||||
|
// Charged ranged upgrades
|
||||||
|
CDamage,
|
||||||
|
CKnockback,
|
||||||
|
CProjSpeed,
|
||||||
|
CDrain,
|
||||||
|
CSpeed,
|
||||||
|
CMove,
|
||||||
|
// Repeater upgrades
|
||||||
UnlockRepeater,
|
UnlockRepeater,
|
||||||
|
RDamage,
|
||||||
|
RLeap,
|
||||||
|
RArrows,
|
||||||
|
RCost,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
@ -42,6 +42,8 @@ pub struct StaticData {
|
|||||||
pub projectile_gravity: Option<Gravity>,
|
pub projectile_gravity: Option<Gravity>,
|
||||||
pub initial_projectile_speed: f32,
|
pub initial_projectile_speed: f32,
|
||||||
pub scaled_projectile_speed: f32,
|
pub scaled_projectile_speed: f32,
|
||||||
|
/// Move speed efficiency
|
||||||
|
pub move_speed: f32,
|
||||||
/// What key is used to press ability
|
/// What key is used to press ability
|
||||||
pub ability_key: AbilityKey,
|
pub ability_key: AbilityKey,
|
||||||
}
|
}
|
||||||
@ -63,7 +65,7 @@ impl CharacterBehavior for Data {
|
|||||||
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate::from(data);
|
let mut update = StateUpdate::from(data);
|
||||||
|
|
||||||
handle_move(data, &mut update, 0.3);
|
handle_move(data, &mut update, self.static_data.move_speed);
|
||||||
handle_jump(data, &mut update);
|
handle_jump(data, &mut update);
|
||||||
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
if !ability_key_is_pressed(data, self.static_data.ability_key) {
|
||||||
handle_interrupt(data, &mut update, false);
|
handle_interrupt(data, &mut update, false);
|
||||||
|
@ -3,7 +3,7 @@ use crate::{
|
|||||||
inventory::slot::EquipSlot,
|
inventory::slot::EquipSlot,
|
||||||
item::{Hands, ItemKind, Tool, ToolKind},
|
item::{Hands, ItemKind, Tool, ToolKind},
|
||||||
quadruped_low, quadruped_medium,
|
quadruped_low, quadruped_medium,
|
||||||
skills::{AxeSkill, HammerSkill, Skill, SwordSkill},
|
skills::{AxeSkill, BowSkill, HammerSkill, Skill, SwordSkill},
|
||||||
theropod, Body, CharacterState, StateUpdate,
|
theropod, Body, CharacterState, StateUpdate,
|
||||||
},
|
},
|
||||||
consts::{FRIC_GROUND, GRAVITY},
|
consts::{FRIC_GROUND, GRAVITY},
|
||||||
@ -512,6 +512,15 @@ pub fn handle_ability3_input(data: &JoinData, update: &mut StateUpdate) {
|
|||||||
{
|
{
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
Some(ToolKind::Bow)
|
||||||
|
if !&data
|
||||||
|
.stats
|
||||||
|
.skill_set
|
||||||
|
.skills
|
||||||
|
.contains_key(&Skill::Bow(BowSkill::UnlockRepeater)) =>
|
||||||
|
{
|
||||||
|
None
|
||||||
|
},
|
||||||
_ => Some(s),
|
_ => Some(s),
|
||||||
})
|
})
|
||||||
.map(|a| {
|
.map(|a| {
|
||||||
|
Loading…
Reference in New Issue
Block a user