Path: blob/master/Sonic 1/Scripts/Players/Player2Object.txt
1480 views
// ----------------------------------1// RSDK Project: Sonic 12// Script Description: "Player 2 Object" Object3// Script Author: Christian Whitehead/Simon Thomley4// Unpacked by Rubberduckycooly's script unpacker5// ----------------------------------67// ========================8// Aliases9// ========================1011private alias object.type : player.type12private alias object.groupID : player.groupID13private alias object.state : player.state14private alias object.visible : player.visible15private alias object.propertyValue : player.character16private alias object.priority : player.priority17private alias object.xpos : player.xpos18private alias object.ypos : player.ypos19private alias object.iypos : player.iypos20private alias object.lookPosY : player.lookPosY21private alias object.xvel : player.xvel22private alias object.yvel : player.yvel23private alias object.speed : player.speed24private alias object.rotation : player.rotation25private alias object.angle : player.angle26private alias object.direction : player.direction27private alias object.gravity : player.gravity28private alias object.frame : player.frame29private alias object.animation : player.animation30private alias object.prevAnimation : player.prevAnimation31private alias object.animationSpeed : player.animationSpeed32private alias object.animationTimer : player.animationTimer33private alias object.drawOrder : player.drawOrder34private alias object.controlLock : player.controlLock35private alias object.controlMode : player.controlMode36private alias object.interaction : player.interaction37private alias object.collisionPlane : player.collisionPlane38private alias object.tileCollisions : player.tileCollisions39private alias object.outOfBounds : player.outOfBounds4041private alias object.jumpPress : player.jumpPress42private alias object.jumpHold : player.jumpHold43private alias object.up : player.up44private alias object.down : player.down45private alias object.left : player.left46private alias object.right : player.right4748// The majority of these are the same as the Player Object, though a couple - namely the last few - are different49private alias object.value1 : player.timer50private alias object.value3 : player.drownTimer51private alias object.value4 : player.drownLevel52private alias object.value7 : player.invincibleTimer53private alias object.value8 : player.blinkTimer54private alias object.value12 : player.tailFrame55private alias object.value13 : player.tailAnim56private alias object.value16 : player.isSidekick57private alias object.value18 : player.sortedDrawOrder58private alias object.value19 : player.badnikBonus59private alias object.value25 : player.gravityStrength60private alias object.value26 : player.flightVelocity61private alias object.value30 : player.jumpOffset62private alias object.value31 : player.rollingDeceleration63private alias object.value32 : player.jumpAbility64private alias object.value33 : player.actionSpindash65private alias object.value34 : player.collisionDisabled66private alias object.value40 : player.hitboxLeft67private alias object.value38 : player.hitboxTop68private alias object.value41 : player.hitboxRight69private alias object.value39 : player.hitboxBottom70private alias object.value42 : player.prevGravity7172// These following values are exclusive to the Player 2 Object73// (Neat trivia - did you know that in the initial versions of the game, Origins's Drop Dash overlapped with these values?74// That's why Tails wouldn't respawn a lot of the time, since every time he jumped his Drop Dash timer,75// which overlapped with his respawn timer, would also reset. Nowadays though, the Drop Dash is a global var instead)76private alias object.value43 : player.jumpInTimer77private alias object.value44 : player.stateInputP278private alias object.value45 : player.autoJumpTimer79private alias object.value46 : player.targetLeaderPos.x80private alias object.value47 : player.targetLeaderPos.y8182// Draw Order Aliases83private alias -1 : DRAWORDER_PLAYER8485// player.character Aliases86private alias 1 : CHARACTER_TAILS8788// Reserved Object Slots89private alias 0 : SLOT_PLAYER190private alias 1 : SLOT_PLAYER2919293// ========================94// Function Declarations95// ========================9697reserve function Player2_GetDelayedInput98reserve function Player2_Input_GamepadAssist99reserve function Player2_Input_AI_Follow100reserve function Player2_Input_AI_SpindashPt1101reserve function Player2_Input_AI_SpindashPt2102reserve function Player2_State_FlyToPlayer103reserve function Player2_HandleSidekickRespawn104reserve function Player2_ProcessUpdateP2105reserve function Player2_Input_None106reserve function Player2_Action_DblJumpTailsAI107108109// ========================110// Static Values111// ========================112113public value Player2_stateUp = 0114public value Player2_stateDown = 0115public value Player2_stateLeft = 0116public value Player2_stateRight = 0117public value Player2_stateJumpPress = 0118public value Player2_stateJumpHold = 0119public value Player2_nextLeaderPosID = 0120public value Player2_lastLeaderPosID = 0121122123// ========================124// Tables125// ========================126127public table Player2_leaderPosBufferX[16]128public table Player2_leaderPosBufferY[16]129130131// ========================132// Function Definitions133// ========================134135public function Player2_Input_None136temp0 = 0137end function138139140public function Player2_Action_DblJumpTailsAI141CheckNotEqual(player.stateInputP2, Player2_Input_None)142temp0 = checkResult143#platform: USE_ORIGINS144CheckNotEqual(player.stateInputP2, Player2_Input_GamepadAssist)145temp0 &= checkResult146#endplatform147CheckNotEqual(player.up, true)148temp0 &= checkResult149if temp0 == false150CallFunction(Player_Action_DblJumpTails)151end if152end function153154155public function Player2_GetDelayedInput156if player.controlMode > CONTROLMODE_NONE157Player2_stateUp <<= 1158Player2_stateUp |= player[SLOT_PLAYER1].up159Player2_stateUp &= 0xFFFF160Player2_stateDown <<= 1161Player2_stateDown |= player[SLOT_PLAYER1].down162Player2_stateDown &= 0xFFFF163Player2_stateLeft <<= 1164Player2_stateLeft |= player[SLOT_PLAYER1].left165Player2_stateLeft &= 0xFFFF166Player2_stateRight <<= 1167Player2_stateRight |= player[SLOT_PLAYER1].right168Player2_stateRight &= 0xFFFF169Player2_stateJumpPress <<= 1170Player2_stateJumpPress |= player[SLOT_PLAYER1].jumpPress171Player2_stateJumpPress &= 0xFFFF172Player2_stateJumpHold <<= 1173Player2_stateJumpHold |= player[SLOT_PLAYER1].jumpHold174Player2_stateJumpHold &= 0xFFFF175176if player[SLOT_PLAYER1].state == Player_State_Carried177Player2_stateDown <<= 15178Player2_stateLeft <<= 15179Player2_stateRight <<= 15180Player2_stateJumpPress <<= 15181Player2_stateJumpHold <<= 15182end if183184temp0 = Player2_stateUp185temp0 >>= 15186player.up = temp0187188temp0 = Player2_stateDown189temp0 >>= 15190player.down = temp0191192temp0 = Player2_stateLeft193temp0 >>= 15194player.left = temp0195196temp0 = Player2_stateRight197temp0 >>= 15198player.right = temp0199200temp0 = Player2_stateJumpPress201temp0 >>= 15202player.jumpPress = temp0203204temp0 = Player2_stateJumpHold205temp0 >>= 15206player.jumpHold = temp0207else208Player2_stateUp = 0209Player2_stateDown = 0210Player2_stateLeft = 0211Player2_stateRight = 0212Player2_stateJumpPress = 0213Player2_stateJumpHold = 0214end if215216if player[SLOT_PLAYER1].state != Player_State_Death217if player[SLOT_PLAYER1].type != TypeName[Death Event]218SetTableValue(player[SLOT_PLAYER1].xpos, Player2_lastLeaderPosID, Player2_leaderPosBufferX)219SetTableValue(player[SLOT_PLAYER1].ypos, Player2_lastLeaderPosID, Player2_leaderPosBufferY)220Player2_lastLeaderPosID++221Player2_lastLeaderPosID &= 15222Player2_nextLeaderPosID++223Player2_nextLeaderPosID &= 15224225// (check if P1's in the air this frame while they weren't last frame)226CheckEqual(player[SLOT_PLAYER1].gravity, GRAVITY_AIR)227temp0 = checkResult228CheckEqual(player[SLOT_PLAYER1].prevGravity, GRAVITY_GROUND)229temp0 &= checkResult230if temp0 == false231GetTableValue(player.targetLeaderPos.x, Player2_nextLeaderPosID, Player2_leaderPosBufferX)232GetTableValue(player.targetLeaderPos.y, Player2_nextLeaderPosID, Player2_leaderPosBufferY)233else234player.targetLeaderPos.x = player[SLOT_PLAYER1].xpos235player.targetLeaderPos.y = player[SLOT_PLAYER1].ypos236end if237else238temp0 = Player2_lastLeaderPosID239temp0--240if temp0 < 0241temp0 += 16242end if243244GetTableValue(player.targetLeaderPos.x, temp0, Player2_leaderPosBufferX)245GetTableValue(player.targetLeaderPos.y, temp0, Player2_leaderPosBufferY)246end if247else248temp0 = Player2_lastLeaderPosID249temp0--250if temp0 < 0251temp0 += 16252end if253254GetTableValue(player.targetLeaderPos.x, temp0, Player2_leaderPosBufferX)255GetTableValue(player.targetLeaderPos.y, temp0, Player2_leaderPosBufferY)256end if257end function258259260public function Player2_Input_GamepadAssist261#platform: USE_ORIGINS262IsInputSlotAssigned(2)263if checkResult == false264player.stateInputP2 = Player2_Input_AI_Follow265AssignInputSlotToDevice(2, -1)266return267end if268269ProcessObjectControl()270271temp0 = player.up272temp0 |= player.down273temp0 |= player.left274temp0 |= player.right275temp0 |= player.jumpHold276if temp0 == false277player.autoJumpTimer++278if player.autoJumpTimer >= 600279player.stateInputP2 = Player2_Input_AI_Follow280AssignInputSlotToDevice(2, -1)281end if282else283player.autoJumpTimer = 0284end if285#endplatform286end function287288289public function Player2_Input_AI_Follow290CallFunction(Player2_GetDelayedInput)291if player[SLOT_PLAYER1].type == TypeName[Player Object]292temp0 = player.angle293temp0 += 16294temp0 &= 0xE0295if temp0 == 0296if player.left == true297temp0 = player[SLOT_PLAYER1].xpos298temp0 -= 0x80000299if player.xpos < temp0300if player.xvel <= 0301player.left = false302end if303end if304end if305306if player.right == true307temp0 = player[SLOT_PLAYER1].xpos308temp0 += 0x80000309if player.xpos > temp0310if player.yvel <= 0311player.right = false312end if313end if314end if315end if316317if player[SLOT_PLAYER1].state != Player_State_Carried318temp0 = player.targetLeaderPos.x319temp1 = player[SLOT_PLAYER1].gravity320temp1 |= player[SLOT_PLAYER1].prevGravity321if temp1 == GRAVITY_GROUND322if player[SLOT_PLAYER1].speed < 0x20000323if player[SLOT_PLAYER1].speed > -0x20000324if player[SLOT_PLAYER1].direction == FACING_RIGHT325temp0 -= 0x200000326else327temp0 += 0x200000328end if329end if330end if331end if332333temp0 -= player.xpos334if temp0 != 0335if temp0 < 0336if temp0 <= -0x300000337player.right = false338player.left = true339end if340341if player.speed != 0342if player.direction == FACING_LEFT343Cos256(temp1, player.angle)344temp1 *= 0xC0345player.xpos -= temp1346end if347end if348else349if temp0 >= 0x300000350player.left = false351player.right = true352end if353354if player.speed != 0355if player.direction == FACING_RIGHT356Cos256(temp1, player.angle)357temp1 *= 0xC0358player.xpos += temp1359end if360end if361end if362end if363364if player.animation == ANI_PUSHING365player.autoJumpTimer++366if player[SLOT_PLAYER1].direction == player.direction367if player[SLOT_PLAYER1].animation == ANI_PUSHING368player.autoJumpTimer = 0369end if370end if371372if player.autoJumpTimer >= 30373if player.gravity == GRAVITY_GROUND374CallFunction(Player_Action_Jump)375end if376player.timer = 0377player.autoJumpTimer = 0378end if379else380temp0 = player.ypos381temp0 -= player.targetLeaderPos.y382if temp0 > 0x200000383player.autoJumpTimer++384if player.autoJumpTimer >= 64385if player.gravity == GRAVITY_GROUND386CallFunction(Player_Action_Jump)387end if388player.timer = 0389player.autoJumpTimer = 0390end if391else392player.autoJumpTimer = 0393end if394end if395396if player.controlLock > 0397if player.speed < 0x8000398if player.speed > -0x8000399player.stateInputP2 = Player2_Input_AI_SpindashPt1400end if401end if402end if403end if404end if405406#platform: USE_ORIGINS407// Look for any input from controller 2408temp0 = keyDown[2].up409temp0 |= keyDown[2].down410temp0 |= keyDown[2].left411temp0 |= keyDown[2].right412temp0 |= keyDown[2].buttonA413temp0 |= keyDown[2].buttonB414temp0 |= keyDown[2].buttonC415416if temp0 == true417// Enable P2 controls418player.autoJumpTimer = 0419player.stateInputP2 = Player2_Input_GamepadAssist420end if421#endplatform422end function423424425public function Player2_Input_AI_SpindashPt1426player.up = false427player.down = false428player.left = false429player.right = false430player.jumpPress = false431player.jumpHold = false432if player.controlLock == 0433if player.gravity == GRAVITY_GROUND434if player.speed < 0x4000435if player.speed > -0x4000436player.stateInputP2 = Player2_Input_AI_SpindashPt2437player.autoJumpTimer = 1438if player.animation != ANI_SPINDASH439if player.xpos < player.targetLeaderPos.x440player.direction = FACING_RIGHT441else442player.direction = FACING_LEFT443end if444445player.down = true446end if447end if448end if449end if450end if451end function452453454public function Player2_Input_AI_SpindashPt2455if player.autoJumpTimer < 64456player.down = true457temp0 = player.autoJumpTimer458temp0 &= 15459if temp0 == 0460player.jumpPress = true461else462player.jumpPress = false463end if464player.autoJumpTimer++465else466player.autoJumpTimer = 0467player.down = false468player.jumpPress = false469player.stateInputP2 = Player2_Input_AI_Follow470end if471end function472473474public function Player2_State_FlyToPlayer475CallFunction(Player2_GetDelayedInput)476if player.gravityStrength == 0x3800477player.animation = ANI_FLYING478else479player.animation = ANI_SWIMMING480end if481482temp0 = player.targetLeaderPos.x483temp0 -= player.xpos484temp1 = temp0485temp0 >>= 4486487if player.xpos < player.targetLeaderPos.x488player.direction = FACING_RIGHT489if temp0 > 0xC0000490temp0 = 0xC0000491end if492493if player[SLOT_PLAYER1].xvel > 0494temp0 += player[SLOT_PLAYER1].xvel495end if496497temp0 += 0x10000498if temp0 > temp1499temp0 = temp1500temp1 = 0501end if502else503player.direction = FACING_LEFT504if temp0 < -0xC0000505temp0 = -0xC0000506end if507508if player[SLOT_PLAYER1].xvel < 0509temp0 += player[SLOT_PLAYER1].xvel510end if511512temp0 -= 0x10000513if temp0 < temp1514temp0 = temp1515temp1 = 0516end if517end if518player.xpos += temp0519520if player.ypos < player.targetLeaderPos.y521player.ypos += 0x10000522end if523524if player.ypos > player.targetLeaderPos.y525player.ypos -= 0x10000526end if527528if player[SLOT_PLAYER1].type != TypeName[Death Event]529if player[SLOT_PLAYER1].state != Player_State_Death530if player[SLOT_PLAYER1].state != Player_State_Drown531if player[SLOT_PLAYER1].state != Player_State_TubeRoll532if temp1 == 0533temp0 = player.targetLeaderPos.y534temp0 -= player.ypos535if temp0 < 0536FlipSign(temp0)537end if538539if temp0 < 0x20000540#platform: USE_STANDALONE541player.state = Player_State_Air542#endplatform543#platform: USE_ORIGINS544player.state = Player_State_Air_NoDropDash545#endplatform546547player.animation = ANI_JUMPING548player.gravity = GRAVITY_AIR549player.tileCollisions = true550player.interaction = true551player.controlMode = CONTROLMODE_P2552player.controlLock = 0553player.angle = 0554player.stateInputP2 = Player2_Input_AI_Follow555player.collisionPlane = player[SLOT_PLAYER1].collisionPlane556Player2_stateUp = 0557Player2_stateDown = 0558Player2_stateLeft = 0559Player2_stateRight = 0560Player2_stateJumpPress = 0561Player2_stateJumpHold = 0562end if563end if564end if565end if566end if567end if568end function569570571public function Player2_HandleSidekickRespawn572if player[SLOT_PLAYER1].type == TypeName[Player Object]573if player.outOfBounds == true574player.jumpInTimer++575else576player.jumpInTimer = 0577end if578579if player.jumpInTimer >= 240580player.jumpInTimer = 0581player.state = Player2_State_FlyToPlayer582player.xpos = player[SLOT_PLAYER1].xpos583player.ypos = screen.yoffset584player.ypos -= 128585player.ypos <<= 16586player.xvel = 0587player.yvel = 0588player.speed = 0589player.tileCollisions = false590player.interaction = false591player.controlMode = CONTROLMODE_P2592player.sortedDrawOrder = 4593player.drownTimer = 0594player.drownLevel = 0595end if596597CheckEqual(player[SLOT_PLAYER1].state, Player_State_Death)598temp0 = checkResult599CheckEqual(player[SLOT_PLAYER1].type, TypeName[Death Event])600temp0 |= checkResult601CheckNotEqual(player.state, Player_State_Hurt)602temp0 &= checkResult603CheckNotEqual(player.state, Player_State_Death)604temp0 &= checkResult605if temp0 == true606player.jumpInTimer = 0607player.state = Player2_State_FlyToPlayer608player.xvel = 0609player.yvel = 0610player.speed = 0611player.tileCollisions = false612player.interaction = false613end if614end if615end function616617618public function Player2_ProcessUpdateP2619if player.state == Player_State_Death620player.stateInputP2 = Player2_Input_None621end if622623if player.state == Player_State_Drown624player.stateInputP2 = Player2_Input_None625end if626627CallFunction(player.stateInputP2)628629if player.state != Player_State_Hurt630if player.blinkTimer > 0631player.blinkTimer--632GetBit(temp0, player.blinkTimer, 2)633if temp0 == true634player.visible = false635else636player.visible = true637end if638end if639end if640641if player.invincibleTimer > 0642if player.state != Player_State_Hurt643if player.invincibleTimer > 2000644player.invincibleTimer = 120645player.blinkTimer = 3646end if647end if648649player.invincibleTimer--650if player.invincibleTimer == 0651player.blinkTimer = 0652player.visible = true653end if654end if655656if player.state != Player_State_LookUp657if player.state != Player_State_Crouch658// P2 is never a camera target so this doesn't matter much anyways, but may as well659660if player.lookPosY > 0661player.lookPosY -= 2662end if663664if player.lookPosY < 0665player.lookPosY += 2666end if667end if668end if669670if player.state != Player_State_Fly671if player.flightVelocity != 0672StopSfx(SfxName[Flying])673StopSfx(SfxName[Tired])674player.flightVelocity = 0675end if676end if677end function678679680// ========================681// Events682// ========================683684event ObjectUpdate685CallFunction(Player2_ProcessUpdateP2)686CallFunction(player.state)687ProcessAnimation()688CallFunction(TailsObject_ProcessTailSprite)689690if player.collisionDisabled == false691temp0 = player.prevGravity692player.prevGravity = player.gravity693ProcessObjectMovement()694player.prevGravity ^= GRAVITY_AIR695CheckEqual(player.gravity, GRAVITY_GROUND)696player.prevGravity |= checkResult697player.prevGravity ^= GRAVITY_AIR698if temp0 == GRAVITY_AIR699if player.prevGravity == GRAVITY_GROUND700player.badnikBonus = 0701if player.animation == ANI_JUMPING702if player.down == false703if player.state != Player_State_Roll704if player.state != Player_State_TubeRoll705player.animation = ANI_WALKING706player.iypos += player.jumpOffset707end if708end if709end if710end if711end if712end if713else714player.collisionDisabled = false715end if716717CallFunction(Player2_HandleSidekickRespawn)718end event719720721event ObjectDraw722if player.animation != player.prevAnimation723player.prevAnimation = player.animation724player.frame = 0725player.animationTimer = 0726player.animationSpeed = 0727end if728729if player.tailAnim != player.animation730if player.animation > 4 // worth noting that it uses the raw number directly rather than the ANI_* variables... (for ref - note that 4 is ANI_LOOKINGDOWN)731player.tailFrame = 0732end if733734if player.tailAnim > 4735player.tailFrame = 0736end if737738player.tailAnim = player.animation739end if740741// Draw the Tails part of Tails742switch player.tailAnim743case 0 // ANI_STOPPED744if player.frame == 0745temp0 = player.tailFrame746temp0 >>= 3747if player.visible == true748DrawSpriteFX(temp0, FX_FLIP, player.xpos, player.ypos)749end if750end if751break752753case 1 // ANI_WAITING754case 3 // ANI_LOOKINGUP755case 4 // ANI_LOOKINGDOWN756case 37 // ANI_CONTINUE_UP757temp0 = player.tailFrame758temp0 >>= 3759if player.visible == true760DrawSpriteFX(temp0, FX_FLIP, player.xpos, player.ypos)761end if762break763764case 7 // ANI_SKIDDING765case 9 // ANI_SPINDASH766temp0 = player.tailFrame767temp0 >>= 2768temp0 += 11769if player.visible == true770DrawSpriteFX(temp0, FX_FLIP, player.xpos, player.ypos)771end if772break773774case 10 // ANI_JUMPING775case 43 // Unknown, this was probably "SSRoll" before it got moved to its own ani file776temp0 = player.tailFrame777temp0 >>= 2778CheckEqual(player.xvel, 0)779temp1 = checkResult780CheckEqual(player.yvel, 0)781temp1 &= checkResult782temp2 = player.rotation783if temp1 == 0784ATan2(player.rotation, player.xvel, player.yvel)785player.rotation += 16786player.rotation &= 255787player.rotation >>= 5788switch player.rotation789case 0790case 8791temp0 += 5792player.rotation = 0x00793break794795case 1796temp0 += 8797if player.direction == FACING_RIGHT798player.rotation = 0x40799else800player.rotation = 0x00801end if802break803804case 2805temp0 += 5806player.rotation = 0x40807break808809case 3810temp0 += 8811if player.direction == FACING_RIGHT812player.rotation = 0x80813else814player.rotation = 0x40815end if816break817818case 4819temp0 += 5820player.rotation = 0x80821break822823case 5824temp0 += 8825if player.direction == FACING_RIGHT826player.rotation = 0xC0827else828player.rotation = 0x80829end if830break831832case 6833temp0 += 5834player.rotation = 0xC0835break836837case 7838temp0 += 8839if player.direction == FACING_RIGHT840player.rotation = 0x00841else842player.rotation = 0xC0843end if844break845end switch846847if player.direction == FACING_LEFT848player.rotation += 128849end if850else851temp0 += 5852player.rotation = 0x00853end if854855player.rotation <<= 1856if player.visible == true857DrawSpriteFX(temp0, FX_ROTATE, player.xpos, player.ypos)858end if859player.rotation = temp2860break861862case 17 // ANI_PUSHING863temp0 = player.tailFrame864temp0 /= 10865temp0 += 11866if player.visible == true867DrawSpriteFX(temp0, FX_FLIP, player.xpos, player.ypos)868end if869break870871end switch872873// Draw Tails himself874// (Separate tails are drawn in the process above)875DrawObjectAnimation()876end event877878879event ObjectStartup880Player2_nextLeaderPosID = 1881Player2_lastLeaderPosID = 0882Player2_stateUp = 0883Player2_stateDown = 0884Player2_stateLeft = 0885Player2_stateRight = 0886Player2_stateJumpPress = 0887Player2_stateJumpHold = 0888889if stage.player2Enabled == true890// Always make P2 start 16 pixels to the left of P1, regardless of if a P2 object is placed in the scene or not891// (It should never be anyway, but MZ1 does a few way OOB for some reason...)892ResetObjectEntity(SLOT_PLAYER2, TypeName[Player 2 Object], 1, player[SLOT_PLAYER1].xpos, player[SLOT_PLAYER1].ypos)893player[SLOT_PLAYER2].xpos -= 0x100000894895// We're using the ani for Tails's main sprites, and the Sprite Frames for his Tails896LoadSpriteSheet("Players/Tails1.gif")897LoadAnimation("Tails.ani")898899SpriteFrame(-22, -8, 16, 24, 82, 199)900SpriteFrame(-26, -8, 20, 24, 99, 199)901SpriteFrame(-26, -8, 20, 24, 120, 199)902SpriteFrame(-26, -8, 20, 24, 141, 199)903SpriteFrame(-26, -8, 20, 24, 162, 199)904SpriteFrame(-35, -8, 24, 16, 231, 166)905SpriteFrame(-35, -8, 24, 16, 231, 183)906SpriteFrame(-35, -8, 24, 16, 231, 200)907SpriteFrame(-25, 9, 20, 16, 235, 217)908SpriteFrame(-25, 9, 18, 16, 237, 234)909SpriteFrame(-25, 9, 20, 16, 216, 234)910SpriteFrame(-30, -6, 24, 16, 231, 166)911SpriteFrame(-30, -6, 24, 16, 231, 183)912SpriteFrame(-30, -6, 24, 16, 231, 200)913914player[SLOT_PLAYER2].groupID = GROUP_PLAYERS915player[SLOT_PLAYER2].character = CHARACTER_TAILS916#platform: USE_STANDALONE917player[SLOT_PLAYER2].state = Player_State_Air918#endplatform919#platform: USE_ORIGINS920player[SLOT_PLAYER2].state = Player_State_Air_NoDropDash921#endplatform922player[SLOT_PLAYER2].priority = PRIORITY_ACTIVE923#platform: USE_STANDALONE924player[SLOT_PLAYER2].controlMode = CONTROLMODE_P1925#endplatform926#platform: USE_ORIGINS927player[SLOT_PLAYER2].controlMode = CONTROLMODE_P2928#endplatform929player[SLOT_PLAYER2].drawOrder = DRAWORDER_PLAYER930player[SLOT_PLAYER2].sortedDrawOrder = 4931currentPlayer = SLOT_PLAYER2932CallFunction(Player_UpdatePhysicsState)933player[SLOT_PLAYER2].rollingDeceleration = 0x2000934player[SLOT_PLAYER2].jumpOffset = -1935player[SLOT_PLAYER2].isSidekick = true936player[SLOT_PLAYER2].jumpAbility = Player2_Action_DblJumpTailsAI937938if options.spindash == true939player[SLOT_PLAYER2].actionSpindash = Player_Action_Spindash940else941player[SLOT_PLAYER2].actionSpindash = Player_Action_Jump942end if943944CheckCurrentStageFolder("Continue")945if checkResult == true946player[SLOT_PLAYER2].stateInputP2 = Player2_Input_None947else948player[SLOT_PLAYER2].stateInputP2 = Player2_Input_AI_Follow949end if950951// Reset the position buffer table, fill it up with P1's starting position for now952temp0 = 0953while temp0 < 16954SetTableValue(player[SLOT_PLAYER1].xpos, temp0, Player2_leaderPosBufferX)955SetTableValue(player[SLOT_PLAYER1].ypos, temp0, Player2_leaderPosBufferY)956temp0++957loop958959// Set player hitboxes960player[SLOT_PLAYER2].hitboxLeft = C_BOX961player[SLOT_PLAYER2].hitboxRight = C_BOX962player[SLOT_PLAYER2].hitboxTop = C_BOX963player[SLOT_PLAYER2].hitboxBottom = C_BOX964965#platform: USE_ORIGINS966AssignInputSlotToDevice(2, -1)967#endplatform968end if969end event970971972// ========================973// Editor Events974// ========================975976event RSDKDraw977DrawSprite(0)978end event979980981event RSDKLoad982LoadSpriteSheet("Players/Tails1.gif")983SpriteFrame(-22, -8, 16, 24, 82, 199) // snip984985SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")986end event987988989