Path: blob/master/Sonic 2/Scripts/HPZ/Water.txt
1480 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// ========================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.direction : player.direction27private alias object.gravity : player.gravity28private alias object.animation : player.animation29private alias object.interaction : player.interaction30private alias object.tileCollisions : player.tileCollisions3132private alias object.value1 : player.timer33private alias object.value3 : player.drownTimer34private alias object.value4 : player.drownLevel35private alias object.value7 : player.invincibleTimer36private alias object.value18 : player.sortedDrawOrder37private alias object.value20 : player.topSpeed38private alias object.value21 : player.acceleration39private alias object.value22 : player.deceleration40private alias object.value23 : player.airAcceleration41private alias object.value24 : player.airDeceleration42private alias object.value25 : player.gravityStrength43private alias object.value27 : player.jumpStrength44private alias object.value28 : player.jumpCap45private alias object.value37 : player.shield4647// Super States48private alias 1 : SUPERSTATE_SUPER4950// AirBubble Aliases51private alias object.value1 : airBubble.originPos.x52private alias object.value2 : airBubble.targetPlayer5354// CountdownBubble Aliases55private alias object.value1 : countdownBubble.drawPos.x56private alias object.value2 : countdownBubble.drawPos.y5758// Shields59private alias 0 : SHIELD_NONE60private alias 2 : SHIELD_BUBBLE61private alias 3 : SHIELD_FIRE62private alias 4 : SHIELD_LIGHTNING6364// Tracks65private alias 0 : TRACK_STAGE66private alias 2 : TRACK_INVINCIBLE67private alias 6 : TRACK_DROWNING686970// ========================71// Function Declarations72// ========================7374reserve function Water_SpawnSmallAirBubble75reserve function Water_SpawnCountDownBubble76reserve function Water_ResetDrownMusic777879// ========================80// Static Values81// ========================8283private value Water_waterSlotID = 084private value Water_activateFlag = 0858687// ========================88// Function Definitions89// ========================9091private function Water_SpawnSmallAirBubble92if object[+currentPlayer].constBubbleTimer > 093object[+currentPlayer].constBubbleTimer--9495if object[+currentPlayer].randBubbleTimer > 096object[+currentPlayer].randBubbleTimer--97else98CreateTempObject(TypeName[Air Bubble], 2, player[currentPlayer].xpos, player[currentPlayer].ypos)99object[tempObjectPos].drawOrder = 4100object[tempObjectPos].yvel = -0x8800101airBubble[tempObjectPos].targetPlayer = currentPlayer102if player[currentPlayer].direction == FLIP_NONE103object[tempObjectPos].xpos += 0x60000104else105object[tempObjectPos].xpos -= 0x60000106object[tempObjectPos].angle = 256107end if108airBubble[tempObjectPos].originPos.x = object[tempObjectPos].xpos109object[+currentPlayer].randBubbleTimer = 512110end if111else112Rand(temp0, 3)113if temp0 == 1114Rand(object[+currentPlayer].randBubbleTimer, 16)115object[+currentPlayer].randBubbleTimer += 8116else117object[+currentPlayer].randBubbleTimer = 512118end if119120object[+currentPlayer].constBubbleTimer = 60121CreateTempObject(TypeName[Air Bubble], 2, player[currentPlayer].xpos, player[currentPlayer].ypos)122object[tempObjectPos].drawOrder = 4123object[tempObjectPos].yvel = -0x8800124airBubble[tempObjectPos].targetPlayer = currentPlayer125if player[currentPlayer].direction == FLIP_NONE126object[tempObjectPos].xpos += 0x60000127else128object[tempObjectPos].xpos -= 0x60000129object[tempObjectPos].angle = 256130end if131132airBubble[tempObjectPos].originPos.x = object[tempObjectPos].xpos133end if134end function135136137private function Water_SpawnCountDownBubble138CreateTempObject(TypeName[Countdown Bubble], temp0, player[currentPlayer].xpos, player[currentPlayer].ypos)139object[tempObjectPos].drawOrder = 5140object[tempObjectPos].yvel = -0x8800141countdownBubble[tempObjectPos].drawPos.y = currentPlayer // this is odd... this is drawPos.y, not "targetPlayer", likely a leftover from AirBubble spawning142if player[currentPlayer].direction == FLIP_NONE143object[tempObjectPos].xpos += 0x60000144else145object[tempObjectPos].xpos -= 0x60000146object[tempObjectPos].angle = 256147end if148149countdownBubble[tempObjectPos].drawPos.x = object[tempObjectPos].xpos150end function151152153private function Water_ResetDrownMusic154if currentPlayer == 0155arrayPos0 = Water_waterSlotID156arrayPos0 += currentPlayer157if player[currentPlayer].type != TypeName[Death Event]158if music.currentTrack == TRACK_DROWNING159if object[arrayPos0].nextTrackID == TRACK_INVINCIBLE160arrayPos1 = currentPlayer161arrayPos1 += playerCount162if object[arrayPos1].type != TypeName[Invincibility]163if Player_superState != SUPERSTATE_SUPER164object[arrayPos0].nextTrackID = TRACK_STAGE165end if166end if167end if168169PlayMusic(object[arrayPos0].nextTrackID)170end if171end if172end if173end function174175176// ========================177// Events178// ========================179180event ObjectUpdate181temp0 = player[0].xpos182temp0 >>= 16183temp1 = player[0].ypos184temp1 >>= 16185arrayPos0 = object.entityPos186if HPZSetup_bossFightActive == false187if object.ypos < stage.newWaterLevel188object.ypos += 0x20000189end if190191if object.ypos > stage.newWaterLevel192object.ypos -= 0x20000193end if194195temp0 = oscillation196temp0 <<= 1197Sin(stage.waterLevel, temp0)198stage.waterLevel <<= 10199stage.waterLevel += object.ypos200temp7 = stage.waterLevel201stage.waterLevel >>= 16202else203object.ypos = stage.waterLevel204object.ypos <<= 16205stage.newWaterLevel = object.ypos206temp7 = object.ypos207end if208209currentPlayer = 0210while currentPlayer < playerCount211if player[currentPlayer].gravityStrength == 0x3800212CheckNotEqual(player[currentPlayer].type, TypeName[Debug Mode])213temp0 = checkResult214CheckNotEqual(player[currentPlayer].state, Player_State_Death)215temp0 &= checkResult216CheckGreater(player[currentPlayer].ypos, temp7)217temp0 &= checkResult218if temp0 == true219if player[currentPlayer].yvel > 0220player[currentPlayer].yvel >>= 2221end if222223if object.ypos < stage.newWaterLevel224player[currentPlayer].yvel += 0x10000225end if226227if player[currentPlayer].state == Player_State_Fly228StopSfx(SfxName[Flying])229StopSfx(SfxName[Jump])230end if231232player[currentPlayer].xvel >>= 1233player[currentPlayer].speed >>= 1234235CallFunction(Player_UpdatePhysicsState)236237if player[currentPlayer].yvel != 0238CreateTempObject(TypeName[Water Splash], 0, player[currentPlayer].xpos, temp7)239object[tempObjectPos].drawOrder = 4240player[currentPlayer].sortedDrawOrder = 4241if player[currentPlayer].state != Player_State_Static242PlaySfx(SfxName[Water Splash], false)243end if244end if245246object[+currentPlayer].constBubbleTimer = 52247player[currentPlayer].drownTimer = 0248end if249else250if player[currentPlayer].invincibleTimer == 0251if player[currentPlayer].shield == SHIELD_FIRE252temp2 = 0253while temp2 < 8254Rand(temp0, 32)255Rand(temp1, 32)256temp0 -= 16257temp0 <<= 16258temp0 += player[currentPlayer].xpos259temp1 -= 16260temp1 <<= 16261temp1 += player[currentPlayer].ypos262CreateTempObject(TypeName[Dust Puff], 0, temp0, temp1)263object[tempObjectPos].drawOrder = player[currentPlayer].sortedDrawOrder264object[tempObjectPos].drawOrder++265object[tempObjectPos].xvel = player[currentPlayer].xvel266object[tempObjectPos].yvel = player[currentPlayer].yvel267temp2++268loop269270player[currentPlayer].shield = SHIELD_NONE271arrayPos0 = currentPlayer272arrayPos0 += playerCount273CallFunction(Player_ApplyShield)274end if275276// Player hit the water with a lightning shield - take their shield and electrocute the water277if player[currentPlayer].shield == SHIELD_LIGHTNING278player[currentPlayer].shield = SHIELD_NONE279arrayPos0 = currentPlayer280arrayPos0 += playerCount281CallFunction(Player_ApplyShield)282Water_flashTimer = 4283end if284end if285286if player[currentPlayer].shield != SHIELD_BUBBLE287if player[currentPlayer].drownTimer == 0288player[currentPlayer].drownLevel = 0289CallFunction(Water_ResetDrownMusic)290end if291292switch player[currentPlayer].drownLevel293case 0294CallFunction(Water_SpawnSmallAirBubble)295player[currentPlayer].drownTimer++296if player[currentPlayer].drownTimer == 360297if currentPlayer == 0298PlaySfx(SfxName[Drown Alert], false)299end if300player[currentPlayer].drownLevel++301end if302break303304case 1305CallFunction(Water_SpawnSmallAirBubble)306player[currentPlayer].drownTimer++307if player[currentPlayer].drownTimer == 660308if currentPlayer == 0309PlaySfx(SfxName[Drown Alert], false)310end if311player[currentPlayer].drownLevel++312end if313break314315case 2316CallFunction(Water_SpawnSmallAirBubble)317player[currentPlayer].drownTimer++318if player[currentPlayer].drownTimer == 960319if currentPlayer == 0320PlaySfx(SfxName[Drown Alert], false)321end if322player[currentPlayer].drownLevel++323end if324break325326case 3327CallFunction(Water_SpawnSmallAirBubble)328player[currentPlayer].drownTimer++329if player[currentPlayer].drownTimer == 1080330if currentPlayer == 0331object.nextTrackID = music.currentTrack332PlayMusic(TRACK_DROWNING)333end if334335temp0 = 0336CallFunction(Water_SpawnCountDownBubble)337player[currentPlayer].drownLevel++338end if339break340341case 4342CallFunction(Water_SpawnSmallAirBubble)343player[currentPlayer].drownTimer++344if player[currentPlayer].drownTimer == 1200345temp0 = 1346CallFunction(Water_SpawnCountDownBubble)347player[currentPlayer].drownLevel++348end if349break350351case 5352CallFunction(Water_SpawnSmallAirBubble)353player[currentPlayer].drownTimer++354if player[currentPlayer].drownTimer == 1320355temp0 = 2356CallFunction(Water_SpawnCountDownBubble)357player[currentPlayer].drownLevel++358end if359break360361case 6362CallFunction(Water_SpawnSmallAirBubble)363player[currentPlayer].drownTimer++364if player[currentPlayer].drownTimer == 1440365temp0 = 3366CallFunction(Water_SpawnCountDownBubble)367player[currentPlayer].drownLevel++368end if369break370371case 7372CallFunction(Water_SpawnSmallAirBubble)373player[currentPlayer].drownTimer++374if player[currentPlayer].drownTimer == 1560375temp0 = 4376CallFunction(Water_SpawnCountDownBubble)377player[currentPlayer].drownLevel++378end if379break380381case 8382CallFunction(Water_SpawnSmallAirBubble)383player[currentPlayer].drownTimer++384if player[currentPlayer].drownTimer == 1680385temp0 = 5386CallFunction(Water_SpawnCountDownBubble)387player[currentPlayer].drownLevel++388end if389break390391case 9392CallFunction(Water_SpawnSmallAirBubble)393player[currentPlayer].drownTimer++394if player[currentPlayer].drownTimer == 1800395if player[currentPlayer].state != Player_State_Death396if currentPlayer == 0397stage.timeEnabled = false398camera[0].enabled = false399end if400player[currentPlayer].state = Player_State_Drown401player[currentPlayer].animation = ANI_DROWNING402player[currentPlayer].speed = 0403player[currentPlayer].xvel = 0404player[currentPlayer].yvel = 0405player[currentPlayer].tileCollisions = false406player[currentPlayer].interaction = false407player[currentPlayer].sortedDrawOrder = 5408object[+currentPlayer].constBubbleTimer = 2409PlaySfx(SfxName[Drowning], false)410player[currentPlayer].drownLevel++411end if412end if413break414415case 10416player[currentPlayer].drownTimer++417if player[currentPlayer].drownTimer == 1860418player[currentPlayer].drownLevel++419end if420421if object[+currentPlayer].constBubbleTimer > 0422object[+currentPlayer].constBubbleTimer--423if object[+currentPlayer].randBubbleTimer > 0424object[+currentPlayer].randBubbleTimer--425else426Rand(temp1, 2)427temp1 += 2428CreateTempObject(TypeName[Air Bubble], temp1, player[currentPlayer].xpos, player[currentPlayer].ypos)429object[tempObjectPos].drawOrder = 5430object[tempObjectPos].yvel = -0x8800431object[tempObjectPos].ypos -= 0x60000432airBubble[tempObjectPos].targetPlayer = currentPlayer433Rand(object[tempObjectPos].angle, 256)434airBubble[tempObjectPos].originPos.x = object[tempObjectPos].xpos435object[+currentPlayer].randBubbleTimer = 512436end if437else438Rand(temp0, 5)439if temp0 == 1440object[+currentPlayer].randBubbleTimer = 2441else442object[+currentPlayer].randBubbleTimer = 512443end if444object[+currentPlayer].constBubbleTimer = 6445446Rand(temp1, 2)447temp1 += 2448CreateTempObject(TypeName[Air Bubble], temp1, player[currentPlayer].xpos, player[currentPlayer].ypos)449object[tempObjectPos].drawOrder = 5450object[tempObjectPos].yvel = -0x8800451object[tempObjectPos].ypos -= 0x60000452airBubble[tempObjectPos].targetPlayer = currentPlayer453Rand(object[tempObjectPos].angle, 0x100)454airBubble[tempObjectPos].originPos.x = object[tempObjectPos].xpos455end if456break457end switch458end if459460CheckEqual(player[currentPlayer].type, TypeName[Debug Mode])461temp0 = checkResult462CheckLower(player[currentPlayer].ypos, temp7)463temp0 |= checkResult464if temp0 == true465if player[currentPlayer].state != Player_State_Death466player[currentPlayer].yvel <<= 1467if player[currentPlayer].yvel < -0x100000468player[currentPlayer].yvel = -0x100000469end if470471#platform: USE_STANDALONE472// Fixes a bug where jumping at the surface of the water will set your velocity too high473// Also yep this fix isn't in Origins, this is taken from the Sega Forever releases of the game474if player[currentPlayer].animation == ANI_JUMPING475if player[currentPlayer].timer > 0476if player[currentPlayer].yvel < -0x68000477player[currentPlayer].yvel = -0x68000478end if479end if480end if481#endplatform482483if player[currentPlayer].state == Player_State_Fly484if player[currentPlayer].timer < 480485PlaySfx(SfxName[Flying], true)486else487PlaySfx(SfxName[Jump], true)488end if489end if490491492CallFunction(Player_UpdatePhysicsState)493if player[currentPlayer].yvel != 0494temp0 = object.ypos495temp0 -= player[currentPlayer].ypos496if temp0 < 0xF00000497CreateTempObject(TypeName[Water Splash], 0, player[currentPlayer].xpos, temp7)498object[tempObjectPos].drawOrder = 4499player[currentPlayer].sortedDrawOrder = 4500if player[currentPlayer].state != Player_State_Static501PlaySfx(SfxName[Water Splash], false)502end if503end if504end if505506player[currentPlayer].drownTimer = 0507CallFunction(Water_ResetDrownMusic)508end if509end if510end if511512currentPlayer++513loop514515object.animationTimer++516object.animationTimer &= 31517object.frame = object.animationTimer518object.frame >>= 3519end event520521522event ObjectDraw523temp0 = screen.xoffset524Sin(temp1, oscillation)525temp1 >>= 5526temp0 += temp1527temp0 &= 63528FlipSign(temp0)529530temp1 = stage.waterLevel531temp1 -= screen.yoffset532DrawSpriteScreenFX(object.frame, FX_INK, temp0, temp1)533534temp0 += 256535DrawSpriteScreenFX(object.frame, FX_INK, temp0, temp1)536end event537538539event ObjectStartup540foreach (TypeName[Water], arrayPos0, ALL_ENTITIES)541object[arrayPos0].priority = PRIORITY_ACTIVE542object[arrayPos0].drawOrder = 5543object[arrayPos0].inkEffect = INK_ALPHA544object[arrayPos0].alpha = 0xA0545stage.newWaterLevel = object[arrayPos0].ypos546Water_waterSlotID = arrayPos0547stage.waterLevel = stage.newWaterLevel548stage.waterLevel >>= 16549object[arrayPos0].ypos = stage.newWaterLevel550next551552if starPostID >= 32553stage.waterState = recWaterState554stage.waterLevel = recWaterLevel555stage.newWaterLevel = recWaterLevel556stage.newWaterLevel <<= 16557arrayPos0 = Water_waterSlotID558object[arrayPos0].ypos = stage.newWaterLevel559else560stage.waterState = 0561end if562563Water_activateFlag = false564565foreach (GROUP_PLAYERS, currentPlayer, ALL_ENTITIES)566player[currentPlayer].drownTimer = 0567if player[currentPlayer].ypos > stage.newWaterLevel568player[currentPlayer].yvel >>= 2569player[currentPlayer].xvel >>= 1570player[currentPlayer].speed >>= 1571player[currentPlayer].topSpeed >>= 1572player[currentPlayer].acceleration >>= 1573player[currentPlayer].deceleration >>= 1574player[currentPlayer].airAcceleration >>= 1575player[currentPlayer].airDeceleration >>= 1576player[currentPlayer].gravityStrength = 0x1000577if stage.playerListPos == PLAYER_KNUCKLES_A578player[currentPlayer].jumpStrength = 0x30000579else580player[currentPlayer].jumpStrength = 0x38000581end if582player[currentPlayer].jumpCap = -0x20000583arrayPos0 = Water_waterSlotID584arrayPos0 += currentPlayer585object[arrayPos0].constBubbleTimer = 52586end if587next588589LoadSpriteSheet("HPZ/Objects2.gif")590SpriteFrame(0, -8, 256, 16, 0, 0)591SpriteFrame(0, -8, 256, 16, 0, 16)592SpriteFrame(0, -8, 256, 16, 0, 32)593SpriteFrame(0, -8, 256, 16, 0, 48)594595BrokenMonitor_ResetDrownMusic = Water_ResetDrownMusic596end event597598599// ========================600// Editor Events601// ========================602603event RSDKDraw604DrawSprite(0)605end event606607608event RSDKLoad609LoadSpriteSheet("HPZ/Objects2.gif")610SpriteFrame(0, -8, 256, 16, 0, 0)611612SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")613end event614615616