mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Addressed some review.
This commit is contained in:
parent
64c8321626
commit
8221336587
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -6191,7 +6191,6 @@ name = "veloren-common"
|
||||
version = "0.10.0"
|
||||
dependencies = [
|
||||
"approx 0.4.0",
|
||||
"bincode",
|
||||
"bitflags",
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
@ -6216,6 +6215,7 @@ dependencies = [
|
||||
"ron 0.7.0",
|
||||
"roots",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"sha2",
|
||||
"slab",
|
||||
|
@ -1,83 +1,83 @@
|
||||
({
|
||||
General(HealthIncrease): Some(10),
|
||||
General(EnergyIncrease): Some(5),
|
||||
Sword(TsDamage): Some(3),
|
||||
Sword(TsRegen): Some(2),
|
||||
Sword(TsSpeed): Some(3),
|
||||
Sword(DCost): Some(2),
|
||||
Sword(DDrain): Some(2),
|
||||
Sword(DDamage): Some(2),
|
||||
Sword(DScaling): Some(3),
|
||||
Sword(SDamage): Some(2),
|
||||
Sword(SSpeed): Some(2),
|
||||
Sword(SCost): Some(2),
|
||||
Sword(SSpins): Some(2),
|
||||
Axe(DsDamage): Some(3),
|
||||
Axe(DsRegen): Some(2),
|
||||
Axe(DsSpeed): Some(3),
|
||||
Axe(SDamage): Some(3),
|
||||
Axe(SSpeed): Some(2),
|
||||
Axe(SCost): Some(2),
|
||||
Axe(LDamage): Some(2),
|
||||
Axe(LKnockback): Some(2),
|
||||
Axe(LCost): Some(2),
|
||||
Axe(LDistance): Some(2),
|
||||
Hammer(SsKnockback): Some(2),
|
||||
Hammer(SsDamage): Some(3),
|
||||
Hammer(SsRegen): Some(2),
|
||||
Hammer(SsSpeed): Some(3),
|
||||
Hammer(CDamage): Some(3),
|
||||
Hammer(CKnockback): Some(3),
|
||||
Hammer(CDrain): Some(2),
|
||||
Hammer(CSpeed): Some(2),
|
||||
Hammer(LDamage): Some(2),
|
||||
Hammer(LCost): Some(2),
|
||||
Hammer(LDistance): Some(2),
|
||||
Hammer(LKnockback): Some(2),
|
||||
Hammer(LRange): Some(2),
|
||||
Bow(ProjSpeed): Some(2),
|
||||
Bow(CDamage): Some(3),
|
||||
Bow(CRegen): Some(2),
|
||||
Bow(CKnockback): Some(2),
|
||||
Bow(CSpeed): Some(2),
|
||||
Bow(CMove): Some(2),
|
||||
Bow(RDamage): Some(3),
|
||||
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(BRegen): Some(2),
|
||||
Staff(BRadius): Some(3),
|
||||
Staff(FRange): Some(2),
|
||||
Staff(FDamage): Some(3),
|
||||
Staff(FDrain): Some(2),
|
||||
Staff(FVelocity): Some(2),
|
||||
Staff(SDamage): Some(2),
|
||||
Staff(SKnockback): Some(2),
|
||||
Staff(SRange): Some(2),
|
||||
Staff(SCost): Some(2),
|
||||
Sceptre(LDamage): Some(3),
|
||||
Sceptre(LRange): Some(2),
|
||||
Sceptre(LLifesteal): Some(3),
|
||||
Sceptre(LRegen): Some(2),
|
||||
Sceptre(HHeal): Some(3),
|
||||
Sceptre(HRange): Some(2),
|
||||
Sceptre(HDuration): Some(2),
|
||||
Sceptre(HCost): Some(2),
|
||||
Sceptre(AStrength): Some(2),
|
||||
Sceptre(ADuration): Some(2),
|
||||
Sceptre(ARange): Some(2),
|
||||
Sceptre(ACost): Some(2),
|
||||
Roll(Cost): Some(2),
|
||||
Roll(Strength): Some(2),
|
||||
Roll(Duration): Some(2),
|
||||
Climb(Cost): Some(2),
|
||||
Climb(Speed): Some(2),
|
||||
Swim(Speed): Some(2),
|
||||
Pick(Speed): Some(3),
|
||||
Pick(OreGain): Some(3),
|
||||
Pick(GemGain): Some(3),
|
||||
General(HealthIncrease): 10,
|
||||
General(EnergyIncrease): 5,
|
||||
Sword(TsDamage): 3,
|
||||
Sword(TsRegen): 2,
|
||||
Sword(TsSpeed): 3,
|
||||
Sword(DCost): 2,
|
||||
Sword(DDrain): 2,
|
||||
Sword(DDamage): 2,
|
||||
Sword(DScaling): 3,
|
||||
Sword(SDamage): 2,
|
||||
Sword(SSpeed): 2,
|
||||
Sword(SCost): 2,
|
||||
Sword(SSpins): 2,
|
||||
Axe(DsDamage): 3,
|
||||
Axe(DsRegen): 2,
|
||||
Axe(DsSpeed): 3,
|
||||
Axe(SDamage): 3,
|
||||
Axe(SSpeed): 2,
|
||||
Axe(SCost): 2,
|
||||
Axe(LDamage): 2,
|
||||
Axe(LKnockback): 2,
|
||||
Axe(LCost): 2,
|
||||
Axe(LDistance): 2,
|
||||
Hammer(SsKnockback): 2,
|
||||
Hammer(SsDamage): 3,
|
||||
Hammer(SsRegen): 2,
|
||||
Hammer(SsSpeed): 3,
|
||||
Hammer(CDamage): 3,
|
||||
Hammer(CKnockback): 3,
|
||||
Hammer(CDrain): 2,
|
||||
Hammer(CSpeed): 2,
|
||||
Hammer(LDamage): 2,
|
||||
Hammer(LCost): 2,
|
||||
Hammer(LDistance): 2,
|
||||
Hammer(LKnockback): 2,
|
||||
Hammer(LRange): 2,
|
||||
Bow(ProjSpeed): 2,
|
||||
Bow(CDamage): 3,
|
||||
Bow(CRegen): 2,
|
||||
Bow(CKnockback): 2,
|
||||
Bow(CSpeed): 2,
|
||||
Bow(CMove): 2,
|
||||
Bow(RDamage): 3,
|
||||
Bow(RCost): 2,
|
||||
Bow(RSpeed): 2,
|
||||
Bow(SDamage): 2,
|
||||
Bow(SCost): 2,
|
||||
Bow(SArrows): 2,
|
||||
Bow(SSpread): 2,
|
||||
Staff(BDamage): 3,
|
||||
Staff(BRegen): 2,
|
||||
Staff(BRadius): 3,
|
||||
Staff(FRange): 2,
|
||||
Staff(FDamage): 3,
|
||||
Staff(FDrain): 2,
|
||||
Staff(FVelocity): 2,
|
||||
Staff(SDamage): 2,
|
||||
Staff(SKnockback): 2,
|
||||
Staff(SRange): 2,
|
||||
Staff(SCost): 2,
|
||||
Sceptre(LDamage): 3,
|
||||
Sceptre(LRange): 2,
|
||||
Sceptre(LLifesteal): 3,
|
||||
Sceptre(LRegen): 2,
|
||||
Sceptre(HHeal): 3,
|
||||
Sceptre(HRange): 2,
|
||||
Sceptre(HDuration): 2,
|
||||
Sceptre(HCost): 2,
|
||||
Sceptre(AStrength): 2,
|
||||
Sceptre(ADuration): 2,
|
||||
Sceptre(ARange): 2,
|
||||
Sceptre(ACost): 2,
|
||||
Roll(Cost): 2,
|
||||
Roll(Strength): 2,
|
||||
Roll(Duration): 2,
|
||||
Climb(Cost): 2,
|
||||
Climb(Speed): 2,
|
||||
Swim(Speed): 2,
|
||||
Pick(Speed): 3,
|
||||
Pick(OreGain): 3,
|
||||
Pick(GemGain): 3,
|
||||
})
|
||||
|
@ -1,27 +1,27 @@
|
||||
({
|
||||
Sword(SDamage): {Sword(UnlockSpin): None},
|
||||
Sword(SSpeed): {Sword(UnlockSpin): None},
|
||||
Sword(SCost): {Sword(UnlockSpin): None},
|
||||
Sword(SSpins): {Sword(UnlockSpin): None},
|
||||
Axe(LDamage): {Axe(UnlockLeap): None},
|
||||
Axe(LKnockback): {Axe(UnlockLeap): None},
|
||||
Axe(LCost): {Axe(UnlockLeap): None},
|
||||
Axe(LDistance): {Axe(UnlockLeap): None},
|
||||
Hammer(LDamage): {Hammer(UnlockLeap): None},
|
||||
Hammer(LCost): {Hammer(UnlockLeap): None},
|
||||
Hammer(LDistance): {Hammer(UnlockLeap): None},
|
||||
Hammer(LKnockback): {Hammer(UnlockLeap): None},
|
||||
Hammer(LRange): {Hammer(UnlockLeap): None},
|
||||
Bow(SDamage): {Bow(UnlockShotgun): None},
|
||||
Bow(SCost): {Bow(UnlockShotgun): None},
|
||||
Bow(SArrows): {Bow(UnlockShotgun): None},
|
||||
Bow(SSpread): {Bow(UnlockShotgun): None},
|
||||
Staff(SDamage): {Staff(UnlockShockwave): None},
|
||||
Staff(SKnockback): {Staff(UnlockShockwave): None},
|
||||
Staff(SRange): {Staff(UnlockShockwave): None},
|
||||
Staff(SCost): {Staff(UnlockShockwave): None},
|
||||
Sceptre(AStrength): {Sceptre(UnlockAura): None},
|
||||
Sceptre(ADuration): {Sceptre(UnlockAura): None},
|
||||
Sceptre(ARange): {Sceptre(UnlockAura): None},
|
||||
Sceptre(ACost): {Sceptre(UnlockAura): None},
|
||||
Sword(SDamage): {Sword(UnlockSpin): 1},
|
||||
Sword(SSpeed): {Sword(UnlockSpin): 1},
|
||||
Sword(SCost): {Sword(UnlockSpin): 1},
|
||||
Sword(SSpins): {Sword(UnlockSpin): 1},
|
||||
Axe(LDamage): {Axe(UnlockLeap): 1},
|
||||
Axe(LKnockback): {Axe(UnlockLeap): 1},
|
||||
Axe(LCost): {Axe(UnlockLeap): 1},
|
||||
Axe(LDistance): {Axe(UnlockLeap): 1},
|
||||
Hammer(LDamage): {Hammer(UnlockLeap): 1},
|
||||
Hammer(LCost): {Hammer(UnlockLeap): 1},
|
||||
Hammer(LDistance): {Hammer(UnlockLeap): 1},
|
||||
Hammer(LKnockback): {Hammer(UnlockLeap): 1},
|
||||
Hammer(LRange): {Hammer(UnlockLeap): 1},
|
||||
Bow(SDamage): {Bow(UnlockShotgun): 1},
|
||||
Bow(SCost): {Bow(UnlockShotgun): 1},
|
||||
Bow(SArrows): {Bow(UnlockShotgun): 1},
|
||||
Bow(SSpread): {Bow(UnlockShotgun): 1},
|
||||
Staff(SDamage): {Staff(UnlockShockwave): 1},
|
||||
Staff(SKnockback): {Staff(UnlockShockwave): 1},
|
||||
Staff(SRange): {Staff(UnlockShockwave): 1},
|
||||
Staff(SCost): {Staff(UnlockShockwave): 1},
|
||||
Sceptre(AStrength): {Sceptre(UnlockAura): 1},
|
||||
Sceptre(ADuration): {Sceptre(UnlockAura): 1},
|
||||
Sceptre(ARange): {Sceptre(UnlockAura): 1},
|
||||
Sceptre(ACost): {Sceptre(UnlockAura): 1},
|
||||
})
|
@ -26,7 +26,7 @@
|
||||
Sword(DDamage),
|
||||
Sword(DScaling),
|
||||
Sword(DSpeed),
|
||||
Sword(DInfinite),
|
||||
Sword(DChargeThrough),
|
||||
Sword(UnlockSpin),
|
||||
Sword(SDamage),
|
||||
Sword(SSpeed),
|
||||
|
@ -2,9 +2,9 @@
|
||||
Group(Weapon(Axe)),
|
||||
|
||||
// DoubleStrike
|
||||
Skill((Axe(DsDamage), Some(1))),
|
||||
Skill((Axe(DsDamage), 1)),
|
||||
// Spin
|
||||
Skill((Axe(SInfinite), None)),
|
||||
Skill((Axe(SDamage), Some(1))),
|
||||
Skill((Axe(SInfinite), 1)),
|
||||
Skill((Axe(SDamage), 1)),
|
||||
|
||||
])
|
||||
|
@ -2,13 +2,13 @@
|
||||
Group(Weapon(Bow)),
|
||||
|
||||
// Projectile Speed
|
||||
Skill((Bow(ProjSpeed), Some(1))),
|
||||
Skill((Bow(ProjSpeed), 1)),
|
||||
|
||||
// Charged
|
||||
Skill((Bow(CDamage), Some(1))),
|
||||
Skill((Bow(CKnockback), Some(1))),
|
||||
Skill((Bow(CDamage), 1)),
|
||||
Skill((Bow(CKnockback), 1)),
|
||||
|
||||
// Repeater
|
||||
Skill((Bow(RDamage), Some(1))),
|
||||
Skill((Bow(RDamage), 1)),
|
||||
|
||||
])
|
||||
|
@ -1,4 +1,4 @@
|
||||
([
|
||||
Skill((General(HealthIncrease), Some(2))),
|
||||
Skill((General(EnergyIncrease), Some(1))),
|
||||
Skill((General(HealthIncrease), 2)),
|
||||
Skill((General(EnergyIncrease), 1)),
|
||||
])
|
||||
|
@ -2,11 +2,11 @@
|
||||
Group(Weapon(Hammer)),
|
||||
|
||||
// Single Strike, as single as you are
|
||||
Skill((Hammer(SsKnockback), Some(1))),
|
||||
Skill((Hammer(SsDamage), Some(1))),
|
||||
Skill((Hammer(SsKnockback), 1)),
|
||||
Skill((Hammer(SsDamage), 1)),
|
||||
|
||||
// Charged
|
||||
Skill((Hammer(CDamage), Some(1))),
|
||||
Skill((Hammer(CKnockback), Some(1))),
|
||||
Skill((Hammer(CDamage), 1)),
|
||||
Skill((Hammer(CKnockback), 1)),
|
||||
|
||||
])
|
||||
|
@ -2,11 +2,11 @@
|
||||
Group(Weapon(Sceptre)),
|
||||
|
||||
// Beam
|
||||
Skill((Sceptre(LDamage), Some(1))),
|
||||
Skill((Sceptre(LRange), Some(1))),
|
||||
Skill((Sceptre(LDamage), 1)),
|
||||
Skill((Sceptre(LRange), 1)),
|
||||
|
||||
// Heal
|
||||
Skill((Sceptre(HHeal), Some(1))),
|
||||
Skill((Sceptre(HDuration), Some(1))),
|
||||
Skill((Sceptre(HHeal), 1)),
|
||||
Skill((Sceptre(HDuration), 1)),
|
||||
|
||||
])
|
||||
|
@ -2,11 +2,11 @@
|
||||
Group(Weapon(Staff)),
|
||||
|
||||
// Fireball
|
||||
Skill((Staff(BDamage), Some(2))),
|
||||
Skill((Staff(BRegen), Some(2))),
|
||||
Skill((Staff(BRadius), Some(1))),
|
||||
Skill((Staff(BDamage), 2)),
|
||||
Skill((Staff(BRegen), 2)),
|
||||
Skill((Staff(BRadius), 1)),
|
||||
|
||||
// Flamethrower
|
||||
Skill((Staff(FRange), Some(1))),
|
||||
Skill((Staff(FRange), 1)),
|
||||
|
||||
])
|
@ -1,14 +1,14 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
|
||||
Skill((Sword(InterruptingAttacks), None)),
|
||||
Skill((Sword(InterruptingAttacks), 1)),
|
||||
|
||||
// TripleStrike
|
||||
Skill((Sword(TsCombo), None)),
|
||||
Skill((Sword(TsDamage), Some(1))),
|
||||
Skill((Sword(TsRegen), Some(1))),
|
||||
Skill((Sword(TsCombo), 1)),
|
||||
Skill((Sword(TsDamage), 1)),
|
||||
Skill((Sword(TsRegen), 1)),
|
||||
|
||||
// Dash
|
||||
Skill((Sword(DCost), Some(1))),
|
||||
Skill((Sword(DCost), 1)),
|
||||
|
||||
])
|
||||
|
@ -2,13 +2,13 @@
|
||||
Group(Weapon(Axe)),
|
||||
|
||||
// DoubleStrike
|
||||
Skill((Axe(DsCombo), None)),
|
||||
Skill((Axe(DsDamage), Some(1))),
|
||||
Skill((Axe(DsRegen), Some(1))),
|
||||
Skill((Axe(DsCombo), 1)),
|
||||
Skill((Axe(DsDamage), 1)),
|
||||
Skill((Axe(DsRegen), 1)),
|
||||
// Spin
|
||||
Skill((Axe(SInfinite), None)),
|
||||
Skill((Axe(SHelicopter), None)),
|
||||
Skill((Axe(SDamage), Some(1))),
|
||||
Skill((Axe(SSpeed), Some(1))),
|
||||
Skill((Axe(SInfinite), 1)),
|
||||
Skill((Axe(SHelicopter), 1)),
|
||||
Skill((Axe(SDamage), 1)),
|
||||
Skill((Axe(SSpeed), 1)),
|
||||
|
||||
])
|
||||
|
@ -2,16 +2,16 @@
|
||||
Group(Weapon(Bow)),
|
||||
|
||||
// Projectile Speed
|
||||
Skill((Bow(ProjSpeed), Some(1))),
|
||||
Skill((Bow(ProjSpeed), 1)),
|
||||
|
||||
// Charged
|
||||
Skill((Bow(CDamage), Some(1))),
|
||||
Skill((Bow(CKnockback), Some(1))),
|
||||
Skill((Bow(CSpeed), Some(1))),
|
||||
Skill((Bow(CRegen), Some(1))),
|
||||
Skill((Bow(CDamage), 1)),
|
||||
Skill((Bow(CKnockback), 1)),
|
||||
Skill((Bow(CSpeed), 1)),
|
||||
Skill((Bow(CRegen), 1)),
|
||||
|
||||
// Repeater
|
||||
Skill((Bow(RDamage), Some(1))),
|
||||
Skill((Bow(RCost), Some(1))),
|
||||
Skill((Bow(RDamage), 1)),
|
||||
Skill((Bow(RCost), 1)),
|
||||
|
||||
])
|
||||
|
@ -1,4 +1,4 @@
|
||||
([
|
||||
Skill((General(HealthIncrease), Some(4))),
|
||||
Skill((General(EnergyIncrease), Some(2))),
|
||||
Skill((General(HealthIncrease), 4)),
|
||||
Skill((General(EnergyIncrease), 2)),
|
||||
])
|
||||
|
@ -2,15 +2,15 @@
|
||||
Group(Weapon(Hammer)),
|
||||
|
||||
// Single Strike, as single as you are
|
||||
Skill((Hammer(SsKnockback), Some(1))),
|
||||
Skill((Hammer(SsDamage), Some(2))),
|
||||
Skill((Hammer(SsRegen), Some(1))),
|
||||
Skill((Hammer(SsSpeed), Some(1))),
|
||||
Skill((Hammer(SsKnockback), 1)),
|
||||
Skill((Hammer(SsDamage), 2)),
|
||||
Skill((Hammer(SsRegen), 1)),
|
||||
Skill((Hammer(SsSpeed), 1)),
|
||||
|
||||
// Charged
|
||||
Skill((Hammer(CDamage), Some(1))),
|
||||
Skill((Hammer(CKnockback), Some(1))),
|
||||
Skill((Hammer(CDrain), Some(1))),
|
||||
Skill((Hammer(CSpeed), Some(1))),
|
||||
Skill((Hammer(CDamage), 1)),
|
||||
Skill((Hammer(CKnockback), 1)),
|
||||
Skill((Hammer(CDrain), 1)),
|
||||
Skill((Hammer(CSpeed), 1)),
|
||||
|
||||
])
|
||||
|
@ -2,15 +2,15 @@
|
||||
Group(Weapon(Sceptre)),
|
||||
|
||||
// Beam
|
||||
Skill((Sceptre(LDamage), Some(1))),
|
||||
Skill((Sceptre(LRange), Some(1))),
|
||||
Skill((Sceptre(LLifesteal), Some(1))),
|
||||
Skill((Sceptre(LRegen), Some(1))),
|
||||
Skill((Sceptre(LDamage), 1)),
|
||||
Skill((Sceptre(LRange), 1)),
|
||||
Skill((Sceptre(LLifesteal), 1)),
|
||||
Skill((Sceptre(LRegen), 1)),
|
||||
|
||||
// Heal
|
||||
Skill((Sceptre(HHeal), Some(1))),
|
||||
Skill((Sceptre(HDuration), Some(1))),
|
||||
Skill((Sceptre(HRange), Some(1))),
|
||||
Skill((Sceptre(HCost), Some(1))),
|
||||
Skill((Sceptre(HHeal), 1)),
|
||||
Skill((Sceptre(HDuration), 1)),
|
||||
Skill((Sceptre(HRange), 1)),
|
||||
Skill((Sceptre(HCost), 1)),
|
||||
|
||||
])
|
||||
|
@ -2,12 +2,12 @@
|
||||
Group(Weapon(Staff)),
|
||||
|
||||
// Fireball
|
||||
Skill((Staff(BDamage), Some(2))),
|
||||
Skill((Staff(BRegen), Some(2))),
|
||||
Skill((Staff(BRadius), Some(1))),
|
||||
Skill((Staff(BDamage), 2)),
|
||||
Skill((Staff(BRegen), 2)),
|
||||
Skill((Staff(BRadius), 1)),
|
||||
|
||||
// Flamethrower
|
||||
Skill((Staff(FRange), Some(2))),
|
||||
Skill((Staff(FDamage), Some(2))),
|
||||
Skill((Staff(FRange), 2)),
|
||||
Skill((Staff(FDamage), 2)),
|
||||
|
||||
])
|
||||
|
@ -1,17 +1,17 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
|
||||
Skill((Sword(InterruptingAttacks), None)),
|
||||
Skill((Sword(InterruptingAttacks), 1)),
|
||||
|
||||
// TripleStrike
|
||||
Skill((Sword(TsCombo), None)),
|
||||
Skill((Sword(TsDamage), Some(1))),
|
||||
Skill((Sword(TsRegen), Some(1))),
|
||||
Skill((Sword(TsSpeed), Some(1))),
|
||||
Skill((Sword(TsCombo), 1)),
|
||||
Skill((Sword(TsDamage), 1)),
|
||||
Skill((Sword(TsRegen), 1)),
|
||||
Skill((Sword(TsSpeed), 1)),
|
||||
|
||||
// Dash
|
||||
Skill((Sword(DCost), Some(1))),
|
||||
Skill((Sword(DDrain), Some(1))),
|
||||
Skill((Sword(DDamage), Some(1))),
|
||||
Skill((Sword(DCost), 1)),
|
||||
Skill((Sword(DDrain), 1)),
|
||||
Skill((Sword(DDamage), 1)),
|
||||
|
||||
])
|
||||
|
@ -2,19 +2,19 @@
|
||||
Group(Weapon(Axe)),
|
||||
|
||||
// DoubleStrike
|
||||
Skill((Axe(DsCombo), None)),
|
||||
Skill((Axe(DsDamage), Some(1))),
|
||||
Skill((Axe(DsRegen), Some(1))),
|
||||
Skill((Axe(DsSpeed), Some(1))),
|
||||
Skill((Axe(DsCombo), 1)),
|
||||
Skill((Axe(DsDamage), 1)),
|
||||
Skill((Axe(DsRegen), 1)),
|
||||
Skill((Axe(DsSpeed), 1)),
|
||||
|
||||
// Spin
|
||||
Skill((Axe(SInfinite), None)),
|
||||
Skill((Axe(SHelicopter), None)),
|
||||
Skill((Axe(SDamage), Some(1))),
|
||||
Skill((Axe(SSpeed), Some(1))),
|
||||
Skill((Axe(SCost), Some(1))),
|
||||
Skill((Axe(SInfinite), 1)),
|
||||
Skill((Axe(SHelicopter), 1)),
|
||||
Skill((Axe(SDamage), 1)),
|
||||
Skill((Axe(SSpeed), 1)),
|
||||
Skill((Axe(SCost), 1)),
|
||||
|
||||
// Leap
|
||||
Skill((Axe(UnlockLeap), None)),
|
||||
Skill((Axe(LDamage), Some(1))),
|
||||
Skill((Axe(UnlockLeap), 1)),
|
||||
Skill((Axe(LDamage), 1)),
|
||||
])
|
||||
|
@ -2,22 +2,22 @@
|
||||
Group(Weapon(Bow)),
|
||||
|
||||
// Projectile Speed
|
||||
Skill((Bow(ProjSpeed), Some(2))),
|
||||
Skill((Bow(ProjSpeed), 2)),
|
||||
|
||||
// Charged
|
||||
Skill((Bow(CDamage), Some(1))),
|
||||
Skill((Bow(CKnockback), Some(1))),
|
||||
Skill((Bow(CSpeed), Some(1))),
|
||||
Skill((Bow(CRegen), Some(1))),
|
||||
Skill((Bow(CMove), Some(1))),
|
||||
Skill((Bow(CDamage), 1)),
|
||||
Skill((Bow(CKnockback), 1)),
|
||||
Skill((Bow(CSpeed), 1)),
|
||||
Skill((Bow(CRegen), 1)),
|
||||
Skill((Bow(CMove), 1)),
|
||||
|
||||
// Repeater
|
||||
Skill((Bow(RDamage), Some(1))),
|
||||
Skill((Bow(RCost), Some(1))),
|
||||
Skill((Bow(RSpeed), Some(1))),
|
||||
Skill((Bow(RDamage), 1)),
|
||||
Skill((Bow(RCost), 1)),
|
||||
Skill((Bow(RSpeed), 1)),
|
||||
|
||||
// Shotgun
|
||||
Skill((Bow(UnlockShotgun), None)),
|
||||
Skill((Bow(SDamage), Some(1))),
|
||||
Skill((Bow(SCost), Some(1))),
|
||||
Skill((Bow(UnlockShotgun), 1)),
|
||||
Skill((Bow(SDamage), 1)),
|
||||
Skill((Bow(SCost), 1)),
|
||||
])
|
||||
|
@ -1,4 +1,4 @@
|
||||
([
|
||||
Skill((General(HealthIncrease), Some(6))),
|
||||
Skill((General(EnergyIncrease), Some(3))),
|
||||
Skill((General(HealthIncrease), 6)),
|
||||
Skill((General(EnergyIncrease), 3)),
|
||||
])
|
||||
|
@ -2,20 +2,20 @@
|
||||
Group(Weapon(Hammer)),
|
||||
|
||||
// Single Strike, as single as you are
|
||||
Skill((Hammer(SsKnockback), Some(2))),
|
||||
Skill((Hammer(SsDamage), Some(2))),
|
||||
Skill((Hammer(SsRegen), Some(1))),
|
||||
Skill((Hammer(SsSpeed), Some(1))),
|
||||
Skill((Hammer(SsKnockback), 2)),
|
||||
Skill((Hammer(SsDamage), 2)),
|
||||
Skill((Hammer(SsRegen), 1)),
|
||||
Skill((Hammer(SsSpeed), 1)),
|
||||
|
||||
// Charged
|
||||
Skill((Hammer(CDamage), Some(2))),
|
||||
Skill((Hammer(CKnockback), Some(1))),
|
||||
Skill((Hammer(CDrain), Some(1))),
|
||||
Skill((Hammer(CSpeed), Some(1))),
|
||||
Skill((Hammer(CDamage), 2)),
|
||||
Skill((Hammer(CKnockback), 1)),
|
||||
Skill((Hammer(CDrain), 1)),
|
||||
Skill((Hammer(CSpeed), 1)),
|
||||
|
||||
// Leap
|
||||
Skill((Hammer(UnlockLeap), None)),
|
||||
Skill((Hammer(LDamage), Some(1))),
|
||||
Skill((Hammer(LCost), Some(1))),
|
||||
Skill((Hammer(LDistance), Some(1))),
|
||||
Skill((Hammer(UnlockLeap), 1)),
|
||||
Skill((Hammer(LDamage), 1)),
|
||||
Skill((Hammer(LCost), 1)),
|
||||
Skill((Hammer(LDistance), 1)),
|
||||
])
|
||||
|
@ -2,18 +2,18 @@
|
||||
Group(Weapon(Sceptre)),
|
||||
|
||||
// Beam
|
||||
Skill((Sceptre(LDamage), Some(2))),
|
||||
Skill((Sceptre(LRange), Some(2))),
|
||||
Skill((Sceptre(LLifesteal), Some(1))),
|
||||
Skill((Sceptre(LRegen), Some(1))),
|
||||
Skill((Sceptre(LDamage), 2)),
|
||||
Skill((Sceptre(LRange), 2)),
|
||||
Skill((Sceptre(LLifesteal), 1)),
|
||||
Skill((Sceptre(LRegen), 1)),
|
||||
|
||||
// Heal
|
||||
Skill((Sceptre(HHeal), Some(2))),
|
||||
Skill((Sceptre(HDuration), Some(1))),
|
||||
Skill((Sceptre(HRange), Some(1))),
|
||||
Skill((Sceptre(HCost), Some(1))),
|
||||
Skill((Sceptre(HHeal), 2)),
|
||||
Skill((Sceptre(HDuration), 1)),
|
||||
Skill((Sceptre(HRange), 1)),
|
||||
Skill((Sceptre(HCost), 1)),
|
||||
// Ward
|
||||
Skill((Sceptre(UnlockAura), None)),
|
||||
Skill((Sceptre(AStrength), Some(1))),
|
||||
Skill((Sceptre(ADuration), Some(1))),
|
||||
Skill((Sceptre(UnlockAura), 1)),
|
||||
Skill((Sceptre(AStrength), 1)),
|
||||
Skill((Sceptre(ADuration), 1)),
|
||||
])
|
||||
|
@ -2,14 +2,14 @@
|
||||
Group(Weapon(Staff)),
|
||||
|
||||
// Fireball
|
||||
Skill((Staff(BDamage), Some(2))),
|
||||
Skill((Staff(BRegen), Some(2))),
|
||||
Skill((Staff(BRadius), Some(2))),
|
||||
Skill((Staff(BDamage), 2)),
|
||||
Skill((Staff(BRegen), 2)),
|
||||
Skill((Staff(BRadius), 2)),
|
||||
|
||||
// Flamethrower
|
||||
Skill((Staff(FRange), Some(2))),
|
||||
Skill((Staff(FDamage), Some(3))),
|
||||
Skill((Staff(FDrain), Some(2))),
|
||||
Skill((Staff(FVelocity), Some(1))),
|
||||
Skill((Staff(FRange), 2)),
|
||||
Skill((Staff(FDamage), 3)),
|
||||
Skill((Staff(FDrain), 2)),
|
||||
Skill((Staff(FVelocity), 1)),
|
||||
|
||||
])
|
@ -1,23 +1,23 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
|
||||
Skill((Sword(InterruptingAttacks), None)),
|
||||
Skill((Sword(InterruptingAttacks), 1)),
|
||||
|
||||
// TripleStrike
|
||||
Skill((Sword(TsCombo), None)),
|
||||
Skill((Sword(TsDamage), Some(2))),
|
||||
Skill((Sword(TsRegen), Some(2))),
|
||||
Skill((Sword(TsSpeed), Some(1))),
|
||||
Skill((Sword(TsCombo), 1)),
|
||||
Skill((Sword(TsDamage), 2)),
|
||||
Skill((Sword(TsRegen), 2)),
|
||||
Skill((Sword(TsSpeed), 1)),
|
||||
|
||||
// Dash
|
||||
Skill((Sword(DCost), Some(2))),
|
||||
Skill((Sword(DDrain), Some(2))),
|
||||
Skill((Sword(DDamage), Some(1))),
|
||||
Skill((Sword(DScaling), Some(1))),
|
||||
Skill((Sword(DSpeed), None)),
|
||||
Skill((Sword(DCost), 2)),
|
||||
Skill((Sword(DDrain), 2)),
|
||||
Skill((Sword(DDamage), 1)),
|
||||
Skill((Sword(DScaling), 1)),
|
||||
Skill((Sword(DSpeed), 1)),
|
||||
|
||||
// Spin of death
|
||||
Skill((Sword(UnlockSpin), None)),
|
||||
Skill((Sword(SDamage), Some(1))),
|
||||
Skill((Sword(SSpeed), Some(1))),
|
||||
Skill((Sword(UnlockSpin), 1)),
|
||||
Skill((Sword(SDamage), 1)),
|
||||
Skill((Sword(SSpeed), 1)),
|
||||
])
|
||||
|
@ -2,22 +2,22 @@
|
||||
Group(Weapon(Axe)),
|
||||
|
||||
// DoubleStrike
|
||||
Skill((Axe(DsCombo), None)),
|
||||
Skill((Axe(DsDamage), Some(2))),
|
||||
Skill((Axe(DsRegen), Some(1))),
|
||||
Skill((Axe(DsSpeed), Some(2))),
|
||||
Skill((Axe(DsCombo), 1)),
|
||||
Skill((Axe(DsDamage), 2)),
|
||||
Skill((Axe(DsRegen), 1)),
|
||||
Skill((Axe(DsSpeed), 2)),
|
||||
|
||||
// Spin
|
||||
Skill((Axe(SInfinite), None)),
|
||||
Skill((Axe(SHelicopter), None)),
|
||||
Skill((Axe(SDamage), Some(2))),
|
||||
Skill((Axe(SSpeed), Some(1))),
|
||||
Skill((Axe(SCost), Some(1))),
|
||||
Skill((Axe(SInfinite), 1)),
|
||||
Skill((Axe(SHelicopter), 1)),
|
||||
Skill((Axe(SDamage), 2)),
|
||||
Skill((Axe(SSpeed), 1)),
|
||||
Skill((Axe(SCost), 1)),
|
||||
|
||||
// Leap
|
||||
Skill((Axe(UnlockLeap), None)),
|
||||
Skill((Axe(LDamage), Some(1))),
|
||||
Skill((Axe(LKnockback), Some(1))),
|
||||
Skill((Axe(LCost), Some(1))),
|
||||
Skill((Axe(LDistance), Some(1))),
|
||||
Skill((Axe(UnlockLeap), 1)),
|
||||
Skill((Axe(LDamage), 1)),
|
||||
Skill((Axe(LKnockback), 1)),
|
||||
Skill((Axe(LCost), 1)),
|
||||
Skill((Axe(LDistance), 1)),
|
||||
])
|
||||
|
@ -2,24 +2,24 @@
|
||||
Group(Weapon(Bow)),
|
||||
|
||||
// Projectile Speed
|
||||
Skill((Bow(ProjSpeed), Some(2))),
|
||||
Skill((Bow(ProjSpeed), 2)),
|
||||
|
||||
// Charged
|
||||
Skill((Bow(CDamage), Some(2))),
|
||||
Skill((Bow(CKnockback), Some(2))),
|
||||
Skill((Bow(CSpeed), Some(2))),
|
||||
Skill((Bow(CRegen), Some(1))),
|
||||
Skill((Bow(CMove), Some(1))),
|
||||
Skill((Bow(CDamage), 2)),
|
||||
Skill((Bow(CKnockback), 2)),
|
||||
Skill((Bow(CSpeed), 2)),
|
||||
Skill((Bow(CRegen), 1)),
|
||||
Skill((Bow(CMove), 1)),
|
||||
|
||||
// Repeater
|
||||
Skill((Bow(RDamage), Some(2))),
|
||||
Skill((Bow(RCost), Some(1))),
|
||||
Skill((Bow(RSpeed), Some(1))),
|
||||
Skill((Bow(RDamage), 2)),
|
||||
Skill((Bow(RCost), 1)),
|
||||
Skill((Bow(RSpeed), 1)),
|
||||
|
||||
// Shotgun
|
||||
Skill((Bow(UnlockShotgun), None)),
|
||||
Skill((Bow(SDamage), Some(1))),
|
||||
Skill((Bow(SCost), Some(1))),
|
||||
Skill((Bow(SArrows), Some(1))),
|
||||
Skill((Bow(SSpread), Some(1))),
|
||||
Skill((Bow(UnlockShotgun), 1)),
|
||||
Skill((Bow(SDamage), 1)),
|
||||
Skill((Bow(SCost), 1)),
|
||||
Skill((Bow(SArrows), 1)),
|
||||
Skill((Bow(SSpread), 1)),
|
||||
])
|
||||
|
@ -1,4 +1,4 @@
|
||||
([
|
||||
Skill((General(HealthIncrease), Some(8))),
|
||||
Skill((General(EnergyIncrease), Some(4))),
|
||||
Skill((General(HealthIncrease), 8)),
|
||||
Skill((General(EnergyIncrease), 4)),
|
||||
])
|
||||
|
@ -2,22 +2,22 @@
|
||||
Group(Weapon(Hammer)),
|
||||
|
||||
// Single Strike, as single as you are
|
||||
Skill((Hammer(SsKnockback), Some(2))),
|
||||
Skill((Hammer(SsDamage), Some(2))),
|
||||
Skill((Hammer(SsRegen), Some(2))),
|
||||
Skill((Hammer(SsSpeed), Some(2))),
|
||||
Skill((Hammer(SsKnockback), 2)),
|
||||
Skill((Hammer(SsDamage), 2)),
|
||||
Skill((Hammer(SsRegen), 2)),
|
||||
Skill((Hammer(SsSpeed), 2)),
|
||||
|
||||
// Charged
|
||||
Skill((Hammer(CDamage), Some(2))),
|
||||
Skill((Hammer(CKnockback), Some(2))),
|
||||
Skill((Hammer(CDrain), Some(2))),
|
||||
Skill((Hammer(CSpeed), Some(2))),
|
||||
Skill((Hammer(CDamage), 2)),
|
||||
Skill((Hammer(CKnockback), 2)),
|
||||
Skill((Hammer(CDrain), 2)),
|
||||
Skill((Hammer(CSpeed), 2)),
|
||||
|
||||
// Leap
|
||||
Skill((Hammer(UnlockLeap), None)),
|
||||
Skill((Hammer(LDamage), Some(1))),
|
||||
Skill((Hammer(LCost), Some(1))),
|
||||
Skill((Hammer(LDistance), Some(1))),
|
||||
Skill((Hammer(LKnockback), Some(1))),
|
||||
Skill((Hammer(LRange), Some(1))),
|
||||
Skill((Hammer(UnlockLeap), 1)),
|
||||
Skill((Hammer(LDamage), 1)),
|
||||
Skill((Hammer(LCost), 1)),
|
||||
Skill((Hammer(LDistance), 1)),
|
||||
Skill((Hammer(LKnockback), 1)),
|
||||
Skill((Hammer(LRange), 1)),
|
||||
])
|
||||
|
@ -2,20 +2,20 @@
|
||||
Group(Weapon(Sceptre)),
|
||||
|
||||
// Beam
|
||||
Skill((Sceptre(LDamage), Some(2))),
|
||||
Skill((Sceptre(LRange), Some(2))),
|
||||
Skill((Sceptre(LLifesteal), Some(2))),
|
||||
Skill((Sceptre(LRegen), Some(2))),
|
||||
Skill((Sceptre(LDamage), 2)),
|
||||
Skill((Sceptre(LRange), 2)),
|
||||
Skill((Sceptre(LLifesteal), 2)),
|
||||
Skill((Sceptre(LRegen), 2)),
|
||||
|
||||
// Heal
|
||||
Skill((Sceptre(HHeal), Some(2))),
|
||||
Skill((Sceptre(HDuration), Some(2))),
|
||||
Skill((Sceptre(HRange), Some(2))),
|
||||
Skill((Sceptre(HCost), Some(2))),
|
||||
Skill((Sceptre(HHeal), 2)),
|
||||
Skill((Sceptre(HDuration), 2)),
|
||||
Skill((Sceptre(HRange), 2)),
|
||||
Skill((Sceptre(HCost), 2)),
|
||||
// Ward
|
||||
Skill((Sceptre(UnlockAura), None)),
|
||||
Skill((Sceptre(AStrength), Some(1))),
|
||||
Skill((Sceptre(ADuration), Some(1))),
|
||||
Skill((Sceptre(ARange), Some(1))),
|
||||
Skill((Sceptre(ACost), Some(1))),
|
||||
Skill((Sceptre(UnlockAura), 1)),
|
||||
Skill((Sceptre(AStrength), 1)),
|
||||
Skill((Sceptre(ADuration), 1)),
|
||||
Skill((Sceptre(ARange), 1)),
|
||||
Skill((Sceptre(ACost), 1)),
|
||||
])
|
||||
|
@ -2,20 +2,20 @@
|
||||
Group(Weapon(Staff)),
|
||||
|
||||
// Fireball
|
||||
Skill((Staff(BDamage), Some(1))),
|
||||
Skill((Staff(BRegen), Some(2))),
|
||||
Skill((Staff(BRadius), Some(2))),
|
||||
Skill((Staff(BDamage), 1)),
|
||||
Skill((Staff(BRegen), 2)),
|
||||
Skill((Staff(BRadius), 2)),
|
||||
|
||||
// Flamethrower
|
||||
Skill((Staff(FRange), Some(2))),
|
||||
Skill((Staff(FDamage), Some(1))),
|
||||
Skill((Staff(FDrain), Some(1))),
|
||||
Skill((Staff(FVelocity), Some(2))),
|
||||
Skill((Staff(FRange), 2)),
|
||||
Skill((Staff(FDamage), 1)),
|
||||
Skill((Staff(FDrain), 1)),
|
||||
Skill((Staff(FVelocity), 2)),
|
||||
|
||||
// Shockwave
|
||||
Skill((Staff(UnlockShockwave), None)),
|
||||
Skill((Staff(SDamage), Some(1))),
|
||||
Skill((Staff(SKnockback), Some(1))),
|
||||
Skill((Staff(SRange), Some(1))),
|
||||
Skill((Staff(SCost), Some(1))),
|
||||
Skill((Staff(UnlockShockwave), 1)),
|
||||
Skill((Staff(SDamage), 1)),
|
||||
Skill((Staff(SKnockback), 1)),
|
||||
Skill((Staff(SRange), 1)),
|
||||
Skill((Staff(SCost), 1)),
|
||||
])
|
||||
|
@ -1,26 +1,26 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
|
||||
Skill((Sword(InterruptingAttacks), None)),
|
||||
Skill((Sword(InterruptingAttacks), 1)),
|
||||
|
||||
// TripleStrike
|
||||
Skill((Sword(TsCombo), None)),
|
||||
Skill((Sword(TsDamage), Some(2))),
|
||||
Skill((Sword(TsRegen), Some(2))),
|
||||
Skill((Sword(TsSpeed), Some(3))),
|
||||
Skill((Sword(TsCombo), 1)),
|
||||
Skill((Sword(TsDamage), 2)),
|
||||
Skill((Sword(TsRegen), 2)),
|
||||
Skill((Sword(TsSpeed), 3)),
|
||||
|
||||
// Dash
|
||||
Skill((Sword(DCost), Some(2))),
|
||||
Skill((Sword(DDrain), Some(2))),
|
||||
Skill((Sword(DDamage), Some(2))),
|
||||
Skill((Sword(DScaling), Some(2))),
|
||||
Skill((Sword(DSpeed), None)),
|
||||
Skill((Sword(DInfinite), None)),
|
||||
Skill((Sword(DCost), 2)),
|
||||
Skill((Sword(DDrain), 2)),
|
||||
Skill((Sword(DDamage), 2)),
|
||||
Skill((Sword(DScaling), 2)),
|
||||
Skill((Sword(DSpeed), 1)),
|
||||
Skill((Sword(DChargeThrough), 1)),
|
||||
|
||||
// Spin of death
|
||||
Skill((Sword(UnlockSpin), None)),
|
||||
Skill((Sword(SDamage), Some(1))),
|
||||
Skill((Sword(SSpeed), Some(1))),
|
||||
Skill((Sword(SSpins), Some(1))),
|
||||
Skill((Sword(SCost), Some(1))),
|
||||
Skill((Sword(UnlockSpin), 1)),
|
||||
Skill((Sword(SDamage), 1)),
|
||||
Skill((Sword(SSpeed), 1)),
|
||||
Skill((Sword(SSpins), 1)),
|
||||
Skill((Sword(SCost), 1)),
|
||||
])
|
||||
|
@ -2,22 +2,22 @@
|
||||
Group(Weapon(Axe)),
|
||||
|
||||
// DoubleStrike
|
||||
Skill((Axe(DsCombo), None)),
|
||||
Skill((Axe(DsDamage), Some(3))),
|
||||
Skill((Axe(DsRegen), Some(2))),
|
||||
Skill((Axe(DsSpeed), Some(3))),
|
||||
Skill((Axe(DsCombo), 1)),
|
||||
Skill((Axe(DsDamage), 3)),
|
||||
Skill((Axe(DsRegen), 2)),
|
||||
Skill((Axe(DsSpeed), 3)),
|
||||
|
||||
// Spin
|
||||
Skill((Axe(SInfinite), None)),
|
||||
Skill((Axe(SHelicopter), None)),
|
||||
Skill((Axe(SDamage), Some(3))),
|
||||
Skill((Axe(SSpeed), Some(2))),
|
||||
Skill((Axe(SCost), Some(2))),
|
||||
Skill((Axe(SInfinite), 1)),
|
||||
Skill((Axe(SHelicopter), 1)),
|
||||
Skill((Axe(SDamage), 3)),
|
||||
Skill((Axe(SSpeed), 2)),
|
||||
Skill((Axe(SCost), 2)),
|
||||
|
||||
// Leap
|
||||
Skill((Axe(UnlockLeap), None)),
|
||||
Skill((Axe(LDamage), Some(2))),
|
||||
Skill((Axe(LKnockback), Some(2))),
|
||||
Skill((Axe(LCost), Some(2))),
|
||||
Skill((Axe(LDistance), Some(2))),
|
||||
Skill((Axe(UnlockLeap), 1)),
|
||||
Skill((Axe(LDamage), 2)),
|
||||
Skill((Axe(LKnockback), 2)),
|
||||
Skill((Axe(LCost), 2)),
|
||||
Skill((Axe(LDistance), 2)),
|
||||
])
|
||||
|
@ -2,24 +2,24 @@
|
||||
Group(Weapon(Bow)),
|
||||
|
||||
// Projectile Speed
|
||||
Skill((Bow(ProjSpeed), Some(2))),
|
||||
Skill((Bow(ProjSpeed), 2)),
|
||||
|
||||
// Charged
|
||||
Skill((Bow(CDamage), Some(3))),
|
||||
Skill((Bow(CKnockback), Some(2))),
|
||||
Skill((Bow(CSpeed), Some(2))),
|
||||
Skill((Bow(CRegen), Some(2))),
|
||||
Skill((Bow(CMove), Some(2))),
|
||||
Skill((Bow(CDamage), 3)),
|
||||
Skill((Bow(CKnockback), 2)),
|
||||
Skill((Bow(CSpeed), 2)),
|
||||
Skill((Bow(CRegen), 2)),
|
||||
Skill((Bow(CMove), 2)),
|
||||
|
||||
// Repeater
|
||||
Skill((Bow(RDamage), Some(3))),
|
||||
Skill((Bow(RCost), Some(2))),
|
||||
Skill((Bow(RSpeed), Some(2))),
|
||||
Skill((Bow(RDamage), 3)),
|
||||
Skill((Bow(RCost), 2)),
|
||||
Skill((Bow(RSpeed), 2)),
|
||||
|
||||
// Shotgun
|
||||
Skill((Bow(UnlockShotgun), None)),
|
||||
Skill((Bow(SDamage), Some(2))),
|
||||
Skill((Bow(SCost), Some(2))),
|
||||
Skill((Bow(SArrows), Some(2))),
|
||||
Skill((Bow(SSpread), Some(2))),
|
||||
Skill((Bow(UnlockShotgun), 1)),
|
||||
Skill((Bow(SDamage), 2)),
|
||||
Skill((Bow(SCost), 2)),
|
||||
Skill((Bow(SArrows), 2)),
|
||||
Skill((Bow(SSpread), 2)),
|
||||
])
|
||||
|
@ -1,4 +1,4 @@
|
||||
([
|
||||
Skill((General(HealthIncrease), Some(10))),
|
||||
Skill((General(EnergyIncrease), Some(5))),
|
||||
Skill((General(HealthIncrease), 10)),
|
||||
Skill((General(EnergyIncrease), 5)),
|
||||
])
|
||||
|
@ -2,22 +2,22 @@
|
||||
Group(Weapon(Hammer)),
|
||||
|
||||
// Single Strike, as single as you are
|
||||
Skill((Hammer(SsKnockback), Some(2))),
|
||||
Skill((Hammer(SsDamage), Some(3))),
|
||||
Skill((Hammer(SsRegen), Some(2))),
|
||||
Skill((Hammer(SsSpeed), Some(3))),
|
||||
Skill((Hammer(SsKnockback), 2)),
|
||||
Skill((Hammer(SsDamage), 3)),
|
||||
Skill((Hammer(SsRegen), 2)),
|
||||
Skill((Hammer(SsSpeed), 3)),
|
||||
|
||||
// Charged
|
||||
Skill((Hammer(CDamage), Some(3))),
|
||||
Skill((Hammer(CKnockback), Some(3))),
|
||||
Skill((Hammer(CDrain), Some(2))),
|
||||
Skill((Hammer(CSpeed), Some(2))),
|
||||
Skill((Hammer(CDamage), 3)),
|
||||
Skill((Hammer(CKnockback), 3)),
|
||||
Skill((Hammer(CDrain), 2)),
|
||||
Skill((Hammer(CSpeed), 2)),
|
||||
|
||||
// Leap
|
||||
Skill((Hammer(UnlockLeap), None)),
|
||||
Skill((Hammer(LDamage), Some(2))),
|
||||
Skill((Hammer(LCost), Some(2))),
|
||||
Skill((Hammer(LDistance), Some(2))),
|
||||
Skill((Hammer(LKnockback), Some(2))),
|
||||
Skill((Hammer(LRange), Some(2))),
|
||||
Skill((Hammer(UnlockLeap), 1)),
|
||||
Skill((Hammer(LDamage), 2)),
|
||||
Skill((Hammer(LCost), 2)),
|
||||
Skill((Hammer(LDistance), 2)),
|
||||
Skill((Hammer(LKnockback), 2)),
|
||||
Skill((Hammer(LRange), 2)),
|
||||
])
|
||||
|
@ -2,20 +2,20 @@
|
||||
Group(Weapon(Sceptre)),
|
||||
|
||||
// Beam
|
||||
Skill((Sceptre(LDamage), Some(3))),
|
||||
Skill((Sceptre(LRange), Some(2))),
|
||||
Skill((Sceptre(LLifesteal), Some(3))),
|
||||
Skill((Sceptre(LRegen), Some(2))),
|
||||
Skill((Sceptre(LDamage), 3)),
|
||||
Skill((Sceptre(LRange), 2)),
|
||||
Skill((Sceptre(LLifesteal), 3)),
|
||||
Skill((Sceptre(LRegen), 2)),
|
||||
|
||||
// Heal
|
||||
Skill((Sceptre(HHeal), Some(3))),
|
||||
Skill((Sceptre(HDuration), Some(2))),
|
||||
Skill((Sceptre(HRange), Some(2))),
|
||||
Skill((Sceptre(HCost), Some(2))),
|
||||
Skill((Sceptre(HHeal), 3)),
|
||||
Skill((Sceptre(HDuration), 2)),
|
||||
Skill((Sceptre(HRange), 2)),
|
||||
Skill((Sceptre(HCost), 2)),
|
||||
// Ward
|
||||
Skill((Sceptre(UnlockAura), None)),
|
||||
Skill((Sceptre(AStrength), Some(2))),
|
||||
Skill((Sceptre(ADuration), Some(2))),
|
||||
Skill((Sceptre(ARange), Some(2))),
|
||||
Skill((Sceptre(ACost), Some(2))),
|
||||
Skill((Sceptre(UnlockAura), 1)),
|
||||
Skill((Sceptre(AStrength), 2)),
|
||||
Skill((Sceptre(ADuration), 2)),
|
||||
Skill((Sceptre(ARange), 2)),
|
||||
Skill((Sceptre(ACost), 2)),
|
||||
])
|
||||
|
@ -2,20 +2,20 @@
|
||||
Group(Weapon(Staff)),
|
||||
|
||||
// Fireball
|
||||
Skill((Staff(BDamage), Some(3))),
|
||||
Skill((Staff(BRegen), Some(2))),
|
||||
Skill((Staff(BRadius), Some(3))),
|
||||
Skill((Staff(BDamage), 3)),
|
||||
Skill((Staff(BRegen), 2)),
|
||||
Skill((Staff(BRadius), 3)),
|
||||
|
||||
// Flamethrower
|
||||
Skill((Staff(FRange), Some(2))),
|
||||
Skill((Staff(FDamage), Some(3))),
|
||||
Skill((Staff(FDrain), Some(2))),
|
||||
Skill((Staff(FVelocity), Some(2))),
|
||||
Skill((Staff(FRange), 2)),
|
||||
Skill((Staff(FDamage), 3)),
|
||||
Skill((Staff(FDrain), 2)),
|
||||
Skill((Staff(FVelocity), 2)),
|
||||
|
||||
// Shockwave
|
||||
Skill((Staff(UnlockShockwave), None)),
|
||||
Skill((Staff(SDamage), Some(2))),
|
||||
Skill((Staff(SKnockback), Some(2))),
|
||||
Skill((Staff(SRange), Some(2))),
|
||||
Skill((Staff(SCost), Some(2))),
|
||||
Skill((Staff(UnlockShockwave), 1)),
|
||||
Skill((Staff(SDamage), 2)),
|
||||
Skill((Staff(SKnockback), 2)),
|
||||
Skill((Staff(SRange), 2)),
|
||||
Skill((Staff(SCost), 2)),
|
||||
])
|
||||
|
@ -1,26 +1,26 @@
|
||||
([
|
||||
Group(Weapon(Sword)),
|
||||
|
||||
Skill((Sword(InterruptingAttacks), None)),
|
||||
Skill((Sword(InterruptingAttacks), 1)),
|
||||
|
||||
// TripleStrike
|
||||
Skill((Sword(TsCombo), None)),
|
||||
Skill((Sword(TsDamage), Some(3))),
|
||||
Skill((Sword(TsRegen), Some(2))),
|
||||
Skill((Sword(TsSpeed), Some(3))),
|
||||
Skill((Sword(TsCombo), 1)),
|
||||
Skill((Sword(TsDamage), 3)),
|
||||
Skill((Sword(TsRegen), 2)),
|
||||
Skill((Sword(TsSpeed), 3)),
|
||||
|
||||
// Dash
|
||||
Skill((Sword(DCost), Some(2))),
|
||||
Skill((Sword(DDrain), Some(2))),
|
||||
Skill((Sword(DDamage), Some(2))),
|
||||
Skill((Sword(DScaling), Some(3))),
|
||||
Skill((Sword(DSpeed), None)),
|
||||
Skill((Sword(DInfinite), None)),
|
||||
Skill((Sword(DCost), 2)),
|
||||
Skill((Sword(DDrain), 2)),
|
||||
Skill((Sword(DDamage), 2)),
|
||||
Skill((Sword(DScaling), 3)),
|
||||
Skill((Sword(DSpeed), 1)),
|
||||
Skill((Sword(DChargeThrough), 1)),
|
||||
|
||||
// Spin of death
|
||||
Skill((Sword(UnlockSpin), None)),
|
||||
Skill((Sword(SDamage), Some(2))),
|
||||
Skill((Sword(SSpeed), Some(2))),
|
||||
Skill((Sword(SSpins), Some(2))),
|
||||
Skill((Sword(SCost), Some(2))),
|
||||
Skill((Sword(UnlockSpin), 1)),
|
||||
Skill((Sword(SDamage), 2)),
|
||||
Skill((Sword(SSpeed), 2)),
|
||||
Skill((Sword(SSpins), 2)),
|
||||
Skill((Sword(SCost), 2)),
|
||||
])
|
||||
|
@ -27,7 +27,7 @@
|
||||
(Sword(DDamage), 2),
|
||||
(Sword(DScaling), 3),
|
||||
(Sword(DSpeed), 1),
|
||||
(Sword(DInfinite), 1),
|
||||
(Sword(DChargeThrough), 1),
|
||||
|
||||
(Sword(UnlockSpin), 1),
|
||||
(Sword(SDamage), 2),
|
||||
@ -157,7 +157,7 @@
|
||||
(Sword(DDamage), 2),
|
||||
(Sword(DScaling), 2),
|
||||
(Sword(DSpeed), 1),
|
||||
(Sword(DInfinite), 1),
|
||||
(Sword(DChargeThrough), 1),
|
||||
|
||||
(Sword(UnlockSpin), 1),
|
||||
(Sword(SDamage), 1),
|
||||
|
@ -30,7 +30,7 @@ vek = { version = "=0.14.1", features = ["serde"] }
|
||||
chrono = "0.4"
|
||||
chrono-tz = "0.6"
|
||||
sha2 = "0.9.8"
|
||||
bincode = "1.3.1"
|
||||
serde_json = "1.0.50"
|
||||
|
||||
# Strum
|
||||
strum = { version = "0.23", features = ["derive"] }
|
||||
|
@ -1187,7 +1187,7 @@ impl CharacterAbility {
|
||||
..
|
||||
} = self
|
||||
{
|
||||
if let Ok(Some(level)) = skillset.skill_level(Skill::Pick(Speed)) {
|
||||
if let Ok(level) = skillset.skill_level(Skill::Pick(Speed)) {
|
||||
let modifiers = SKILL_MODIFIERS.mining_tree;
|
||||
|
||||
let speed = modifiers.speed.powi(level.into());
|
||||
@ -1211,13 +1211,13 @@ impl CharacterAbility {
|
||||
|
||||
let modifiers = SKILL_MODIFIERS.general_tree.roll;
|
||||
|
||||
if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Cost)) {
|
||||
if let Ok(level) = skillset.skill_level(Skill::Roll(Cost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Strength)) {
|
||||
if let Ok(level) = skillset.skill_level(Skill::Roll(Strength)) {
|
||||
*roll_strength *= modifiers.strength.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Duration)) {
|
||||
if let Ok(level) = skillset.skill_level(Skill::Roll(Duration)) {
|
||||
*movement_duration *= modifiers.duration.powi(level.into());
|
||||
}
|
||||
}
|
||||
@ -1241,9 +1241,7 @@ impl CharacterAbility {
|
||||
*is_interruptible = skillset.has_skill(Sword(InterruptingAttacks));
|
||||
|
||||
if skillset.has_skill(Sword(TsCombo)) {
|
||||
let speed_segments = Sword(TsSpeed)
|
||||
.max_level()
|
||||
.map_or(1.0, |l| f32::from(l) + 1.0);
|
||||
let speed_segments = f32::from(Sword(TsSpeed).max_level()) + 1.0;
|
||||
let speed_level = f32::from(skillset.skill_level_or(Sword(TsSpeed), 0));
|
||||
*speed_increase = (speed_level + 1.0) / speed_segments;
|
||||
*max_speed_increase = (speed_level + 1.0) / speed_segments;
|
||||
@ -1259,7 +1257,7 @@ impl CharacterAbility {
|
||||
|
||||
*max_energy_gain *= f32::from((energy_level + 1) * stages - 1)
|
||||
* f32::from(stages - 1)
|
||||
/ f32::from(Sword(TsRegen).max_level().unwrap() + 1);
|
||||
/ f32::from(Sword(TsRegen).max_level() + 1);
|
||||
*scales_from_combo = skillset.skill_level_or(Sword(TsDamage), 0).into();
|
||||
},
|
||||
CharacterAbility::DashMelee {
|
||||
@ -1274,22 +1272,22 @@ impl CharacterAbility {
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.sword_tree.dash;
|
||||
*is_interruptible = skillset.has_skill(Sword(InterruptingAttacks));
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sword(DCost)) {
|
||||
if let Ok(level) = skillset.skill_level(Sword(DCost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sword(DDrain)) {
|
||||
if let Ok(level) = skillset.skill_level(Sword(DDrain)) {
|
||||
*energy_drain *= modifiers.energy_drain.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sword(DDamage)) {
|
||||
if let Ok(level) = skillset.skill_level(Sword(DDamage)) {
|
||||
*base_damage *= modifiers.base_damage.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sword(DScaling)) {
|
||||
if let Ok(level) = skillset.skill_level(Sword(DScaling)) {
|
||||
*scaled_damage *= modifiers.scaled_damage.powi(level.into());
|
||||
}
|
||||
if skillset.has_skill(Sword(DSpeed)) {
|
||||
*forward_speed *= modifiers.forward_speed;
|
||||
}
|
||||
*charge_through = skillset.has_skill(Sword(DInfinite));
|
||||
*charge_through = skillset.has_skill(Sword(DChargeThrough));
|
||||
},
|
||||
CharacterAbility::SpinMelee {
|
||||
ref mut is_interruptible,
|
||||
@ -1301,13 +1299,13 @@ impl CharacterAbility {
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.sword_tree.spin;
|
||||
*is_interruptible = skillset.has_skill(Sword(InterruptingAttacks));
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sword(SDamage)) {
|
||||
if let Ok(level) = skillset.skill_level(Sword(SDamage)) {
|
||||
*base_damage *= modifiers.base_damage.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sword(SSpeed)) {
|
||||
if let Ok(level) = skillset.skill_level(Sword(SSpeed)) {
|
||||
*swing_duration *= modifiers.swing_duration.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sword(SCost)) {
|
||||
if let Ok(level) = skillset.skill_level(Sword(SCost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
let spin_level = skillset.skill_level_or(Sword(SSpins), 0);
|
||||
@ -1334,7 +1332,7 @@ impl CharacterAbility {
|
||||
if !skillset.has_skill(Axe(DsCombo)) {
|
||||
stage_data.pop();
|
||||
}
|
||||
let speed_segments = f32::from(Axe(DsSpeed).max_level().unwrap_or(1));
|
||||
let speed_segments = f32::from(Axe(DsSpeed).max_level());
|
||||
let speed_level = f32::from(skillset.skill_level_or(Axe(DsSpeed), 0));
|
||||
*speed_increase *= speed_level / speed_segments;
|
||||
*max_speed_increase *= speed_level / speed_segments;
|
||||
@ -1346,7 +1344,7 @@ impl CharacterAbility {
|
||||
|
||||
*max_energy_gain *= f32::from((energy_level + 1) * stages - 1).max(1.0)
|
||||
* f32::from(stages - 1).max(1.0)
|
||||
/ f32::from(Axe(DsRegen).max_level().unwrap() + 1);
|
||||
/ f32::from(Axe(DsRegen).max_level() + 1);
|
||||
*scales_from_combo = skillset.skill_level_or(Axe(DsDamage), 0).into();
|
||||
},
|
||||
CharacterAbility::SpinMelee {
|
||||
@ -1365,13 +1363,13 @@ impl CharacterAbility {
|
||||
} else {
|
||||
spin_melee::MovementBehavior::ForwardGround
|
||||
};
|
||||
if let Ok(Some(level)) = skillset.skill_level(Axe(SDamage)) {
|
||||
if let Ok(level) = skillset.skill_level(Axe(SDamage)) {
|
||||
*base_damage *= modifiers.base_damage.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Axe(SSpeed)) {
|
||||
if let Ok(level) = skillset.skill_level(Axe(SSpeed)) {
|
||||
*swing_duration *= modifiers.swing_duration.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Axe(SCost)) {
|
||||
if let Ok(level) = skillset.skill_level(Axe(SCost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
},
|
||||
@ -1384,16 +1382,16 @@ impl CharacterAbility {
|
||||
..
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.axe_tree.leap;
|
||||
if let Ok(Some(level)) = skillset.skill_level(Axe(LDamage)) {
|
||||
if let Ok(level) = skillset.skill_level(Axe(LDamage)) {
|
||||
*base_damage *= modifiers.base_damage.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Axe(LKnockback)) {
|
||||
if let Ok(level) = skillset.skill_level(Axe(LKnockback)) {
|
||||
*knockback *= modifiers.knockback.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Axe(LCost)) {
|
||||
if let Ok(level) = skillset.skill_level(Axe(LCost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Axe(LDistance)) {
|
||||
if let Ok(level) = skillset.skill_level(Axe(LDistance)) {
|
||||
let strength = modifiers.leap_strength;
|
||||
*forward_leap_strength *= strength.powi(level.into());
|
||||
*vertical_leap_strength *= strength.powi(level.into());
|
||||
@ -1419,13 +1417,13 @@ impl CharacterAbility {
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.hammer_tree.single_strike;
|
||||
|
||||
if let Ok(Some(level)) = skillset.skill_level(Hammer(SsKnockback)) {
|
||||
if let Ok(level) = skillset.skill_level(Hammer(SsKnockback)) {
|
||||
*stage_data = (*stage_data)
|
||||
.iter()
|
||||
.map(|s| s.modify_strike(modifiers.knockback.powi(level.into())))
|
||||
.collect::<Vec<_>>();
|
||||
}
|
||||
let speed_segments = f32::from(Hammer(SsSpeed).max_level().unwrap_or(1));
|
||||
let speed_segments = f32::from(Hammer(SsSpeed).max_level());
|
||||
let speed_level = f32::from(skillset.skill_level_or(Hammer(SsSpeed), 0));
|
||||
*speed_increase *= speed_level / speed_segments;
|
||||
*max_speed_increase *= speed_level / speed_segments;
|
||||
@ -1436,7 +1434,7 @@ impl CharacterAbility {
|
||||
.expect("number of stages can't be more than u16");
|
||||
|
||||
*max_energy_gain *= f32::from((energy_level + 1) * stages)
|
||||
/ f32::from((Hammer(SsRegen).max_level().unwrap() + 1) * stages);
|
||||
/ f32::from((Hammer(SsRegen).max_level() + 1) * stages);
|
||||
|
||||
*scales_from_combo = skillset.skill_level_or(Hammer(SsDamage), 0).into();
|
||||
},
|
||||
@ -1449,16 +1447,16 @@ impl CharacterAbility {
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.hammer_tree.charged;
|
||||
|
||||
if let Ok(Some(level)) = skillset.skill_level(Hammer(CDamage)) {
|
||||
if let Ok(level) = skillset.skill_level(Hammer(CDamage)) {
|
||||
*scaled_damage *= modifiers.scaled_damage.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Hammer(CKnockback)) {
|
||||
if let Ok(level) = skillset.skill_level(Hammer(CKnockback)) {
|
||||
*scaled_knockback *= modifiers.scaled_knockback.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Hammer(CDrain)) {
|
||||
if let Ok(level) = skillset.skill_level(Hammer(CDrain)) {
|
||||
*energy_drain *= modifiers.energy_drain.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Hammer(CSpeed)) {
|
||||
if let Ok(level) = skillset.skill_level(Hammer(CSpeed)) {
|
||||
let charge_time = 1.0 / modifiers.charge_rate;
|
||||
*charge_duration *= charge_time.powi(level.into());
|
||||
}
|
||||
@ -1473,21 +1471,21 @@ impl CharacterAbility {
|
||||
..
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.hammer_tree.leap;
|
||||
if let Ok(Some(level)) = skillset.skill_level(Hammer(LDamage)) {
|
||||
if let Ok(level) = skillset.skill_level(Hammer(LDamage)) {
|
||||
*base_damage *= modifiers.base_damage.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Hammer(LKnockback)) {
|
||||
if let Ok(level) = skillset.skill_level(Hammer(LKnockback)) {
|
||||
*knockback *= modifiers.knockback.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Hammer(LCost)) {
|
||||
if let Ok(level) = skillset.skill_level(Hammer(LCost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Hammer(LDistance)) {
|
||||
if let Ok(level) = skillset.skill_level(Hammer(LDistance)) {
|
||||
let strength = modifiers.leap_strength;
|
||||
*forward_leap_strength *= strength.powi(level.into());
|
||||
*vertical_leap_strength *= strength.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Hammer(LRange)) {
|
||||
if let Ok(level) = skillset.skill_level(Hammer(LRange)) {
|
||||
*range += modifiers.range * f32::from(level);
|
||||
}
|
||||
},
|
||||
@ -1516,31 +1514,31 @@ impl CharacterAbility {
|
||||
..
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.bow_tree.charged;
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(ProjSpeed)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(ProjSpeed)) {
|
||||
let projectile_speed_scaling = projectile_speed_modifier.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(level) = skillset.skill_level(Bow(CDamage)) {
|
||||
let damage_scaling = modifiers.damage_scaling.powi(level.into());
|
||||
*initial_damage *= damage_scaling;
|
||||
*scaled_damage *= damage_scaling;
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(CRegen)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(CRegen)) {
|
||||
let regen_scaling = modifiers.regen_scaling.powi(level.into());
|
||||
*initial_regen *= regen_scaling;
|
||||
*scaled_regen *= regen_scaling;
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(CKnockback)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(CKnockback)) {
|
||||
let knockback_scaling = modifiers.knockback_scaling.powi(level.into());
|
||||
*initial_knockback *= knockback_scaling;
|
||||
*scaled_knockback *= knockback_scaling;
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(CSpeed)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(CSpeed)) {
|
||||
let charge_time = 1.0 / modifiers.charge_rate;
|
||||
*charge_duration *= charge_time.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(CMove)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(CMove)) {
|
||||
*move_speed *= modifiers.move_speed.powi(level.into());
|
||||
}
|
||||
},
|
||||
@ -1552,17 +1550,17 @@ impl CharacterAbility {
|
||||
..
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.bow_tree.repeater;
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(ProjSpeed)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(ProjSpeed)) {
|
||||
*projectile_speed *= projectile_speed_modifier.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(RDamage)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(RDamage)) {
|
||||
let power = modifiers.power.powi(level.into());
|
||||
*projectile = projectile.modified_projectile(power, 1_f32, 1_f32);
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(RCost)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(RCost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(RSpeed)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(RSpeed)) {
|
||||
*max_speed *= modifiers.max_speed.powi(level.into());
|
||||
}
|
||||
},
|
||||
@ -1575,20 +1573,20 @@ impl CharacterAbility {
|
||||
..
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.bow_tree.shotgun;
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(ProjSpeed)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(ProjSpeed)) {
|
||||
*projectile_speed *= projectile_speed_modifier.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(SDamage)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(SDamage)) {
|
||||
let power = modifiers.power.powi(level.into());
|
||||
*projectile = projectile.modified_projectile(power, 1_f32, 1_f32);
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(SCost)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(SCost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(SArrows)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(SArrows)) {
|
||||
*num_projectiles += u32::from(level) * modifiers.num_projectiles;
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(SSpread)) {
|
||||
if let Ok(level) = skillset.skill_level(Bow(SSpread)) {
|
||||
*projectile_spread *= modifiers.spread.powi(level.into());
|
||||
}
|
||||
},
|
||||
@ -1622,19 +1620,19 @@ impl CharacterAbility {
|
||||
..
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.staff_tree.flamethrower;
|
||||
if let Ok(Some(level)) = skillset.skill_level(Staff(FDamage)) {
|
||||
if let Ok(level) = skillset.skill_level(Staff(FDamage)) {
|
||||
*damage *= modifiers.damage.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Staff(FRange)) {
|
||||
if let Ok(level) = skillset.skill_level(Staff(FRange)) {
|
||||
let range_mod = modifiers.range.powi(level.into());
|
||||
*range *= range_mod;
|
||||
// Duration modified to keep velocity constant
|
||||
*beam_duration *= range_mod;
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Staff(FDrain)) {
|
||||
if let Ok(level) = skillset.skill_level(Staff(FDrain)) {
|
||||
*energy_drain *= modifiers.energy_drain.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Staff(FVelocity)) {
|
||||
if let Ok(level) = skillset.skill_level(Staff(FVelocity)) {
|
||||
let velocity_increase = modifiers.velocity.powi(level.into());
|
||||
let duration_mod = 1.0 / (1.0 + velocity_increase);
|
||||
*beam_duration *= duration_mod;
|
||||
@ -1648,17 +1646,17 @@ impl CharacterAbility {
|
||||
..
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.staff_tree.shockwave;
|
||||
if let Ok(Some(level)) = skillset.skill_level(Staff(SDamage)) {
|
||||
if let Ok(level) = skillset.skill_level(Staff(SDamage)) {
|
||||
*damage *= modifiers.damage.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Staff(SKnockback)) {
|
||||
if let Ok(level) = skillset.skill_level(Staff(SKnockback)) {
|
||||
let knockback_mod = modifiers.knockback.powi(level.into());
|
||||
*knockback = knockback.modify_strength(knockback_mod);
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Staff(SRange)) {
|
||||
if let Ok(level) = skillset.skill_level(Staff(SRange)) {
|
||||
*shockwave_duration *= modifiers.duration.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Staff(SCost)) {
|
||||
if let Ok(level) = skillset.skill_level(Staff(SCost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
},
|
||||
@ -1681,19 +1679,19 @@ impl CharacterAbility {
|
||||
..
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.sceptre_tree.beam;
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(LDamage)) {
|
||||
if let Ok(level) = skillset.skill_level(Sceptre(LDamage)) {
|
||||
*damage *= modifiers.damage.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(LRange)) {
|
||||
if let Ok(level) = skillset.skill_level(Sceptre(LRange)) {
|
||||
let range_mod = modifiers.range.powi(level.into());
|
||||
*range *= range_mod;
|
||||
// Duration modified to keep velocity constant
|
||||
*beam_duration *= range_mod;
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(LRegen)) {
|
||||
if let Ok(level) = skillset.skill_level(Sceptre(LRegen)) {
|
||||
*energy_regen *= modifiers.energy_regen.powi(level.into());
|
||||
}
|
||||
if let (Ok(Some(level)), Some(CombatEffect::Lifesteal(ref mut lifesteal))) =
|
||||
if let (Ok(level), Some(CombatEffect::Lifesteal(ref mut lifesteal))) =
|
||||
(skillset.skill_level(Sceptre(LLifesteal)), damage_effect)
|
||||
{
|
||||
*lifesteal *= modifiers.lifesteal.powi(level.into());
|
||||
@ -1707,18 +1705,18 @@ impl CharacterAbility {
|
||||
..
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.sceptre_tree.healing_aura;
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(HHeal)) {
|
||||
if let Ok(level) = skillset.skill_level(Sceptre(HHeal)) {
|
||||
aura.strength *= modifiers.strength.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(HDuration)) {
|
||||
if let Ok(level) = skillset.skill_level(Sceptre(HDuration)) {
|
||||
if let Some(ref mut duration) = aura.duration {
|
||||
*duration *= modifiers.duration.powi(level.into());
|
||||
}
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(HRange)) {
|
||||
if let Ok(level) = skillset.skill_level(Sceptre(HRange)) {
|
||||
*range *= modifiers.range.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(HCost)) {
|
||||
if let Ok(level) = skillset.skill_level(Sceptre(HCost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
},
|
||||
@ -1730,18 +1728,18 @@ impl CharacterAbility {
|
||||
..
|
||||
} => {
|
||||
let modifiers = SKILL_MODIFIERS.sceptre_tree.warding_aura;
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(AStrength)) {
|
||||
if let Ok(level) = skillset.skill_level(Sceptre(AStrength)) {
|
||||
aura.strength *= modifiers.strength.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(ADuration)) {
|
||||
if let Ok(level) = skillset.skill_level(Sceptre(ADuration)) {
|
||||
if let Some(ref mut duration) = aura.duration {
|
||||
*duration *= modifiers.duration.powi(level.into());
|
||||
}
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(ARange)) {
|
||||
if let Ok(level) = skillset.skill_level(Sceptre(ARange)) {
|
||||
*range *= modifiers.range.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(ACost)) {
|
||||
if let Ok(level) = skillset.skill_level(Sceptre(ACost)) {
|
||||
*energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
},
|
||||
|
@ -5,7 +5,6 @@ use crate::{
|
||||
skills::{GeneralSkill, Skill},
|
||||
},
|
||||
};
|
||||
use bincode;
|
||||
use hashbrown::HashMap;
|
||||
use lazy_static::lazy_static;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -17,6 +16,9 @@ use tracing::{trace, warn};
|
||||
|
||||
pub mod skills;
|
||||
|
||||
/// BTreeSet is used here to ensure that skills are ordered. This is important
|
||||
/// to ensure that the hash created from it is consistent so that we don't
|
||||
/// needlessly force a respec when loading skills from persistence.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SkillTreeMap(HashMap<SkillGroupKind, BTreeSet<Skill>>);
|
||||
|
||||
@ -32,7 +34,7 @@ pub struct SkillGroupDef {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SkillLevelMap(HashMap<Skill, Option<u16>>);
|
||||
pub struct SkillLevelMap(HashMap<Skill, u16>);
|
||||
|
||||
impl Asset for SkillLevelMap {
|
||||
type Loader = assets::RonLoader;
|
||||
@ -41,7 +43,7 @@ impl Asset for SkillLevelMap {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SkillPrerequisitesMap(HashMap<Skill, HashMap<Skill, Option<u16>>>);
|
||||
pub struct SkillPrerequisitesMap(HashMap<Skill, HashMap<Skill, u16>>);
|
||||
|
||||
impl Asset for SkillPrerequisitesMap {
|
||||
type Loader = assets::RonLoader;
|
||||
@ -63,14 +65,11 @@ lazy_static! {
|
||||
total_skill_point_cost: skills
|
||||
.iter()
|
||||
.map(|skill| {
|
||||
if let Some(max_level) = skill.max_level() {
|
||||
let max_level = skill.max_level();
|
||||
(1..=max_level)
|
||||
.into_iter()
|
||||
.map(|level| skill.skill_cost(Some(level)))
|
||||
.sum()
|
||||
} else {
|
||||
skill.skill_cost(None)
|
||||
}
|
||||
.map(|level| skill.skill_cost(level))
|
||||
.sum::<u16>()
|
||||
})
|
||||
.sum()
|
||||
})
|
||||
@ -85,13 +84,13 @@ lazy_static! {
|
||||
map.iter().flat_map(|(sgk, skills)| skills.into_iter().map(move |s| (*s, *sgk))).collect()
|
||||
};
|
||||
// Loads the maximum level that a skill can obtain
|
||||
pub static ref SKILL_MAX_LEVEL: HashMap<Skill, Option<u16>> = {
|
||||
pub static ref SKILL_MAX_LEVEL: HashMap<Skill, u16> = {
|
||||
SkillLevelMap::load_expect_cloned(
|
||||
"common.skill_trees.skill_max_levels",
|
||||
).0
|
||||
};
|
||||
// Loads the prerequisite skills for a particular skill
|
||||
pub static ref SKILL_PREREQUISITES: HashMap<Skill, HashMap<Skill, Option<u16>>> = {
|
||||
pub static ref SKILL_PREREQUISITES: HashMap<Skill, HashMap<Skill, u16>> = {
|
||||
SkillPrerequisitesMap::load_expect_cloned(
|
||||
"common.skill_trees.skill_prerequisites",
|
||||
).0
|
||||
@ -103,9 +102,9 @@ lazy_static! {
|
||||
let mut hashes = HashMap::new();
|
||||
for (skill_group_kind, skills) in map.iter() {
|
||||
let mut hasher = Sha256::new();
|
||||
let bincode_input: Vec<_> = skills.iter().map(|skill| (*skill, skill.max_level())).collect();
|
||||
let hash_input = bincode::serialize(&bincode_input).unwrap_or_default();
|
||||
hasher.update(hash_input);
|
||||
let json_input: Vec<_> = skills.iter().map(|skill| (*skill, skill.max_level())).collect();
|
||||
let hash_input = serde_json::to_string(&json_input).unwrap_or_default();
|
||||
hasher.update(hash_input.as_bytes());
|
||||
let hash_result = hasher.finalize();
|
||||
hashes.insert(*skill_group_kind, hash_result.iter().copied().collect());
|
||||
}
|
||||
@ -121,6 +120,8 @@ pub enum SkillGroupKind {
|
||||
|
||||
impl SkillGroupKind {
|
||||
/// Gets the cost in experience of earning a skill point
|
||||
/// Changing this is forward compatible with persistence and will
|
||||
/// automatically force a respec for skill group kinds that are affected.
|
||||
pub fn skill_point_cost(self, level: u16) -> u32 {
|
||||
const EXP_INCREMENT: f32 = 10.0;
|
||||
const STARTING_EXP: f32 = 70.0;
|
||||
@ -186,9 +187,21 @@ impl SkillGroup {
|
||||
pub fn earn_skill_point(&mut self) -> Result<(), SpRewardError> {
|
||||
let sp_cost = self.skill_group_kind.skill_point_cost(self.earned_sp);
|
||||
if self.available_experience() >= sp_cost {
|
||||
self.spent_exp = self.spent_exp.saturating_add(sp_cost);
|
||||
self.available_sp = self.available_sp.saturating_add(1);
|
||||
self.earned_sp = self.earned_sp.saturating_add(1);
|
||||
let new_spent_exp = self
|
||||
.spent_exp
|
||||
.checked_add(sp_cost)
|
||||
.ok_or(SpRewardError::Overflow)?;
|
||||
let new_earned_sp = self
|
||||
.earned_sp
|
||||
.checked_add(1)
|
||||
.ok_or(SpRewardError::Overflow)?;
|
||||
let new_available_sp = self
|
||||
.available_sp
|
||||
.checked_add(1)
|
||||
.ok_or(SpRewardError::Overflow)?;
|
||||
self.spent_exp = new_spent_exp;
|
||||
self.earned_sp = new_earned_sp;
|
||||
self.available_sp = new_available_sp;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SpRewardError::InsufficientExp)
|
||||
@ -202,7 +215,7 @@ impl SkillGroup {
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct SkillSet {
|
||||
skill_groups: Vec<SkillGroup>,
|
||||
skills: HashMap<Skill, Option<u16>>,
|
||||
skills: HashMap<Skill, u16>,
|
||||
pub modify_health: bool,
|
||||
pub modify_energy: bool,
|
||||
}
|
||||
@ -229,12 +242,12 @@ impl Default for SkillSet {
|
||||
}
|
||||
|
||||
impl SkillSet {
|
||||
pub fn initial_skills() -> HashMap<Skill, Option<u16>> {
|
||||
pub fn initial_skills() -> HashMap<Skill, u16> {
|
||||
let mut skills = HashMap::new();
|
||||
skills.insert(Skill::UnlockGroup(SkillGroupKind::General), None);
|
||||
skills.insert(Skill::UnlockGroup(SkillGroupKind::General), 1);
|
||||
skills.insert(
|
||||
Skill::UnlockGroup(SkillGroupKind::Weapon(ToolKind::Pick)),
|
||||
None,
|
||||
1,
|
||||
);
|
||||
skills
|
||||
}
|
||||
@ -310,10 +323,15 @@ impl SkillSet {
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to a particular skill group in a skillset
|
||||
/// Requires that skillset contains skill that unlocks the skill group
|
||||
fn skill_group_mut(&mut self, skill_group: SkillGroupKind) -> Option<&mut SkillGroup> {
|
||||
// In order to mutate skill group, we check that the prerequisite skill has been
|
||||
// acquired, as this is one of the requirements for us to consider the skill
|
||||
// group accessible.
|
||||
let skill_group_accessible = self.skill_group_accessible(skill_group);
|
||||
self.skill_groups
|
||||
.iter_mut()
|
||||
.find(|s_g| s_g.skill_group_kind == skill_group)
|
||||
.find(|s_g| s_g.skill_group_kind == skill_group && skill_group_accessible)
|
||||
}
|
||||
|
||||
/// Adds experience to the skill group within an entity's skill set
|
||||
@ -347,13 +365,13 @@ impl SkillSet {
|
||||
skill_group_kind: SkillGroupKind,
|
||||
number_of_skill_points: u16,
|
||||
) {
|
||||
if let Some(mut skill_group) = self.skill_group_mut(skill_group_kind) {
|
||||
skill_group.available_sp = skill_group
|
||||
.available_sp
|
||||
.saturating_add(number_of_skill_points);
|
||||
skill_group.earned_sp = skill_group.earned_sp.saturating_add(number_of_skill_points);
|
||||
} else {
|
||||
warn!("Tried to add skill points to a skill group that player does not have");
|
||||
for _ in 0..number_of_skill_points {
|
||||
let exp_needed = self.skill_point_cost(skill_group_kind);
|
||||
self.add_experience(skill_group_kind, exp_needed);
|
||||
if self.earn_skill_point(skill_group_kind).is_err() {
|
||||
warn!("Failed to add skill point");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -397,11 +415,7 @@ impl SkillSet {
|
||||
/// Checks if player has sufficient skill points to purchase a skill
|
||||
pub fn sufficient_skill_points(&self, skill: Skill) -> bool {
|
||||
if let Some(skill_group_kind) = skill.skill_group_kind() {
|
||||
if let Some(skill_group) = self
|
||||
.skill_groups
|
||||
.iter()
|
||||
.find(|x| x.skill_group_kind == skill_group_kind)
|
||||
{
|
||||
if let Some(skill_group) = self.skill_group(skill_group_kind) {
|
||||
let needed_sp = self.skill_cost(skill);
|
||||
skill_group.available_sp >= needed_sp
|
||||
} else {
|
||||
@ -413,13 +427,13 @@ impl SkillSet {
|
||||
}
|
||||
|
||||
/// Checks the next level of a skill
|
||||
fn next_skill_level(&self, skill: Skill) -> Option<u16> {
|
||||
fn next_skill_level(&self, skill: Skill) -> u16 {
|
||||
if let Ok(level) = self.skill_level(skill) {
|
||||
// If already has skill, and that skill has levels, level + 1
|
||||
level.map(|l| l + 1)
|
||||
// If already has skill, then level + 1
|
||||
level + 1
|
||||
} else {
|
||||
// Else if the skill has levels, 1
|
||||
skill.max_level().map(|_| 1)
|
||||
// Otherwise the next level is the first level
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
@ -431,11 +445,13 @@ impl SkillSet {
|
||||
let prerequisites_met = self.prerequisites_met(skill);
|
||||
// Check that skill is not yet at max level
|
||||
if !matches!(self.skills.get(&skill), Some(level) if *level == skill.max_level()) {
|
||||
if self.has_skill(Skill::UnlockGroup(skill_group_kind)) {
|
||||
if let Some(mut skill_group) = self.skill_group_mut(skill_group_kind) {
|
||||
if prerequisites_met {
|
||||
if skill_group.available_sp >= skill.skill_cost(next_level) {
|
||||
skill_group.available_sp -= skill.skill_cost(next_level);
|
||||
if let Some(new_available_sp) = skill_group
|
||||
.available_sp
|
||||
.checked_sub(skill.skill_cost(next_level))
|
||||
{
|
||||
skill_group.available_sp = new_available_sp;
|
||||
skill_group.ordered_skills.push(skill);
|
||||
match skill {
|
||||
Skill::UnlockGroup(group) => {
|
||||
@ -452,9 +468,7 @@ impl SkillSet {
|
||||
self.skills.insert(skill, next_level);
|
||||
Ok(())
|
||||
} else {
|
||||
trace!(
|
||||
"Tried to unlock skill for skill group with insufficient SP"
|
||||
);
|
||||
trace!("Tried to unlock skill for skill group with insufficient SP");
|
||||
Err(SkillUnlockError::InsufficientSP)
|
||||
}
|
||||
} else {
|
||||
@ -465,10 +479,6 @@ impl SkillSet {
|
||||
trace!("Tried to unlock skill for a skill group that player does not have");
|
||||
Err(SkillUnlockError::UnavailableSkillGroup)
|
||||
}
|
||||
} else {
|
||||
trace!("Tried to unlock skill for a skill group that player does not have");
|
||||
Err(SkillUnlockError::UnavailableSkillGroup)
|
||||
}
|
||||
} else {
|
||||
trace!("Tried to unlock skill the player already has");
|
||||
Err(SkillUnlockError::SkillAlreadyUnlocked)
|
||||
@ -486,6 +496,7 @@ impl SkillSet {
|
||||
pub fn has_available_sp(&self) -> bool {
|
||||
self.skill_groups.iter().any(|sg| {
|
||||
sg.available_sp > 0
|
||||
// Subtraction in bounds because of the invariant that available_sp <= earned_sp
|
||||
&& (sg.earned_sp - sg.available_sp) < sg.skill_group_kind.total_skill_point_cost()
|
||||
})
|
||||
}
|
||||
@ -503,7 +514,7 @@ impl SkillSet {
|
||||
pub fn has_skill(&self, skill: Skill) -> bool { self.skills.contains_key(&skill) }
|
||||
|
||||
/// Returns the level of the skill
|
||||
pub fn skill_level(&self, skill: Skill) -> Result<Option<u16>, SkillError> {
|
||||
pub fn skill_level(&self, skill: Skill) -> Result<u16, SkillError> {
|
||||
if let Some(level) = self.skills.get(&skill).copied() {
|
||||
Ok(level)
|
||||
} else {
|
||||
@ -513,7 +524,7 @@ impl SkillSet {
|
||||
|
||||
/// Returns the level of the skill or passed value as default
|
||||
pub fn skill_level_or(&self, skill: Skill, default: u16) -> u16 {
|
||||
if let Ok(Some(level)) = self.skill_level(skill) {
|
||||
if let Ok(level) = self.skill_level(skill) {
|
||||
level
|
||||
} else {
|
||||
default
|
||||
@ -521,6 +532,7 @@ impl SkillSet {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SkillError {
|
||||
MissingSkill,
|
||||
}
|
||||
@ -537,4 +549,5 @@ pub enum SkillUnlockError {
|
||||
pub enum SpRewardError {
|
||||
InsufficientExp,
|
||||
UnavailableSkillGroup,
|
||||
Overflow,
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ pub enum Skill {
|
||||
Climb(ClimbSkill),
|
||||
Swim(SwimSkill),
|
||||
Pick(MiningSkill),
|
||||
// TODO: Don't do this, maybe Sharp has idea?
|
||||
UnlockGroup(SkillGroupKind),
|
||||
}
|
||||
|
||||
@ -41,7 +40,7 @@ pub enum SwordSkill {
|
||||
DDamage,
|
||||
DScaling,
|
||||
DSpeed,
|
||||
DInfinite, // Represents charge through, not migrated because laziness
|
||||
DChargeThrough,
|
||||
// Spin upgrades
|
||||
UnlockSpin,
|
||||
SDamage,
|
||||
@ -187,23 +186,30 @@ pub enum MiningSkill {
|
||||
impl Skill {
|
||||
/// Returns a vec of prerequisite skills (it should only be necessary to
|
||||
/// note direct prerequisites)
|
||||
pub fn prerequisite_skills(&self) -> impl Iterator<Item = (Skill, Option<u16>)> {
|
||||
/// Automatically filters itself from the skills returned
|
||||
pub fn prerequisite_skills(&self) -> impl Iterator<Item = (Skill, u16)> + '_ {
|
||||
SKILL_PREREQUISITES
|
||||
.get(self)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(|(skill, level)| (*skill, *level))
|
||||
.filter_map(move |(skill, level)| {
|
||||
if self == skill {
|
||||
None
|
||||
} else {
|
||||
Some((*skill, *level))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the cost in skill points of unlocking a particular skill
|
||||
pub fn skill_cost(&self, level: Option<u16>) -> u16 {
|
||||
pub fn skill_cost(&self, level: u16) -> u16 {
|
||||
// TODO: Better balance the costs later
|
||||
level.unwrap_or(1)
|
||||
level
|
||||
}
|
||||
|
||||
/// Returns the maximum level a skill can reach, returns None if the skill
|
||||
/// doesn't level
|
||||
pub fn max_level(&self) -> Option<u16> { SKILL_MAX_LEVEL.get(self).copied().flatten() }
|
||||
pub fn max_level(&self) -> u16 { SKILL_MAX_LEVEL.get(self).copied().unwrap_or(1) }
|
||||
|
||||
/// Returns the skill group type for a skill from the static skill group
|
||||
/// definitions.
|
||||
|
@ -23,19 +23,19 @@ impl assets::Asset for SkillSetTree {
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
enum SkillNode {
|
||||
Tree(String),
|
||||
Skill((Skill, Option<u16>)),
|
||||
Skill((Skill, u16)),
|
||||
Group(SkillGroupKind),
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
fn skills_from_asset_expect(asset_specifier: &str) -> Vec<(Skill, Option<u16>)> {
|
||||
fn skills_from_asset_expect(asset_specifier: &str) -> Vec<(Skill, u16)> {
|
||||
let nodes = SkillSetTree::load_expect(asset_specifier).read();
|
||||
|
||||
skills_from_nodes(&nodes.0)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
fn skills_from_nodes(nodes: &[SkillNode]) -> Vec<(Skill, Option<u16>)> {
|
||||
fn skills_from_nodes(nodes: &[SkillNode]) -> Vec<(Skill, u16)> {
|
||||
let mut skills = Vec::new();
|
||||
for node in nodes {
|
||||
match node {
|
||||
@ -46,7 +46,7 @@ fn skills_from_nodes(nodes: &[SkillNode]) -> Vec<(Skill, Option<u16>)> {
|
||||
skills.push(*req);
|
||||
},
|
||||
SkillNode::Group(group) => {
|
||||
skills.push((Skill::UnlockGroup(*group), None));
|
||||
skills.push((Skill::UnlockGroup(*group), 1));
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -95,7 +95,7 @@ impl SkillSetBuilder {
|
||||
/// 1) If added skill doesn't have any group
|
||||
/// 2) If added skill already applied
|
||||
/// 3) If added skill wasn't applied at the end
|
||||
pub fn with_skill(mut self, skill: Skill, level: Option<u16>) -> Self {
|
||||
pub fn with_skill(mut self, skill: Skill, level: u16) -> Self {
|
||||
let group = if let Some(skill_group) = skill.skill_group_kind() {
|
||||
skill_group
|
||||
} else {
|
||||
@ -114,7 +114,7 @@ impl SkillSetBuilder {
|
||||
);
|
||||
common_base::dev_panic!(err, or return self);
|
||||
}
|
||||
for _ in 0..level.unwrap_or(1) {
|
||||
for _ in 0..level {
|
||||
skill_set.add_skill_points(group, skill_set.skill_cost(skill));
|
||||
if let Err(err) = skill_set.unlock_skill(skill) {
|
||||
let err_msg = format!("Failed to add skill: {:?}. Error: {:?}", skill, err);
|
||||
@ -137,7 +137,7 @@ impl SkillSetBuilder {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
fn skill_is_applied(skill_set: &SkillSet, skill: Skill, level: Option<u16>) -> bool {
|
||||
fn skill_is_applied(skill_set: &SkillSet, skill: Skill, level: u16) -> bool {
|
||||
if let Ok(applied_level) = skill_set.skill_level(skill) {
|
||||
applied_level == level
|
||||
} else {
|
||||
|
@ -34,10 +34,10 @@ impl Data {
|
||||
pub fn create_adjusted_by_skills(join_data: &JoinData) -> Self {
|
||||
let modifiers = SKILL_MODIFIERS.general_tree.climb;
|
||||
let mut data = Data::default();
|
||||
if let Ok(Some(level)) = join_data.skill_set.skill_level(Skill::Climb(Cost)) {
|
||||
if let Ok(level) = join_data.skill_set.skill_level(Skill::Climb(Cost)) {
|
||||
data.static_data.energy_cost *= modifiers.energy_cost.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = join_data.skill_set.skill_level(Skill::Climb(Speed)) {
|
||||
if let Ok(level) = join_data.skill_set.skill_level(Skill::Climb(Speed)) {
|
||||
data.static_data.movement_speed *= modifiers.speed.powi(level.into());
|
||||
}
|
||||
data
|
||||
|
@ -437,7 +437,7 @@ fn swim_move(
|
||||
let force = efficiency * force;
|
||||
let mut water_accel = force / data.mass.0;
|
||||
|
||||
if let Ok(Some(level)) = data.skill_set.skill_level(Skill::Swim(SwimSkill::Speed)) {
|
||||
if let Ok(level) = data.skill_set.skill_level(Skill::Swim(SwimSkill::Speed)) {
|
||||
let modifiers = SKILL_MODIFIERS.general_tree.swim;
|
||||
water_accel *= modifiers.speed.powi(level.into());
|
||||
}
|
||||
|
@ -140,17 +140,17 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
if !skills_to_level.is_empty() {
|
||||
for skill_group in skills_to_level {
|
||||
if skill_set.earn_skill_point(skill_group).is_err() {
|
||||
warn!(
|
||||
"Attempted to add skill point to group which is inelgible to earn one"
|
||||
);
|
||||
}
|
||||
outcomes.push(Outcome::SkillPointGain {
|
||||
match skill_set.earn_skill_point(skill_group) {
|
||||
Ok(_) => outcomes.push(Outcome::SkillPointGain {
|
||||
uid: *uid,
|
||||
skill_tree: skill_group,
|
||||
total_points: skill_set.earned_sp(skill_group),
|
||||
pos: pos.0,
|
||||
});
|
||||
}),
|
||||
Err(_) => warn!(
|
||||
"Attempted to add skill point to group which is inelgible to earn one"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -167,7 +167,6 @@ impl<'a> System<'a> for Sys {
|
||||
if skill_set.modify_health {
|
||||
let health_level = skill_set
|
||||
.skill_level(Skill::General(GeneralSkill::HealthIncrease))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0);
|
||||
health.update_max_hp(*body, health_level);
|
||||
skill_set.modify_health = false;
|
||||
@ -175,7 +174,6 @@ impl<'a> System<'a> for Sys {
|
||||
if skill_set.modify_energy {
|
||||
let energy_level = skill_set
|
||||
.skill_level(Skill::General(GeneralSkill::EnergyIncrease))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0);
|
||||
energy.update_max_energy(*body, energy_level);
|
||||
skill_set.modify_energy = false;
|
||||
|
@ -530,6 +530,8 @@ fn convert_skill_groups_from_database(
|
||||
spent_exp: 0,
|
||||
available_sp: 0,
|
||||
earned_sp: 0,
|
||||
// Ordered skills empty here as skills get inserted later as they are unlocked, so long
|
||||
// as there is not a respec.
|
||||
ordered_skills: Vec::new(),
|
||||
};
|
||||
|
||||
@ -559,16 +561,17 @@ pub fn convert_skill_groups_to_database(
|
||||
entity_id: CharacterId,
|
||||
skill_groups: Vec<skillset::SkillGroup>,
|
||||
) -> Vec<SkillGroup> {
|
||||
let skill_group_hashes = &skillset::SKILL_GROUP_HASHES;
|
||||
skill_groups
|
||||
.into_iter()
|
||||
.map(|sg| SkillGroup {
|
||||
entity_id,
|
||||
skill_group_kind: json_models::skill_group_to_db_string(sg.skill_group_kind),
|
||||
earned_exp: sg.earned_exp as i32,
|
||||
spent_exp: sg.spent_exp as i32,
|
||||
earned_exp: i64::from(sg.earned_exp),
|
||||
spent_exp: i64::from(sg.spent_exp),
|
||||
// If fails to convert, just forces a respec on next login
|
||||
skills: serde_json::to_string(&sg.ordered_skills).unwrap_or_else(|_| "".to_string()),
|
||||
hash_val: skillset::SKILL_GROUP_HASHES
|
||||
hash_val: skill_group_hashes
|
||||
.get(&sg.skill_group_kind)
|
||||
.cloned()
|
||||
.unwrap_or_default(),
|
||||
|
@ -23,8 +23,8 @@ pub struct Body {
|
||||
pub struct SkillGroup {
|
||||
pub entity_id: i64,
|
||||
pub skill_group_kind: String,
|
||||
pub earned_exp: i32,
|
||||
pub spent_exp: i32,
|
||||
pub earned_exp: i64,
|
||||
pub spent_exp: i64,
|
||||
pub skills: String,
|
||||
pub hash_val: Vec<u8>,
|
||||
}
|
||||
|
@ -221,7 +221,6 @@ impl StateExt for State {
|
||||
body,
|
||||
skill_set
|
||||
.skill_level(Skill::General(GeneralSkill::EnergyIncrease))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0),
|
||||
))
|
||||
.with(stats)
|
||||
@ -508,11 +507,9 @@ impl StateExt for State {
|
||||
let (health_level, energy_level) = (
|
||||
skill_set
|
||||
.skill_level(Skill::General(GeneralSkill::HealthIncrease))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0),
|
||||
skill_set
|
||||
.skill_level(Skill::General(GeneralSkill::EnergyIncrease))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0),
|
||||
);
|
||||
self.write_component_ignore_entity_dead(entity, comp::Health::new(body, health_level));
|
||||
|
@ -903,7 +903,7 @@ impl<'a> Diary<'a> {
|
||||
id: state.skill_sword_dash_4,
|
||||
},
|
||||
SkillIcon::Unlockable {
|
||||
skill: Skill::Sword(DInfinite),
|
||||
skill: Skill::Sword(DChargeThrough),
|
||||
image: self.imgs.physical_distance_skill,
|
||||
position: MidTopWithMarginOn(state.skills_top_r[5], 3.0),
|
||||
id: state.skill_sword_dash_5,
|
||||
@ -1996,11 +1996,8 @@ impl<'a> Diary<'a> {
|
||||
diary_tooltip: &Tooltip,
|
||||
) {
|
||||
let label = if self.skill_set.prerequisites_met(skill) {
|
||||
let current = self
|
||||
.skill_set
|
||||
.skill_level(skill)
|
||||
.map_or(0, |l| l.unwrap_or(1));
|
||||
let max = skill.max_level().unwrap_or(1);
|
||||
let current = self.skill_set.skill_level(skill).unwrap_or(0);
|
||||
let max = skill.max_level();
|
||||
format!("{}/{}", current, max)
|
||||
} else {
|
||||
"".to_owned()
|
||||
@ -2195,7 +2192,7 @@ fn sword_skill_strings(skill: SwordSkill, i18n: &Localization) -> (&str, Cow<str
|
||||
"hud.skill.sw_dash_speed",
|
||||
modifiers.dash.forward_speed,
|
||||
),
|
||||
SwordSkill::DInfinite => localize(
|
||||
SwordSkill::DChargeThrough => localize(
|
||||
i18n,
|
||||
"hud.skill.sw_dash_charge_through_title",
|
||||
"hud.skill.sw_dash_charge_through",
|
||||
|
Loading…
Reference in New Issue
Block a user