sm64-roblox-liberty-prime/sm64/Mario/Stationary.client.lua
2022-10-13 03:53:17 -05:00

677 lines
16 KiB
Lua

--!strict
local System = require(script.Parent)
local Animations = System.Animations
local Sounds = System.Sounds
local Enums = System.Enums
local Util = System.Util
local Action = Enums.Action
local ActionFlags = Enums.ActionFlags
local ActionGroup = Enums.ActionGroups
local AirStep = Enums.AirStep
local MarioEyes = Enums.MarioEyes
local InputFlags = Enums.InputFlags
local MarioFlags = Enums.MarioFlags
local ParticleFlags = Enums.ParticleFlags
type Mario = System.Mario
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Helpers
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local DEF_ACTION: (number, (Mario) -> boolean) -> () = System.RegisterAction
local function checkCommonIdleCancels(m: Mario)
local floor = m.Floor
if floor and floor.Normal.Y < 0.29237169 then
return m:PushOffSteepFloor(Action.FREEFALL, 0)
end
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.A_PRESSED) then
return m:SetJumpingAction(Action.JUMP, 0)
end
if m.Input:Has(InputFlags.OFF_FLOOR) then
return m:SetAction(Action.FREEFALL)
end
if m.Input:Has(InputFlags.ABOVE_SLIDE) then
return m:SetAction(Action.BEGIN_SLIDING)
end
if m.Input:Has(InputFlags.NONZERO_ANALOG) then
m.FaceAngle = Util.SetYint16(m.FaceAngle, m.IntendedYaw)
return m:SetAction(Action.WALKING)
end
if m.Input:Has(InputFlags.B_PRESSED) then
return m:SetAction(Action.PUNCHING)
end
if m.Input:Has(InputFlags.Z_DOWN) then
return m:SetAction(Action.START_CROUCHING)
end
return false
end
local function playAnimSound(m: Mario, actionState: number, animFrame: number, sound: Sound)
if m.ActionState == actionState and m.AnimFrame == animFrame then
m:PlaySound(sound)
end
end
local function stoppingStep(m: Mario, anim: Animation, action: number)
m:StationaryGroundStep()
m:SetAnimation(anim)
if m:IsAnimPastEnd() then
m:SetAction(action)
end
end
local function landingStep(m: Mario, anim: Animation, action: number)
stoppingStep(m, anim, action)
return false
end
local function checkCommonLandingCancels(m: Mario, action: number)
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.A_PRESSED) then
if action == 0 then
m:SetJumpFromLanding()
else
m:SetJumpingAction(action, 0)
end
end
if m.Input:Has(InputFlags.NONZERO_ANALOG, InputFlags.A_PRESSED, InputFlags.OFF_FLOOR, InputFlags.ABOVE_SLIDE) then
return m:CheckCommonActionExits()
end
if m.Input:Has(InputFlags.B_PRESSED) then
return m:SetAction(Action.PUNCHING)
end
return false
end
local function animatedStationaryGroundStep(m: Mario, anim: Animation, endAction: number)
m:StationaryGroundStep()
m:SetAnimation(anim)
if m:IsAnimAtEnd() then
m:SetAction(endAction)
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Actions
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
DEF_ACTION(Action.IDLE, function(m: Mario)
if not bit32.btest(m.ActionArg, 1) and m.Health < 0x300 then
return m:SetAction(Action.PANTING)
end
if checkCommonIdleCancels(m) then
return true
end
if m.ActionState == 3 then
return m:SetAction(Action.START_SLEEPING)
end
if bit32.btest(m.ActionArg, 1) then
m:SetAnimation(Animations.STAND_AGAINST_WALL)
else
if m.ActionState == 0 then
m:SetAnimation(Animations.IDLE_HEAD_LEFT)
elseif m.ActionState == 1 then
m:SetAnimation(Animations.IDLE_HEAD_RIGHT)
elseif m.ActionState == 2 then
m:SetAnimation(Animations.IDLE_HEAD_CENTER)
end
if m:IsAnimAtEnd() then
m.ActionState += 1
if m.ActionState == 3 then
local deltaYOfFloorBehindMario = m.Position.Y - m:FindFloorHeightRelativePolar(-0x8000, 60)
if 24 < math.abs(deltaYOfFloorBehindMario) then
m.ActionState = 0
else
m.ActionTimer += 1
if m.ActionTimer < 10 then
m.ActionState = 0
end
end
end
end
end
m:StationaryGroundStep()
return false
end)
DEF_ACTION(Action.START_SLEEPING, function(m: Mario)
local animFrame
if checkCommonIdleCancels(m) then
return true
end
if m.ActionState == 4 then
m:SetAction(Action.SLEEPING)
end
if m.ActionState == 0 then
animFrame = m:SetAnimation(Animations.START_SLEEP_IDLE)
elseif m.ActionState == 1 then
animFrame = m:SetAnimation(Animations.START_SLEEP_SCRATCH)
elseif m.ActionState == 2 then
animFrame = m:SetAnimation(Animations.START_SLEEP_YAWN)
m.BodyState.EyeState = MarioEyes.HALF_CLOSED
elseif m.ActionState == 3 then
animFrame = m:SetAnimation(Animations.START_SLEEP_SITTING)
m.BodyState.EyeState = MarioEyes.HALF_CLOSED
end
playAnimSound(m, 1, 41, Sounds.ACTION_PAT_BACK)
playAnimSound(m, 1, 49, Sounds.ACTION_PAT_BACK)
if m:IsAnimAtEnd() then
m.ActionState += 1
end
if m.ActionState == 2 and animFrame == -1 then
m:PlaySound(Sounds.MARIO_YAWNING)
end
if m.ActionState == 1 and animFrame == -1 then
m:PlaySound(Sounds.MARIO_IMA_TIRED)
end
m:StationaryGroundStep()
return false
end)
DEF_ACTION(Action.SLEEPING, function(m: Mario)
local animFrame
if
m.Input:Has(
InputFlags.NONZERO_ANALOG,
InputFlags.A_PRESSED,
InputFlags.OFF_FLOOR,
InputFlags.ABOVE_SLIDE,
InputFlags.FIRST_PERSON,
InputFlags.STOMPED,
InputFlags.B_PRESSED,
InputFlags.Z_PRESSED
)
then
return m:SetAction(Action.WAKING_UP, m.ActionState)
end
if m.Position.Y - m:FindFloorHeightRelativePolar(-0x8000, 60) > 24 then
return m:SetAction(Action.WAKING_UP, m.ActionState)
end
m.BodyState.EyeState = MarioEyes.CLOSED
m:StationaryGroundStep()
if m.ActionState == 0 then
animFrame = m:SetAnimation(Animations.SLEEP_IDLE)
if animFrame == 2 then
m:PlaySound(Sounds.MARIO_SNORING1)
end
if animFrame == 20 then
m:PlaySound(Sounds.MARIO_SNORING2)
end
if m:IsAnimAtEnd() then
m.ActionTimer += 1
if m.ActionTimer > 45 then
m.ActionState += 1
end
end
elseif m.ActionState == 1 then
if m:SetAnimation(Animations.SLEEP_START_LYING) == 18 then
m:PlayHeavyLandingSound(Sounds.ACTION_TERRAIN_BODY_HIT_GROUND)
end
if m:IsAnimAtEnd() then
m.ActionState += 1
end
elseif m.ActionState == 2 then
m:SetAnimation(Animations.SLEEP_LYING)
m:PlaySoundIfNoFlag(Sounds.MARIO_SNORING3, MarioFlags.ACTION_SOUND_PLAYED)
end
return false
end)
DEF_ACTION(Action.WAKING_UP, function(m: Mario)
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.OFF_FLOOR) then
return m:SetAction(Action.FREEFALL)
end
if m.Input:Has(InputFlags.ABOVE_SLIDE) then
return m:SetAction(Action.BEGIN_SLIDING)
end
m.ActionTimer += 1
if m.ActionTimer > 20 then
return m:SetAction(Action.IDLE)
end
m:StationaryGroundStep()
m:SetAnimation(if m.ActionArg == 0 then Animations.WAKE_FROM_SLEEP else Animations.WAKE_FROM_LYING)
return false
end)
DEF_ACTION(Action.STANDING_AGAINST_WALL, function(m: Mario)
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.NONZERO_ANALOG, InputFlags.A_PRESSED, InputFlags.OFF_FLOOR, InputFlags.ABOVE_SLIDE) then
return m:CheckCommonActionExits()
end
if m.Input:Has(InputFlags.B_PRESSED) then
return m:SetAction(Action.PUNCHING)
end
m:SetAnimation(Animations.A_POSE)
m:StationaryGroundStep()
return false
end)
DEF_ACTION(Action.CROUCHING, function(m: Mario)
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.A_PRESSED) then
return m:SetAction(Action.BACKFLIP)
end
if m.Input:Has(InputFlags.OFF_FLOOR) then
return m:SetAction(Action.FREEFALL)
end
if m.Input:Has(InputFlags.ABOVE_SLIDE) then
return m:SetAction(Action.BEGIN_SLIDING)
end
if not m.Input:Has(InputFlags.Z_DOWN) then
return m:SetAction(Action.STOP_CROUCHING)
end
if m.Input:Has(InputFlags.NONZERO_ANALOG) then
return m:SetAction(Action.START_CRAWLING)
end
if m.Input:Has(InputFlags.B_PRESSED) then
return m:SetAction(Action.PUNCHING, 9)
end
m:StationaryGroundStep()
m:SetAnimation(Animations.CROUCHING)
return false
end)
DEF_ACTION(Action.PANTING, function(m: Mario)
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Health >= 0x500 then
return m:SetAction(Action.IDLE)
end
if checkCommonIdleCancels(m) then
return true
end
if m:SetAnimation(Animations.PANTING) == 1 then
m:PlaySound(Sounds.MARIO_PANTING)
end
m:StationaryGroundStep()
m.BodyState.EyeState = MarioEyes.HALF_CLOSED
return false
end)
DEF_ACTION(Action.BRAKING_STOP, function(m: Mario)
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.OFF_FLOOR) then
return m:SetAction(Action.FREEFALL)
end
if m.Input:Has(InputFlags.B_PRESSED) then
return m:SetAction(Action.PUNCHING)
end
if m.Input:Has(InputFlags.NONZERO_ANALOG, InputFlags.A_PRESSED, InputFlags.OFF_FLOOR, InputFlags.ABOVE_SLIDE) then
return m:CheckCommonActionExits()
end
stoppingStep(m, Animations.STOP_SKID, Action.IDLE)
return false
end)
DEF_ACTION(Action.BUTT_SLIDE_STOP, function(m: Mario)
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.NONZERO_ANALOG, InputFlags.A_PRESSED, InputFlags.OFF_FLOOR, InputFlags.ABOVE_SLIDE) then
return m:CheckCommonActionExits()
end
stoppingStep(m, Animations.STOP_SLIDE, Action.IDLE)
if m.AnimFrame == 6 then
m:PlayLandingSound()
end
return false
end)
DEF_ACTION(Action.SLIDE_KICK_SLIDE_STOP, function(m: Mario)
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.OFF_FLOOR) then
return m:SetAction(Action.FREEFALL)
end
stoppingStep(m, Animations.CROUCH_FROM_SLIDE_KICK, Action.CROUCHING)
return false
end)
DEF_ACTION(Action.START_CROUCHING, function(m: Mario)
if m:CheckCommonActionExits() then
return true
end
m:StationaryGroundStep()
m:SetAnimation(Animations.START_CROUCHING)
if m:IsAnimPastEnd() then
m:SetAction(Action.CROUCHING)
end
return false
end)
DEF_ACTION(Action.STOP_CROUCHING, function(m: Mario)
if m:CheckCommonActionExits() then
return true
end
m:StationaryGroundStep()
m:SetAnimation(Animations.START_CROUCHING)
if m:IsAnimPastEnd() then
m:SetAction(Action.IDLE)
end
return false
end)
DEF_ACTION(Action.START_CRAWLING, function(m: Mario)
if m.Input:Has(InputFlags.OFF_FLOOR) then
return m:SetAction(Action.FREEFALL)
end
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.ABOVE_SLIDE) then
return m:SetAction(Action.BEGIN_SLIDING)
end
m:StationaryGroundStep()
m:SetAnimation(Animations.START_CRAWLING)
if m:IsAnimPastEnd() then
m:SetAction(Action.CRAWLING)
end
return false
end)
DEF_ACTION(Action.STOP_CRAWLING, function(m: Mario)
if m.Input:Has(InputFlags.OFF_FLOOR) then
return m:SetAction(Action.FREEFALL)
end
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.ABOVE_SLIDE) then
return m:SetAction(Action.BEGIN_SLIDING)
end
m:StationaryGroundStep()
m:SetAnimation(Animations.STOP_CRAWLING)
if m:IsAnimPastEnd() then
m:SetAction(Action.CROUCHING)
end
return false
end)
DEF_ACTION(Action.SHOCKWAVE_BOUNCE, function(m: Mario)
m.ActionTimer += 1
if m.ActionTimer == 48 then
m:SetAction(Action.IDLE)
end
local sp1E = bit32.lshift(m.ActionTimer % 16, 12)
local sp18 = ((6 - m.ActionTimer / 8) * 8) + 4
m:SetForwardVel(0)
m.Velocity = Vector3.zero
if Util.Sins(sp1E) >= 0 then
m.Position = Util.SetY(m.Position, Util.Sins(sp1E) * sp18 + m.FloorHeight)
else
m.Position = Util.SetY(m.Position, m.FloorHeight - Util.Sins(sp1E) * sp18)
end
m:SetAnimation(Animations.A_POSE)
return false
end)
DEF_ACTION(Action.JUMP_LAND_STOP, function(m: Mario)
if checkCommonLandingCancels(m, 0) then
return true
end
landingStep(m, Animations.LAND_FROM_SINGLE_JUMP, Action.IDLE)
return false
end)
DEF_ACTION(Action.DOUBLE_JUMP_LAND_STOP, function(m: Mario)
if checkCommonLandingCancels(m, 0) then
return true
end
landingStep(m, Animations.LAND_FROM_DOUBLE_JUMP, Action.IDLE)
return false
end)
DEF_ACTION(Action.SIDE_FLIP_LAND_STOP, function(m: Mario)
if checkCommonLandingCancels(m, 0) then
return true
end
landingStep(m, Animations.SLIDEFLIP_LAND, Action.IDLE)
return false
end)
DEF_ACTION(Action.FREEFALL_LAND_STOP, function(m: Mario)
if checkCommonLandingCancels(m, 0) then
return true
end
landingStep(m, Animations.GENERAL_LAND, Action.IDLE)
return false
end)
DEF_ACTION(Action.TRIPLE_JUMP_LAND_STOP, function(m: Mario)
if checkCommonLandingCancels(m, Action.JUMP) then
return true
end
landingStep(m, Animations.GENERAL_LAND, Action.IDLE)
return false
end)
DEF_ACTION(Action.BACKFLIP_LAND_STOP, function(m: Mario)
if not m.Input:Has(InputFlags.Z_DOWN) and m.AnimFrame >= 6 then
m.Input:Remove(InputFlags.A_PRESSED)
end
if checkCommonLandingCancels(m, Action.BACKFLIP) then
return true
end
landingStep(m, Animations.TRIPLE_JUMP_LAND, Action.IDLE)
return false
end)
DEF_ACTION(Action.LAVA_BOOST_LAND, function(m: Mario)
m.Input:Remove(InputFlags.FIRST_PERSON, InputFlags.B_PRESSED)
if checkCommonLandingCancels(m, 0) then
return true
end
landingStep(m, Animations.STAND_UP_FROM_LAVA_BOOST, Action.IDLE)
return false
end)
DEF_ACTION(Action.LONG_JUMP_LAND_STOP, function(m: Mario)
m.Input:Remove(InputFlags.B_PRESSED)
if checkCommonLandingCancels(m, Action.JUMP) then
return true
end
landingStep(
m,
if m.LongJumpIsSlow then Animations.CROUCH_FROM_FAST_LONGJUMP else Animations.CROUCH_FROM_SLOW_LONGJUMP,
Action.CROUCHING
)
return false
end)
DEF_ACTION(Action.TWIRL_LAND, function(m: Mario)
m.ActionState = 1
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.OFF_FLOOR) then
return m:SetAction(Action.FREEFALL)
end
m:StationaryGroundStep()
m:SetAnimation(Animations.TWIRL_LAND)
if m.AngleVel.Y > 0 then
m.AngleVel -= Vector3int16.new(0, 0x400, 0)
if m.AngleVel.Y < 0 then
m.AngleVel *= Vector3int16.new(1, 0, 1)
end
m.TwirlYaw += m.AngleVel.Y
end
m.GfxAngle += Vector3int16.new(0, m.TwirlYaw, 0)
if m:IsAnimAtEnd() and m.AngleVel.Y == 0 then
m.FaceAngle += Vector3int16.new(0, m.TwirlYaw, 0)
m:SetAction(Action.IDLE)
end
return false
end)
DEF_ACTION(Action.GROUND_POUND_LAND, function(m: Mario)
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.OFF_FLOOR) then
return m:SetAction(Action.FREEFALL)
end
if m.Input:Has(InputFlags.ABOVE_SLIDE) then
return m:SetAction(Action.BUTT_SLIDE)
end
landingStep(m, Animations.GROUND_POUND_LANDING, Action.BUTT_SLIDE_STOP)
return false
end)
DEF_ACTION(Action.STOMACH_SLIDE_STOP, function(m: Mario)
if m.Input:Has(InputFlags.STOMPED) then
return m:SetAction(Action.SHOCKWAVE_BOUNCE)
end
if m.Input:Has(InputFlags.OFF_FLOOR) then
return m:SetAction(Action.FREEFALL)
end
if m.Input:Has(InputFlags.ABOVE_SLIDE) then
return m:SetAction(Action.BEGIN_SLIDING)
end
animatedStationaryGroundStep(m, Animations.SLOW_LAND_FROM_DIVE, Action.IDLE)
return false
end)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------