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    // Basic ranged upgrades
128    BDamage,
129    BRegen,
130    BRadius,
131    // Flamethrower upgrades
132    FDamage,
133    FRange,
134    FDrain,
135    FVelocity,
136    // Shockwave upgrades
137    UnlockShockwave,
138    SDamage,
139    SKnockback,
140    SRange,
141    SCost,
142}
143
144#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
145pub enum SceptreSkill {
146    // Lifesteal beam upgrades
147    LDamage,
148    LRange,
149    LLifesteal,
150    LRegen,
151    // Healing aura upgrades
152    HHeal,
153    HRange,
154    HDuration,
155    HCost,
156    // Warding aura upgrades
157    UnlockAura,
158    AStrength,
159    ADuration,
160    ARange,
161    ACost,
162}
163
164#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
165pub enum ClimbSkill {
166    Cost,
167    Speed,
168}
169
170#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
171pub enum SwimSkill {
172    Speed,
173}
174
175#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
176pub enum MiningSkill {
177    Speed,
178    OreGain,
179    GemGain,
180}
181
182impl Skill {
183    /// Is unable to detect cyclic dependencies, so ensure that there are no
184    /// cycles if you modify the prerequisite map.
185    pub fn prerequisite_skills(&self) -> Option<&SkillPrerequisite> {
186        SKILL_PREREQUISITES.get(self)
187    }
188
189    /// Returns the cost in skill points of unlocking a particular skill
190    pub fn skill_cost(&self, level: u16) -> u16 { level }
191
192    /// Returns the maximum level a skill can reach, returns None if the skill
193    /// doesn't level
194    pub fn max_level(&self) -> u16 { SKILL_MAX_LEVEL.get(self).copied().unwrap_or(1) }
195
196    /// Returns the skill group type for a skill from the static skill group
197    /// definitions.
198    pub fn skill_group_kind(&self) -> Option<SkillGroupKind> {
199        SKILL_GROUP_LOOKUP.get(self).copied()
200    }
201}
202
203/// Tree of modifiers that represent how stats are
204/// changed per each skill level.
205///
206/// It's used as bridge between ECS systems
207/// and voxygen Diary for skill descriptions and helps to sync them.
208///
209/// NOTE: Just adding constant does nothing, you need to use it in both
210/// ECS systems and Diary.
211// TODO: make it lazy_static and move to .ron?
212pub const SKILL_MODIFIERS: SkillTreeModifiers = SkillTreeModifiers::get();
213
214pub struct SkillTreeModifiers {
215    pub staff_tree: StaffTreeModifiers,
216    pub sceptre_tree: SceptreTreeModifiers,
217    pub mining_tree: MiningTreeModifiers,
218    pub general_tree: GeneralTreeModifiers,
219}
220
221impl SkillTreeModifiers {
222    const fn get() -> Self {
223        Self {
224            staff_tree: StaffTreeModifiers::get(),
225            sceptre_tree: SceptreTreeModifiers::get(),
226            mining_tree: MiningTreeModifiers::get(),
227            general_tree: GeneralTreeModifiers::get(),
228        }
229    }
230}
231
232pub struct StaffTreeModifiers {
233    pub fireball: StaffFireballModifiers,
234    pub flamethrower: StaffFlamethrowerModifiers,
235    pub shockwave: StaffShockwaveModifiers,
236}
237
238pub struct StaffFireballModifiers {
239    pub power: f32,
240    pub regen: f32,
241    pub range: f32,
242}
243
244pub struct StaffFlamethrowerModifiers {
245    pub damage: f32,
246    pub range: f32,
247    pub energy_drain: f32,
248    pub velocity: f32,
249}
250
251pub struct StaffShockwaveModifiers {
252    pub damage: f32,
253    pub knockback: f32,
254    pub duration: f32,
255    pub energy_cost: f32,
256}
257
258impl StaffTreeModifiers {
259    const fn get() -> Self {
260        Self {
261            fireball: StaffFireballModifiers {
262                power: 1.05,
263                regen: 1.05,
264                range: 1.05,
265            },
266            flamethrower: StaffFlamethrowerModifiers {
267                damage: 1.1,
268                range: 1.05,
269                energy_drain: 0.95,
270                velocity: 1.05,
271            },
272            shockwave: StaffShockwaveModifiers {
273                damage: 1.1,
274                knockback: 1.05,
275                duration: 1.05,
276                energy_cost: 0.95,
277            },
278        }
279    }
280}
281
282pub struct SceptreTreeModifiers {
283    pub beam: SceptreBeamModifiers,
284    pub healing_aura: SceptreHealingAuraModifiers,
285    pub warding_aura: SceptreWardingAuraModifiers,
286}
287
288pub struct SceptreBeamModifiers {
289    pub damage: f32,
290    pub range: f32,
291    pub energy_regen: f32,
292    pub lifesteal: f32,
293}
294
295pub struct SceptreHealingAuraModifiers {
296    pub strength: f32,
297    pub duration: f32,
298    pub range: f32,
299    pub energy_cost: f32,
300}
301
302pub struct SceptreWardingAuraModifiers {
303    pub strength: f32,
304    pub duration: f32,
305    pub range: f32,
306    pub energy_cost: f32,
307}
308
309impl SceptreTreeModifiers {
310    const fn get() -> Self {
311        Self {
312            beam: SceptreBeamModifiers {
313                damage: 1.05,
314                range: 1.05,
315                energy_regen: 1.05,
316                lifesteal: 1.05,
317            },
318            healing_aura: SceptreHealingAuraModifiers {
319                strength: 1.05,
320                duration: 1.05,
321                range: 1.05,
322                energy_cost: 0.95,
323            },
324            warding_aura: SceptreWardingAuraModifiers {
325                strength: 1.05,
326                duration: 1.05,
327                range: 1.05,
328                energy_cost: 0.95,
329            },
330        }
331    }
332}
333
334pub struct MiningTreeModifiers {
335    pub speed: f32,
336    pub gem_gain: f32,
337    pub ore_gain: f32,
338}
339
340impl MiningTreeModifiers {
341    const fn get() -> Self {
342        Self {
343            speed: 1.1,
344            gem_gain: 0.1,
345            ore_gain: 0.1,
346        }
347    }
348}
349
350pub struct GeneralTreeModifiers {
351    pub swim: SwimTreeModifiers,
352    pub climb: ClimbTreeModifiers,
353}
354
355pub struct SwimTreeModifiers {
356    pub speed: f32,
357}
358
359pub struct ClimbTreeModifiers {
360    pub energy_cost: f32,
361    pub speed: f32,
362}
363
364impl GeneralTreeModifiers {
365    const fn get() -> Self {
366        Self {
367            swim: SwimTreeModifiers { speed: 1.25 },
368            climb: ClimbTreeModifiers {
369                energy_cost: 0.8,
370                speed: 1.2,
371            },
372        }
373    }
374}