Staff skill tree.

This commit is contained in:
Sam 2020-12-24 12:54:00 -05:00
parent 662a08defc
commit 5c7705f874
10 changed files with 272 additions and 11 deletions

View File

@ -3,7 +3,7 @@ ItemDef(
description: "Shouldn't this be a hammer?", description: "Shouldn't this be a hammer?",
kind: Tool( kind: Tool(
( (
kind: Bow, kind: Staff,
stats: ( stats: (
equip_time_millis: 0, equip_time_millis: 0,
power: 1000.0, power: 1000.0,

View File

@ -46,4 +46,16 @@
Bow(RDamage): Some(2), Bow(RDamage): Some(2),
Bow(RArrows): Some(2), Bow(RArrows): Some(2),
Bow(RCost): Some(2), Bow(RCost): Some(2),
Staff(BDamage): Some(3),
Staff(BRegen): Some(2),
Staff(BRadius): Some(2),
Staff(FRange): Some(2),
Staff(FDamage): Some(3),
Staff(FDrain): Some(2),
Staff(FVelocity): Some(2),
Staff(UnlockShockwave): Some(2),
Staff(SDamage): Some(2),
Staff(SKnockback): Some(2),
Staff(SRange): Some(2),
Staff(SCost): Some(2),
}) })

View File

@ -49,4 +49,14 @@
Bow(RLeap): {Bow(UnlockRepeater): None}, Bow(RLeap): {Bow(UnlockRepeater): None},
Bow(RArrows): {Bow(UnlockRepeater): None}, Bow(RArrows): {Bow(UnlockRepeater): None},
Bow(RCost): {Bow(UnlockRepeater): None}, Bow(RCost): {Bow(UnlockRepeater): None},
Staff(BDamage): {Staff(BExplosion): None},
Staff(BRegen): {Staff(BExplosion): None},
Staff(BRadius): {Staff(BExplosion): None},
Staff(FRange): {Staff(FDamage): Some(1)},
Staff(FDrain): {Staff(FDamage): Some(1)},
Staff(FVelocity): {Staff(FDamage): Some(1)},
Staff(SDamage): {Staff(UnlockShockwave): None},
Staff(SKnockback): {Staff(UnlockShockwave): None},
Staff(SRange): {Staff(UnlockShockwave): None},
Staff(SCost): {Staff(UnlockShockwave): None},
}) })

View File

@ -75,7 +75,19 @@
Bow(RCost), Bow(RCost),
], ],
Weapon(Staff): [ Weapon(Staff): [
Staff(BExplosion),
Staff(BDamage),
Staff(BRegen),
Staff(BRadius),
Staff(FDamage),
Staff(FRange),
Staff(FDrain),
Staff(FVelocity),
Staff(UnlockShockwave), Staff(UnlockShockwave),
Staff(SDamage),
Staff(SKnockback),
Staff(SRange),
Staff(SCost),
], ],
Weapon(Sceptre): [ Weapon(Sceptre): [
Sceptre(Unlock404), Sceptre(Unlock404),

View File

@ -1249,6 +1249,71 @@ impl Client {
SkillGroupType::Weapon(Staff), SkillGroupType::Weapon(Staff),
))); )));
}, },
"@unlock staff fireball" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::BExplosion,
)));
},
"@unlock staff fireball damage" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::BDamage,
)));
},
"@unlock staff fireball regen" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::BRegen,
)));
},
"@unlock staff fireball radius" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::BRadius,
)));
},
"@unlock staff beam damage" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::FDamage,
)));
},
"@unlock staff beam range" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::FRange,
)));
},
"@unlock staff beam drain" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::FDrain,
)));
},
"@unlock staff beam velocity" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::FVelocity,
)));
},
"@unlock staff shockwave" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::UnlockShockwave,
)));
},
"@unlock staff shockwave damage" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::SDamage,
)));
},
"@unlock staff shockwave knockback" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::SKnockback,
)));
},
"@unlock staff shockwave range" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::SRange,
)));
},
"@unlock staff shockwave cost" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::Staff(
StaffSkill::SCost,
)));
},
"@unlock sceptre" => { "@unlock sceptre" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::UnlockGroup( self.send_msg(ClientGeneral::UnlockSkill(Skill::UnlockGroup(
SkillGroupType::Weapon(Sceptre), SkillGroupType::Weapon(Sceptre),

View File

@ -195,6 +195,16 @@ impl Knockback {
}, },
} }
} }
pub fn modify_strength(mut self, power: f32) -> Self {
use Knockback::*;
match self {
Away(ref mut f) | Towards(ref mut f) | Up(ref mut f) | TowardsUp(ref mut f) => {
*f *= power;
},
}
self
}
} }
pub fn get_weapons(inv: &Inventory) -> (Option<ToolKind>, Option<ToolKind>) { pub fn get_weapons(inv: &Inventory) -> (Option<ToolKind>, Option<ToolKind>) {

View File

@ -336,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, 1_f32); *projectile = projectile.modified_projectile(power, 1_f32, 1_f32);
}, },
RepeaterRanged { RepeaterRanged {
ref mut movement_duration, ref mut movement_duration,
@ -350,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, 1_f32); *projectile = projectile.modified_projectile(power, 1_f32, 1_f32);
}, },
Boost { Boost {
ref mut movement_duration, ref mut movement_duration,
@ -493,7 +493,7 @@ impl CharacterAbility {
| ChargedRanged { energy_cost, .. } | ChargedRanged { energy_cost, .. }
| Shockwave { energy_cost, .. } | Shockwave { energy_cost, .. }
| BasicBeam { energy_cost, .. } => *energy_cost, | BasicBeam { energy_cost, .. } => *energy_cost,
_ => 0, BasicBlock | Boost { .. } | ComboMelee { .. } => 0,
} }
} }
@ -829,7 +829,7 @@ impl CharacterAbility {
skills.get(&Bow(BRegen)).copied().flatten().unwrap_or(0); skills.get(&Bow(BRegen)).copied().flatten().unwrap_or(0);
let power = 1.3_f32.powi(damage_level.into()); let power = 1.3_f32.powi(damage_level.into());
let regen = 1.5_f32.powi(regen_level.into()); let regen = 1.5_f32.powi(regen_level.into());
*projectile = projectile.modified_projectile(power, regen); *projectile = projectile.modified_projectile(power, regen, 1_f32);
} }
}, },
ChargedRanged { ChargedRanged {
@ -879,7 +879,7 @@ impl CharacterAbility {
} }
if let Some(level) = skills.get(&Bow(RDamage)).copied().flatten() { if let Some(level) = skills.get(&Bow(RDamage)).copied().flatten() {
let power = 1.3_f32.powi(level.into()); let power = 1.3_f32.powi(level.into());
*projectile = projectile.modified_projectile(power, 1_f32); *projectile = projectile.modified_projectile(power, 1_f32, 1_f32);
} }
if !skills.contains_key(&Bow(RLeap)) { if !skills.contains_key(&Bow(RLeap)) {
*leap = None; *leap = None;
@ -895,6 +895,80 @@ impl CharacterAbility {
_ => {}, _ => {},
} }
}, },
ToolKind::Staff => {
use skills::StaffSkill::*;
match self {
BasicRanged {
ref mut projectile, ..
} => {
if !skills.contains_key(&Staff(BExplosion)) {
*projectile = projectile.fireball_to_firebolt();
}
{
let damage_level =
skills.get(&Staff(BDamage)).copied().flatten().unwrap_or(0);
let regen_level =
skills.get(&Staff(BRegen)).copied().flatten().unwrap_or(0);
let range_level =
skills.get(&Staff(BRadius)).copied().flatten().unwrap_or(0);
let power = 1.2_f32.powi(damage_level.into());
let regen = 1.2_f32.powi(regen_level.into());
let range = 1.1_f32.powi(range_level.into());
*projectile = projectile.modified_projectile(power, regen, range);
}
},
BasicBeam {
ref mut base_dps,
ref mut range,
ref mut energy_drain,
ref mut beam_duration,
..
} => {
if let Some(level) = skills.get(&Staff(FDamage)).copied().flatten() {
*base_dps = (*base_dps as f32 * 1.3_f32.powi(level.into())) as u32;
}
if let Some(level) = skills.get(&Staff(FRange)).copied().flatten() {
*range *= 1.25_f32.powi(level.into());
// Duration modified to keep velocity constant
*beam_duration =
(*beam_duration as f32 * 1.4_f32.powi(level.into())) as u64;
}
if let Some(level) = skills.get(&Staff(FDrain)).copied().flatten() {
*energy_drain =
(*energy_drain as f32 * 0.8_f32.powi(level.into())) as u32;
}
if let Some(level) = skills.get(&Staff(FVelocity)).copied().flatten() {
let velocity_increase = 1.25_f32.powi(level.into());
let duration_mod = 1.0 / (1.0 + velocity_increase);
*beam_duration = (*beam_duration as f32 * duration_mod) as u64;
}
},
Shockwave {
ref mut damage,
ref mut knockback,
ref mut shockwave_duration,
ref mut energy_cost,
..
} => {
if let Some(level) = skills.get(&Staff(SDamage)).copied().flatten() {
*damage = (*damage as f32 * 1.3_f32.powi(level.into())) as u32;
}
if let Some(level) = skills.get(&Staff(SKnockback)).copied().flatten() {
*knockback = knockback.modify_strength(1.3_f32.powi(level.into()));
}
if let Some(level) = skills.get(&Staff(SRange)).copied().flatten() {
*shockwave_duration = (*shockwave_duration as f32
* 1.2_f32.powi(level.into()))
as u64;
}
if let Some(level) = skills.get(&Staff(SCost)).copied().flatten() {
*energy_cost =
(*energy_cost as f32 * 0.8_f32.powi(level.into())) as u32;
}
},
_ => {},
}
},
_ => {}, _ => {},
} }
} }

View File

@ -53,6 +53,10 @@ pub enum ProjectileConstructor {
radius: f32, radius: f32,
energy_regen: u32, energy_regen: u32,
}, },
Firebolt {
damage: f32,
energy_regen: u32,
},
Heal { Heal {
heal: f32, heal: f32,
damage: f32, damage: f32,
@ -134,7 +138,24 @@ impl ProjectileConstructor {
}), }),
Effect::Vanish, Effect::Vanish,
], ],
time_left: Duration::from_secs(20), time_left: Duration::from_secs(10),
owner,
ignore_group: true,
},
Firebolt {
damage,
energy_regen,
} => Projectile {
hit_solid: vec![Effect::Vanish],
hit_entity: vec![
Effect::Damage(Some(GroupTarget::OutOfGroup), Damage {
source: DamageSource::Energy,
value: damage,
}),
Effect::RewardEnergy(energy_regen),
Effect::Vanish,
],
time_left: Duration::from_secs(10),
owner, owner,
ignore_group: true, ignore_group: true,
}, },
@ -189,7 +210,7 @@ impl ProjectileConstructor {
}), }),
Effect::Vanish, Effect::Vanish,
], ],
time_left: Duration::from_secs(20), time_left: Duration::from_secs(10),
owner, owner,
ignore_group: true, ignore_group: true,
}, },
@ -203,7 +224,7 @@ impl ProjectileConstructor {
} }
} }
pub fn modified_projectile(mut self, power: f32, regen: f32) -> Self { pub fn modified_projectile(mut self, power: f32, regen: f32, range: f32) -> Self {
use ProjectileConstructor::*; use ProjectileConstructor::*;
match self { match self {
Arrow { Arrow {
@ -214,19 +235,52 @@ impl ProjectileConstructor {
*damage *= power; *damage *= power;
*energy_regen = (*energy_regen as f32 * regen) as u32; *energy_regen = (*energy_regen as f32 * regen) as u32;
}, },
Fireball { ref mut damage, .. } => { Fireball {
ref mut damage,
ref mut energy_regen,
ref mut radius,
..
} => {
*damage *= power; *damage *= power;
*energy_regen = (*energy_regen as f32 * regen) as u32;
*radius *= range;
},
Firebolt {
ref mut damage,
ref mut energy_regen,
..
} => {
*damage *= power;
*energy_regen = (*energy_regen as f32 * regen) as u32;
}, },
Heal { Heal {
ref mut damage, ref mut damage,
ref mut heal, ref mut heal,
ref mut radius,
.. ..
} => { } => {
*damage *= power; *damage *= power;
*heal *= power; *heal *= power;
*radius *= range;
}, },
Possess => {}, Possess => {},
} }
self self
} }
pub fn fireball_to_firebolt(self) -> Self {
if let ProjectileConstructor::Fireball {
damage,
energy_regen,
..
} = self
{
ProjectileConstructor::Firebolt {
damage,
energy_regen: energy_regen * 2,
}
} else {
self
}
}
} }

View File

@ -164,7 +164,22 @@ pub enum BowSkill {
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub enum StaffSkill { pub enum StaffSkill {
// Basic ranged upgrades
BExplosion,
BDamage,
BRegen,
BRadius,
// Flamethrower upgrades
FDamage,
FRange,
FDrain,
FVelocity,
// Shockwave upgrades
UnlockShockwave, UnlockShockwave,
SDamage,
SKnockback,
SRange,
SCost,
} }
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]

View File

@ -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, BowSkill, HammerSkill, Skill, SwordSkill}, skills::{AxeSkill, BowSkill, HammerSkill, Skill, StaffSkill, SwordSkill},
theropod, Body, CharacterState, StateUpdate, theropod, Body, CharacterState, StateUpdate,
}, },
consts::{FRIC_GROUND, GRAVITY}, consts::{FRIC_GROUND, GRAVITY},
@ -521,6 +521,15 @@ pub fn handle_ability3_input(data: &JoinData, update: &mut StateUpdate) {
{ {
None None
}, },
Some(ToolKind::Staff)
if !&data
.stats
.skill_set
.skills
.contains_key(&Skill::Staff(StaffSkill::UnlockShockwave)) =>
{
None
},
_ => Some(s), _ => Some(s),
}) })
.map(|a| { .map(|a| {