veloren_common/comp/skillset/
skills.rs

1use crate::comp::skillset::{
2    SKILL_GROUP_LOOKUP, SKILL_MAX_LEVEL, SKILL_PREREQUISITES, SkillGroupKind, SkillPrerequisite,
3};
4use serde::{Deserialize, Serialize};
5
6/// Represents a skill that a player can unlock, that either grants them some
7/// kind of active ability, or a passive effect etc. Obviously because this is
8/// an enum it doesn't describe what the skill actually -does-, this will be
9/// handled by dedicated ECS systems.
10// NOTE: if skill does use some constant, add it to corresponding
11// SkillTree Modifiers below.
12#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
13pub enum Skill {
14    Sword(SwordSkill),
15    Axe(AxeSkill),
16    Hammer(HammerSkill),
17    Bow(BowSkill),
18    Staff(StaffSkill),
19    Sceptre(SceptreSkill),
20    Climb(ClimbSkill),
21    Swim(SwimSkill),
22    Pick(MiningSkill),
23    UnlockGroup(SkillGroupKind),
24}
25
26#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
27pub enum SwordSkill {
28    CrescentSlash,
29    FellStrike,
30    Skewer,
31    Cascade,
32    CrossCut,
33    Finisher,
34    HeavySweep,
35    HeavyPommelStrike,
36    HeavyFortitude,
37    HeavyPillarThrust,
38    AgileQuickDraw,
39    AgileFeint,
40    AgileDancingEdge,
41    AgileFlurry,
42    DefensiveRiposte,
43    DefensiveDisengage,
44    DefensiveDeflect,
45    DefensiveStalwartSword,
46    CripplingGouge,
47    CripplingHamstring,
48    CripplingBloodyGash,
49    CripplingEviscerate,
50    CleavingWhirlwindSlice,
51    CleavingEarthSplitter,
52    CleavingSkySplitter,
53    CleavingBladeFever,
54}
55
56#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
57pub enum AxeSkill {
58    BrutalSwing,
59    Berserk,
60    RisingTide,
61    SavageSense,
62    AdrenalineRush,
63    Execute,
64    Maelstrom,
65    Rake,
66    Bloodfeast,
67    FierceRaze,
68    Furor,
69    Fracture,
70    Lacerate,
71    Riptide,
72    SkullBash,
73    Sunder,
74    Plunder,
75    Defiance,
76    Keelhaul,
77    Bulkhead,
78    Capsize,
79}
80
81#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
82pub enum HammerSkill {
83    ScornfulSwipe,
84    Tremor,
85    VigorousBash,
86    Retaliate,
87    SpineCracker,
88    Breach,
89    IronTempest,
90    Upheaval,
91    Thunderclap,
92    SeismicShock,
93    HeavyWhorl,
94    Intercept,
95    PileDriver,
96    LungPummel,
97    HelmCrusher,
98    Rampart,
99    Tenacity,
100    Earthshaker,
101    Judgement,
102}
103
104#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
105pub enum BowSkill {
106    Foothold,
107    HeavyNock,
108    ArdentHunt,
109    OwlTalon,
110    EagleEye,
111    Heartseeker,
112    Hawkstrike,
113    SepticShot,
114    IgniteArrow,
115    DrenchArrow,
116    FreezeArrow,
117    JoltArrow,
118    Barrage,
119    PiercingGale,
120    Scatterburst,
121    Fusillade,
122    DeathVolley,
123}
124
125#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
126pub enum StaffSkill {
127    FireShockwave,
128    NapalmStrike,
129    FlameCloak,
130    FireDash,
131    FireBreath,
132    Pyroclasm,
133}
134
135#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
136pub enum SceptreSkill {
137    // Lifesteal beam upgrades
138    LDamage,
139    LRange,
140    LLifesteal,
141    LRegen,
142    // Healing aura upgrades
143    HHeal,
144    HRange,
145    HDuration,
146    HCost,
147    // Warding aura upgrades
148    UnlockAura,
149    AStrength,
150    ADuration,
151    ARange,
152    ACost,
153}
154
155#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
156pub enum ClimbSkill {
157    Cost,
158    Speed,
159}
160
161#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
162pub enum SwimSkill {
163    Speed,
164}
165
166#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
167pub enum MiningSkill {
168    Speed,
169    OreGain,
170    GemGain,
171}
172
173impl Skill {
174    /// Is unable to detect cyclic dependencies, so ensure that there are no
175    /// cycles if you modify the prerequisite map.
176    pub fn prerequisite_skills(&self) -> Option<&SkillPrerequisite> {
177        SKILL_PREREQUISITES.get(self)
178    }
179
180    /// Returns the cost in skill points of unlocking a particular skill
181    pub fn skill_cost(&self, level: u16) -> u16 { level }
182
183    /// Returns the maximum level a skill can reach, returns None if the skill
184    /// doesn't level
185    pub fn max_level(&self) -> u16 { SKILL_MAX_LEVEL.get(self).copied().unwrap_or(1) }
186
187    /// Returns the skill group type for a skill from the static skill group
188    /// definitions.
189    pub fn skill_group_kind(&self) -> Option<SkillGroupKind> {
190        SKILL_GROUP_LOOKUP.get(self).copied()
191    }
192}
193
194/// Tree of modifiers that represent how stats are
195/// changed per each skill level.
196///
197/// It's used as bridge between ECS systems
198/// and voxygen Diary for skill descriptions and helps to sync them.
199///
200/// NOTE: Just adding constant does nothing, you need to use it in both
201/// ECS systems and Diary.
202// TODO: make it lazy_static and move to .ron?
203pub const SKILL_MODIFIERS: SkillTreeModifiers = SkillTreeModifiers::get();
204
205pub struct SkillTreeModifiers {
206    pub staff_tree: StaffTreeModifiers,
207    pub sceptre_tree: SceptreTreeModifiers,
208    pub mining_tree: MiningTreeModifiers,
209    pub general_tree: GeneralTreeModifiers,
210}
211
212impl SkillTreeModifiers {
213    const fn get() -> Self {
214        Self {
215            staff_tree: StaffTreeModifiers::get(),
216            sceptre_tree: SceptreTreeModifiers::get(),
217            mining_tree: MiningTreeModifiers::get(),
218            general_tree: GeneralTreeModifiers::get(),
219        }
220    }
221}
222
223pub struct StaffTreeModifiers {
224    pub fireball: StaffFireballModifiers,
225    pub flamethrower: StaffFlamethrowerModifiers,
226    pub shockwave: StaffShockwaveModifiers,
227}
228
229pub struct StaffFireballModifiers {
230    pub power: f32,
231    pub regen: f32,
232    pub range: f32,
233}
234
235pub struct StaffFlamethrowerModifiers {
236    pub damage: f32,
237    pub range: f32,
238    pub energy_drain: f32,
239    pub velocity: f32,
240}
241
242pub struct StaffShockwaveModifiers {
243    pub damage: f32,
244    pub knockback: f32,
245    pub duration: f32,
246    pub energy_cost: f32,
247}
248
249impl StaffTreeModifiers {
250    const fn get() -> Self {
251        Self {
252            fireball: StaffFireballModifiers {
253                power: 1.05,
254                regen: 1.05,
255                range: 1.05,
256            },
257            flamethrower: StaffFlamethrowerModifiers {
258                damage: 1.1,
259                range: 1.05,
260                energy_drain: 0.95,
261                velocity: 1.05,
262            },
263            shockwave: StaffShockwaveModifiers {
264                damage: 1.1,
265                knockback: 1.05,
266                duration: 1.05,
267                energy_cost: 0.95,
268            },
269        }
270    }
271}
272
273pub struct SceptreTreeModifiers {
274    pub beam: SceptreBeamModifiers,
275    pub healing_aura: SceptreHealingAuraModifiers,
276    pub warding_aura: SceptreWardingAuraModifiers,
277}
278
279pub struct SceptreBeamModifiers {
280    pub damage: f32,
281    pub range: f32,
282    pub energy_regen: f32,
283    pub lifesteal: f32,
284}
285
286pub struct SceptreHealingAuraModifiers {
287    pub strength: f32,
288    pub duration: f32,
289    pub range: f32,
290    pub energy_cost: f32,
291}
292
293pub struct SceptreWardingAuraModifiers {
294    pub strength: f32,
295    pub duration: f32,
296    pub range: f32,
297    pub energy_cost: f32,
298}
299
300impl SceptreTreeModifiers {
301    const fn get() -> Self {
302        Self {
303            beam: SceptreBeamModifiers {
304                damage: 1.05,
305                range: 1.05,
306                energy_regen: 1.05,
307                lifesteal: 1.05,
308            },
309            healing_aura: SceptreHealingAuraModifiers {
310                strength: 1.05,
311                duration: 1.05,
312                range: 1.05,
313                energy_cost: 0.95,
314            },
315            warding_aura: SceptreWardingAuraModifiers {
316                strength: 1.05,
317                duration: 1.05,
318                range: 1.05,
319                energy_cost: 0.95,
320            },
321        }
322    }
323}
324
325pub struct MiningTreeModifiers {
326    pub speed: f32,
327    pub gem_gain: f32,
328    pub ore_gain: f32,
329}
330
331impl MiningTreeModifiers {
332    const fn get() -> Self {
333        Self {
334            speed: 1.1,
335            gem_gain: 0.1,
336            ore_gain: 0.1,
337        }
338    }
339}
340
341pub struct GeneralTreeModifiers {
342    pub swim: SwimTreeModifiers,
343    pub climb: ClimbTreeModifiers,
344}
345
346pub struct SwimTreeModifiers {
347    pub speed: f32,
348}
349
350pub struct ClimbTreeModifiers {
351    pub energy_cost: f32,
352    pub speed: f32,
353}
354
355impl GeneralTreeModifiers {
356    const fn get() -> Self {
357        Self {
358            swim: SwimTreeModifiers { speed: 1.25 },
359            climb: ClimbTreeModifiers {
360                energy_cost: 0.8,
361                speed: 1.2,
362            },
363        }
364    }
365}