Path: blob/master/Sonic 2/Scripts/Mission/Water.txt
1482 views
// ----------------------------------1// RSDK Project: Sonic 22// 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// This Object is used in Mission "Extreme! Tails Doggy Paddle Challenge" - M105 - DLC_Zone0210// It's a modified version of CPZ's Water object, but with all the moving water functionality taken out1112// ========================13// Aliases14// ========================1516private alias object.value1 : object.constBubbleTimer17private alias object.value2 : object.randBubbleTimer18private alias object.value3 : object.proccessActEffects // Not used19private alias object.value8 : object.nextTrackID // stores the track that should play after the drowning one stops2021// AirBubble Aliases22private alias object.value1 : airBubble.originPos.x23private alias object.value2 : airBubble.targetPlayer2425// CountdownBubble Aliases26private alias object.value1 : countdownBubble.drawPos.x27private alias object.value2 : countdownBubble.drawPos.y2829// Player Aliases30private alias object.type : player.type31private alias object.state : player.state32private alias object.xpos : player.xpos33private alias object.ypos : player.ypos34private alias object.xvel : player.xvel35private alias object.yvel : player.yvel36private alias object.speed : player.speed37private alias object.direction : player.direction38private alias object.gravity : player.gravity39private alias object.animation : player.animation40private alias object.interaction : player.interaction41private alias object.tileCollisions : player.tileCollisions42private alias object.value1 : player.timer43private alias object.value3 : player.drownTimer44private alias object.value4 : player.drownLevel45private alias object.value7 : player.invincibleTimer46private alias object.value18 : player.sortedDrawOrder47private alias object.value20 : player.topSpeed48private alias object.value21 : player.acceleration49private alias object.value22 : player.deceleration50private alias object.value23 : player.airAcceleration51private alias object.value24 : player.airDeceleration52private alias object.value25 : player.gravityStrength53private alias object.value27 : player.jumpStrength54private alias object.value28 : player.jumpCap55private alias object.value37 : player.shield5657private alias 1 : SUPERSTATE_SUPER5859// Shields60private alias 0 : SHIELD_NONE61private alias 2 : SHIELD_BUBBLE62private alias 3 : SHIELD_FIRE63private alias 4 : SHIELD_LIGHTNING6465// Tracks66private alias 0 : TRACK_STAGE67private alias 2 : TRACK_INVINCIBLE68private alias 6 : TRACK_DROWNING697071// ========================72// Function Declarations73// ========================7475reserve function Water_SpawnSmallAirBubble76reserve function Water_SpawnCountDownBubble77reserve function Water_ResetDrownMusic787980// ========================81// Static Values82// ========================8384private value Water_waterSlotID = 085private value Water_activateFlag = 0868788// ========================89// Function Definitions90// ========================9192private function Water_SpawnSmallAirBubble93if object[+currentPlayer].constBubbleTimer > 094object[+currentPlayer].constBubbleTimer--9596if object[+currentPlayer].randBubbleTimer > 097object[+currentPlayer].randBubbleTimer--98else99CreateTempObject(TypeName[Air Bubble], 2, player[currentPlayer].xpos, player[currentPlayer].ypos)100object[tempObjectPos].drawOrder = 4101object[tempObjectPos].yvel = -0x8800102airBubble[tempObjectPos].targetPlayer = currentPlayer103if player[currentPlayer].direction == FACING_RIGHT104object[tempObjectPos].xpos += 0x60000105else106object[tempObjectPos].xpos -= 0x60000107object[tempObjectPos].angle = 256108end if109airBubble[tempObjectPos].originPos.x = object[tempObjectPos].xpos110object[+currentPlayer].randBubbleTimer = 512111end if112else113Rand(temp0, 3)114if temp0 == 1115Rand(object[+currentPlayer].randBubbleTimer, 16)116object[+currentPlayer].randBubbleTimer += 8117else118object[+currentPlayer].randBubbleTimer = 512119end if120121object[+currentPlayer].constBubbleTimer = 60122CreateTempObject(TypeName[Air Bubble], 2, player[currentPlayer].xpos, player[currentPlayer].ypos)123object[tempObjectPos].drawOrder = 4124object[tempObjectPos].yvel = -0x8800125airBubble[tempObjectPos].targetPlayer = currentPlayer126if player[currentPlayer].direction == FACING_RIGHT127object[tempObjectPos].xpos += 0x60000128else129object[tempObjectPos].xpos -= 0x60000130object[tempObjectPos].angle = 256131end if132133airBubble[tempObjectPos].originPos.x = object[tempObjectPos].xpos134end if135end function136137138private function Water_SpawnCountDownBubble139CreateTempObject(TypeName[Countdown Bubble], temp0, player[currentPlayer].xpos, player[currentPlayer].ypos)140object[tempObjectPos].drawOrder = 5141object[tempObjectPos].yvel = -0x8800142countdownBubble[tempObjectPos].drawPos.y = currentPlayer // this is odd... this is drawPos.y, not "targetPlayer", likely a leftover from AirBubble spawning143if player[currentPlayer].direction == FACING_RIGHT144object[tempObjectPos].xpos += 0x60000145else146object[tempObjectPos].xpos -= 0x60000147object[tempObjectPos].angle = 256148end if149150countdownBubble[tempObjectPos].drawPos.x = object[tempObjectPos].xpos151end function152153154private function Water_ResetDrownMusic155if currentPlayer == 0156arrayPos0 = Water_waterSlotID157arrayPos0 += currentPlayer158if player[currentPlayer].type != TypeName[Death Event]159if music.currentTrack == TRACK_DROWNING160if object[arrayPos0].nextTrackID == TRACK_INVINCIBLE161arrayPos1 = currentPlayer162arrayPos1 += playerCount163if object[arrayPos1].type != TypeName[Invincibility]164if Player_superState != SUPERSTATE_SUPER165object[arrayPos0].nextTrackID = TRACK_STAGE166end if167end if168end if169170PlayMusic(object[arrayPos0].nextTrackID)171end if172end if173end if174end function175176177// ========================178// Events179// ========================180181event ObjectUpdate182temp0 = player[0].xpos183temp0 >>= 16184temp1 = player[0].ypos185temp1 >>= 16186187arrayPos0 = object.entityPos188189if object.ypos < stage.newWaterLevel190object.ypos += 0x10000191end if192if object.ypos > stage.newWaterLevel193object.ypos -= 0x10000194end if195196temp0 = oscillation197temp0 <<= 1198Sin(stage.waterLevel, temp0)199stage.waterLevel <<= 10200stage.waterLevel += object.ypos201temp7 = stage.waterLevel202stage.waterLevel >>= 16203204currentPlayer = 0205while currentPlayer < playerCount206if player[currentPlayer].gravityStrength == 0x3800207CheckNotEqual(player[currentPlayer].type, TypeName[Debug Mode])208temp0 = checkResult209CheckNotEqual(player[currentPlayer].state, Player_State_Death)210temp0 &= checkResult211CheckNotEqual(player[currentPlayer].state, Player_State_Static)212temp0 &= checkResult213CheckGreater(player[currentPlayer].ypos, temp7)214temp0 &= checkResult215if temp0 == true216if player[currentPlayer].yvel > 0217player[currentPlayer].yvel >>= 2218end if219220if object.ypos < stage.newWaterLevel221player[currentPlayer].yvel += 0x10000222end if223224if player[currentPlayer].state == Player_State_Fly225StopSfx(SfxName[Flying])226StopSfx(SfxName[Jump])227end if228229player[currentPlayer].xvel >>= 1230player[currentPlayer].speed >>= 1231232CallFunction(Player_UpdatePhysicsState)233if currentPlayer == 0234CPZSetup_enteredWater = true235end if236237if player[currentPlayer].yvel != 0238CreateTempObject(TypeName[Water Splash], 0, player[currentPlayer].xpos, temp7)239object[tempObjectPos].drawOrder = 4240player[currentPlayer].sortedDrawOrder = 4241PlaySfx(SfxName[Water Splash], false)242end if243244object[+currentPlayer].constBubbleTimer = 52245player[currentPlayer].drownTimer = 0246end if247else248if player[currentPlayer].invincibleTimer == 0249if player[currentPlayer].shield == SHIELD_FIRE250temp2 = 0251while temp2 < 8252Rand(temp0, 32)253Rand(temp1, 32)254temp0 -= 16255temp0 <<= 16256temp0 += player[currentPlayer].xpos257temp1 -= 16258temp1 <<= 16259temp1 += player[currentPlayer].ypos260CreateTempObject(TypeName[Dust Puff], 0, temp0, temp1)261object[tempObjectPos].drawOrder = player[currentPlayer].sortedDrawOrder262object[tempObjectPos].drawOrder++263object[tempObjectPos].xvel = player[currentPlayer].xvel264object[tempObjectPos].yvel = player[currentPlayer].yvel265temp2++266loop267268player[currentPlayer].shield = SHIELD_NONE269arrayPos0 = currentPlayer270arrayPos0 += playerCount271CallFunction(Player_ApplyShield)272end if273274// Player hit the water with a lightning shield - take their shield and electrocute the water275if player[currentPlayer].shield == SHIELD_LIGHTNING276player[currentPlayer].shield = SHIELD_NONE277arrayPos0 = currentPlayer278arrayPos0 += playerCount279CallFunction(Player_ApplyShield)280Water_flashTimer = 4281end if282end if283284if player[currentPlayer].shield != SHIELD_BUBBLE285if player[currentPlayer].drownTimer == 0286player[currentPlayer].drownLevel = 0287CallFunction(Water_ResetDrownMusic)288end if289290switch player[currentPlayer].drownLevel291case 0292CallFunction(Water_SpawnSmallAirBubble)293player[currentPlayer].drownTimer++294if player[currentPlayer].drownTimer == 360295if currentPlayer == 0296PlaySfx(SfxName[Drown Alert], false)297end if298player[currentPlayer].drownLevel++299end if300break301302case 1303CallFunction(Water_SpawnSmallAirBubble)304player[currentPlayer].drownTimer++305if player[currentPlayer].drownTimer == 660306if currentPlayer == 0307PlaySfx(SfxName[Drown Alert], false)308end if309player[currentPlayer].drownLevel++310end if311break312313case 2314CallFunction(Water_SpawnSmallAirBubble)315player[currentPlayer].drownTimer++316if player[currentPlayer].drownTimer == 960317if currentPlayer == 0318PlaySfx(SfxName[Drown Alert], false)319end if320player[currentPlayer].drownLevel++321end if322break323324case 3325CallFunction(Water_SpawnSmallAirBubble)326player[currentPlayer].drownTimer++327if player[currentPlayer].drownTimer == 1080328if currentPlayer == 0329object.nextTrackID = music.currentTrack330PlayMusic(TRACK_DROWNING)331end if332333temp0 = 0334CallFunction(Water_SpawnCountDownBubble)335player[currentPlayer].drownLevel++336end if337break338339case 4340CallFunction(Water_SpawnSmallAirBubble)341player[currentPlayer].drownTimer++342if player[currentPlayer].drownTimer == 1200343temp0 = 1344CallFunction(Water_SpawnCountDownBubble)345player[currentPlayer].drownLevel++346end if347break348349case 5350CallFunction(Water_SpawnSmallAirBubble)351player[currentPlayer].drownTimer++352if player[currentPlayer].drownTimer == 1320353temp0 = 2354CallFunction(Water_SpawnCountDownBubble)355player[currentPlayer].drownLevel++356end if357break358359case 6360CallFunction(Water_SpawnSmallAirBubble)361player[currentPlayer].drownTimer++362if player[currentPlayer].drownTimer == 1440363temp0 = 3364CallFunction(Water_SpawnCountDownBubble)365player[currentPlayer].drownLevel++366end if367break368369case 7370CallFunction(Water_SpawnSmallAirBubble)371player[currentPlayer].drownTimer++372if player[currentPlayer].drownTimer == 1560373temp0 = 4374CallFunction(Water_SpawnCountDownBubble)375player[currentPlayer].drownLevel++376end if377break378379case 8380CallFunction(Water_SpawnSmallAirBubble)381player[currentPlayer].drownTimer++382if player[currentPlayer].drownTimer == 1680383temp0 = 5384CallFunction(Water_SpawnCountDownBubble)385player[currentPlayer].drownLevel++386end if387break388389case 9390CallFunction(Water_SpawnSmallAirBubble)391player[currentPlayer].drownTimer++392if player[currentPlayer].drownTimer == 1800393if player[currentPlayer].state != Player_State_Death394if currentPlayer == 0395stage.timeEnabled = false396camera[0].enabled = false397end if398player[currentPlayer].state = Player_State_Drown399player[currentPlayer].animation = ANI_DROWNING400player[currentPlayer].speed = 0401player[currentPlayer].xvel = 0402player[currentPlayer].yvel = 0403player[currentPlayer].tileCollisions = false404player[currentPlayer].interaction = false405player[currentPlayer].sortedDrawOrder = 5406object[+currentPlayer].constBubbleTimer = 2407PlaySfx(SfxName[Drowning], false)408player[currentPlayer].drownLevel++409end if410end if411break412413case 10414player[currentPlayer].drownTimer++415if player[currentPlayer].drownTimer == 1860416player[currentPlayer].drownLevel++417end if418419if object[+currentPlayer].constBubbleTimer > 0420object[+currentPlayer].constBubbleTimer--421if object[+currentPlayer].randBubbleTimer > 0422object[+currentPlayer].randBubbleTimer--423else424Rand(temp1, 2)425temp1 += 2426CreateTempObject(TypeName[Air Bubble], temp1, player[currentPlayer].xpos, player[currentPlayer].ypos)427object[tempObjectPos].drawOrder = 5428object[tempObjectPos].yvel = -0x8800429object[tempObjectPos].ypos -= 0x60000430airBubble[tempObjectPos].targetPlayer = currentPlayer431Rand(object[tempObjectPos].angle, 256)432airBubble[tempObjectPos].originPos.x = object[tempObjectPos].xpos433object[+currentPlayer].randBubbleTimer = 512434end if435else436Rand(temp0, 5)437if temp0 == 1438object[+currentPlayer].randBubbleTimer = 2439else440object[+currentPlayer].randBubbleTimer = 512441end if442object[+currentPlayer].constBubbleTimer = 6443444Rand(temp1, 2)445temp1 += 2446CreateTempObject(TypeName[Air Bubble], temp1, player[currentPlayer].xpos, player[currentPlayer].ypos)447object[tempObjectPos].drawOrder = 5448object[tempObjectPos].yvel = -0x8800449object[tempObjectPos].ypos -= 0x60000450airBubble[tempObjectPos].targetPlayer = currentPlayer451Rand(object[tempObjectPos].angle, 0x100)452airBubble[tempObjectPos].originPos.x = object[tempObjectPos].xpos453end if454break455end switch456end if457458CheckEqual(player[currentPlayer].type, TypeName[Debug Mode])459temp0 = checkResult460CheckLower(player[currentPlayer].ypos, temp7)461temp0 |= checkResult462if temp0 == true463if player[currentPlayer].state != Player_State_Death464player[currentPlayer].yvel <<= 1465if player[currentPlayer].yvel < -0x100000466player[currentPlayer].yvel = -0x100000467end if468469// (Normally the hi-jump water bug fix would be here, but Origins doesn't have it so)470471if player[currentPlayer].state == Player_State_Fly472if player[currentPlayer].timer < 480473PlaySfx(SfxName[Flying], true)474else475PlaySfx(SfxName[Jump], true)476end if477end if478479480CallFunction(Player_UpdatePhysicsState)481if player[currentPlayer].yvel != 0482temp0 = object.ypos483temp0 -= player[currentPlayer].ypos484if temp0 < 0xF00000485CreateTempObject(TypeName[Water Splash], 0, player[currentPlayer].xpos, temp7)486object[tempObjectPos].drawOrder = 4487player[currentPlayer].sortedDrawOrder = 4488PlaySfx(SfxName[Water Splash], false)489end if490end if491492player[currentPlayer].drownTimer = 0493CallFunction(Water_ResetDrownMusic)494end if495end if496end if497498currentPlayer++499loop500501object.animationTimer++502object.animationTimer &= 31503object.frame = object.animationTimer504object.frame >>= 3505end event506507508event ObjectDraw509temp0 = screen.xoffset510Sin(temp1, oscillation)511temp1 >>= 5512temp0 += temp1513temp0 &= 63514FlipSign(temp0)515516temp1 = stage.waterLevel517temp1 -= screen.yoffset518DrawSpriteScreenFX(object.frame, FX_INK, temp0, temp1)519520temp0 += 256521DrawSpriteScreenFX(object.frame, FX_INK, temp0, temp1)522end event523524525event ObjectStartup526if options.vsMode == true527foreach (TypeName[Water], arrayPos0, ALL_ENTITIES)528object[arrayPos0].type = TypeName[Blank Object]529next530end if531532foreach (TypeName[Water], arrayPos0, ALL_ENTITIES)533object[arrayPos0].priority = PRIORITY_ACTIVE534object[arrayPos0].drawOrder = 5535object[arrayPos0].inkEffect = INK_ALPHA536object[arrayPos0].alpha = 0xA0537538// Huh? In-game credits?539// This is just a leftover from the S1 LZ Water script, where Water would be specially set up for the credits demo540// In this game there's no such thing though, this never really hits541if credits.screen == 0542stage.newWaterLevel = object[arrayPos0].ypos543else544stage.waterState = 1545stage.newWaterLevel = 0x4C80000546temp0 = player[0].xpos547temp0 >>= 16548temp1 = player[0].ypos549temp1 >>= 16550end if551Water_waterSlotID = arrayPos0552stage.newWaterLevel = object[arrayPos0].ypos // While the original CPZ Water script would call object.proccessActEffects here, the Mission Water script just sticks with where the Water obj is placed in the scene553stage.waterLevel = stage.newWaterLevel554stage.waterLevel >>= 16555556if starPostID >= 32557stage.waterState = recWaterState558stage.waterLevel = recWaterLevel559stage.newWaterLevel = recWaterLevel560stage.newWaterLevel <<= 16561arrayPos0 = Water_waterSlotID562object[arrayPos0].ypos = stage.newWaterLevel563else564if credits.screen == 0565stage.waterState = 0566end if567end if568next569570Water_activateFlag = false571572foreach (GROUP_PLAYERS, currentPlayer, ALL_ENTITIES)573player[currentPlayer].drownTimer = 0574if player[currentPlayer].ypos > stage.newWaterLevel575player[currentPlayer].yvel >>= 2576player[currentPlayer].xvel >>= 1577player[currentPlayer].speed >>= 1578player[currentPlayer].topSpeed >>= 1579player[currentPlayer].acceleration >>= 1580player[currentPlayer].deceleration >>= 1581player[currentPlayer].airAcceleration >>= 1582player[currentPlayer].airDeceleration >>= 1583player[currentPlayer].gravityStrength = 0x1000584if stage.playerListPos == PLAYER_KNUCKLES_A585player[currentPlayer].jumpStrength = 0x30000586else587player[currentPlayer].jumpStrength = 0x38000588end if589player[currentPlayer].jumpCap = -0x20000590arrayPos0 = Water_waterSlotID591arrayPos0 += currentPlayer592object[arrayPos0].constBubbleTimer = 52593end if594next595596LoadSpriteSheet("CPZ/Objects2.gif")597SpriteFrame(0, -8, 256, 16, 0, 0)598SpriteFrame(0, -8, 256, 16, 0, 16)599SpriteFrame(0, -8, 256, 16, 0, 32)600SpriteFrame(0, -8, 256, 16, 0, 48)601602BrokenMonitor_ResetDrownMusic = Water_ResetDrownMusic603end event604605606// ========================607// Editor Events608// ========================609610event RSDKDraw611DrawSprite(0)612end event613614615event RSDKLoad616LoadSpriteSheet("CPZ/Objects2.gif")617SpriteFrame(0, -8, 256, 16, 0, 0)618619SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")620end event621622623