mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'sam/rework-bow' into 'master'
Bow Rework See merge request veloren/veloren!2310
This commit is contained in:
commit
285904a850
@ -23,10 +23,10 @@
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
Tool(Bow): (
|
Tool(Bow): (
|
||||||
primary: "common.abilities.bow.basic",
|
primary: "common.abilities.bow.charged",
|
||||||
secondary: "common.abilities.bow.charged",
|
secondary: "common.abilities.bow.repeater",
|
||||||
abilities: [
|
abilities: [
|
||||||
(Some(Bow(UnlockRepeater)), "common.abilities.bow.repeater"),
|
(Some(Bow(UnlockShotgun)), "common.abilities.bow.shotgun"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Custom("Husk"): (
|
Custom("Husk"): (
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
ChargedRanged(
|
ChargedRanged(
|
||||||
energy_cost: 1,
|
energy_cost: 0,
|
||||||
energy_drain: 300,
|
energy_drain: 0,
|
||||||
initial_damage: 10,
|
initial_regen: 50,
|
||||||
scaled_damage: 190,
|
scaled_regen: 150,
|
||||||
initial_knockback: 10.0,
|
initial_damage: 50,
|
||||||
|
scaled_damage: 200,
|
||||||
|
initial_knockback: 0.0,
|
||||||
scaled_knockback: 10.0,
|
scaled_knockback: 10.0,
|
||||||
speed: 1.0,
|
speed: 1.0,
|
||||||
buildup_duration: 0.1,
|
buildup_duration: 0.2,
|
||||||
charge_duration: 1.5,
|
charge_duration: 2.0,
|
||||||
recover_duration: 0.5,
|
recover_duration: 0.3,
|
||||||
projectile_body: Object(MultiArrow),
|
projectile_body: Object(Arrow),
|
||||||
projectile_light: None,
|
projectile_light: None,
|
||||||
initial_projectile_speed: 120.0,
|
initial_projectile_speed: 100.0,
|
||||||
scaled_projectile_speed: 160.0,
|
scaled_projectile_speed: 150.0,
|
||||||
move_speed: 0.3,
|
move_speed: 0.6,
|
||||||
damage_kind: Piercing,
|
|
||||||
)
|
)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
RepeaterRanged(
|
RepeaterRanged(
|
||||||
energy_cost: 450,
|
energy_cost: 50,
|
||||||
movement_duration: 0.3,
|
|
||||||
buildup_duration: 0.2,
|
buildup_duration: 0.2,
|
||||||
shoot_duration: 0.2,
|
shoot_duration: 1.0,
|
||||||
recover_duration: 0.8,
|
recover_duration: 0.8,
|
||||||
leap: Some(5.0),
|
max_speed: 5.0,
|
||||||
|
half_speed_at: 4,
|
||||||
projectile: Arrow(
|
projectile: Arrow(
|
||||||
damage: 40.0,
|
damage: 40.0,
|
||||||
knockback: 5.0,
|
knockback: 5.0,
|
||||||
@ -12,6 +12,5 @@ RepeaterRanged(
|
|||||||
),
|
),
|
||||||
projectile_body: Object(Arrow),
|
projectile_body: Object(Arrow),
|
||||||
projectile_light: None,
|
projectile_light: None,
|
||||||
projectile_speed: 120.0,
|
projectile_speed: 100.0,
|
||||||
reps_remaining: 3,
|
|
||||||
)
|
)
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
BasicRanged(
|
BasicRanged(
|
||||||
energy_cost: 0,
|
energy_cost: 450,
|
||||||
buildup_duration: 0.4,
|
buildup_duration: 0.4,
|
||||||
recover_duration: 0.3,
|
recover_duration: 0.3,
|
||||||
|
projectile_spread: 0.05,
|
||||||
projectile: Arrow(
|
projectile: Arrow(
|
||||||
damage: 90.0,
|
damage: 40.0,
|
||||||
knockback: 5.0,
|
knockback: 5.0,
|
||||||
energy_regen: 40,
|
energy_regen: 0,
|
||||||
),
|
),
|
||||||
projectile_body: Object(Arrow),
|
projectile_body: Object(Arrow),
|
||||||
projectile_light: None,
|
projectile_light: None,
|
||||||
projectile_speed: 120.0,
|
projectile_speed: 60.0,
|
||||||
|
num_projectiles: 4,
|
||||||
)
|
)
|
@ -10,4 +10,6 @@ BasicRanged(
|
|||||||
projectile_body: Object(Arrow),
|
projectile_body: Object(Arrow),
|
||||||
projectile_light: None,
|
projectile_light: None,
|
||||||
projectile_speed: 100.0,
|
projectile_speed: 100.0,
|
||||||
|
num_projectiles: 1,
|
||||||
|
projectile_spread: 0.0,
|
||||||
)
|
)
|
||||||
|
@ -14,4 +14,6 @@ BasicRanged(
|
|||||||
}),*/
|
}),*/
|
||||||
projectile_gravity: Some(Gravity(0.15)),
|
projectile_gravity: Some(Gravity(0.15)),
|
||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
|
num_projectiles: 1,
|
||||||
|
projectile_spread: 0.0,
|
||||||
)
|
)
|
||||||
|
@ -14,4 +14,6 @@ BasicRanged(
|
|||||||
}),*/
|
}),*/
|
||||||
projectile_gravity: Some(Gravity(0.15)),
|
projectile_gravity: Some(Gravity(0.15)),
|
||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
|
num_projectiles: 1,
|
||||||
|
projectile_spread: 0.0,
|
||||||
)
|
)
|
||||||
|
@ -10,4 +10,6 @@ BasicRanged(
|
|||||||
projectile_body: Object(ClayRocket),
|
projectile_body: Object(ClayRocket),
|
||||||
projectile_light: None,
|
projectile_light: None,
|
||||||
projectile_speed: 30.0,
|
projectile_speed: 30.0,
|
||||||
|
num_projectiles: 1,
|
||||||
|
projectile_spread: 0.0,
|
||||||
)
|
)
|
||||||
|
@ -8,5 +8,7 @@ BasicRanged(
|
|||||||
),
|
),
|
||||||
projectile_body: Object(FireworkPurple),
|
projectile_body: Object(FireworkPurple),
|
||||||
projectile_speed: 100.0,
|
projectile_speed: 100.0,
|
||||||
|
num_projectiles: 1,
|
||||||
|
projectile_spread: 0.0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,4 +13,6 @@ BasicRanged(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
}),*/
|
}),*/
|
||||||
projectile_speed: 70.0,
|
projectile_speed: 70.0,
|
||||||
|
num_projectiles: 1,
|
||||||
|
projectile_spread: 0.0,
|
||||||
)
|
)
|
||||||
|
@ -10,4 +10,6 @@ BasicRanged(
|
|||||||
projectile_body: Object(ArrowTurret),
|
projectile_body: Object(ArrowTurret),
|
||||||
projectile_light: None,
|
projectile_light: None,
|
||||||
projectile_speed: 130.0,
|
projectile_speed: 130.0,
|
||||||
|
num_projectiles: 1,
|
||||||
|
projectile_spread: 0.0,
|
||||||
)
|
)
|
||||||
|
@ -12,4 +12,6 @@ BasicRanged(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
}),*/
|
}),*/
|
||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
|
num_projectiles: 1,
|
||||||
|
projectile_spread: 0.0,
|
||||||
)
|
)
|
||||||
|
@ -9,4 +9,6 @@ BasicRanged(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
}),*/
|
}),*/
|
||||||
projectile_speed: 100.0,
|
projectile_speed: 100.0,
|
||||||
|
num_projectiles: 1,
|
||||||
|
projectile_spread: 0.0,
|
||||||
)
|
)
|
@ -1,5 +1,5 @@
|
|||||||
LeapMelee(
|
LeapMelee(
|
||||||
energy_cost: 700,
|
energy_cost: 500,
|
||||||
buildup_duration: 0.1,
|
buildup_duration: 0.1,
|
||||||
movement_duration: 0.8,
|
movement_duration: 0.8,
|
||||||
swing_duration: 0.15,
|
swing_duration: 0.15,
|
||||||
|
@ -9,4 +9,6 @@ BasicRanged(
|
|||||||
),
|
),
|
||||||
projectile_body: Object(BoltFire),
|
projectile_body: Object(BoltFire),
|
||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
|
num_projectiles: 1,
|
||||||
|
projectile_spread: 0.0,
|
||||||
)
|
)
|
||||||
|
@ -13,4 +13,6 @@ BasicRanged(
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
}),*/
|
}),*/
|
||||||
projectile_speed: 60.0,
|
projectile_speed: 60.0,
|
||||||
|
num_projectiles: 1,
|
||||||
|
projectile_spread: 0.0,
|
||||||
)
|
)
|
||||||
|
@ -36,17 +36,18 @@
|
|||||||
Hammer(LKnockback): Some(2),
|
Hammer(LKnockback): Some(2),
|
||||||
Hammer(LRange): Some(2),
|
Hammer(LRange): Some(2),
|
||||||
Bow(ProjSpeed): Some(2),
|
Bow(ProjSpeed): Some(2),
|
||||||
Bow(BDamage): Some(3),
|
|
||||||
Bow(BRegen): Some(2),
|
|
||||||
Bow(CDamage): Some(3),
|
Bow(CDamage): Some(3),
|
||||||
|
Bow(CRegen): Some(2),
|
||||||
Bow(CKnockback): Some(2),
|
Bow(CKnockback): Some(2),
|
||||||
Bow(CProjSpeed): Some(2),
|
|
||||||
Bow(CDrain): Some(2),
|
|
||||||
Bow(CSpeed): Some(2),
|
Bow(CSpeed): Some(2),
|
||||||
Bow(CMove): Some(2),
|
Bow(CMove): Some(2),
|
||||||
Bow(RDamage): Some(2),
|
Bow(RDamage): Some(3),
|
||||||
Bow(RArrows): Some(2),
|
|
||||||
Bow(RCost): Some(2),
|
Bow(RCost): Some(2),
|
||||||
|
Bow(RSpeed): Some(2),
|
||||||
|
Bow(SDamage): Some(2),
|
||||||
|
Bow(SCost): Some(2),
|
||||||
|
Bow(SArrows): Some(2),
|
||||||
|
Bow(SSpread): Some(2),
|
||||||
Staff(BDamage): Some(3),
|
Staff(BDamage): Some(3),
|
||||||
Staff(BRegen): Some(2),
|
Staff(BRegen): Some(2),
|
||||||
Staff(BRadius): Some(3),
|
Staff(BRadius): Some(3),
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
Hammer(LDistance): {Hammer(UnlockLeap): None},
|
Hammer(LDistance): {Hammer(UnlockLeap): None},
|
||||||
Hammer(LKnockback): {Hammer(UnlockLeap): None},
|
Hammer(LKnockback): {Hammer(UnlockLeap): None},
|
||||||
Hammer(LRange): {Hammer(UnlockLeap): None},
|
Hammer(LRange): {Hammer(UnlockLeap): None},
|
||||||
Bow(RDamage): {Bow(UnlockRepeater): None},
|
Bow(SDamage): {Bow(UnlockShotgun): None},
|
||||||
Bow(RGlide): {Bow(UnlockRepeater): None},
|
Bow(SCost): {Bow(UnlockShotgun): None},
|
||||||
Bow(RArrows): {Bow(UnlockRepeater): None},
|
Bow(SArrows): {Bow(UnlockShotgun): None},
|
||||||
Bow(RCost): {Bow(UnlockRepeater): None},
|
Bow(SSpread): {Bow(UnlockShotgun): None},
|
||||||
Staff(SDamage): {Staff(UnlockShockwave): None},
|
Staff(SDamage): {Staff(UnlockShockwave): None},
|
||||||
Staff(SKnockback): {Staff(UnlockShockwave): None},
|
Staff(SKnockback): {Staff(UnlockShockwave): None},
|
||||||
Staff(SRange): {Staff(UnlockShockwave): None},
|
Staff(SRange): {Staff(UnlockShockwave): None},
|
||||||
|
@ -67,19 +67,19 @@
|
|||||||
],
|
],
|
||||||
Weapon(Bow): [
|
Weapon(Bow): [
|
||||||
Bow(ProjSpeed),
|
Bow(ProjSpeed),
|
||||||
Bow(BDamage),
|
|
||||||
Bow(BRegen),
|
|
||||||
Bow(CDamage),
|
Bow(CDamage),
|
||||||
|
Bow(CRegen),
|
||||||
Bow(CKnockback),
|
Bow(CKnockback),
|
||||||
Bow(CProjSpeed),
|
|
||||||
Bow(CDrain),
|
|
||||||
Bow(CSpeed),
|
Bow(CSpeed),
|
||||||
Bow(CMove),
|
Bow(CMove),
|
||||||
Bow(UnlockRepeater),
|
|
||||||
Bow(RDamage),
|
Bow(RDamage),
|
||||||
Bow(RGlide),
|
|
||||||
Bow(RArrows),
|
|
||||||
Bow(RCost),
|
Bow(RCost),
|
||||||
|
Bow(RSpeed),
|
||||||
|
Bow(UnlockShotgun),
|
||||||
|
Bow(SDamage),
|
||||||
|
Bow(SCost),
|
||||||
|
Bow(SArrows),
|
||||||
|
Bow(SSpread),
|
||||||
],
|
],
|
||||||
Weapon(Staff): [
|
Weapon(Staff): [
|
||||||
Staff(BDamage),
|
Staff(BDamage),
|
||||||
|
@ -76,21 +76,23 @@
|
|||||||
(UnlockGroup(Weapon(Bow)), 1),
|
(UnlockGroup(Weapon(Bow)), 1),
|
||||||
|
|
||||||
(Bow(ProjSpeed), 2),
|
(Bow(ProjSpeed), 2),
|
||||||
(Bow(BDamage), 3),
|
|
||||||
(Bow(BRegen), 2),
|
|
||||||
|
|
||||||
(Bow(CDamage), 3),
|
(Bow(CDamage), 3),
|
||||||
(Bow(CKnockback), 2),
|
(Bow(CKnockback), 2),
|
||||||
(Bow(CProjSpeed), 2),
|
|
||||||
(Bow(CDrain), 2),
|
|
||||||
(Bow(CSpeed), 2),
|
(Bow(CSpeed), 2),
|
||||||
|
(Bow(CRegen), 2),
|
||||||
(Bow(CMove), 2),
|
(Bow(CMove), 2),
|
||||||
|
|
||||||
(Bow(UnlockRepeater), 1),
|
(Bow(RDamage), 3),
|
||||||
(Bow(RGlide), 1),
|
|
||||||
(Bow(RDamage), 2),
|
|
||||||
(Bow(RArrows), 2),
|
|
||||||
(Bow(RCost), 2),
|
(Bow(RCost), 2),
|
||||||
|
(Bow(RSpeed), 2),
|
||||||
|
|
||||||
|
(Bow(UnlockShotgun), 1),
|
||||||
|
(Bow(SDamage), 2),
|
||||||
|
(Bow(SCost), 2),
|
||||||
|
(Bow(SArrows), 2),
|
||||||
|
(Bow(SSpread), 2),
|
||||||
|
|
||||||
// Staff
|
// Staff
|
||||||
(UnlockGroup(Weapon(Staff)), 1),
|
(UnlockGroup(Weapon(Staff)), 1),
|
||||||
|
|
||||||
@ -126,4 +128,40 @@
|
|||||||
(Sceptre(ARange), 2),
|
(Sceptre(ARange), 2),
|
||||||
(Sceptre(ACost), 2),
|
(Sceptre(ACost), 2),
|
||||||
],
|
],
|
||||||
|
// Basic skill preset to unlock all abilities
|
||||||
|
"basic": [
|
||||||
|
// General skills
|
||||||
|
|
||||||
|
// Sword
|
||||||
|
(UnlockGroup(Weapon(Sword)), 1),
|
||||||
|
|
||||||
|
(Sword(InterruptingAttacks), 1),
|
||||||
|
(Sword(DInfinite), 1),
|
||||||
|
(Sword(UnlockSpin), 1),
|
||||||
|
|
||||||
|
// Axe
|
||||||
|
(UnlockGroup(Weapon(Axe)), 1),
|
||||||
|
|
||||||
|
(Axe(SInfinite), 1),
|
||||||
|
(Axe(UnlockLeap), 1),
|
||||||
|
|
||||||
|
// Hammer
|
||||||
|
(UnlockGroup(Weapon(Hammer)), 1),
|
||||||
|
|
||||||
|
(Hammer(UnlockLeap), 1),
|
||||||
|
// Bow
|
||||||
|
(UnlockGroup(Weapon(Bow)), 1),
|
||||||
|
|
||||||
|
(Bow(UnlockShotgun), 1),
|
||||||
|
|
||||||
|
// Staff
|
||||||
|
(UnlockGroup(Weapon(Staff)), 1),
|
||||||
|
|
||||||
|
(Staff(UnlockShockwave), 1),
|
||||||
|
|
||||||
|
// Sceptre
|
||||||
|
(UnlockGroup(Weapon(Sceptre)), 1),
|
||||||
|
|
||||||
|
(Sceptre(UnlockAura), 1),
|
||||||
|
],
|
||||||
})
|
})
|
||||||
|
@ -104,36 +104,36 @@
|
|||||||
// Bow
|
// Bow
|
||||||
"hud.skill.bow_projectile_speed_title" : "Projectile Speed",
|
"hud.skill.bow_projectile_speed_title" : "Projectile Speed",
|
||||||
"hud.skill.bow_projectile_speed" : "Allows you to shoot arrows further, faster, by 30%{SP}",
|
"hud.skill.bow_projectile_speed" : "Allows you to shoot arrows further, faster, by 30%{SP}",
|
||||||
"hud.skill.bow_arrow_count_title" : "Arrow Count",
|
|
||||||
"hud.skill.bow_arrow_count" : "shoot an additional arrow when you leap{SP}",
|
|
||||||
"hud.skill.bow_repeater_cost_title" : "Repeater Cost",
|
|
||||||
"hud.skill.bow_repeater_cost" : "Decreases the energy cost to become a gliding repeater by 30%{SP}",
|
|
||||||
"hud.skill.bow_repeater_glide_title" : "Repeater Glide",
|
|
||||||
"hud.skill.bow_repeater_glide" : "Glide further while repeating{SP}",
|
|
||||||
"hud.skill.bow_repeater_damage_title" : "Repeater Damage",
|
|
||||||
"hud.skill.bow_repeater_damage" : "Increases the damage done by 40%{SP}",
|
|
||||||
"hud.skill.bow_repeater_unlock_title" : "Repeater Unlock",
|
|
||||||
"hud.skill.bow_repeater_unlock" : "Unlocks the ability to leap in the air and shoot a barrage of arrows{SP}",
|
|
||||||
"hud.skill.bow_charged_title" : "Charged Shoot",
|
"hud.skill.bow_charged_title" : "Charged Shoot",
|
||||||
"hud.skill.bow_charged" : "Because you waited longer",
|
"hud.skill.bow_charged" : "Because you waited longer",
|
||||||
"hud.skill.bow_charged_knockback_title" : "Charged Knockback",
|
|
||||||
"hud.skill.bow_charged_knockback" : "Knock enemies further back by 25%{SP}",
|
|
||||||
"hud.skill.bow_charged_move_speed_title" : "Charged Move Speed",
|
|
||||||
"hud.skill.bow_charged_move_speed" : "Increases how fast you can shuffle while charging the attack by 25%{SP}",
|
|
||||||
"hud.skill.bow_charged_speed_title" : "Charged Speed",
|
|
||||||
"hud.skill.bow_charged_speed" : "Increases the rate that you charge the attack by 10%{SP}",
|
|
||||||
"hud.skill.bow_charged_projectile_speed_title" : "Charged Projectile Speed",
|
|
||||||
"hud.skill.bow_charged_projectile_speed" : "Projectile speed increased by an additional 20% while charging{SP}",
|
|
||||||
"hud.skill.bow_charged_drain_title" : "Charged Drain",
|
|
||||||
"hud.skill.bow_charged_drain" : "Decreases the rate of stamina drain by 15%{SP}",
|
|
||||||
"hud.skill.bow_charged_damage_title" : "Charged Damage",
|
"hud.skill.bow_charged_damage_title" : "Charged Damage",
|
||||||
"hud.skill.bow_charged_damage" : "Increases damage by 20%{SP}",
|
"hud.skill.bow_charged_damage" : "Increases damage by 20%{SP}",
|
||||||
"hud.skill.bow_energy_regen_title" : "Energy Regen",
|
"hud.skill.bow_charged_energy_regen_title" : "Charged Regen",
|
||||||
"hud.skill.bow_energy_regen" : "Increases stamina gain by 40%{SP}",
|
"hud.skill.bow_charged_energy_regen" : "Increases stamina recovery by 20%{SP}",
|
||||||
"hud.skill.bow_title" : "Arrow Shoot",
|
"hud.skill.bow_charged_knockback_title" : "Charged Knockback",
|
||||||
"hud.skill.bow" : "Infinite quiver included, not suitable for children",
|
"hud.skill.bow_charged_knockback" : "Knock enemies further back by 20%{SP}",
|
||||||
"hud.skill.bow_damage_title" : "Damage",
|
"hud.skill.bow_charged_speed_title" : "Charged Speed",
|
||||||
"hud.skill.bow_damage" : "Increases damage by 25%{SP}",
|
"hud.skill.bow_charged_speed" : "Increases the rate that you charge the attack by 10%{SP}",
|
||||||
|
"hud.skill.bow_charged_move_title" : "Charged Move Speed",
|
||||||
|
"hud.skill.bow_charged_move" : "Increases how fast you can shuffle while charging the attack by 10%{SP}",
|
||||||
|
"hud.skill.bow_repeater_title" : "Repeater",
|
||||||
|
"hud.skill.bow_repeater" : "Shoots faster the longer you fire for",
|
||||||
|
"hud.skill.bow_repeater_damage_title" : "Repeater Damage",
|
||||||
|
"hud.skill.bow_repeater_damage" : "Increases the damage done by 20%{SP}",
|
||||||
|
"hud.skill.bow_repeater_cost_title" : "Repeater Cost",
|
||||||
|
"hud.skill.bow_repeater_cost" : "Decreases the energy cost to become a repeater by 20%{SP}",
|
||||||
|
"hud.skill.bow_repeater_speed_title" : "Repeater Speed",
|
||||||
|
"hud.skill.bow_repeater_speed" : "Increases the rate at which you fire arrows by 20%{SP}",
|
||||||
|
"hud.skill.bow_shotgun_unlock_title" : "Unlocks Shotgun",
|
||||||
|
"hud.skill.bow_shotgun_unlock" : "Unlocks ability to fire multiple arrows at once{SP}",
|
||||||
|
"hud.skill.bow_shotgun_damage_title" : "Shotgun Damage",
|
||||||
|
"hud.skill.bow_shotgun_damage" : "Increases the damage done by 20%{SP}",
|
||||||
|
"hud.skill.bow_shotgun_cost_title" : "Shotgun Cost",
|
||||||
|
"hud.skill.bow_shotgun_cost" : "Decreases the cost of shotgun by 20%{SP}",
|
||||||
|
"hud.skill.bow_shotgun_arrow_count_title" : "Shotgun Arrows",
|
||||||
|
"hud.skill.bow_shotgun_arrow_count" : "Increases the number of arrows in the burst by 1{SP}",
|
||||||
|
"hud.skill.bow_shotgun_spread_title" : "Shotgun Spread",
|
||||||
|
"hud.skill.bow_shotgun_spread" : "Decreases the spread of the arrows by 20%{SP}",
|
||||||
// Hammer
|
// Hammer
|
||||||
"hud.skill.hmr_leap_radius_title" : "Leap Radius",
|
"hud.skill.hmr_leap_radius_title" : "Leap Radius",
|
||||||
"hud.skill.hmr_leap_radius" : "Increases attack radius on ground slam by 1 meter{SP}",
|
"hud.skill.hmr_leap_radius" : "Increases attack radius on ground slam by 1 meter{SP}",
|
||||||
|
@ -912,3 +912,13 @@ impl ArgumentSpec {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_loading_skill_presets() {
|
||||||
|
SkillPresetManifest::load_expect("server.manifests.presets");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -79,19 +79,20 @@ pub enum CharacterAbility {
|
|||||||
projectile_body: Body,
|
projectile_body: Body,
|
||||||
projectile_light: Option<LightEmitter>,
|
projectile_light: Option<LightEmitter>,
|
||||||
projectile_speed: f32,
|
projectile_speed: f32,
|
||||||
|
num_projectiles: u32,
|
||||||
|
projectile_spread: f32,
|
||||||
},
|
},
|
||||||
RepeaterRanged {
|
RepeaterRanged {
|
||||||
energy_cost: f32,
|
energy_cost: f32,
|
||||||
movement_duration: f32,
|
|
||||||
buildup_duration: f32,
|
buildup_duration: f32,
|
||||||
shoot_duration: f32,
|
shoot_duration: f32,
|
||||||
recover_duration: f32,
|
recover_duration: f32,
|
||||||
leap: Option<f32>,
|
max_speed: f32,
|
||||||
|
half_speed_at: u32,
|
||||||
projectile: ProjectileConstructor,
|
projectile: ProjectileConstructor,
|
||||||
projectile_body: Body,
|
projectile_body: Body,
|
||||||
projectile_light: Option<LightEmitter>,
|
projectile_light: Option<LightEmitter>,
|
||||||
projectile_speed: f32,
|
projectile_speed: f32,
|
||||||
reps_remaining: u32,
|
|
||||||
},
|
},
|
||||||
Boost {
|
Boost {
|
||||||
movement_duration: f32,
|
movement_duration: f32,
|
||||||
@ -201,6 +202,8 @@ pub enum CharacterAbility {
|
|||||||
ChargedRanged {
|
ChargedRanged {
|
||||||
energy_cost: f32,
|
energy_cost: f32,
|
||||||
energy_drain: f32,
|
energy_drain: f32,
|
||||||
|
initial_regen: f32,
|
||||||
|
scaled_regen: f32,
|
||||||
initial_damage: f32,
|
initial_damage: f32,
|
||||||
scaled_damage: f32,
|
scaled_damage: f32,
|
||||||
initial_knockback: f32,
|
initial_knockback: f32,
|
||||||
@ -214,7 +217,6 @@ pub enum CharacterAbility {
|
|||||||
initial_projectile_speed: f32,
|
initial_projectile_speed: f32,
|
||||||
scaled_projectile_speed: f32,
|
scaled_projectile_speed: f32,
|
||||||
move_speed: f32,
|
move_speed: f32,
|
||||||
damage_kind: DamageKind,
|
|
||||||
},
|
},
|
||||||
Shockwave {
|
Shockwave {
|
||||||
energy_cost: f32,
|
energy_cost: f32,
|
||||||
@ -340,14 +342,9 @@ impl CharacterAbility {
|
|||||||
.energy
|
.energy
|
||||||
.try_change_by(-(*energy_cost as i32), EnergySource::Ability)
|
.try_change_by(-(*energy_cost as i32), EnergySource::Ability)
|
||||||
.is_ok(),
|
.is_ok(),
|
||||||
CharacterAbility::RepeaterRanged {
|
// Consumes energy within state, so value only checked before entering state
|
||||||
energy_cost, leap, ..
|
CharacterAbility::RepeaterRanged { energy_cost, .. } => {
|
||||||
} => {
|
update.energy.current() as f32 >= *energy_cost
|
||||||
(leap.is_none() || update.vel.0.z >= 0.0)
|
|
||||||
&& update
|
|
||||||
.energy
|
|
||||||
.try_change_by(-(*energy_cost as i32), EnergySource::Ability)
|
|
||||||
.is_ok()
|
|
||||||
},
|
},
|
||||||
CharacterAbility::LeapMelee { energy_cost, .. } => {
|
CharacterAbility::LeapMelee { energy_cost, .. } => {
|
||||||
update.vel.0.z >= 0.0
|
update.vel.0.z >= 0.0
|
||||||
@ -414,14 +411,12 @@ impl CharacterAbility {
|
|||||||
*projectile = projectile.modified_projectile(power, 1_f32, 1_f32);
|
*projectile = projectile.modified_projectile(power, 1_f32, 1_f32);
|
||||||
},
|
},
|
||||||
RepeaterRanged {
|
RepeaterRanged {
|
||||||
ref mut movement_duration,
|
|
||||||
ref mut buildup_duration,
|
ref mut buildup_duration,
|
||||||
ref mut shoot_duration,
|
ref mut shoot_duration,
|
||||||
ref mut recover_duration,
|
ref mut recover_duration,
|
||||||
ref mut projectile,
|
ref mut projectile,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
*movement_duration /= speed;
|
|
||||||
*buildup_duration /= speed;
|
*buildup_duration /= speed;
|
||||||
*shoot_duration /= speed;
|
*shoot_duration /= speed;
|
||||||
*recover_duration /= speed;
|
*recover_duration /= speed;
|
||||||
@ -944,81 +939,90 @@ impl CharacterAbility {
|
|||||||
Some(ToolKind::Bow) => {
|
Some(ToolKind::Bow) => {
|
||||||
use skills::BowSkill::*;
|
use skills::BowSkill::*;
|
||||||
match self {
|
match self {
|
||||||
BasicRanged {
|
|
||||||
ref mut projectile,
|
|
||||||
ref mut projectile_speed,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
if let Ok(Some(level)) = skillset.skill_level(Bow(ProjSpeed)) {
|
|
||||||
*projectile_speed *= 1.3_f32.powi(level.into());
|
|
||||||
}
|
|
||||||
let damage_level = skillset
|
|
||||||
.skill_level(Bow(BDamage))
|
|
||||||
.unwrap_or(None)
|
|
||||||
.unwrap_or(0);
|
|
||||||
let regen_level = skillset
|
|
||||||
.skill_level(Bow(BRegen))
|
|
||||||
.unwrap_or(None)
|
|
||||||
.unwrap_or(0);
|
|
||||||
let power = 1.20_f32.powi(damage_level.into());
|
|
||||||
let regen = 1.4_f32.powi(regen_level.into());
|
|
||||||
*projectile = projectile.modified_projectile(power, regen, 1_f32);
|
|
||||||
},
|
|
||||||
ChargedRanged {
|
ChargedRanged {
|
||||||
|
ref mut initial_damage,
|
||||||
ref mut scaled_damage,
|
ref mut scaled_damage,
|
||||||
|
ref mut initial_regen,
|
||||||
|
ref mut scaled_regen,
|
||||||
|
ref mut initial_knockback,
|
||||||
ref mut scaled_knockback,
|
ref mut scaled_knockback,
|
||||||
ref mut energy_drain,
|
|
||||||
ref mut speed,
|
ref mut speed,
|
||||||
|
ref mut move_speed,
|
||||||
ref mut initial_projectile_speed,
|
ref mut initial_projectile_speed,
|
||||||
ref mut scaled_projectile_speed,
|
ref mut scaled_projectile_speed,
|
||||||
ref mut move_speed,
|
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Ok(Some(level)) = skillset.skill_level(Bow(ProjSpeed)) {
|
if let Ok(Some(level)) = skillset.skill_level(Bow(ProjSpeed)) {
|
||||||
*initial_projectile_speed *= 1.3_f32.powi(level.into());
|
let projectile_speed_scaling = 1.2_f32.powi(level.into());
|
||||||
|
*initial_projectile_speed *= projectile_speed_scaling;
|
||||||
|
*scaled_projectile_speed *= projectile_speed_scaling;
|
||||||
}
|
}
|
||||||
if let Ok(Some(level)) = skillset.skill_level(Bow(CDamage)) {
|
if let Ok(Some(level)) = skillset.skill_level(Bow(CDamage)) {
|
||||||
*scaled_damage *= 1.2_f32.powi(level.into());
|
let damage_scaling = 1.2_f32.powi(level.into());
|
||||||
|
*initial_damage *= damage_scaling;
|
||||||
|
*scaled_damage *= damage_scaling;
|
||||||
|
}
|
||||||
|
if let Ok(Some(level)) = skillset.skill_level(Bow(CRegen)) {
|
||||||
|
let regen_scaling = 1.2_f32.powi(level.into());
|
||||||
|
*initial_regen *= regen_scaling;
|
||||||
|
*scaled_regen *= regen_scaling;
|
||||||
}
|
}
|
||||||
if let Ok(Some(level)) = skillset.skill_level(Bow(CKnockback)) {
|
if let Ok(Some(level)) = skillset.skill_level(Bow(CKnockback)) {
|
||||||
*scaled_knockback *= 1.25_f32.powi(level.into());
|
let knockback_scaling = 1.2_f32.powi(level.into());
|
||||||
}
|
*initial_knockback *= knockback_scaling;
|
||||||
if let Ok(Some(level)) = skillset.skill_level(Bow(CProjSpeed)) {
|
*scaled_knockback *= knockback_scaling;
|
||||||
*scaled_projectile_speed *= 1.2_f32.powi(level.into());
|
|
||||||
}
|
|
||||||
if let Ok(Some(level)) = skillset.skill_level(Bow(CDrain)) {
|
|
||||||
*energy_drain *= 0.85_f32.powi(level.into());
|
|
||||||
}
|
}
|
||||||
if let Ok(Some(level)) = skillset.skill_level(Bow(CSpeed)) {
|
if let Ok(Some(level)) = skillset.skill_level(Bow(CSpeed)) {
|
||||||
*speed *= 1.10_f32.powi(level.into());
|
*speed *= 1.1_f32.powi(level.into());
|
||||||
}
|
}
|
||||||
if let Ok(Some(level)) = skillset.skill_level(Bow(CMove)) {
|
if let Ok(Some(level)) = skillset.skill_level(Bow(CMove)) {
|
||||||
*move_speed *= 1.25_f32.powi(level.into());
|
*move_speed *= 1.1_f32.powi(level.into());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
RepeaterRanged {
|
RepeaterRanged {
|
||||||
ref mut energy_cost,
|
ref mut energy_cost,
|
||||||
ref mut buildup_duration,
|
|
||||||
ref mut projectile,
|
ref mut projectile,
|
||||||
ref mut reps_remaining,
|
ref mut max_speed,
|
||||||
ref mut projectile_speed,
|
ref mut projectile_speed,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Ok(Some(level)) = skillset.skill_level(Bow(ProjSpeed)) {
|
if let Ok(Some(level)) = skillset.skill_level(Bow(ProjSpeed)) {
|
||||||
*projectile_speed *= 1.3_f32.powi(level.into());
|
*projectile_speed *= 1.2_f32.powi(level.into());
|
||||||
}
|
}
|
||||||
if let Ok(Some(level)) = skillset.skill_level(Bow(RDamage)) {
|
if let Ok(Some(level)) = skillset.skill_level(Bow(RDamage)) {
|
||||||
let power = 1.4_f32.powi(level.into());
|
let power = 1.2_f32.powi(level.into());
|
||||||
*projectile = projectile.modified_projectile(power, 1_f32, 1_f32);
|
*projectile = projectile.modified_projectile(power, 1_f32, 1_f32);
|
||||||
}
|
}
|
||||||
if !skillset.has_skill(Bow(RGlide)) {
|
|
||||||
*buildup_duration = 0.001;
|
|
||||||
}
|
|
||||||
if let Ok(Some(level)) = skillset.skill_level(Bow(RArrows)) {
|
|
||||||
*reps_remaining += level as u32;
|
|
||||||
}
|
|
||||||
if let Ok(Some(level)) = skillset.skill_level(Bow(RCost)) {
|
if let Ok(Some(level)) = skillset.skill_level(Bow(RCost)) {
|
||||||
*energy_cost *= 0.70_f32.powi(level.into());
|
*energy_cost *= 0.8_f32.powi(level.into());
|
||||||
|
}
|
||||||
|
if let Ok(Some(level)) = skillset.skill_level(Bow(RSpeed)) {
|
||||||
|
*max_speed *= 1.2_f32.powi(level.into());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
BasicRanged {
|
||||||
|
ref mut projectile,
|
||||||
|
ref mut energy_cost,
|
||||||
|
ref mut num_projectiles,
|
||||||
|
ref mut projectile_spread,
|
||||||
|
ref mut projectile_speed,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
if let Ok(Some(level)) = skillset.skill_level(Bow(ProjSpeed)) {
|
||||||
|
*projectile_speed *= 1.2_f32.powi(level.into());
|
||||||
|
}
|
||||||
|
if let Ok(Some(level)) = skillset.skill_level(Bow(SDamage)) {
|
||||||
|
let power = 1.2_f32.powi(level.into());
|
||||||
|
*projectile = projectile.modified_projectile(power, 1_f32, 1_f32);
|
||||||
|
}
|
||||||
|
if let Ok(Some(level)) = skillset.skill_level(Bow(SCost)) {
|
||||||
|
*energy_cost *= 0.8_f32.powi(level.into());
|
||||||
|
}
|
||||||
|
if let Ok(Some(level)) = skillset.skill_level(Bow(SArrows)) {
|
||||||
|
*num_projectiles += level as u32;
|
||||||
|
}
|
||||||
|
if let Ok(Some(level)) = skillset.skill_level(Bow(SSpread)) {
|
||||||
|
*projectile_spread *= 0.8_f32.powi(level.into());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
@ -1233,6 +1237,8 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
|||||||
projectile_light,
|
projectile_light,
|
||||||
projectile_speed,
|
projectile_speed,
|
||||||
energy_cost: _,
|
energy_cost: _,
|
||||||
|
num_projectiles,
|
||||||
|
projectile_spread,
|
||||||
} => CharacterState::BasicRanged(basic_ranged::Data {
|
} => CharacterState::BasicRanged(basic_ranged::Data {
|
||||||
static_data: basic_ranged::StaticData {
|
static_data: basic_ranged::StaticData {
|
||||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||||
@ -1241,6 +1247,8 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
|||||||
projectile_body: *projectile_body,
|
projectile_body: *projectile_body,
|
||||||
projectile_light: *projectile_light,
|
projectile_light: *projectile_light,
|
||||||
projectile_speed: *projectile_speed,
|
projectile_speed: *projectile_speed,
|
||||||
|
num_projectiles: *num_projectiles,
|
||||||
|
projectile_spread: *projectile_spread,
|
||||||
ability_info,
|
ability_info,
|
||||||
},
|
},
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
@ -1500,6 +1508,8 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
|||||||
CharacterAbility::ChargedRanged {
|
CharacterAbility::ChargedRanged {
|
||||||
energy_cost: _,
|
energy_cost: _,
|
||||||
energy_drain,
|
energy_drain,
|
||||||
|
initial_regen,
|
||||||
|
scaled_regen,
|
||||||
initial_damage,
|
initial_damage,
|
||||||
scaled_damage,
|
scaled_damage,
|
||||||
initial_knockback,
|
initial_knockback,
|
||||||
@ -1513,13 +1523,14 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
|||||||
initial_projectile_speed,
|
initial_projectile_speed,
|
||||||
scaled_projectile_speed,
|
scaled_projectile_speed,
|
||||||
move_speed,
|
move_speed,
|
||||||
damage_kind,
|
|
||||||
} => CharacterState::ChargedRanged(charged_ranged::Data {
|
} => CharacterState::ChargedRanged(charged_ranged::Data {
|
||||||
static_data: charged_ranged::StaticData {
|
static_data: charged_ranged::StaticData {
|
||||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||||
charge_duration: Duration::from_secs_f32(*charge_duration),
|
charge_duration: Duration::from_secs_f32(*charge_duration),
|
||||||
recover_duration: Duration::from_secs_f32(*recover_duration),
|
recover_duration: Duration::from_secs_f32(*recover_duration),
|
||||||
energy_drain: *energy_drain,
|
energy_drain: *energy_drain,
|
||||||
|
initial_regen: *initial_regen,
|
||||||
|
scaled_regen: *scaled_regen,
|
||||||
initial_damage: *initial_damage,
|
initial_damage: *initial_damage,
|
||||||
scaled_damage: *scaled_damage,
|
scaled_damage: *scaled_damage,
|
||||||
speed: *speed,
|
speed: *speed,
|
||||||
@ -1531,31 +1542,31 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
|||||||
scaled_projectile_speed: *scaled_projectile_speed,
|
scaled_projectile_speed: *scaled_projectile_speed,
|
||||||
move_speed: *move_speed,
|
move_speed: *move_speed,
|
||||||
ability_info,
|
ability_info,
|
||||||
damage_kind: *damage_kind,
|
|
||||||
},
|
},
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
stage_section: StageSection::Buildup,
|
stage_section: StageSection::Buildup,
|
||||||
exhausted: false,
|
exhausted: false,
|
||||||
}),
|
}),
|
||||||
CharacterAbility::RepeaterRanged {
|
CharacterAbility::RepeaterRanged {
|
||||||
energy_cost: _,
|
energy_cost,
|
||||||
movement_duration,
|
|
||||||
buildup_duration,
|
buildup_duration,
|
||||||
shoot_duration,
|
shoot_duration,
|
||||||
recover_duration,
|
recover_duration,
|
||||||
leap,
|
max_speed,
|
||||||
|
half_speed_at,
|
||||||
projectile,
|
projectile,
|
||||||
projectile_body,
|
projectile_body,
|
||||||
projectile_light,
|
projectile_light,
|
||||||
projectile_speed,
|
projectile_speed,
|
||||||
reps_remaining,
|
|
||||||
} => CharacterState::RepeaterRanged(repeater_ranged::Data {
|
} => CharacterState::RepeaterRanged(repeater_ranged::Data {
|
||||||
static_data: repeater_ranged::StaticData {
|
static_data: repeater_ranged::StaticData {
|
||||||
movement_duration: Duration::from_secs_f32(*movement_duration),
|
|
||||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||||
shoot_duration: Duration::from_secs_f32(*shoot_duration),
|
shoot_duration: Duration::from_secs_f32(*shoot_duration),
|
||||||
recover_duration: Duration::from_secs_f32(*recover_duration),
|
recover_duration: Duration::from_secs_f32(*recover_duration),
|
||||||
leap: *leap,
|
energy_cost: *energy_cost,
|
||||||
|
// 1.0 is subtracted as 1.0 is added in state file
|
||||||
|
max_speed: *max_speed - 1.0,
|
||||||
|
half_speed_at: *half_speed_at,
|
||||||
projectile: *projectile,
|
projectile: *projectile,
|
||||||
projectile_body: *projectile_body,
|
projectile_body: *projectile_body,
|
||||||
projectile_light: *projectile_light,
|
projectile_light: *projectile_light,
|
||||||
@ -1563,8 +1574,9 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
|||||||
ability_info,
|
ability_info,
|
||||||
},
|
},
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
stage_section: StageSection::Movement,
|
stage_section: StageSection::Buildup,
|
||||||
reps_remaining: *reps_remaining,
|
projectiles_fired: 0,
|
||||||
|
speed: 1.0,
|
||||||
}),
|
}),
|
||||||
CharacterAbility::Shockwave {
|
CharacterAbility::Shockwave {
|
||||||
energy_cost: _,
|
energy_cost: _,
|
||||||
|
@ -12,7 +12,7 @@ use specs::Component;
|
|||||||
use specs_idvs::IdvStorage;
|
use specs_idvs::IdvStorage;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub enum Effect {
|
pub enum Effect {
|
||||||
Attack(Attack),
|
Attack(Attack),
|
||||||
Explode(Explosion),
|
Explode(Explosion),
|
||||||
@ -21,7 +21,7 @@ pub enum Effect {
|
|||||||
Possess,
|
Possess,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Projectile {
|
pub struct Projectile {
|
||||||
// TODO: use SmallVec for these effects
|
// TODO: use SmallVec for these effects
|
||||||
pub hit_solid: Vec<Effect>,
|
pub hit_solid: Vec<Effect>,
|
||||||
|
@ -183,22 +183,22 @@ pub enum HammerSkill {
|
|||||||
pub enum BowSkill {
|
pub enum BowSkill {
|
||||||
// Passives
|
// Passives
|
||||||
ProjSpeed,
|
ProjSpeed,
|
||||||
// Basic ranged upgrades
|
// Charged upgrades
|
||||||
BDamage,
|
|
||||||
BRegen,
|
|
||||||
// Charged ranged upgrades
|
|
||||||
CDamage,
|
CDamage,
|
||||||
|
CRegen,
|
||||||
CKnockback,
|
CKnockback,
|
||||||
CProjSpeed,
|
|
||||||
CDrain,
|
|
||||||
CSpeed,
|
CSpeed,
|
||||||
CMove,
|
CMove,
|
||||||
// Repeater upgrades
|
// Repeater upgrades
|
||||||
UnlockRepeater,
|
|
||||||
RDamage,
|
RDamage,
|
||||||
RGlide,
|
|
||||||
RArrows,
|
|
||||||
RCost,
|
RCost,
|
||||||
|
RSpeed,
|
||||||
|
// Shotgun upgrades
|
||||||
|
UnlockShotgun,
|
||||||
|
SDamage,
|
||||||
|
SCost,
|
||||||
|
SArrows,
|
||||||
|
SSpread,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
@ -51,11 +51,11 @@ impl SkillSetBuilder {
|
|||||||
// Bow
|
// Bow
|
||||||
Self::default()
|
Self::default()
|
||||||
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
||||||
.with_skill(Skill::Bow(BowSkill::BDamage), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
||||||
},
|
},
|
||||||
_ => Self::default(),
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
@ -66,11 +66,11 @@ impl SkillSetBuilder {
|
|||||||
// Bow
|
// Bow
|
||||||
Self::default()
|
Self::default()
|
||||||
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
||||||
.with_skill(Skill::Bow(BowSkill::BDamage), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
||||||
},
|
},
|
||||||
_ => Self::default(),
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
@ -81,11 +81,11 @@ impl SkillSetBuilder {
|
|||||||
// Bow
|
// Bow
|
||||||
Self::default()
|
Self::default()
|
||||||
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
||||||
.with_skill(Skill::Bow(BowSkill::BDamage), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
||||||
},
|
},
|
||||||
_ => Self::default(),
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
@ -96,11 +96,11 @@ impl SkillSetBuilder {
|
|||||||
// Bow
|
// Bow
|
||||||
Self::default()
|
Self::default()
|
||||||
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
||||||
.with_skill(Skill::Bow(BowSkill::BDamage), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
||||||
},
|
},
|
||||||
_ => Self::default(),
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
@ -111,11 +111,11 @@ impl SkillSetBuilder {
|
|||||||
// Bow
|
// Bow
|
||||||
Self::default()
|
Self::default()
|
||||||
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
||||||
.with_skill(Skill::Bow(BowSkill::BDamage), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
||||||
},
|
},
|
||||||
_ => Self::default(),
|
_ => Self::default(),
|
||||||
}
|
}
|
||||||
@ -176,11 +176,11 @@ impl SkillSetBuilder {
|
|||||||
// Bow
|
// Bow
|
||||||
Self::default()
|
Self::default()
|
||||||
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
||||||
.with_skill(Skill::Bow(BowSkill::BDamage), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::ProjSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::ProjSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CProjSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::RSpeed), Some(1))
|
||||||
},
|
},
|
||||||
Some(ToolKind::Staff) => {
|
Some(ToolKind::Staff) => {
|
||||||
// Staff
|
// Staff
|
||||||
@ -234,13 +234,13 @@ impl SkillSetBuilder {
|
|||||||
// Bow
|
// Bow
|
||||||
Self::default()
|
Self::default()
|
||||||
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
||||||
.with_skill(Skill::Bow(BowSkill::BDamage), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::UnlockRepeater), None)
|
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::RArrows), Some(1))
|
.with_skill(Skill::Bow(BowSkill::UnlockShotgun), None)
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SArrows), Some(1))
|
||||||
},
|
},
|
||||||
Some(ToolKind::Staff) => {
|
Some(ToolKind::Staff) => {
|
||||||
// Staff
|
// Staff
|
||||||
@ -303,14 +303,14 @@ impl SkillSetBuilder {
|
|||||||
// Bow
|
// Bow
|
||||||
Self::default()
|
Self::default()
|
||||||
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
||||||
.with_skill(Skill::Bow(BowSkill::BDamage), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::ProjSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::ProjSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::BRegen), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CDrain), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CRegen), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::UnlockRepeater), None)
|
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::RGlide), None)
|
.with_skill(Skill::Bow(BowSkill::RCost), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::UnlockShotgun), None)
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SCost), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::RCost), Some(1))
|
.with_skill(Skill::Bow(BowSkill::RCost), Some(1))
|
||||||
},
|
},
|
||||||
Some(ToolKind::Staff) => {
|
Some(ToolKind::Staff) => {
|
||||||
@ -376,16 +376,16 @@ impl SkillSetBuilder {
|
|||||||
// Bow
|
// Bow
|
||||||
Self::default()
|
Self::default()
|
||||||
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
||||||
.with_skill(Skill::Bow(BowSkill::BDamage), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::ProjSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::ProjSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CProjSpeed), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CDrain), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::UnlockRepeater), None)
|
|
||||||
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::RGlide), None)
|
.with_skill(Skill::Bow(BowSkill::RSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::RArrows), Some(1))
|
.with_skill(Skill::Bow(BowSkill::RCost), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::UnlockShotgun), None)
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SDamage), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SArrows), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SSpread), Some(1))
|
||||||
},
|
},
|
||||||
Some(ToolKind::Staff) => {
|
Some(ToolKind::Staff) => {
|
||||||
// Staff
|
// Staff
|
||||||
@ -453,16 +453,16 @@ impl SkillSetBuilder {
|
|||||||
// Bow
|
// Bow
|
||||||
Self::default()
|
Self::default()
|
||||||
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
||||||
.with_skill(Skill::Bow(BowSkill::BDamage), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CProjSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CDrain), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::UnlockRepeater), None)
|
|
||||||
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::RGlide), None)
|
|
||||||
.with_skill(Skill::Bow(BowSkill::RArrows), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::RCost), Some(1))
|
.with_skill(Skill::Bow(BowSkill::RCost), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::UnlockShotgun), None)
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SDamage), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SSpread), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SArrows), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SCost), Some(1))
|
||||||
},
|
},
|
||||||
Some(ToolKind::Staff) => {
|
Some(ToolKind::Staff) => {
|
||||||
// Staff
|
// Staff
|
||||||
@ -536,18 +536,18 @@ impl SkillSetBuilder {
|
|||||||
// Bow
|
// Bow
|
||||||
Self::default()
|
Self::default()
|
||||||
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
||||||
.with_skill(Skill::Bow(BowSkill::BDamage), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::BRegen), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::CRegen), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CProjSpeed), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::UnlockRepeater), None)
|
|
||||||
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::RGlide), None)
|
.with_skill(Skill::Bow(BowSkill::RSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::RArrows), Some(1))
|
.with_skill(Skill::Bow(BowSkill::UnlockShotgun), None)
|
||||||
.with_skill(Skill::Bow(BowSkill::RCost), Some(1))
|
.with_skill(Skill::Bow(BowSkill::SDamage), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SSpread), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SArrows), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SCost), Some(1))
|
||||||
},
|
},
|
||||||
Some(ToolKind::Staff) => {
|
Some(ToolKind::Staff) => {
|
||||||
// Staff
|
// Staff
|
||||||
@ -629,20 +629,20 @@ impl SkillSetBuilder {
|
|||||||
// Bow
|
// Bow
|
||||||
Self::default()
|
Self::default()
|
||||||
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
.with_skill_group(SkillGroupKind::Weapon(ToolKind::Bow))
|
||||||
.with_skill(Skill::Bow(BowSkill::BDamage), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::ProjSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::ProjSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::BRegen), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CDamage), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::CRegen), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CKnockback), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CProjSpeed), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CDrain), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
.with_skill(Skill::Bow(BowSkill::CMove), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::UnlockRepeater), None)
|
|
||||||
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
.with_skill(Skill::Bow(BowSkill::RDamage), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::RGlide), None)
|
.with_skill(Skill::Bow(BowSkill::RSpeed), Some(1))
|
||||||
.with_skill(Skill::Bow(BowSkill::RArrows), Some(1))
|
|
||||||
.with_skill(Skill::Bow(BowSkill::RCost), Some(1))
|
.with_skill(Skill::Bow(BowSkill::RCost), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::UnlockShotgun), None)
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SDamage), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SSpread), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SArrows), Some(1))
|
||||||
|
.with_skill(Skill::Bow(BowSkill::SCost), Some(1))
|
||||||
},
|
},
|
||||||
Some(ToolKind::Staff) => {
|
Some(ToolKind::Staff) => {
|
||||||
// Staff
|
// Staff
|
||||||
|
@ -5,7 +5,9 @@ use crate::{
|
|||||||
behavior::{CharacterBehavior, JoinData},
|
behavior::{CharacterBehavior, JoinData},
|
||||||
utils::*,
|
utils::*,
|
||||||
},
|
},
|
||||||
|
util::Dir,
|
||||||
};
|
};
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@ -16,11 +18,15 @@ pub struct StaticData {
|
|||||||
pub buildup_duration: Duration,
|
pub buildup_duration: Duration,
|
||||||
/// How long the state has until exiting
|
/// How long the state has until exiting
|
||||||
pub recover_duration: Duration,
|
pub recover_duration: Duration,
|
||||||
|
/// How much spread there is when more than 1 projectile is created
|
||||||
|
pub projectile_spread: f32,
|
||||||
/// Projectile variables
|
/// Projectile variables
|
||||||
pub projectile: ProjectileConstructor,
|
pub projectile: ProjectileConstructor,
|
||||||
pub projectile_body: Body,
|
pub projectile_body: Body,
|
||||||
pub projectile_light: Option<LightEmitter>,
|
pub projectile_light: Option<LightEmitter>,
|
||||||
pub projectile_speed: f32,
|
pub projectile_speed: f32,
|
||||||
|
/// How many projectiles are simultaneously fired
|
||||||
|
pub num_projectiles: u32,
|
||||||
/// What key is used to press ability
|
/// What key is used to press ability
|
||||||
pub ability_info: AbilityInfo,
|
pub ability_info: AbilityInfo,
|
||||||
}
|
}
|
||||||
@ -76,15 +82,28 @@ impl CharacterBehavior for Data {
|
|||||||
crit_chance,
|
crit_chance,
|
||||||
crit_mult,
|
crit_mult,
|
||||||
);
|
);
|
||||||
update.server_events.push_front(ServerEvent::Shoot {
|
// Shoots all projectiles simultaneously
|
||||||
entity: data.entity,
|
for i in 0..self.static_data.num_projectiles {
|
||||||
dir: data.inputs.look_dir,
|
// Adds a slight spread to the projectiles. First projectile has no spread,
|
||||||
body: self.static_data.projectile_body,
|
// and spread increases linearly with number of projectiles created.
|
||||||
projectile,
|
let dir = Dir::from_unnormalized(data.inputs.look_dir.map(|x| {
|
||||||
light: self.static_data.projectile_light,
|
let offset = (2.0 * thread_rng().gen::<f32>() - 1.0)
|
||||||
speed: self.static_data.projectile_speed,
|
* self.static_data.projectile_spread
|
||||||
object: None,
|
* i as f32;
|
||||||
});
|
x + offset
|
||||||
|
}))
|
||||||
|
.unwrap_or(data.inputs.look_dir);
|
||||||
|
// Tells server to create and shoot the projectile
|
||||||
|
update.server_events.push_front(ServerEvent::Shoot {
|
||||||
|
entity: data.entity,
|
||||||
|
dir,
|
||||||
|
body: self.static_data.projectile_body,
|
||||||
|
projectile: projectile.clone(),
|
||||||
|
light: self.static_data.projectile_light,
|
||||||
|
speed: self.static_data.projectile_speed,
|
||||||
|
object: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
update.character = CharacterState::BasicRanged(Data {
|
update.character = CharacterState::BasicRanged(Data {
|
||||||
exhausted: true,
|
exhausted: true,
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
combat::{
|
|
||||||
Attack, AttackDamage, AttackEffect, CombatBuff, CombatEffect, CombatRequirement, Damage,
|
|
||||||
DamageKind, DamageSource, GroupTarget, Knockback, KnockbackDir,
|
|
||||||
},
|
|
||||||
comp::{
|
comp::{
|
||||||
projectile, Body, CharacterState, EnergyChange, EnergySource, LightEmitter, Projectile,
|
projectile::ProjectileConstructor, Body, CharacterState, EnergyChange, EnergySource,
|
||||||
StateUpdate,
|
LightEmitter, StateUpdate,
|
||||||
},
|
},
|
||||||
event::ServerEvent,
|
event::ServerEvent,
|
||||||
states::{
|
states::{
|
||||||
@ -27,6 +23,10 @@ pub struct StaticData {
|
|||||||
pub recover_duration: Duration,
|
pub recover_duration: Duration,
|
||||||
/// How much energy is drained per second when charging
|
/// How much energy is drained per second when charging
|
||||||
pub energy_drain: f32,
|
pub energy_drain: f32,
|
||||||
|
/// How much energy is gained with no charge
|
||||||
|
pub initial_regen: f32,
|
||||||
|
/// How much the energy gain scales as it is charged
|
||||||
|
pub scaled_regen: f32,
|
||||||
/// How much damage is dealt with no charge
|
/// How much damage is dealt with no charge
|
||||||
pub initial_damage: f32,
|
pub initial_damage: f32,
|
||||||
/// How much the damage scales as it is charged
|
/// How much the damage scales as it is charged
|
||||||
@ -46,8 +46,6 @@ pub struct StaticData {
|
|||||||
pub move_speed: f32,
|
pub move_speed: f32,
|
||||||
/// What key is used to press ability
|
/// What key is used to press ability
|
||||||
pub ability_info: AbilityInfo,
|
pub ability_info: AbilityInfo,
|
||||||
/// What kind of damage the attack does
|
|
||||||
pub damage_kind: DamageKind,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@ -96,45 +94,19 @@ impl CharacterBehavior for Data {
|
|||||||
let charge_frac = (self.timer.as_secs_f32()
|
let charge_frac = (self.timer.as_secs_f32()
|
||||||
/ self.static_data.charge_duration.as_secs_f32())
|
/ self.static_data.charge_duration.as_secs_f32())
|
||||||
.min(1.0);
|
.min(1.0);
|
||||||
let knockback = AttackEffect::new(
|
let arrow = ProjectileConstructor::Arrow {
|
||||||
Some(GroupTarget::OutOfGroup),
|
damage: self.static_data.initial_damage as f32
|
||||||
CombatEffect::Knockback(Knockback {
|
+ charge_frac * self.static_data.scaled_damage as f32,
|
||||||
strength: self.static_data.initial_knockback
|
knockback: self.static_data.initial_knockback
|
||||||
+ charge_frac * self.static_data.scaled_knockback,
|
+ charge_frac * self.static_data.scaled_knockback,
|
||||||
direction: KnockbackDir::Away,
|
energy_regen: self.static_data.initial_regen
|
||||||
}),
|
+ charge_frac * self.static_data.scaled_regen,
|
||||||
)
|
};
|
||||||
.with_requirement(CombatRequirement::AnyDamage);
|
// Fire
|
||||||
let buff = CombatEffect::Buff(CombatBuff::default_physical());
|
|
||||||
let damage = AttackDamage::new(
|
|
||||||
Damage {
|
|
||||||
source: DamageSource::Projectile,
|
|
||||||
kind: self.static_data.damage_kind,
|
|
||||||
value: self.static_data.initial_damage as f32
|
|
||||||
+ charge_frac * self.static_data.scaled_damage as f32,
|
|
||||||
},
|
|
||||||
Some(GroupTarget::OutOfGroup),
|
|
||||||
)
|
|
||||||
.with_effect(buff);
|
|
||||||
let (crit_chance, crit_mult) =
|
let (crit_chance, crit_mult) =
|
||||||
get_crit_data(data, self.static_data.ability_info);
|
get_crit_data(data, self.static_data.ability_info);
|
||||||
let attack = Attack::default()
|
let projectile =
|
||||||
.with_damage(damage)
|
arrow.create_projectile(Some(*data.uid), crit_chance, crit_mult);
|
||||||
.with_crit(crit_chance, crit_mult)
|
|
||||||
.with_effect(knockback)
|
|
||||||
.with_combo_increment();
|
|
||||||
|
|
||||||
// Fire
|
|
||||||
let projectile = Projectile {
|
|
||||||
hit_solid: vec![projectile::Effect::Stick],
|
|
||||||
hit_entity: vec![
|
|
||||||
projectile::Effect::Attack(attack),
|
|
||||||
projectile::Effect::Vanish,
|
|
||||||
],
|
|
||||||
time_left: Duration::from_secs(15),
|
|
||||||
owner: Some(*data.uid),
|
|
||||||
ignore_group: true,
|
|
||||||
};
|
|
||||||
update.server_events.push_front(ServerEvent::Shoot {
|
update.server_events.push_front(ServerEvent::Shoot {
|
||||||
entity: data.entity,
|
entity: data.entity,
|
||||||
dir: data.inputs.look_dir,
|
dir: data.inputs.look_dir,
|
||||||
@ -166,7 +138,7 @@ impl CharacterBehavior for Data {
|
|||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
|
|
||||||
// Consumes energy if there's enough left and RMB is held down
|
// Consumes energy if there's enough left and input is held down
|
||||||
update.energy.change_by(EnergyChange {
|
update.energy.change_by(EnergyChange {
|
||||||
amount: -(self.static_data.energy_drain as f32
|
amount: -(self.static_data.energy_drain as f32
|
||||||
* data.dt.0
|
* data.dt.0
|
||||||
|
@ -1,29 +1,32 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{Body, CharacterState, LightEmitter, ProjectileConstructor, StateUpdate},
|
comp::{
|
||||||
|
Body, CharacterState, EnergyChange, EnergySource, LightEmitter, ProjectileConstructor,
|
||||||
|
StateUpdate,
|
||||||
|
},
|
||||||
event::ServerEvent,
|
event::ServerEvent,
|
||||||
states::{
|
states::{
|
||||||
behavior::{CharacterBehavior, JoinData},
|
behavior::{CharacterBehavior, JoinData},
|
||||||
utils::{StageSection, *},
|
utils::{StageSection, *},
|
||||||
},
|
},
|
||||||
util::dir::*,
|
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use vek::Vec3;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
/// Separated out to condense update portions of character state
|
/// Separated out to condense update portions of character state
|
||||||
pub struct StaticData {
|
pub struct StaticData {
|
||||||
/// How long the state is in movement
|
|
||||||
pub movement_duration: Duration,
|
|
||||||
/// How long we've readied the weapon
|
/// How long we've readied the weapon
|
||||||
pub buildup_duration: Duration,
|
pub buildup_duration: Duration,
|
||||||
/// How long the state is shooting
|
/// How long the state is shooting
|
||||||
pub shoot_duration: Duration,
|
pub shoot_duration: Duration,
|
||||||
/// How long the state has until exiting
|
/// How long the state has until exiting
|
||||||
pub recover_duration: Duration,
|
pub recover_duration: Duration,
|
||||||
/// Whether there should be a jump and how strong the leap is
|
/// Energy cost per projectile
|
||||||
pub leap: Option<f32>,
|
pub energy_cost: f32,
|
||||||
|
/// Max speed that can be reached
|
||||||
|
pub max_speed: f32,
|
||||||
|
/// Projectiles required to reach half of max speed
|
||||||
|
pub half_speed_at: u32,
|
||||||
/// Projectile options
|
/// Projectile options
|
||||||
pub projectile: ProjectileConstructor,
|
pub projectile: ProjectileConstructor,
|
||||||
pub projectile_body: Body,
|
pub projectile_body: Body,
|
||||||
@ -42,64 +45,20 @@ pub struct Data {
|
|||||||
pub timer: Duration,
|
pub timer: Duration,
|
||||||
/// What section the character stage is in
|
/// What section the character stage is in
|
||||||
pub stage_section: StageSection,
|
pub stage_section: StageSection,
|
||||||
/// How many repetitions remaining
|
/// Speed of the state while in shoot section
|
||||||
pub reps_remaining: u32,
|
pub speed: f32,
|
||||||
|
/// Number of projectiles fired so far
|
||||||
|
pub projectiles_fired: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CharacterBehavior for Data {
|
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_orientation(data, &mut update, 1.0);
|
handle_orientation(data, &mut update, 1.0);
|
||||||
handle_move(data, &mut update, 1.0);
|
handle_move(data, &mut update, 0.3);
|
||||||
handle_jump(data, &mut update, 1.0);
|
|
||||||
|
|
||||||
match self.stage_section {
|
match self.stage_section {
|
||||||
StageSection::Movement => {
|
|
||||||
// Jumping
|
|
||||||
if let Some(leap_strength) = self.static_data.leap {
|
|
||||||
let progress = 1.0
|
|
||||||
- self.timer.as_secs_f32()
|
|
||||||
/ self.static_data.movement_duration.as_secs_f32();
|
|
||||||
handle_forced_movement(
|
|
||||||
data,
|
|
||||||
&mut update,
|
|
||||||
ForcedMovement::Leap {
|
|
||||||
vertical: leap_strength,
|
|
||||||
forward: 10.0,
|
|
||||||
progress,
|
|
||||||
direction: MovementDirection::Move,
|
|
||||||
},
|
|
||||||
1.0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if self.timer < self.static_data.movement_duration {
|
|
||||||
// Do movement
|
|
||||||
update.character = CharacterState::RepeaterRanged(Data {
|
|
||||||
timer: self
|
|
||||||
.timer
|
|
||||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
|
||||||
.unwrap_or_default(),
|
|
||||||
..*self
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Transition to buildup
|
|
||||||
update.character = CharacterState::RepeaterRanged(Data {
|
|
||||||
timer: Duration::default(),
|
|
||||||
stage_section: StageSection::Buildup,
|
|
||||||
..*self
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
StageSection::Buildup => {
|
StageSection::Buildup => {
|
||||||
// Aim gliding
|
|
||||||
if self.static_data.leap.is_some() {
|
|
||||||
handle_forced_movement(
|
|
||||||
data,
|
|
||||||
&mut update,
|
|
||||||
ForcedMovement::Hover { move_input: 0.1 },
|
|
||||||
1.0,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if self.timer < self.static_data.buildup_duration {
|
if self.timer < self.static_data.buildup_duration {
|
||||||
// Buildup to attack
|
// Buildup to attack
|
||||||
update.character = CharacterState::RepeaterRanged(Data {
|
update.character = CharacterState::RepeaterRanged(Data {
|
||||||
@ -119,12 +78,19 @@ impl CharacterBehavior for Data {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
StageSection::Shoot => {
|
StageSection::Shoot => {
|
||||||
// Aim gliding
|
if self.timer < self.static_data.shoot_duration {
|
||||||
if self.static_data.leap.is_some() {
|
// Draw projectile
|
||||||
update.vel.0 = Vec3::new(data.vel.0.x, data.vel.0.y, 0.0);
|
update.character = CharacterState::RepeaterRanged(Data {
|
||||||
}
|
timer: self
|
||||||
if self.reps_remaining > 0 {
|
.timer
|
||||||
// Fire
|
.checked_add(Duration::from_secs_f32(data.dt.0 * self.speed))
|
||||||
|
.unwrap_or_default(),
|
||||||
|
..*self
|
||||||
|
});
|
||||||
|
} else if input_is_pressed(data, self.static_data.ability_info.input)
|
||||||
|
&& update.energy.current() as f32 >= self.static_data.energy_cost
|
||||||
|
{
|
||||||
|
// Fire if input is pressed still
|
||||||
let (crit_chance, crit_mult) =
|
let (crit_chance, crit_mult) =
|
||||||
get_crit_data(data, self.static_data.ability_info);
|
get_crit_data(data, self.static_data.ability_info);
|
||||||
let projectile = self.static_data.projectile.create_projectile(
|
let projectile = self.static_data.projectile.create_projectile(
|
||||||
@ -134,23 +100,7 @@ impl CharacterBehavior for Data {
|
|||||||
);
|
);
|
||||||
update.server_events.push_front(ServerEvent::Shoot {
|
update.server_events.push_front(ServerEvent::Shoot {
|
||||||
entity: data.entity,
|
entity: data.entity,
|
||||||
// Provides slight variation to projectile direction
|
dir: data.inputs.look_dir,
|
||||||
dir: Dir::from_unnormalized(Vec3::new(
|
|
||||||
data.inputs.look_dir[0]
|
|
||||||
+ (if self.reps_remaining % 2 == 0 {
|
|
||||||
self.reps_remaining as f32 / 400.0
|
|
||||||
} else {
|
|
||||||
-1.0 * self.reps_remaining as f32 / 400.0
|
|
||||||
}),
|
|
||||||
data.inputs.look_dir[1]
|
|
||||||
+ (if self.reps_remaining % 2 == 0 {
|
|
||||||
-1.0 * self.reps_remaining as f32 / 400.0
|
|
||||||
} else {
|
|
||||||
self.reps_remaining as f32 / 400.0
|
|
||||||
}),
|
|
||||||
data.inputs.look_dir[2],
|
|
||||||
))
|
|
||||||
.unwrap_or(data.inputs.look_dir),
|
|
||||||
body: self.static_data.projectile_body,
|
body: self.static_data.projectile_body,
|
||||||
projectile,
|
projectile,
|
||||||
light: self.static_data.projectile_light,
|
light: self.static_data.projectile_light,
|
||||||
@ -158,22 +108,26 @@ impl CharacterBehavior for Data {
|
|||||||
object: None,
|
object: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Shoot projectiles
|
// Removes energy from character when arrow is fired
|
||||||
update.character = CharacterState::RepeaterRanged(Data {
|
update.server_events.push_front(ServerEvent::EnergyChange {
|
||||||
timer: self
|
entity: data.entity,
|
||||||
.timer
|
change: EnergyChange {
|
||||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
amount: -self.static_data.energy_cost as i32,
|
||||||
.unwrap_or_default(),
|
source: EnergySource::Ability,
|
||||||
reps_remaining: self.reps_remaining - 1,
|
},
|
||||||
..*self
|
|
||||||
});
|
});
|
||||||
} else if self.timer < self.static_data.shoot_duration {
|
|
||||||
// Finish shooting
|
// Sets new speed of shoot. Scales based off of the number of projectiles fired.
|
||||||
|
let new_speed = 1.0
|
||||||
|
+ self.projectiles_fired as f32
|
||||||
|
/ (self.static_data.half_speed_at as f32
|
||||||
|
+ self.projectiles_fired as f32)
|
||||||
|
* self.static_data.max_speed;
|
||||||
|
|
||||||
update.character = CharacterState::RepeaterRanged(Data {
|
update.character = CharacterState::RepeaterRanged(Data {
|
||||||
timer: self
|
timer: Duration::default(),
|
||||||
.timer
|
speed: new_speed,
|
||||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
projectiles_fired: self.projectiles_fired + 1,
|
||||||
.unwrap_or_default(),
|
|
||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -186,10 +140,7 @@ impl CharacterBehavior for Data {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
StageSection::Recover => {
|
StageSection::Recover => {
|
||||||
if self.static_data.leap.is_some() && data.physics.on_ground {
|
if self.timer < self.static_data.recover_duration {
|
||||||
// Done
|
|
||||||
update.character = CharacterState::Wielding;
|
|
||||||
} else if self.timer < self.static_data.recover_duration {
|
|
||||||
// Recover from attack
|
// Recover from attack
|
||||||
update.character = CharacterState::RepeaterRanged(Data {
|
update.character = CharacterState::RepeaterRanged(Data {
|
||||||
timer: self
|
timer: self
|
||||||
|
@ -3058,12 +3058,13 @@ fn handle_skill_preset(
|
|||||||
fn clear_skillset(skill_set: &mut comp::SkillSet) { *skill_set = comp::SkillSet::default(); }
|
fn clear_skillset(skill_set: &mut comp::SkillSet) { *skill_set = comp::SkillSet::default(); }
|
||||||
|
|
||||||
fn set_skills(skill_set: &mut comp::SkillSet, preset: &str) -> CmdResult<()> {
|
fn set_skills(skill_set: &mut comp::SkillSet, preset: &str) -> CmdResult<()> {
|
||||||
let presets =
|
let presets = match common::cmd::SkillPresetManifest::load("server.manifests.presets") {
|
||||||
if let Ok(presets) = common::cmd::SkillPresetManifest::load("server.manifests.presets") {
|
Ok(presets) => presets.read().0.clone(),
|
||||||
presets.read().0.clone()
|
Err(err) => {
|
||||||
} else {
|
warn!("Error in preset: {}", err);
|
||||||
return Err("Error while loading presets".to_owned());
|
return Err("Error while loading presets".to_owned());
|
||||||
};
|
},
|
||||||
|
};
|
||||||
if let Some(preset) = presets.get(preset) {
|
if let Some(preset) = presets.get(preset) {
|
||||||
for (skill, level) in preset {
|
for (skill, level) in preset {
|
||||||
let group = if let Some(group) = skill.skill_group_kind() {
|
let group = if let Some(group) = skill.skill_group_kind() {
|
||||||
|
19
server/src/migrations/V38__reset_bow_skills.sql
Normal file
19
server/src/migrations/V38__reset_bow_skills.sql
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
-- Resets bow skill tree by deleting bow skills and setting available skill points to earned skill points
|
||||||
|
-- Deletes all bow skills, does not delete unlock bow skill
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow ProjSpeed';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow BDamage';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow BRegen';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow CDamage';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow CKnockback';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow CProjSpeed';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow CDrain';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow CSpeed';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow CMove';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow UnlockRepeater';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow RDamage';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow RGlide';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow RArrows';
|
||||||
|
DELETE FROM skill WHERE skill = 'Bow RCost';
|
||||||
|
-- Resets available skill points to earned skill points for bow skill tree
|
||||||
|
UPDATE skill_group
|
||||||
|
SET available_sp = earned_sp WHERE skill_group_kind = 'Weapon Bow';
|
@ -92,19 +92,19 @@ pub fn skill_to_db_string(skill: comp::skills::Skill) -> String {
|
|||||||
Hammer(HammerSkill::LKnockback) => "Hammer LKnockback",
|
Hammer(HammerSkill::LKnockback) => "Hammer LKnockback",
|
||||||
Hammer(HammerSkill::LRange) => "Hammer LRange",
|
Hammer(HammerSkill::LRange) => "Hammer LRange",
|
||||||
Bow(BowSkill::ProjSpeed) => "Bow ProjSpeed",
|
Bow(BowSkill::ProjSpeed) => "Bow ProjSpeed",
|
||||||
Bow(BowSkill::BDamage) => "Bow BDamage",
|
|
||||||
Bow(BowSkill::BRegen) => "Bow BRegen",
|
|
||||||
Bow(BowSkill::CDamage) => "Bow CDamage",
|
Bow(BowSkill::CDamage) => "Bow CDamage",
|
||||||
|
Bow(BowSkill::CRegen) => "Bow CRegen",
|
||||||
Bow(BowSkill::CKnockback) => "Bow CKnockback",
|
Bow(BowSkill::CKnockback) => "Bow CKnockback",
|
||||||
Bow(BowSkill::CProjSpeed) => "Bow CProjSpeed",
|
|
||||||
Bow(BowSkill::CDrain) => "Bow CDrain",
|
|
||||||
Bow(BowSkill::CSpeed) => "Bow CSpeed",
|
Bow(BowSkill::CSpeed) => "Bow CSpeed",
|
||||||
Bow(BowSkill::CMove) => "Bow CMove",
|
Bow(BowSkill::CMove) => "Bow CMove",
|
||||||
Bow(BowSkill::UnlockRepeater) => "Bow UnlockRepeater",
|
|
||||||
Bow(BowSkill::RDamage) => "Bow RDamage",
|
Bow(BowSkill::RDamage) => "Bow RDamage",
|
||||||
Bow(BowSkill::RGlide) => "Bow RGlide",
|
|
||||||
Bow(BowSkill::RArrows) => "Bow RArrows",
|
|
||||||
Bow(BowSkill::RCost) => "Bow RCost",
|
Bow(BowSkill::RCost) => "Bow RCost",
|
||||||
|
Bow(BowSkill::RSpeed) => "Bow RSpeed",
|
||||||
|
Bow(BowSkill::UnlockShotgun) => "Bow UnlockShotgun",
|
||||||
|
Bow(BowSkill::SDamage) => "Bow SDamage",
|
||||||
|
Bow(BowSkill::SCost) => "Bow SCost",
|
||||||
|
Bow(BowSkill::SArrows) => "Bow SArrows",
|
||||||
|
Bow(BowSkill::SSpread) => "Bow SSpread",
|
||||||
Staff(StaffSkill::BDamage) => "Staff BDamage",
|
Staff(StaffSkill::BDamage) => "Staff BDamage",
|
||||||
Staff(StaffSkill::BRegen) => "Staff BRegen",
|
Staff(StaffSkill::BRegen) => "Staff BRegen",
|
||||||
Staff(StaffSkill::BRadius) => "Staff BRadius",
|
Staff(StaffSkill::BRadius) => "Staff BRadius",
|
||||||
@ -212,19 +212,19 @@ pub fn db_string_to_skill(skill_string: &str) -> comp::skills::Skill {
|
|||||||
"Hammer LKnockback" => Hammer(HammerSkill::LKnockback),
|
"Hammer LKnockback" => Hammer(HammerSkill::LKnockback),
|
||||||
"Hammer LRange" => Hammer(HammerSkill::LRange),
|
"Hammer LRange" => Hammer(HammerSkill::LRange),
|
||||||
"Bow ProjSpeed" => Bow(BowSkill::ProjSpeed),
|
"Bow ProjSpeed" => Bow(BowSkill::ProjSpeed),
|
||||||
"Bow BDamage" => Bow(BowSkill::BDamage),
|
|
||||||
"Bow BRegen" => Bow(BowSkill::BRegen),
|
|
||||||
"Bow CDamage" => Bow(BowSkill::CDamage),
|
"Bow CDamage" => Bow(BowSkill::CDamage),
|
||||||
|
"Bow CRegen" => Bow(BowSkill::CRegen),
|
||||||
"Bow CKnockback" => Bow(BowSkill::CKnockback),
|
"Bow CKnockback" => Bow(BowSkill::CKnockback),
|
||||||
"Bow CProjSpeed" => Bow(BowSkill::CProjSpeed),
|
|
||||||
"Bow CDrain" => Bow(BowSkill::CDrain),
|
|
||||||
"Bow CSpeed" => Bow(BowSkill::CSpeed),
|
"Bow CSpeed" => Bow(BowSkill::CSpeed),
|
||||||
"Bow CMove" => Bow(BowSkill::CMove),
|
"Bow CMove" => Bow(BowSkill::CMove),
|
||||||
"Bow UnlockRepeater" => Bow(BowSkill::UnlockRepeater),
|
|
||||||
"Bow RDamage" => Bow(BowSkill::RDamage),
|
"Bow RDamage" => Bow(BowSkill::RDamage),
|
||||||
"Bow RGlide" => Bow(BowSkill::RGlide),
|
|
||||||
"Bow RArrows" => Bow(BowSkill::RArrows),
|
|
||||||
"Bow RCost" => Bow(BowSkill::RCost),
|
"Bow RCost" => Bow(BowSkill::RCost),
|
||||||
|
"Bow RSpeed" => Bow(BowSkill::RSpeed),
|
||||||
|
"Bow UnlockShotgun" => Bow(BowSkill::UnlockShotgun),
|
||||||
|
"Bow SDamage" => Bow(BowSkill::SDamage),
|
||||||
|
"Bow SCost" => Bow(BowSkill::SCost),
|
||||||
|
"Bow SArrows" => Bow(BowSkill::SArrows),
|
||||||
|
"Bow SSpread" => Bow(BowSkill::SSpread),
|
||||||
"Staff BDamage" => Staff(StaffSkill::BDamage),
|
"Staff BDamage" => Staff(StaffSkill::BDamage),
|
||||||
"Staff BRegen" => Staff(StaffSkill::BRegen),
|
"Staff BRegen" => Staff(StaffSkill::BRegen),
|
||||||
"Staff BRadius" => Staff(StaffSkill::BRadius),
|
"Staff BRadius" => Staff(StaffSkill::BRadius),
|
||||||
|
@ -2091,7 +2091,7 @@ impl<'a> AgentData<'a> {
|
|||||||
agent.action_state.timer += read_data.dt.0;
|
agent.action_state.timer += read_data.dt.0;
|
||||||
} else if self
|
} else if self
|
||||||
.skill_set
|
.skill_set
|
||||||
.has_skill(Skill::Bow(BowSkill::UnlockRepeater))
|
.has_skill(Skill::Bow(BowSkill::UnlockShotgun))
|
||||||
&& self.energy.current() > 400
|
&& self.energy.current() > 400
|
||||||
&& thread_rng().gen_bool(0.8)
|
&& thread_rng().gen_bool(0.8)
|
||||||
{
|
{
|
||||||
|
@ -26,26 +26,28 @@ impl Animation for RepeaterAnimation {
|
|||||||
#[allow(clippy::approx_constant)] // TODO: Pending review in #587
|
#[allow(clippy::approx_constant)] // TODO: Pending review in #587
|
||||||
fn update_skeleton_inner<'a>(
|
fn update_skeleton_inner<'a>(
|
||||||
skeleton: &Self::Skeleton,
|
skeleton: &Self::Skeleton,
|
||||||
(ability_info, hands, _velocity, _global_time, stage_section): Self::Dependency<'a>,
|
(ability_info, hands, velocity, _global_time, stage_section): Self::Dependency<'a>,
|
||||||
anim_time: f32,
|
anim_time: f32,
|
||||||
rate: &mut f32,
|
rate: &mut f32,
|
||||||
s_a: &SkeletonAttr,
|
s_a: &SkeletonAttr,
|
||||||
) -> Self::Skeleton {
|
) -> Self::Skeleton {
|
||||||
*rate = 1.0;
|
*rate = 1.0;
|
||||||
let mut next = (*skeleton).clone();
|
let mut next = (*skeleton).clone();
|
||||||
|
let speed = Vec2::<f32>::from(velocity).magnitude();
|
||||||
|
|
||||||
let (move1, move2, move3, _move4) = match stage_section {
|
let (move1base, move2base, move3base, move4) = match stage_section {
|
||||||
Some(StageSection::Movement) => (anim_time, 0.0, 0.0, 0.0),
|
Some(StageSection::Movement) => (anim_time, 0.0, 0.0, 0.0),
|
||||||
Some(StageSection::Buildup) => (1.0, anim_time, 0.0, 0.0),
|
Some(StageSection::Buildup) => (1.0, anim_time, 0.0, 0.0),
|
||||||
Some(StageSection::Shoot) => (1.0, 1.0, anim_time, 0.0),
|
Some(StageSection::Shoot) => (1.0, 1.0, anim_time, 0.0),
|
||||||
Some(StageSection::Recover) => (1.1, 1.0, 1.0, anim_time),
|
Some(StageSection::Recover) => (1.1, 1.0, 1.0, anim_time),
|
||||||
_ => (0.0, 0.0, 0.0, 0.0),
|
_ => (0.0, 0.0, 0.0, 0.0),
|
||||||
};
|
};
|
||||||
|
let pullback = 1.0 - move4;
|
||||||
|
let move1 = move1base * pullback;
|
||||||
|
let move2 = move2base * pullback;
|
||||||
|
let move3 = move3base * pullback;
|
||||||
// end spin stuff
|
// end spin stuff
|
||||||
|
|
||||||
fn fire(x: f32) -> f32 { (x * 18.0).sin() }
|
|
||||||
|
|
||||||
if let Some(ToolKind::Bow) = ability_info.and_then(|a| a.tool) {
|
if let Some(ToolKind::Bow) = ability_info.and_then(|a| a.tool) {
|
||||||
next.hand_l.position = Vec3::new(s_a.bhl.0, s_a.bhl.1, s_a.bhl.2);
|
next.hand_l.position = Vec3::new(s_a.bhl.0, s_a.bhl.1, s_a.bhl.2);
|
||||||
next.hand_l.orientation = Quaternion::rotation_x(s_a.bhl.3);
|
next.hand_l.orientation = Quaternion::rotation_x(s_a.bhl.3);
|
||||||
@ -54,49 +56,46 @@ impl Animation for RepeaterAnimation {
|
|||||||
next.main.position = Vec3::new(0.0, 0.0, 0.0);
|
next.main.position = Vec3::new(0.0, 0.0, 0.0);
|
||||||
next.main.orientation = Quaternion::rotation_y(0.0) * Quaternion::rotation_z(0.0);
|
next.main.orientation = Quaternion::rotation_y(0.0) * Quaternion::rotation_z(0.0);
|
||||||
|
|
||||||
next.hold.position = Vec3::new(1.2, -1.0, -5.2);
|
next.hold.position = Vec3::new(0.0, -1.0 + move3 * 2.0, -5.2);
|
||||||
next.hold.orientation = Quaternion::rotation_x(-1.7) * Quaternion::rotation_z(-0.1);
|
next.hold.orientation = Quaternion::rotation_x(-1.57) * Quaternion::rotation_z(0.0);
|
||||||
next.hold.scale = Vec3::one() * 1.0 * (1.0 - move3);
|
next.hold.scale = Vec3::one() * (1.0);
|
||||||
|
if speed < 0.5 {
|
||||||
|
next.foot_l.position = Vec3::new(
|
||||||
|
-s_a.foot.0 + move1 * -0.75,
|
||||||
|
s_a.foot.1 + move1 * 4.0,
|
||||||
|
s_a.foot.2,
|
||||||
|
);
|
||||||
|
next.foot_l.orientation =
|
||||||
|
Quaternion::rotation_x(move1 * 0.2 + move2 * -0.1 + move3 * -0.2)
|
||||||
|
* Quaternion::rotation_z(move3 * 0.1);
|
||||||
|
|
||||||
next.foot_l.position = Vec3::new(
|
next.foot_r.position = Vec3::new(s_a.foot.0 + move1 * 0.75, s_a.foot.1, s_a.foot.2);
|
||||||
-s_a.foot.0 + move1 * -0.75 - 0.75,
|
next.foot_r.orientation =
|
||||||
s_a.foot.1 + move1 * 4.0 + 4.0,
|
Quaternion::rotation_x(move1 * 0.06 + move2 * -0.2 + move3 * -0.5)
|
||||||
s_a.foot.2 + move1 * 2.5 + 2.5,
|
* Quaternion::rotation_z(move1 * -0.6 + move3 * 0.8);
|
||||||
);
|
next.chest.position = Vec3::new(0.0, s_a.chest.0, s_a.chest.1);
|
||||||
next.foot_l.orientation = Quaternion::rotation_x(move1 * 0.6 + 0.6 + move2 * -0.2)
|
next.chest.orientation = Quaternion::rotation_x(0.0);
|
||||||
* Quaternion::rotation_z(move1 * 0.3 + 0.3);
|
} else {
|
||||||
|
};
|
||||||
next.foot_r.position = Vec3::new(
|
next.shorts.position = Vec3::new(0.0, s_a.shorts.0 + move1 * 2.0, s_a.shorts.1);
|
||||||
s_a.foot.0 + move1 * 0.75 + 0.75,
|
next.shorts.orientation = Quaternion::rotation_x(move1 * 0.2 + move3 * 0.2);
|
||||||
s_a.foot.1 + move1 * 4.0 + 4.0,
|
next.belt.position = Vec3::new(0.0, s_a.belt.0 + move1 * 1.0, s_a.belt.1);
|
||||||
s_a.foot.2 + move1 * 2.5 + 2.5,
|
next.belt.orientation = Quaternion::rotation_x(move1 * 0.1 + move3 * 0.1);
|
||||||
);
|
|
||||||
next.foot_r.orientation = Quaternion::rotation_x(move1 * 0.6 + 0.6 + move2 * -0.2)
|
|
||||||
* Quaternion::rotation_z(move1 * -0.3 - 0.3);
|
|
||||||
next.shorts.position =
|
|
||||||
Vec3::new(0.0, s_a.shorts.0 + move1 * 4.0, s_a.shorts.1 + move1 * 1.0);
|
|
||||||
next.shorts.orientation = Quaternion::rotation_x(move1 * 0.6);
|
|
||||||
next.belt.position = Vec3::new(0.0, s_a.belt.0 + move1 * 2.0, s_a.belt.1);
|
|
||||||
next.belt.orientation = Quaternion::rotation_x(move1 * 0.2);
|
|
||||||
next.control.position = Vec3::new(
|
next.control.position = Vec3::new(
|
||||||
s_a.bc.0 + move1 * 5.0,
|
s_a.bc.0 + move1 * 5.0,
|
||||||
s_a.bc.1 + move1 * 3.0,
|
s_a.bc.1 + move1 * 3.0,
|
||||||
s_a.bc.2 + move1 * 1.0,
|
s_a.bc.2 + move1 * 5.0,
|
||||||
);
|
);
|
||||||
next.control.orientation = Quaternion::rotation_x(s_a.bc.3 + move1 * 0.4)
|
next.control.orientation = Quaternion::rotation_x(s_a.bc.3 + move1 * 0.4)
|
||||||
* Quaternion::rotation_y(s_a.bc.4 + move1 * 0.8)
|
* Quaternion::rotation_y(s_a.bc.4 + move1 * 0.8)
|
||||||
* Quaternion::rotation_z(s_a.bc.5);
|
* Quaternion::rotation_z(s_a.bc.5);
|
||||||
next.head.orientation = Quaternion::rotation_y(move1 * 0.15 + move2 * 0.05);
|
next.head.orientation = Quaternion::rotation_x(move1 * 0.15)
|
||||||
next.torso.orientation =
|
* Quaternion::rotation_y(move1 * 0.15 + move2 * 0.05);
|
||||||
Quaternion::rotation_x(move1 * 0.1 + move2 * 0.1 + move3 * 0.15);
|
next.torso.orientation = Quaternion::rotation_x(move1 * 0.25 + move3 * -0.2);
|
||||||
|
|
||||||
next.hand_l.position = Vec3::new(
|
next.hand_l.position = Vec3::new(0.0, -2.5 + move3 * -6.0, 0.0);
|
||||||
2.0 + fire(move3) * -6.0 - 3.0,
|
next.hand_l.orientation = Quaternion::rotation_x(1.5)
|
||||||
1.5 + fire(move3) * -6.0 - 3.0,
|
* Quaternion::rotation_y(-0.0)
|
||||||
0.0,
|
|
||||||
);
|
|
||||||
next.hand_l.orientation = Quaternion::rotation_x(1.20)
|
|
||||||
* Quaternion::rotation_y(-0.6)
|
|
||||||
* Quaternion::rotation_z(-0.3);
|
* Quaternion::rotation_z(-0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,21 +102,21 @@ widget_ids! {
|
|||||||
skill_hammer_leap_4,
|
skill_hammer_leap_4,
|
||||||
skill_hammer_leap_5,
|
skill_hammer_leap_5,
|
||||||
bow_render,
|
bow_render,
|
||||||
skill_bow_basic_0,
|
|
||||||
skill_bow_basic_1,
|
|
||||||
skill_bow_basic_2,
|
|
||||||
skill_bow_charged_0,
|
skill_bow_charged_0,
|
||||||
skill_bow_charged_1,
|
skill_bow_charged_1,
|
||||||
skill_bow_charged_2,
|
skill_bow_charged_2,
|
||||||
skill_bow_charged_3,
|
skill_bow_charged_3,
|
||||||
skill_bow_charged_4,
|
skill_bow_charged_4,
|
||||||
skill_bow_charged_5,
|
skill_bow_charged_5,
|
||||||
skill_bow_charged_6,
|
|
||||||
skill_bow_repeater_0,
|
skill_bow_repeater_0,
|
||||||
skill_bow_repeater_1,
|
skill_bow_repeater_1,
|
||||||
skill_bow_repeater_2,
|
skill_bow_repeater_2,
|
||||||
skill_bow_repeater_3,
|
skill_bow_repeater_3,
|
||||||
skill_bow_repeater_4,
|
skill_bow_shotgun_0,
|
||||||
|
skill_bow_shotgun_1,
|
||||||
|
skill_bow_shotgun_2,
|
||||||
|
skill_bow_shotgun_3,
|
||||||
|
skill_bow_shotgun_4,
|
||||||
skill_bow_passive_0,
|
skill_bow_passive_0,
|
||||||
staff_render,
|
staff_render,
|
||||||
skill_staff_basic_0,
|
skill_staff_basic_0,
|
||||||
@ -538,7 +538,7 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
SelectedSkillTree::Weapon(ToolKind::Sword) => 5,
|
SelectedSkillTree::Weapon(ToolKind::Sword) => 5,
|
||||||
SelectedSkillTree::Weapon(ToolKind::Axe) => 5,
|
SelectedSkillTree::Weapon(ToolKind::Axe) => 5,
|
||||||
SelectedSkillTree::Weapon(ToolKind::Hammer) => 5,
|
SelectedSkillTree::Weapon(ToolKind::Hammer) => 5,
|
||||||
SelectedSkillTree::Weapon(ToolKind::Bow) => 3,
|
SelectedSkillTree::Weapon(ToolKind::Bow) => 6,
|
||||||
SelectedSkillTree::Weapon(ToolKind::Staff) => 4,
|
SelectedSkillTree::Weapon(ToolKind::Staff) => 4,
|
||||||
SelectedSkillTree::Weapon(ToolKind::Sceptre) => 5,
|
SelectedSkillTree::Weapon(ToolKind::Sceptre) => 5,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
@ -548,7 +548,7 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
SelectedSkillTree::Weapon(ToolKind::Sword) => 7,
|
SelectedSkillTree::Weapon(ToolKind::Sword) => 7,
|
||||||
SelectedSkillTree::Weapon(ToolKind::Axe) => 6,
|
SelectedSkillTree::Weapon(ToolKind::Axe) => 6,
|
||||||
SelectedSkillTree::Weapon(ToolKind::Hammer) => 5,
|
SelectedSkillTree::Weapon(ToolKind::Hammer) => 5,
|
||||||
SelectedSkillTree::Weapon(ToolKind::Bow) => 7,
|
SelectedSkillTree::Weapon(ToolKind::Bow) => 4,
|
||||||
SelectedSkillTree::Weapon(ToolKind::Staff) => 5,
|
SelectedSkillTree::Weapon(ToolKind::Staff) => 5,
|
||||||
SelectedSkillTree::Weapon(ToolKind::Sceptre) => 4,
|
SelectedSkillTree::Weapon(ToolKind::Sceptre) => 4,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
@ -2507,72 +2507,6 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
Button::image(self.imgs.bow_m1)
|
Button::image(self.imgs.bow_m1)
|
||||||
.w_h(74.0, 74.0)
|
.w_h(74.0, 74.0)
|
||||||
.mid_top_with_margin_on(state.skills_top_l[0], 3.0)
|
.mid_top_with_margin_on(state.skills_top_l[0], 3.0)
|
||||||
.with_tooltip(
|
|
||||||
self.tooltip_manager,
|
|
||||||
&self.localized_strings.get("hud.skill.bow_title"),
|
|
||||||
&self.localized_strings.get("hud.skill.bow"),
|
|
||||||
&diary_tooltip,
|
|
||||||
TEXT_COLOR,
|
|
||||||
)
|
|
||||||
.set(state.skill_bow_basic_0, ui);
|
|
||||||
let skill = Skill::Bow(BDamage);
|
|
||||||
if create_skill_button(
|
|
||||||
self.imgs.physical_damage_skill,
|
|
||||||
state.skills_top_l[1],
|
|
||||||
&self.skill_set,
|
|
||||||
skill,
|
|
||||||
self.fonts,
|
|
||||||
&get_skill_label(skill, &self.skill_set),
|
|
||||||
)
|
|
||||||
.with_tooltip(
|
|
||||||
self.tooltip_manager,
|
|
||||||
&self.localized_strings.get("hud.skill.bow_damage_title"),
|
|
||||||
&add_sp_cost_tooltip(
|
|
||||||
&self.localized_strings.get("hud.skill.bow_damage"),
|
|
||||||
skill,
|
|
||||||
&self.skill_set,
|
|
||||||
&self.localized_strings,
|
|
||||||
),
|
|
||||||
&diary_tooltip,
|
|
||||||
TEXT_COLOR,
|
|
||||||
)
|
|
||||||
.set(state.skill_bow_basic_1, ui)
|
|
||||||
.was_clicked()
|
|
||||||
{
|
|
||||||
events.push(Event::UnlockSkill(skill));
|
|
||||||
};
|
|
||||||
let skill = Skill::Bow(BRegen);
|
|
||||||
if create_skill_button(
|
|
||||||
self.imgs.physical_energy_regen_skill,
|
|
||||||
state.skills_top_l[2],
|
|
||||||
&self.skill_set,
|
|
||||||
skill,
|
|
||||||
self.fonts,
|
|
||||||
&get_skill_label(skill, &self.skill_set),
|
|
||||||
)
|
|
||||||
.with_tooltip(
|
|
||||||
self.tooltip_manager,
|
|
||||||
&self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.skill.bow_energy_regen_title"),
|
|
||||||
&add_sp_cost_tooltip(
|
|
||||||
&self.localized_strings.get("hud.skill.bow_energy_regen"),
|
|
||||||
skill,
|
|
||||||
&self.skill_set,
|
|
||||||
&self.localized_strings,
|
|
||||||
),
|
|
||||||
&diary_tooltip,
|
|
||||||
TEXT_COLOR,
|
|
||||||
)
|
|
||||||
.set(state.skill_bow_basic_2, ui)
|
|
||||||
.was_clicked()
|
|
||||||
{
|
|
||||||
events.push(Event::UnlockSkill(skill));
|
|
||||||
};
|
|
||||||
// Top right skills
|
|
||||||
Button::image(self.imgs.bow_m2)
|
|
||||||
.w_h(74.0, 74.0)
|
|
||||||
.mid_top_with_margin_on(state.skills_top_r[0], 3.0)
|
|
||||||
.with_tooltip(
|
.with_tooltip(
|
||||||
self.tooltip_manager,
|
self.tooltip_manager,
|
||||||
&self.localized_strings.get("hud.skill.bow_charged_title"),
|
&self.localized_strings.get("hud.skill.bow_charged_title"),
|
||||||
@ -2584,7 +2518,7 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
let skill = Skill::Bow(CDamage);
|
let skill = Skill::Bow(CDamage);
|
||||||
if create_skill_button(
|
if create_skill_button(
|
||||||
self.imgs.physical_damage_skill,
|
self.imgs.physical_damage_skill,
|
||||||
state.skills_top_r[1],
|
state.skills_top_l[1],
|
||||||
&self.skill_set,
|
&self.skill_set,
|
||||||
skill,
|
skill,
|
||||||
self.fonts,
|
self.fonts,
|
||||||
@ -2609,10 +2543,10 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
{
|
{
|
||||||
events.push(Event::UnlockSkill(skill));
|
events.push(Event::UnlockSkill(skill));
|
||||||
};
|
};
|
||||||
let skill = Skill::Bow(CDrain);
|
let skill = Skill::Bow(CRegen);
|
||||||
if create_skill_button(
|
if create_skill_button(
|
||||||
self.imgs.physical_energy_drain_skill,
|
self.imgs.physical_energy_regen_skill,
|
||||||
state.skills_top_r[2],
|
state.skills_top_l[2],
|
||||||
&self.skill_set,
|
&self.skill_set,
|
||||||
skill,
|
skill,
|
||||||
self.fonts,
|
self.fonts,
|
||||||
@ -2622,9 +2556,11 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
self.tooltip_manager,
|
self.tooltip_manager,
|
||||||
&self
|
&self
|
||||||
.localized_strings
|
.localized_strings
|
||||||
.get("hud.skill.bow_charged_drain_title"),
|
.get("hud.skill.bow_charged_energy_regen_title"),
|
||||||
&add_sp_cost_tooltip(
|
&add_sp_cost_tooltip(
|
||||||
&self.localized_strings.get("hud.skill.bow_charged_drain"),
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.skill.bow_charged_energy_regen"),
|
||||||
skill,
|
skill,
|
||||||
&self.skill_set,
|
&self.skill_set,
|
||||||
&self.localized_strings,
|
&self.localized_strings,
|
||||||
@ -2637,10 +2573,10 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
{
|
{
|
||||||
events.push(Event::UnlockSkill(skill));
|
events.push(Event::UnlockSkill(skill));
|
||||||
};
|
};
|
||||||
let skill = Skill::Bow(CProjSpeed);
|
let skill = Skill::Bow(CKnockback);
|
||||||
if create_skill_button(
|
if create_skill_button(
|
||||||
self.imgs.physical_projectile_speed_skill,
|
self.imgs.physical_knockback_skill,
|
||||||
state.skills_top_r[3],
|
state.skills_top_l[3],
|
||||||
&self.skill_set,
|
&self.skill_set,
|
||||||
skill,
|
skill,
|
||||||
self.fonts,
|
self.fonts,
|
||||||
@ -2650,11 +2586,11 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
self.tooltip_manager,
|
self.tooltip_manager,
|
||||||
&self
|
&self
|
||||||
.localized_strings
|
.localized_strings
|
||||||
.get("hud.skill.bow_charged_projectile_speed_title"),
|
.get("hud.skill.bow_charged_knockback_title"),
|
||||||
&add_sp_cost_tooltip(
|
&add_sp_cost_tooltip(
|
||||||
&self
|
&self
|
||||||
.localized_strings
|
.localized_strings
|
||||||
.get("hud.skill.bow_charged_projectile_speed"),
|
.get("hud.skill.bow_charged_knockback"),
|
||||||
skill,
|
skill,
|
||||||
&self.skill_set,
|
&self.skill_set,
|
||||||
&self.localized_strings,
|
&self.localized_strings,
|
||||||
@ -2670,7 +2606,7 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
let skill = Skill::Bow(CSpeed);
|
let skill = Skill::Bow(CSpeed);
|
||||||
if create_skill_button(
|
if create_skill_button(
|
||||||
self.imgs.physical_speed_skill,
|
self.imgs.physical_speed_skill,
|
||||||
state.skills_top_r[4],
|
state.skills_top_l[4],
|
||||||
&self.skill_set,
|
&self.skill_set,
|
||||||
skill,
|
skill,
|
||||||
self.fonts,
|
self.fonts,
|
||||||
@ -2698,7 +2634,7 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
let skill = Skill::Bow(CMove);
|
let skill = Skill::Bow(CMove);
|
||||||
if create_skill_button(
|
if create_skill_button(
|
||||||
self.imgs.physical_speed_skill,
|
self.imgs.physical_speed_skill,
|
||||||
state.skills_top_r[5],
|
state.skills_top_l[5],
|
||||||
&self.skill_set,
|
&self.skill_set,
|
||||||
skill,
|
skill,
|
||||||
self.fonts,
|
self.fonts,
|
||||||
@ -2708,11 +2644,9 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
self.tooltip_manager,
|
self.tooltip_manager,
|
||||||
&self
|
&self
|
||||||
.localized_strings
|
.localized_strings
|
||||||
.get("hud.skill.bow_charged_move_speed_title"),
|
.get("hud.skill.bow_charged_move_title"),
|
||||||
&add_sp_cost_tooltip(
|
&add_sp_cost_tooltip(
|
||||||
&self
|
&self.localized_strings.get("hud.skill.bow_charged_move"),
|
||||||
.localized_strings
|
|
||||||
.get("hud.skill.bow_charged_move_speed"),
|
|
||||||
skill,
|
skill,
|
||||||
&self.skill_set,
|
&self.skill_set,
|
||||||
&self.localized_strings,
|
&self.localized_strings,
|
||||||
@ -2725,69 +2659,22 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
{
|
{
|
||||||
events.push(Event::UnlockSkill(skill));
|
events.push(Event::UnlockSkill(skill));
|
||||||
};
|
};
|
||||||
let skill = Skill::Bow(CKnockback);
|
// Top right skills
|
||||||
if create_skill_button(
|
Button::image(self.imgs.bow_m2)
|
||||||
self.imgs.physical_knockback_skill,
|
.w_h(74.0, 74.0)
|
||||||
state.skills_top_r[6],
|
.mid_top_with_margin_on(state.skills_top_r[0], 3.0)
|
||||||
&self.skill_set,
|
.with_tooltip(
|
||||||
skill,
|
self.tooltip_manager,
|
||||||
self.fonts,
|
&self.localized_strings.get("hud.skill.bow_repeater_title"),
|
||||||
&get_skill_label(skill, &self.skill_set),
|
&self.localized_strings.get("hud.skill.bow_repeater"),
|
||||||
)
|
&diary_tooltip,
|
||||||
.with_tooltip(
|
TEXT_COLOR,
|
||||||
self.tooltip_manager,
|
)
|
||||||
&self
|
.set(state.skill_bow_repeater_0, ui);
|
||||||
.localized_strings
|
|
||||||
.get("hud.skill.bow_charged_knockback_title"),
|
|
||||||
&add_sp_cost_tooltip(
|
|
||||||
&self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.skill.bow_charged_knockback"),
|
|
||||||
skill,
|
|
||||||
&self.skill_set,
|
|
||||||
&self.localized_strings,
|
|
||||||
),
|
|
||||||
&diary_tooltip,
|
|
||||||
TEXT_COLOR,
|
|
||||||
)
|
|
||||||
.set(state.skill_bow_charged_6, ui)
|
|
||||||
.was_clicked()
|
|
||||||
{
|
|
||||||
events.push(Event::UnlockSkill(skill));
|
|
||||||
};
|
|
||||||
// Bottom left skills
|
|
||||||
let skill = Skill::Bow(UnlockRepeater);
|
|
||||||
if create_skill_button(
|
|
||||||
self.imgs.skill_bow_jump_burst,
|
|
||||||
state.skills_bot_l[0],
|
|
||||||
&self.skill_set,
|
|
||||||
skill,
|
|
||||||
self.fonts,
|
|
||||||
&get_skill_label(skill, &self.skill_set),
|
|
||||||
)
|
|
||||||
.with_tooltip(
|
|
||||||
self.tooltip_manager,
|
|
||||||
&self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.skill.bow_repeater_unlock_title"),
|
|
||||||
&add_sp_cost_tooltip(
|
|
||||||
&self.localized_strings.get("hud.skill.bow_repeater_unlock"),
|
|
||||||
skill,
|
|
||||||
&self.skill_set,
|
|
||||||
&self.localized_strings,
|
|
||||||
),
|
|
||||||
&diary_tooltip,
|
|
||||||
TEXT_COLOR,
|
|
||||||
)
|
|
||||||
.set(state.skill_bow_repeater_0, ui)
|
|
||||||
.was_clicked()
|
|
||||||
{
|
|
||||||
events.push(Event::UnlockSkill(skill));
|
|
||||||
};
|
|
||||||
let skill = Skill::Bow(RDamage);
|
let skill = Skill::Bow(RDamage);
|
||||||
if create_skill_button(
|
if create_skill_button(
|
||||||
self.imgs.physical_damage_skill,
|
self.imgs.physical_damage_skill,
|
||||||
state.skills_bot_l[1],
|
state.skills_top_r[1],
|
||||||
&self.skill_set,
|
&self.skill_set,
|
||||||
skill,
|
skill,
|
||||||
self.fonts,
|
self.fonts,
|
||||||
@ -2812,38 +2699,10 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
{
|
{
|
||||||
events.push(Event::UnlockSkill(skill));
|
events.push(Event::UnlockSkill(skill));
|
||||||
};
|
};
|
||||||
let skill = Skill::Bow(RGlide);
|
|
||||||
if create_skill_button(
|
|
||||||
self.imgs.physical_helicopter_skill,
|
|
||||||
state.skills_bot_l[2],
|
|
||||||
&self.skill_set,
|
|
||||||
skill,
|
|
||||||
self.fonts,
|
|
||||||
&get_skill_label(skill, &self.skill_set),
|
|
||||||
)
|
|
||||||
.with_tooltip(
|
|
||||||
self.tooltip_manager,
|
|
||||||
&self
|
|
||||||
.localized_strings
|
|
||||||
.get("hud.skill.bow_repeater_glide_title"),
|
|
||||||
&add_sp_cost_tooltip(
|
|
||||||
&self.localized_strings.get("hud.skill.bow_repeater_glide"),
|
|
||||||
skill,
|
|
||||||
&self.skill_set,
|
|
||||||
&self.localized_strings,
|
|
||||||
),
|
|
||||||
&diary_tooltip,
|
|
||||||
TEXT_COLOR,
|
|
||||||
)
|
|
||||||
.set(state.skill_bow_repeater_2, ui)
|
|
||||||
.was_clicked()
|
|
||||||
{
|
|
||||||
events.push(Event::UnlockSkill(skill));
|
|
||||||
};
|
|
||||||
let skill = Skill::Bow(RCost);
|
let skill = Skill::Bow(RCost);
|
||||||
if create_skill_button(
|
if create_skill_button(
|
||||||
self.imgs.physical_cost_skill,
|
self.imgs.physical_cost_skill,
|
||||||
state.skills_bot_l[3],
|
state.skills_top_r[2],
|
||||||
&self.skill_set,
|
&self.skill_set,
|
||||||
skill,
|
skill,
|
||||||
self.fonts,
|
self.fonts,
|
||||||
@ -2863,14 +2722,157 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
&diary_tooltip,
|
&diary_tooltip,
|
||||||
TEXT_COLOR,
|
TEXT_COLOR,
|
||||||
)
|
)
|
||||||
|
.set(state.skill_bow_repeater_2, ui)
|
||||||
|
.was_clicked()
|
||||||
|
{
|
||||||
|
events.push(Event::UnlockSkill(skill));
|
||||||
|
};
|
||||||
|
let skill = Skill::Bow(RSpeed);
|
||||||
|
if create_skill_button(
|
||||||
|
self.imgs.physical_speed_skill,
|
||||||
|
state.skills_top_r[3],
|
||||||
|
&self.skill_set,
|
||||||
|
skill,
|
||||||
|
self.fonts,
|
||||||
|
&get_skill_label(skill, &self.skill_set),
|
||||||
|
)
|
||||||
|
.with_tooltip(
|
||||||
|
self.tooltip_manager,
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.skill.bow_repeater_speed_title"),
|
||||||
|
&add_sp_cost_tooltip(
|
||||||
|
&self.localized_strings.get("hud.skill.bow_repeater_speed"),
|
||||||
|
skill,
|
||||||
|
&self.skill_set,
|
||||||
|
&self.localized_strings,
|
||||||
|
),
|
||||||
|
&diary_tooltip,
|
||||||
|
TEXT_COLOR,
|
||||||
|
)
|
||||||
.set(state.skill_bow_repeater_3, ui)
|
.set(state.skill_bow_repeater_3, ui)
|
||||||
.was_clicked()
|
.was_clicked()
|
||||||
{
|
{
|
||||||
events.push(Event::UnlockSkill(skill));
|
events.push(Event::UnlockSkill(skill));
|
||||||
};
|
};
|
||||||
let skill = Skill::Bow(RArrows);
|
// Bottom left skills
|
||||||
|
let skill = Skill::Bow(UnlockShotgun);
|
||||||
|
if create_skill_button(
|
||||||
|
self.imgs.skill_bow_jump_burst,
|
||||||
|
state.skills_bot_l[0],
|
||||||
|
&self.skill_set,
|
||||||
|
skill,
|
||||||
|
self.fonts,
|
||||||
|
&get_skill_label(skill, &self.skill_set),
|
||||||
|
)
|
||||||
|
.with_tooltip(
|
||||||
|
self.tooltip_manager,
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.skill.bow_shotgun_unlock_title"),
|
||||||
|
&add_sp_cost_tooltip(
|
||||||
|
&self.localized_strings.get("hud.skill.bow_shotgun_unlock"),
|
||||||
|
skill,
|
||||||
|
&self.skill_set,
|
||||||
|
&self.localized_strings,
|
||||||
|
),
|
||||||
|
&diary_tooltip,
|
||||||
|
TEXT_COLOR,
|
||||||
|
)
|
||||||
|
.set(state.skill_bow_shotgun_0, ui)
|
||||||
|
.was_clicked()
|
||||||
|
{
|
||||||
|
events.push(Event::UnlockSkill(skill));
|
||||||
|
};
|
||||||
|
let skill = Skill::Bow(SDamage);
|
||||||
|
if create_skill_button(
|
||||||
|
self.imgs.physical_damage_skill,
|
||||||
|
state.skills_bot_l[1],
|
||||||
|
&self.skill_set,
|
||||||
|
skill,
|
||||||
|
self.fonts,
|
||||||
|
&get_skill_label(skill, &self.skill_set),
|
||||||
|
)
|
||||||
|
.with_tooltip(
|
||||||
|
self.tooltip_manager,
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.skill.bow_shotgun_damage_title"),
|
||||||
|
&add_sp_cost_tooltip(
|
||||||
|
&self.localized_strings.get("hud.skill.bow_shotgun_damage"),
|
||||||
|
skill,
|
||||||
|
&self.skill_set,
|
||||||
|
&self.localized_strings,
|
||||||
|
),
|
||||||
|
&diary_tooltip,
|
||||||
|
TEXT_COLOR,
|
||||||
|
)
|
||||||
|
.set(state.skill_bow_shotgun_1, ui)
|
||||||
|
.was_clicked()
|
||||||
|
{
|
||||||
|
events.push(Event::UnlockSkill(skill));
|
||||||
|
};
|
||||||
|
let skill = Skill::Bow(SCost);
|
||||||
|
if create_skill_button(
|
||||||
|
self.imgs.physical_cost_skill,
|
||||||
|
state.skills_bot_l[2],
|
||||||
|
&self.skill_set,
|
||||||
|
skill,
|
||||||
|
self.fonts,
|
||||||
|
&get_skill_label(skill, &self.skill_set),
|
||||||
|
)
|
||||||
|
.with_tooltip(
|
||||||
|
self.tooltip_manager,
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.skill.bow_shotgun_cost_title"),
|
||||||
|
&add_sp_cost_tooltip(
|
||||||
|
&self.localized_strings.get("hud.skill.bow_shotgun_cost"),
|
||||||
|
skill,
|
||||||
|
&self.skill_set,
|
||||||
|
&self.localized_strings,
|
||||||
|
),
|
||||||
|
&diary_tooltip,
|
||||||
|
TEXT_COLOR,
|
||||||
|
)
|
||||||
|
.set(state.skill_bow_shotgun_2, ui)
|
||||||
|
.was_clicked()
|
||||||
|
{
|
||||||
|
events.push(Event::UnlockSkill(skill));
|
||||||
|
};
|
||||||
|
let skill = Skill::Bow(SArrows);
|
||||||
if create_skill_button(
|
if create_skill_button(
|
||||||
self.imgs.physical_amount_skill,
|
self.imgs.physical_amount_skill,
|
||||||
|
state.skills_bot_l[3],
|
||||||
|
&self.skill_set,
|
||||||
|
skill,
|
||||||
|
self.fonts,
|
||||||
|
&get_skill_label(skill, &self.skill_set),
|
||||||
|
)
|
||||||
|
.with_tooltip(
|
||||||
|
self.tooltip_manager,
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.skill.bow_shotgun_arrow_count_title"),
|
||||||
|
&add_sp_cost_tooltip(
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.skill.bow_shotgun_arrow_count"),
|
||||||
|
skill,
|
||||||
|
&self.skill_set,
|
||||||
|
&self.localized_strings,
|
||||||
|
),
|
||||||
|
&diary_tooltip,
|
||||||
|
TEXT_COLOR,
|
||||||
|
)
|
||||||
|
.set(state.skill_bow_shotgun_3, ui)
|
||||||
|
.was_clicked()
|
||||||
|
{
|
||||||
|
events.push(Event::UnlockSkill(skill));
|
||||||
|
};
|
||||||
|
let skill = Skill::Bow(SSpread);
|
||||||
|
if create_skill_button(
|
||||||
|
self.imgs.physical_explosion_skill,
|
||||||
state.skills_bot_l[4],
|
state.skills_bot_l[4],
|
||||||
&self.skill_set,
|
&self.skill_set,
|
||||||
skill,
|
skill,
|
||||||
@ -2881,9 +2883,9 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
self.tooltip_manager,
|
self.tooltip_manager,
|
||||||
&self
|
&self
|
||||||
.localized_strings
|
.localized_strings
|
||||||
.get("hud.skill.bow_arrow_count_title"),
|
.get("hud.skill.bow_shotgun_spread_title"),
|
||||||
&add_sp_cost_tooltip(
|
&add_sp_cost_tooltip(
|
||||||
&self.localized_strings.get("hud.skill.bow_arrow_count"),
|
&self.localized_strings.get("hud.skill.bow_shotgun_spread"),
|
||||||
skill,
|
skill,
|
||||||
&self.skill_set,
|
&self.skill_set,
|
||||||
&self.localized_strings,
|
&self.localized_strings,
|
||||||
@ -2891,7 +2893,7 @@ impl<'a> Widget for Diary<'a> {
|
|||||||
&diary_tooltip,
|
&diary_tooltip,
|
||||||
TEXT_COLOR,
|
TEXT_COLOR,
|
||||||
)
|
)
|
||||||
.set(state.skill_bow_repeater_4, ui)
|
.set(state.skill_bow_shotgun_4, ui)
|
||||||
.was_clicked()
|
.was_clicked()
|
||||||
{
|
{
|
||||||
events.push(Event::UnlockSkill(skill));
|
events.push(Event::UnlockSkill(skill));
|
||||||
|
@ -1015,9 +1015,6 @@ impl FigureMgr {
|
|||||||
StageSection::Buildup => {
|
StageSection::Buildup => {
|
||||||
stage_time / s.static_data.buildup_duration.as_secs_f32()
|
stage_time / s.static_data.buildup_duration.as_secs_f32()
|
||||||
},
|
},
|
||||||
StageSection::Movement => {
|
|
||||||
stage_time / s.static_data.movement_duration.as_secs_f32()
|
|
||||||
},
|
|
||||||
StageSection::Shoot => {
|
StageSection::Shoot => {
|
||||||
stage_time / s.static_data.shoot_duration.as_secs_f32()
|
stage_time / s.static_data.shoot_duration.as_secs_f32()
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user