Implemented bow skill tree.

This commit is contained in:
Sam 2020-12-22 21:28:55 -05:00
parent 4dfe14c103
commit 662a08defc
14 changed files with 225 additions and 11 deletions

View File

@ -5,7 +5,7 @@ BasicRanged(
projectile: Arrow(
damage: 80.0,
knockback: 5.0,
energy_regen: 100,
energy_regen: 50,
),
projectile_body: Object(Arrow),
projectile_light: None,

View File

@ -14,4 +14,5 @@ ChargedRanged(
projectile_gravity: Some(Gravity(0.2)),
initial_projectile_speed: 100.0,
scaled_projectile_speed: 400.0,
move_speed: 0.3,
)

View File

@ -14,5 +14,5 @@ RepeaterRanged(
projectile_light: None,
projectile_gravity: Some(Gravity(0.2)),
projectile_speed: 100.0,
reps_remaining: 5,
reps_remaining: 3,
)

View File

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

View File

@ -34,4 +34,16 @@
Hammer(LDistance): Some(2),
Hammer(LKnockback): 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),
})

View File

@ -39,4 +39,14 @@
Hammer(LDistance): {Hammer(LUnlockLeap): None},
Hammer(LKnockback): {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},
})

View File

@ -59,7 +59,20 @@
Hammer(LRange),
],
Weapon(Bow): [
Bow(ProjSpeed),
Bow(BDamage),
Bow(BRegen),
Bow(CDamage),
Bow(CKnockback),
Bow(CProjSpeed),
Bow(CDrain),
Bow(CSpeed),
Bow(CMove),
Bow(UnlockRepeater),
Bow(RDamage),
Bow(RLeap),
Bow(RArrows),
Bow(RCost),
],
Weapon(Staff): [
Staff(UnlockShockwave),

View File

@ -1186,6 +1186,64 @@ impl Client {
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" => {
self.send_msg(ClientGeneral::UnlockSkill(Skill::UnlockGroup(
SkillGroupType::Weapon(Staff),

View File

@ -87,9 +87,9 @@ impl Damage {
},
DamageSource::Projectile => {
// Critical hit
if rand::random() {
/*if rand::random() {
damage *= 1.2;
}
}*/
// Armor
damage *= 1.0 - damage_reduction;

View File

@ -189,6 +189,7 @@ pub enum CharacterAbility {
projectile_gravity: Option<Gravity>,
initial_projectile_speed: f32,
scaled_projectile_speed: f32,
move_speed: f32,
},
Shockwave {
energy_cost: u32,
@ -335,7 +336,7 @@ impl CharacterAbility {
} => {
*buildup_duration = (*buildup_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 {
ref mut movement_duration,
@ -349,7 +350,7 @@ impl CharacterAbility {
*buildup_duration = (*buildup_duration as f32 / speed) as u64;
*shoot_duration = (*shoot_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 {
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,
initial_projectile_speed,
scaled_projectile_speed,
move_speed,
} => CharacterState::ChargedRanged(charged_ranged::Data {
static_data: charged_ranged::StaticData {
buildup_duration: Duration::from_millis(*buildup_duration),
@ -1101,6 +1187,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: *move_speed,
ability_key: key,
},
timer: Duration::default(),

View File

@ -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::*;
match self {
Arrow { ref mut damage, .. } => {
Arrow {
ref mut damage,
ref mut energy_regen,
..
} => {
*damage *= power;
*energy_regen = (*energy_regen as f32 * regen) as u32;
},
Fireball { ref mut damage, .. } => {
*damage *= power;

View File

@ -142,7 +142,24 @@ pub enum HammerSkill {
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub enum BowSkill {
// Passives
ProjSpeed,
// Basic ranged upgrades
BDamage,
BRegen,
// Charged ranged upgrades
CDamage,
CKnockback,
CProjSpeed,
CDrain,
CSpeed,
CMove,
// Repeater upgrades
UnlockRepeater,
RDamage,
RLeap,
RArrows,
RCost,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]

View File

@ -42,6 +42,8 @@ pub struct StaticData {
pub projectile_gravity: Option<Gravity>,
pub initial_projectile_speed: f32,
pub scaled_projectile_speed: f32,
/// Move speed efficiency
pub move_speed: f32,
/// What key is used to press ability
pub ability_key: AbilityKey,
}
@ -63,7 +65,7 @@ impl CharacterBehavior for Data {
fn behavior(&self, data: &JoinData) -> StateUpdate {
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);
if !ability_key_is_pressed(data, self.static_data.ability_key) {
handle_interrupt(data, &mut update, false);

View File

@ -3,7 +3,7 @@ use crate::{
inventory::slot::EquipSlot,
item::{Hands, ItemKind, Tool, ToolKind},
quadruped_low, quadruped_medium,
skills::{AxeSkill, HammerSkill, Skill, SwordSkill},
skills::{AxeSkill, BowSkill, HammerSkill, Skill, SwordSkill},
theropod, Body, CharacterState, StateUpdate,
},
consts::{FRIC_GROUND, GRAVITY},
@ -512,6 +512,15 @@ pub fn handle_ability3_input(data: &JoinData, update: &mut StateUpdate) {
{
None
},
Some(ToolKind::Bow)
if !&data
.stats
.skill_set
.skills
.contains_key(&Skill::Bow(BowSkill::UnlockRepeater)) =>
{
None
},
_ => Some(s),
})
.map(|a| {