veloren_voxygen_anim/bird_large/
combomelee.rs1use 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}