Path: blob/master/Sonic 2/Scripts/WFZ/Tornado.txt
1483 views
// ----------------------------------1// RSDK Project: Sonic 22// Script Description: Tornado Object3// Script Author: Christian Whitehead/Simon Thomley4// Unpacked by Rubberduckycooly's script unpacker5// ----------------------------------67// ========================8// Aliases9// ========================1011private alias object.value0 : object.timer12private alias object.value1 : object.duration13private alias object.value2 : object.stood14private alias object.value3 : object.lastPos.y15private alias object.value4 : object.collisionOffset.y16private alias object.value5 : object.pilotFrame17private alias object.value6 : object.pilotFrameDelay18private alias object.value7 : object.pilotAnimPos19private alias object.value8 : object.velocityTablePos20private alias object.value9 : object.boosterActive21private alias object.value10 : object.jumpAbilityFunc2223// States24private alias 0 : TORNADO_SETUPINTRO25private alias 1 : TORNADO_FLYINTRO26private alias 2 : TORNADO_SHOTDOWN27private alias 3 : TORNADO_FALLING28private alias 4 : TORNADO_SETUPOUTRO29private alias 5 : TORNADO_WAITFORPLAYER30private alias 6 : TORNADO_MOVEPLAYERTOEDGE31private alias 7 : TORNADO_JUMPONTOTORNADO32private alias 8 : TORNADO_LANDONTORNADO33private alias 9 : TORNADO_CHASESEQUENCE34private alias 10 : TORNADO_FINISHACT3536// Player Aliases37private alias object.type : player.type38private alias object.state : player.state39private alias object.xpos : player.xpos40private alias object.ypos : player.ypos41private alias object.xvel : player.xvel42private alias object.yvel : player.yvel43private alias object.speed : player.speed44private alias object.gravity : player.gravity45private alias object.controlMode : player.controlMode46private alias object.scrollTracking : player.scrollTracking4748private alias object.jumpPress : player.jumpPress49private alias object.jumpHold : player.jumpHold50private alias object.up : player.up51private alias object.down : player.down52private alias object.left : player.left53private alias object.right : player.right5455private alias object.value0 : player.rings56private alias object.value1 : player.timer57private alias object.value9 : player.skidSpeed58private alias object.value20 : player.topSpeed59private alias object.value21 : player.acceleration60private alias object.value22 : player.deceleration61private alias object.value23 : player.airAcceleration62private alias object.value24 : player.airDeceleration63private alias object.value25 : player.gravityStrength // Also used in underwater checks, 0x1000 if underwater, otherwise 0x3800. Not to be confused with player.gravity64private alias object.value27 : player.jumpStrength65private alias object.value28 : player.jumpCap66private alias object.value29 : player.rollingFriction // Active rolling deceleration - With the player holding the opposite direction67private alias object.value32 : player.jumpAbility // Used to store whatever function this player has for its jump ability68private alias object.value35 : player.jumpAbilityState6970// WFZEggmanThruster Aliases71private alias object.value0 : wfzEggmanThruster.interval7273// Super States74private alias 2 : SUPERSTATE_FADEOUT7576// Game Modes77private alias 0 : MODE_NOSAVE78private alias 1 : MODE_SAVEGAME79private alias 2 : MODE_TIMEATTACK808182// ========================83// Function Declarations84// ========================8586reserve function Tornado_Explode878889// ========================90// Tables91// ========================9293private table Tornado_TailsPilotFrameTable945, 32956, 8967, 8978, 8987, 8996, 161009, 321016, 16102end table103104private table Tornado_SonicPilotFrameTable10510, 910611, 910710, 910811, 910910, 911011, 911110, 911211, 9113end table114115private table Tornado_velocityDurationTable116520117640118712119744120808121968122104812311601241224125144812665535127end table128129private table Tornado_moveVelocityTable130-0x10000, -0x100001310x10000, 0x000001320x00000, 0x100001330x10000, -0x100001340x10000, 0x100001350x10000, -0x10000136-0x10000, 0x10000137-0x10000, -0x10000138-0x10000, 0x10000139-0x20000, 0x000001400x00000, 0x00000141end table142143144// ========================145// Function Definitions146// ========================147148// Called to create explosions after the Tornado gets shot149// Poor Tails...150private function Tornado_Explode151if object.duration == 0152object.duration = 15153temp0 = object.xpos154Rand(temp1, 8)155temp1 <<= 18156temp0 -= temp1157temp1 = object.ypos158temp1 += 0x100000159CreateTempObject(TypeName[T Explosion], 0, temp0, temp1)160else161object.duration--162end if163end function164165166// ========================167// Events168// ========================169170event ObjectUpdate171object.lastPos.y = object.ypos172object.drawOrder = 4173174// States TORNADO_SETUPINTRO -> TORNADO_FALLING are for the stage's intro175// States after that are for the chase cutscene when Tails helps you hitch a ride on Robotnik's ship176177switch object.state178case TORNADO_SETUPINTRO179temp0 = player[0].xpos180temp0 -= 0x100000181if object.xpos < temp0182object.type = TypeName[Blank Object]183else184if stage.playerListPos == PLAYER_TAILS_A185// Main player is Tails, shift him down a bit to account for his shorter height186player[0].ypos += 0x40000187end if188object.state++189end if190break191192case TORNADO_FLYINTRO193// Just flying straight for a brief moment194object.xpos += object.xvel195196object.timer--197if object.timer == 0198object.yvel = 0x10000199object.timer = 96200object.state = TORNADO_SHOTDOWN201else202temp0 = object.xpos203temp0 -= 0x100000204if player[0].xpos < temp0205player[0].xpos = temp0206end if207208temp0 += 0x200000209if player[0].xpos > temp0210player[0].xpos = temp0211end if212end if213break214215case TORNADO_SHOTDOWN216// Tornado getting shot217object.xpos += object.xvel218object.ypos += object.yvel219220temp0 = oscillation221temp0 &= 0x1F222if temp0 == 0223PlaySfx(SfxName[Laser Skim], false)224end if225226object.timer--227if object.timer == 0228object.xvel = 0x20000229object.yvel = 0x20000230object.timer = 96231object.state = TORNADO_FALLING232end if233CallFunction(Tornado_Explode)234break235236case TORNADO_FALLING237// Tornado after being shot, it's just falling now...238object.xpos += object.xvel239object.ypos += object.yvel240if object.outOfBounds == true241// Despawn it when out of view242object.type = TypeName[Blank Object]243end if244CallFunction(Tornado_Explode)245break246247case TORNADO_SETUPOUTRO248// Start of end-of-level cutscene, start removing control from the player,249BoxCollisionTest(C_TOUCH, object.entityPos, -640, -192, 0, 0, 0, C_BOX, C_BOX, C_BOX, C_BOX)250if checkResult == true251if player[0].gravity == GRAVITY_GROUND252player[0].controlMode = CONTROLMODE_NONE253player[0].jumpPress = false254player[0].jumpHold = false255player[0].up = false256player[0].down = false257player[0].left = false258player[0].right = false259Player_superState = SUPERSTATE_FADEOUT260object.state = TORNADO_WAITFORPLAYER261end if262end if263break264265case TORNADO_WAITFORPLAYER266if player[0].state == Player_State_Ground267player[0].timer = 0268end if269270object.timer++271if object.timer >= 120272object.timer = 0273object.state = TORNADO_MOVEPLAYERTOEDGE274end if275break276277case TORNADO_MOVEPLAYERTOEDGE278player[0].right = true279280temp0 = object.xpos281temp0 -= 0x100000282if player[0].xpos >= temp0283player[0].xpos = temp0284player[0].xvel = 0285player[0].speed = 0286player[0].right = 0287object.xvel = 0x10000288object.yvel = -0x10000289object.state = TORNADO_JUMPONTOTORNADO290end if291break292293case TORNADO_JUMPONTOTORNADO294object.xpos += object.xvel295object.ypos += object.yvel296297object.timer++298if object.timer == 72299player[0].jumpPress = true300player[0].jumpHold = true301player[0].right = true302object.jumpAbilityFunc = player[0].jumpAbility303304// Reset the physics values to match Sonic's, even Knux' jump height is ignored here so that the cutscene doesn't desync305player[0].jumpAbility = Player_State_Static306player[0].gravityStrength = 0x3800307player[0].topSpeed = 0x60000308player[0].acceleration = 0xC00309player[0].deceleration = 0xC00310player[0].airAcceleration = 0x1800311player[0].airDeceleration = 0x600312player[0].skidSpeed = 0x8000313player[0].rollingFriction = 0x600314player[0].jumpStrength = 0x68000315player[0].jumpCap = -0x40000316317object.state = TORNADO_LANDONTORNADO318end if319break320321case TORNADO_LANDONTORNADO322object.xpos += object.xvel323object.ypos += object.yvel324object.timer++325#platform: USE_ORIGINS326// Added in Origins Plus, make sure Sonic or Amy don't Drop Dash to their deaths327// This is a global variable, which is why we aren't specifying the object position328player.dropdashCount0 = 0329#endplatform330BoxCollisionTest(C_PLATFORM, object.entityPos, -20, -8, 20, 8, 0, C_BOX, C_BOX, C_BOX, C_BOX)331if checkResult == true332player[0].jumpPress = false333player[0].jumpHold = false334player[0].xvel = 0335player[0].speed = 0336player[0].right = false337player[0].jumpAbility = object.jumpAbilityFunc338GetTableValue(object.duration, object.velocityTablePos, Tornado_velocityDurationTable)339object.velocityTablePos++340object.state = TORNADO_CHASESEQUENCE341end if342break343344case TORNADO_CHASESEQUENCE345if object.timer < 1160346tileLayer[1].scrollSpeed -= 256347if tileLayer[1].scrollSpeed < -0x60000348tileLayer[1].scrollSpeed = -0x60000349end if350else351if object.timer > 2048352tileLayer[1].scrollSpeed += 0x600353if tileLayer[1].scrollSpeed > 0354tileLayer[1].scrollSpeed = 0355end if356357tileLayer[3].scrollSpeed += 0x4E0358if tileLayer[3].scrollSpeed > 0359tileLayer[3].scrollSpeed = 0360if stage.activeLayer[1] != 2361stage.activeLayer[1] = 2 // Show Death Egg Dock BG362stage.activeLayer[3] = 2 // Show Death Egg Dock BG363tileLayer[2].scrollPos = 0364tileLayer[2].scrollSpeed = 0365hParallax[4].scrollPos = 0366hParallax[4].scrollSpeed = 0x20000367end if368end if369end if370end if371player[0].timer = 0372373object.timer++374if object.timer >= object.duration375temp0 = object.velocityTablePos376temp0 <<= 1377GetTableValue(object.xvel, temp0, Tornado_moveVelocityTable)378temp0++379GetTableValue(object.yvel, temp0, Tornado_moveVelocityTable)380GetTableValue(object.duration, object.velocityTablePos, Tornado_velocityDurationTable)381object.velocityTablePos++382end if383384// "Checkpoints" or "keyframes" of sorts are used here, to mark whenever a change should happen385// Any value not listed here just does nothing386switch object.timer387case 296388object.boosterActive = true389hParallax[0].scrollSpeed <<= 1390hParallax[1].scrollSpeed <<= 1391hParallax[2].scrollSpeed <<= 1392hParallax[3].scrollSpeed <<= 1393break394395case 1148396player[0].jumpPress = true397player[0].jumpHold = true398break399400case 1149401player[0].jumpPress = false402break403404case 1160405wfzEggmanThruster[+4].interval = 1406wfzEggmanThruster[+5].interval = 1407wfzEggmanThruster[+6].interval = 1408hParallax[0].scrollSpeed <<= 2409hParallax[1].scrollSpeed <<= 2410hParallax[2].scrollSpeed <<= 2411hParallax[3].scrollSpeed <<= 2412player[0].gravity = GRAVITY_GROUND413player[0].scrollTracking = false414tileLayer[1].scrollSpeed = -0x80000415tileLayer[3].scrollSpeed = -0x80000416break417418case 2200419stage.activeLayer[0] = 3 // Show the Sky & Space BG420tileLayer[3].scrollPos = 0x2490000421tileLayer[3].scrollSpeed = tileLayer[1].scrollSpeed422break423424case 2624425object.timer = 0426object.state = TORNADO_FINISHACT427break428429end switch430431object.xpos += object.xvel432object.ypos += object.yvel433break434435case TORNADO_FINISHACT436// This stage doesn't have an [Act Finish] object so this object takes its place437music.volume -= 2438object.timer += 4439SetScreenFade(0x00, 0x00, 0x00, object.timer)440if object.timer == 384441StopMusic()442fadeColor = 0443object.timer = 0444starPostID = 0445object.direction = FACING_RIGHT // this doesn't really matter much446447#platform: USE_ORIGINS448if game.playMode == BOOT_PLAYMODE_BOSSRUSH449CallNativeFunction2(NotifyCallback, NOTIFY_BOSS_END, 1) // the [Eggman Laser] object already does this, so the Tornado never really gets a chance to do it450LoadStage()451else452#endplatform453stage.listPos++454455// Huh?456// If the stage we're going to is after HPZ, then go back to OOZ1?457// if you really wanna, ig...458if stage.listPos > 20459stage.listPos = 12460end if461462if options.gameMode == MODE_SAVEGAME463arrayPos1 = options.saveSlot464arrayPos1 <<= 3465if stage.player2Enabled == true466#platform: USE_STANDALONE467saveRAM[arrayPos1] = 3468#endplatform469#platform: USE_ORIGINS470switch stage.playerListPos471case PLAYER_SONIC_A472saveRAM[arrayPos1] = PLAYER_SONIC_TAILS473break474475case PLAYER_KNUCKLES_A476saveRAM[arrayPos1] = PLAYER_KNUCKLES_TAILS477break478479case PLAYER_AMY_A480saveRAM[arrayPos1] = PLAYER_AMY_TAILS481break482end switch483#endplatform484else485saveRAM[arrayPos1] = stage.playerListPos486end if487arrayPos1++488489saveRAM[arrayPos1] = player.lives490arrayPos1++491492saveRAM[arrayPos1] = player.score493arrayPos1++494495saveRAM[arrayPos1] = player.scoreBonus496arrayPos1++497498// Bug Details:499// This is missing the check for if your save file is already past the next act500// This means the save file's act will be overwritten to Death Egg Zone, even if you're on a Complete save file...501saveRAM[arrayPos1] = stage.listPos502saveRAM[arrayPos1]++503arrayPos1++504505saveRAM[arrayPos1] = specialStage.emeralds506arrayPos1++507508saveRAM[arrayPos1] = specialStage.listPos509WriteSaveRAM()510end if511512if options.gameMode == MODE_TIMEATTACK513timeAttack.result = stage.seconds514timeAttack.result *= 100515temp0 = stage.minutes516temp0 *= 6000517timeAttack.result += temp0518timeAttack.result += stage.milliSeconds519stage.listPos--520CallNativeFunction2(SetLeaderboard, stage.listPos, timeAttack.result)521engine.state = 8522else523temp0 = engine.trialMode524if stage.listPos >= stage.listSize525temp0 = true526end if527528if temp0 == false529#platform: USE_ORIGINS530CallNativeFunction4(NotifyCallback, NOTIFY_STATS_ENEMY, StageStatsUsabilityParam1, StageStatsUsabilityParam2, StageStatsUsabilityParam3)531CallNativeFunction2(NotifyCallback, NOTIFY_STATS_RING, player[0].rings)532temp0 = StageStatsUsabilityParam5533temp0 &= 1534temp1 = StageStatsUsabilityParam5535temp1 &= 2536temp2 = StageStatsUsabilityParam5537temp2 &= 4538CallNativeFunction4(NotifyCallback, NOTIFY_STATS_CHARA_ACTION, temp0, temp1, temp2)539CallNativeFunction2(NotifyCallback, NOTIFY_ACT_FINISH, 0)540StageStatsUsabilityParam1 = 0541StageStatsUsabilityParam2 = 0542StageStatsUsabilityParam3 = 0543StageStatsUsabilityParam4 = 0544StageStatsUsabilityParam5 = 0545StatsUsabilityParam1 = 0546StatsUsabilityParam2 = 0547StatsUsabilityParam3 = 0548StatsUsabilityParam4 = 0549StatsUsabilityParam5 = 0550#endplatform551552LoadStage()553else554stage.activeList = PRESENTATION_STAGE555stage.listPos = 0556LoadStage()557end if558end if559#platform: USE_ORIGINS560end if561#endplatform562end if563break564end switch565566temp0 = object.ypos567568object.lastPos.y &= 0xFFFF0000569object.collisionOffset.y = object.ypos570object.collisionOffset.y &= 0xFFFF0000571object.collisionOffset.y -= object.lastPos.y572object.ypos = object.lastPos.y573574object.stood = false575foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)576temp2 = player[currentPlayer].yvel577BoxCollisionTest(C_PLATFORM, object.entityPos, -20, -8, 20, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)578if checkResult == true579player[currentPlayer].xpos += object.xvel580player[currentPlayer].ypos += object.yvel581object.stood |= true582end if583next584object.ypos = temp0585586object.frame++587object.frame &= 3588589if object.pilotFrameDelay < 2590if stage.playerListPos == PLAYER_TAILS_A591GetTableValue(object.pilotFrame, object.pilotAnimPos, Tornado_SonicPilotFrameTable)592object.pilotAnimPos++593594GetTableValue(object.pilotFrameDelay, object.pilotAnimPos, Tornado_SonicPilotFrameTable)595object.pilotAnimPos++596else597GetTableValue(object.pilotFrame, object.pilotAnimPos, Tornado_TailsPilotFrameTable)598object.pilotAnimPos++599600GetTableValue(object.pilotFrameDelay, object.pilotAnimPos, Tornado_TailsPilotFrameTable)601object.pilotAnimPos++602end if603604object.pilotAnimPos &= 15605else606object.pilotFrameDelay--607end if608end event609610611event ObjectDraw612DrawSprite(object.frame)613DrawSprite(4)614DrawSprite(object.pilotFrame)615616if object.state >= TORNADO_JUMPONTOTORNADO617DrawSprite(12)618619if object.boosterActive == true620temp0 = oscillation621temp0 &= 1622temp0 += 13623DrawSprite(temp0)624end if625end if626end event627628629event ObjectStartup630LoadSpriteSheet("SCZ/Objects.gif")631SpriteFrame(21, 8, 4, 24, 378, 215) // Propeller - Frame 1 - #0632SpriteFrame(21, 11, 4, 18, 383, 218) // Propeller - Frame 2 - #1633SpriteFrame(21, 16, 4, 8, 388, 223) // Propeller - Frame 3 - #2634SpriteFrame(21, 11, 4, 18, 393, 218) // Propeller - Frame 4 - #3635SpriteFrame(-95, -16, 116, 64, 261, 191) // Tornado - #4636SpriteFrame(-45, -8, 21, 16, 261, 174) // Pilot (Tails) - Frame 1 - #5637SpriteFrame(-45, -8, 21, 16, 283, 174) // Pilot (Tails) - Frame 2 - #6638SpriteFrame(-45, -8, 21, 16, 305, 174) // Pilot (Tails) - Frame 3 - #7639SpriteFrame(-45, -8, 21, 16, 327, 174) // Pilot (Tails) - Frame 4 - #8640SpriteFrame(-47, -8, 23, 16, 349, 174) // Pilot (Tails) - Frame 5 - #9641SpriteFrame(-50, -8, 24, 16, 294, 157) // Pilot (Sonic) - Frame 6 - #10642SpriteFrame(-50, -8, 24, 16, 319, 157) // Pilot (Sonic) - Frame 2 - #11643SpriteFrame(-39, 32, 56, 16, 375, 90) // Booster - #12644SpriteFrame(-55, 32, 16, 16, 386, 107) // Booster Flame - Frame 1 - #13645SpriteFrame(-71, 32, 32, 16, 386, 124) // Booster Flame - Frame 2 - #14646647if playerCount > 1 // Remove P2648player[1].type = TypeName[Blank Object]649playerCount = 1650end if651652foreach (TypeName[Tornado], arrayPos0, ALL_ENTITIES)653object[arrayPos0].priority = PRIORITY_ACTIVE654if object[arrayPos0].propertyValue == 0655object[arrayPos0].xvel = 0x10000656object[arrayPos0].timer = 192657else658if options.gameMode == MODE_TIMEATTACK659ResetObjectEntity(arrayPos0, TypeName[Blank Object], 0, 0, 0)660else661object[arrayPos0].state = TORNADO_SETUPOUTRO662end if663end if664next665end event666667668// ========================669// Editor Events670// ========================671672event RSDKEdit673if editor.returnVariable == true674switch editor.variableID675case EDIT_VAR_PROPVAL // property value676checkResult = object.propertyValue677break678679case 0 // type680checkResult = object.propertyValue681break682683end switch684else685switch editor.variableID686case EDIT_VAR_PROPVAL // property value687object.propertyValue = editor.variableValue688break689690case 0 // type691object.propertyValue = editor.variableValue692break693694end switch695end if696end event697698699event RSDKDraw700DrawSprite(0)701DrawSprite(1)702DrawSprite(2)703end event704705706event RSDKLoad707LoadSpriteSheet("SCZ/Objects.gif")708SpriteFrame(21, 8, 4, 24, 378, 215)709SpriteFrame(-95, -16, 116, 64, 261, 191)710SpriteFrame(-45, -8, 21, 16, 283, 174)711712AddEditorVariable("type")713SetActiveVariable("type")714AddEnumVariable("Intro Cutscene", 0)715AddEnumVariable("Outro Cutscene", 1)716end event717718719