-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathy-custom-geo-functions.lua
More file actions
304 lines (255 loc) · 9.7 KB
/
y-custom-geo-functions.lua
File metadata and controls
304 lines (255 loc) · 9.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
-- Custom Geo Functions --
--- @param m MarioState
--- @return integer
--- Returns from directions between 1-8 depending on the camera angle
function mario_yaw_from_camera(m)
local l = gLakituState
local tau = math.pi * 2
local headAngle = m.marioObj.header.gfx.angle.y
-- vvv Needs fixing later. vvv
--[[for i = MARIO_ANIM_PART_ROOT, MARIO_ANIM_PART_HEAD + 1 do
headAngle = headAngle + m.marioBodyState.animPartsRot[i].y
end]]
local vector = {X = l.pos.x - m.pos.x, Y = l.pos.y - m.pos.y, Z = l.pos.z - m.pos.z}
local r0 = math.rad((headAngle * 360) / 0x10000)
local r1 = r0 < 0 and tau - math.abs(r0) or r0
local a0 = math.atan(vector.Z, vector.X) + math.pi * 0.5
local a1
a1 = ((a0 < 0 and tau - math.abs(a0) or a0) + r1)
local a2 = (a1 % tau) * 8 / tau
local angle = (math.round(a2) % 8) + 1
return angle
end
-- Sonic Spin/Ball Acts --
local sSonicSpinBallActs = {
[ACT_SONIC_SPIN_JUMP] = true,
[ACT_SONIC_SPIN_DASH] = true,
[ACT_SONIC_AIR_SPIN] = true,
[ACT_SONIC_HOMING_ATTACK] = true,
}
local sSonicInstashieldActs = {
[ACT_SONIC_SPIN_JUMP] = true,
[ACT_SONIC_AIR_SPIN] = true,
}
local sSonicSpinDashActs = {
[ACT_SONIC_SPIN_DASH_CHARGE] = true,
}
--- @param n GraphNode | FnGraphNode
--- Switches between the spin and ball models during a spin/ball actions
function geo_ball_switch(n)
local switch = cast_graph_node(n)
local m = geo_get_mario_state()
local e = gCharacterStates[m.playerIndex].sonic
if sSonicSpinBallActs[m.action] then
if sSonicInstashieldActs[m.action] and e.instashieldTimer > 0 then
switch.selectedCase = 4
else
switch.selectedCase = ((m.actionTimer - 1) % 4 // 2 + 1)
end
elseif sSonicSpinDashActs[m.action] then
switch.selectedCase = 3
elseif m.action == ACT_GROUND_POUND and m.actionTimer > 15 then
switch.selectedCase = 1
else
switch.selectedCase = 0
end
end
-- SlowDownBoots
--- @param n GraphNode | FnGraphNode
--- Switches states when SlowDownBoots is true.
function custom_slowdown_right(n)
local switch = cast_graph_node(n)
local m = geo_get_mario_state()
local e = gCharacterStates[m.playerIndex].sonic
switch.selectedCase = sSlowDownBoots and 1 or 0
end
function custom_slowdown_left(n)
local switch = cast_graph_node(n)
local m = geo_get_mario_state()
local e = gCharacterStates[m.playerIndex].sonic
switch.selectedCase = sSlowDownBoots and 1 or 0
end
-- Spindash States --
--- @param n GraphNode | FnGraphNode
--- Switches the spindash states
function geo_custom_spindash_states(n)
local switch = cast_graph_node(n)
local m = geo_get_mario_state()
local e = gCharacterStates[m.playerIndex].sonic
switch.selectedCase = math.floor(e.spindashState)
end
-- Mouth Switch --
SONIC_MOUTH_NORMAL = 0 --- @type SonicMouthGSCId
SONIC_MOUTH_FROWN = 1 --- @type SonicMouthGSCId
SONIC_MOUTH_GRIMACING = 2 --- @type SonicMouthGSCId
SONIC_MOUTH_HAPPY = 3 --- @type SonicMouthGSCId
SONIC_MOUTH_GRIN = 4 --- @type SonicMouthGSCId
SONIC_MOUTH_ATTACKED = 5 --- @type SonicMouthGSCId
SONIC_MOUTH_SHOCKED = 6 --- @type SonicMouthGSCId
SONIC_MOUTH_SURPRISED = 7 --- @type SonicMouthGSCId
SONIC_MOUTH_NEUTRAL = 8 --- @type SonicMouthGSCId
local sGrimacingActs = {
[ACT_HOLD_HEAVY_IDLE] = true,
[ACT_SHIVERING] = true,
[ACT_HOLD_HEAVY_WALKING] = true,
[ACT_SHOCKED] = true,
[ACT_HEAVY_THROW] = true,
}
local sSurprisedEyeStates = {
[MARIO_EYES_LOOK_LEFT] = true,
[MARIO_EYES_LOOK_RIGHT] = true,
[MARIO_EYES_LOOK_UP] = true,
[MARIO_EYES_LOOK_DOWN] = true,
}
--- @param n GraphNode | FnGraphNode
--- Switches the mouth state
function geo_switch_mario_mouth(n)
local switch = cast_graph_node(n)
local m = geo_get_mario_state()
local o = geo_get_current_object()
local homingAttacked = m.action == ACT_SONIC_FALL and m.actionArg >= 5
local frame = m.marioObj.header.gfx.animInfo.animFrame
if m.marioBodyState.eyeState == MARIO_EYES_DEAD then
switch.selectedCase = SONIC_MOUTH_ATTACKED
elseif sGrimacingActs[m.action] then
switch.selectedCase = SONIC_MOUTH_GRIMACING
elseif m.action == ACT_PANTING then
switch.selectedCase = SONIC_MOUTH_SURPRISED
elseif m.marioBodyState.eyeState == MARIO_EYES_HALF_CLOSED and m.action == ACT_START_SLEEPING then
switch.selectedCase = SONIC_MOUTH_SHOCKED
m.actionTimer = 0
elseif m.marioBodyState.handState == MARIO_HAND_PEACE_SIGN or (homingAttacked and frame <= 22) then
switch.selectedCase = SONIC_MOUTH_GRIN
else
switch.selectedCase = SONIC_MOUTH_NORMAL
end
end
-- Mouth Side Switch --
SONIC_MOUTH_LEFT = 0 --- @type SonicMouthSideGSCId
SONIC_MOUTH_RIGHT = 1 --- @type SonicMouthSideGSCId
--- @param n GraphNode | FnGraphNode
--- Switches the side that the mouth is being displayed on
function geo_switch_mario_mouth_side(n)
local switch = cast_graph_node(n)
local m = geo_get_mario_state()
local o = geo_get_current_object()
local angle = mario_yaw_from_camera(m)
if angle <= 4 or m.marioBodyState.handState == MARIO_HAND_PEACE_SIGN then
switch.selectedCase = SONIC_MOUTH_RIGHT
else
switch.selectedCase = SONIC_MOUTH_LEFT
end
end
-- Custom Hand Switch --
-- Hand Params
SONIC_HAND_RIGHT = 0 --- @type HandParam
SONIC_HAND_LEFT = 1 --- @type HandParam
WAPEACH_HAND_AXE = 2 --- @type HandParam
-- Wapeach Hand
local sWapeachAxeActs = {
[ACT_AXE_CHOP] = true,
[ACT_AXE_SPIN] = true,
[ACT_AXE_SPIN_AIR] = true,
[ACT_AXE_SPIN_DIZZY] = true,
}
-- Sonic Hand
local sSonicHandCopies = {
[MARIO_HAND_FISTS] = true,
[MARIO_HAND_OPEN] = true,
[MARIO_HAND_HOLDING_CAP] = true,
[MARIO_HAND_HOLDING_WING_CAP] = true,
[MARIO_HAND_RIGHT_OPEN] = true,
}
local sSonicHandStateActs = {
[ACT_STAR_DANCE_EXIT] = { [SONIC_HAND_LEFT] = MARIO_HAND_PEACE_SIGN, [SONIC_HAND_RIGHT] = MARIO_HAND_FISTS },
[ACT_STAR_DANCE_NO_EXIT] = { [SONIC_HAND_LEFT] = MARIO_HAND_PEACE_SIGN, [SONIC_HAND_RIGHT] = MARIO_HAND_FISTS },
}
--- @param n GraphNode | FnGraphNode
--- Switches the hand state
function geo_custom_hand_switch(n)
local switch = cast_graph_node(n)
local m = geo_get_mario_state()
local bodyState = geo_get_body_state()
local param = switch.parameter
local frame = m.marioObj.header.gfx.animInfo.animFrame
if param == WAPEACH_HAND_AXE then
if sWapeachAxeActs[m.action] or m.marioObj.header.gfx.animInfo.animID == CS_ANIM_MENU then
switch.selectedCase = 1
else
switch.selectedCase = 0
end
else
if sSonicHandStateActs[m.action] and frame >= 58 then
switch.selectedCase = sSonicHandStateActs[m.action][param]
elseif m.action == ACT_SONIC_FALL and m.actionArg >= 5 then
local animIndex = m.actionArg - 4
local handCases = {
[1] = {condition = in_between(frame, 9, 19, true), hands = {[SONIC_HAND_LEFT] = MARIO_HAND_PEACE_SIGN, [SONIC_HAND_RIGHT] = MARIO_HAND_OPEN}},
[2] = {condition = in_between(frame, 9, 22, true), hands = {[SONIC_HAND_LEFT] = MARIO_HAND_OPEN, [SONIC_HAND_RIGHT] = MARIO_HAND_OPEN}},
[4] = {condition = frame <= 26, hands = {[SONIC_HAND_LEFT] = MARIO_HAND_PEACE_SIGN, [SONIC_HAND_RIGHT] = MARIO_HAND_PEACE_SIGN}},
}
local case = handCases[animIndex]
if case and case.condition and case.hands[param] then
switch.selectedCase = case.hands[param]
else
switch.selectedCase = MARIO_HAND_FISTS
end
elseif sSonicHandCopies[bodyState.handState] then
if bodyState.handState == MARIO_HAND_OPEN or bodyState.handState == MARIO_HAND_RIGHT_OPEN then
if bodyState.handState == MARIO_HAND_OPEN then
if param == SONIC_HAND_LEFT then
switch.selectedCase = MARIO_HAND_OPEN
end
end
if bodyState.handState == MARIO_HAND_RIGHT_OPEN then
if param == SONIC_HAND_RIGHT then
switch.selectedCase = MARIO_HAND_OPEN
end
end
elseif (bodyState.action & ACT_FLAG_SWIMMING_OR_FLYING) ~= 0 then
switch.selectedCase = MARIO_HAND_OPEN
else
switch.selectedCase = bodyState.handState
end
end
end
end
-- Donkey Kong Angry Acts --
local sDonkeyKongAngryActs = {
[ACT_DONKEY_KONG_POUND] = true,
[ACT_DONKEY_KONG_POUND_HIT] = true,
}
--- @param n GraphNode | FnGraphNode
--- Switches between normal head and angry head during angry actions
function geo_custom_dk_head_switch(n)
local switch = cast_graph_node(n)
local m = geo_get_mario_state()
if sDonkeyKongAngryActs[m.action] then
switch.selectedCase = 1
else
switch.selectedCase = 0
end
end
local sDonkeyKongRollActs = {
[ACT_DONKEY_KONG_ROLL] = true,
[ACT_DONKEY_KONG_ROLL_AIR] = true,
}
--- @param n GraphNode | FnGraphNode
--- Switches between the spin and main model.
function custom_dkroll_switch(n)
local switch = cast_graph_node(n)
local m = geo_get_mario_state()
if sDonkeyKongRollActs[m.action] and (m.action ~= ACT_DONKEY_KONG_ROLL or
m.actionState ~= 0) then
switch.selectedCase = 1
else
switch.selectedCase = 0
end
end
-- Yoshi Tongue Head Switch --
--- @param n GraphNode | FnGraphNode
--- Switches Yoshi Heads
function custom_yoshi_heads(n)
local switch = cast_graph_node(n)
local m = geo_get_mario_state()
end