Path: blob/master/Sonic 1/Scripts/LZ/Water.txt
1480 views
// ----------------------------------1// RSDK Project: Sonic 12// Script Description: Water Object3// Script Author: Christian Whitehead/Simon Thomley4// Unpacked by Rubberduckycooly's script unpacker5// ----------------------------------67// Any water objects in the scene should be followed by THREE blank objects, these manage player stuff89// ========================10// Aliases11// ========================1213private alias object.value1 : object.constBubbleTimer14private alias object.value2 : object.randBubbleTimer15private alias object.value3 : object.proccessActEffects16private alias object.value8 : object.nextTrackID // Stores the track that should play after the drowning one stops1718// Player Aliases19private alias object.type : player.type20private alias object.state : player.state21private alias object.xpos : player.xpos22private alias object.ypos : player.ypos23private alias object.xvel : player.xvel24private alias object.yvel : player.yvel25private alias object.speed : player.speed26private alias object.gravity : player.gravity27private alias object.animation : player.animation28private alias object.direction : player.direction29private alias object.tileCollisions : player.tileCollisions30private alias object.interaction : player.interaction3132private alias object.value1 : player.timer33private alias object.value3 : player.drownTimer34private alias object.value4 : player.drownLevel35private alias object.value18 : player.sortedDrawOrder36private alias object.value20 : player.topSpeed37private alias object.value21 : player.acceleration38private alias object.value22 : player.deceleration39private alias object.value23 : player.airAcceleration40private alias object.value24 : player.airDeceleration41private alias object.value25 : player.gravityStrength42private alias object.value27 : player.jumpStrength43private alias object.value28 : player.jumpCap44private alias object.value37 : player.shield4546// AirBubble Aliases47private alias object.value1 : airBubble.originPos.x48private alias object.value2 : airBubble.targetPlayer4950// CountdownBubble Aliases51private alias object.value1 : countdownBubble.drawPos.x52private alias object.value2 : countdownBubble.drawPos.y5354// Death Event Aliases55private alias object.value4 : object.timeOver5657// Shields58private alias 0 : SHIELD_NONE59private alias 2 : SHIELD_BUBBLE60private alias 3 : SHIELD_FIRE61private alias 4 : SHIELD_LIGHTNING6263// Tracks64private alias 0 : TRACK_STAGE65private alias 2 : TRACK_INVINCIBLE66private alias 6 : TRACK_DROWNING6768// Super States69private alias 1 : SUPERSTATE_SUPER707172// ========================73// Function Declarations74// ========================7576reserve function Water_ProcessLZAct177reserve function Water_ProcessLZAct278reserve function Water_ProcessLZAct379reserve function Water_ProcessSBZAct380reserve function Water_SpawnSmallAirBubble81reserve function Water_SpawnCountDownBubble82reserve function Water_ResetDrownMusic838485// ========================86// Static Values87// ========================8889public value Water_waterSlotID = 090public value Water_activateFlag = 0919293// ========================94// Tables95// ========================9697private table Water_processActTable[5]9899100// ========================101// Function Definitions102// ========================103104private function Water_ProcessLZAct1105switch stage.waterState106case 0107stage.newWaterLevel = 0xB80000108if temp0 >= 1696109stage.newWaterLevel = 0x1080000110if temp1 < 512111if temp0 >= 3360112stage.newWaterLevel = 0xE80000113if temp0 >= 5536114stage.newWaterLevel = 0x1080000115end if116end if117else118if temp0 >= 3232119stage.newWaterLevel = 0x3180000120if temp0 >= 4384121stage.newWaterLevel = 0x5C80000122if temp0 >= 5152123stage.newWaterLevel = 0x3A80000124if object[arrayPos0].ypos == stage.newWaterLevel125stage.waterState = 1126end if127end if128end if129end if130end if131end if132break133134case 1135if temp1 < 736136stage.newWaterLevel = 0x3A80000137if temp0 >= 5024138stage.newWaterLevel = 0x1080000139stage.waterState = 2140end if141end if142break143144case 2145break146147end switch148end function149150151private function Water_ProcessLZAct2152stage.newWaterLevel = 0x3280000153if temp0 >= 1440154stage.newWaterLevel = 0x3C80000155if temp0 >= 2976156stage.newWaterLevel = 0x4280000157end if158end if159end function160161162private function Water_ProcessLZAct3163switch stage.waterState164case 0165stage.newWaterLevel = 0xA000000166object[arrayPos0].ypos = stage.newWaterLevel167if temp0 >= 1696168if temp1 >= 960169if temp1 < 1536170stage.waterState = 1171stage.newWaterLevel = 0x4C80000172object[arrayPos0].ypos = stage.newWaterLevel173PlaySfx(SfxName[Large Wall], false)174SetTileLayerEntry(302, 0, 12, 5)175SetTileLayerEntry(303, 0, 13, 5)176end if177end if178end if179break180181case 1182temp3 = 0x4C80000183if temp0 >= 2048184temp3 = 0x3080000185if temp0 >= 0x14A0186temp2 = false187if stage.newWaterLevel == 0x5080000188temp2 = true189else190if temp1 >= 1536191temp2 = true192else193if temp1 < 640194temp2 = true195end if196end if197end if198199if temp2 == true200temp3 = 0x5080000201object[arrayPos0].ypos = temp3202if temp0 >= 6160203stage.waterState = 2204end if205end if206end if207end if208stage.newWaterLevel = temp3209break210211case 2212stage.newWaterLevel = 0x5080000213if temp0 >= 6400214stage.newWaterLevel = 0x1880000215if temp0 < 7040216if object[arrayPos0].ypos == stage.newWaterLevel217stage.waterState = 3218end if219else220stage.waterState = 3221end if222end if223break224225case 3226stage.newWaterLevel = 0x1880000227object[arrayPos0].ypos = stage.newWaterLevel228229if temp1 > 1792230stage.newWaterLevel = 0xA000000231object[arrayPos0].ypos = stage.newWaterLevel232end if233234if temp1 < 160235stage.newWaterLevel = 0xA000000236object[arrayPos0].ypos = stage.newWaterLevel237end if238239if temp0 >= 7040240stage.newWaterLevel = 0xA000000241object[arrayPos0].ypos = stage.newWaterLevel242if temp0 >= 7264243stage.waterState = 4244stage.newWaterLevel = 0x6080000245object[arrayPos0].ypos = 0x7C00000246Water_activateFlag = true247end if248end if249break250251case 4252if temp0 >= 7840253stage.newWaterLevel = 0x1280000254end if255break256257end switch258end function259260261private function Water_ProcessSBZAct3262stage.newWaterLevel = 0x2280000263if temp0 >= 4000264stage.newWaterLevel = 0x4C80000265end if266end function267268269private function Water_SpawnSmallAirBubble270if object[+currentPlayer].constBubbleTimer > 0271object[+currentPlayer].constBubbleTimer--272273if object[+currentPlayer].randBubbleTimer > 0274object[+currentPlayer].randBubbleTimer--275else276CreateTempObject(TypeName[Air Bubble], 2, player[currentPlayer].xpos, player[currentPlayer].ypos)277object[tempObjectPos].drawOrder = 4278object[tempObjectPos].yvel = -0x8800279airBubble[tempObjectPos].targetPlayer = currentPlayer280if player[currentPlayer].direction == FLIP_NONE281object[tempObjectPos].xpos += 0x60000282else283object[tempObjectPos].xpos -= 0x60000284object[tempObjectPos].angle = 256285end if286airBubble[tempObjectPos].originPos.x = object[tempObjectPos].xpos287object[+currentPlayer].randBubbleTimer = 512288end if289else290Rand(temp0, 3)291if temp0 == 1292Rand(object[+currentPlayer].randBubbleTimer, 16)293object[+currentPlayer].randBubbleTimer += 8294else295object[+currentPlayer].randBubbleTimer = 512296end if297298object[+currentPlayer].constBubbleTimer = 60299CreateTempObject(TypeName[Air Bubble], 2, player[currentPlayer].xpos, player[currentPlayer].ypos)300object[tempObjectPos].drawOrder = 4301object[tempObjectPos].yvel = -0x8800302airBubble[tempObjectPos].targetPlayer = currentPlayer303if player[currentPlayer].direction == FLIP_NONE304object[tempObjectPos].xpos += 0x60000305else306object[tempObjectPos].xpos -= 0x60000307object[tempObjectPos].angle = 256308end if309310airBubble[tempObjectPos].originPos.x = object[tempObjectPos].xpos311end if312end function313314315private function Water_SpawnCountDownBubble316CreateTempObject(TypeName[Countdown Bubble], temp0, player[currentPlayer].xpos, player[currentPlayer].ypos)317object[tempObjectPos].drawOrder = 5318object[tempObjectPos].yvel = -0x8800319countdownBubble[tempObjectPos].drawPos.y = currentPlayer // this is odd... this is drawPos.y, not "targetPlayer", likely a leftover from AirBubble spawning320321if player[currentPlayer].direction == FLIP_NONE322object[tempObjectPos].xpos += 0x60000323else324object[tempObjectPos].xpos -= 0x60000325object[tempObjectPos].angle = 0x100326end if327328countdownBubble[tempObjectPos].drawPos.x = object[tempObjectPos].xpos329end function330331332private function Water_ResetDrownMusic333if currentPlayer == 0334arrayPos0 = Water_waterSlotID335arrayPos0 += currentPlayer336if player[currentPlayer].type != TypeName[Death Event]337if music.currentTrack == TRACK_DROWNING338if object[arrayPos0].nextTrackID == TRACK_INVINCIBLE339arrayPos1 = currentPlayer340arrayPos1 += playerCount341if object[arrayPos1].type != TypeName[Invincibility]342if Player_superState != SUPERSTATE_SUPER343object[arrayPos0].nextTrackID = TRACK_STAGE344end if345end if346end if347348PlayMusic(object[arrayPos0].nextTrackID)349end if350end if351end if352end function353354355// ========================356// Events357// ========================358359event ObjectUpdate360temp0 = player[0].xpos361temp0 >>= 16362temp1 = player[0].ypos363temp1 >>= 16364365arrayPos0 = object.entityPos366CallFunction(object.proccessActEffects)367368if object.ypos < stage.newWaterLevel369object.ypos += 0x10000370end if371if object.ypos > stage.newWaterLevel372object.ypos -= 0x10000373end if374375temp0 = oscillation376temp0 <<= 1377Sin(stage.waterLevel, temp0)378stage.waterLevel <<= 10379stage.waterLevel += object.ypos380temp7 = stage.waterLevel381stage.waterLevel >>= 16382383currentPlayer = 0384while currentPlayer < playerCount385#platform: USE_ORIGINS386if game.playMode == BOOT_PLAYMODE_MISSION387if stage.timeEnabled == false388if object[currentPlayer].type == TypeName[Player Object]389player[currentPlayer].drownTimer = 0390end if391392if object[currentPlayer].type == TypeName[Death Event]393object[currentPlayer].timeOver = 11 // this value is normally true/false.. why are we making it 11?394end if395end if396end if397#endplatform398399if player[currentPlayer].gravityStrength == 0x3800400CheckNotEqual(player[currentPlayer].type, TypeName[Debug Mode])401temp0 = checkResult402CheckNotEqual(player[currentPlayer].state, Player_State_Death)403temp0 &= checkResult404CheckGreater(player[currentPlayer].ypos, temp7)405temp0 &= checkResult406if temp0 == true407if player[currentPlayer].yvel > 0408player[currentPlayer].yvel >>= 2409end if410411if object.ypos < stage.newWaterLevel412player[currentPlayer].yvel += 0x10000413end if414415if player[currentPlayer].state == Player_State_Fly416StopSfx(SfxName[Flying])417StopSfx(SfxName[Jump])418end if419420player[currentPlayer].xvel >>= 1421player[currentPlayer].speed >>= 1422423CallFunction(Player_UpdatePhysicsState)424if player[currentPlayer].yvel != 0425CreateTempObject(TypeName[Water Splash], 0, player[currentPlayer].xpos, temp7)426object[tempObjectPos].drawOrder = 4427PlaySfx(SfxName[Water Splash], false)428end if429430object[+currentPlayer].constBubbleTimer = 52431player[currentPlayer].drownTimer = 0432end if433else434if player[currentPlayer].shield == SHIELD_FIRE435temp2 = 0436while temp2 < 8437Rand(temp0, 32)438Rand(temp1, 32)439temp0 -= 16440temp0 <<= 16441temp0 += player[currentPlayer].xpos442temp1 -= 16443temp1 <<= 16444temp1 += player[currentPlayer].ypos445CreateTempObject(TypeName[Dust Puff], 0, temp0, temp1)446object[tempObjectPos].drawOrder = player[currentPlayer].sortedDrawOrder447object[tempObjectPos].drawOrder++448object[tempObjectPos].xvel = player[currentPlayer].xvel449object[tempObjectPos].yvel = player[currentPlayer].yvel450temp2++451loop452453player[currentPlayer].shield = SHIELD_NONE454arrayPos0 = currentPlayer455arrayPos0 += playerCount456CallFunction(Player_ApplyShield)457end if458459if player[currentPlayer].shield == SHIELD_LIGHTNING460player[currentPlayer].shield = SHIELD_NONE461arrayPos0 = currentPlayer462arrayPos0 += playerCount463CallFunction(Player_ApplyShield)464Water_flashTimer = 4465end if466467if player[currentPlayer].shield != SHIELD_BUBBLE468if player[currentPlayer].drownTimer == 0469player[currentPlayer].drownLevel = 0470CallFunction(Water_ResetDrownMusic)471end if472473switch player[currentPlayer].drownLevel474case 0475CallFunction(Water_SpawnSmallAirBubble)476player[currentPlayer].drownTimer++477if player[currentPlayer].drownTimer == 360478if currentPlayer == 0479PlaySfx(SfxName[Drown Alert], false)480end if481player[currentPlayer].drownLevel++482end if483break484485case 1486CallFunction(Water_SpawnSmallAirBubble)487player[currentPlayer].drownTimer++488if player[currentPlayer].drownTimer == 660489if currentPlayer == 0490PlaySfx(SfxName[Drown Alert], false)491end if492player[currentPlayer].drownLevel++493end if494break495496case 2497CallFunction(Water_SpawnSmallAirBubble)498player[currentPlayer].drownTimer++499if player[currentPlayer].drownTimer == 960500if currentPlayer == 0501PlaySfx(SfxName[Drown Alert], false)502end if503player[currentPlayer].drownLevel++504end if505break506507case 3508CallFunction(Water_SpawnSmallAirBubble)509player[currentPlayer].drownTimer++510if player[currentPlayer].drownTimer == 1080511if currentPlayer == 0512object.nextTrackID = music.currentTrack513PlayMusic(TRACK_DROWNING)514end if515516temp0 = 0517CallFunction(Water_SpawnCountDownBubble)518player[currentPlayer].drownLevel++519end if520break521522case 4523CallFunction(Water_SpawnSmallAirBubble)524player[currentPlayer].drownTimer++525if player[currentPlayer].drownTimer == 1200526temp0 = 1527CallFunction(Water_SpawnCountDownBubble)528player[currentPlayer].drownLevel++529end if530break531532case 5533CallFunction(Water_SpawnSmallAirBubble)534player[currentPlayer].drownTimer++535if player[currentPlayer].drownTimer == 1320536temp0 = 2537CallFunction(Water_SpawnCountDownBubble)538player[currentPlayer].drownLevel++539end if540break541542case 6543CallFunction(Water_SpawnSmallAirBubble)544player[currentPlayer].drownTimer++545if player[currentPlayer].drownTimer == 1440546temp0 = 3547CallFunction(Water_SpawnCountDownBubble)548player[currentPlayer].drownLevel++549end if550break551552case 7553CallFunction(Water_SpawnSmallAirBubble)554player[currentPlayer].drownTimer++555if player[currentPlayer].drownTimer == 1560556temp0 = 4557CallFunction(Water_SpawnCountDownBubble)558player[currentPlayer].drownLevel++559end if560break561562case 8563CallFunction(Water_SpawnSmallAirBubble)564player[currentPlayer].drownTimer++565if player[currentPlayer].drownTimer == 1680566temp0 = 5567CallFunction(Water_SpawnCountDownBubble)568player[currentPlayer].drownLevel++569end if570break571572case 9573CallFunction(Water_SpawnSmallAirBubble)574player[currentPlayer].drownTimer++575if player[currentPlayer].drownTimer == 1800576if player[currentPlayer].state != Player_State_Death577if currentPlayer == 0578stage.timeEnabled = false579camera[0].enabled = false580end if581player[currentPlayer].state = Player_State_Drown582player[currentPlayer].animation = ANI_DROWNING583player[currentPlayer].speed = 0584player[currentPlayer].xvel = 0585player[currentPlayer].yvel = 0586player[currentPlayer].tileCollisions = false587player[currentPlayer].interaction = false588player[currentPlayer].sortedDrawOrder = 5589object[+currentPlayer].constBubbleTimer = 2590PlaySfx(SfxName[Drowning], false)591player[currentPlayer].drownLevel++592end if593end if594break595596case 10597player[currentPlayer].drownTimer++598if player[currentPlayer].drownTimer == 1860599player[currentPlayer].drownLevel++600end if601602if object[+currentPlayer].constBubbleTimer > 0603object[+currentPlayer].constBubbleTimer--604if object[+currentPlayer].randBubbleTimer > 0605object[+currentPlayer].randBubbleTimer--606else607Rand(temp1, 2)608temp1 += 2609CreateTempObject(TypeName[Air Bubble], temp1, player[currentPlayer].xpos, player[currentPlayer].ypos)610object[tempObjectPos].drawOrder = 5611object[tempObjectPos].yvel = -0x8800612object[tempObjectPos].ypos -= 0x60000613airBubble[tempObjectPos].targetPlayer = currentPlayer614Rand(object[tempObjectPos].angle, 256)615airBubble[tempObjectPos].originPos.x = object[tempObjectPos].xpos616object[+currentPlayer].randBubbleTimer = 512617end if618else619Rand(temp0, 5)620if temp0 == 1621object[+currentPlayer].randBubbleTimer = 2622else623object[+currentPlayer].randBubbleTimer = 512624end if625object[+currentPlayer].constBubbleTimer = 6626627Rand(temp1, 2)628temp1 += 2629CreateTempObject(TypeName[Air Bubble], temp1, player[currentPlayer].xpos, player[currentPlayer].ypos)630object[tempObjectPos].drawOrder = 5631object[tempObjectPos].yvel = -0x8800632object[tempObjectPos].ypos -= 0x60000633airBubble[tempObjectPos].targetPlayer = currentPlayer634Rand(object[tempObjectPos].angle, 0x100)635airBubble[tempObjectPos].originPos.x = object[tempObjectPos].xpos636end if637break638end switch639end if640641CheckEqual(player[currentPlayer].type, TypeName[Debug Mode])642temp0 = checkResult643CheckLower(player[currentPlayer].ypos, temp7)644temp0 |= checkResult645if temp0 == true646if player[currentPlayer].state != Player_State_Death647player[currentPlayer].yvel <<= 1648if player[currentPlayer].yvel < -0x100000649player[currentPlayer].yvel = -0x100000650end if651652// Fixes a bug where jumping at the surface of the water will set your velocity too high653// Interestingly, unlike S2 this fix IS in the Origins version of this game654if player[currentPlayer].animation == ANI_JUMPING655if player[currentPlayer].timer > 0656if player[currentPlayer].yvel < -0x68000657player[currentPlayer].yvel = -0x68000658end if659end if660end if661662if player[currentPlayer].state == Player_State_Fly663if player[currentPlayer].timer < 480664PlaySfx(SfxName[Flying], true)665else666PlaySfx(SfxName[Jump], true)667end if668end if669670671CallFunction(Player_UpdatePhysicsState)672if player[currentPlayer].yvel != 0673temp0 = object.ypos674temp0 -= player[currentPlayer].ypos675if temp0 < 0xF00000676CreateTempObject(TypeName[Water Splash], 0, player[currentPlayer].xpos, temp7)677object[tempObjectPos].drawOrder = 4678PlaySfx(SfxName[Water Splash], false)679end if680end if681682player[currentPlayer].drownTimer = 0683CallFunction(Water_ResetDrownMusic)684end if685end if686end if687currentPlayer++688loop689690object.animationTimer++691object.animationTimer %= 24692object.frame = object.animationTimer693object.frame >>= 3694end event695696697event ObjectDraw698temp0 = screen.xoffset699Sin(temp1, oscillation)700temp1 >>= 5701temp0 += temp1702temp0 &= 63703FlipSign(temp0)704705temp1 = stage.waterLevel706temp1 -= screen.yoffset707DrawSpriteScreenFX(object.frame, FX_INK, temp0, temp1)708709temp0 += 256710DrawSpriteScreenFX(object.frame, FX_INK, temp0, temp1)711end event712713714event ObjectStartup715LoadSpriteSheet("LZ/Objects2.gif")716717SetTableValue(Water_ProcessLZAct1, 1, Water_processActTable)718SetTableValue(Water_ProcessLZAct2, 2, Water_processActTable)719SetTableValue(Water_ProcessLZAct3, 3, Water_processActTable)720SetTableValue(Water_ProcessSBZAct3, 4, Water_processActTable)721722foreach (TypeName[Water], arrayPos0, ALL_ENTITIES)723object[arrayPos0].priority = PRIORITY_ACTIVE724object[arrayPos0].drawOrder = 5725object[arrayPos0].inkEffect = INK_ALPHA726object[arrayPos0].alpha = 0xA0727if credits.screen == 0728stage.newWaterLevel = object[arrayPos0].ypos729else730stage.waterState = 1731stage.newWaterLevel = 0x4C80000732temp0 = player[0].xpos733temp0 >>= 16734temp1 = player[0].ypos735temp1 >>= 16736end if737Water_waterSlotID = arrayPos0738GetTableValue(object[arrayPos0].proccessActEffects, stage.actNum, Water_processActTable)739CallFunction(object[arrayPos0].proccessActEffects)740stage.waterLevel = stage.newWaterLevel741stage.waterLevel >>= 16742object[arrayPos0].ypos = stage.newWaterLevel743next744745if lampPostID > 31746stage.waterState = recWaterState747stage.waterLevel = recWaterLevel748stage.newWaterLevel = recWaterLevel749stage.newWaterLevel <<= 16750arrayPos0 = Water_waterSlotID751object[arrayPos0].ypos = stage.newWaterLevel752else753if credits.screen == 0754stage.waterState = 0755end if756end if757758Water_activateFlag = false759760foreach (GROUP_PLAYERS, currentPlayer, ALL_ENTITIES)761player[currentPlayer].drownTimer = 0762if player[currentPlayer].ypos > stage.newWaterLevel763player[currentPlayer].yvel >>= 2764player[currentPlayer].xvel >>= 1765player[currentPlayer].speed >>= 1766player[currentPlayer].topSpeed >>= 1767player[currentPlayer].acceleration >>= 1768player[currentPlayer].deceleration >>= 1769player[currentPlayer].airAcceleration >>= 1770player[currentPlayer].airDeceleration >>= 1771player[currentPlayer].gravityStrength = 0x1000772if stage.playerListPos == PLAYER_KNUCKLES_A773player[currentPlayer].jumpStrength = 0x30000774else775player[currentPlayer].jumpStrength = 0x38000776end if777player[currentPlayer].jumpCap = -0x20000778arrayPos0 = Water_waterSlotID779arrayPos0 += currentPlayer780object[arrayPos0].constBubbleTimer = 52781end if782next783784SpriteFrame(0, -8, 256, 16, 0, 129)785SpriteFrame(0, -8, 256, 16, 0, 146)786SpriteFrame(0, -8, 256, 16, 0, 163)787788BrokenMonitor_ResetDrownMusic = Water_ResetDrownMusic789end event790791792// ========================793// Editor Events794// ========================795796event RSDKDraw797DrawSprite(0)798end event799800801event RSDKLoad802LoadSpriteSheet("LZ/Objects2.gif")803SpriteFrame(0, -8, 256, 16, 0, 129)804805SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")806end event807808809