Path: blob/master/Sonic 2/Scripts/Enemies/Rexon.txt
1480 views
// ----------------------------------1// RSDK Project: Sonic 22// Script Description: Rexon Object3// Script Author: Christian Whitehead/Simon Thomley4// Unpacked by Rubberduckycooly's script unpacker5// ----------------------------------67// ========================8// Aliases9// ========================1011private alias object.value0 : object.timer1213private alias object.value1 : object.head.magnitude14private alias object.value2 : object.head.amplitude15private alias object.value3 : object.head.x16private alias object.value4 : object.head.y1718// Piece order is desending in height (IE piece 1 is right next to the head, piece 4 is right next to the shell)1920private alias object.value5 : object.piece1.magnitude21private alias object.value6 : object.piece1.amplitude22private alias object.value7 : object.piece1.x23private alias object.value8 : object.piece1.y2425private alias object.value9 : object.piece2.magnitude26private alias object.value10 : object.piece2.amplitude27private alias object.value11 : object.piece2.x28private alias object.value12 : object.piece2.y2930private alias object.value13 : object.piece3.magnitude31private alias object.value14 : object.piece3.amplitude32private alias object.value15 : object.piece3.x33private alias object.value16 : object.piece3.y3435private alias object.value17 : object.piece4.magnitude36private alias object.value18 : object.piece4.amplitude37private alias object.value19 : object.piece4.x38private alias object.value20 : object.piece4.y3940private alias object.value21 : object.head.direction41private alias object.value22 : object.piece1.direction42private alias object.value23 : object.piece2.direction43private alias object.value24 : object.piece3.direction4445private alias object.value25 : object.startPos.x4647// Fragment alias, holds the entityPos of the Rexon it originated from48private alias object.value0 : object.parentRexon4950private alias 0 : REXON_AWAITPLAYER51private alias 1 : REXON_RISE152private alias 2 : REXON_RISE253private alias 3 : REXON_RISE354private alias 4 : REXON_RISE455private alias 5 : REXON_RISE556private alias 6 : REXON_SHOOT57private alias 7 : REXON_SHELL58private alias 8 : REXON_FRAGMENT5960// Player Aliases61private alias object.xpos : player.xpos6263private alias object.value40 : player.hitboxLeft64private alias object.value38 : player.hitboxTop65private alias object.value41 : player.hitboxRight66private alias object.value39 : player.hitboxBottom676869// ========================70// Function Declarations71// ========================7273reserve function Rexon_Reset74reserve function Rexon_DebugDraw75reserve function Rexon_DebugSpawn767778// ========================79// Function Definitions80// ========================8182private function Rexon_Reset83temp0 = object[arrayPos0].startPos.x84temp1 = object[arrayPos0].ypos85ResetObjectEntity(object[arrayPos0].entityPos, TypeName[Rexon], 0, temp0, temp1)86object[arrayPos0].startPos.x = temp087object[arrayPos0].xvel = -0x200088object[arrayPos0].timer = 12889object[arrayPos0].head.amplitude = 36890object[arrayPos0].piece1.amplitude = 36891object[arrayPos0].piece2.amplitude = 36892object[arrayPos0].piece3.amplitude = 36893object[arrayPos0].piece4.amplitude = 36894end function959697private function Rexon_DebugDraw98DrawSpriteFX(3, FX_FLIP, object.xpos, object.ypos)99end function100101102private function Rexon_DebugSpawn103CreateTempObject(TypeName[Rexon], 0, object.xpos, object.ypos)104object[tempObjectPos].startPos.x = object.xpos105arrayPos0 = object[tempObjectPos].entityPos106107CallFunction(Rexon_Reset)108end function109110111// ========================112// Events113// ========================114115event ObjectUpdate116switch object.state117case REXON_AWAITPLAYER118// Swimming around, waiting for the player119object.priority = PRIORITY_ACTIVE120121object.xpos += object.xvel122object.timer--123if object.timer == 0124object.timer = 128125object.direction ^= FLIP_X126FlipSign(object.xvel)127end if128129// Check if the player's in range130foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)131if object.direction == FLIP_NONE132BoxCollisionTest(C_TOUCH, object.entityPos, -160, -256, 96, 256, currentPlayer, -1, -1, 1, 1)133else134BoxCollisionTest(C_TOUCH, object.entityPos, -96, -256, 160, 256, currentPlayer, -1, -1, 1, 1)135end if136137if checkResult == true138if player[currentPlayer].xpos > object.xpos139object.direction = FLIP_X140else141object.direction = FLIP_NONE142end if143object.state++144end if145next146break147148case REXON_RISE1149if object.head.magnitude >= 3200150object.state++151object.head.magnitude = 3200152end if153154object.head.magnitude += 640155break156157case REXON_RISE2158if object.piece1.magnitude >= 3200159object.state++160object.piece1.magnitude = 3200161end if162163object.piece1.magnitude += 640164object.head.amplitude += 2165break166167case REXON_RISE3168if object.piece2.magnitude >= 3200169object.state++170object.piece2.magnitude = 3200171end if172173object.piece2.magnitude += 640174object.head.amplitude += 2175object.piece1.amplitude += 2176break177178case REXON_RISE4179if object.piece3.magnitude >= 3200180object.state++181object.piece3.magnitude = 3200182end if183184object.piece3.magnitude += 640185object.head.amplitude += 2186object.piece1.amplitude += 2187object.piece2.amplitude += 2188break189190case REXON_RISE5191if object.piece4.magnitude >= 2688192object.state++193object.piece4.magnitude = 2688194end if195196object.piece4.magnitude += 640197object.head.amplitude += 2198object.piece1.amplitude += 2199object.piece2.amplitude += 2200object.piece3.amplitude += 2201break202203case REXON_SHOOT204if object.head.direction == FLIP_NONE205object.head.amplitude++206if object.head.amplitude == 384207object.frame = 0 // Close the Rexon's mouth208end if209210if object.head.amplitude >= 416211object.head.direction = FLIP_X212end if213else214object.head.amplitude--215if object.head.amplitude == 368216object.frame = 1 // Make the Rexon open wide217end if218219if object.head.amplitude <= 352220object.head.direction = FLIP_NONE221CreateTempObject(TypeName[Rexon Shot], 0, object.head.x, object.head.y)222if object.direction == FLIP_NONE223object[tempObjectPos].xvel = -0x10000224object[tempObjectPos].xpos -= 0x100000225else226object[tempObjectPos].xvel = 0x10000227object[tempObjectPos].xpos += 0x100000228end if229object[tempObjectPos].yvel = 0x8000230object[tempObjectPos].ypos += 0x40000231end if232end if233234if object.piece1.direction == FLIP_NONE235object.piece1.amplitude++236if object.piece1.amplitude >= 416237object.piece1.direction = FLIP_X238end if239else240object.piece1.amplitude--241if object.piece1.amplitude <= 352242object.piece1.direction = FLIP_NONE243end if244end if245246if object.piece2.direction == FLIP_NONE247object.piece2.amplitude++248if object.piece2.amplitude >= 416249object.piece2.direction = FLIP_X250end if251else252object.piece2.amplitude--253if object.piece2.amplitude <= 352254object.piece2.direction = FLIP_NONE255end if256end if257258if object.piece3.direction == FLIP_NONE259object.piece3.amplitude++260if object.piece3.amplitude >= 416261object.piece3.direction = FLIP_X262end if263else264object.piece3.amplitude--265if object.piece3.amplitude <= 352266object.piece3.direction = FLIP_NONE267end if268end if269break270271case REXON_SHELL272// Just a lone shell, don't do anything273break274275case REXON_FRAGMENT276arrayPos0 = object.parentRexon277if object[arrayPos0].state != REXON_SHELL278// If the Rexon isn't actually defeated, then despawn279object.type = TypeName[Blank Object]280end if281282object.xpos += object.xvel283object.ypos += object.yvel284object.yvel += 0x3800285286if object.outOfBounds == true287object.type = TypeName[Blank Object]288end if289break290291end switch292293// Calculate the positions of all body fragments in this (rather lengthy) process294295temp0 = object.xpos296if object.direction == FLIP_NONE297temp0 -= 0x1C0000298else299temp0 += 0x1C0000300end if301302temp1 = object.ypos303temp1 += 0x110000304305temp2 = object.piece4.amplitude306temp2 >>= 1307if object.direction == FLIP_X308temp2 -= 0xC0309FlipSign(temp2)310temp2 += 0xC0311temp2 &= 0xFF312end if313Cos256(object.piece4.x, temp2)314object.piece4.x *= object.piece4.magnitude315object.piece4.x += temp0316Sin256(object.piece4.y, temp2)317object.piece4.y *= object.piece4.magnitude318object.piece4.y += temp1319320temp2 = object.piece3.amplitude321temp2 >>= 1322if object.direction == FLIP_X323temp2 -= 0xC0324FlipSign(temp2)325temp2 += 0xC0326temp2 &= 0xFF327end if328Cos256(object.piece3.x, temp2)329object.piece3.x *= object.piece3.magnitude330object.piece3.x += object.piece4.x331Sin256(object.piece3.y, temp2)332object.piece3.y *= object.piece3.magnitude333object.piece3.y += object.piece4.y334335temp2 = object.piece2.amplitude336temp2 >>= 1337if object.direction == FLIP_X338temp2 -= 0xC0339FlipSign(temp2)340temp2 += 0xC0341temp2 &= 0xFF342end if343Cos256(object.piece2.x, temp2)344object.piece2.x *= object.piece2.magnitude345object.piece2.x += object.piece3.x346Sin256(object.piece2.y, temp2)347object.piece2.y *= object.piece2.magnitude348object.piece2.y += object.piece3.y349350temp2 = object.piece1.amplitude351temp2 >>= 1352if object.direction == FLIP_X353temp2 -= 0xC0354FlipSign(temp2)355temp2 += 0xC0356temp2 &= 0xFF357end if358Cos256(object.piece1.x, temp2)359object.piece1.x *= object.piece1.magnitude360object.piece1.x += object.piece2.x361Sin256(object.piece1.y, temp2)362object.piece1.y *= object.piece1.magnitude363object.piece1.y += object.piece2.y364365temp2 = object.head.amplitude366temp2 >>= 1367if object.direction == FLIP_X368temp2 -= 0xC0369FlipSign(temp2)370temp2 += 0xC0371temp2 &= 0xFF372end if373Cos256(object.head.x, temp2)374object.head.x *= object.head.magnitude375object.head.x += object.piece1.x376Sin256(object.head.y, temp2)377object.head.y *= object.head.magnitude378object.head.y += object.piece1.y379380if object.state != REXON_FRAGMENT381if object.outOfBounds == true382temp0 = object.xpos383object.xpos = object.startPos.x384if object.outOfBounds == true385arrayPos0 = object.entityPos386CallFunction(Rexon_Reset)387else388object.xpos = temp0389end if390end if391392temp6 = object.xpos393temp7 = object.ypos394foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)395// Provide a shell box for players to stand on396BoxCollisionTest(C_SOLID, object.entityPos, -16, -8, 16, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)397if object.state != REXON_SHELL398// Check if the head's been hit399object.xpos = object.head.x400object.ypos = object.head.y401BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)402if checkResult == true403// Create neck fragment pieces to make the Rexon fall apart404CreateTempObject(TypeName[Rexon], 0, object.piece1.x, object.piece1.y)405object[tempObjectPos].xvel = -0x8000406object[tempObjectPos].state = REXON_FRAGMENT407object[tempObjectPos].direction = object.direction408object[tempObjectPos].parentRexon = object.entityPos409410CreateTempObject(TypeName[Rexon], 0, object.piece2.x, object.piece2.y)411object[tempObjectPos].xvel = 0x10000412object[tempObjectPos].state = REXON_FRAGMENT413object[tempObjectPos].direction = object.direction414object[tempObjectPos].parentRexon = object.entityPos415416CreateTempObject(TypeName[Rexon], 0, object.piece3.x, object.piece3.y)417object[tempObjectPos].xvel = -0x10000418object[tempObjectPos].state = REXON_FRAGMENT419object[tempObjectPos].direction = object.direction420object[tempObjectPos].parentRexon = object.entityPos421422CreateTempObject(TypeName[Rexon], 0, object.piece4.x, object.piece4.y)423object[tempObjectPos].xvel = 0x8000424object[tempObjectPos].state = REXON_FRAGMENT425object[tempObjectPos].direction = object.direction426object[tempObjectPos].parentRexon = object.entityPos427428temp4 = object.startPos.x429temp5 = object.direction430CallFunction(Player_BadnikBreak)431if object.type != TypeName[Rexon]432// If the Rexon has been destroyed, turn it back into a Rexon so that its shell platform stays433object.type = TypeName[Rexon]434object.startPos.x = temp4435object.direction = temp5436object.priority = PRIORITY_ACTIVE437object.state = REXON_SHELL438end if439end if440441// Check hitboxes for all body parts individually, too442object.xpos = object.piece1.x443object.ypos = object.piece1.y444BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)445if checkResult == true446CallFunction(Player_Hit)447end if448449object.xpos = object.piece2.x450object.ypos = object.piece2.y451BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)452if checkResult == true453CallFunction(Player_Hit)454end if455456object.xpos = object.piece3.x457object.ypos = object.piece3.y458BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)459if checkResult == true460CallFunction(Player_Hit)461end if462463object.xpos = object.piece4.x464object.ypos = object.piece4.y465BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)466if checkResult == true467CallFunction(Player_Hit)468end if469end if470next471472object.xpos = temp6473object.ypos = temp7474end if475end event476477478event ObjectDraw479switch object.state480case REXON_RISE1481case REXON_RISE2482case REXON_RISE3483case REXON_RISE4484case REXON_RISE5485case REXON_SHOOT486DrawSpriteFX(2, FX_FLIP, object.piece4.x, object.piece4.y)487DrawSpriteFX(2, FX_FLIP, object.piece3.x, object.piece3.y)488DrawSpriteFX(2, FX_FLIP, object.piece2.x, object.piece2.y)489DrawSpriteFX(2, FX_FLIP, object.piece1.x, object.piece1.y)490DrawSpriteFX(object.frame, FX_FLIP, object.head.x, object.head.y)491// [Fallthrough to shell drawing]492case REXON_AWAITPLAYER493case REXON_SHELL494DrawSpriteFX(3, FX_FLIP, object.xpos, object.ypos)495break496497case REXON_FRAGMENT498DrawSpriteFX(2, FX_FLIP, object.xpos, object.ypos)499break500501end switch502end event503504505event ObjectStartup506CheckCurrentStageFolder("Zone05")507if checkResult == true508LoadSpriteSheet("HTZ/Objects.gif")509510// Head Frame, Mouth Closed511SpriteFrame(-19, -6, 23, 16, 143, 123)512513// Head Frame, Mouth Open514SpriteFrame(-19, -6, 23, 16, 45, 55)515516// Neck Frame517SpriteFrame(-8, -8, 16, 16, 52, 38)518519// Body Frame520SpriteFrame(-16, -8, 32, 16, 91, 105)521else522LoadSpriteSheet("MBZ/Objects.gif")523524// Duplicate data of HTZ sheet data, appears broken in-game525526// Head Frame, Mouth Closed527SpriteFrame(-19, -6, 23, 16, 143, 123)528529// Head Frame, Mouth Open530SpriteFrame(-19, -6, 23, 16, 45, 55)531532// Neck Frame533SpriteFrame(-8, -8, 16, 16, 52, 38)534535// Body Frame536SpriteFrame(-16, -8, 32, 16, 91, 105)537end if538539foreach (TypeName[Rexon], arrayPos0, ALL_ENTITIES)540object[arrayPos0].startPos.x = object[arrayPos0].xpos541CallFunction(Rexon_Reset)542next543544SetTableValue(TypeName[Rexon], DebugMode_ObjCount, DebugMode_TypesTable)545SetTableValue(Rexon_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)546SetTableValue(Rexon_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)547DebugMode_ObjCount++548end event549550551// ========================552// Editor Events553// ========================554555event RSDKDraw556object.head.amplitude = 368557object.head.magnitude = 3200558559object.piece1.amplitude = 368560object.piece1.magnitude = 3200561562object.piece2.amplitude = 368563object.piece2.magnitude = 3200564565object.piece3.amplitude = 368566object.piece3.magnitude = 3200567568object.piece4.amplitude = 368569object.piece4.magnitude = 3200570571temp0 = object.xpos572temp0 -= 0x1C0000573574temp1 = object.ypos575temp1 += 0x110000576577temp2 = object.piece4.amplitude578temp2 >>= 1579Cos256(object.piece4.x, temp2)580object.piece4.x *= object.piece4.magnitude581object.piece4.x += temp0582Sin256(object.piece4.y, temp2)583object.piece4.y *= object.piece4.magnitude584object.piece4.y += temp1585586temp2 = object.piece3.amplitude587temp2 >>= 1588Cos256(object.piece3.x, temp2)589object.piece3.x *= object.piece3.magnitude590object.piece3.x += object.piece4.x591Sin256(object.piece3.y, temp2)592object.piece3.y *= object.piece3.magnitude593object.piece3.y += object.piece4.y594595temp2 = object.piece2.amplitude596temp2 >>= 1597Cos256(object.piece2.x, temp2)598object.piece2.x *= object.piece2.magnitude599object.piece2.x += object.piece3.x600Sin256(object.piece2.y, temp2)601object.piece2.y *= object.piece2.magnitude602object.piece2.y += object.piece3.y603604temp2 = object.piece1.amplitude605temp2 >>= 1606Cos256(object.piece1.x, temp2)607object.piece1.x *= object.piece1.magnitude608object.piece1.x += object.piece2.x609Sin256(object.piece1.y, temp2)610object.piece1.y *= object.piece1.magnitude611object.piece1.y += object.piece2.y612613temp2 = object.head.amplitude614temp2 >>= 1615Cos256(object.head.x, temp2)616object.head.x *= object.head.magnitude617object.head.x += object.piece1.x618Sin256(object.head.y, temp2)619object.head.y *= object.head.magnitude620object.head.y += object.piece1.y621622DrawSpriteXY(1, object.piece4.x, object.piece4.y)623DrawSpriteXY(1, object.piece3.x, object.piece3.y)624DrawSpriteXY(1, object.piece2.x, object.piece2.y)625DrawSpriteXY(1, object.piece1.x, object.piece1.y)626DrawSpriteXY(0, object.head.x, object.head.y)627DrawSpriteXY(2, object.xpos, object.ypos)628end event629630631event RSDKLoad632CheckCurrentStageFolder("Zone05")633if checkResult == true634LoadSpriteSheet("HTZ/Objects.gif")635SpriteFrame(-19, -6, 23, 16, 143, 123)636SpriteFrame(-8, -8, 16, 16, 52, 38)637SpriteFrame(-16, -8, 32, 16, 91, 105)638else639LoadSpriteSheet("MBZ/Objects.gif")640SpriteFrame(-19, -6, 23, 16, 143, 123)641SpriteFrame(-8, -8, 16, 16, 52, 38)642SpriteFrame(-16, -8, 32, 16, 91, 105)643end if644645// Ported Rexons have it set, but new ones don't646// While it probably meant something in the original game, in this game it doesn't do anything647SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")648end event649650651