Path: blob/master/Sonic 2/Scripts/Players/PlayerObject.txt
1479 views
// ----------------------------------1// RSDK Project: Sonic 22// Script Description: Player Object Object3// Script Author: Christian Whitehead/Simon Thomley4// Unpacked by Rubberduckycooly's script unpacker5// ----------------------------------67// ========================8// Aliases9// ========================1011public alias 0x100 : GROUP_PLAYERS12public alias arrayPos6 : currentPlayer13public alias arrayPos7 : playerCount1415// Gravity16public alias 0 : GRAVITY_GROUND17public alias 1 : GRAVITY_AIR1819// Priority20public alias 0 : PRIORITY_BOUNDS21public alias 1 : PRIORITY_ACTIVE22public alias 2 : PRIORITY_ALWAYS23public alias 3 : PRIORITY_XBOUNDS24public alias 4 : PRIORITY_XBOUNDS_DESTROY25public alias 5 : PRIORITY_INACTIVE26public alias 6 : PRIORITY_BOUNDS_SMALL27public alias 7 : PRIORITY_ACTIVE_SMALL2829// Control Modes30public alias -1 : CONTROLMODE_NONE31public alias 0 : CONTROLMODE_P132public alias 1 : CONTROLMODE_P233public alias 2 : CONTROLMODE_P3 // Although unused by the game normally, RSDKv5U does have support for up to 4 players34public alias 3 : CONTROLMODE_P43536// Camera Styles37public alias 0 : CAMERASTYLE_FOLLOW38public alias 1 : CAMERASTYLE_EXTENDED39public alias 2 : CAMERASTYLE_EXTENDED_OFFSET_L40public alias 3 : CAMERASTYLE_EXTENDED_OFFSET_R41public alias 4 : CAMERASTYLE_HLOCKED42// Origins Only43public alias 5 : CAMERASTYLE_FIXED44public alias 6 : CAMERASTYLE_STATIC4546// Ink Effects47public alias 0 : INK_NONE48public alias 1 : INK_BLEND49public alias 2 : INK_ALPHA50public alias 3 : INK_ADD51public alias 4 : INK_SUB5253// Flip Directions54public alias 0 : FLIP_NONE55public alias 1 : FLIP_X56public alias 2 : FLIP_Y57public alias 3 : FLIP_XY5859// Collision Sides60public alias 0 : CSIDE_FLOOR61public alias 1 : CSIDE_LWALL62public alias 2 : CSIDE_RWALL63public alias 3 : CSIDE_ROOF64public alias 4 : CSIDE_LENTITY // Origins only65public alias 5 : CSIDE_RENTITY // Origins only6667// Collision Modes68public alias 0 : CMODE_FLOOR69public alias 1 : CMODE_LWALL70public alias 2 : CMODE_ROOF71public alias 3 : CMODE_RWALL7273// Collision Directions74public alias 0 : COL_NONE75public alias 1 : COL_TOP76public alias 2 : COL_LEFT77public alias 3 : COL_RIGHT78public alias 4 : COL_BOTTOM7980// Reserved Object Slot Aliases81private alias 0 : SLOT_PLAYER182private alias 1 : SLOT_PLAYER283private alias 11 : SLOT_TITLECARD84private alias 30 : SLOT_ACTFINISH8586// Draw Order87private alias -1 : DRAWORDER_PLAYER8889// Tile Info ID Aliases90private alias 8 : TILEINFO_ANGLEB9192// Player List Pos Aliases93// The A at the end of each of these stands for Alias, Origins Plus introduced global variables for player slots but we need to support Standalone too94// Also switch cases don't support variables so we have to do this either way95public alias 0 : PLAYER_SONIC_A96public alias 1 : PLAYER_TAILS_A97public alias 2 : PLAYER_KNUCKLES_A98public alias 3 : PLAYER_SONIC_TAILS_A99public alias 4 : PLAYER_KNUCKLES_TAILS_A100public alias 5 : PLAYER_AMY_A101public alias 6 : PLAYER_AMY_TAILS_A102103// Shields104private alias 0 : SHIELD_NONE105private alias 1 : SHIELD_NORMAL106private alias 2 : SHIELD_BUBBLE107private alias 3 : SHIELD_FIRE108private alias 4 : SHIELD_LIGHTNING109110// Shield Types Aliases111private alias 0 : SHIELDTYPE_S2112private alias 1 : SHIELDTYPE_S3113114// Bubble Shield Aliases115private alias 2 : BUBBLESHIELD_BOUNCE_SETUP116117// Fire Shield Aliases118private alias 2 : FIRESHIELD_DASH_SETUP119120// Super States121private alias 0 : SUPERSTATE_NONE122private alias 1 : SUPERSTATE_SUPER123private alias 2 : SUPERSTATE_FADEOUT124private alias 3 : SUPERSTATE_END125126// Modes127private alias 2 : MODE_TIMEATTACK128private alias 8 : MISSIONNO_MERCY129130// Global Variable ID Aliases (yeah it's weird, the game uses global variables like an array sometimes, so these aliases are the IDs of those variables)131// (these numbers correspond to the variable's position in the GameConfig global variable list)132private alias 22 : GLOBAL_PLAYERSCORE133private alias 25 : GLOBAL_PLAYERLIVES134135// Tracks136private alias 0 : TRACK_STAGE137private alias 2 : TRACK_INVINCIBLE138private alias 5 : TRACK_GAMEOVER139private alias 7 : TRACK_SUPER140141// Stats Aliases142private alias StageStatsUsabilityParam1 : stageStat.badnikDestroyCount143private alias StageStatsUsabilityParam2 : stageStat.spindashDestroyCount144private alias StageStatsUsabilityParam3 : stageStat.buzzerDestroyCount145146// We can't use TypeName aliases for stage objects in global objects, so regular aliases will have to do147private alias 54 : TYPE_BUZZER148private alias 56 : TYPE_BEE149150// Variables151private alias object.type : player.type152private alias object.groupID : player.groupID // Normally GROUP_PLAYERS, unless in Debug Mode or some other strange scenario153private alias object.entityPos : player.entityPos // Where the player is on the object list - P1 should be 0, P2 should be 1154private alias object.state : player.state155private alias object.visible : player.visible156private alias object.propertyValue : player.character // Individual character type of the object. See the Player List Pos aliases157private alias object.xpos : player.xpos // Total world-space position (0x10000 == 1.0)158private alias object.ypos : player.ypos159private alias object.ixpos : player.ixpos // Screen space position (1 == 1)160private alias object.iypos : player.iypos161private alias object.lookPosX : player.lookPosX // Camera offset based on this player's position162private alias object.lookPosY : player.lookPosY163private alias object.xvel : player.xvel // Based on world-space (see above)164private alias object.yvel : player.yvel165private alias object.speed : player.speed // Based on world-space (see above)166private alias object.rotation : player.rotation // 512-based, not 360 degrees167private alias object.angle : player.angle // See above168private alias object.direction : player.direction169private alias object.gravity : player.gravity // GRAVITY_GROUND or GRAVITY_AIR. Not to be confused with player.gravityStrength, see there for more info170private alias object.frame : player.frame171private alias object.animation : player.animation172private alias object.prevAnimation : player.prevAnimation173private alias object.animationSpeed : player.animationSpeed174private alias object.animationTimer : player.animationTimer175private alias object.drawOrder : player.drawOrder // Should always be DRAWORDER_PLAYER, to change draw order use player.sortedDrawOrder instead176private alias object.pushing : player.pushing177private alias object.controlLock : player.controlLock // Timer for how long control lock is active. Not to be confused with roll jump lock, see the Player_Action_Jump function for that178private alias object.controlMode : player.controlMode // See CONTROLMODE_* aliases179private alias object.interaction : player.interaction // Will the object interact with other objects?180private alias object.scrollTracking : player.scrollTracking // Determines if the camera will track the player's position or just follow it181private alias object.collisionMode : player.collisionMode182private alias object.collisionLeft : player.collisionLeft183private alias object.collisionTop : player.collisionTop184private alias object.collisionRight : player.collisionRight185private alias object.collisionBottom : player.collisionBottom186private alias object.collisionPlane : player.collisionPlane187private alias object.floorSensorC : player.floorSensorC188private alias object.floorSensorL : player.floorSensorL189private alias object.floorSensorR : player.floorSensorR190private alias object.floorSensorLC : player.floorSensorLC191private alias object.floorSensorRC : player.floorSensorRC192private alias object.tileCollisions : player.tileCollisions193private alias object.priority : player.priority194195// *Object-wise* input, not to be confused with keyPress[0].X and keyDown[0].X196private alias object.jumpPress : player.jumpPress197private alias object.jumpHold : player.jumpHold198private alias object.up : player.up199private alias object.down : player.down200private alias object.left : player.left201private alias object.right : player.right202203// Object value aliases204private alias object.value0 : player.rings205private alias object.value1 : player.timer206private alias object.value2 : player.abilityTimer // Note: Also used by death/drowning state207private alias object.value3 : player.drownTimer // Countdown before player moves to next drown "level"208private alias object.value4 : player.drownLevel209private alias object.value5 : player.rollAnimationSpeed210private alias object.value6 : player.speedShoesTimer211private alias object.value7 : player.invincibleTimer212private alias object.value8 : player.blinkTimer213private alias object.value9 : player.skidSpeed214private alias object.value10 : player.animationReserve // Used by springs to store what animation will play after the bounce animation215private alias object.value11 : player.scrollDelay // A timer of how long the camera will stay locked for216private alias object.value12 : player.tailFrame // One of Tails's tail values, not used by the player itself217private alias object.value13 : player.tailAnim // Also one of Tails's tail values218private alias object.value14 : player.skidding219// value15 is unused220private alias object.value16 : player.isSidekick // true if an AI character (P2 in singleplayer), false otherwise (P1, P2 in 2PVS)221private alias object.value17 : debugMode.currentSelection222private alias object.value18 : player.sortedDrawOrder223private alias object.value19 : player.badnikBonus // How many enemies the player has bounced on in a row224private alias object.value20 : player.topSpeed225private alias object.value21 : player.acceleration226private alias object.value22 : player.deceleration227private alias object.value23 : player.airAcceleration228private alias object.value24 : player.airDeceleration229private alias object.value25 : player.gravityStrength // Also used in underwater checks, 0x1000 if underwater, otherwise 0x3800. Not to be confused with player.gravity230private alias object.value26 : player.flightVelocity // Used by Tails only231private alias object.value27 : player.jumpStrength232private alias object.value28 : player.jumpCap233private alias object.value29 : player.rollingFriction // Active rolling deceleration - With the player holding the opposite direction234private alias object.value30 : player.jumpOffset // Added to the player's position when jumping/rolling. Normally -5 for S&K, and -1 for Tails235private alias object.value31 : player.rollingDeceleration // Passive rolling deceleration - Without the player holding the opposite direction236private alias object.value32 : player.jumpAbility // Used to store whatever function this player has for its jump ability237private alias object.value33 : player.spindashFunction // Used to store whatever function this player has for its spindash ability238private alias object.value34 : player.collisionDisabled239private alias object.value35 : player.jumpAbilityState240private alias object.value36 : player.flyCarryTimer // Tails assist lockout timer241private alias object.value37 : player.shield // Current shield the player has, see SHIELD_* constants242private alias object.value40 : player.hitboxLeft243private alias object.value38 : player.hitboxTop244private alias object.value41 : player.hitboxRight245private alias object.value39 : player.hitboxBottom246private alias object.value42 : player.prevGravity247248// Values used in Origins249private alias object.value16 : player.releasingDropDash250private alias object.value47 : player.disableGravity // Added in Origins 2.0.1, used after clearing/failing a mission251252// P2 values253private alias object.value43 : player.jumpInTimer254private alias object.value44 : player.p2InputFunction255private alias object.value45 : player.autoJumpTimer256private alias object.value46 : player.targetLeaderPos.x257private alias object.value47 : player.targetLeaderPos.y258259// Death Event Aliases260private alias object.drawOrder : deathEvent.drawOrder261private alias object.state : deathEvent.state262private alias object.value1 : deathEvent.leftTextPos263private alias object.value2 : deathEvent.rightTextPos264private alias object.value3 : deathEvent.timer265266// Death Event States267private alias 0 : DEATHEVENT_GAMEOVER268private alias 1 : DEATHEVENT_TIMEOVER269private alias 2 : DEATHEVENT_DEATH270private alias 3 : DEATHEVENT_DEATH_TA271272// VSGame Aliases273private alias object.state : vsGame.state274private alias object.value0 : vsGame.timer275276// VSGame States277private alias 2 : VSGAME_FADEOUT278private alias 7 : VSGAME_SCREENFADE279280281// ========================282// Function Declarations283// ========================284285reserve function Player_ProcessUpdate286reserve function Player_State_Static287reserve function Player_HandleGroundMovement288reserve function Player_HandleAirFriction289reserve function Player_HandleAirMovement290reserve function Player_HandleOnGround291reserve function Player_Action_Jump292reserve function Player_Action_Spindash293reserve function Player_Action_DblJumpTails294reserve function Player_Action_DblJumpKnux295reserve function Player_State_Ground296reserve function Player_State_Sleeping297reserve function Player_State_Air_NoDropDash298reserve function Player_State_Air299reserve function Player_State_TubeAirRoll300reserve function Player_State_Roll301reserve function Player_State_RollJump302reserve function Player_State_LookUp303reserve function Player_State_Crouch304reserve function Player_State_Spindash305reserve function Player_State_Fly306reserve function Player_State_GlideLeft307reserve function Player_State_GlideRight308reserve function Player_State_GlideDrop309reserve function Player_State_GlideSlide310reserve function Player_State_Climb311reserve function Player_State_LedgePullUp312reserve function Player_State_GotHit313reserve function Player_State_Hurt314reserve function Player_State_Death315reserve function Player_State_Drown316reserve function Player_State_HangBar // Unused - Leftover from CD317reserve function Player_State_TubeRoll318reserve function Player_State_Clinging319reserve function Player_State_Waterslide320reserve function Player_State_Carried321reserve function Player_State_ContinueRun322reserve function Player_SetDropDashCharge323reserve function Player_GetDropDashCharge324reserve function Player_HandleDropDash325reserve function Player_CheckIfOnScreen326reserve function Player_Action_DblJumpAmy327reserve function Player_Action_HammerDash328reserve function Player_State_HammerDash329reserve function Player_SetHammerDashSpeed330reserve function Player_HandleAmyHitbox331reserve function Player_SetupAttractDemo332reserve function Player_ApplyShield333reserve function Player_HandleSuperPalette_Sonic334reserve function Player_HandleSuperPalette_Tails335reserve function Player_HandleSuperPalette_Knux336reserve function Player_HandleSuperPalette_Amy337reserve function Player_UpdatePhysicsState338reserve function Player_HandleSuperForm339reserve function Player_CheckHit340reserve function Player_BadnikBreak341reserve function Player_Hit342reserve function Player_FireHit343reserve function Player_LightningHit344reserve function Player_ProjectileHit345reserve function Player_SpikeHit346reserve function Player_Kill347reserve function Player_HandleRollAnimSpeed348reserve function Player_HandleWalkAnimSpeed349reserve function Player_HandleRunAnimSpeed350reserve function Player_HandleRollDeceleration351reserve function Player_State_Transform352reserve function Player_TryTransform353reserve function Player_State_BubbleBounce354reserve function Player_Action_DblJumpSonic355reserve function Player_HandleFlyCarry356357358// ========================359// Static Values360// ========================361362public value Player_flyCarryLeaderXPos = 0363public value Player_flyCarryLeaderYPos = 0364public value Player_flyCarryBuddyXPos = 0365public value Player_flyCarryBuddyYPos = 0366367public value Player_superState = 0368public value Player_superRingLossTimer = 0369public value Player_superBlendClr = 0370public value Player_superBlendTimer = 0371372public value Player_attractTable = 0373public value Player_attractTablePos = 0374public value Player_attractTableSize = 0375public value Player_attractFrameCount = 0376public value Player_attractDuration = 0377378// All these below are unused379private value Player_unusedValue1 = 0380private value Player_unusedValue2 = 0381private value Player_unusedValue3 = 0382private value Player_unusedValue4 = 0383private value Player_unusedValue5 = 0384private value Player_unusedValue6 = 0385private value Player_unusedValue7 = 0386387388// ========================389// Tables390// ========================391392public table Player_SonicSuperPal3930x2020A0, 0x2040C0, 0x4040E0, 0x6060E03940x404080, 0x4060A0, 0x6060E0, 0x8080E03950x606060, 0x6080A0, 0x8080E0, 0xA0A0E03960x808040, 0x80A0A0, 0xA0A0E0, 0xC0C0E03970xA0A040, 0xA0C0A0, 0xC0C0E0, 0xE0E0E03980xC0C040, 0xC0E0A0, 0xE0E0E0, 0xE0E0E03990xE0E040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E04000xE0E060, 0xE0E0E0, 0xE0E0E0, 0xE0E0E04010xE0E080, 0xE0E0E0, 0xE0E0E0, 0xE0E0E04020xE0E060, 0xE0E0C0, 0xE0E0E0, 0xE0E0E04030xE0E040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E04040xE0E020, 0xE0E080, 0xE0E0C0, 0xE0E0E04050xE0E000, 0xE0E060, 0xE0E0A0, 0xE0E0E04060xE0E000, 0xE0E040, 0xE0E080, 0xE0E0C04070xE0E000, 0xE0E060, 0xE0E0A0, 0xE0E0E04080xE0E000, 0xE0E080, 0xE0E0C0, 0xE0E0E0409end table410411public table Player_SonicSuperAltPal4120x202080, 0x4040A0, 0x6060C0, 0x8080E04130x404060, 0x6060A0, 0x8080E0, 0xA0A0E04140x606040, 0x8080A0, 0xA0A0E0, 0xC0C0E04150x808040, 0xA0A0A0, 0xC0C0E0, 0xE0E0E04160xA0A040, 0xC0C0A0, 0xE0E0E0, 0xE0E0E04170xC0C040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E04180xE0E040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E04190xE0E060, 0xE0E0E0, 0xE0E0E0, 0xE0E0E04200xE0E080, 0xE0E0E0, 0xE0E0E0, 0xE0E0E04210xE0E060, 0xE0E0C0, 0xE0E0E0, 0xE0E0E04220xE0E040, 0xE0E0A0, 0xE0E0E0, 0xE0E0E04230xE0E020, 0xE0E080, 0xE0E0C0, 0xE0E0E04240xE0E000, 0xE0E060, 0xE0E0A0, 0xE0E0E04250xE0E000, 0xE0E040, 0xE0E080, 0xE0E0C04260xE0E000, 0xE0E060, 0xE0E0A0, 0xE0E0E04270xE0E000, 0xE0E080, 0xE0E0C0, 0xE0E0E0428end table429430public table Player_TailsSuperPal4310x800000, 0xE08000, 0xE0A000, 0xA060404320x800000, 0xE0A020, 0xE0C040, 0xA060404330xA06040, 0xE0C040, 0xE0C080, 0xC060404340xC06040, 0xE0C080, 0xE0E0A0, 0xE080404350xA06040, 0xE0C040, 0xE0C080, 0xC060404360x800000, 0xE0A020, 0xE0C040, 0xA06040437end table438439public table Player_TailsSuperAltPal4400x800000, 0xE08000, 0xE0A000, 0xA060404410x800000, 0xE0A020, 0xE0C040, 0xA060404420xA06040, 0xE0C040, 0xE0C080, 0xC060404430xC06040, 0xE0C080, 0xE0E0A0, 0xE080404440xA06040, 0xE0C040, 0xE0C080, 0xC060404450x800000, 0xE0A020, 0xE0C040, 0xA06040446end table447448public table Player_KnuxSuperPal4490x600020, 0xC00020, 0xE040604500x802040, 0xE04060, 0xE060A04510xA04060, 0xE06080, 0xE080C04520xC06080, 0xE080A0, 0xE0A0E04530xE080A0, 0xE0A0C0, 0xE0C0E04540xE0A0C0, 0xE0C0E0, 0xE0E0E04550xE080A0, 0xE0A0C0, 0xE0C0E04560xC06080, 0xE080A0, 0xE0A0E04570xA04060, 0xE06080, 0xE080C04580x802040, 0xE04060, 0xE060A0459end table460461public table Player_KnuxSuperAltPal4620x600020, 0xC00040, 0xE040804630x802040, 0xE04060, 0xE060A04640xA04060, 0xE06080, 0xE080C04650xC06080, 0xE080A0, 0xE0A0E04660xE080A0, 0xE0A0C0, 0xE0C0E04670xE0A0C0, 0xE0C0E0, 0xE0E0E04680xE080A0, 0xE0A0C0, 0xE0C0E04690xC06080, 0xE080A0, 0xE0A0E04700xA04060, 0xE06080, 0xE080C04710x802040, 0xE04060, 0xE060A0472end table473474// Bug Details (yeah we haven't gotten to any actual code yet and there's already an issue):475// Amy's base palette is completely missing in both of these tables, causing the game to apply the first super palette when the scene loads instead476// This is what causes Amy's fur to be slightly brighter in-game compared to the spritesheets and global palette477// Note that if you're looking to fix this, you'll also have to edit the Player_HandleSuperPalette_Amy function to account for the new line478479public table Player_AmySuperPal4800xD468B0, 0xFC8CFC, 0xFCD4FC, 0x8C2068, 0xB0448C4810xF488D0, 0xFCACFC, 0xFCE4FC, 0xAC4088, 0xD064AC4820xF4A8F0, 0xFCCCFC, 0xFCE4FC, 0xCC60A8, 0xF084CC4830xF4C8F0, 0xFCECFC, 0xFCE4FC, 0xEC80C8, 0xF0A4EC4840xF4E8F0, 0xFCECFC, 0xFCE4FC, 0xECA0E8, 0xF0C4EC4850xF4E8F0, 0xFCECFC, 0xFCE4FC, 0xECC0E8, 0xF0E4EC4860xF4E8F0, 0xFCECFC, 0xFCE4FC, 0xECA0E8, 0xF0C4EC4870xF4C8F0, 0xFCECFC, 0xFCE4FC, 0xEC80C8, 0xF0A4EC4880xF4A8F0, 0xFCCCFC, 0xFCE4FC, 0xCC60A8, 0xF084CC4890xF488D0, 0xFCACFC, 0xFCE4FC, 0xAC4088, 0xD064AC490end table491492public table Player_AmySuperAltPal4930xD468B0, 0xFC8CFC, 0xFCD4FC, 0x8C2068, 0xB0448C4940xF488D0, 0xFCACFC, 0xFCE4FC, 0xAC4088, 0xD064AC4950xF4A8F0, 0xFCCCFC, 0xFCE4FC, 0xCC60A8, 0xF084CC4960xF4C8F0, 0xFCECFC, 0xFCE4FC, 0xEC80C8, 0xF0A4EC4970xF4E8F0, 0xFCECFC, 0xFCE4FC, 0xECA0E8, 0xF0C4EC4980xF4E8F0, 0xFCECFC, 0xFCE4FC, 0xECC0E8, 0xF0E4EC4990xF4E8F0, 0xFCECFC, 0xFCE4FC, 0xECA0E8, 0xF0C4EC5000xF4C8F0, 0xFCECFC, 0xFCE4FC, 0xEC80C8, 0xF0A4EC5010xF4A8F0, 0xFCCCFC, 0xFCE4FC, 0xCC60A8, 0xF084CC5020xF488D0, 0xFCACFC, 0xFCE4FC, 0xAC4088, 0xD064AC503end table504505// Each line of these physics tables store the values in this order:506// Top Speed, Ground Acceleration, Air Acceleration, Air Deleceration, Skid Speed, Rolling Friction, Jump Strength, Jump Cap507// Note that Ground Deceleration is not defined here, rather it's set based on Ground Acceleration508509private table Player_SonicPhysicsTable5100x60000, 0x0C00, 0x1800, 0x0600, 0x08000, 0x0600, 0x68000, -0x40000 // Normal5110x30000, 0x0600, 0x0C00, 0x0300, 0x04000, 0x0300, 0x38000, -0x20000 // Underwater5120xA0000, 0x3000, 0x6000, 0x1800, 0x10000, 0x0600, 0x80000, -0x40000 // Super5130x50000, 0x1800, 0x3000, 0x0C00, 0x08000, 0x0300, 0x38000, -0x20000 // Super + Underwater5140xC0000, 0x1800, 0x3000, 0x0C00, 0x08000, 0x0600, 0x68000, -0x40000 // Speed Shoes5150x60000, 0x0C00, 0x1800, 0x0600, 0x04000, 0x0300, 0x38000, -0x20000 // Speed Shoes + Underwater5160xC0000, 0x1800, 0x3000, 0x0C00, 0x08000, 0x0600, 0x80000, -0x40000 // Speed Shoes + Super5170x60000, 0x0C00, 0x1800, 0x0600, 0x04000, 0x0300, 0x38000, -0x20000 // Speed Shoes + Super + Underwater518end table519520private table Player_TailsPhysicsTable5210x60000, 0x0C00, 0x1800, 0x0600, 0x08000, 0x0600, 0x68000, -0x40000 // Normal5220x30000, 0x0600, 0x0C00, 0x0300, 0x04000, 0x0300, 0x38000, -0x20000 // Underwater5230xA0000, 0x3000, 0x6000, 0x1800, 0x10000, 0x0600, 0x80000, -0x40000 // Super5240x50000, 0x1800, 0x3000, 0x0C00, 0x08000, 0x0300, 0x38000, -0x20000 // Super + Underwater5250xC0000, 0x1800, 0x3000, 0x0C00, 0x08000, 0x0600, 0x68000, -0x40000 // Speed Shoes5260x60000, 0x0C00, 0x1800, 0x0600, 0x04000, 0x0300, 0x38000, -0x20000 // Speed Shoes + Underwater5270xC0000, 0x1800, 0x3000, 0x0C00, 0x08000, 0x0600, 0x80000, -0x40000 // Speed Shoes + Super5280x60000, 0x0C00, 0x1800, 0x0600, 0x04000, 0x0300, 0x38000, -0x20000 // Speed Shoes + Super + Underwater529end table530531private table Player_KnuxPhysicsTable5320x60000, 0x0C00, 0x1800, 0x0600, 0x08000, 0x0600, 0x60000, -0x40000 // Normal5330x30000, 0x0600, 0x0C00, 0x0300, 0x04000, 0x0300, 0x30000, -0x20000 // Underwater5340xA0000, 0x3000, 0x6000, 0x1800, 0x10000, 0x0600, 0x60000, -0x40000 // Super5350x50000, 0x1800, 0x3000, 0x0C00, 0x08000, 0x0300, 0x30000, -0x20000 // Super + Underwater5360xC0000, 0x1800, 0x3000, 0x0C00, 0x08000, 0x0600, 0x60000, -0x40000 // Speed Shoes5370x60000, 0x0C00, 0x1800, 0x0600, 0x04000, 0x0300, 0x30000, -0x20000 // Speed Shoes + Underwater5380xC0000, 0x1800, 0x3000, 0x0C00, 0x08000, 0x0600, 0x60000, -0x40000 // Speed Shoes + Super5390x60000, 0x0C00, 0x1800, 0x0600, 0x08000, 0x0300, 0x30000, -0x20000 // Speed Shoes + Super + Underwater540end table541542private table Player_AmyPhysicsTable5430x60000, 0x0C00, 0x1800, 0x0600, 0x08000, 0x0600, 0x68000, -0x40000 // Normal5440x30000, 0x0600, 0x0C00, 0x0300, 0x04000, 0x0300, 0x38000, -0x20000 // Underwater5450xA0000, 0x3000, 0x6000, 0x1800, 0x10000, 0x0600, 0x80000, -0x40000 // Super5460x50000, 0x1800, 0x3000, 0x0C00, 0x08000, 0x0300, 0x38000, -0x20000 // Super + Underwater5470xC0000, 0x1800, 0x3000, 0x0C00, 0x08000, 0x0600, 0x68000, -0x40000 // Speed Shoes5480x60000, 0x0C00, 0x1800, 0x0600, 0x04000, 0x0300, 0x38000, -0x20000 // Speed Shoes + Underwater5490xC0000, 0x1800, 0x3000, 0x0C00, 0x08000, 0x0600, 0x80000, -0x40000 // Speed Shoes + Super5500x60000, 0x0C00, 0x1800, 0x0600, 0x04000, 0x0300, 0x38000, -0x20000 // Speed Shoes + Super + Underwater551end table552553554// ========================555// Function Definitions556// ========================557558public function Player_HandleAmyHitbox559#platform: USE_ORIGINS560// Bug Details: (first line of code in the script and there's already something, huh?)561// This checks against P1's character ID, and while that's fine in singleplayer, it fails to account for P2 Amy in VS...562// Not that it matters, the Player 2 Object doesn't call this function anyway563564if stage.playerListPos == PLAYER_AMY565temp0 = false566567if player[currentPlayer].animation == ANI_HAMMER_JUMP568temp0 = true569570player[currentPlayer].hitboxTop = -25571player[currentPlayer].hitboxBottom = 25572player[currentPlayer].hitboxLeft = -25573player[currentPlayer].hitboxRight = 25574end if575576if player[currentPlayer].animation == ANI_HAMMER_DASH577temp0 = true578579player[currentPlayer].hitboxBottom = 17580player[currentPlayer].hitboxTop = -24581player[currentPlayer].hitboxLeft = -18582player[currentPlayer].hitboxRight = 10583584switch player[currentPlayer].frame585case 0586case 4587player[currentPlayer].hitboxTop = -17588player[currentPlayer].hitboxLeft = -10589player[currentPlayer].hitboxRight = 23590break591592case 1593case 5594player[currentPlayer].hitboxTop = -17595player[currentPlayer].hitboxLeft = -23596player[currentPlayer].hitboxRight = 10597break598599case 2600case 6601player[currentPlayer].hitboxTop = -24602player[currentPlayer].hitboxLeft = -18603player[currentPlayer].hitboxRight = 10604break605606case 3607case 7608player[currentPlayer].hitboxTop = -26609player[currentPlayer].hitboxLeft = -10610player[currentPlayer].hitboxRight = 25611break612end switch613614if player[currentPlayer].direction == FACING_LEFT615// Swap the left and right values616temp1 = player[currentPlayer].hitboxLeft617player[currentPlayer].hitboxLeft = player[currentPlayer].hitboxRight618player[currentPlayer].hitboxRight = temp1619player[currentPlayer].hitboxLeft *= -1620player[currentPlayer].hitboxRight *= -1621end if622end if623624if temp0 == false625// Default to regular hitbox626player[currentPlayer].hitboxTop = C_BOX627player[currentPlayer].hitboxBottom = C_BOX628player[currentPlayer].hitboxLeft = C_BOX629player[currentPlayer].hitboxRight = C_BOX630end if631end if632#endplatform633end function634635636// Initialize the character object for replay playback637public function Player_SetupAttractDemo638Player_attractTablePos = 2639Player_attractFrameCount = 1640641currentPlayer = SLOT_PLAYER1642while currentPlayer < playerCount643GetTableValue(player[currentPlayer].xpos, 0, Player_attractTable)644GetTableValue(player[currentPlayer].ypos, 1, Player_attractTable)645player[currentPlayer].controlMode = CONTROLMODE_NONE646player[currentPlayer].up = false647player[currentPlayer].down = false648player[currentPlayer].left = false649player[currentPlayer].right = false650player[currentPlayer].jumpPress = false651player[currentPlayer].jumpHold = false652player[currentPlayer].timer = 0653currentPlayer++654loop655656camera[0].xpos = player[SLOT_PLAYER1].ixpos657camera[0].ypos = player[SLOT_PLAYER1].iypos658end function659660661public function Player_ApplyShield662switch player[currentPlayer].shield663case SHIELD_NONE664ResetObjectEntity(arrayPos0, TypeName[Blank Object], 0, 0, 0)665break666667case SHIELD_NORMAL668ResetObjectEntity(arrayPos0, blueShieldType, 0, 0, 0)669object[arrayPos0].priority = PRIORITY_ACTIVE670object[arrayPos0].inkEffect = INK_ALPHA671object[arrayPos0].alpha = 0xA0672break673674case SHIELD_BUBBLE675ResetObjectEntity(arrayPos0, TypeName[Bubble Shield], 0, 0, 0)676object[arrayPos0].priority = PRIORITY_ACTIVE677break678679case SHIELD_FIRE680ResetObjectEntity(arrayPos0, TypeName[Fire Shield], 0, 0, 0)681object[arrayPos0].priority = PRIORITY_ACTIVE682break683684case SHIELD_LIGHTNING685ResetObjectEntity(arrayPos0, TypeName[LightningShield], 0, 0, 0)686object[arrayPos0].priority = PRIORITY_ACTIVE687break688end switch689end function690691692public function Player_HandleSuperPalette_Sonic693if Player_superState == SUPERSTATE_SUPER694Player_superBlendTimer++695if Player_superBlendTimer >= 4696Player_superBlendTimer = 0697698Player_superBlendClr += 4699if Player_superBlendClr >= 64700Player_superBlendClr = 24701end if702end if703else704Player_superBlendTimer++705if Player_superBlendTimer >= 8706Player_superBlendTimer = 0707708Player_superBlendClr -= 4709if Player_superBlendClr <= 0710Player_superBlendClr = 0711Player_superState = SUPERSTATE_NONE712end if713714if Player_superBlendClr >= 24715Player_superBlendClr = 24716end if717end if718end if719720temp1 = Player_superBlendClr721722GetTableValue(temp0, temp1, Player_SonicSuperPal)723SetPaletteEntry(0, 2, temp0)724GetTableValue(temp0, temp1, Player_SonicSuperAltPal)725SetPaletteEntry(1, 2, temp0)726temp1++727728GetTableValue(temp0, temp1, Player_SonicSuperPal)729SetPaletteEntry(0, 3, temp0)730GetTableValue(temp0, temp1, Player_SonicSuperAltPal)731SetPaletteEntry(1, 3, temp0)732temp1++733734GetTableValue(temp0, temp1, Player_SonicSuperPal)735SetPaletteEntry(0, 4, temp0)736GetTableValue(temp0, temp1, Player_SonicSuperAltPal)737SetPaletteEntry(1, 4, temp0)738temp1++739740GetTableValue(temp0, temp1, Player_SonicSuperPal)741SetPaletteEntry(0, 5, temp0)742GetTableValue(temp0, temp1, Player_SonicSuperAltPal)743SetPaletteEntry(1, 5, temp0)744end function745746747public function Player_HandleSuperPalette_Tails748if Player_superState == SUPERSTATE_SUPER749Player_superBlendTimer++750if Player_superBlendTimer >= 12751Player_superBlendTimer = 0752753Player_superBlendClr += 4754if Player_superBlendClr >= 24755Player_superBlendClr = 0756end if757end if758else759if Player_superBlendClr > 12760FlipSign(Player_superBlendClr)761Player_superBlendClr += 24762end if763764Player_superBlendTimer++765if Player_superBlendTimer >= 12766Player_superBlendTimer = 0767768Player_superBlendClr -= 4769if Player_superBlendClr <= 0770Player_superBlendClr = 0771Player_superState = SUPERSTATE_NONE772end if773end if774end if775776temp1 = Player_superBlendClr777778GetTableValue(temp0, temp1, Player_TailsSuperPal)779SetPaletteEntry(0, 13, temp0)780GetTableValue(temp0, temp1, Player_TailsSuperAltPal)781SetPaletteEntry(1, 13, temp0)782temp1++783784GetTableValue(temp0, temp1, Player_TailsSuperPal)785SetPaletteEntry(0, 17, temp0)786GetTableValue(temp0, temp1, Player_TailsSuperAltPal)787SetPaletteEntry(1, 17, temp0)788temp1++789790GetTableValue(temp0, temp1, Player_TailsSuperPal)791SetPaletteEntry(0, 18, temp0)792GetTableValue(temp0, temp1, Player_TailsSuperAltPal)793SetPaletteEntry(1, 18, temp0)794temp1++795796GetTableValue(temp0, temp1, Player_TailsSuperPal)797SetPaletteEntry(0, 16, temp0)798GetTableValue(temp0, temp1, Player_TailsSuperAltPal)799SetPaletteEntry(1, 16, temp0)800end function801802803public function Player_HandleSuperPalette_Knux804if Player_superState == SUPERSTATE_SUPER805Player_superBlendTimer++806if Player_superBlendTimer >= 12807Player_superBlendTimer = 9808809Player_superBlendClr += 3810if Player_superBlendClr >= 30811Player_superBlendTimer = 0812Player_superBlendClr = 0813end if814end if815else816if Player_superBlendClr > 15817FlipSign(Player_superBlendClr)818Player_superBlendClr += 30819end if820821Player_superBlendTimer++822if Player_superBlendTimer >= 12823Player_superBlendTimer = 0824825Player_superBlendClr -= 3826if Player_superBlendClr <= 0827Player_superBlendClr = 0828Player_superState = SUPERSTATE_NONE829end if830end if831end if832833temp1 = Player_superBlendClr834835GetTableValue(temp0, temp1, Player_KnuxSuperPal)836SetPaletteEntry(0, 26, temp0)837GetTableValue(temp0, temp1, Player_KnuxSuperAltPal)838SetPaletteEntry(1, 26, temp0)839temp1++840841GetTableValue(temp0, temp1, Player_KnuxSuperPal)842SetPaletteEntry(0, 27, temp0)843GetTableValue(temp0, temp1, Player_KnuxSuperAltPal)844SetPaletteEntry(1, 27, temp0)845temp1++846847GetTableValue(temp0, temp1, Player_KnuxSuperPal)848SetPaletteEntry(0, 28, temp0)849GetTableValue(temp0, temp1, Player_KnuxSuperAltPal)850SetPaletteEntry(1, 28, temp0)851end function852853854public function Player_HandleSuperPalette_Amy855#platform: USE_ORIGINS856if Player_superState == SUPERSTATE_SUPER857Player_superBlendTimer++858if Player_superBlendTimer >= 12859Player_superBlendTimer = 5860Player_superBlendClr += 5861if Player_superBlendClr >= 50862Player_superBlendClr = 0863end if864end if865else866if Player_superBlendClr > 15867FlipSign(Player_superBlendClr)868Player_superBlendClr += 50869end if870871Player_superBlendTimer++872if Player_superBlendTimer >= 12873Player_superBlendTimer = 0874Player_superBlendClr -= 5875if Player_superBlendClr <= 0876Player_superBlendClr = 0877Player_superState = SUPERSTATE_NONE878end if879end if880end if881882temp1 = Player_superBlendClr883884GetTableValue(temp0, temp1, Player_AmySuperPal)885SetPaletteEntry(0, 54, temp0)886GetTableValue(temp0, temp1, Player_AmySuperAltPal)887SetPaletteEntry(1, 54, temp0)888temp1++889890GetTableValue(temp0, temp1, Player_AmySuperPal)891SetPaletteEntry(0, 50, temp0)892GetTableValue(temp0, temp1, Player_AmySuperAltPal)893SetPaletteEntry(1, 50, temp0)894temp1++895896GetTableValue(temp0, temp1, Player_AmySuperPal)897SetPaletteEntry(0, 51, temp0)898GetTableValue(temp0, temp1, Player_AmySuperAltPal)899SetPaletteEntry(1, 51, temp0)900temp1++901902GetTableValue(temp0, temp1, Player_AmySuperPal)903SetPaletteEntry(0, 52, temp0)904GetTableValue(temp0, temp1, Player_AmySuperAltPal)905SetPaletteEntry(1, 52, temp0)906temp1++907908GetTableValue(temp0, temp1, Player_AmySuperPal)909SetPaletteEntry(0, 53, temp0)910GetTableValue(temp0, temp1, Player_AmySuperAltPal)911SetPaletteEntry(1, 53, temp0)912#endplatform913end function914915916public function Player_UpdatePhysicsState917// Bug Details:918// -> While this works fine in singleplayer and 2013's online multiplayer, this doesn't work as intended in Origins's local 2PVS919// Namely, this function here is looking at stage.playerListPos, which is P1's character ID, meaning that P2 will always assume P1's physics920// -> This means that, for example, you can have P2 Sonic with Knuckles's jump height, lots of softlocks incoming...921922switch stage.playerListPos923case PLAYER_SONIC_A924case PLAYER_SONIC_TAILS_A925temp0 = Player_SonicPhysicsTable926break927928case PLAYER_TAILS_A929temp0 = Player_TailsPhysicsTable930break931932case PLAYER_KNUCKLES_A933temp0 = Player_KnuxPhysicsTable934break935936#platform: USE_ORIGINS937case PLAYER_AMY_A938temp0 = Player_AmyPhysicsTable939break940#endplatform941end switch942943temp1 = 0944temp2 = 0945if stage.state != STAGE_FROZEN946temp3 = player[currentPlayer].ypos947temp3 >>= 16948CheckGreater(temp3, stage.waterLevel)949temp4 = checkResult950CheckNotEqual(player[currentPlayer].type, TypeName[Debug Mode])951temp4 &= checkResult952if temp4 == true953SetBit(temp1, 0, true)954player[currentPlayer].gravityStrength = 0x1000955else956player[currentPlayer].gravityStrength = 0x3800957end if958959if Player_superState == SUPERSTATE_SUPER960#platform: USE_ORIGINS961// Tails can no longer be silly :(962if player[currentPlayer].isSidekick == false963#endplatform964SetBit(temp1, 1, true)965temp2 = 2966#platform: USE_ORIGINS967end if968#endplatform969end if970971if player[currentPlayer].speedShoesTimer > 0972SetBit(temp1, 2, true)973temp2 = 1974end if975976temp1 <<= 3977end if978979GetTableValue(player[currentPlayer].topSpeed, temp1, temp0)980temp1++981GetTableValue(player[currentPlayer].acceleration, temp1, temp0)982player[currentPlayer].deceleration = player[currentPlayer].acceleration983player[currentPlayer].deceleration >>= temp2984temp1++985GetTableValue(player[currentPlayer].airAcceleration, temp1, temp0)986temp1++987GetTableValue(player[currentPlayer].airDeceleration, temp1, temp0)988temp1++989GetTableValue(player[currentPlayer].skidSpeed, temp1, temp0)990temp1++991GetTableValue(player[currentPlayer].rollingFriction, temp1, temp0)992temp1++993GetTableValue(player[currentPlayer].jumpStrength, temp1, temp0)994temp1++995GetTableValue(player[currentPlayer].jumpCap, temp1, temp0)996end function997998999public function Player_HandleSuperForm1000if Player_superState != SUPERSTATE_NONE1001switch stage.playerListPos1002case PLAYER_SONIC_A1003case PLAYER_SONIC_TAILS_A1004CallFunction(Player_HandleSuperPalette_Sonic)1005break10061007case PLAYER_TAILS_A1008CallFunction(Player_HandleSuperPalette_Tails)1009break10101011case PLAYER_KNUCKLES_A1012CallFunction(Player_HandleSuperPalette_Knux)1013break10141015#platform: USE_ORIGINS1016case PLAYER_AMY_A1017CallFunction(Player_HandleSuperPalette_Amy)1018break1019#endplatform1020end switch1021end if10221023if Player_superState == SUPERSTATE_SUPER1024player.invincibleTimer = 601025Player_superRingLossTimer++1026if Player_superRingLossTimer == 601027Player_superRingLossTimer = 010281029player.rings--1030if player.rings <= 01031player.rings = 01032Player_superState = SUPERSTATE_FADEOUT1033end if1034end if1035end if10361037if Player_superState == SUPERSTATE_FADEOUT1038if stage.playerListPos == PLAYER_SONIC_A1039LoadAnimation("Sonic.ani") // Restore the normal Sonic sprites1040end if10411042if music.currentTrack == TRACK_SUPER1043PlayMusic(TRACK_STAGE)1044end if10451046player.invincibleTimer = 01047currentPlayer = player.entityPos1048if player.state != Player_State_Death1049if player.state != Player_State_Drown1050arrayPos0 = currentPlayer1051arrayPos0 += playerCount1052CallFunction(Player_ApplyShield)1053end if1054end if10551056Player_superState = SUPERSTATE_END1057CallFunction(Player_UpdatePhysicsState)1058end if1059end function106010611062public function Player_CheckHit1063CheckEqual(player[currentPlayer].animation, ANI_JUMPING)1064temp0 = checkResult1065CheckEqual(player[currentPlayer].animation, ANI_SPINDASH)1066temp0 |= checkResult1067CheckEqual(player[currentPlayer].animation, ANI_GLIDING)1068temp0 |= checkResult1069CheckEqual(player[currentPlayer].animation, ANI_GLIDING_STOP)1070temp0 |= checkResult1071CheckNotEqual(player[currentPlayer].invincibleTimer, 0)1072temp0 |= checkResult10731074#platform: USE_ORIGINS1075// Amy's trusty Pico Pico Hammer can bash through anything!10761077// Bug Details:1078// This checks against P1's character ID, and while that's fine in singleplayer, it fails to account for P2 Amy in VS...1079// The reason these checks are here is because of AI Tails (These animations' IDs are the same as some of Tails' fly carry animations), though clearly they weren't implemented properly1080if stage.playerListPos == PLAYER_AMY1081if player[currentPlayer].isSidekick == false1082CheckEqual(player[currentPlayer].animation, ANI_HAMMER_JUMP)1083temp0 |= checkResult1084CheckEqual(player[currentPlayer].animation, ANI_HAMMER_DASH)1085temp0 |= checkResult1086end if1087end if1088#endplatform10891090// Tails can also destroy badniks when flying, but only if the badnik is above him (hitting his tails)1091// So check for that, too1092CheckEqual(player[currentPlayer].animation, ANI_FLYING)1093temp1 = checkResult1094CheckEqual(player[currentPlayer].animation, ANI_FLYINGTIRED)1095temp1 |= checkResult1096CheckEqual(player[currentPlayer].animation, ANI_FLY_LIFT_UP)1097temp1 |= checkResult1098CheckEqual(player[currentPlayer].animation, ANI_FLY_LIFT_DOWN)1099temp1 |= checkResult1100CheckEqual(player[currentPlayer].animation, ANI_FLY_LIFT_TIRED)1101temp1 |= checkResult1102if temp1 == true1103CheckGreater(player[currentPlayer].ypos, object.ypos)1104temp0 |= checkResult1105end if11061107if temp0 == true1108if player[currentPlayer].gravity == GRAVITY_AIR1109FlipSign(player[currentPlayer].xvel)1110player[currentPlayer].speed = player[currentPlayer].xvel1111player[currentPlayer].yvel += player[currentPlayer].gravityStrength1112player[currentPlayer].yvel += player[currentPlayer].gravityStrength1113FlipSign(player[currentPlayer].yvel)1114end if11151116if player[currentPlayer].animation == ANI_GLIDING1117player[currentPlayer].animation = ANI_GLIDING_DROP1118player[currentPlayer].state = Player_State_GlideDrop1119end if11201121checkResult = true1122else1123if player[currentPlayer].state != Player_State_Death1124if player[currentPlayer].invincibleTimer == 01125if player[currentPlayer].blinkTimer == 01126player[currentPlayer].state = Player_State_GotHit1127if player[currentPlayer].xpos > object.xpos1128player[currentPlayer].speed = 0x200001129else1130player[currentPlayer].speed = -0x200001131end if1132end if1133end if1134end if11351136checkResult = false1137end if1138end function113911401141public function Player_BadnikBreak1142CheckEqual(player[currentPlayer].animation, ANI_JUMPING)1143temp0 = checkResult1144CheckEqual(player[currentPlayer].animation, ANI_SPINDASH)1145temp0 |= checkResult1146CheckEqual(player[currentPlayer].animation, ANI_GLIDING)1147temp0 |= checkResult1148CheckEqual(player[currentPlayer].animation, ANI_GLIDING_STOP)1149temp0 |= checkResult1150CheckNotEqual(player[currentPlayer].invincibleTimer, 0)1151temp0 |= checkResult11521153#platform: USE_ORIGINS1154// Amy's trusty Pico Pico Hammer can bash through anything!11551156// Bug Details:1157// This checks against P1's character ID, and while that's fine in singleplayer, it fails to account for P2 Amy in VS...1158// The reason these checks are here is because of AI Tails (These animations' IDs are the same as some of Tails' fly carry animations), though clearly they weren't implemented properly1159if stage.playerListPos == PLAYER_AMY1160if player[currentPlayer].isSidekick == false1161CheckEqual(player[currentPlayer].animation, ANI_HAMMER_JUMP)1162temp0 |= checkResult1163CheckEqual(player[currentPlayer].animation, ANI_HAMMER_DASH)1164temp0 |= checkResult1165end if1166end if1167#endplatform11681169// Tails can also break badniks that are hit his tails while flying, check for that1170CheckEqual(player[currentPlayer].animation, ANI_FLYING)1171temp1 = checkResult1172CheckEqual(player[currentPlayer].animation, ANI_FLYINGTIRED)1173temp1 |= checkResult1174CheckEqual(player[currentPlayer].animation, ANI_FLY_LIFT_UP)1175temp1 |= checkResult1176CheckEqual(player[currentPlayer].animation, ANI_FLY_LIFT_DOWN)1177temp1 |= checkResult1178CheckEqual(player[currentPlayer].animation, ANI_FLY_LIFT_TIRED)1179temp1 |= checkResult1180if temp1 == true1181CheckGreater(player[currentPlayer].ypos, object.ypos)1182temp0 |= checkResult1183end if11841185#platform: USE_ORIGINS1186if game.playMode == BOOT_PLAYMODE_MISSION1187if stage.timeEnabled == false1188temp0 = false1189end if1190end if1191#endplatform11921193if temp0 == true1194#platform: USE_ORIGINS1195CheckCurrentStageFolder("Zone01") // Emerald Hill Zone1196if checkResult == true1197CheckEqual(object.type, TYPE_BUZZER)1198temp1 = checkResult1199CheckEqual(object.type, TYPE_BEE) // I do appreciate the gesture but, why? As-is, Bees are unused in both the main game and missions, were they planning to do something with them?1200temp1 |= checkResult1201if temp1 == true1202stageStat.buzzerDestroyCount++1203end if1204end if1205#endplatform12061207ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, object.xpos, object.ypos)1208Rand(checkResult, 32)1209if checkResult >= 161210CreateTempObject(animalType1, 0, object.xpos, object.ypos)1211else1212CreateTempObject(animalType2, 0, object.xpos, object.ypos)1213end if1214object[tempObjectPos].priority = PRIORITY_ACTIVE_SMALL12151216CreateTempObject(TypeName[Smoke Puff], 0, object.xpos, object.ypos)1217object[tempObjectPos].drawOrder = 412181219CreateTempObject(TypeName[Object Score], player[currentPlayer].badnikBonus, object.xpos, object.ypos)1220object[tempObjectPos].drawOrder = 412211222#platform: USE_STANDALONE1223PlaySfx(SfxName[Destroy], false)1224#endplatform12251226#platform: USE_ORIGINS1227// Bug Details: See above12281229temp2 = false12301231if stage.playerListPos == PLAYER_AMY1232if player[currentPlayer].isSidekick == false1233if player[currentPlayer].animation == ANI_HAMMER_JUMP1234temp2 = true1235end if12361237if player[currentPlayer].animation == ANI_HAMMER_DASH1238temp2 = true1239end if1240end if1241end if12421243if temp2 == true1244PlaySfx(SfxName[HammerHit], false)1245else1246PlaySfx(SfxName[Destroy], false)1247end if1248#endplatform12491250if player[currentPlayer].yvel > 01251if player[currentPlayer].ypos >= object.ypos1252player[currentPlayer].yvel -= 0x100001253else1254player[currentPlayer].yvel += player[currentPlayer].gravityStrength1255player[currentPlayer].yvel += player[currentPlayer].gravityStrength1256FlipSign(player[currentPlayer].yvel)1257end if1258else1259player[currentPlayer].yvel += 0x100001260end if1261temp1 = arrayPos012621263// global variable "array" (yes, this is actually how its done)1264if options.vsMode == false1265temp0 = currentPlayer1266currentPlayer = SLOT_PLAYER11267arrayPos0 = GLOBAL_PLAYERSCORE1268#platform: USE_DECOMP1269arrayPos0 = VarName[player.score]1270#endplatform1271else1272arrayPos0 = GLOBAL_PLAYERSCORE1273#platform: USE_DECOMP1274arrayPos0 = VarName[player.score]1275#endplatform1276arrayPos0 += currentPlayer1277end if12781279switch player[currentPlayer].badnikBonus1280case 01281global[arrayPos0] += 1001282break12831284case 11285global[arrayPos0] += 2001286break12871288case 21289global[arrayPos0] += 5001290break12911292case 31293case 41294case 51295case 61296case 71297case 81298case 91299case 101300case 111301case 121302case 131303case 141304global[arrayPos0] += 10001305break13061307case 151308global[arrayPos0] += 100001309break13101311end switch13121313if player[currentPlayer].badnikBonus < 151314player[currentPlayer].badnikBonus++1315end if13161317if options.vsMode == false1318currentPlayer = temp01319end if1320arrayPos0 = temp113211322#platform: USE_ORIGINS1323temp0 = 013241325// While it's used in Sonic 1, there aren't any missions in Sonic 2 which utilise this1326CheckEqual(player[currentPlayer].state, Player_State_Roll)1327temp1 = checkResult1328CheckEqual(player[currentPlayer].state, Player_State_RollJump)1329temp1 |= checkResult1330if temp1 == true1331if object.propertyValue == 01332temp0 = KILL_ENEMY_ATTR_SPINDASH1333stageStat.spindashDestroyCount++1334end if1335end if13361337// Same case for this, too1338CheckEqual(player[currentPlayer].state, Player_State_GlideLeft)1339temp1 = checkResult1340CheckEqual(player[currentPlayer].state, Player_State_GlideRight)1341temp1 |= checkResult1342if temp1 == true1343temp0 = KILL_ENEMY_ATTR_GLIDING1344end if13451346stageStat.badnikDestroyCount++13471348// This one's used, though1349CallNativeFunction2(NotifyCallback, NOTIFY_KILL_ENEMY, temp0)1350if game.playMode == BOOT_PLAYMODE_MISSION1351if game.missionFunctionNo == MISSIONNO_MERCY1352game.forceKillPlayer = true1353end if1354end if1355#endplatform1356else1357if player[currentPlayer].state != Player_State_Death1358if player[currentPlayer].invincibleTimer == 01359if player[currentPlayer].blinkTimer == 01360player[currentPlayer].state = Player_State_GotHit13611362#platform: USE_ORIGINS1363if game.playMode == BOOT_PLAYMODE_MISSION1364if game.missionFunctionNo == MISSIONNO_MERCY1365game.missionValue = true1366end if1367end if1368#endplatform13691370if player[currentPlayer].xpos > object.xpos1371player[currentPlayer].speed = 0x200001372else1373player[currentPlayer].speed = -0x200001374end if1375end if1376end if1377end if1378end if1379end function138013811382public function Player_Hit1383if player[currentPlayer].state != Player_State_Death1384arrayPos0 = player[currentPlayer].entityPos1385arrayPos0 += playerCount1386if player[currentPlayer].invincibleTimer == 01387if player[currentPlayer].blinkTimer == 01388player[currentPlayer].state = Player_State_GotHit1389if player[currentPlayer].xpos > object.xpos1390player[currentPlayer].speed = 0x200001391else1392player[currentPlayer].speed = -0x200001393end if1394end if1395end if1396end if1397end function139813991400public function Player_FireHit1401if player[currentPlayer].shield != SHIELD_FIRE1402if player[currentPlayer].state != Player_State_Death1403arrayPos0 = player[currentPlayer].entityPos1404arrayPos0 += playerCount1405if player[currentPlayer].invincibleTimer == 01406if player[currentPlayer].blinkTimer == 01407player[currentPlayer].state = Player_State_GotHit1408if player[currentPlayer].xpos > object.xpos1409player[currentPlayer].speed = 0x200001410else1411player[currentPlayer].speed = -0x200001412end if1413end if1414end if1415end if1416end if1417end function141814191420public function Player_LightningHit1421if player[currentPlayer].shield != SHIELD_LIGHTNING1422if player[currentPlayer].state != Player_State_Death1423arrayPos0 = player[currentPlayer].entityPos1424arrayPos0 += playerCount1425if player[currentPlayer].invincibleTimer == 01426if player[currentPlayer].blinkTimer == 01427player[currentPlayer].state = Player_State_GotHit1428if player[currentPlayer].xpos > object.xpos1429player[currentPlayer].speed = 0x200001430else1431player[currentPlayer].speed = -0x200001432end if1433end if1434end if1435end if1436end if1437end function143814391440public function Player_ProjectileHit1441if player[currentPlayer].shield > SHIELD_NORMAL // Only elemental shields should relfect projectiles1442temp0 = player[currentPlayer].xpos1443temp0 -= object.xpos14441445temp1 = player[currentPlayer].ypos1446temp1 -= object.ypos14471448ATan2(temp2, temp0, temp1)1449Sin256(temp0, temp2)1450Cos256(temp1, temp2)14511452object.xvel = temp11453object.xvel *= -0x8001454object.yvel = temp01455object.yvel *= -0x8001456else1457if player[currentPlayer].state != Player_State_Death1458arrayPos0 = player[currentPlayer].entityPos1459arrayPos0 += playerCount14601461if player[currentPlayer].invincibleTimer == 01462if player[currentPlayer].blinkTimer == 01463player[currentPlayer].state = Player_State_GotHit14641465if player[currentPlayer].xpos > object.xpos1466player[currentPlayer].speed = 0x200001467else1468player[currentPlayer].speed = -0x200001469end if1470end if1471end if1472end if1473end if1474end function147514761477public function Player_SpikeHit1478if player[currentPlayer].state != Player_State_Death1479arrayPos0 = player[currentPlayer].entityPos1480arrayPos0 += playerCount14811482if player[currentPlayer].invincibleTimer == 01483if player[currentPlayer].state != Player_State_GotHit1484if player[currentPlayer].state != Player_State_Hurt1485// Check for spike bug and player invulnerability1486// Do note though, by default spike bug is disabled in this game and there's no way to turn it on (disregading the Broken Monitor dead code) so only this second blink timer check actually does anything1487temp0 = options.spikeBehavior1488CheckEqual(player[currentPlayer].blinkTimer, 0)1489temp0 |= checkResult14901491if temp0 == true1492if player[currentPlayer].blinkTimer == 01493player[currentPlayer].blinkTimer = 21494end if14951496player[currentPlayer].state = Player_State_GotHit1497if player[currentPlayer].xpos > object.xpos1498player[currentPlayer].speed = 0x200001499else1500player[currentPlayer].speed = -0x200001501end if1502end if1503end if1504end if1505end if1506end if1507end function150815091510public function Player_Kill1511#platform: USE_ORIGINS1512// Bug Details:1513// This code was added in 2.0.1 to prevent the player from dying after clearing/failing a mission1514// However, they used temp0 here, which causes objects that use that variable when updating its position to disappear1515// (This bug was fixed in 2.0.0, but now it's back, hooray!)15161517temp0 = false1518if game.playMode == BOOT_PLAYMODE_MISSION1519if stage.timeEnabled == false1520temp0 = true1521end if1522end if15231524if temp0 == false1525CallFunction(Player_CheckIfOnScreen)1526if checkResult != false1527PlaySfx(SfxName[Hurt], false)1528end if1529#endplatform15301531#platform: USE_STANDALONE1532PlaySfx(SfxName[Hurt], false)1533#endplatform15341535player[currentPlayer].speed = 01536player[currentPlayer].xvel = 01537player[currentPlayer].yvel = -0x680001538player[currentPlayer].state = Player_State_Death1539player[currentPlayer].animation = ANI_DYING1540player[currentPlayer].tileCollisions = false1541player[currentPlayer].interaction = false1542player[currentPlayer].blinkTimer = 01543player[currentPlayer].visible = true1544#platform: USE_STANDALONE1545player[currentPlayer].sortedDrawOrder = 61546#endplatform1547#platform: USE_ORIGINS1548player[currentPlayer].sortedDrawOrder = 71549#endplatform15501551if options.vsMode == false1552if currentPlayer == 01553// If P1 is the one who died, then freeze everything else1554player[currentPlayer].priority = PRIORITY_ALWAYS1555if player[1].type == TypeName[Player 2 Object]1556player[1].priority = PRIORITY_ALWAYS1557end if15581559camera[0].enabled = false1560stage.state = STAGE_FROZEN1561end if1562else1563#platform: USE_STANDALONE1564if currentPlayer == camera[0].target1565camera[0].enabled = false1566end if1567#endplatform15681569#platform: USE_ORIGINS1570if currentPlayer == camera[currentPlayer].target1571camera[currentPlayer].style = CAMERASTYLE_STATIC1572end if1573#endplatform1574end if15751576// Move to the shield object slot1577arrayPos0 = currentPlayer1578arrayPos0 += playerCount15791580if object[arrayPos0].type == invincibilityType1581// This... doesn't actually seem to do anything1582object[arrayPos0].propertyValue = 31583end if15841585// Remove the player's shield1586object[arrayPos0].type = TypeName[Blank Object]1587player[currentPlayer].shield = SHIELD_NONE1588#platform: USE_ORIGINS1589else1590player[currentPlayer].disableGravity = true1591end if1592#endplatform1593end function159415951596public function Player_ProcessUpdate1597if options.attractMode == false1598#platform: USE_STANDALONE1599if player.controlMode == CONTROLMODE_P11600// No control lock active right now, process player control16011602// Check if the player's touched the bottom left of the screen1603CheckTouchRect(0, 96, screen.xcenter, screen.ysize)16041605if checkResult > -11606arrayPos0 = checkResult16071608temp0 = touchscreen[arrayPos0].xpos1609temp0 -= saveRAM[39] // Virtual DPad X Pos16101611temp1 = touchscreen[arrayPos0].ypos1612temp1 -= saveRAM[40] // Virtual DPad Y Pos16131614ATan2(temp2, temp0, temp1)1615temp2 += 321616temp2 &= 2551617temp2 >>= 616181619switch temp21620case 01621keyDown[1].right = true1622break16231624case 11625keyDown[1].down = true1626break16271628case 21629keyDown[1].left = true1630break16311632case 31633keyDown[1].up = true1634break1635end switch1636end if16371638// And now check if the player's touched the jump button portion of the touch screen1639CheckTouchRect(screen.xcenter, 96, screen.xsize, 240)16401641if checkResult > -11642keyDown[1].buttonA = true1643end if16441645// Update touchJump1646// (touchJump is the state of the touchscreen jump button the previous frame, used to differenciate new taps from previous holds)1647if touchJump == false1648keyPress[1].buttonA |= keyDown[1].buttonA1649end if1650touchJump = keyDown[1].buttonA16511652if stage.debugMode == true1653// If in Debug Mode, check for the item switcher button too1654CheckTouchRect(0, 0, 112, 56)1655if checkResult > -11656keyDown[1].buttonB = true1657end if16581659// Update touchDebug too, it's the B button equivalent of touchJump1660if touchDebug == false1661keyPress[1].buttonB |= keyDown[1].buttonB1662end if1663touchDebug = keyDown[1].buttonB1664end if16651666// Check for the pause button being pressed as well1667CheckTouchRect(240, 0, screen.xsize, 40)1668if checkResult > -11669if options.vsMode == false1670PlaySfx(SfxName[Menu Back], false)1671StopSfx(SfxName[Flying])1672StopSfx(SfxName[Tired])1673engine.state = 51674end if1675end if16761677if keyPress[0].start == true1678if options.vsMode == false1679PlaySfx(SfxName[Menu Back], false)1680StopSfx(SfxName[Flying])1681StopSfx(SfxName[Tired])1682engine.state = 51683end if1684end if1685end if1686#endplatform16871688#platform: USE_ORIGINS1689// Origins doesn't have any of that fancy touch stuff to account for, just a single pause button1690if keyPress[1].start == true1691engine.state = 51692end if1693#endplatform16941695// Call the function for supporting physical gamepads as well1696ProcessObjectControl()16971698if options.vsMode == true1699// If in comp mode, send over the player at this point1700CallNativeFunction2(SendEntity, 0, false)1701end if1702else1703// No pausing during credits1704// (I don't think this actually does anything, though..? Sonic 2 doesn't have in-game credits like Sonic 1 did)1705if credits.screen == 01706#platform: USE_STANDALONE1707// Allow skipping of the demo by pausing1708CheckTouchRect(0, 0, screen.xsize, screen.ysize)1709if keyPress[0].start == true1710checkResult = 01711end if17121713if checkResult > -11714if Player_attractDuration > 11715Player_attractDuration = 11716end if1717end if17181719if keyPress[0].start == true1720if Player_attractDuration > 11721Player_attractDuration = 11722end if1723end if1724#endplatform17251726#platform: USE_ORIGINS1727if keyPress[1].start == true1728if Player_attractDuration > 11729Player_attractDuration = 11730end if1731end if1732#endplatform1733end if17341735if player.controlMode == CONTROLMODE_P11736Player_attractFrameCount--1737if Player_attractFrameCount < 11738if Player_attractTablePos < Player_attractTableSize1739GetTableValue(temp0, Player_attractTablePos, Player_attractTable)1740GetBit(player.up, temp0, 0)1741GetBit(player.down, temp0, 1)1742GetBit(player.left, temp0, 2)1743GetBit(player.right, temp0, 3)1744GetBit(player.jumpPress, temp0, 4)1745GetBit(player.jumpHold, temp0, 5)1746Player_attractTablePos++1747GetTableValue(Player_attractFrameCount, Player_attractTablePos, Player_attractTable)1748Player_attractTablePos++1749end if1750else1751if player.jumpPress == true1752player.jumpPress = false1753end if1754end if17551756if Player_attractDuration > 01757Player_attractDuration--1758if Player_attractDuration < 11759ResetObjectEntity(SLOT_TITLECARD, TypeName[Title Card], 0, 0, 0)1760object[SLOT_TITLECARD].state = 81761object[SLOT_TITLECARD].priority = PRIORITY_ACTIVE1762object[SLOT_TITLECARD].drawOrder = 61763player.invincibleTimer = 801764camera[0].enabled = false1765end if1766end if1767end if1768end if17691770if player.speedShoesTimer > 01771player.speedShoesTimer--1772if player.speedShoesTimer < 11773currentPlayer = player.entityPos1774CallFunction(Player_UpdatePhysicsState)17751776// If any player has speed shoes, keep the sped-up music1777temp0 = false1778foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)1779temp0 += player[currentPlayer].speedShoesTimer1780next17811782if temp0 == false1783if SlowDownMusic != 01784CallFunction(SlowDownMusic)1785end if1786end if17871788player.speedShoesTimer = 01789end if1790end if17911792if player.state != Player_State_Hurt1793if player.blinkTimer > 01794player.blinkTimer--17951796GetBit(temp0, player.blinkTimer, 2)1797if temp0 == true1798player.visible = false1799else1800player.visible = true1801end if1802end if1803end if18041805if player.invincibleTimer > 01806player.invincibleTimer--1807if player.invincibleTimer == 01808// If any player is invincible, continue playing the invincibility music1809temp0 = false1810foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)1811temp0 += player[currentPlayer].invincibleTimer1812next18131814if temp0 == false1815if music.currentTrack == TRACK_INVINCIBLE1816PlayMusic(TRACK_STAGE)1817end if1818end if18191820if object[+playerCount].type == invincibilityType1821currentPlayer = player.entityPos1822arrayPos0 = currentPlayer1823arrayPos0 += playerCount1824CallFunction(Player_ApplyShield)1825end if1826end if1827end if18281829if player.state != Player_State_LookUp1830if player.state != Player_State_Crouch1831// Move the camera back to its normal position1832if player.lookPosY > 01833player.lookPosY -= 21834end if18351836if player.lookPosY < 01837player.lookPosY += 21838end if1839end if1840end if18411842// After a spindash release, restore the camera back to normal after a few short moments1843if player.scrollDelay > 01844player.scrollDelay--1845if player.scrollDelay == 01846currentPlayer = player.entityPos1847if player.entityPos == camera[currentPlayer].target1848// Restore the camera's state1849camera[currentPlayer].style = CAMERASTYLE_FOLLOW1850end if1851end if1852end if18531854if player.state != Player_State_Fly1855if player.flightVelocity != 01856// As a fail-safe, if not flying, enforce that the SFX stop playing as well1857StopSfx(SfxName[Flying])1858StopSfx(SfxName[Tired])1859player.flightVelocity = 01860end if1861end if1862end function186318641865public function Player_State_Static1866checkResult = false1867end function186818691870public function Player_HandleRollAnimSpeed1871if player.character == PLAYER_TAILS_A1872player.rollAnimationSpeed = 1201873else1874player.rollAnimationSpeed = player.speed1875if player.rollAnimationSpeed < 01876FlipSign(player.rollAnimationSpeed)1877end if18781879player.rollAnimationSpeed *= 2401880player.rollAnimationSpeed /= 0x600001881player.rollAnimationSpeed += 481882end if1883end function188418851886public function Player_HandleWalkAnimSpeed1887player.animationSpeed = player.speed18881889if player.animationSpeed < 01890FlipSign(player.animationSpeed)1891end if18921893player.animationSpeed *= 601894player.animationSpeed /= 0x600001895player.animationSpeed += 201896end function189718981899public function Player_HandleRunAnimSpeed1900player.animationSpeed = player.speed19011902if player.animationSpeed < 01903FlipSign(player.animationSpeed)1904end if19051906player.animationSpeed *= 801907player.animationSpeed /= 0x600001908end function190919101911public function Player_HandleGroundMovement1912if player.controlLock > 01913// No moving while the control lock is active, simply just adjust player speed dependong on their angle for right now1914player.controlLock--1915Sin256(temp0, player.angle)1916temp0 *= 0x20001917temp0 >>= 81918player.speed += temp01919else1920if player.left == true1921temp0 = player.topSpeed1922FlipSign(temp0)1923if player.speed > temp01924if player.speed > 01925if player.collisionMode == CMODE_FLOOR1926if player.speed > 0x400001927player.skidding = 161928end if1929end if19301931if player.speed < player.skidSpeed1932player.speed = player.skidSpeed1933FlipSign(player.speed)1934player.skidding = 01935else1936player.speed -= player.skidSpeed1937end if1938else1939player.speed -= player.acceleration1940player.skidding = 01941end if1942end if19431944if player.speed <= 01945player.direction = FACING_LEFT1946end if1947end if19481949if player.right == true1950if player.speed < player.topSpeed1951if player.speed < 01952if player.collisionMode == CMODE_FLOOR1953if player.speed < -0x400001954player.skidding = 161955end if1956end if19571958temp0 = player.skidSpeed1959FlipSign(temp0)1960if player.speed > temp01961player.speed = player.skidSpeed1962player.skidding = 01963else1964player.speed += player.skidSpeed1965end if1966else1967player.speed += player.acceleration1968player.skidding = 01969end if1970end if19711972if player.speed >= 01973player.direction = FACING_RIGHT1974end if1975end if19761977temp0 = player.left1978temp0 |= player.right1979if temp0 == false1980if player.speed > 01981player.speed -= player.deceleration1982if player.speed < 01983player.speed = 01984end if1985else1986player.speed += player.deceleration1987if player.speed > 01988player.speed = 01989end if1990end if19911992if player.speed > 0x20001993Sin256(temp0, player.angle)1994temp0 *= 0x20001995temp0 >>= 81996player.speed += temp01997end if19981999if player.speed < -0x20002000Sin256(temp0, player.angle)2001temp0 *= 0x20002002temp0 >>= 82003player.speed += temp02004end if20052006if player.angle > 1922007if player.angle < 2282008if player.speed > -0x100002009if player.speed < 0x100002010player.controlLock = 302011end if2012end if2013end if2014end if20152016if player.angle > 282017if player.angle < 642018if player.speed > -0x100002019if player.speed < 0x100002020player.controlLock = 302021end if2022end if2023end if2024end if2025else2026Sin256(temp0, player.angle)2027temp0 *= 0x20002028temp0 >>= 82029player.speed += temp02030if player.right == true2031if player.left == false2032if player.angle > 1922033if player.angle < 2282034if player.speed < 0x280002035if player.speed > -0x200002036player.controlLock = 302037end if2038end if2039end if2040end if2041end if2042else2043if player.left == true2044if player.angle > 282045if player.angle < 642046if player.speed > -0x280002047if player.speed < 0x200002048player.controlLock = 302049end if2050end if2051end if2052end if2053end if2054end if2055end if20562057if options.speedCap == true2058// Enforce the speed cap2059if player.left == true2060temp0 = player.topSpeed2061FlipSign(temp0)2062if player.speed < temp02063player.speed = temp02064end if2065end if20662067if player.right == true2068if player.speed > player.topSpeed2069player.speed = player.topSpeed2070end if2071end if2072end if2073end if20742075switch player.collisionMode2076case CMODE_LWALL2077if player.angle <= 1922078if player.speed > -0x200002079if player.speed < 0x200002080player.gravity = GRAVITY_AIR2081player.angle = 02082player.collisionMode = CMODE_FLOOR2083player.speed = player.xvel2084end if2085end if2086end if2087break20882089case CMODE_ROOF2090if player.speed > -0x200002091if player.speed < 0x200002092player.gravity = GRAVITY_AIR2093player.angle = 02094player.collisionMode = CMODE_FLOOR2095player.speed = player.xvel2096end if2097end if2098break20992100case CMODE_RWALL2101if player.angle >= 642102if player.speed > -0x200002103if player.speed < 0x200002104player.gravity = GRAVITY_AIR2105player.angle = 02106player.collisionMode = CMODE_FLOOR2107player.speed = player.xvel2108end if2109end if2110end if2111break21122113end switch2114end function211521162117public function Player_HandleAirFriction2118if player.yvel > -0x400002119if player.yvel < 02120temp0 = player.speed2121temp0 >>= 52122player.speed -= temp02123end if2124end if21252126temp0 = player.topSpeed2127FlipSign(temp0)2128if player.speed > temp02129if player.left == true2130player.speed -= player.airAcceleration2131player.direction = FACING_LEFT2132end if2133else2134if player.left == true2135player.direction = FACING_LEFT2136end if2137end if21382139if player.speed < player.topSpeed2140if player.right == true2141player.speed += player.airAcceleration2142player.direction = FACING_RIGHT2143end if2144else2145if player.right == true2146player.direction = FACING_RIGHT2147end if2148end if21492150if options.airSpeedCap == true2151if player.left == true2152temp0 = player.topSpeed2153FlipSign(temp0)2154if player.speed < temp02155player.speed = temp02156end if2157end if21582159if player.right == true2160if player.speed > player.topSpeed2161player.speed = player.topSpeed2162end if2163end if2164end if21652166#platform: USE_ORIGINS2167if game.playMode == BOOT_PLAYMODE_MISSION2168if stage.timeEnabled == false2169temp1 = screen.yoffset2170temp1 += screen.ysize2171temp1 += 402172if player.iypos > temp12173player.iypos = temp12174end if2175end if2176end if2177#endplatform2178end function217921802181public function Player_HandleRollDeceleration2182if player.right == true2183if player.speed < 02184player.speed += player.rollingDeceleration2185end if2186end if21872188if player.left == true2189if player.speed > 02190player.speed -= player.rollingDeceleration2191end if2192end if21932194temp1 = player.speed2195if player.speed > 02196player.speed -= player.rollingFriction2197Sin256(temp0, player.angle)2198if temp0 > 02199Sin256(temp0, player.angle)2200temp0 *= 0x50002201else2202Sin256(temp0, player.angle)2203temp0 *= 0x14002204end if2205temp0 >>= 82206player.speed += temp02207if player.speed > 0x1200002208player.speed = 0x1200002209end if2210else2211player.speed += player.rollingFriction22122213Sin256(temp0, player.angle)2214if temp0 < 02215Sin256(temp0, player.angle)2216temp0 *= 0x50002217else2218Sin256(temp0, player.angle)2219temp0 *= 0x14002220end if2221temp0 >>= 822222223player.speed += temp02224if player.speed < -0x1200002225player.speed = -0x1200002226end if2227end if22282229switch player.collisionMode2230case CMODE_FLOOR2231case CMODE_ROOF2232if temp1 > 02233if player.speed < 02234player.speed = 02235player.state = Player_State_Ground2236end if2237else2238if player.speed > 02239player.speed = 02240player.state = Player_State_Ground2241end if2242end if2243break22442245case CMODE_LWALL2246if player.angle < 1932247if temp1 > 02248if player.speed < 0x200002249player.gravity = GRAVITY_AIR2250player.xvel = 02251player.speed = 02252end if2253end if2254end if2255break22562257case CMODE_RWALL2258if player.angle > 632259if temp1 < 02260if player.speed > -0x200002261player.gravity = GRAVITY_AIR2262player.xvel = 02263player.speed = 02264end if2265end if2266end if2267break22682269end switch2270end function227122722273public function Player_HandleAirMovement2274player.scrollTracking = true22752276#platform: USE_STANDALONE2277player.yvel += player.gravityStrength2278#endplatform22792280#platform: USE_ORIGINS2281// Bug Details:2282// Sonic Team wrapped this in a check, where if you init "Player_Kill" while the stage is finished,2283// -> it disables the gravity of the player (in Mission Mode)2284// However, this check uses the "currentPlayer" array, and while this is no issue for the other characters,2285// -> it used to become one for Tails (as either Tails Object or Player 2 Object)2286// This results in various issues in Origins 2.0.1, such as crashes, Tails losing gravity, etc.2287// This was fixed (kinda) in Origins 2.0.2, see Tails Object.22882289if player[currentPlayer].disableGravity == false2290player.yvel += player.gravityStrength2291end if2292#endplatform22932294if player.yvel < player.jumpCap2295if player.jumpHold == false2296if player.timer > 02297player.yvel = player.jumpCap2298temp0 = player.speed2299temp0 >>= 52300player.speed -= temp02301end if2302end if2303end if2304player.xvel = player.speed23052306if player.rotation < 2562307if player.rotation > 02308player.rotation -= 42309else2310player.rotation = 02311end if2312else2313if player.rotation < 5122314player.rotation += 42315else2316player.rotation = 02317end if2318end if23192320player.collisionMode = CMODE_FLOOR2321if player.animation == ANI_JUMPING2322player.animationSpeed = player.rollAnimationSpeed2323end if2324end function232523262327public function Player_HandleOnGround2328player.scrollTracking = false2329Cos256(temp0, player.angle)2330temp0 *= player.speed2331temp0 >>= 82332player.xvel = temp023332334Sin256(temp0, player.angle)2335temp0 *= player.speed2336temp0 >>= 82337player.yvel = temp02338end function233923402341public function Player_Action_Jump2342// Let's mind our head!!!2343temp1 = false2344if player.collisionMode == CMODE_FLOOR2345temp6 = player.xpos2346temp7 = player.ypos2347temp0 = player.collisionTop2348temp0 -= 22349ObjectTileCollision(CSIDE_ROOF, 0, temp0, player.collisionPlane)23502351temp1 = checkResult2352player.xpos = temp62353player.ypos = temp72354temp0 = player.collisionBottom2355if player.animation != ANI_JUMPING2356player.iypos -= player.jumpOffset2357temp0 += player.jumpOffset2358end if2359ObjectTileCollision(CSIDE_FLOOR, 0, temp0, player.collisionPlane)2360end if23612362if temp1 == false2363player.controlLock = 02364player.gravity = GRAVITY_AIR2365temp1 = player.jumpStrength2366temp1 += player.gravityStrength2367Sin256(player.xvel, player.angle)2368player.xvel *= temp12369Cos256(temp0, player.angle)2370temp0 *= player.speed2371player.xvel += temp02372player.xvel >>= 823732374Sin256(player.yvel, player.angle)2375player.yvel *= player.speed2376Cos256(temp0, player.angle)2377temp0 *= temp12378player.yvel -= temp02379player.yvel >>= 823802381player.speed = player.xvel2382player.scrollTracking = true2383player.animation = ANI_JUMPING2384player.angle = 02385player.collisionMode = CMODE_FLOOR2386player.timer = 12387CallFunction(Player_HandleRollAnimSpeed)23882389if player.state == Player_State_Roll2390player.state = Player_State_RollJump2391else2392player.state = Player_State_Air2393end if23942395#platform: USE_STANDALONE2396PlaySfx(SfxName[Jump], false)2397#endplatform23982399#platform: USE_ORIGINS2400// This was introduced in 1.0.4 in order to make P2 Tails's jump SFX less obnoxious when he's off-screen2401currentPlayer = player.entityPos2402CallFunction(Player_CheckIfOnScreen)2403if checkResult != false2404PlaySfx(SfxName[Jump], false)2405end if2406#endplatform24072408player.collisionDisabled = true2409player.jumpAbilityState = 12410end if24112412#platform: USE_ORIGINS2413if game.playMode == BOOT_PLAYMODE_CLASSIC2414temp7 = -12415else2416temp7 = 02417end if2418CallFunction(Player_SetDropDashCharge)2419#endplatform2420end function242124222423public function Player_Action_Spindash2424player.state = Player_State_Spindash2425player.animation = ANI_SPINDASH2426player.abilityTimer = 024272428#platform: USE_ORIGINS2429// Don't play the Charge sound effect if using the Drop Dash2430CheckEqual(player.releasingDropDash, true)2431temp0 = checkResult2432CallFunction(Player_GetDropDashCharge)2433CheckGreater(20, temp7)2434temp0 |= checkResult2435if temp0 == true2436PlaySfx(SfxName[Charge], false)2437end if2438#endplatform24392440#platform: USE_STANDALONE2441PlaySfx(SfxName[Charge], false)2442#endplatform24432444CreateTempObject(TypeName[Dust Puff], player.entityPos, player.xpos, player.ypos)2445object[tempObjectPos].iypos = player.collisionBottom2446object[tempObjectPos].ypos += player.ypos2447object[tempObjectPos].frame = 42448object[tempObjectPos].drawOrder = 42449object[tempObjectPos].direction = player.direction2450end function245124522453public function Player_State_Transform2454player.collisionDisabled = true24552456player.timer--2457if player.timer == 02458#platform: USE_STANDALONE2459player.state = Player_State_Air2460#endplatform2461#platform: USE_ORIGINS2462player.state = Player_State_Air_NoDropDash2463#endplatform2464player.animation = ANI_WALKING2465end if2466end function246724682469public function Player_TryTransform2470if stage.timeEnabled == true2471// Move to the shield object slot and spawn a Super Spark there2472arrayPos0 = currentPlayer2473arrayPos0 += playerCount2474ResetObjectEntity(arrayPos0, TypeName[Super Spark], 0, player[SLOT_PLAYER1].xpos, player[SLOT_PLAYER1].ypos)2475object[arrayPos0].priority = PRIORITY_ACTIVE24762477PlaySfx(SfxName[Transform], false)2478PlayMusic(TRACK_SUPER)24792480Player_superState = SUPERSTATE_SUPER2481player[currentPlayer].invincibleTimer = 602482player[currentPlayer].blinkTimer = 02483player[currentPlayer].visible = true24842485CallFunction(Player_UpdatePhysicsState)2486if stage.playerListPos == PLAYER_SONIC_A2487LoadAnimation("SuperSonic.ani")2488end if24892490player[currentPlayer].state = Player_State_Transform2491player[currentPlayer].collisionDisabled = true2492player[currentPlayer].animation = ANI_SUPER_TRANSFORM2493player[currentPlayer].timer = 242494end if2495end function249624972498public function Player_State_BubbleBounce2499CallFunction(Player_HandleAirFriction)2500CheckNotEqual(player.shield, SHIELD_BUBBLE)2501temp0 = checkResult2502CheckNotEqual(player.invincibleTimer, 0)2503temp0 |= checkResult2504CheckEqual(Player_superState, SUPERSTATE_SUPER)2505temp0 |= checkResult25062507if temp0 == true2508#platform: USE_STANDALONE2509player.state = Player_State_Air2510#endplatform2511#platform: USE_ORIGINS2512player.state = Player_State_Air_NoDropDash2513#endplatform2514else2515if player.gravity == GRAVITY_AIR2516CallFunction(Player_HandleAirMovement)2517else2518player.jumpAbilityState = 12519player.gravity = GRAVITY_AIR2520if player.jumpStrength == 0x380002521temp1 = -0x400002522else2523temp1 = -0x780002524end if2525temp1 += player.gravityStrength2526Sin256(player.xvel, player.angle)2527player.xvel *= temp12528Cos256(temp0, player.angle)2529temp0 *= player.speed2530player.xvel += temp02531player.xvel >>= 825322533Sin256(player.yvel, player.angle)2534player.yvel *= player.speed2535Cos256(temp0, player.angle)2536temp0 *= temp12537player.yvel = temp02538player.yvel >>= 825392540player.speed = player.xvel2541player.scrollTracking = true2542player.animation = ANI_JUMPING2543player.angle = 02544player.collisionMode = CMODE_FLOOR2545player.timer = 12546CallFunction(Player_HandleRollAnimSpeed)2547#platform: USE_STANDALONE2548player.state = Player_State_Air2549#endplatform2550#platform: USE_ORIGINS2551player.state = Player_State_Air_NoDropDash2552#endplatform2553PlaySfx(SfxName[Bubble Bounce], false)2554object[+playerCount].state = 42555end if2556end if2557end function255825592560public function Player_Action_DblJumpSonic2561#platform: USE_ORIGINS2562if keyPress[1].buttonY != false2563CheckEqual(specialStage.emeralds, 0x7F)2564temp0 = checkResult2565CheckGreater(player.rings, 49)2566temp0 &= checkResult2567CheckNotEqual(Player_superState, SUPERSTATE_SUPER)2568temp0 &= checkResult2569CheckNotEqual(object[SLOT_ACTFINISH].type, TypeName[Act Finish])2570temp0 &= checkResult25712572if temp0 == true2573currentPlayer = player.entityPos2574CallFunction(Player_TryTransform)2575CallNativeFunction4(NotifyCallback, NOTIFY_STATS_CHARA_ACTION, 1, 0, 0)2576end if2577end if2578#endplatform25792580if player.jumpPress == true2581#platform: USE_STANDALONE2582CheckEqual(specialStage.emeralds, 0x7F)2583temp0 = checkResult2584CheckGreater(player.rings, 49)2585temp0 &= checkResult2586CheckNotEqual(Player_superState, SUPERSTATE_SUPER)2587temp0 &= checkResult2588CheckNotEqual(object[SLOT_ACTFINISH].type, TypeName[Act Finish])2589temp0 &= checkResult25902591if temp0 == true2592currentPlayer = player.entityPos2593CallFunction(Player_TryTransform)2594else2595#endplatform2596CheckEqual(player.invincibleTimer, 0)2597temp0 = checkResult2598CheckNotEqual(Player_superState, SUPERSTATE_SUPER)2599temp0 &= checkResult26002601if temp0 == true2602switch player.shield2603case SHIELD_NONE2604temp0 = options.shieldType2605temp0 &= SHIELDTYPE_S3 // (see if it's S2 or S3 shields, ignore whether or not it's set to random)2606if temp0 > SHIELDTYPE_S22607PlaySfx(SfxName[Insta Shield], false)2608if object[+playerCount].type == TypeName[Blank Object]2609currentPlayer = player.entityPos2610arrayPos0 = currentPlayer2611arrayPos0 += playerCount2612ResetObjectEntity(arrayPos0, TypeName[Insta Shield], 0, 0, 0)2613object[arrayPos0].priority = PRIORITY_ACTIVE2614end if26152616player.jumpAbilityState = 22617object[+playerCount].state = 1 // (this does nothing btw)2618if player.state == Player_State_RollJump2619player.state = Player_State_Air2620end if2621end if2622break26232624case SHIELD_NORMAL2625break26262627case SHIELD_BUBBLE2628PlaySfx(SfxName[Bubble Bounce], false)2629player.yvel = 0x800002630player.xvel = 02631player.speed = player.xvel2632player.jumpAbilityState = 22633player.state = Player_State_BubbleBounce2634object[+playerCount].state = BUBBLESHIELD_BOUNCE_SETUP2635break26362637case SHIELD_FIRE2638PlaySfx(SfxName[Fire Dash], false)2639GetBit(temp0, player.direction, 0)2640if temp0 == FLIP_NONE2641player.xvel = 0x800002642else2643player.xvel = -0x800002644end if26452646player.speed = player.xvel2647player.yvel = 02648player.jumpAbilityState = 22649currentPlayer = player.entityPos2650if player.entityPos == camera[currentPlayer].target2651player.scrollDelay = 152652camera[currentPlayer].style = CAMERASTYLE_HLOCKED2653end if26542655if player.state == Player_State_RollJump2656player.state = Player_State_Air2657end if26582659object[+playerCount].state = FIRESHIELD_DASH_SETUP2660object[+playerCount].direction = player.direction2661break26622663case SHIELD_LIGHTNING2664PlaySfx(SfxName[Lightning Jump], false)2665player.yvel = -0x580002666player.jumpAbilityState = 226672668CreateTempObject(TypeName[Lightning Spark], 0, player.xpos, player.ypos)2669object[tempObjectPos].xvel = -0x200002670object[tempObjectPos].yvel = -0x2000026712672CreateTempObject(TypeName[Lightning Spark], 0, player.xpos, player.ypos)2673object[tempObjectPos].xvel = 0x200002674object[tempObjectPos].yvel = -0x2000026752676CreateTempObject(TypeName[Lightning Spark], 0, player.xpos, player.ypos)2677object[tempObjectPos].xvel = -0x200002678object[tempObjectPos].yvel = 0x2000026792680CreateTempObject(TypeName[Lightning Spark], 0, player.xpos, player.ypos)2681object[tempObjectPos].xvel = 0x200002682object[tempObjectPos].yvel = 0x2000026832684if player.state == Player_State_RollJump2685player.state = Player_State_Air2686end if2687break2688end switch2689end if2690#platform: USE_STANDALONE2691end if2692#endplatform2693end if2694end function269526962697public function Player_Action_DblJumpTails2698#platform: USE_ORIGINS2699// Tails can't even transform in Origins normally and yet they updated this anyway... how nice of them!2700if keyPress[1].buttonY != false2701CheckEqual(specialStage.emeralds, 0x7F)2702temp0 = checkResult2703CheckGreater(player.rings, 49)2704temp0 &= checkResult2705CheckNotEqual(Player_superState, SUPERSTATE_SUPER)2706temp0 &= checkResult2707CheckEqual(options.superTails, true)2708temp0 &= checkResult27092710if temp0 == true2711currentPlayer = player.entityPos2712CallFunction(Player_TryTransform)2713end if2714end if2715#endplatform27162717if player.jumpPress == true2718#platform: USE_STANDALONE2719CheckEqual(specialStage.emeralds, 0x7F)2720temp0 = checkResult2721CheckGreater(player.rings, 49)2722temp0 &= checkResult2723CheckNotEqual(Player_superState, SUPERSTATE_SUPER)2724temp0 &= checkResult2725CheckEqual(options.superTails, true)2726temp0 &= checkResult27272728if temp0 == true2729currentPlayer = player.entityPos2730CallFunction(Player_TryTransform)2731else2732#endplatform2733#platform: USE_ORIGINS2734if player.isSidekick == false2735CallNativeFunction4(NotifyCallback, NOTIFY_STATS_CHARA_ACTION, 0, 1, 0)2736end if2737#endplatform27382739player.timer = 02740player.state = Player_State_Fly2741player.flightVelocity = 0x80027422743if player.gravityStrength == 0x38002744PlaySfx(SfxName[Flying], true)2745player.animation = ANI_FLYING2746else2747player.animation = ANI_SWIMMING2748end if2749#platform: USE_STANDALONE2750end if2751#endplatform2752end if2753end function275427552756public function Player_Action_DblJumpKnux2757#platform: USE_ORIGINS2758if keyPress[1].buttonY != false2759CheckEqual(specialStage.emeralds, 0x7F)2760temp0 = checkResult2761CheckGreater(player.rings, 49)2762temp0 &= checkResult2763CheckNotEqual(Player_superState, SUPERSTATE_SUPER)2764temp0 &= checkResult27652766if temp0 == true2767currentPlayer = player.entityPos2768CallFunction(Player_TryTransform)2769end if2770end if2771#endplatform27722773if player.jumpPress == true2774#platform: USE_STANDALONE2775CheckEqual(specialStage.emeralds, 0x7F)2776temp0 = checkResult2777CheckGreater(player.rings, 49)2778temp0 &= checkResult2779CheckNotEqual(Player_superState, SUPERSTATE_SUPER)2780temp0 &= checkResult27812782if temp0 == true2783currentPlayer = player.entityPos2784CallFunction(Player_TryTransform)2785else2786#endplatform2787#platform: USE_ORIGINS2788if player.isSidekick == false // Knuckles is never a sidekick LOL2789CallNativeFunction4(NotifyCallback, NOTIFY_STATS_CHARA_ACTION2, 1, 0, 0)2790end if2791#endplatform27922793player.speed = 0x400002794if player.yvel < 02795player.yvel = 02796end if27972798if player.direction == FACING_RIGHT2799player.state = Player_State_GlideRight2800player.xvel = 0x400002801player.timer = 02802else2803player.state = Player_State_GlideLeft2804player.xvel = -0x400002805player.timer = 2562806end if28072808player.animation = ANI_GLIDING2809player.frame = 22810#platform: USE_STANDALONE2811end if2812#endplatform2813end if2814end function281528162817// Handles activating the Drop Dash (Check Player_State_Air or Player_State_RollJump for releasing it)2818// Both Sonic and Amy use this function in Origins Plus, how fun!2819public function Player_HandleDropDash2820#platform: USE_ORIGINS2821if player.releasingDropDash == false2822CallFunction(Player_GetDropDashCharge)2823if temp7 >= 02824if temp7 == 02825if player.jumpPress == true2826switch player.character2827case PLAYER_SONIC_A2828CheckEqual(player.character, PLAYER_SONIC_A) // A bit redundant here, but whatever2829temp0 = checkResult2830// You can't use the Drop Dash with elemental shields2831CheckNotEqual(player.shield, SHIELD_BUBBLE)2832temp0 &= checkResult2833CheckNotEqual(player.shield, SHIELD_FIRE)2834temp0 &= checkResult2835CheckNotEqual(player.shield, SHIELD_LIGHTNING)2836temp0 &= checkResult28372838if temp0 == true2839temp7 = 12840else2841temp7 = -12842end if2843break28442845case PLAYER_AMY_A2846// Amy defies all the odds and is able to Drop Dash with any shield2847temp7 = 12848break2849end switch2850end if2851else2852if player.jumpHold == false2853if temp7 >= 202854temp7 = -12855end if2856else2857temp7++2858if temp7 == 202859PlaySfx(SfxName[DropDash], false)2860end if2861if temp7 >= 202862// Set Sonic to always use the full ball sprite2863// This code, when placed here, doesn't work properly. Check ObjectUpdate for the same code in a more proper location2864if player.animation == ANI_JUMPING2865player.frame = 12866player.animationTimer = 02867player.animationSpeed = 12868end if2869end if2870end if2871end if28722873CallFunction(Player_SetDropDashCharge)2874end if2875end if2876#endplatform2877end function28782879// Yes, this is actually how Sonic Team programmed this2880// Note about these next two functions, player.dropdashCount0 and player.dropdashCount1 are global variables, NOT object values2881// Also, the "player.dropdashCount2" and "player.dropdashCount3" values introduced in Origins Plus are unused, this function stayed the same between 1.0.4 and later versions28822883public function Player_SetDropDashCharge2884#platform: USE_ORIGINS2885if player.entityPos == SLOT_PLAYER12886player.dropdashCount0 = temp72887else2888player.dropdashCount1 = temp72889end if2890#endplatform2891end function289228932894public function Player_GetDropDashCharge2895#platform: USE_ORIGINS2896if player.entityPos == SLOT_PLAYER12897temp7 = player.dropdashCount02898else2899temp7 = player.dropdashCount12900end if2901#endplatform2902end function290329042905public function Player_CheckIfOnScreen2906#platform: USE_ORIGINS2907// This function is new to Origins, it was added in 1.0.4 in order to not make certain SFX play when P2 Tails was far off-screen2908// In Origins Plus, the S1 equivalent of this function was updated to fix a bug, but they forgot to fix it here too...29092910// ...at least they added a check for VS Mode!2911if options.vsMode == true2912checkResult = true2913else2914checkResult = false29152916temp0 = screen.xoffset2917temp0 -= 202918if player[currentPlayer].ixpos > temp02919temp0 = screen.xoffset2920temp0 += screen.xsize2921temp0 += 202922if player[currentPlayer].ixpos < temp02923temp0 = screen.yoffset2924temp0 -= 402925if player[currentPlayer].iypos > temp02926temp0 = screen.yoffset2927temp0 += screen.ysize2928temp0 += 402929if player[currentPlayer].iypos < temp02930checkResult = true2931end if2932end if2933end if2934end if2935end if2936#endplatform2937end function293829392940public function Player_State_Ground2941if player.animation != ANI_SKIDDING2942temp7 = true2943else2944temp7 = false2945end if29462947CallFunction(Player_HandleGroundMovement)2948if player.gravity == GRAVITY_AIR2949#platform: USE_STANDALONE2950player.state = Player_State_Air2951#endplatform2952#platform: USE_ORIGINS2953player.state = Player_State_Air_NoDropDash2954#endplatform2955CallFunction(Player_HandleAirMovement)2956else2957CallFunction(Player_HandleOnGround)2958if player.speed == 02959if player.collisionMode == CMODE_FLOOR2960switch player.character2961case PLAYER_SONIC_A2962if Player_superState == SUPERSTATE_SUPER2963player.animation = ANI_STOPPED2964player.timer = 02965if player.floorSensorC == false2966if player.floorSensorR == false2967player.animation = ANI_FLAILING12968player.direction = FACING_RIGHT2969end if29702971if player.floorSensorL == false2972player.animation = ANI_FLAILING12973player.direction = FACING_LEFT2974end if2975end if2976else2977if player.timer < 2402978player.animation = ANI_STOPPED2979player.timer++2980else2981player.animation = ANI_WAITING2982player.timer++2983if player.timer == 0x4B02984player.timer = 02985player.state = Player_State_Sleeping2986end if2987end if29882989if player.direction == FACING_RIGHT2990if player.floorSensorR == false2991if player.floorSensorC == false2992player.timer = 02993if player.floorSensorLC == false2994player.animation = ANI_FLAILING32995else2996player.animation = ANI_FLAILING12997end if2998end if2999else3000if player.floorSensorL == false3001if player.floorSensorC == false3002player.timer = 03003player.animation = ANI_FLAILING23004end if3005end if3006end if3007else3008if player.floorSensorL == false3009if player.floorSensorC == false3010player.timer = 03011if player.floorSensorRC == false3012player.animation = ANI_FLAILING33013else3014player.animation = ANI_FLAILING13015end if3016end if3017else3018if player.floorSensorR == false3019if player.floorSensorC == false3020player.timer = 03021player.animation = ANI_FLAILING23022end if3023end if3024end if3025end if3026end if3027break30283029case PLAYER_TAILS_A3030if player.timer < 2403031player.animation = ANI_STOPPED3032player.timer++3033else3034player.animation = ANI_WAITING3035end if30363037if player.floorSensorC == false3038if player.floorSensorR == false3039player.timer = 03040player.animation = ANI_FLAILING13041player.direction = FACING_RIGHT3042end if3043if player.floorSensorL == false3044player.timer = 03045player.animation = ANI_FLAILING13046player.direction = FACING_LEFT3047end if3048end if3049break30503051case PLAYER_KNUCKLES_A3052if player.timer < 2403053player.animation = ANI_STOPPED3054player.timer++3055else3056#platform: USE_STANDALONE3057player.animation = ANI_WAITING3058player.timer++3059if player.timer == 8343060player.timer = 03061player.animation = ANI_STOPPED3062end if3063#endplatform30643065#platform: USE_ORIGINS3066if player.timer < 5703067player.animation = ANI_WAITING3068player.timer++3069else3070player.animation = ANI_BORED3071player.timer++3072if player.timer == 8423073player.timer = 03074player.animation = ANI_STOPPED3075end if3076end if3077#endplatform3078end if30793080if player.floorSensorC == false3081if player.floorSensorR == false3082player.timer = 03083player.animation = ANI_FLAILING13084if player.direction == FACING_LEFT3085player.prevAnimation = ANI_FLAILING13086player.frame = 43087player.animationTimer = 03088player.animationSpeed = 03089end if3090player.direction = FACING_RIGHT3091end if30923093if player.floorSensorL == false3094player.timer = 03095player.animation = ANI_FLAILING13096if player.direction == FACING_RIGHT3097player.prevAnimation = ANI_FLAILING13098player.frame = 43099player.animationTimer = 03100player.animationSpeed = 03101end if3102player.direction = FACING_LEFT3103end if3104end if3105break31063107#platform: USE_ORIGINS3108case PLAYER_AMY_A3109if player.timer < 2403110player.animation = ANI_STOPPED3111player.timer++3112else3113if player.timer < 11073114player.animation = ANI_WAITING3115player.timer++3116else3117player.animation = ANI_BORED3118player.timer++3119if player.timer >= 12453120// Nothing here LOL3121end if3122end if3123end if31243125// btw Amy's Flailing1 and Flailing3 animations are the same thing, this whole thing is just copied from Sonic (who *does* have unique flailing1/3 animations)3126if player.direction == FACING_RIGHT3127if player.floorSensorR == false3128if player.floorSensorC == false3129player.timer = 03130if player.floorSensorLC == false3131player.animation = ANI_FLAILING33132else3133player.animation = ANI_FLAILING13134end if3135end if3136else3137if player.floorSensorL == false3138if player.floorSensorC == false3139player.timer = 03140player.animation = ANI_FLAILING23141end if3142end if3143end if3144else3145if player.floorSensorL == false3146if player.floorSensorC == false3147player.timer = 03148if player.floorSensorRC == false3149player.animation = ANI_FLAILING33150else3151player.animation = ANI_FLAILING13152end if3153end if3154else3155if player.floorSensorR == false3156if player.floorSensorC == false3157player.timer = 03158player.animation = ANI_FLAILING23159end if3160end if3161end if3162end if3163break3164#endplatform3165end switch3166end if3167else3168player.timer = 03169if player.speed > 03170if player.speed < 0x5F5C23171player.animation = ANI_WALKING3172CallFunction(Player_HandleWalkAnimSpeed)3173else3174if player.speed > 0x9FFFF3175player.animation = ANI_PEELOUT3176else3177player.animation = ANI_RUNNING3178end if3179CallFunction(Player_HandleRunAnimSpeed)3180end if3181else3182if player.speed > -0x5F5C23183player.animation = ANI_WALKING3184CallFunction(Player_HandleWalkAnimSpeed)3185else3186if player.speed < -0x9FFFF3187player.animation = ANI_PEELOUT3188else3189player.animation = ANI_RUNNING3190end if3191CallFunction(Player_HandleRunAnimSpeed)3192end if3193end if3194end if31953196if player.skidding > 03197if temp7 == true3198PlaySfx(SfxName[Skidding], false)3199end if3200player.animation = ANI_SKIDDING3201player.animationSpeed = 03202player.skidding--3203if ringTimer == 03204CreateTempObject(TypeName[Dust Puff], 0, player.xpos, player.ypos)3205object[tempObjectPos].iypos += player.collisionBottom3206object[tempObjectPos].drawOrder = player.sortedDrawOrder3207end if32083209if player.speed > 03210player.direction = FACING_RIGHT3211else3212player.direction = FACING_LEFT3213end if3214end if32153216if player.collisionMode == CMODE_FLOOR3217if player.pushing == 23218player.animation = ANI_PUSHING3219player.animationSpeed = 03220end if3221end if32223223if player.jumpPress == true3224CallFunction(Player_Action_Jump)3225else3226if player.up == true3227if player.speed == 03228if player.animation != ANI_FLAILING13229if player.animation != ANI_FLAILING23230player.state = Player_State_LookUp3231player.timer = 03232else3233player.up = false3234player.down = false3235end if3236else3237player.up = false3238player.down = false3239end if3240end if3241end if32423243if player.down == true3244if player.speed == 03245if player.animation != ANI_FLAILING13246if player.animation != ANI_FLAILING23247player.state = Player_State_Crouch3248player.timer = 03249else3250player.up = false3251player.down = false3252end if3253else3254player.up = false3255player.down = false3256end if3257else3258if player.left == false3259if player.right == false3260if player.speed > 03261if player.speed > 0x88003262player.state = Player_State_Roll3263player.animation = ANI_JUMPING3264if player.prevAnimation != ANI_JUMPING3265player.iypos -= player.jumpOffset3266end if32673268player.abilityTimer = 0x4003269PlaySfx(SfxName[Rolling], false)3270end if3271else3272if player.speed < -0x88003273player.state = Player_State_Roll3274player.animation = ANI_JUMPING3275if player.prevAnimation != ANI_JUMPING3276player.iypos -= player.jumpOffset3277end if32783279player.abilityTimer = 0x4003280PlaySfx(SfxName[Rolling], false)3281end if3282end if3283end if3284end if3285end if3286end if3287end if3288end if3289end function329032913292public function Player_State_Sleeping3293if player.gravity == GRAVITY_AIR3294#platform: USE_STANDALONE3295player.state = Player_State_Air3296#endplatform3297#platform: USE_ORIGINS3298player.state = Player_State_Air_NoDropDash3299#endplatform3300CallFunction(Player_HandleAirMovement)3301else3302CallFunction(Player_HandleOnGround)3303if player.animation == ANI_CONTINUE_UP3304if player.frame == 13305player.state = Player_State_Ground3306end if3307else3308player.animation = ANI_BORED3309end if33103311if player.jumpPress == true3312CallFunction(Player_Action_Jump)3313else3314if player.up == true3315player.animation = ANI_CONTINUE_UP3316end if33173318if player.down == true3319player.animation = ANI_CONTINUE_UP3320end if33213322if player.left == true3323player.animation = ANI_CONTINUE_UP3324end if33253326if player.right == true3327player.animation = ANI_CONTINUE_UP3328end if3329end if3330end if3331end function333233333334// Prevents the player from using the Drop Dash if they went in midair without jumping3335public function Player_State_Air_NoDropDash3336#platform: USE_ORIGINS3337temp7 = -13338CallFunction(Player_SetDropDashCharge)3339player.state = Player_State_Air_NoDropDash3340CallFunction(Player_State_Air)3341#endplatform3342end function334333443345public function Player_State_Air3346CallFunction(Player_HandleAirFriction)33473348if player.gravity == GRAVITY_AIR3349CallFunction(Player_HandleAirMovement)33503351if player.yvel > 0x200003352if player.animation == ANI_FLAILING13353player.animation = ANI_WALKING3354end if33553356if player.animation == ANI_FLAILING23357player.animation = ANI_WALKING3358end if3359end if33603361if player.animation == ANI_BOUNCING3362if player.yvel >= 03363if player.animationReserve == ANI_STOPPED3364player.animationReserve = ANI_WALKING3365end if3366player.animation = player.animationReserve3367end if3368end if33693370if player.animation == ANI_SKIDDING3371if player.skidding > 03372player.skidding--3373else3374player.animation = ANI_WALKING3375player.prevAnimation = ANI_WALKING3376player.frame = 03377player.animationSpeed = 403378end if3379end if33803381if player.animation == ANI_TWIRL3382if player.animationSpeed == 403383if player.frame >= 123384player.animation = ANI_WALKING3385player.prevAnimation = ANI_WALKING3386player.frame = 03387end if3388else3389if player.frame >= 243390player.animation = ANI_WALKING3391player.prevAnimation = ANI_WALKING3392player.frame = 03393player.animationSpeed = 403394end if3395end if3396end if33973398if player.animation == ANI_HURT3399if player.yvel >= 03400if player.animationReserve == ANI_STOPPED3401player.animationReserve = ANI_WALKING3402end if3403player.animation = player.animationReserve3404end if3405end if34063407#platform: USE_STANDALONE3408if player.animation == ANI_JUMPING3409if player.jumpAbilityState == 13410if player.yvel >= player.jumpCap3411CallFunction(player.jumpAbility)3412end if3413end if3414end if3415#endplatform34163417#platform: USE_ORIGINS3418if player.yvel >= player.jumpCap3419CallFunction(Player_HandleDropDash)3420if player.animation == ANI_JUMPING3421if player.jumpAbilityState == 13422CallFunction(player.jumpAbility)3423end if3424end if3425end if3426#endplatform3427else3428#platform: USE_STANDALONE3429player.state = Player_State_Ground3430CallFunction(Player_HandleOnGround)3431player.skidding = 03432#endplatform34333434#platform: USE_ORIGINS3435CheckEqual(player.releasingDropDash, false)3436temp0 = checkResult3437temp1 = 203438temp1 -= 1 // yep3439CallFunction(Player_GetDropDashCharge)3440CheckGreater(temp7, temp1)3441temp0 &= checkResult34423443if temp0 == true3444switch player.character3445case PLAYER_SONIC_A3446CallFunction(Player_Action_Spindash) // Good ol' Sonic Team programming3447break34483449case PLAYER_AMY_A3450CallFunction(Player_Action_HammerDash)3451break3452end switch34533454if Player_superState == SUPERSTATE_SUPER3455screen.shakeY = 63456end if3457else3458player.state = Player_State_Ground3459CallFunction(Player_HandleOnGround)3460player.skidding = 03461end if3462#endplatform3463end if3464end function34653466public function Player_State_TubeAirRoll3467CallFunction(Player_HandleAirFriction)34683469if player.gravity == GRAVITY_AIR3470CallFunction(Player_HandleAirMovement)3471else3472player.state = Player_State_TubeRoll3473CallFunction(Player_HandleOnGround)3474player.skidding = 03475end if34763477player.animation = ANI_JUMPING3478end function347934803481public function Player_State_Roll3482CallFunction(Player_HandleRollDeceleration)34833484if player.gravity == GRAVITY_AIR3485#platform: USE_STANDALONE3486player.state = Player_State_Air3487#endplatform3488#platform: USE_ORIGINS3489player.state = Player_State_Air_NoDropDash3490#endplatform3491player.timer = 03492CallFunction(Player_HandleAirMovement)3493else3494CallFunction(Player_HandleRollAnimSpeed)3495player.animationSpeed = player.rollAnimationSpeed3496CallFunction(Player_HandleOnGround)3497if player.jumpPress == true3498CallFunction(Player_Action_Jump)3499end if3500end if3501end function350235033504public function Player_State_RollJump3505#platform: USE_ORIGINS3506// Origins Plus removed Roll Jump Lock! We should still apply it to attract demos so they don't break, though3507if options.attractMode == true3508#endplatform3509player.left = false3510player.right = false3511#platform: USE_ORIGINS3512end if3513#endplatform35143515CallFunction(Player_HandleAirFriction)35163517if player.gravity == GRAVITY_AIR3518#platform: USE_STANDALONE3519if player.animation == ANI_JUMPING3520if player.jumpAbilityState == 13521if player.yvel >= player.jumpCap3522CallFunction(player.jumpAbility)3523end if3524end if3525end if3526#endplatform35273528#platform: USE_ORIGINS3529if player.yvel >= player.jumpCap3530CallFunction(Player_HandleDropDash)3531if player.animation == ANI_JUMPING3532if player.jumpAbilityState == 13533CallFunction(player.jumpAbility)3534end if3535end if3536end if3537#endplatform35383539CallFunction(Player_HandleAirMovement)3540else3541#platform: USE_STANDALONE3542player.state = Player_State_Ground3543CallFunction(Player_HandleOnGround)3544player.skidding = 03545#endplatform35463547#platform: USE_ORIGINS3548CheckEqual(player.releasingDropDash, false)3549temp0 = checkResult3550temp1 = 203551temp1 -= 1 // yep3552CallFunction(Player_GetDropDashCharge)3553CheckGreater(temp7, temp1)3554temp0 &= checkResult35553556if temp0 == true3557switch player.character3558case PLAYER_SONIC_A3559CallFunction(Player_Action_Spindash) // Good ol' Sonic Team programming3560break35613562case PLAYER_AMY_A3563CallFunction(Player_Action_HammerDash)3564break3565end switch35663567if Player_superState == SUPERSTATE_SUPER3568screen.shakeY = 63569end if3570else3571player.state = Player_State_Ground3572CallFunction(Player_HandleOnGround)3573player.skidding = 03574end if3575#endplatform3576end if3577end function357835793580public function Player_State_LookUp3581#platform: USE_ORIGINS3582currentPlayer = player.entityPos3583#endplatform35843585if player.up == false3586player.state = Player_State_Ground3587player.timer = 03588else3589if player.timer < 603590player.timer++3591else3592temp0 = player.ypos3593temp0 >>= 163594#platform: USE_STANDALONE3595temp0 -= camera[0].ypos3596#endplatform35973598#platform: USE_ORIGINS3599temp0 -= camera[currentPlayer].ypos3600#endplatform3601temp0 -= 1123602if player.lookPosY > temp03603player.lookPosY -= 23604end if3605end if36063607player.animation = ANI_LOOKINGUP3608if player.gravity == GRAVITY_AIR3609#platform: USE_STANDALONE3610player.state = Player_State_Air3611#endplatform3612#platform: USE_ORIGINS3613player.state = Player_State_Air_NoDropDash3614#endplatform3615player.timer = 03616else3617if player.jumpPress == true3618CallFunction(Player_Action_Jump)3619end if3620end if3621end if3622end function362336243625public function Player_State_Crouch3626#platform: USE_ORIGINS3627currentPlayer = player.entityPos3628#endplatform36293630if player.down == false3631player.state = Player_State_Ground3632player.timer = 03633else3634if player.timer < 603635player.timer++3636else3637temp0 = player.ypos3638temp0 >>= 163639#platform: USE_STANDALONE3640temp0 -= camera[0].ypos3641#endplatform36423643#platform: USE_ORIGINS3644temp0 -= camera[currentPlayer].ypos3645#endplatform3646temp0 += 963647if player.lookPosY < temp03648player.lookPosY += 23649end if3650end if36513652player.animation = ANI_LOOKINGDOWN3653if player.gravity == GRAVITY_AIR3654#platform: USE_STANDALONE3655player.state = Player_State_Air3656#endplatform3657#platform: USE_ORIGINS3658player.state = Player_State_Air_NoDropDash3659#endplatform3660player.timer = 03661else3662if player.jumpPress == true3663CallFunction(player.spindashFunction)3664end if3665end if3666end if3667end function366836693670public function Player_State_Spindash3671if player.gravity == GRAVITY_AIR3672#platform: USE_STANDALONE3673player.state = Player_State_Air3674#endplatform3675#platform: USE_ORIGINS3676player.state = Player_State_Air_NoDropDash3677#endplatform3678player.speed = 03679end if36803681if player.jumpPress == true3682if player.abilityTimer < 0x900003683player.abilityTimer += 0x200003684else3685player.abilityTimer = 0x800003686end if36873688player.frame = 03689PlaySfx(SfxName[Charge], false)3690else3691temp0 = player.abilityTimer3692temp0 >>= 53693player.abilityTimer -= temp03694end if36953696#platform: USE_ORIGINS3697temp1 = player.down36983699CheckEqual(player.releasingDropDash, false)3700temp2 = checkResult3701temp3 = 203702temp3 -= 1 // yep3703CallFunction(Player_GetDropDashCharge)3704CheckGreater(temp7, temp3)3705temp2 &= checkResult37063707if temp2 == true3708temp7 = -13709CallFunction(Player_SetDropDashCharge)3710Sin256(temp0, player.angle)37113712if player.direction == FACING_RIGHT3713if temp0 >= 03714temp0 <<= 123715else3716temp0 <<= 113717end if3718else3719if temp0 >= 03720temp0 <<= 113721else3722temp0 <<= 123723end if3724FlipSign(temp0)3725end if37263727player.abilityTimer = temp03728temp1 = false3729end if37303731if temp1 == false3732#endplatform37333734#platform: USE_STANDALONE3735if player.down == false3736#endplatform3737// Release the spindash!37383739player.timer = 03740player.state = Player_State_Roll3741player.animation = ANI_JUMPING3742player.iypos -= player.jumpOffset37433744currentPlayer = player.entityPos3745if player.entityPos == camera[currentPlayer].target3746player.scrollDelay = 153747camera[currentPlayer].style = CAMERASTYLE_HLOCKED3748end if37493750temp0 = player.abilityTimer3751temp0 >>= 173752temp0 <<= 163753if Player_superState == SUPERSTATE_SUPER3754temp0 += 0xB00003755else3756temp0 += 0x800003757end if37583759if player.direction == FACING_RIGHT3760player.speed = temp03761else3762player.speed = temp03763FlipSign(player.speed)3764end if37653766StopSfx(SfxName[Charge])3767PlaySfx(SfxName[Release], false)3768CallFunction(Player_HandleOnGround)3769end if3770end function377137723773public function Player_HandleFlyCarry3774if player.flyCarryTimer != 03775player.flyCarryTimer--3776end if37773778temp0 = player.xpos3779temp1 = player.ypos3780temp1 += 0x1F00003781if player[SLOT_PLAYER1].animation == ANI_JUMPING3782temp1 += 0x500003783end if37843785temp0 -= player[SLOT_PLAYER1].xpos3786temp1 -= player[SLOT_PLAYER1].ypos3787if player[SLOT_PLAYER1].state != Player_State_Carried3788CheckEqual(player[SLOT_PLAYER1].gravity, GRAVITY_GROUND)3789temp2 = checkResult3790CheckGreater(player.yvel, 0)3791temp2 &= checkResult37923793if temp2 == false3794CheckEqual(player[SLOT_PLAYER1].state, Player_State_Ground)3795temp2 = checkResult3796CheckEqual(player[SLOT_PLAYER1].state, Player_State_Roll)3797temp2 |= checkResult3798CheckEqual(player[SLOT_PLAYER1].state, Player_State_Air)3799temp2 |= checkResult3800CheckEqual(player[SLOT_PLAYER1].state, Player_State_RollJump)3801temp2 |= checkResult3802CheckEqual(player[SLOT_PLAYER1].state, Player_State_LookUp)3803temp2 |= checkResult3804CheckEqual(player[SLOT_PLAYER1].state, Player_State_Crouch)3805temp2 |= checkResult38063807if temp2 != false3808temp2 = temp03809Abs(temp2)3810temp3 = temp13811Abs(temp3)3812if temp2 <= 0x800003813if temp3 <= 0x800003814if player.flyCarryTimer == 03815if player[SLOT_PLAYER1].down == false3816player[SLOT_PLAYER1].animation = ANI_HANGING3817player[SLOT_PLAYER1].state = Player_State_Carried3818player[SLOT_PLAYER1].xpos += temp03819player[SLOT_PLAYER1].ypos += temp13820PlaySfx(SfxName[Catch], false)3821end if3822end if3823end if3824end if3825end if3826end if3827end if38283829if player[SLOT_PLAYER1].state == Player_State_Carried3830temp2 = player.xpos3831temp3 = player.ypos3832temp6 = player.xvel3833temp7 = player.yvel3834ProcessObjectMovement()38353836Player_flyCarryBuddyXPos = player.xpos3837Player_flyCarryBuddyYPos = player.ypos3838temp4 = player.xpos3839temp4 &= 0xFFFF00003840temp5 = player.ypos3841temp5 &= 0xFFFF00003842temp5 += 0x1F00003843player.xpos = temp23844player.ypos = temp33845player.xvel = temp63846player.yvel = temp738473848stage.entityPos = SLOT_PLAYER13849temp0 = player.xpos3850temp0 &= 0xFFFF00003851temp1 = player.ypos3852temp1 &= 0xFFFF00003853player.xvel = temp43854player.yvel = temp53855player.xvel -= temp03856player.yvel -= temp13857ProcessObjectMovement()38583859stage.entityPos = SLOT_PLAYER23860#platform: USE_STANDALONE3861player[SLOT_PLAYER1].collisionPlane = player.collisionPlane3862#endplatform3863#platform: USE_ORIGINS3864player.collisionPlane = player[SLOT_PLAYER1].collisionPlane3865player.sortedDrawOrder = player[SLOT_PLAYER1].sortedDrawOrder3866#endplatform3867player[SLOT_PLAYER1].speed = player.speed3868player[SLOT_PLAYER1].direction = player.direction3869Player_flyCarryLeaderXPos = player[SLOT_PLAYER1].xpos3870Player_flyCarryLeaderYPos = player[SLOT_PLAYER1].ypos3871temp2 = player[SLOT_PLAYER1].xpos3872temp2 &= 0xFFFF00003873temp3 = player[SLOT_PLAYER1].ypos3874temp3 &= 0xFFFF00003875CheckNotEqual(temp4, temp2)3876temp6 = checkResult3877CheckNotEqual(temp5, temp3)3878temp6 |= checkResult3879if temp6 == true3880if player[SLOT_PLAYER1].gravity == GRAVITY_GROUND3881player[SLOT_PLAYER1].state = Player_State_Ground3882else3883#platform: USE_STANDALONE3884player[SLOT_PLAYER1].state = Player_State_Air3885#endplatform3886#platform: USE_ORIGINS3887player[SLOT_PLAYER1].state = Player_State_Air_NoDropDash3888#endplatform3889end if38903891player.flyCarryTimer = 303892end if3893end if3894end function389538963897public function Player_State_Carried3898if player[1].state != Player_State_Fly3899#platform: USE_STANDALONE3900player.state = Player_State_Air3901#endplatform3902#platform: USE_ORIGINS3903player.state = Player_State_Air_NoDropDash3904#endplatform3905end if39063907temp0 = player[1].xpos3908temp0 &= 0xFFFF00003909temp2 = player.xpos3910temp2 &= 0xFFFF00003911if player.xpos == Player_flyCarryLeaderXPos3912Player_flyCarryBuddyXPos &= 0xFFFF00003913temp1 = temp03914temp1 -= Player_flyCarryBuddyXPos3915temp2 += temp13916end if39173918if temp0 != temp23919if player.gravity == GRAVITY_GROUND3920player.state = Player_State_Ground3921else3922#platform: USE_STANDALONE3923player.state = Player_State_Air3924#endplatform3925#platform: USE_ORIGINS3926player.state = Player_State_Air_NoDropDash3927#endplatform3928end if3929end if39303931if player.gravity == GRAVITY_GROUND3932if player.yvel >= 03933player.state = Player_State_Ground3934end if3935end if39363937if player.jumpPress != false3938if player.down != false3939if player.gravityStrength == 0x38003940player.yvel = -0x400003941else3942player.yvel = -0x200003943end if3944player.state = Player_State_Air3945player.animation = ANI_JUMPING3946end if3947end if39483949if player.state == Player_State_Carried3950player.xvel = 03951player.yvel = 03952player.speed = 03953else3954player[1].flyCarryTimer = 303955end if3956end function395739583959public function Player_State_Fly3960CallFunction(Player_HandleAirFriction)3961if player.gravity == GRAVITY_AIR3962player.xvel = player.speed3963if player.yvel < -0x100003964player.flightVelocity = 0x8003965else3966if player.yvel < 13967if player.abilityTimer < 603968player.abilityTimer++3969else3970player.flightVelocity = 0x8003971end if3972end if3973end if39743975player.yvel += player.flightVelocity3976temp0 = stage.curYBoundary13977temp0 += 163978temp0 <<= 1639793980if player.ypos < temp03981if player.yvel < 03982player.yvel = 03983end if3984end if39853986if options.vsMode == false3987CallFunction(Player_HandleFlyCarry)3988end if39893990if player.timer < 4803991if player.gravityStrength == 0x38003992if player[SLOT_PLAYER1].state == Player_State_Carried3993if player.yvel < 03994player.animation = ANI_FLY_LIFT_UP3995player.animationSpeed = 2403996else3997player.animation = ANI_FLY_LIFT_DOWN3998player.animationSpeed = 1203999end if4000else4001player.animation = ANI_FLYING4002if player.yvel < 04003player.animationSpeed = 2404004else4005player.animationSpeed = 1204006end if4007end if4008else4009if player[SLOT_PLAYER1].state == Player_State_Carried4010player.animation = ANI_SWIM_LIFT4011else4012player.animation = ANI_SWIMMING40134014if player.yvel < 04015player.animationSpeed = 604016else4017player.animationSpeed = 304018end if4019end if4020end if40214022player.timer++4023if player.timer == 4804024if player.gravityStrength == 0x38004025if player[SLOT_PLAYER1].state == Player_State_Carried4026player.animation = ANI_FLY_LIFT_TIRED4027else4028player.animation = ANI_FLYINGTIRED4029end if4030player.animationSpeed = 12040314032StopSfx(SfxName[Flying])4033PlaySfx(SfxName[Tired], true)4034else4035if player[SLOT_PLAYER1].state == Player_State_Carried4036player.animation = ANI_SWIM_LIFT4037else4038player.animation = ANI_SWIMMINGTIRED4039end if4040end if4041else4042if player.jumpPress == true4043CheckNotEqual(player.gravityStrength, 0x3800)4044temp0 = checkResult4045CheckEqual(player[SLOT_PLAYER1].state, Player_State_Carried)4046temp0 &= checkResult40474048if temp0 == false4049player.flightVelocity = -0x20004050player.abilityTimer = 04051end if4052end if4053end if4054else4055if player.gravityStrength == 0x38004056if player[SLOT_PLAYER1].state == Player_State_Carried4057player.animation = ANI_FLY_LIFT_TIRED4058else4059player.animation = ANI_FLYINGTIRED4060end if4061else4062if player[SLOT_PLAYER1].state == Player_State_Carried4063player.animation = ANI_SWIM_LIFT4064else4065player.animation = ANI_SWIMMINGTIRED4066end if4067end if4068end if4069else4070player.animation = ANI_WALKING4071player.state = Player_State_Ground4072CallFunction(Player_HandleOnGround)4073end if4074end function407540764077public function Player_State_GlideLeft4078if player.gravity == GRAVITY_AIR4079if player.jumpHold == true4080if player.timer == 2564081if player.speed < 0x1800004082player.speed += 0x4004083end if4084else4085if player.speed < 0x400004086player.speed += 0x10004087end if4088end if40894090if player.yvel > 0x80004091player.yvel -= 0x20004092else4093player.yvel += 0x20004094end if40954096if player.timer < 2564097player.timer += 44098end if40994100if player.timer < 1704101if player.timer > 864102player.frame = 04103else4104if player.timer > 444105player.frame = 14106else4107player.frame = 24108end if4109end if4110else4111if player.timer < 2124112player.frame = 14113else4114player.frame = 24115end if4116end if41174118temp7 = player.xpos4119if player.timer < 1284120player.direction = FACING_RIGHT4121temp0 = false4122temp1 = false4123else4124player.direction = FACING_LEFT41254126player.xpos = temp74127player.xpos += player.xvel4128player.ypos = player.ypos4129ObjectTileCollision(CSIDE_RWALL, -12, -2, player.collisionPlane)41304131temp0 = checkResult4132temp2 = player.xpos4133player.xpos = temp74134player.xpos += player.xvel4135ObjectTileCollision(CSIDE_RWALL, -12, 11, player.collisionPlane)41364137temp1 = checkResult4138temp3 = player.xpos4139end if41404141Cos(player.xvel, player.timer)4142player.xvel *= player.speed4143player.xvel >>= 941444145if player.right == true4146player.state = Player_State_GlideRight4147end if41484149player.xpos = temp74150checkResult = temp04151checkResult &= temp14152if checkResult == true4153if temp2 == temp34154player.state = Player_State_Climb4155player.speed = 04156player.xvel = 04157player.yvel = 04158player.timer = 04159PlaySfx(SfxName[Catch], false)4160else4161player.timer = 04162player.xvel >>= 24163player.speed = player.xvel4164player.animation = ANI_GLIDING_DROP4165player.state = Player_State_GlideDrop4166end if4167else4168if temp0 == true4169player.timer = 04170player.xvel >>= 24171player.speed = player.xvel4172player.animation = ANI_GLIDING_DROP4173player.state = Player_State_GlideDrop4174end if4175end if4176else4177player.timer = 04178player.xvel >>= 24179player.speed = player.xvel4180player.animation = ANI_GLIDING_DROP4181player.state = Player_State_GlideDrop4182end if4183else4184if player.collisionMode == CMODE_FLOOR4185player.timer = 04186player.state = Player_State_GlideSlide4187player.animation = ANI_GLIDING_STOP4188player.speed = player.xvel4189else4190player.state = Player_State_Ground4191CallFunction(Player_HandleOnGround)4192player.skidding = 04193end if4194end if41954196temp0 = stage.curYBoundary14197temp0 += 164198temp0 <<= 164199if player.ypos < temp04200player.xvel = 04201player.speed = player.xvel4202end if4203end function420442054206public function Player_State_GlideRight4207if player.gravity == GRAVITY_AIR4208if player.jumpHold == true4209if player.timer == 04210if player.speed < 0x1800004211player.speed += 0x4004212end if4213else4214if player.speed < 0x400004215player.speed += 0x10004216end if4217end if42184219if player.yvel > 0x80004220player.yvel -= 0x20004221else4222player.yvel += 0x20004223end if42244225if player.timer > 04226player.timer -= 44227end if42284229if player.timer < 1704230if player.timer > 864231player.frame = 04232else4233if player.timer > 444234player.frame = 14235else4236player.frame = 24237end if4238end if4239else4240if player.timer < 2124241player.frame = 14242else4243player.frame = 24244end if4245end if42464247temp7 = player.xpos4248if player.timer < 1284249player.direction = FACING_RIGHT42504251player.xpos = temp74252player.xpos += player.xvel4253player.ypos = player.ypos4254ObjectTileCollision(CSIDE_LWALL, 12, -2, player.collisionPlane)42554256temp0 = checkResult4257temp2 = player.xpos4258player.xpos = temp74259player.xpos += player.xvel4260ObjectTileCollision(CSIDE_LWALL, 12, 11, player.collisionPlane)42614262temp1 = checkResult4263temp3 = player.xpos4264else4265player.direction = FACING_LEFT4266temp0 = false4267temp1 = false4268end if42694270Cos(player.xvel, player.timer)4271player.xvel *= player.speed4272player.xvel >>= 94273if player.left == true4274player.state = Player_State_GlideLeft4275end if42764277player.xpos = temp74278checkResult = temp04279checkResult &= temp14280if checkResult == true4281temp2 >>= 14282temp3 >>= 14283if temp2 == temp34284player.state = Player_State_Climb4285player.speed = 04286player.xvel = 04287player.yvel = 04288player.timer = 04289PlaySfx(SfxName[Catch], false)4290else4291player.timer = 04292player.xvel >>= 24293player.speed = player.xvel4294player.animation = ANI_GLIDING_DROP4295player.state = Player_State_GlideDrop4296end if4297else4298if temp0 == true4299player.speed = 04300player.timer = 04301player.xvel >>= 24302player.speed = player.xvel4303player.animation = ANI_GLIDING_DROP4304player.state = Player_State_GlideDrop4305end if4306end if4307else4308player.timer = 04309player.xvel >>= 24310player.speed = player.xvel4311player.animation = ANI_GLIDING_DROP4312player.state = Player_State_GlideDrop4313end if4314else4315if player.collisionMode == CMODE_FLOOR4316player.timer = 04317player.state = Player_State_GlideSlide4318player.animation = ANI_GLIDING_STOP4319player.speed = player.xvel4320else4321player.state = Player_State_Ground4322CallFunction(Player_HandleOnGround)4323player.skidding = 04324end if4325end if43264327temp0 = stage.curYBoundary14328temp0 += 164329temp0 <<= 164330if player.ypos < temp04331player.xvel = 04332player.speed = player.xvel4333end if4334end function433543364337public function Player_State_GlideDrop4338if player.gravity == GRAVITY_AIR4339CallFunction(Player_HandleAirFriction)4340CallFunction(Player_HandleAirMovement)4341else4342#platform: USE_ORIGINS4343// Origins Plus added performing actions out of this state like in S3&K, neat!4344if player.jumpPress == true4345player.xvel = 04346player.speed = 04347if player.down == true4348CallFunction(player.spindashFunction)4349else4350CallFunction(Player_Action_Jump)4351end if4352else4353#endplatform4354if player.timer == 04355PlaySfx(SfxName[Landing], false)4356end if43574358player.scrollTracking = false4359player.speed = 04360player.xvel = 04361player.animation = ANI_LOOKINGDOWN4362player.prevAnimation = ANI_LOOKINGDOWN4363player.frame = 243644365if player.timer < 164366player.timer++4367else4368player.state = Player_State_Ground4369CallFunction(Player_HandleOnGround)4370player.skidding = 04371end if4372#platform: USE_ORIGINS4373end if4374#endplatform4375end if4376end function437743784379public function Player_State_GlideSlide4380if player.gravity == GRAVITY_GROUND4381if player.speed == 04382#platform: USE_ORIGINS4383// Origins Plus added performing actions out of this state like in S3&K, neat!4384if player.jumpPress == true4385if player.down == true4386CallFunction(player.spindashFunction)4387else4388CallFunction(Player_Action_Jump)4389end if4390else4391#endplatform4392player.scrollTracking = false4393player.frame = 14394if player.timer < 164395player.timer++4396else4397player.state = Player_State_Ground4398CallFunction(Player_HandleOnGround)4399player.skidding = 04400end if4401#platform: USE_ORIGINS4402end if4403#endplatform4404else4405if ringTimer == 04406CreateTempObject(TypeName[Dust Puff], 0, player.xpos, player.ypos)4407object[tempObjectPos].iypos += player.collisionBottom4408object[tempObjectPos].drawOrder = player.sortedDrawOrder44094410if player.timer == 04411PlaySfx(SfxName[Sliding], false)4412player.timer = 14413else4414player.timer = 04415end if4416end if44174418player.frame = 04419if player.speed > 04420player.speed -= 0x20004421if player.speed < 04422player.speed = 04423player.timer = 04424end if4425else4426player.speed += 0x20004427if player.speed > 04428player.speed = 04429player.timer = 04430end if4431end if44324433if player.jumpHold == false4434player.speed = 04435player.timer = 04436end if4437end if44384439player.xvel = player.speed4440else4441player.timer = 04442player.animation = ANI_GLIDING_DROP4443player.state = Player_State_GlideDrop4444end if4445end function444644474448public function Player_State_Climb4449if player.gravity == GRAVITY_AIR4450player.animation = ANI_CLIMBING4451if player.up == true4452if Player_superState == SUPERSTATE_SUPER4453player.yvel = -0x200004454else4455player.yvel = -0x100004456end if4457temp0 = player.collisionTop4458temp0 *= -0x1000044594460if player.ypos < temp04461player.ypos = temp04462end if44634464player.timer++4465if player.timer == 44466player.timer = 04467player.frame++4468player.frame %= 64469end if4470else4471if player.down == true4472if Player_superState == SUPERSTATE_SUPER4473player.yvel = 0x200004474else4475player.yvel = 0x100004476end if44774478player.timer++4479if player.timer == 44480player.timer = 04481if player.frame < 14482player.frame += 64483end if44844485player.frame--4486end if4487else4488player.yvel = 04489end if4490end if44914492if player.jumpPress == true4493player.animation = ANI_JUMPING4494player.state = Player_State_Air4495player.timer = 04496PlaySfx(SfxName[Jump], false)44974498if player.direction == FACING_LEFT4499player.xvel = 0x400004500player.speed = 0x400004501player.direction = FACING_RIGHT4502else4503player.xvel = -0x400004504player.speed = -0x400004505player.direction = FACING_LEFT4506end if45074508player.yvel = -0x400004509if player.gravityStrength != 0x38004510player.xvel >>= 14511player.speed >>= 14512player.yvel >>= 14513end if4514else4515if player.direction == FACING_RIGHT4516temp2 = player.xpos4517ObjectTileGrip(CSIDE_LWALL, 10, -10, player.collisionPlane)45184519temp0 = checkResult4520temp3 = player.xpos4521player.xpos = temp24522ObjectTileGrip(CSIDE_LWALL, 10, 11, player.collisionPlane)45234524temp1 = checkResult4525if player.xpos > temp34526player.xpos = temp34527end if4528else4529temp2 = player.xpos4530ObjectTileGrip(CSIDE_RWALL, -10, -10, player.collisionPlane)45314532temp0 = checkResult4533temp3 = player.xpos4534player.xpos = temp24535ObjectTileGrip(CSIDE_RWALL, -10, 11, player.collisionPlane)45364537temp1 = checkResult4538if player.xpos < temp34539player.xpos = temp34540end if4541end if45424543if temp0 == false4544player.xpos = temp24545player.animation = ANI_LEDGEPULLUP4546player.yvel = 04547player.timer = 04548player.state = Player_State_LedgePullUp4549player.tileCollisions = false45504551if player.direction == FACING_RIGHT4552player.xpos += 0x100004553end if4554else4555if temp1 == false4556player.animation = ANI_GLIDING_DROP4557player.prevAnimation = ANI_GLIDING_DROP4558player.frame = 24559player.timer = 04560player.state = Player_State_GlideDrop4561end if4562end if4563end if4564else4565player.animation = ANI_WALKING4566player.state = Player_State_Ground4567CallFunction(Player_HandleOnGround)4568end if4569end function457045714572public function Player_State_LedgePullUp4573switch player.frame4574case 04575if player.timer < 54576ObjectTileGrip(CSIDE_FLOOR, 12, -9, player.collisionPlane)4577player.timer++4578else4579player.timer = 04580player.frame++45814582if player.direction == FACING_RIGHT4583player.xpos += 0x900004584else4585player.xpos -= 0x900004586end if45874588player.ypos -= 0xA00004589end if4590break45914592case 14593if player.timer < 54594player.timer++4595else4596player.timer = 04597player.frame++45984599if player.direction == FACING_RIGHT4600player.xpos += 0x500004601else4602player.xpos -= 0x500004603end if46044605player.ypos -= 0x200004606end if4607break46084609case 24610if player.timer < 54611player.timer++4612else4613player.timer = 04614player.animation = ANI_STOPPED4615#platform: USE_STANDALONE4616player.state = Player_State_Air4617#endplatform4618#platform: USE_ORIGINS4619player.state = Player_State_Air_NoDropDash4620#endplatform4621player.ypos -= 0xA00004622player.tileCollisions = true4623end if4624break46254626end switch4627end function462846294630public function Player_State_GotHit4631#platform: USE_ORIGINS4632temp2 = false4633if game.playMode == BOOT_PLAYMODE_MISSION4634if game.missionFunctionNo == MISSIONNO_MERCY4635if game.missionValue == true4636game.missionValue = false4637temp2 = true4638end if4639end if4640end if4641#endplatform46424643if player.isSidekick == false4644arrayPos0 = player.entityPos4645arrayPos0 += playerCount4646if player.shield != SHIELD_NONE4647temp0 = 14648ResetObjectEntity(arrayPos0, TypeName[Blank Object], 0, 0, 0)4649player.shield = SHIELD_NONE4650CheckEqual(options.spikeBehavior, 0)4651temp1 = checkResult4652CheckNotEqual(player.blinkTimer, 0)4653temp1 &= checkResult4654if temp1 == true4655PlaySfx(SfxName[Spike], false)4656else4657PlaySfx(SfxName[Hurt], false)4658end if4659else4660if player.rings == 04661if player.blinkTimer != 04662PlaySfx(SfxName[Spike], false)4663else4664PlaySfx(SfxName[Hurt], false)4665end if46664667temp0 = 34668else4669PlaySfx(SfxName[Lose Rings], false)4670temp0 = 24671end if4672end if4673else4674temp0 = 14675if player.blinkTimer != 04676PlaySfx(SfxName[Spike], false)4677else4678PlaySfx(SfxName[Hurt], false)4679end if4680end if46814682#platform: USE_ORIGINS4683if game.playMode == BOOT_PLAYMODE_MISSION4684// For the mission "Bodyguard" (Player 2 isn't in any other missions)4685if player.type == TypeName[Player 2 Object]4686temp0 = 34687game.forceKillPlayer = true4688end if4689end if4690#endplatform46914692player.visible = true46934694#platform: USE_ORIGINS4695if temp2 != 04696temp0 = 34697end if4698#endplatform46994700switch temp04701default4702case 0 // No effect4703break47044705case 1 // Recoil4706player.state = Player_State_Hurt4707player.animation = ANI_HURT4708player.yvel = -0x400004709player.gravity = GRAVITY_AIR4710player.scrollTracking = true4711player.tileCollisions = true4712player.blinkTimer = 12047134714if player.gravityStrength == 0x10004715player.speed >>= 14716player.yvel >>= 14717end if4718break47194720case 2 // Damage, losing rings4721player.state = Player_State_Hurt4722player.animation = ANI_HURT4723player.yvel = -0x400004724player.gravity = GRAVITY_AIR4725player.scrollTracking = true4726player.tileCollisions = true4727player.blinkTimer = 1204728if player.gravityStrength == 0x10004729player.speed >>= 14730player.yvel >>= 14731end if47324733temp0 = player.rings4734if temp0 > 164735temp1 = temp04736temp1 -= 164737temp0 = 164738else4739temp1 = 04740end if47414742if temp1 > 164743temp1 = 164744end if4745temp3 = temp14746temp3 >>= 14747temp3 <<= 54748temp2 = 3844749temp2 -= temp34750temp3 >>= 44751if temp3 == temp14752temp2 += 164753else4754temp2 -= 164755end if47564757temp3 = 04758while temp3 < temp14759CreateTempObject(TypeName[Lose Ring], player.collisionPlane, player.xpos, player.ypos)4760Cos(object[tempObjectPos].xvel, temp2)4761Sin(object[tempObjectPos].yvel, temp2)4762object[tempObjectPos].xvel <<= 84763object[tempObjectPos].yvel <<= 84764object[tempObjectPos].animationSpeed = 2564765object[tempObjectPos].inkEffect = INK_ALPHA4766object[tempObjectPos].alpha = 2564767temp3++4768temp2 += 324769loop4770temp3 = temp04771temp3 >>= 14772temp3 <<= 54773temp2 = 3844774temp2 -= temp34775temp3 >>= 44776if temp3 == temp04777temp2 += 164778else4779temp2 -= 164780end if47814782temp3 = 04783while temp3 < temp04784CreateTempObject(TypeName[Lose Ring], player.collisionPlane, player.xpos, player.ypos)4785Cos(object[tempObjectPos].xvel, temp2)4786Sin(object[tempObjectPos].yvel, temp2)4787object[tempObjectPos].xvel <<= 94788object[tempObjectPos].yvel <<= 94789object[tempObjectPos].animationSpeed = 2564790object[tempObjectPos].inkEffect = INK_ALPHA4791object[tempObjectPos].alpha = 2564792temp3++4793temp2 += 324794loop4795player.rings = 04796ringExtraLife = 1004797break47984799case 3 // Death!4800#platform: USE_STANDALONE4801player.sortedDrawOrder = 64802#endplatform4803#platform: USE_ORIGINS4804player.sortedDrawOrder = 74805#endplatform4806player.speed = 04807player.yvel = -0x700004808player.xvel = 04809player.state = Player_State_Death4810player.animation = ANI_DYING4811player.tileCollisions = false4812player.interaction = false4813#platform: USE_ORIGINS4814currentPlayer = object.entityPos4815#endplatform4816#platform: USE_STANDALONE4817if player.entityPos == camera[0].target4818#endplatform4819#platform: USE_ORIGINS4820if player.entityPos == camera[currentPlayer].target4821#endplatform4822player.priority = PRIORITY_ALWAYS4823if player[1].type == TypeName[Player 2 Object]4824player[1].priority = PRIORITY_ALWAYS4825end if4826#platform: USE_STANDALONE4827camera[0].enabled = false4828if options.vsMode == false4829stage.state = STAGE_FROZEN4830end if4831#endplatform48324833#platform: USE_ORIGINS4834if options.vsMode == false4835stage.state = STAGE_FROZEN4836camera[currentPlayer].enabled = false4837else4838camera[currentPlayer].style = CAMERASTYLE_STATIC4839end if4840#endplatform4841end if48424843if object[+playerCount].type == invincibilityType4844object[+playerCount].propertyValue = 34845end if48464847object[+playerCount].type = TypeName[Blank Object]4848break48494850end switch4851end function485248534854public function Player_State_Hurt4855if player.gravity == GRAVITY_AIR4856player.scrollTracking = true4857if player.gravityStrength == 0x38004858player.yvel += 0x30004859else4860player.yvel += 0xF004861end if48624863player.xvel = player.speed4864else4865player.state = Player_State_Ground4866player.speed = 04867player.xvel = 04868CallFunction(Player_HandleOnGround)4869end if4870end function487148724873public function Player_State_Death4874if player.entityPos == SLOT_PLAYER14875// If Player 1, then stop all Super activity4876if Player_superState == SUPERSTATE_SUPER4877Player_superState = SUPERSTATE_FADEOUT4878end if4879end if48804881if player.controlMode != CONTROLMODE_NONE4882player.yvel = -0x700004883player.controlMode = CONTROLMODE_NONE4884end if48854886if player.blinkTimer != 04887player.blinkTimer = 04888player.visible = true4889end if48904891player.yvel += 0x38004892if player.animation != ANI_BORED4893player.animation = ANI_DYING4894end if48954896currentPlayer = player.entityPos4897if player.entityPos == camera[currentPlayer].target4898temp0 = camera[currentPlayer].ypos4899temp0 += 2724900temp0 <<= 164901if player.ypos > temp04902player.ypos = temp04903end if4904end if49054906if player.yvel > 0x1000004907if player.isSidekick == false4908#platform: USE_ORIGINS4909CallNativeFunction2(NotifyCallback, NOTIFY_DEATH_EVENT, 0)4910#endplatform49114912// global variable "array" (yes, this is actually how its done)4913arrayPos0 = GLOBAL_PLAYERLIVES4914#platform: USE_DECOMP4915arrayPos0 = VarName[player.lives]4916#endplatform4917arrayPos0 += player.entityPos49184919#platform: USE_ORIGINS4920if game.coinMode == false4921if game.playMode != BOOT_PLAYMODE_MISSION4922CheckEqual(game.playMode, BOOT_PLAYMODE_BOSSRUSH)4923temp0 = checkResult4924CheckEqual(game.oneStageFlag, false)4925temp0 |= checkResult4926if temp0 != false4927global[arrayPos0]--4928end if4929end if4930end if4931#endplatform49324933#platform: USE_STANDALONE4934global[arrayPos0]--4935#endplatform49364937if options.vsMode == false4938stage.timeEnabled = false49394940player.type = TypeName[Death Event]4941#platform: USE_STANDALONE4942deathEvent.drawOrder = 64943deathEvent.leftTextPos = screen.xcenter4944deathEvent.leftTextPos -= 2644945deathEvent.rightTextPos = screen.xcenter4946deathEvent.rightTextPos += 2004947#endplatform4948#platform: USE_ORIGINS4949deathEvent.drawOrder = 74950deathEvent.leftTextPos = screen.xcenter4951deathEvent.leftTextPos -= 2324952deathEvent.rightTextPos = screen.xcenter4953deathEvent.rightTextPos += 2324954#endplatform4955if options.gameMode == MODE_TIMEATTACK4956deathEvent.timer = 04957deathEvent.state = DEATHEVENT_DEATH_TA4958else4959if global[arrayPos0] == 0 // If the player has no lives left4960deathEvent.timer = -28804961deathEvent.state = DEATHEVENT_GAMEOVER4962PlayMusic(TRACK_GAMEOVER)4963stage.pauseEnabled = false4964#platform: USE_ORIGINS4965if game.oneStageFlag != false4966if game.playMode == BOOT_PLAYMODE_BOSSRUSH4967CallNativeFunction4(NotifyCallback, NOTIFY_STAGE_RETRY, 0, stage.listPos, 0)4968end if4969end if4970#endplatform4971else4972deathEvent.timer = 04973deathEvent.state = DEATHEVENT_DEATH4974if stage.timeOver == true4975#platform: USE_ORIGINS4976if game.oneStageFlag == false4977#endplatform4978deathEvent.timer = -28804979deathEvent.state = DEATHEVENT_TIMEOVER4980PlayMusic(TRACK_GAMEOVER)4981stage.pauseEnabled = false4982#platform: USE_ORIGINS4983end if4984#endplatform4985end if4986end if4987end if4988else4989if global[arrayPos0] == 0 // player.lives4990player.type = TypeName[Death Event]4991deathEvent.state = DEATHEVENT_GAMEOVER4992end if49934994if stage.timeOver == true4995player.type = TypeName[Death Event]4996deathEvent.state = DEATHEVENT_TIMEOVER4997end if49984999if player.type == TypeName[Death Event]5000#platform: USE_STANDALONE5001deathEvent.drawOrder = 65002deathEvent.leftTextPos = screen.xcenter5003deathEvent.leftTextPos -= 2645004deathEvent.rightTextPos = screen.xcenter5005deathEvent.rightTextPos += 2005006#endplatform5007#platform: USE_ORIGINS5008deathEvent.drawOrder = 75009deathEvent.leftTextPos = screen.xcenter5010deathEvent.leftTextPos -= 2325011deathEvent.rightTextPos = screen.xcenter5012deathEvent.rightTextPos += 2325013#endplatform5014deathEvent.timer = -28805015PlayMusic(TRACK_GAMEOVER)5016stage.pauseEnabled = false5017else5018#platform: USE_STANDALONE5019player.state = Player_State_Air5020#endplatform5021#platform: USE_ORIGINS5022player.state = Player_State_Air_NoDropDash5023#endplatform5024player.rings = 05025player.priority = PRIORITY_ACTIVE5026player.gravity = GRAVITY_AIR5027player.animation = ANI_HURT5028if player.entityPos == SLOT_PLAYER15029player.xpos = vs.restartX15030player.ypos = vs.restartY15031else5032player.xpos = vs.restartX25033player.ypos = vs.restartY25034end if5035player.direction = FACING_RIGHT5036player.tileCollisions = true5037player.interaction = true5038player.visible = true5039#platform: USE_STANDALONE5040player.controlMode = CONTROLMODE_P15041#endplatform5042#platform: USE_ORIGINS5043player.controlMode = currentPlayer5044#endplatform5045player.scrollTracking = true5046player.drawOrder = DRAWORDER_PLAYER5047player.sortedDrawOrder = 45048player.collisionPlane = 05049#platform: USE_STANDALONE5050if player.entityPos == camera[0].target5051CreateTempObject(TypeName[VS Game], 0, player.xpos, player.ypos)5052vsGame[tempObjectPos].timer = 3845053vsGame[tempObjectPos].state = VSGAME_FADEOUT5054camera[0].xpos = player.ixpos5055camera[0].ypos = player.iypos5056camera[0].enabled = true5057end if5058#endplatform5059#platform: USE_ORIGINS5060CreateTempObject(TypeName[VS Game], currentPlayer, player.xpos, player.ypos)5061vsGame[tempObjectPos].timer = 3845062vsGame[tempObjectPos].state = VSGAME_SCREENFADE5063camera[currentPlayer].xpos = player.ixpos5064camera[currentPlayer].ypos = player.iypos5065camera[currentPlayer].style = CAMERASTYLE_FOLLOW5066camera[currentPlayer].enabled = true5067#endplatform5068end if5069end if5070end if5071end if5072end function507350745075public function Player_State_Drown5076if player.entityPos == SLOT_PLAYER15077if Player_superState == SUPERSTATE_SUPER5078Player_superState = SUPERSTATE_FADEOUT5079end if5080end if50815082player.controlMode = CONTROLMODE_NONE5083player.yvel += player.gravityStrength5084player.animation = ANI_DROWNING50855086currentPlayer = player.entityPos5087if player.entityPos == camera[currentPlayer].target5088temp0 = camera[currentPlayer].ypos5089temp0 += 2725090temp0 <<= 165091if player.ypos > temp05092player.ypos = temp05093end if5094end if50955096if player.yvel > 0x800005097if player.isSidekick == false5098#platform: USE_ORIGINS5099CallNativeFunction2(NotifyCallback, NOTIFY_DEATH_EVENT, 0)5100#endplatform51015102// global variable "array" (yes, this is actually how its done)5103arrayPos0 = GLOBAL_PLAYERLIVES5104#platform: USE_DECOMP5105arrayPos0 = VarName[player.lives]5106#endplatform5107arrayPos0 += player.entityPos51085109#platform: USE_ORIGINS5110if global[arrayPos0] > 05111if game.coinMode == false5112if game.playMode != BOOT_PLAYMODE_MISSION5113CheckEqual(game.playMode, BOOT_PLAYMODE_BOSSRUSH)5114temp0 = checkResult5115CheckEqual(game.oneStageFlag, false)5116temp0 |= checkResult5117if temp0 != false5118global[arrayPos0]--5119end if5120end if5121end if5122end if5123#endplatform51245125#platform: USE_STANDALONE5126if global[arrayPos0] > 05127global[arrayPos0]--5128end if5129#endplatform51305131if options.vsMode == false5132stage.timeEnabled = false51335134player.type = TypeName[Death Event]5135#platform: USE_STANDALONE5136deathEvent.drawOrder = 65137deathEvent.leftTextPos = screen.xcenter5138deathEvent.leftTextPos -= 2645139deathEvent.rightTextPos = screen.xcenter5140deathEvent.rightTextPos += 2005141#endplatform5142#platform: USE_ORIGINS5143deathEvent.drawOrder = 75144deathEvent.leftTextPos = screen.xcenter5145deathEvent.leftTextPos -= 2325146deathEvent.rightTextPos = screen.xcenter5147deathEvent.rightTextPos += 2325148#endplatform5149if options.gameMode == MODE_TIMEATTACK5150deathEvent.timer = 05151deathEvent.state = DEATHEVENT_DEATH_TA5152else5153#platform: USE_STANDALONE5154if global[arrayPos0] == 05155#endplatform5156#platform: USE_ORIGINS5157if player.lives == 05158#endplatform5159deathEvent.timer = -28805160deathEvent.state = DEATHEVENT_GAMEOVER5161PlayMusic(TRACK_GAMEOVER)5162stage.pauseEnabled = false5163else5164deathEvent.timer = 05165deathEvent.state = DEATHEVENT_DEATH5166end if5167end if5168else5169#platform: USE_STANDALONE5170player.state = Player_State_Air5171#endplatform5172#platform: USE_ORIGINS5173player.state = Player_State_Air_NoDropDash5174#endplatform5175player.rings = 05176player.priority = PRIORITY_ACTIVE5177player.gravity = GRAVITY_AIR5178player.animation = ANI_HURT5179if player.entityPos == SLOT_PLAYER15180player.xpos = vs.restartX15181player.ypos = vs.restartY15182else5183player.xpos = vs.restartX25184player.ypos = vs.restartY25185end if51865187player.direction = FACING_RIGHT5188player.tileCollisions = true5189player.interaction = true5190player.visible = true5191#platform: USE_STANDALONE5192player.controlMode = CONTROLMODE_P15193#endplatform5194#platform: USE_ORIGINS5195player.controlMode = currentPlayer5196#endplatform5197player.scrollTracking = true5198player.drawOrder = DRAWORDER_PLAYER5199player.sortedDrawOrder = 45200player.collisionPlane = 05201#platform: USE_STANDALONE5202if player.entityPos == camera[0].target5203CreateTempObject(TypeName[VS Game], 0, player.xpos, player.ypos)5204vsGame[tempObjectPos].timer = 3845205vsGame[tempObjectPos].state = VSGAME_FADEOUT5206camera[0].xpos = player.ixpos5207camera[0].ypos = player.iypos5208camera[0].enabled = true5209end if5210#endplatform5211#platform: USE_ORIGINS5212CreateTempObject(TypeName[VS Game], currentPlayer, player.xpos, player.ypos)5213vsGame[tempObjectPos].timer = 3845214vsGame[tempObjectPos].state = VSGAME_SCREENFADE5215camera[currentPlayer].xpos = player.ixpos5216camera[currentPlayer].ypos = player.iypos5217camera[currentPlayer].style = CAMERASTYLE_FOLLOW5218camera[currentPlayer].enabled = true5219#endplatform5220end if5221end if5222end if5223end function522452255226// Wacky Workbench hanging bar gimmick5227// Unused leftover from CD5228public function Player_State_HangBar5229if player.left == true5230player.direction = FACING_LEFT5231player.speed = -0x200005232player.animationSpeed = 305233else5234if player.right == true5235player.direction = FACING_RIGHT5236player.speed = 0x200005237player.animationSpeed = 305238else5239player.speed = 05240player.animationSpeed = 05241end if5242end if5243temp1 = player.xpos5244temp1 >>= 165245temp2 = player.ypos5246temp2 >>= 165247temp2 += player.collisionTop52485249Get16x16TileInfo(temp0, temp1, temp2, TILEINFO_ANGLEB)5250if temp0 != 3 // this is the bar tile flag value5251// and even if this function isn't used in Origins they still updated it there lol5252#platform: USE_STANDALONE5253player.state = Player_State_Air5254#endplatform5255#platform: USE_ORIGINS5256player.state = Player_State_Air_NoDropDash5257#endplatform5258player.speed = 05259player.animationSpeed = 05260player.yvel = 05261end if52625263if player.jumpPress == true5264player.state = Player_State_Air5265player.yvel = 05266player.speed = 05267player.animationSpeed = 05268player.ypos += 0x400005269end if52705271player.xvel = player.speed5272end function527352745275public function Player_State_TubeRoll5276#platform: USE_ORIGINS5277temp7 = -15278CallFunction(Player_SetDropDashCharge)5279#endplatform52805281if player.gravity == GRAVITY_AIR5282player.state = Player_State_TubeAirRoll5283player.timer = 05284CallFunction(Player_HandleAirMovement)5285else5286if player.speed > 05287if player.collisionMode == CMODE_FLOOR5288if player.speed < 0x100005289player.speed = 0x400005290end if5291end if5292else5293if player.collisionMode == CMODE_FLOOR5294if player.speed > -0x100005295player.speed = -0x400005296end if5297end if5298end if52995300if player.right == true5301if player.speed < 05302player.speed += player.rollingDeceleration5303end if5304end if53055306if player.left == true5307if player.speed > 05308player.speed -= player.rollingDeceleration5309end if5310end if53115312if player.speed > 05313player.speed -= player.rollingFriction5314Sin256(temp0, player.angle)5315if temp0 > 05316Sin256(temp0, player.angle)5317temp0 *= 0x50005318else5319Sin256(temp0, player.angle)5320temp0 *= 0x1E005321end if5322temp0 >>= 853235324player.speed += temp05325else5326player.speed += player.rollingFriction5327Sin256(temp0, player.angle)5328if temp0 < 05329Sin256(temp0, player.angle)5330temp0 *= 0x50005331else5332Sin256(temp0, player.angle)5333temp0 *= 0x1E005334end if5335temp0 >>= 853365337player.speed += temp05338end if53395340CallFunction(Player_HandleRollAnimSpeed)5341player.animationSpeed = player.rollAnimationSpeed5342CallFunction(Player_HandleOnGround)5343end if5344end function534553465347// Unused state5348// WFZ's clinging just uses an identical duplicate of this instead (WFZSetup_State_Clinging) stored within the stage's setup script5349public function Player_State_Clinging5350player.gravity = GRAVITY_AIR5351if player.animation != ANI_CLINGING5352player.xvel = 0x800005353player.speed = 0x800005354else5355player.xvel = 05356player.speed = 05357end if53585359if player.up == true5360player.ypos -= 0x100005361else5362if player.down == true5363player.ypos += 0x100005364end if5365end if53665367player.yvel = 05368end function536953705371public function Player_State_Waterslide5372if player.gravity == GRAVITY_AIR5373#platform: USE_STANDALONE5374player.state = Player_State_Air5375#endplatform5376#platform: USE_ORIGINS5377player.state = Player_State_Air_NoDropDash5378#endplatform5379player.angle = 05380player.collisionMode = CMODE_FLOOR5381player.timer = 05382CallFunction(Player_HandleAirMovement)5383player.animation = ANI_WATERSLIDE5384else5385if player.direction == FACING_RIGHT5386player.speed = 0xA00005387else5388player.speed = -0xA00005389end if5390CallFunction(Player_HandleRollAnimSpeed)5391player.animation = ANI_WATERSLIDE53925393CallFunction(Player_HandleOnGround)5394if player.jumpPress == true5395CallFunction(Player_Action_Jump)5396end if5397end if5398end function539954005401public function Player_State_ContinueRun5402if player.speed > 0x100005403player.timer = 05404if player.speed < 0x5F5C25405player.animation = ANI_WALKING5406CallFunction(Player_HandleWalkAnimSpeed)5407else5408if player.speed > 0x9FFFF5409player.animation = ANI_PEELOUT5410else5411player.animation = ANI_RUNNING5412end if54135414CallFunction(Player_HandleRunAnimSpeed)5415end if5416end if5417end function54185419public function Player_Action_DblJumpAmy5420#platform: USE_ORIGINS5421if keyPress[1].buttonY != false5422CheckEqual(specialStage.emeralds, 0x7F)5423temp0 = checkResult5424CheckGreater(player.rings, 49)5425temp0 &= checkResult5426CheckNotEqual(Player_superState, SUPERSTATE_SUPER)5427temp0 &= checkResult54285429if temp0 == true5430currentPlayer = player.entityPos5431CallFunction(Player_TryTransform)5432end if5433end if54345435if player.jumpPress == true5436PlaySfx(SfxName[HammerJump], false)5437CallNativeFunction4(NotifyCallback, NOTIFY_STATS_CHARA_ACTION2, 0, 1, 0)54385439// Change the animation without resetting the frame or animation speed5440temp0 = player.animationSpeed5441temp1 = player.frame5442player.animation = ANI_HAMMER_JUMP5443ProcessAnimation()5444player.animationSpeed = temp05445player.frame = temp154465447// No states are set here or anything, instead Amy shares Sonic's Drop Dash code seen in Player_HandleDropDash5448end if5449#endplatform5450end function545154525453public function Player_Action_HammerDash5454#platform: USE_ORIGINS5455PlaySfx(SfxName[HammerDash], false)54565457player.state = Player_State_HammerDash5458player.animation = ANI_HAMMER_DASH5459player.timer = 054605461temp7 = -15462CallFunction(Player_SetDropDashCharge)5463CallFunction(Player_SetHammerDashSpeed)5464#endplatform5465end function546654675468public function Player_State_HammerDash5469#platform: USE_ORIGINS5470if player.right == true5471player.direction = FACING_RIGHT5472else5473if player.left == true5474player.direction = FACING_LEFT5475end if5476end if54775478temp0 = true54795480if player.speed != 05481player.timer++5482if player.jumpHold == true5483if player.timer < 605484CallFunction(Player_SetHammerDashSpeed)5485if player.gravity == GRAVITY_AIR5486CallFunction(Player_HandleAirMovement)5487else5488CallFunction(Player_HandleOnGround)5489end if5490temp0 = false5491end if5492end if5493end if54945495// If Amy is on a steep enough slope, cancel the move5496// (Despite the patch notes for version 2.0.1 claiming this was removed, it's very much still here)5497Cos256(temp1, player.angle)5498if temp1 <= 05499temp0 = true5500end if55015502if temp0 == true5503object.state = Player_State_Ground5504end if5505#endplatform5506end function550755085509public function Player_SetHammerDashSpeed5510#platform: USE_ORIGINS5511if player.direction == FACING_RIGHT5512player.speed = 0x600005513else5514// Could they not have just set it to -0x60000?5515player.speed = 05516player.speed -= 0x600005517end if5518#endplatform5519end function552055215522// ========================5523// Events5524// ========================55255526event ObjectUpdate5527#platform: USE_ORIGINS5528currentPlayer = player.entityPos5529#endplatform55305531if stage.debugMode == true5532CallFunction(Player_ProcessUpdate)5533CheckEqual(options.attractMode, false)5534temp0 = checkResult5535CheckEqual(keyPress[0].buttonB, true)5536temp0 &= checkResult5537if temp0 == true5538currentPlayer = player.entityPos5539player.type = TypeName[Debug Mode]5540player.yvel = 05541player.state = Player_State_Static5542player.frame = 05543player.rotation = 05544player.interaction = false5545player.drawOrder = 45546player.priority = PRIORITY_ACTIVE5547player.blinkTimer = 05548player.visible = true5549player.abilityTimer = 05550player.drownTimer = 05551player.drownLevel = 05552player.frame = debugMode.currentSelection5553camera[currentPlayer].enabled = true5554camera[currentPlayer].style = CAMERASTYLE_FOLLOW5555player.hitboxLeft = C_BOX5556player.hitboxTop = C_BOX5557player.hitboxRight = C_BOX5558player.hitboxBottom = C_BOX55595560// This pretty much only happens when the player died, but now that they're entering Debug Mode, everything can be restored again5561if stage.state == STAGE_FROZEN5562stage.state = STAGE_RUNNING5563end if55645565if player[1].type == TypeName[Player 2 Object]5566player[1].priority = PRIORITY_ACTIVE5567end if55685569if object[+playerCount].propertyValue == 35570object[+playerCount].type = invincibilityType5571object[+playerCount].propertyValue = 05572end if5573else5574if player.gravity == GRAVITY_GROUND5575player.jumpAbilityState = 05576end if55775578CallFunction(player.state)55795580// The Origins folks didn't put the Drop Dash "animation" code here...55815582currentPlayer = player.entityPos55835584ProcessAnimation()55855586if player.entityPos == camera[currentPlayer].target5587// Bug Details:5588// This check handles the jump offset so the jump ball sprite isn't higher than it's supposed to be relative to the actual player position5589// In Origins Plus, Amy has a second animation related to being in a jumpball, but this code doesn't take that into account. Whoops!5590if player.animation == ANI_JUMPING5591camera[currentPlayer].adjustY = player.jumpOffset5592else5593if camera[currentPlayer].adjustY == player.jumpOffset5594camera[currentPlayer].adjustY = 05595player.iypos += player.jumpOffset5596end if5597end if5598end if55995600if player.collisionDisabled == false5601temp0 = player.prevGravity5602player.prevGravity = player.gravity5603ProcessObjectMovement()5604player.prevGravity ^= GRAVITY_AIR5605CheckEqual(player.gravity, GRAVITY_GROUND)5606player.prevGravity |= checkResult5607player.prevGravity ^= GRAVITY_AIR56085609if temp0 == GRAVITY_AIR5610if player.prevGravity == GRAVITY_GROUND5611player.badnikBonus = 05612if player.animation == ANI_JUMPING5613if player.down == false5614if player.state != Player_State_BubbleBounce5615if player.state != Player_State_Roll5616if player.state != Player_State_TubeRoll5617player.animation = ANI_WALKING5618if player.entityPos == camera[currentPlayer].target5619camera[currentPlayer].adjustY = 05620end if56215622player.iypos += player.jumpOffset5623end if5624end if5625end if5626end if5627end if5628end if5629end if5630else5631player.collisionDisabled = false5632end if5633end if5634else5635CallFunction(Player_ProcessUpdate)56365637if player.gravity == GRAVITY_GROUND5638player.jumpAbilityState = 05639end if56405641CallFunction(player.state)56425643currentPlayer = player.entityPos56445645#platform: USE_ORIGINS5646// Set Sonic to always use the full ball sprite while drop dashing5647// Bug Details: This implementation has the side effect of freezing Sonic's/Amy's sprite while on Casino Night's flippers if they landed with a Drop Dash charged5648CallFunction(Player_GetDropDashCharge)5649if temp7 >= 205650if player.animation == ANI_JUMPING5651player.frame = 15652player.animationTimer = 05653player.animationSpeed = 15654end if5655end if5656#endplatform56575658ProcessAnimation()56595660if player.entityPos == camera[currentPlayer].target5661// Bug Details: See above5662if player.animation == ANI_JUMPING5663camera[currentPlayer].adjustY = player.jumpOffset5664else5665if camera[currentPlayer].adjustY == player.jumpOffset5666camera[currentPlayer].adjustY = 05667player.iypos += player.jumpOffset5668end if5669end if5670end if56715672if player.collisionDisabled == false5673temp0 = player.prevGravity5674player.prevGravity = player.gravity5675ProcessObjectMovement()5676player.prevGravity ^= GRAVITY_AIR5677CheckEqual(player.gravity, GRAVITY_GROUND)5678player.prevGravity |= checkResult5679player.prevGravity ^= GRAVITY_AIR56805681if temp0 == GRAVITY_AIR5682if player.prevGravity == GRAVITY_GROUND5683player.badnikBonus = 05684if player.animation == ANI_JUMPING5685if player.down == false5686if player.state != Player_State_BubbleBounce5687if player.state != Player_State_Roll5688if player.state != Player_State_TubeRoll5689player.animation = ANI_WALKING5690if player.entityPos == camera[currentPlayer].target5691camera[currentPlayer].adjustY = 05692end if56935694player.iypos += player.jumpOffset5695end if5696end if5697end if5698end if5699end if5700end if5701end if5702else5703player.collisionDisabled = false5704end if5705end if57065707CallFunction(Player_HandleSuperForm)57085709#platform: USE_ORIGINS5710if game.playMode == BOOT_PLAYMODE_BOSSRUSH5711if game.missionCondition == MISSION_CONDITION_CLEAR5712player.invincibleTimer = 8057135714// Death Egg Zone handles the following itself5715CheckCurrentStageFolder("BR9Zone12")5716if checkResult == false5717CheckEqual(player[SLOT_PLAYER1].state, Player_State_Ground)5718temp0 = checkResult5719CheckEqual(player[SLOT_PLAYER1].state, Player_State_Static)5720temp0 |= checkResult57215722if temp0 == true5723// Prevent the player from moving anymore5724// Don't know why we have to specify object slot 0 when this code will only ever run in that slot but ok5725player[SLOT_PLAYER1].state = Player_State_Static5726player[SLOT_PLAYER1].controlMode = CONTROLMODE_NONE5727player[SLOT_PLAYER1].interaction = false5728player[SLOT_PLAYER1].up = false5729player[SLOT_PLAYER1].down = false5730player[SLOT_PLAYER1].left = false5731player[SLOT_PLAYER1].right = false5732player[SLOT_PLAYER1].jumpHold = false5733player[SLOT_PLAYER1].jumpPress = false5734player[SLOT_PLAYER1].xvel = 05735player[SLOT_PLAYER1].yvel = 05736player[SLOT_PLAYER1].speed = 05737player[SLOT_PLAYER1].animation = ANI_WAITING5738end if5739end if5740end if5741end if57425743CallFunction(Player_HandleAmyHitbox)5744#endplatform5745end event574657475748event ObjectDraw5749if player.animation != player.prevAnimation5750// If the player's animation is different than the one they had last frame, reset all the other animation values too5751// Note that the ProcessAnimation function seen in ObjectMain does this too, so this is more of a fail-safe5752player.prevAnimation = player.animation5753player.frame = 05754player.animationTimer = 05755player.animationSpeed = 05756end if57575758DrawObjectAnimation()5759end event576057615762event ObjectStartup5763playerCount = 057645765// Do note, the foreach goes order ascending, which is why Origins mission scenes with several Player Objects can still function correctly since5766// the last one on the list is used5767foreach (TypeName[Player Object], arrayPos0, ALL_ENTITIES)5768camera[0].enabled = true5769camera[0].style = CAMERASTYLE_FOLLOW5770camera[0].target = SLOT_PLAYER157715772currentPlayer = SLOT_PLAYER157735774#platform: USE_STANDALONE5775if stage.playerListPos >= PLAYER_SONIC_TAILS_A // If playing as Sonic & Tails5776stage.playerListPos = PLAYER_SONIC_A5777stage.player2Enabled = true5778end if5779#endplatform57805781#platform: USE_ORIGINS5782switch stage.playerListPos5783case PLAYER_SONIC_TAILS_A5784stage.playerListPos = PLAYER_SONIC5785stage.player2Enabled = true5786break57875788case PLAYER_KNUCKLES_TAILS_A5789stage.playerListPos = PLAYER_KNUCKLES5790stage.player2Enabled = true5791break57925793case PLAYER_AMY_TAILS_A5794stage.playerListPos = PLAYER_AMY5795stage.player2Enabled = true5796break5797end switch5798#endplatform57995800ResetObjectEntity(SLOT_PLAYER1, TypeName[Player Object], 0, player[arrayPos0].xpos, player[arrayPos0].ypos)5801camera[0].xpos = player[SLOT_PLAYER1].ixpos5802camera[0].ypos = player[SLOT_PLAYER1].iypos58035804player[SLOT_PLAYER1].groupID = GROUP_PLAYERS5805player[SLOT_PLAYER1].state = Player_State_Air5806player[SLOT_PLAYER1].priority = PRIORITY_ACTIVE5807player[SLOT_PLAYER1].drawOrder = DRAWORDER_PLAYER5808player[SLOT_PLAYER1].sortedDrawOrder = 45809player[SLOT_PLAYER1].rollingDeceleration = 0x20005810player[SLOT_PLAYER1].spindashFunction = Player_Action_Spindash5811player[SLOT_PLAYER1].hitboxLeft = C_BOX5812player[SLOT_PLAYER1].hitboxTop = C_BOX5813player[SLOT_PLAYER1].hitboxRight = C_BOX5814player[SLOT_PLAYER1].hitboxBottom = C_BOX58155816// Reset things for Super forms5817Player_superState = SUPERSTATE_NONE5818Player_superRingLossTimer = 05819Player_superBlendClr = 05820Player_superBlendTimer = 058215822switch stage.playerListPos5823case PLAYER_SONIC_A5824LoadAnimation("SuperSonic.ani") // This isn't because you're starting the act as Super Sonic, this is here to load all the necessary sprite sheets5825LoadAnimation("Sonic.ani")5826CallFunction(Player_HandleSuperPalette_Sonic)5827player[SLOT_PLAYER1].character = PLAYER_SONIC_A5828player[SLOT_PLAYER1].jumpOffset = -55829player[SLOT_PLAYER1].jumpAbility = Player_Action_DblJumpSonic5830ANI_PEELOUT = ANI_RUNNING5831break58325833case PLAYER_TAILS_A5834player[SLOT_PLAYER1].type = TypeName[Tails Object]5835player[SLOT_PLAYER1].character = PLAYER_TAILS_A5836CallFunction(Player_HandleSuperPalette_Tails)5837LoadAnimation("Tails.ani")5838player[SLOT_PLAYER1].jumpOffset = -158395840if options.vsMode == true5841options.tailsFlight = true5842end if58435844if options.tailsFlight == true5845player[SLOT_PLAYER1].jumpAbility = Player_Action_DblJumpTails5846else5847player[SLOT_PLAYER1].jumpAbility = Player_State_Static // Not being used as a State here, simply more of a dummy function5848end if58495850stage.player2Enabled = false5851break58525853case PLAYER_KNUCKLES_A5854LoadAnimation("Knuckles.ani")5855CallFunction(Player_HandleSuperPalette_Knux)5856player[SLOT_PLAYER1].character = PLAYER_KNUCKLES_A5857player[SLOT_PLAYER1].jumpOffset = -55858player[SLOT_PLAYER1].jumpAbility = Player_Action_DblJumpKnux5859ANI_PEELOUT = ANI_RUNNING58605861// Note this check is actually bugged, this only checks for the last three save slots, ignoring the first one5862// Also yes this check is still in Origins LOL5863// It only works perchance, as per the bug listed right above5864if options.saveSlot > 05865stage.player2Enabled = false5866end if5867break58685869#platform: USE_ORIGINS5870case PLAYER_AMY_A5871LoadAnimation("Amy.ani")5872CallFunction(Player_HandleSuperPalette_Amy)5873player[SLOT_PLAYER1].character = PLAYER_AMY5874player[SLOT_PLAYER1].jumpOffset = -45875player[SLOT_PLAYER1].jumpAbility = Player_Action_DblJumpAmy5876ANI_PEELOUT = ANI_RUNNING5877break5878#endplatform5879end switch58805881if stage.player2Enabled == true5882playerCount = 25883else5884playerCount = 15885end if58865887currentPlayer = SLOT_PLAYER15888CallFunction(Player_UpdatePhysicsState)5889ResetObjectEntity(arrayPos0, TypeName[Blank Object], 0, 0, 0)5890next5891end event589258935894// ========================5895// Editor Events5896// ========================58975898event RSDKDraw5899DrawSprite(0)5900end event590159025903event RSDKLoad5904LoadSpriteSheet("Players/Sonic1.gif")5905SpriteFrame(-16, -19, 27, 39, 1, 1)59065907// used in-game, but shouldn't be set from the editor5908SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")5909end event591059115912