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