veloren_voxygen_anim/bird_large/
combomelee.rs

1use super::{
2    super::{Animation, vek::*},
3    BirdLargeSkeleton, SkeletonAttr,
4};
5use common::states::utils::StageSection;
6
7pub struct ComboAnimation;
8impl Animation for ComboAnimation {
9    type Dependency<'a> = (
10        Option<&'a str>,
11        Option<StageSection>,
12        usize,
13        f32,
14        f32,
15        Vec3<f32>,
16        Vec3<f32>,
17        bool,
18    );
19    type Skeleton = BirdLargeSkeleton;
20
21    #[cfg(feature = "use-dyn-lib")]
22    const UPDATE_FN: &'static [u8] = b"bird_large_combo\0";
23
24    #[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_combo")]
25    fn update_skeleton_inner(
26        skeleton: &Self::Skeleton,
27        (
28            ability_id,
29            stage_section,
30            current_strike,
31            global_time,
32            timer,
33            orientation,
34            last_ori,
35            on_ground,
36        ): Self::Dependency<'_>,
37        anim_time: f32,
38        rate: &mut f32,
39        s_a: &SkeletonAttr,
40    ) -> Self::Skeleton {
41        *rate = 1.0;
42        let mut next = (*skeleton).clone();
43
44        let multi_strike_pullback = 1.0
45            - if matches!(stage_section, Some(StageSection::Recover)) {
46                anim_time.powi(4)
47            } else {
48                0.0
49            };
50
51        let (move1base, move2base, _move3) = match stage_section {
52            Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0, 0.0),
53            Some(StageSection::Action) => (1.0, anim_time, 0.0),
54            Some(StageSection::Recover) => (1.0, 1.0, anim_time.powf(4.0)),
55            _ => (0.0, 0.0, 0.0),
56        };
57
58        let wave_slow_cos = (anim_time * 4.5).cos();
59
60        let subtract = global_time - timer;
61        let check = subtract - subtract.trunc();
62        let mirror = (check - 0.5).signum();
63
64        let move1 = move1base * multi_strike_pullback;
65        let move2 = move2base * multi_strike_pullback;
66        let move1mirror = move1base * multi_strike_pullback * mirror;
67        let ori: Vec2<f32> = Vec2::from(orientation);
68        let last_ori = Vec2::from(last_ori);
69        let tilt = if vek::Vec2::new(ori, last_ori)
70            .map(|o| o.magnitude_squared())
71            .map(|m| m > 0.001 && m.is_finite())
72            .reduce_and()
73            && ori.angle_between(last_ori).is_finite()
74        {
75            ori.angle_between(last_ori).min(0.2)
76                * last_ori.determine_side(Vec2::zero(), ori).signum()
77        } else {
78            0.0
79        } * 1.3;
80
81        for strike in 0..=current_strike {
82            match ability_id {
83                Some("common.abilities.custom.birdlargefire.legstrike") => match strike {
84                    0..=2 => {
85                        next.chest.position = Vec3::new(
86                            0.0,
87                            s_a.chest.0,
88                            s_a.chest.1 + wave_slow_cos * 0.06 + move2 * -6.0,
89                        );
90                        next.chest.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.8);
91                        next.leg_r.orientation = Quaternion::rotation_x(move1 * 1.5 + move2 * -2.5);
92                        next.leg_l.orientation = Quaternion::rotation_x(move1 * 1.5 + move2 * -2.5);
93                    },
94                    _ => {},
95                },
96                _ => match strike {
97                    0..=2 => {
98                        next.chest.position = Vec3::new(
99                            0.0,
100                            s_a.chest.0,
101                            s_a.chest.1 + wave_slow_cos * 0.06 + move2 * -6.0,
102                        );
103                        next.chest.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.8);
104
105                        next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1);
106                        next.neck.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.4)
107                            * Quaternion::rotation_z(move1 * tilt * 1.5)
108                            * Quaternion::rotation_y(move1mirror * 0.3);
109
110                        next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
111                        next.head.orientation = Quaternion::rotation_x(move1 * -0.2 - move2 * 0.2)
112                            * Quaternion::rotation_y(move1mirror * 0.5);
113
114                        next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1);
115                        next.beak.orientation = Quaternion::rotation_x(
116                            wave_slow_cos * -0.02 + move1 * -0.5 + move2 * 0.5,
117                        );
118
119                        if on_ground {
120                            next.tail_front.position =
121                                Vec3::new(0.0, s_a.tail_front.0, s_a.tail_front.1);
122                            next.tail_front.orientation = Quaternion::rotation_x(-move1 * 0.2);
123                            next.tail_rear.position =
124                                Vec3::new(0.0, s_a.tail_rear.0, s_a.tail_rear.1);
125                            next.tail_rear.orientation = Quaternion::rotation_x(0.0);
126
127                            next.wing_in_l.position =
128                                Vec3::new(-s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2);
129                            next.wing_in_r.position =
130                                Vec3::new(s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2);
131
132                            next.wing_in_l.orientation = Quaternion::rotation_y(
133                                -1.0 + wave_slow_cos * 0.06 + move1 * 1.0 + move2 * 0.5,
134                            ) * Quaternion::rotation_z(0.2);
135                            next.wing_in_r.orientation = Quaternion::rotation_y(
136                                1.0 - wave_slow_cos * 0.06 + move1 * -1.0 + move2 * -0.5,
137                            ) * Quaternion::rotation_z(-0.2);
138
139                            next.wing_mid_l.position =
140                                Vec3::new(-s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2);
141                            next.wing_mid_r.position =
142                                Vec3::new(s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2);
143                            next.wing_mid_l.orientation =
144                                Quaternion::rotation_y(-0.1 + move1 * -0.5)
145                                    * Quaternion::rotation_z(0.7 + move1 * -0.7);
146                            next.wing_mid_r.orientation = Quaternion::rotation_y(0.1 + move1 * 0.5)
147                                * Quaternion::rotation_z(-0.7 + move1 * 0.7);
148
149                            next.wing_out_l.position =
150                                Vec3::new(-s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2);
151                            next.wing_out_r.position =
152                                Vec3::new(s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2);
153                            next.wing_out_l.orientation =
154                                Quaternion::rotation_y(-0.2 + move1 * -0.3)
155                                    * Quaternion::rotation_z(0.2);
156                            next.wing_out_r.orientation = Quaternion::rotation_y(0.2 + move1 * 0.3)
157                                * Quaternion::rotation_z(-0.2);
158                        }
159                    },
160                    _ => {},
161                },
162            }
163        }
164
165        next
166    }
167}