veloren_voxygen_anim/biped_small/
combomelee.rs

1use std::f32::consts::PI;
2
3use super::{
4    super::{Animation, vek::*},
5    BipedSmallSkeleton, SkeletonAttr, biped_small_alpha_axe, biped_small_alpha_dagger,
6    biped_small_alpha_spear, biped_small_wield_spear, init_biped_small_alpha,
7};
8use common::states::utils::StageSection;
9
10pub struct ComboAnimation;
11impl Animation for ComboAnimation {
12    type Dependency<'a> = (Option<&'a str>, StageSection, usize, Vec3<f32>, f32, f32);
13    type Skeleton = BipedSmallSkeleton;
14
15    #[cfg(feature = "use-dyn-lib")]
16    const UPDATE_FN: &'static [u8] = b"biped_small_combo\0";
17
18    #[cfg_attr(feature = "be-dyn-lib", export_name = "biped_small_combo")]
19    fn update_skeleton_inner(
20        skeleton: &Self::Skeleton,
21        (ability_id, stage_section, current_strike, velocity, _global_time, _timer): Self::Dependency<'_>,
22        anim_time: f32,
23        rate: &mut f32,
24        s_a: &SkeletonAttr,
25    ) -> Self::Skeleton {
26        *rate = 1.0;
27        let mut next = (*skeleton).clone();
28
29        next.main.position = Vec3::new(0.0, 0.0, 0.0);
30        next.main.orientation = Quaternion::rotation_z(0.0);
31        let multi_strike_pullback = 1.0
32            - if matches!(stage_section, StageSection::Recover) {
33                anim_time.powi(4)
34            } else {
35                0.0
36            };
37
38        for strike in 0..=current_strike {
39            match ability_id {
40                Some(
41                    "common.abilities.custom.bushly.singlestrike"
42                    | "common.abilities.custom.irrwurz.singlestrike"
43                    | "common.abilities.custom.husk.singlestrike"
44                    | "common.abilities.custom.husk.triplestrike"
45                    | "common.abilities.custom.dwarves.iron_dwarf.singlestrike"
46                    | "common.abilities.custom.dwarves.iron_dwarf.triplestrike",
47                ) => {
48                    let (move1, move2) = if strike == current_strike {
49                        match stage_section {
50                            StageSection::Buildup => {
51                                (((anim_time.max(0.4) - 0.4) * 1.5).powf(0.5), 0.0)
52                            },
53                            StageSection::Action => (1.0, (anim_time.min(0.4) * 2.5).powi(2)),
54                            StageSection::Recover => (1.0, 1.0),
55                            _ => (0.0, 0.0),
56                        }
57                    } else {
58                        (1.0, 1.0)
59                    };
60                    let move1 = move1 * multi_strike_pullback;
61                    let move2 = move2 * multi_strike_pullback;
62                    next.hand_l.position = Vec3::new(s_a.grip.0 * 4.0, 0.0, s_a.grip.2);
63                    next.hand_r.position = Vec3::new(-s_a.grip.0 * 4.0, 0.0, s_a.grip.2);
64                    next.main.position = Vec3::new(0.0, 0.0, 0.0);
65                    next.main.orientation = Quaternion::rotation_x(0.0);
66                    next.hand_l.orientation = Quaternion::rotation_x(0.0);
67                    next.hand_r.orientation = Quaternion::rotation_x(0.0);
68
69                    match strike {
70                        0..=2 => {
71                            next.chest.orientation = Quaternion::rotation_x(move2 * -1.0)
72                                * Quaternion::rotation_z(move1 * 1.2 + move2 * -1.8);
73                            next.hand_l.position = Vec3::new(-s_a.hand.0, s_a.hand.1, s_a.hand.2);
74                            next.hand_l.orientation = Quaternion::rotation_x(1.2);
75                            next.hand_r.position = Vec3::new(s_a.hand.0, s_a.hand.1, s_a.hand.2);
76                            next.hand_r.orientation = Quaternion::rotation_x(1.2);
77                        },
78                        _ => {},
79                    }
80                },
81                Some("common.abilities.custom.cactid.singlestrike") => {
82                    let (move1, move2) = if strike == current_strike {
83                        match stage_section {
84                            StageSection::Buildup => {
85                                (((anim_time.max(0.4) - 0.4) * 1.5).powf(0.5), 0.0)
86                            },
87                            StageSection::Action => (1.0, (anim_time.min(0.4) * 2.5).powi(2)),
88                            StageSection::Recover => (1.0, 1.0),
89                            _ => (0.0, 0.0),
90                        }
91                    } else {
92                        (1.0, 1.0)
93                    };
94                    let move1 = move1 * multi_strike_pullback;
95                    let move2 = move2 * multi_strike_pullback;
96                    next.hand_l.position = Vec3::new(s_a.grip.0 * 4.0, 0.0, s_a.grip.2);
97                    next.hand_r.position = Vec3::new(-s_a.grip.0 * 4.0, 0.0, s_a.grip.2);
98                    next.main.position = Vec3::new(0.0, 0.0, 0.0);
99                    next.main.orientation = Quaternion::rotation_x(0.0);
100                    next.hand_l.orientation = Quaternion::rotation_x(0.0);
101                    next.hand_r.orientation = Quaternion::rotation_x(0.0);
102                    next.head.orientation = Quaternion::rotation_z(move2 * 1.0);
103
104                    next.chest.orientation = Quaternion::rotation_x(move2 * -1.0)
105                        * Quaternion::rotation_z(move1 * -1.2 + move2 * 1.8);
106                    next.hand_l.position = Vec3::new(-s_a.hand.0, s_a.hand.1, s_a.hand.2);
107                    next.hand_l.orientation = Quaternion::rotation_x(1.2);
108                    next.hand_r.position = Vec3::new(s_a.hand.0, s_a.hand.1, s_a.hand.2);
109                    next.hand_r.orientation = Quaternion::rotation_x(1.2);
110                },
111                Some(
112                    "common.abilities.axesimple.doublestrike"
113                    | "common.abilities.custom.goblin_thug.doublestrike"
114                    | "common.abilities.custom.green_legoom.doublestrike"
115                    | "common.abilities.custom.red_legoom.doublestrike"
116                    | "common.abilities.vampire.bloodservant.doublestrike"
117                    | "common.abilities.custom.boreal_warrior.hammer.singlestrike",
118                ) => {
119                    let anim_time = anim_time.min(1.0);
120                    let (move1base, move2base, move3) = match stage_section {
121                        StageSection::Buildup => (anim_time.sqrt(), 0.0, 0.0),
122                        StageSection::Action => (1.0, anim_time.powi(4), 0.0),
123                        StageSection::Recover => (1.0, 1.0, anim_time),
124                        _ => (0.0, 0.0, 0.0),
125                    };
126                    let pullback = 1.0 - move3;
127                    let move1abs = move1base * pullback;
128                    let move2abs = move2base * pullback;
129
130                    init_biped_small_alpha(&mut next, s_a);
131                    biped_small_alpha_axe(&mut next, s_a, move1abs, move2abs);
132                },
133                Some("common.abilities.custom.boreal_warrior.bow.doublestrike") => {
134                    let anim_time = anim_time.min(1.0);
135                    let (move1base, move2base) = if strike == current_strike {
136                        match stage_section {
137                            StageSection::Buildup => (anim_time.sqrt(), 0.0),
138                            StageSection::Action => (1.0, anim_time.powi(4)),
139                            StageSection::Recover => (1.0, 1.0),
140                            _ => (0.0, 0.0),
141                        }
142                    } else {
143                        (1.0, 1.0)
144                    };
145                    let move1 = move1base * multi_strike_pullback;
146                    let move2 = move2base * multi_strike_pullback;
147
148                    match strike {
149                        0 => {
150                            init_biped_small_alpha(&mut next, s_a);
151                            next.control.position += Vec3::new(0.0, 8.0, 0.0);
152                            next.control.orientation.rotate_x(-PI / 8.0);
153                            next.hand_l.position += Vec3::new(-6.0, -4.0, -4.0);
154                            next.hand_l.orientation.rotate_x(PI / 2.0);
155                            next.hand_l.orientation.rotate_z(-PI / 8.0);
156                            next.hand_r.position += Vec3::new(4.0, -4.0, -6.0);
157                            next.hand_r.orientation.rotate_x(PI / 2.0);
158                            next.hand_r.orientation.rotate_z(PI / 9.0);
159
160                            next.chest.orientation.rotate_z(PI / 4.0 * move1);
161                            next.control.position += Vec3::new(0.0, (PI * move1).cos(), 0.0);
162                            next.control.orientation.rotate_y(-PI / 8.0 * move1);
163                            next.control.orientation.rotate_x(-PI / 8.0 * move1.powi(2));
164
165                            next.control
166                                .orientation
167                                .rotate_y(-PI / 3.0 * f32::from(move2 != 0.0));
168                            next.chest.orientation.rotate_z(-PI / 2.5 * move2);
169                        },
170                        1 => {
171                            next.chest.orientation.rotate_z(-PI / 5.0 * move1);
172                            next.control.position += Vec3::new(0.0, (PI * move1).cos(), 0.0);
173                            next.control.orientation.rotate_y(PI / 2.0 * move1);
174
175                            next.control
176                                .orientation
177                                .rotate_y(PI / 3.0 * f32::from(move2 != 0.0));
178                            next.chest.orientation.rotate_z(PI / 2.0 * move2);
179                        },
180                        _ => {},
181                    }
182                },
183                Some(
184                    "common.abilities.daggersimple.singlestrike"
185                    | "common.abilities.vampire.bloodmoon_heiress.singlestrike",
186                ) => {
187                    let anim_time = anim_time.min(1.0);
188                    let (move1base, move2base, move3) = match stage_section {
189                        StageSection::Buildup => (anim_time.sqrt(), 0.0, 0.0),
190                        StageSection::Action => (1.0, anim_time.powi(4), 0.0),
191                        StageSection::Recover => (1.0, 1.0, anim_time),
192                        _ => (0.0, 0.0, 0.0),
193                    };
194                    let pullback = 1.0 - move3;
195                    let move1abs = move1base * pullback;
196                    let move2abs = move2base * pullback;
197
198                    init_biped_small_alpha(&mut next, s_a);
199                    biped_small_alpha_dagger(&mut next, s_a, move1abs, move2abs);
200                },
201                Some(
202                    "common.abilities.spear.doublestrike"
203                    | "common.abilities.custom.purple_legoom.doublestrike",
204                ) => {
205                    let anim_time = anim_time.min(1.0);
206                    let speed = Vec2::<f32>::from(velocity).magnitude();
207                    let speednorm = speed / 9.4;
208                    let speednormcancel = 1.0 - speednorm;
209
210                    let (move1base, move2base, move3) = match stage_section {
211                        StageSection::Buildup => (anim_time.sqrt(), 0.0, 0.0),
212                        StageSection::Action => (1.0, anim_time.powi(4), 0.0),
213                        StageSection::Recover => (1.0, 1.0, anim_time),
214                        _ => (0.0, 0.0, 0.0),
215                    };
216                    let pullback = 1.0 - move3;
217                    let move1abs = move1base * pullback;
218                    let move2abs = move2base * pullback;
219
220                    init_biped_small_alpha(&mut next, s_a);
221                    biped_small_alpha_spear(
222                        &mut next,
223                        s_a,
224                        move1abs,
225                        move2abs,
226                        anim_time,
227                        speednormcancel,
228                    );
229                },
230                Some("common.abilities.haniwa.guard.backpedal") => {
231                    init_biped_small_alpha(&mut next, s_a);
232                    biped_small_wield_spear(&mut next, s_a, anim_time, 0.0, 0.0);
233
234                    let (move1, move2, move3) = match stage_section {
235                        StageSection::Buildup => (anim_time.powf(0.25), 0.0, 0.0),
236                        StageSection::Action => (1.0, anim_time, 0.0),
237                        StageSection::Recover => (1.0, 1.0, anim_time.powf(0.25)),
238                        _ => (0.0, 0.0, 0.0),
239                    };
240                    let pullback = 1.0 - move3;
241                    let move1 = move1 * pullback;
242                    let move2 = move2 * pullback;
243
244                    biped_small_alpha_spear(&mut next, s_a, move1, move2, anim_time, 0.0);
245                },
246                _ => {},
247            }
248        }
249        next
250    }
251}