diff --git a/sm64/Mario/Airborne.client.lua b/sm64/Mario/Airborne.client.lua deleted file mode 100644 index aab3951..0000000 --- a/sm64/Mario/Airborne.client.lua +++ /dev/null @@ -1,1296 +0,0 @@ ---!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 function stopRising(m: Mario) - if m.Velocity.Y > 0 then - m.Velocity *= Vector3.new(1, 0, 1) - end -end - -local function playFlipSounds(m: Mario, frame1: number, frame2: number, frame3: number) - local animFrame = m.AnimFrame - - if animFrame == frame1 or animFrame == frame2 or animFrame == frame3 then - m:PlaySound(Sounds.ACTION_SPIN) - end -end - -local function playFarFallSound(m: Mario) - if m.Flags:Has(MarioFlags.FALLING_FAR) then - return - end - - local action = m.Action - - if action() == Action.TWIRLING then - return - end - - if action() == Action.FLYING then - return - end - - if action:Has(ActionFlags.INVULNERABLE) then - return - end - - if m.PeakHeight - m.Position.Y > 1150 then - m:PlaySound(Sounds.MARIO_WAAAOOOW) - m.Flags:Add(MarioFlags.FALLING_FAR) - end -end - -local function playKnockbackSound(m: Mario) - if m.ActionArg == 0 and math.abs(m.ForwardVel) >= 28 then - m:PlaySoundIfNoFlag(Sounds.MARIO_DOH, MarioFlags.MARIO_SOUND_PLAYED) - else - m:PlaySoundIfNoFlag(Sounds.MARIO_UH, MarioFlags.MARIO_SOUND_PLAYED) - end -end - -local function lavaBoostOnWall(m: Mario) - local wall = m.Wall - - if wall then - local angle = Util.Atan2s(wall.Normal.Z, wall.Normal.X) - m.FaceAngle = Util.SetYint16(m.FaceAngle, angle) - end - - if m.ForwardVel < 24 then - m.ForwardVel = 24 - end - - if not m.Flags:Has(MarioFlags.METAL_CAP) then - m.HurtCounter += if m.Flags:Has(MarioFlags.CAP_ON_HEAD) then 12 else 18 - end - - m:PlaySound(Sounds.MARIO_ON_FIRE) - m:SetAction(Action.LAVA_BOOST, 1) -end - -local function checkFallDamage(m: Mario, hardFallAction: number): boolean - local fallHeight = m.PeakHeight - m.Position.Y - local damageHeight = 1150 - - if m.Action() == Action.TWIRLING then - return false - end - - if m.Velocity.Y < -55 and fallHeight > 3000 then - m.HurtCounter += if m.Flags:Has(MarioFlags.CAP_ON_HEAD) then 16 else 24 - m:PlaySound(Sounds.MARIO_ATTACKED) - m:SetAction(hardFallAction, 4) - elseif fallHeight > damageHeight and not m:FloorIsSlippery() then - m.HurtCounter += if m.Flags:Has(MarioFlags.CAP_ON_HEAD) then 8 else 12 - m:PlaySound(Sounds.MARIO_ATTACKED) - m.SquishTimer = 30 - end - - return false -end - -local function checkKickOrDiveInAir(m: Mario): boolean - if m.Input:Has(InputFlags.B_PRESSED) then - m:SetAction(if m.ForwardVel > 28 then Action.DIVE else Action.JUMP_KICK) - end - - return false -end - -local function updateAirWithTurn(m: Mario) - local dragThreshold = if m.Action() == Action.LONG_JUMP then 48 else 32 - m.ForwardVel = Util.ApproachFloat(m.ForwardVel, 0, 0.35) - - if m.Input:Has(InputFlags.NONZERO_ANALOG) then - local intendedDYaw = m.IntendedYaw - m.FaceAngle.Y - local intendedMag = m.IntendedMag / 32 - - m.ForwardVel += 1.5 * Util.Coss(intendedDYaw) * intendedMag - m.FaceAngle += Vector3int16.new(0, 512 * Util.Sins(intendedDYaw) * intendedMag, 0) - end - - if m.ForwardVel > dragThreshold then - m.ForwardVel -= 1 - end - - if m.ForwardVel < -16 then - m.ForwardVel += 2 - end - - m.SlideVelX = m.ForwardVel * Util.Sins(m.FaceAngle.Y) - m.SlideVelZ = m.ForwardVel * Util.Coss(m.FaceAngle.Y) - m.Velocity = Vector3.new(m.SlideVelX, m.Velocity.Y, m.SlideVelZ) -end - -local function updateAirWithoutTurn(m: Mario) - local dragThreshold = 32 - - if m.Action() == Action.LONG_JUMP then - dragThreshold = 48 - end - - local sidewaysSpeed = 0 - m.ForwardVel = Util.ApproachFloat(m.ForwardVel, 0, 0.35) - - if m.Input:Has(InputFlags.NONZERO_ANALOG) then - local intendedDYaw = m.IntendedYaw - m.FaceAngle.Y - local intendedMag = m.IntendedMag / 32 - - m.ForwardVel += intendedMag * Util.Coss(intendedDYaw) * 1.5 - sidewaysSpeed = intendedMag * Util.Sins(intendedDYaw) * 10 - end - - --! Uncapped air speed. Net positive when moving forward. - if m.ForwardVel > dragThreshold then - m.ForwardVel -= 1 - end - - if m.ForwardVel < -16 then - m.ForwardVel += 2 - end - - m.SlideVelX = m.ForwardVel * Util.Sins(m.FaceAngle.Y) - m.SlideVelZ = m.ForwardVel * Util.Coss(m.FaceAngle.Y) - - m.SlideVelX += sidewaysSpeed * Util.Sins(m.FaceAngle.Y + 0x4000) - m.SlideVelZ += sidewaysSpeed * Util.Coss(m.FaceAngle.Y + 0x4000) - - m.Velocity = Vector3.new(m.SlideVelX, m.Velocity.Y, m.SlideVelZ) -end - -local function updateLavaBoostOrTwirling(m: Mario) - if m.Input:Has(InputFlags.NONZERO_ANALOG) then - local intendedDYaw = m.IntendedYaw - m.FaceAngle.Y - local intendedMag = m.IntendedMag / 32 - - m.ForwardVel += Util.Coss(intendedDYaw) * intendedMag - m.FaceAngle += Vector3int16.new(0, Util.Sins(intendedDYaw) * intendedMag * 1024, 0) - - if m.ForwardVel < 0 then - m.FaceAngle += Vector3int16.new(0, 0x8000, 0) - m.ForwardVel *= -1 - end - - if m.ForwardVel > 32 then - m.ForwardVel -= 2 - end - end - - m.SlideVelX = m.ForwardVel * Util.Sins(m.FaceAngle.Y) - m.SlideVelZ = m.ForwardVel * Util.Coss(m.FaceAngle.Y) - - m.Velocity = Vector3.new(m.SlideVelX, m.Velocity.Y, m.SlideVelZ) -end - -local function updateFlyingYaw(m: Mario) - local targetYawVel = -Util.SignedShort(m.Controller.StickX * (m.ForwardVel / 4)) - - if targetYawVel > 0 then - if m.AngleVel.Y < 0 then - m.AngleVel += Vector3int16.new(0, 0x40, 0) - - if m.AngleVel.Y > 0x10 then - m.AngleVel = Util.SetYint16(m.AngleVel, 0x10) - end - else - local y = Util.ApproachInt(m.AngleVel.Y, targetYawVel, 0x10, 0x20) - m.AngleVel = Util.SetYint16(m.AngleVel, y) - end - elseif targetYawVel < 0 then - if m.AngleVel.Y > 0 then - m.AngleVel -= Vector3int16.new(0, 0x40, 0) - - if m.AngleVel.Y < -0x10 then - m.AngleVel = Util.SetYint16(m.AngleVel, -0x10) - end - else - local y = Util.ApproachInt(m.AngleVel.Y, targetYawVel, 0x20, 0x10) - m.AngleVel = Util.SetYint16(m.AngleVel, y) - end - end - - m.FaceAngle += Vector3int16.new(0, m.AngleVel.Y, 0) - m.FaceAngle = Util.SetZint16(m.FaceAngle, 20 * -m.AngleVel.Y) -end - -local function updateFlyingPitch(m: Mario) - local targetPitchVel = -Util.SignedShort(m.Controller.StickY * (m.ForwardVel / 5)) - - if targetPitchVel > 0 then - if m.AngleVel.X < 0 then - m.AngleVel += Vector3int16.new(0x40, 0, 0) - - if m.AngleVel.X > 0x20 then - m.AngleVel = Util.SetXint16(m.AngleVel, 0x20) - end - else - local x = Util.ApproachInt(m.AngleVel.X, targetPitchVel, 0x20, 0x40) - m.AngleVel = Util.SetXint16(m.AngleVel, x) - end - elseif targetPitchVel < 0 then - if m.AngleVel.X > 0 then - m.AngleVel -= Vector3int16.new(0x40, 0, 0) - - if m.AngleVel.X < -0x20 then - m.AngleVel = Util.SetXint16(m.AngleVel, -0x20) - end - else - local x = Util.ApproachInt(m.AngleVel.X, targetPitchVel, 0x40, 0x20) - m.AngleVel = Util.SetXint16(m.AngleVel, x) - end - else - local x = Util.ApproachInt(m.AngleVel.X, targetPitchVel, 0x40) - m.AngleVel = Util.SetXint16(m.AngleVel, x) - end -end - -local function updateFlying(m: Mario) - updateFlyingPitch(m) - updateFlyingYaw(m) - - m.ForwardVel -= 2 * (m.FaceAngle.X / 0x4000) + 0.1 - m.ForwardVel -= 0.5 * (1 - Util.Coss(m.AngleVel.Y)) - - if m.ForwardVel < 0 then - m.ForwardVel = 0 - end - - if m.ForwardVel > 16 then - m.FaceAngle = Util.SetXint16(m.FaceAngle, (m.ForwardVel - 32) * 6) - elseif m.ForwardVel > 4 then - m.FaceAngle = Util.SetXint16(m.FaceAngle, (m.ForwardVel - 32) * 10) - else - m.FaceAngle -= Vector3int16.new(0x400, 0, 0) - end - - m.FaceAngle += Vector3int16.new(m.AngleVel.X, 0, 0) - - if m.FaceAngle.X > 0x2AAA then - m.FaceAngle = Util.SetXint16(m.FaceAngle, 0x2AAA) - end - - if m.FaceAngle.X < -0x2AAA then - m.FaceAngle = Util.SetXint16(m.FaceAngle, -0x2AAA) - end - - local velX = Util.Coss(m.FaceAngle.X) * Util.Sins(m.FaceAngle.Y) - m.SlideVelX = velX - - local velZ = Util.Coss(m.FaceAngle.X) * Util.Coss(m.FaceAngle.Y) - m.SlideVelZ = velZ - - local velY = Util.Sins(m.FaceAngle.X) - m.Velocity = m.ForwardVel * Vector3.new(velX, velY, velZ) -end - -local function commonAirActionStep(m: Mario, landAction: number, anim: Animation, stepArg: number): number - -- stylua: ignore - local stepResult do - updateAirWithoutTurn(m) - stepResult = m:PerformAirStep(stepArg) - end - - if stepResult == AirStep.NONE then - m:SetAnimation(anim) - elseif stepResult == AirStep.LANDED then - if not checkFallDamage(m, Action.HARD_BACKWARD_GROUND_KB) then - m:SetAction(landAction) - end - elseif stepResult == AirStep.HIT_WALL then - m:SetAnimation(anim) - - if m.ForwardVel > 16 then - m:BonkReflection() - m.FaceAngle += Vector3int16.new(0, 0x8000, 0) - - if m.Wall then - m:SetAction(Action.AIR_HIT_WALL) - else - stopRising(m) - - if m.ForwardVel >= 38 then - m.ParticleFlags:Add(ParticleFlags.VERTICAL_STAR) - m:SetAction(Action.BACKWARD_AIR_KB) - else - if m.ForwardVel > 8 then - m:SetForwardVel(-8) - end - - m:SetAction(Action.SOFT_BONK) - end - end - else - m:SetForwardVel(0) - end - elseif stepResult == AirStep.GRABBED_LEDGE then - m:SetAnimation(Animations.IDLE_ON_LEDGE) - m:SetAction(Action.LEDGE_GRAB) - elseif stepResult == AirStep.GRABBED_CEILING then - m:SetAction(Action.START_HANGING) - elseif stepResult == AirStep.HIT_LAVA_WALL then - lavaBoostOnWall(m) - end - - return stepResult -end - -local function commonRolloutStep(m: Mario, anim: Animation) - local stepResult - - if m.ActionState == 0 then - m.Velocity = Util.SetY(m.Velocity, 30) - m.ActionState = 1 - end - - m:PlaySound(Sounds.ACTION_TERRAIN_JUMP) - updateAirWithoutTurn(m) - - stepResult = m:PerformAirStep() - - if stepResult == AirStep.NONE then - if m.ActionState == 1 then - if m:SetAnimation(anim) == 4 then - m:PlaySound(Sounds.ACTION_SPIN) - end - else - m:SetAnimation(Animations.GENERAL_FALL) - end - elseif stepResult == AirStep.LANDED then - m:SetAction(Action.FREEFALL_LAND_STOP) - m:PlayLandingSound() - elseif stepResult == AirStep.HIT_WALL then - m:SetForwardVel(0) - elseif stepResult == AirStep.HIT_LAVA_WALL then - lavaBoostOnWall(m) - end - - if m.ActionState == 1 and m:IsAnimPastEnd() then - m.ActionState = 2 - end -end - -local function commonAirKnockbackStep( - m: Mario, - landAction: number, - hardFallAction: number, - anim: Animation, - speed: number -) - -- stylua: ignore - local stepResult do - m:SetForwardVel(speed) - stepResult = m:PerformAirStep() - end - - if stepResult == AirStep.NONE then - m:SetAnimation(anim) - elseif stepResult == AirStep.LANDED then - if not checkFallDamage(m, hardFallAction) then - local action = m.Action() - - if action == Action.THROWN_FORWARD or action == Action.THROWN_BACKWARD then - m:SetAction(landAction, m.HurtCounter) - else - m:SetAction(landAction, m.ActionArg) - end - end - elseif stepResult == AirStep.HIT_WALL then - m:SetAnimation(Animations.BACKWARD_AIR_KB) - m:BonkReflection() - - stopRising(m) - m:SetForwardVel(-speed) - elseif stepResult == AirStep.HIT_LAVA_WALL then - lavaBoostOnWall(m) - end - - return stepResult -end - -local function checkWallKick(m: Mario) - if m.WallKickTimer ~= 0 then - if m.Input:Has(InputFlags.A_PRESSED) then - if m.PrevAction() == Action.AIR_HIT_WALL then - m.FaceAngle += Vector3int16.new(0, 0x8000, 0) - end - end - end - - return false -end - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ --- Actions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - -local AIR_STEP_CHECK_BOTH = bit32.bor(AirStep.CHECK_LEDGE_GRAB, AirStep.CHECK_HANG) -local DEF_ACTION: (number, (Mario) -> boolean) -> () = System.RegisterAction - -DEF_ACTION(Action.JUMP, function(m: Mario) - if checkKickOrDiveInAir(m) then - return true - end - - if m.Input:Has(InputFlags.Z_PRESSED) then - return m:SetAction(Action.GROUND_POUND) - end - - m:PlayMarioSound(Sounds.ACTION_TERRAIN_JUMP) - commonAirActionStep(m, Action.JUMP_LAND, Animations.SINGLE_JUMP, AIR_STEP_CHECK_BOTH) - - return false -end) - -DEF_ACTION(Action.DOUBLE_JUMP, function(m: Mario) - local anim = if m.Velocity.Y >= 0 then Animations.DOUBLE_JUMP_RISE else Animations.DOUBLE_JUMP_FALL - - if checkKickOrDiveInAir(m) then - return true - end - - if m.Input:Has(InputFlags.Z_PRESSED) then - return m:SetAction(Action.GROUND_POUND) - end - - m:PlayMarioSound(Sounds.ACTION_TERRAIN_JUMP, Sounds.MARIO_HOOHOO) - commonAirActionStep(m, Action.DOUBLE_JUMP_LAND, anim, AIR_STEP_CHECK_BOTH) - - return false -end) - -DEF_ACTION(Action.TRIPLE_JUMP, function(m: Mario) - if m.Input:Has(InputFlags.B_PRESSED) then - return m:SetAction(Action.DIVE) - end - - if m.Input:Has(InputFlags.Z_PRESSED) then - return m:SetAction(Action.GROUND_POUND) - end - - m:PlayMarioSound(Sounds.ACTION_TERRAIN_JUMP) - commonAirActionStep(m, Action.TRIPLE_JUMP_LAND, Animations.TRIPLE_JUMP, 0) - - playFlipSounds(m, 2, 8, 20) - return false -end) - -DEF_ACTION(Action.BACKFLIP, function(m: Mario) - if m.Input:Has(InputFlags.Z_PRESSED) then - return m:SetAction(Action.GROUND_POUND) - end - - m:PlayMarioSound(Sounds.ACTION_TERRAIN_JUMP, Sounds.MARIO_YAH_WAH_HOO) - commonAirActionStep(m, Action.BACKFLIP_LAND, Animations.BACKFLIP, 0) - - playFlipSounds(m, 2, 3, 17) - return false -end) - -DEF_ACTION(Action.FREEFALL, function(m: Mario) - if m.Input:Has(InputFlags.B_PRESSED) then - return m:SetAction(Action.DIVE) - end - - if m.Input:Has(InputFlags.Z_PRESSED) then - return m:SetAction(Action.GROUND_POUND) - end - - local anim - - if m.ActionArg == 0 then - anim = Animations.GENERAL_FALL - elseif m.ActionArg == 1 then - anim = Animations.FALL_FROM_SLIDE - elseif m.ActionArg == 2 then - anim = Animations.FALL_FROM_SLIDE_KICK - end - - commonAirActionStep(m, Action.FREEFALL_LAND, anim, AirStep.CHECK_LEDGE_GRAB) - return false -end) - -DEF_ACTION(Action.SIDE_FLIP, function(m: Mario) - if m.Input:Has(InputFlags.B_PRESSED) then - return m:SetAction(Action.DIVE) - end - - if m.Input:Has(InputFlags.Z_PRESSED) then - return m:SetAction(Action.GROUND_POUND) - end - - m:PlayMarioSound(Sounds.ACTION_TERRAIN_JUMP) - commonAirActionStep(m, Action.SIDE_FLIP_LAND, Animations.SLIDEFLIP, AirStep.CHECK_LEDGE_GRAB) - - if m.AnimFrame == 6 then - m:PlaySound(Sounds.ACTION_SIDE_FLIP) - end - - return false -end) - -DEF_ACTION(Action.WALL_KICK_AIR, function(m: Mario) - if m.Input:Has(InputFlags.B_PRESSED) then - return m:SetAction(Action.DIVE) - end - - if m.Input:Has(InputFlags.Z_PRESSED) then - return m:SetAction(Action.GROUND_POUND) - end - - m:PlayJumpSound() - commonAirActionStep(m, Action.JUMP_LAND, Animations.SLIDEJUMP, AirStep.CHECK_LEDGE_GRAB) - - return false -end) - -DEF_ACTION(Action.LONG_JUMP, function(m: Mario) - local anim = if m.LongJumpIsSlow then Animations.SLOW_LONGJUMP else Animations.FAST_LONGJUMP - - m:PlayMarioSound(Sounds.ACTION_TERRAIN_JUMP, Sounds.MARIO_YAHOO) - commonAirActionStep(m, Action.LONG_JUMP_LAND, anim, AirStep.CHECK_LEDGE_GRAB) - - return false -end) - -DEF_ACTION(Action.TWIRLING, function(m: Mario) - local startTwirlYaw = m.TwirlYaw - local yawVelTarget = 0x1000 - - if m.Input:Has(InputFlags.A_DOWN) then - yawVelTarget = 0x2000 - end - - local yVel = Util.ApproachInt(m.AngleVel.Y, yawVelTarget, 0x200) - m.AngleVel = Util.SetYint16(m.AngleVel, yVel) - m.TwirlYaw += yVel - - m:SetAnimation(if m.ActionArg == 0 then Animations.START_TWIRL else Animations.TWIRL) - - if m:IsAnimPastEnd() then - m.ActionArg = 1 - end - - if startTwirlYaw > m.TwirlYaw then - m:PlaySound(Sounds.ACTION_TWIRL) - end - - local step = m:PerformAirStep() - - if step == AirStep.LANDED then - m:SetAction(Action.TWIRL_LAND) - elseif step == AirStep.HIT_WALL then - m:BonkReflection(false) - elseif step == AirStep.HIT_LAVA_WALL then - lavaBoostOnWall(m) - end - - m.GfxAngle += Vector3int16.new(0, m.TwirlYaw, 0) - return false -end) - -DEF_ACTION(Action.DIVE, function(m: Mario) - local airStep - - if m.ActionArg == 0 then - m:PlayMarioSound(Sounds.ACTION_THROW, Sounds.MARIO_HOOHOO) - else - m:PlayMarioSound(Sounds.ACTION_TERRAIN_JUMP) - end - - m:SetAnimation(Animations.DIVE) - updateAirWithoutTurn(m) - airStep = m:PerformAirStep() - - if airStep == AirStep.NONE then - if m.Velocity.Y < 0 and m.FaceAngle.X > -0x2AAA then - m.FaceAngle -= Vector3int16.new(0x200, 0, 0) - - if m.FaceAngle.X < -0x2AAA then - m.FaceAngle = Util.SetXint16(m.FaceAngle, -0x2AAA) - end - end - - m.GfxAngle = Util.SetXint16(m.GfxAngle, -m.FaceAngle.X) - elseif airStep == AirStep.LANDED then - if not checkFallDamage(m, Action.HARD_FORWARD_GROUND_KB) then - m:SetAction(Action.DIVE_SLIDE) - end - - m.FaceAngle *= Vector3int16.new(0, 1, 1) - elseif airStep == AirStep.HIT_WALL then - m:BonkReflection(true) - m.FaceAngle *= Vector3int16.new(0, 1, 1) - - stopRising(m) - - m.ParticleFlags:Add(ParticleFlags.VERTICAL_STAR) - m:SetAction(Action.BACKWARD_AIR_KB) - elseif airStep == AirStep.HIT_LAVA_WALL then - lavaBoostOnWall(m) - end - - return false -end) - -DEF_ACTION(Action.STEEP_JUMP, function(m: Mario) - local airStep - - if m.Input:Has(InputFlags.B_PRESSED) then - return m:SetAction(Action.DIVE) - end - - m:PlayMarioSound(Sounds.ACTION_TERRAIN_JUMP) - m:SetForwardVel(0.98 * m.ForwardVel) - airStep = m:PerformAirStep() - - if airStep == AirStep.LANDED then - if not checkFallDamage(m, Action.HARD_BACKWARD_GROUND_KB) then - m.FaceAngle *= Vector3int16.new(0, 1, 1) - m:SetAction(if m.ForwardVel < 0 then Action.BEGIN_SLIDING else Action.JUMP_LAND) - end - elseif airStep == AirStep.HIT_WALL then - m:SetForwardVel(0) - elseif airStep == AirStep.HIT_LAVA_WALL then - lavaBoostOnWall(m) - end - - m:SetAnimation(Animations.SINGLE_JUMP) - m.GfxAngle = Util.SetYint16(m.GfxAngle, m.SteepJumpYaw) - - return false -end) - -DEF_ACTION(Action.GROUND_POUND, function(m: Mario) - local stepResult - local yOffset - - m:PlaySoundIfNoFlag(Sounds.ACTION_THROW, MarioFlags.ACTION_SOUND_PLAYED) - - if m.ActionState == 0 then - if m.ActionTimer < 10 then - yOffset = 20 - 2 * m.ActionTimer - - if m.Position.Y + yOffset + 160 < m.CeilHeight then - m.Position += Vector3.new(0, yOffset, 0) - m.PeakHeight = m.Position.Y - end - end - - m.Velocity = Util.SetY(m.Velocity, -50) - m:SetForwardVel(0) - - -- stylua: ignore - m:SetAnimation(if m.ActionArg == 0 - then Animations.START_GROUND_POUND - else Animations.TRIPLE_JUMP_GROUND_POUND) - - if m.ActionTimer == 0 then - m:PlaySound(Sounds.ACTION_SPIN) - end - - m.ActionTimer += 1 - m.GfxAngle = Vector3int16.new(0, m.FaceAngle.Y, 0) - - if m.ActionTimer >= m.AnimFrameCount + 4 then - m:PlaySound(Sounds.MARIO_GROUND_POUND_WAH) - m.ActionState = 1 - end - else - m:SetAnimation(Animations.GROUND_POUND) - stepResult = m:PerformAirStep() - - if stepResult == AirStep.LANDED then - m:PlayHeavyLandingSound(Sounds.ACTION_HEAVY_LANDING) - - if not checkFallDamage(m, Action.HARD_BACKWARD_GROUND_KB) then - m.ParticleFlags:Add(ParticleFlags.MIST_CIRCLE, ParticleFlags.HORIZONTAL_STAR) - m:SetAction(Action.GROUND_POUND_LAND) - end - elseif stepResult == AirStep.HIT_WALL then - m:SetForwardVel(-16) - stopRising(m) - - m.ParticleFlags:Add(ParticleFlags.VERTICAL_STAR) - m:SetAction(Action.BACKWARD_AIR_KB) - end - end - - return false -end) - -DEF_ACTION(Action.BURNING_JUMP, function(m: Mario) - m:PlayMarioSound(Sounds.ACTION_TERRAIN_JUMP) - m:SetForwardVel(m.ForwardVel) - - if m:PerformAirStep() == AirStep.LANDED then - m:PlayLandingSound() - m:SetAction(Action.BURNING_GROUND) - end - - m:SetAnimation(Animations.GENERAL_FALL) - m.ParticleFlags:Add(ParticleFlags.FIRE) - m:PlaySound(Sounds.MOVING_LAVA_BURN) - - m.BurnTimer += 3 - m.Health -= 10 - - if m.Health < 0x100 then - m.Health = 0xFF - end - - return false -end) - -DEF_ACTION(Action.BURNING_FALL, function(m: Mario) - m:SetForwardVel(m.ForwardVel) - - if m:PerformAirStep() == AirStep.LANDED then - m:PlayLandingSound(Sounds.ACTION_TERRAIN_LANDING) - m:SetAction(Action.BURNING_GROUND) - end - - m:SetAnimation(Animations.GENERAL_FALL) - m.ParticleFlags:Add(ParticleFlags.FIRE) - - m.BurnTimer += 3 - m.Health -= 10 - - if m.Health < 0x100 then - m.Health = 0xFF - end - - return false -end) - -DEF_ACTION(Action.BACKWARD_AIR_KB, function(m: Mario) - if checkWallKick(m) then - return true - end - - playKnockbackSound(m) - commonAirKnockbackStep( - m, - Action.BACKWARD_GROUND_KB, - Action.HARD_BACKWARD_GROUND_KB, - Animations.BACKWARD_AIR_KB, - -16 - ) - - return false -end) - -DEF_ACTION(Action.FORWARD_AIR_KB, function(m: Mario) - if checkWallKick(m) then - return true - end - - playKnockbackSound(m) - commonAirKnockbackStep(m, Action.FORWARD_GROUND_KB, Action.HARD_FORWARD_GROUND_KB, Animations.FORWARD_AIR_KB, 16) - - return false -end) - -DEF_ACTION(Action.HARD_BACKWARD_AIR_KB, function(m: Mario) - if checkWallKick(m) then - return true - end - - playKnockbackSound(m) - commonAirKnockbackStep( - m, - Action.HARD_BACKWARD_GROUND_KB, - Action.HARD_BACKWARD_GROUND_KB, - Animations.BACKWARD_AIR_KB, - -16 - ) - - return false -end) - -DEF_ACTION(Action.HARD_FORWARD_AIR_KB, function(m: Mario) - if checkWallKick(m) then - return true - end - - playKnockbackSound(m) - commonAirKnockbackStep( - m, - Action.HARD_FORWARD_GROUND_KB, - Action.HARD_FORWARD_GROUND_KB, - Animations.FORWARD_AIR_KB, - 16 - ) - - return false -end) - -DEF_ACTION(Action.THROWN_BACKWARD, function(m: Mario) - local landAction = if m.ActionArg ~= 0 then Action.HARD_BACKWARD_GROUND_KB else Action.BACKWARD_GROUND_KB - - m:PlaySoundIfNoFlag(Sounds.MARIO_WAAAOOOW, MarioFlags.MARIO_SOUND_PLAYED) - commonAirKnockbackStep(m, landAction, Action.HARD_BACKWARD_GROUND_KB, Animations.BACKWARD_AIR_KB, m.ForwardVel) - - m.ForwardVel *= 0.98 - return false -end) - -DEF_ACTION(Action.THROWN_FORWARD, function(m: Mario) - local landAction = if m.ActionArg ~= 0 then Action.HARD_FORWARD_GROUND_KB else Action.FORWARD_GROUND_KB - - m:PlaySoundIfNoFlag(Sounds.MARIO_WAAAOOOW, MarioFlags.MARIO_SOUND_PLAYED) - - if - commonAirKnockbackStep(m, landAction, Action.HARD_FORWARD_GROUND_KB, Animations.FORWARD_AIR_KB, m.ForwardVel) - == AirStep.NONE - then - local pitch = Util.Atan2s(m.ForwardVel, -m.Velocity.Y) - - if pitch > 0x1800 then - pitch = 0x1800 - end - - m.GfxAngle = Util.SetXint16(m.GfxAngle, pitch + 0x1800) - end - - m.ForwardVel *= 0.98 - return false -end) - -DEF_ACTION(Action.SOFT_BONK, function(m: Mario) - if checkWallKick(m) then - return true - end - - playKnockbackSound(m) - commonAirKnockbackStep( - m, - Action.FREEFALL_LAND, - Action.HARD_BACKWARD_GROUND_KB, - Animations.GENERAL_FALL, - m.ForwardVel - ) - - return false -end) - -DEF_ACTION(Action.AIR_HIT_WALL, function(m: Mario) - m.ActionTimer += 1 - - if m.ActionTimer <= 2 then - if m.Input:Has(InputFlags.A_PRESSED) then - m.Velocity = Util.SetY(m.Velocity, 52) - m.FaceAngle += Vector3int16.new(0, 0x8000, 0) - return m:SetAction(Action.WALL_KICK_AIR) - end - else - m.WallKickTimer = 5 - stopRising(m) - - if m.ForwardVel >= 38 then - m.ParticleFlags:Add(ParticleFlags.VERTICAL_STAR) - return m:SetAction(Action.BACKWARD_AIR_KB) - elseif m.ForwardVel > 8 then - m:SetForwardVel(-8) - return m:SetAction(Action.SOFT_BONK) - end - end - - m:SetAnimation(Animations.START_WALLKICK) - return true -end) - -DEF_ACTION(Action.FORWARD_ROLLOUT, function(m: Mario) - commonRolloutStep(m, Animations.FORWARD_SPINNING) - return false -end) - -DEF_ACTION(Action.BACKWARD_ROLLOUT, function(m: Mario) - commonRolloutStep(m, Animations.BACKWARD_SPINNING) - return false -end) - -DEF_ACTION(Action.BUTT_SLIDE_AIR, function(m: Mario) - local stepResult - m.ActionTimer += 1 - - if m.ActionTimer > 30 and m.Position.Y - m.FloorHeight > 500 then - return m:SetAction(Action.FREEFALL, 1) - end - - updateAirWithTurn(m) - stepResult = m:PerformAirStep() - - if stepResult == AirStep.LANDED then - if m.ActionState == 0 and m.Velocity.Y < 0 then - local floor = m.Floor - - if floor and floor.Normal.Y > 0.9848077 then - m.Velocity *= Vector3.new(1, -0.5, 1) - m.ActionState = 1 - else - m:SetAction(Action.BUTT_SLIDE) - end - else - m:SetAction(Action.BUTT_SLIDE) - end - - m:PlayLandingSound() - elseif stepResult == AirStep.HIT_WALL then - stopRising(m) - m.ParticleFlags:Add(ParticleFlags.VERTICAL_STAR) - m:SetAction(Action.BACKWARD_AIR_KB) - elseif stepResult == AirStep.HIT_LAVA_WALL then - lavaBoostOnWall(m) - end - - m:SetAnimation(Animations.SLIDE) - return false -end) - -DEF_ACTION(Action.LAVA_BOOST, function(m: Mario) - local stepResult - m:PlaySoundIfNoFlag(Sounds.MARIO_ON_FIRE, MarioFlags.MARIO_SOUND_PLAYED) - - if not m.Input:Has(InputFlags.NONZERO_ANALOG) then - m.ForwardVel = Util.ApproachFloat(m.ForwardVel, 0, 0.35) - end - - updateLavaBoostOrTwirling(m) - stepResult = m:PerformAirStep() - - if stepResult == AirStep.LANDED then - local floor = m.Floor - local floorType: Enum.Material? - - if floor then - floorType = floor.Material - end - - if floorType == Enum.Material.CrackedLava then - m.ActionState = 0 - - if not m.Flags:Has(MarioFlags.METAL_CAP) then - m.HurtCounter += if m.Flags:Has(MarioFlags.CAP_ON_HEAD) then 12 else 18 - end - - m.Velocity = Util.SetY(m.Velocity, 84) - m:PlaySound(Sounds.MARIO_ON_FIRE) - else - m:PlayHeavyLandingSound(Sounds.ACTION_TERRAIN_BODY_HIT_GROUND) - - if m.ActionState < 2 and m.Velocity.Y < 0 then - m.Velocity *= Vector3.new(1, -0.4, 1) - m:SetForwardVel(m.ForwardVel / 2) - m.ActionState += 1 - else - m:SetAction(Action.LAVA_BOOST_LAND) - end - end - elseif stepResult == AirStep.HIT_WALL then - m:BonkReflection() - elseif stepResult == AirStep.HIT_LAVA_WALL then - lavaBoostOnWall(m) - end - - m:SetAnimation(Animations.FIRE_LAVA_BURN) - - if not m.Flags:Has(MarioFlags.METAL_CAP) and m.Velocity.Y > 0 then - m.ParticleFlags:Add(ParticleFlags.FIRE) - - if m.ActionState == 0 then - m:PlaySound(Sounds.MOVING_LAVA_BURN) - end - end - - m.BodyState.EyeState = MarioEyes.DEAD - return false -end) - -DEF_ACTION(Action.SLIDE_KICK, function(m: Mario) - local stepResult - - if m.ActionState == 0 and m.ActionTimer == 0 then - m:PlayMarioSound(Sounds.ACTION_TERRAIN_JUMP, Sounds.MARIO_HOOHOO) - m:SetAnimation(Animations.SLIDE_KICK) - end - - m.ActionTimer += 1 - - if m.ActionTimer > 30 and m.Position.Y - m.FloorHeight > 500 then - return m:SetAction(Action.FREEFALL, 2) - end - - updateAirWithoutTurn(m) - stepResult = m:PerformAirStep() - - if stepResult == AirStep.NONE then - if m.ActionState == 0 then - local tilt = Util.Atan2s(m.ForwardVel, -m.Velocity.Y) - - if tilt > 0x1800 then - tilt = 0x1800 - end - - m.GfxAngle = Util.SetXint16(m.GfxAngle, tilt) - end - elseif stepResult == AirStep.LANDED then - if m.ActionState == 0 and m.Velocity.Y < 0 then - m.Velocity *= Vector3.new(1, -0.5, 1) - m.ActionState = 1 - m.ActionTimer = 0 - else - m:SetAction(Action.SLIDE_KICK_SLIDE) - end - - m:PlayLandingSound() - elseif stepResult == AirStep.HIT_WALL then - stopRising(m) - m.ParticleFlags:Add(ParticleFlags.VERTICAL_STAR) - m:SetAction(Action.BACKWARD_AIR_KB) - elseif stepResult == AirStep.HIT_LAVA_WALL then - lavaBoostOnWall(m) - end - - return false -end) - -DEF_ACTION(Action.JUMP_KICK, function(m: Mario) - local stepResult - - if m.ActionState == 0 then - m:PlaySoundIfNoFlag(Sounds.MARIO_PUNCH_HOO, MarioFlags.ACTION_SOUND_PLAYED) - m.AnimReset = true - - m:SetAnimation(Animations.AIR_KICK) - m.ActionState = 1 - end - - local animFrame = m.AnimFrame - - if animFrame == 0 then - m.BodyState.PunchType = 2 - m.BodyState.PunchTimer = 6 - end - - if animFrame >= 0 and animFrame < 8 then - m.Flags:Add(MarioFlags.KICKING) - end - - updateAirWithoutTurn(m) - stepResult = m:PerformAirStep() - - if stepResult == AirStep.LANDED then - if not checkFallDamage(m, Action.HARD_BACKWARD_GROUND_KB) then - m:SetAction(Action.FREEFALL_LAND) - end - elseif stepResult == AirStep.HIT_WALL then - m:SetForwardVel(0) - end - - return false -end) - -DEF_ACTION(Action.FLYING, function(m: Mario) - local startPitch = m.FaceAngle.X - - if m.Input:Has(InputFlags.Z_PRESSED) then - return m:SetAction(Action.GROUND_POUND) - end - - if not m.Flags:Has(MarioFlags.WING_CAP) then - return m:SetAction(Action.FREEFALL) - end - - if m.ActionState == 0 then - if m.ActionArg == 0 then - m:SetAnimation(Animations.FLY_FROM_CANNON) - else - m:SetAnimation(Animations.FORWARD_SPINNING_FLIP) - - if m.AnimFrame == 1 then - m:PlaySound(Sounds.ACTION_SPIN) - end - end - - if m:IsAnimAtEnd() then - m:SetAnimation(Animations.WING_CAP_FLY) - m.ActionState = 1 - end - end - - local stepResult - do - updateFlying(m) - stepResult = m:PerformAirStep() - end - - if stepResult == AirStep.NONE then - local faceAngle = m.FaceAngle - m.GfxAngle = Util.SetXint16(m.GfxAngle, -m.FaceAngle.X) - m.GfxAngle = Util.SetZint16(m.GfxAngle, m.FaceAngle.Z) - m.ActionTimer = 0 - elseif stepResult == AirStep.LANDED then - m:SetAction(Action.DIVE_SLIDE) - m:SetAnimation(Animations.DIVE) - - m:SetAnimToFrame(7) - m.FaceAngle *= Vector3int16.new(0, 1, 1) - elseif stepResult == AirStep.HIT_WALL then - if m.Wall then - m:SetForwardVel(-16) - m.FaceAngle *= Vector3int16.new(0, 1, 1) - - stopRising(m) - m:PlaySound(if m.Flags:Has(MarioFlags.METAL_CAP) then Sounds.ACTION_METAL_BONK else Sounds.ACTION_BONK) - - m.ParticleFlags:Add(ParticleFlags.VERTICAL_STAR) - m:SetAction(Action.BACKWARD_AIR_KB) - else - m.ActionTimer += 1 - - if m.ActionTimer == 0 then - m:PlaySound(Sounds.ACTION_HIT) - end - - if m.ActionTimer == 30 then - m.ActionTimer = 0 - end - - m.FaceAngle -= Vector3int16.new(0x200, 0, 0) - - if m.FaceAngle.X < -0x2AAA then - m.FaceAngle = Util.SetXint16(m.FaceAngle, -0x2AAA) - end - - m.GfxAngle = Util.SetXint16(m.GfxAngle, -m.FaceAngle.X) - m.GfxAngle = Util.SetZint16(m.GfxAngle, m.FaceAngle.Z) - end - elseif stepResult == AirStep.HIT_LAVA_WALL then - lavaBoostOnWall(m) - end - - if m.FaceAngle.X > 0x800 and m.ForwardVel >= 48 then - m.ParticleFlags:Add(ParticleFlags.DUST) - end - - if startPitch <= 0 and m.FaceAngle.X > 0 and m.ForwardVel >= 48 then - m:PlaySound(Sounds.ACTION_FLYING_FAST) - m:PlaySound(Sounds.MARIO_YAHOO_WAHA_YIPPEE) - end - - m:PlaySound(Sounds.MOVING_FLYING) - m:AdjustSoundForSpeed() - - return false -end) - -DEF_ACTION(Action.FLYING_TRIPLE_JUMP, function(m: Mario) - if m.Input:Has(InputFlags.B_PRESSED) then - return m:SetAction(Action.DIVE) - end - - if m.Input:Has(InputFlags.Z_PRESSED) then - return m:SetAction(Action.GROUND_POUND) - end - - m:PlayMarioSound(Sounds.ACTION_TERRAIN_JUMP, Sounds.MARIO_YAHOO) - - if m.ActionState == 0 then - m:SetAnimation(Animations.TRIPLE_JUMP_FLY) - - if m.AnimFrame == 7 then - m:PlaySound(Sounds.ACTION_SPIN) - end - - if m:IsAnimPastEnd() then - m:SetAnimation(Animations.FORWARD_SPINNING) - m.ActionState = 1 - end - end - - if m.ActionState == 1 and m.AnimFrame == 1 then - m:PlaySound(Sounds.ACTION_SPIN) - end - - if m.Velocity.Y < 4 then - if m.ForwardVel < 32 then - m:SetForwardVel(32) - end - - m:SetAction(Action.FLYING, 1) - end - - m.ActionTimer += 1 - - local stepResult - do - updateAirWithoutTurn(m) - stepResult = m:PerformAirStep() - end - - if stepResult == AirStep.LANDED then - if not checkFallDamage(m, Action.HARD_BACKWARD_GROUND_KB) then - m:SetAction(Action.DOUBLE_JUMP_LAND) - end - elseif stepResult == AirStep.HIT_WALL then - m:BonkReflection() - elseif stepResult == AirStep.HIT_LAVA_WALL then - lavaBoostOnWall(m) - end - - return false -end) - -DEF_ACTION(Action.SPAWN_SPIN_AIRBORNE, function(m: Mario) - m:SetForwardVel(m.ForwardVel) - - if m:PerformAirStep() == AirStep.LANDED then - m:PlayLandingSound(Sounds.ACTION_TERRAIN_LANDING) - m:SetAction(Action.SPAWN_SPIN_LANDING) - end - - if m.ActionState == 0 and m.Position.Y - m.FloorHeight > 300 then - if m:SetAnimation(Animations.FORWARD_SPINNING) == 0 then - m:PlaySound(Sounds.ACTION_SPIN) - end - else - m.ActionState = 1 - m:SetAnimation(Animations.GENERAL_FALL) - end - - return false -end) - -DEF_ACTION(Action.SPAWN_SPIN_LANDING, function(m: Mario) - m:StopAndSetHeightToFloor() - m:SetAnimation(Animations.GENERAL_LAND) - - if m:IsAnimAtEnd() then - m:SetAction(Action.IDLE) - end - - return false -end) - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ diff --git a/sm64/Mario/Moving.client.lua b/sm64/Mario/Moving.client.lua deleted file mode 100644 index dc7bd9f..0000000 --- a/sm64/Mario/Moving.client.lua +++ /dev/null @@ -1,1497 +0,0 @@ ---!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 MarioEyes = Enums.MarioEyes -local GroundStep = Enums.GroundStep -local InputFlags = Enums.InputFlags -local MarioFlags = Enums.MarioFlags -local SurfaceClass = Enums.SurfaceClass -local ParticleFlags = Enums.ParticleFlags - -type Mario = System.Mario - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ --- Landing Actions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - -type LandingAction = { - NumFrames: number, - JumpTimer: number, - EndAction: number, - APressedAction: number, -} - -local sJumpLandAction: LandingAction = { - NumFrames = 4, - JumpTimer = 5, - - EndAction = Action.JUMP_LAND_STOP, - APressedAction = Action.DOUBLE_JUMP, -} - -local sFreefallLandAction: LandingAction = { - NumFrames = 4, - JumpTimer = 5, - - EndAction = Action.FREEFALL_LAND_STOP, - APressedAction = Action.DOUBLE_JUMP, -} - -local sSideFlipLandAction: LandingAction = { - NumFrames = 4, - JumpTimer = 5, - - EndAction = Action.SIDE_FLIP_LAND_STOP, - APressedAction = Action.DOUBLE_JUMP, -} - -local sLongJumpLandAction: LandingAction = { - NumFrames = 6, - JumpTimer = 5, - - EndAction = Action.LONG_JUMP_LAND_STOP, - APressedAction = Action.LONG_JUMP, -} - -local sDoubleJumpLandAction: LandingAction = { - NumFrames = 4, - JumpTimer = 5, - - EndAction = Action.DOUBLE_JUMP_LAND_STOP, - APressedAction = Action.JUMP, -} - -local sTripleJumpLandAction: LandingAction = { - NumFrames = 4, - JumpTimer = 0, - - EndAction = Action.TRIPLE_JUMP_LAND_STOP, - APressedAction = Action.UNINITIALIZED, -} - -local sBackflipLandAction: LandingAction = { - NumFrames = 4, - JumpTimer = 0, - - EndAction = Action.BACKFLIP_LAND_STOP, - APressedAction = Action.BACKFLIP, -} - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ --- Helpers ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - -local DEF_ACTION: (number, (Mario) -> boolean) -> () = System.RegisterAction -local sPunchingForwardVelocities = { 0, 1, 1, 2, 3, 5, 7, 10 } - -local function tiltBodyRunning(m: Mario) - local pitch = m:FindFloorSlope(0) - pitch = pitch * m.ForwardVel / 40 - - return -pitch -end - -local function playStepSound(m: Mario, frame1: number, frame2: number) - if m:IsAnimPastFrame(frame1) or m:IsAnimPastFrame(frame2) then - if m.Flags:Has(MarioFlags.METAL_CAP) then - m:PlaySoundAndSpawnParticles(Sounds.ACTION_METAL_STEP, 0) - else - m:PlaySoundAndSpawnParticles(Sounds.ACTION_TERRAIN_STEP, 0) - end - end -end - -local function alignWithFloor(m: Mario) - local pos = Util.SetY(m.Position, m.FloorHeight) - m.Position = pos - - local radius = 40 - local minY = -radius * 3 - local yaw = m.FaceAngle.Y - - local p0_x = pos.X + radius * Util.Sins(yaw + 0x2AAA) - local p0_z = pos.Z + radius * Util.Coss(yaw + 0x2AAA) - - local p1_x = pos.X + radius * Util.Sins(yaw + 0x8000) - local p1_z = pos.Z + radius * Util.Coss(yaw + 0x8000) - - local p2_x = pos.X + radius * Util.Sins(yaw + 0xD555) - local p2_z = pos.Z + radius * Util.Coss(yaw + 0xD555) - - local test0 = Vector3.new(p0_x, pos.Y + 150, p0_z) - local test1 = Vector3.new(p1_x, pos.Y + 150, p1_z) - local test2 = Vector3.new(p2_x, pos.Y + 150, p2_z) - - local p0_y = Util.FindFloor(test0) - local p1_y = Util.FindFloor(test1) - local p2_y = Util.FindFloor(test2) - - p0_y = p0_y - pos.Y < minY and pos.Y or p0_y - p1_y = p1_y - pos.Y < minY and pos.Y or p1_y - p2_y = p2_y - pos.Y < minY and pos.Y or p2_y - - local avgY = (p0_y + p1_y + p2_y) / 3 - local forward = Vector3.new(Util.Sins(yaw), 0, Util.Coss(yaw)) - - if avgY >= pos.Y then - pos = Util.SetY(pos, avgY) - end - - local a = Vector3.new(p0_x, p0_y, p0_z) - local b = Vector3.new(p1_x, p1_y, p1_z) - local c = Vector3.new(p2_x, p2_y, p2_z) - - local yColumn = (b - a):Cross(c - a).Unit - local xColumn = yColumn:Cross(forward).Unit - m.ThrowMatrix = CFrame.fromMatrix(pos, xColumn, yColumn) -end - -local function beginWalkingAction(m: Mario, forwardVel: number, action: number, actionArg: number?) - m:SetForwardVel(forwardVel) - m.FaceAngle = Util.SetYint16(m.FaceAngle, m.IntendedYaw) - return m:SetAction(action, actionArg) -end - -local function checkLedgeClimbDown(m: Mario) - if m.ForwardVel < 10 then - local pos, wall = Util.FindWallCollisions(m.Position, -10, 10) - - if wall then - local floorHeight, floor = Util.FindFloor(pos) - - if floor and pos.Y - floorHeight > 160 then - local wallAngle = Util.Atan2s(wall.Normal.Z, wall.Normal.X) - local wallDYaw = wallAngle - m.FaceAngle.Y - - if math.abs(wallDYaw) < 0x4000 then - pos -= Vector3.new(20 * wall.Normal.X, 0, 20 * wall.Normal.Z) - m.Position = pos - - m.FaceAngle *= Vector3int16.new(0, 1, 1) - m.FaceAngle = Util.SetYint16(m.FaceAngle, wallAngle + 0x8000) - - m:SetAction(Action.LEDGE_CLIMB_DOWN) - m:SetAnimation(Animations.CLIMB_DOWN_LEDGE) - end - end - end - end -end - -local function slideBonk(m: Mario, fastAction: number, slowAction: number) - if m.ForwardVel > 16 then - m:BonkReflection(true) - m:SetAction(fastAction) - else - m:SetForwardVel(0) - m:SetAction(slowAction) - end -end - -local function setTripleJumpAction(m: Mario) - if m.Flags:Has(MarioFlags.WING_CAP) then - return m:SetAction(Action.FLYING_TRIPLE_JUMP) - elseif m.ForwardVel > 20 then - return m:SetAction(Action.TRIPLE_JUMP) - else - return m:SetAction(Action.JUMP) - end -end - -local function updateSlidingAngle(m: Mario, accel: number, lossFactor: number) - local newFacingDYaw - local facingDYaw - - local floor = m.Floor - - if not floor then - return - end - - assert(floor) - - local slopeAngle = Util.Atan2s(floor.Normal.Z, floor.Normal.X) - local steepness = math.sqrt(floor.Normal.X ^ 2 + floor.Normal.Z ^ 2) - - m.SlideVelX += accel * steepness * Util.Sins(slopeAngle) - m.SlideVelZ += accel * steepness * Util.Coss(slopeAngle) - - m.SlideVelX *= lossFactor - m.SlideVelZ *= lossFactor - - m.SlideYaw = Util.Atan2s(m.SlideVelZ, m.SlideVelX) - - facingDYaw = m.FaceAngle.Y - m.SlideYaw - newFacingDYaw = facingDYaw - - if newFacingDYaw > 0 and newFacingDYaw <= 0x4000 then - newFacingDYaw -= 0x200 - - if newFacingDYaw < 0 then - newFacingDYaw = 0 - end - elseif newFacingDYaw > -0x4000 and newFacingDYaw < 0 then - newFacingDYaw += 0x200 - - if newFacingDYaw > 0 then - newFacingDYaw = 0 - end - elseif newFacingDYaw > 0x4000 and newFacingDYaw < 0x8000 then - newFacingDYaw += 0x200 - - if newFacingDYaw > 0x8000 then - newFacingDYaw = 0x8000 - end - elseif newFacingDYaw > -0x8000 and newFacingDYaw < -0x4000 then - newFacingDYaw -= 0x200 - - if newFacingDYaw < -0x8000 then - newFacingDYaw = -0x8000 - end - end - - m.FaceAngle = Util.SetYint16(m.FaceAngle, m.SlideYaw + newFacingDYaw) - m.Velocity = Vector3.new(m.SlideVelX, 0, m.SlideVelZ) - - --! Speed is capped a frame late (butt slide HSG) - m.ForwardVel = math.sqrt(m.SlideVelX ^ 2 + m.SlideVelZ ^ 2) - - if m.ForwardVel > 100 then - m.SlideVelX = m.SlideVelX * 100 / m.ForwardVel - m.SlideVelZ = m.SlideVelZ * 100 / m.ForwardVel - end - - if newFacingDYaw < -0x4000 or newFacingDYaw > 0x4000 then - m.ForwardVel *= -1 - end -end - -local function updateSliding(m: Mario, stopSpeed: number) - local intendedDYaw = m.IntendedYaw - m.SlideYaw - local forward = Util.Coss(intendedDYaw) - local sideward = Util.Sins(intendedDYaw) - - --! 10k glitch - if forward < 0 and m.ForwardVel > 0 then - forward *= 0.5 + 0.5 * m.ForwardVel / 100 - end - - local floorClass = m:GetFloorClass() - local lossFactor - local accel - - if floorClass == SurfaceClass.VERY_SLIPPERY then - accel = 10 - lossFactor = m.IntendedMag / 32 * forward * 0.02 + 0.98 - elseif floorClass == SurfaceClass.SLIPPERY then - accel = 8 - lossFactor = m.IntendedMag / 32 * forward * 0.02 + 0.96 - elseif floorClass == SurfaceClass.DEFAULT then - accel = 7 - lossFactor = m.IntendedMag / 32 * forward * 0.02 + 0.92 - elseif floorClass == SurfaceClass.NOT_SLIPPERY then - accel = 5 - lossFactor = m.IntendedMag / 32 * forward * 0.02 + 0.92 - end - - local oldSpeed = math.sqrt(m.SlideVelX ^ 2 + m.SlideVelZ ^ 2) - - --! This is attempting to use trig derivatives to rotate Mario's speed. - -- It is slightly off/asymmetric since it uses the new X speed, but the old - -- Z speed. - - m.SlideVelX += m.SlideVelZ * (m.IntendedMag / 32) * sideward * 0.05 - m.SlideVelZ -= m.SlideVelX * (m.IntendedMag / 32) * sideward * 0.05 - - local newSpeed = math.sqrt(m.SlideVelX ^ 2 + m.SlideVelZ ^ 2) - - if oldSpeed > 0 and newSpeed > 0 then - m.SlideVelX *= oldSpeed / newSpeed - m.SlideVelZ *= oldSpeed / newSpeed - end - - local stopped = false - updateSlidingAngle(m, accel, lossFactor) - - if not m:FloorIsSlope() and m.ForwardVel ^ 2 < stopSpeed ^ 2 then - m:SetForwardVel(0) - stopped = true - end - - return stopped -end - -local function applySlopeAccel(m: Mario) - local floor = m.Floor - local floorNormal: Vector3 - - if floor then - floorNormal = floor.Normal - else - floorNormal = Vector3.yAxis - end - - local floorDYaw = m.FloorAngle - m.FaceAngle.Y - local steepness = math.sqrt(floorNormal.X ^ 2 + floorNormal.Z ^ 2) - - if m:FloorIsSlope() then - local slopeClass = 0 - local slopeAccel - - if m.Action() ~= Action.SOFT_BACKWARD_GROUND_KB then - if m.Action() ~= Action.SOFT_FORWARD_GROUND_KB then - slopeClass = m:GetFloorClass() - end - end - - if slopeClass == SurfaceClass.VERY_SLIPPERY then - slopeAccel = 5.3 - elseif slopeClass == SurfaceClass.SLIPPERY then - slopeAccel = 2.7 - elseif slopeClass == SurfaceClass.DEFAULT then - slopeAccel = 1.7 - else - slopeAccel = 0 - end - - if floorDYaw > -0x4000 and floorDYaw < 0x4000 then - m.ForwardVel += slopeAccel * steepness - else - m.ForwardVel -= slopeAccel * steepness - end - end - - m.SlideYaw = m.FaceAngle.Y - m.SlideVelX = m.ForwardVel * Util.Sins(m.FaceAngle.Y) - m.SlideVelZ = m.ForwardVel * Util.Coss(m.FaceAngle.Y) - m.Velocity = Vector3.new(m.SlideVelX, 0, m.SlideVelZ) -end - -local function applyLandingAccel(m: Mario, frictionFactor: number) - local stopped = false - applySlopeAccel(m) - - if not m:FloorIsSlope() then - m.ForwardVel *= frictionFactor - - if m.ForwardVel ^ 2 < 1 then - m:SetForwardVel(0) - stopped = true - end - end - - return stopped -end - -local function applySlopeDecel(m: Mario, decelCoef: number) - local decel - local stopped = false - local floorClass = m:GetFloorClass() - - if floorClass == SurfaceClass.VERY_SLIPPERY then - decel = decelCoef * 0.2 - elseif floorClass == SurfaceClass.SLIPPERY then - decel = decelCoef * 0.7 - elseif floorClass == SurfaceClass.DEFAULT then - decel = decelCoef * 2 - elseif floorClass == SurfaceClass.NOT_SLIPPERY then - decel = decelCoef * 3 - end - - m.ForwardVel = Util.ApproachFloat(m.ForwardVel, 0, decel) - - if m.ForwardVel == 0 then - stopped = true - end - - applySlopeAccel(m) - return stopped -end - -local function updateDeceleratingSpeed(m: Mario) - local stopped = false - m.ForwardVel = Util.ApproachFloat(m.ForwardVel, 0, 1) - - if m.ForwardVel == 0 then - stopped = true - end - - m:SetForwardVel(m.ForwardVel) - return stopped -end - -local function updateWalkingSpeed(m: Mario) - local maxTargetSpeed = 32 - local floor = m.Floor - - local targetSpeed = if m.IntendedMag < maxTargetSpeed then m.IntendedMag else maxTargetSpeed - - if m.ForwardVel < 0 then - m.ForwardVel += 1.1 - elseif m.ForwardVel <= targetSpeed then - m.ForwardVel += 1.1 - m.ForwardVel / 43 - elseif floor and floor.Normal.Y >= 0.95 then - m.ForwardVel -= 1 - end - - if m.ForwardVel > 48 then - m.ForwardVel = 48 - end - - local currY = Util.SignedShort(m.IntendedYaw - m.FaceAngle.Y) - local faceY = m.IntendedYaw - Util.ApproachInt(currY, 0, 0x800) - - m.FaceAngle = Util.SetYint16(m.FaceAngle, faceY) - applySlopeAccel(m) -end - -local function shouldBeginSliding(m: Mario) - if m.Input:Has(InputFlags.ABOVE_SLIDE) then - if m.ForwardVel < -1 or m:FacingDownhill() then - return true - end - end - - return false -end - -local function analogStickHeldBack(m: Mario) - local intendedDYaw = Util.SignedShort(m.IntendedYaw - m.FaceAngle.Y) - return math.abs(intendedDYaw) > 0x471C -end - -local function checkGroundDiveOrPunch(m: Mario) - if m.Input:Has(InputFlags.B_PRESSED) then - --! Speed kick (shoutouts to SimpleFlips) - if m.ForwardVel >= 29 and m.Controller.StickMag > 48 then - m.Velocity = Util.SetY(m.Velocity, 20) - return m:SetAction(Action.DIVE, 1) - end - - return m:SetAction(Action.MOVE_PUNCHING) - end - - return false -end - -local function beginBrakingAction(m: Mario) - if m.ActionState == 1 then - m.FaceAngle = Util.SetYint16(m.FaceAngle, m.ActionArg) - return m:SetAction(Action.STANDING_AGAINST_WALL) - end - - if m.ForwardVel > 16 then - local floor = m.Floor - - if floor and floor.Normal.Y >= 0.17364818 then - return m:SetAction(Action.BRAKING) - end - end - - return m:SetAction(Action.DECELERATING) -end - -local function animAndAudioForWalk(m: Mario) - local baseAccel = if m.IntendedMag > m.ForwardVel then m.IntendedMag else m.ForwardVel - - if baseAccel < 4 then - baseAccel = 4 - end - - local targetPitch = 0 - local accel - - while true do - if m.ActionTimer == 0 then - if baseAccel > 8 then - m.ActionTimer = 2 - else - accel = baseAccel / 4 * 0x10000 - - if accel < 0x1000 then - accel = 0x1000 - end - - m:SetAnimationWithAccel(Animations.START_TIPTOE, accel) - playStepSound(m, 7, 22) - - if m:IsAnimPastFrame(23) then - m.ActionTimer = 2 - end - - break - end - elseif m.ActionTimer == 1 then - if baseAccel > 8 then - m.ActionTimer = 2 - else - accel = baseAccel * 0x10000 - - if accel < 0x1000 then - accel = 0x1000 - end - - m:SetAnimationWithAccel(Animations.TIPTOE, accel) - playStepSound(m, 14, 72) - - break - end - elseif m.ActionTimer == 2 then - if baseAccel < 5 then - m.ActionTimer = 1 - elseif baseAccel > 22 then - m.ActionTimer = 3 - else - accel = baseAccel / 4 * 0x10000 - m:SetAnimationWithAccel(Animations.WALKING, accel) - playStepSound(m, 10, 49) - break - end - elseif m.ActionTimer == 3 then - if baseAccel < 18 then - m.ActionTimer = 2 - else - accel = baseAccel / 4 * 0x10000 - m:SetAnimationWithAccel(Animations.RUNNING, accel) - - playStepSound(m, 9, 45) - targetPitch = tiltBodyRunning(m) - - break - end - end - end - - local walkingPitch = Util.ApproachInt(m.WalkingPitch, targetPitch, 0x800) - walkingPitch = Util.SignedShort(walkingPitch) - - m.WalkingPitch = walkingPitch - m.GfxAngle = Util.SetXint16(m.GfxAngle, walkingPitch) -end - -local function pushOrSidleWall(m: Mario, startPos: Vector3) - local wallAngle: number - local dWallAngle: number - - local dx = m.Position.X - startPos.X - local dz = m.Position.Z - startPos.Z - - local movedDist = math.sqrt(dx ^ 2 + dz ^ 2) - local accel = movedDist * 2 * 0x10000 - - if m.ForwardVel > 6 then - m:SetForwardVel(6) - end - - local wall = m.Wall - - if wall then - wallAngle = Util.Atan2s(wall.Normal.Z, wall.Normal.X) - dWallAngle = Util.SignedShort(assert(wallAngle) - m.FaceAngle.Y) - end - - if wall == nil or math.abs(dWallAngle) >= 0x71C8 then - m:SetAnimation(Animations.PUSHING) - playStepSound(m, 6, 18) - else - if dWallAngle < 0 then - m:SetAnimationWithAccel(Animations.SIDESTEP_RIGHT, accel) - else - m:SetAnimationWithAccel(Animations.SIDESTEP_LEFT, accel) - end - - if m.AnimFrame < 20 then - m:PlaySound(Sounds.MOVING_TERRAIN_SLIDE) - m.ParticleFlags:Add(ParticleFlags.DUST) - end - - m.ActionState = 1 - m.ActionArg = Util.SignedShort(wallAngle + 0x8000) - - m.GfxAngle = Util.SetYint16(m.GfxAngle, m.ActionArg) - m.GfxAngle = Util.SetZint16(m.GfxAngle, m:FindFloorSlope(0x4000)) - end -end - -local function tiltBodyWalking(m: Mario, startYaw: number) - local anim = m.AnimCurrent - local bodyState = m.BodyState - - if anim == Animations.WALKING or anim == Animations.RUNNING then - local dYaw = m.FaceAngle.Y - startYaw - - local tiltZ = -math.clamp(dYaw * m.ForwardVel / 12, -0x1555, 0x1555) - local tiltX = math.clamp(m.ForwardVel * 170, 0, 0x1555) - - local torsoAngle = bodyState.TorsoAngle - tiltZ = Util.ApproachInt(torsoAngle.Z, tiltZ, 0x400) - tiltX = Util.ApproachInt(torsoAngle.X, tiltX, 0x400) - - bodyState.TorsoAngle = Vector3int16.new(tiltX, torsoAngle.Y, tiltZ) - else - bodyState.TorsoAngle *= Vector3int16.new(0, 1, 0) - end -end - -local function tiltBodyButtSlide(m: Mario) - local intendedDYaw = m.IntendedYaw - m.FaceAngle.Y - local bodyState = m.BodyState - - local tiltX = 5461.3335 * m.IntendedMag / 32 * Util.Coss(intendedDYaw) - local tiltZ = -(5461.3335 * m.IntendedMag / 32 * Util.Sins(intendedDYaw)) - - local torsoAngle = bodyState.TorsoAngle - bodyState.TorsoAngle = Vector3int16.new(tiltX, torsoAngle.Y, tiltZ) -end - -local function commonSlideAction(m: Mario, endAction: number, airAction: number, anim: Animation) - local pos = m.Position - m:PlaySound(Sounds.MOVING_TERRAIN_SLIDE) - m:AdjustSoundForSpeed() - - local step = m:PerformGroundStep() - - if step == GroundStep.LEFT_GROUND then - m:SetAction(airAction) - - if math.abs(m.ForwardVel) >= 50 then - m:PlaySound(Sounds.MARIO_HOOHOO) - end - elseif step == GroundStep.NONE then - m:SetAnimation(anim) - alignWithFloor(m) - - m.ParticleFlags:Add(ParticleFlags.DUST) - elseif step == GroundStep.HIT_WALL then - local wall = m.Wall - - if not m:FloorIsSlippery() then - if m.ForwardVel > 16 then - m.ParticleFlags:Add(ParticleFlags.VERTICAL_STAR) - end - - slideBonk(m, Action.GROUND_BONK, endAction) - elseif wall then - local wallAngle = Util.Atan2s(wall.Normal.Z, wall.Normal.X) - local slideSpeed = math.sqrt(m.SlideVelX ^ 2 + m.SlideVelZ ^ 2) * 0.9 - - if slideSpeed < 4 then - slideSpeed = 4 - end - - local slideYaw = Util.SignedShort(m.SlideYaw - wallAngle) - m.SlideYaw = Util.SignedShort(wallAngle - slideYaw + 0x8000) - m.SlideVelX = slideSpeed * Util.Sins(m.SlideYaw) - m.SlideVelZ = slideSpeed * Util.Coss(m.SlideYaw) - m.Velocity = Vector3.new(m.SlideVelX, m.Velocity.Y, m.SlideVelZ) - end - - alignWithFloor(m) - end -end - -local function commonSlideActionWithJump(m: Mario, stopAction: number, airAction: number, anim: Animation) - if m.ActionTimer == 5 then - if m.Input:Has(InputFlags.A_PRESSED) then - return m:SetJumpingAction(Action.JUMP) - end - else - m.ActionTimer += 1 - end - - if updateSliding(m, 4) then - m:SetAction(stopAction) - end - - commonSlideAction(m, stopAction, airAction, anim) - return false -end - -local function commonLandingCancels( - m: Mario, - landingAction: LandingAction, - setAPressAction: (Mario, number, any) -> any -) - local floor = m.Floor - - if floor and floor.Normal.Y < 0.2923717 then - return m:PushOffSteepFloor(Action.FREEFALL) - end - - m.DoubleJumpTimer = landingAction.JumpTimer - - if shouldBeginSliding(m) then - return m:SetAction(Action.BEGIN_SLIDING) - end - - if m.Input:Has(InputFlags.FIRST_PERSON) then - return m:SetAction(landingAction.EndAction) - end - - m.ActionTimer += 1 - - if m.ActionTimer >= landingAction.NumFrames then - return m:SetAction(landingAction.EndAction) - end - - if m.Input:Has(InputFlags.A_PRESSED) then - return setAPressAction(m, landingAction.APressedAction, 0) - end - - if m.Input:Has(InputFlags.OFF_FLOOR) then - return m:SetAction(Action.FREEFALL) - end - - return false -end - -local function stomachSlideAction(m: Mario, stopAction: number, airAction: number, anim: Animation) - if m.ActionTimer == 5 then - if not m.Input:Has(InputFlags.ABOVE_SLIDE) and m.Input:Has(InputFlags.A_PRESSED, InputFlags.B_PRESSED) then - return m:SetAction(if m.ForwardVel >= 0 then Action.FORWARD_ROLLOUT else Action.BACKWARD_ROLLOUT) - end - else - m.ActionTimer += 1 - end - - if updateSliding(m, 4) then - return m:SetAction(stopAction) - end - - commonSlideAction(m, stopAction, airAction, anim) - return false -end - -local function commonGroundKnockbackAction( - m: Mario, - anim: Animation, - minFrame: number, - playHeavyLanding: boolean, - attacked: number -) - local animFrame - - if playHeavyLanding then - m:PlayHeavyLandingSoundOnce(Sounds.ACTION_TERRAIN_BODY_HIT_GROUND) - end - - if attacked > 0 then - m:PlaySoundIfNoFlag(Sounds.MARIO_ATTACKED, MarioFlags.MARIO_SOUND_PLAYED) - else - m:PlaySoundIfNoFlag(Sounds.MARIO_OOOF, MarioFlags.MARIO_SOUND_PLAYED) - end - - m.ForwardVel = math.clamp(m.ForwardVel, -32, 32) - animFrame = m:SetAnimation(anim) - - if animFrame < minFrame then - applyLandingAccel(m, 0.9) - elseif m.ForwardVel > 0 then - m:SetForwardVel(0.1) - else - m:SetForwardVel(-0.1) - end - - if m:PerformGroundStep() == GroundStep.LEFT_GROUND then - if m.ForwardVel >= 0 then - m:SetAction(Action.FORWARD_AIR_KB, attacked) - else - m:SetAction(Action.BACKWARD_AIR_KB, attacked) - end - elseif m:IsAnimAtEnd() then - if m.Health < 0x100 then - m:SetAction(Action.STANDING_DEATH) - else - if attacked > 0 then - m.InvincTimer = 30 - end - - m:SetAction(Action.IDLE) - end - end - - return animFrame -end - -local function commonLandingAction(m: Mario, anim: Animation) - if m.Input:Has(InputFlags.NONZERO_ANALOG) then - applyLandingAccel(m, 0.98) - elseif m.ForwardVel > 16 then - applySlopeDecel(m, 2) - else - m.Velocity *= Vector3.new(1, 0, 1) - end - - local stepResult = m:PerformGroundStep() - - if stepResult == GroundStep.LEFT_GROUND then - m:SetAction(Action.FREEFALL) - elseif stepResult == GroundStep.HIT_WALL then - m:SetAnimation(Animations.PUSHING) - end - - if m.ForwardVel > 16 then - m.ParticleFlags:Add(ParticleFlags.DUST) - end - - m:SetAnimation(anim) - m:PlayLandingSoundOnce(Sounds.ACTION_TERRAIN_LANDING) - - return stepResult -end - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - -DEF_ACTION(Action.WALKING, function(m: Mario) - local startPos - local startYaw = m.FaceAngle.Y - - if shouldBeginSliding(m) then - return m:SetAction(Action.BEGIN_SLIDING) - end - - if m.Input:Has(InputFlags.FIRST_PERSON) then - return beginBrakingAction(m) - end - - if m.Input:Has(InputFlags.A_PRESSED) then - return m:SetJumpFromLanding() - end - - if checkGroundDiveOrPunch(m) then - return true - end - - if m.Input:Has(InputFlags.UNKNOWN_5) then - return beginBrakingAction(m) - end - - if analogStickHeldBack(m) and m.ForwardVel >= 16 then - return m:SetAction(Action.TURNING_AROUND) - end - - if m.Input:Has(InputFlags.Z_PRESSED) then - return m:SetAction(Action.CROUCH_SLIDE) - end - - - -- stylua: ignore - local step do - m.ActionState = 0 - startPos = m.Position - - updateWalkingSpeed(m) - step = m:PerformGroundStep() - end - - if step == GroundStep.LEFT_GROUND then - m:SetAction(Action.FREEFALL) - m:SetAnimation(Animations.GENERAL_FALL) - elseif step == GroundStep.NONE then - animAndAudioForWalk(m) - - if m.IntendedMag - m.ForwardVel > 16 then - m.ParticleFlags:Add(ParticleFlags.DUST) - end - elseif step == GroundStep.HIT_WALL then - pushOrSidleWall(m, startPos) - m.ActionTimer = 0 - end - - checkLedgeClimbDown(m) - tiltBodyWalking(m, startYaw) - - return false -end) - -DEF_ACTION(Action.MOVE_PUNCHING, function(m: Mario) - if shouldBeginSliding(m) then - return m:SetAction(Action.BEGIN_SLIDING) - end - - if m.ActionState == 0 and m.Input:Has(InputFlags.A_DOWN) then - return m:SetAction(Action.JUMP_KICK) - end - - m.ActionState = 1 - m:UpdatePunchSequence() - - if m.ForwardVel > 0 then - applySlopeDecel(m, 0.5) - else - m.ForwardVel += 8 - - if m.ForwardVel >= 0 then - m.ForwardVel = 0 - end - - applySlopeAccel(m) - end - - local step = m:PerformGroundStep() - - if step == GroundStep.LEFT_GROUND then - m:SetAction(Action.FREEFALL) - elseif step == GroundStep.NONE then - m.ParticleFlags:Add(ParticleFlags.DUST) - end - - return false -end) - -DEF_ACTION(Action.TURNING_AROUND, function(m: Mario) - if m.Input:Has(InputFlags.ABOVE_SLIDE) then - return m:SetAction(Action.BEGIN_SLIDING) - end - - if m.Input:Has(InputFlags.A_PRESSED) then - return m:SetAction(Action.SIDE_FLIP) - end - - if not analogStickHeldBack(m) then - return m:SetAction(Action.WALKING) - end - - if applySlopeDecel(m, 2) then - return beginWalkingAction(m, 8, Action.FINISH_TURNING_AROUND) - end - - m:PlaySound(Sounds.MOVING_TERRAIN_SLIDE) - m:AdjustSoundForSpeed() - - local step = m:PerformGroundStep() - - if step == GroundStep.LEFT_GROUND then - m:SetAction(Action.FREEFALL) - elseif step == GroundStep.NONE then - m.ParticleFlags:Add(ParticleFlags.DUST) - end - - if m.ForwardVel >= 18 then - m:SetAnimation(Animations.TURNING_PART1) - else - m:SetAnimation(Animations.TURNING_PART2) - - if m:IsAnimAtEnd() then - if m.ForwardVel > 0 then - beginWalkingAction(m, -m.ForwardVel, Action.WALKING) - else - beginWalkingAction(m, 8, Action.WALKING) - end - - m.AnimSkipInterp = true - end - end - - return false -end) - -DEF_ACTION(Action.FINISH_TURNING_AROUND, function(m: Mario) - if m.Input:Has(InputFlags.ABOVE_SLIDE) then - return m:SetAction(Action.BEGIN_SLIDING) - end - - if m.Input:Has(InputFlags.A_PRESSED) then - return m:SetAction(Action.SIDE_FLIP) - end - - updateWalkingSpeed(m) - m:SetAnimation(Animations.TURNING_PART2) - - if m:PerformGroundStep() == GroundStep.LEFT_GROUND then - m:SetAction(Action.FREEFALL) - end - - if m:IsAnimAtEnd() then - m:SetAction(Action.WALKING) - end - - m.GfxAngle += Vector3int16.new(0, 0x8000, 0) - return false -end) - -DEF_ACTION(Action.BRAKING, function(m: Mario) - if not m.Input:Has(InputFlags.FIRST_PERSON) then - if - m.Input:Has(InputFlags.NONZERO_ANALOG, InputFlags.A_PRESSED, InputFlags.OFF_FLOOR, InputFlags.ABOVE_SLIDE) - then - return m:CheckCommonActionExits() - end - end - - if applySlopeDecel(m, 2) then - return m:SetAction(Action.BRAKING_STOP) - end - - if m.Input:Has(InputFlags.B_PRESSED) then - return m:SetAction(Action.MOVE_PUNCHING) - end - - local stepResult = m:PerformGroundStep() - - if stepResult == GroundStep.LEFT_GROUND then - m:SetAction(Action.FREEFALL) - elseif stepResult == GroundStep.NONE then - m.ParticleFlags:Add(ParticleFlags.DUST) - elseif stepResult == GroundStep.HIT_WALL then - slideBonk(m, Action.BACKWARD_GROUND_KB, Action.BRAKING_STOP) - end - - m:PlaySound(Sounds.MOVING_TERRAIN_SLIDE) - m:SetAnimation(Animations.SKID_ON_GROUND) - m:AdjustSoundForSpeed() - - return false -end) - -DEF_ACTION(Action.DECELERATING, function(m: Mario) - if not m.Input:Has(InputFlags.FIRST_PERSON) then - if shouldBeginSliding(m) then - return m:SetAction(Action.BEGIN_SLIDING) - end - - if m.Input:Has(InputFlags.A_PRESSED) then - return m:SetJumpFromLanding() - end - - if checkGroundDiveOrPunch(m) then - return true - end - - if m.Input:Has(InputFlags.NONZERO_ANALOG) then - return m:SetAction(Action.CROUCH_SLIDE) - end - - if m.Input:Has(InputFlags.Z_PRESSED) then - return m:SetAction(Action.CROUCH_SLIDE) - end - end - - if updateDeceleratingSpeed(m) then - return m:SetAction(Action.IDLE) - end - - local slopeClass = m:GetFloorClass() - local stepResult = m:PerformGroundStep() - - if stepResult == GroundStep.LEFT_GROUND then - m:SetAction(Action.FREEFALL) - elseif stepResult == GroundStep.HIT_WALL then - if slopeClass == SurfaceClass.VERY_SLIPPERY then - m:BonkReflection(true) - else - m:SetForwardVel(0) - end - end - - if slopeClass == SurfaceClass.VERY_SLIPPERY then - m:SetAnimation(Animations.IDLE_HEAD_LEFT) - m:PlaySound(Sounds.MOVING_TERRAIN_SLIDE) - - m:AdjustSoundForSpeed() - m.ParticleFlags:Add(ParticleFlags.DUST) - else - local accel = m.ForwardVel / 4 * 0x10000 - - if accel < 0x1000 then - accel = 0x1000 - end - - m:SetAnimationWithAccel(Animations.WALKING, accel) - playStepSound(m, 10, 49) - end - - return false -end) - -DEF_ACTION(Action.CRAWLING, function(m: Mario) - if shouldBeginSliding(m) then - return m:SetAction(Action.BEGIN_SLIDING) - end - - if m.Input:Has(InputFlags.FIRST_PERSON) then - return m:SetAction(Action.STOP_CRAWLING) - end - - if m.Input:Has(InputFlags.A_PRESSED) then - return m:SetJumpingAction(Action.JUMP) - end - - if checkGroundDiveOrPunch(m) then - return true - end - - if m.Input:Has(InputFlags.UNKNOWN_5) then - return m:SetAction(Action.STOP_CRAWLING) - end - - if not m.Input:Has(InputFlags.Z_DOWN) then - return m:SetAction(Action.STOP_CRAWLING) - end - - m.IntendedMag *= 0.1 - updateWalkingSpeed(m) - - local stepResult = m:PerformGroundStep() - - if stepResult == GroundStep.LEFT_GROUND then - m:SetAction(Action.FREEFALL) - elseif stepResult == GroundStep.HIT_WALL then - if m.ForwardVel > 10 then - m:SetForwardVel(10) - end - - alignWithFloor(m) - elseif stepResult == GroundStep.NONE then - alignWithFloor(m) - end - - local accel = m.IntendedMag * 2 * 0x10000 - m:SetAnimationWithAccel(Animations.CRAWLING, accel) - playStepSound(m, 26, 79) - - return false -end) - -DEF_ACTION(Action.BURNING_GROUND, function(m: Mario) - if m.Input:Has(InputFlags.A_PRESSED) then - return m:SetAction(Action.BURNING_JUMP) - end - - m.BurnTimer += 2 - - if m.BurnTimer > 160 then - return m:SetAction(Action.WALKING) - end - - if m.ForwardVel < 8 then - m.ForwardVel = 8 - end - - if m.ForwardVel > 48 then - m.ForwardVel = 48 - end - - m.ForwardVel = Util.ApproachFloat(m.ForwardVel, 32, 4, 1) - - if m.Input:Has(InputFlags.NONZERO_ANALOG) then - local faceY = m.IntendedYaw - Util.ApproachFloat(m.IntendedYaw - m.FaceAngle.Y, 0, 0x600) - m.FaceAngle = Util.SetYint16(m.FaceAngle, faceY) - end - - applySlopeAccel(m) - - if m:PerformGroundStep() == GroundStep.LEFT_GROUND then - m:SetAction(Action.BURNING_FALL) - end - - local accel = m.ForwardVel / 2 * 0x10000 - m:SetAnimationWithAccel(Animations.RUNNING, accel) - playStepSound(m, 9, 45) - - m.ParticleFlags:Add(ParticleFlags.FIRE) - m:PlaySound(Sounds.MOVING_LAVA_BURN) - - m.Health -= 10 - - if m.Health < 0x100 then - m:SetAction(Action.STANDING_DEATH) - end - - m.BodyState.EyeState = MarioEyes.DEAD - return false -end) - -DEF_ACTION(Action.BUTT_SLIDE, function(m: Mario) - local cancel = commonSlideActionWithJump(m, Action.BUTT_SLIDE_STOP, Action.BUTT_SLIDE_AIR, Animations.SLIDE) - tiltBodyButtSlide(m) - - return cancel -end) - -DEF_ACTION(Action.CROUCH_SLIDE, function(m: Mario) - if m.Input:Has(InputFlags.ABOVE_SLIDE) then - return m:SetAction(Action.BUTT_SLIDE) - end - - if m.ActionTimer < 30 then - m.ActionTimer += 1 - - if m.Input:Has(InputFlags.A_PRESSED) then - if m.ForwardVel > 10 then - return m:SetJumpingAction(Action.LONG_JUMP) - end - end - end - - if m.Input:Has(InputFlags.B_PRESSED) then - if m.ForwardVel >= 10 then - return m:SetAction(Action.SLIDE_KICK) - else - return m:SetAction(Action.MOVE_PUNCHING, 9) - end - end - - if m.Input:Has(InputFlags.A_PRESSED) then - return m:SetAction(Action.JUMP) - end - - if m.Input:Has(InputFlags.FIRST_PERSON) then - return m:SetAction(Action.BRAKING) - end - - return commonSlideActionWithJump(m, Action.CROUCHING, Action.FREEFALL, Animations.START_CROUCHING) -end) - -DEF_ACTION(Action.SLIDE_KICK_SLIDE, function(m: Mario) - local step - - if m.Input:Has(InputFlags.A_PRESSED) then - return m:SetAction(Action.FORWARD_ROLLOUT) - end - - m:SetAnimation(Animations.SLIDE_KICK) - - if m:IsAnimAtEnd() and m.ForwardVel < 1 then - return m:SetAction(Action.SLIDE_KICK_SLIDE_STOP) - end - - updateSliding(m, 1) - step = m:PerformGroundStep() - - if step == GroundStep.LEFT_GROUND then - m:SetAction(Action.FREEFALL, 2) - elseif step == GroundStep.HIT_WALL then - m:BonkReflection(true) - m.ParticleFlags:Add(ParticleFlags.VERTICAL_STAR) - m:SetAction(Action.BACKWARD_GROUND_KB) - end - - m:PlaySound(Sounds.MOVING_TERRAIN_SLIDE) - m.ParticleFlags:Add(ParticleFlags.DUST) - - return false -end) - -DEF_ACTION(Action.STOMACH_SLIDE, function(m: Mario) - if m.ActionTimer == 5 then - if not m.Input:Has(InputFlags.ABOVE_SLIDE) and m.Input:Has(InputFlags.A_PRESSED, InputFlags.B_PRESSED) then - return m:SetAction(if m.ForwardVel >= 0 then Action.FORWARD_ROLLOUT else Action.BACKWARD_ROLLOUT) - end - else - m.ActionTimer += 1 - end - - if updateSliding(m, 4) then - return m:SetAction(Action.STOMACH_SLIDE_STOP) - end - - commonSlideAction(m, Action.STOMACH_SLIDE_STOP, Action.FREEFALL, Animations.SLIDE_DIVE) - return false -end) - -DEF_ACTION(Action.DIVE_SLIDE, function(m: Mario) - if not m.Input:Has(InputFlags.ABOVE_SLIDE) and m.Input:Has(InputFlags.A_PRESSED, InputFlags.B_PRESSED) then - return m:SetAction(if m.ForwardVel >= 0 then Action.FORWARD_ROLLOUT else Action.BACKWARD_ROLLOUT) - end - - m:PlayLandingSoundOnce(Sounds.ACTION_TERRAIN_BODY_HIT_GROUND) - - if updateSliding(m, 8) and m:IsAnimAtEnd() then - m:SetForwardVel(0) - m:SetAction(Action.STOMACH_SLIDE_STOP) - end - - commonSlideAction(m, Action.STOMACH_SLIDE_STOP, Action.FREEFALL, Animations.DIVE) - return false -end) - -DEF_ACTION(Action.HARD_BACKWARD_GROUND_KB, function(m: Mario) - local animFrame = commonGroundKnockbackAction(m, Animations.FALL_OVER_BACKWARDS, 43, true, m.ActionArg) - - if animFrame == 43 and m.Health < 0x100 then - m:SetAction(Action.DEATH_ON_BACK) - end - - if animFrame == 54 and m.PrevAction() == Action.SPECIAL_DEATH_EXIT then - m:PlaySound(Sounds.MARIO_MAMA_MIA) - end - - if animFrame == 69 then - m:PlayLandingSoundOnce(Sounds.ACTION_TERRAIN_LANDING) - end - - return false -end) - -DEF_ACTION(Action.HARD_FORWARD_GROUND_KB, function(m: Mario) - local animFrame = commonGroundKnockbackAction(m, Animations.LAND_ON_STOMACH, 21, true, m.ActionArg) - - if animFrame == 23 and m.Health < 0x100 then - m:SetAction(Action.DEATH_ON_STOMACH) - end - - return false -end) - -DEF_ACTION(Action.BACKWARD_GROUND_KB, function(m: Mario) - commonGroundKnockbackAction(m, Animations.BACKWARD_KB, 22, true, m.ActionArg) - return false -end) - -DEF_ACTION(Action.FORWARD_GROUND_KB, function(m: Mario) - commonGroundKnockbackAction(m, Animations.FORWARD_KB, 20, true, m.ActionArg) - return false -end) - -DEF_ACTION(Action.SOFT_BACKWARD_GROUND_KB, function(m: Mario) - commonGroundKnockbackAction(m, Animations.SOFT_BACK_KB, 100, false, m.ActionArg) - return false -end) - -DEF_ACTION(Action.SOFT_FORWARD_GROUND_KB, function(m: Mario) - commonGroundKnockbackAction(m, Animations.SOFT_FRONT_KB, 100, false, m.ActionArg) - return false -end) - -DEF_ACTION(Action.GROUND_BONK, function(m: Mario) - local animFrame = commonGroundKnockbackAction(m, Animations.GROUND_BONK, 32, true, m.ActionArg) - - if animFrame == 32 then - m:PlayLandingSound(Sounds.ACTION_TERRAIN_LANDING) - end - - return false -end) - -DEF_ACTION(Action.JUMP_LAND, function(m: Mario) - if commonLandingCancels(m, sJumpLandAction, m.SetJumpingAction) then - return true - end - - commonLandingAction(m, Animations.LAND_FROM_SINGLE_JUMP) - return false -end) - -DEF_ACTION(Action.FREEFALL_LAND, function(m: Mario) - if commonLandingCancels(m, sFreefallLandAction, m.SetJumpingAction) then - return true - end - - commonLandingAction(m, Animations.GENERAL_LAND) - return false -end) - -DEF_ACTION(Action.SIDE_FLIP_LAND, function(m: Mario) - if commonLandingCancels(m, sSideFlipLandAction, m.SetJumpingAction) then - return true - end - - if commonLandingAction(m, Animations.SLIDEFLIP_LAND) ~= GroundStep.HIT_WALL then - --m.GfxAngle += Vector3int16.new(0, 0x8000, 0) - end - - return false -end) - -DEF_ACTION(Action.LONG_JUMP_LAND, function(m: Mario) - if not m.Input:Has(InputFlags.Z_DOWN) then - m.Input:Remove(InputFlags.A_PRESSED) - end - - if commonLandingCancels(m, sLongJumpLandAction, m.SetJumpingAction) then - return true - end - - if not m.Input:Has(InputFlags.NONZERO_ANALOG) then - m:PlaySoundIfNoFlag(Sounds.MARIO_UH, MarioFlags.MARIO_SOUND_PLAYED) - end - - -- stylua: ignore - commonLandingAction(m, if m.LongJumpIsSlow - then Animations.CROUCH_FROM_FAST_LONGJUMP - else Animations.CROUCH_FROM_SLOW_LONGJUMP) - - return false -end) - -DEF_ACTION(Action.DOUBLE_JUMP_LAND, function(m: Mario) - if commonLandingCancels(m, sDoubleJumpLandAction, setTripleJumpAction) then - return true - end - - commonLandingAction(m, Animations.LAND_FROM_DOUBLE_JUMP) - return false -end) - -DEF_ACTION(Action.TRIPLE_JUMP_LAND, function(m: Mario) - m.Input:Remove(InputFlags.A_PRESSED) - - if commonLandingCancels(m, sTripleJumpLandAction, m.SetJumpingAction) then - return true - end - - if not m.Input:Has(InputFlags.NONZERO_ANALOG) then - m:PlaySoundIfNoFlag(Sounds.MARIO_HAHA, MarioFlags.MARIO_SOUND_PLAYED) - end - - commonLandingAction(m, Animations.TRIPLE_JUMP_LAND) - return false -end) - -DEF_ACTION(Action.BACKFLIP_LAND, function(m: Mario) - if not m.Input:Has(InputFlags.Z_DOWN) then - m.Input:Remove(InputFlags.A_PRESSED) - end - - if commonLandingCancels(m, sBackflipLandAction, m.SetJumpingAction) then - return true - end - - if not m.Input:Has(InputFlags.NONZERO_ANALOG) then - m:PlaySoundIfNoFlag(Sounds.MARIO_HAHA, MarioFlags.MARIO_SOUND_PLAYED) - end - - commonLandingAction(m, Animations.TRIPLE_JUMP_LAND) - return false -end) - -DEF_ACTION(Action.PUNCHING, 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.ActionState and m.Input:Has(InputFlags.A_DOWN) then - return m:SetAction(Action.JUMP_KICK) - end - - m.ActionState = 1 - - if m.ActionArg == 0 then - m.ActionTimer = 7 - end - - m:SetForwardVel(sPunchingForwardVelocities[m.ActionTimer + 1]) - - if m.ActionTimer > 0 then - m.ActionTimer -= 1 - end - - m:UpdatePunchSequence() - m:PerformGroundStep() - - return false -end)