Path: blob/master/Sonic 2/Scripts/Global/Ring.txt
1480 views
// ----------------------------------1// RSDK Project: Sonic 22// Script Description: Ring Object3// Script Author: Christian Whitehead/Simon Thomley4// Unpacked by Rubberduckycooly's script unpacker5// ----------------------------------67// ========================8// Aliases9// ========================1011private alias object.value1 : object.targetPlayer1213private alias 0 : RING_IDLE14private alias 1 : RING_ATTRACTED1516// Player Aliases17private alias object.state : player.state18private alias object.xpos : player.xpos19private alias object.ypos : player.ypos20private alias object.value0 : player.rings21private alias object.value16 : player.isSidekick22private alias object.value18 : player.currentPlane23private alias object.value37 : player.shield2425private alias 4 : SHIELD_LIGHTNING2627// Game Modes28private alias 2 : MODE_TIMEATTACK2930// Music Events31private alias 25 : SLOT_MUSICEVENT_CHANGE3233private alias 2 : MUSICEVENT_TRANSITION343536// ========================37// Function Declarations38// ========================3940reserve function Ring_DebugDraw41reserve function Ring_DebugSpawn424344// ========================45// Function Definitions46// ========================4748private function Ring_DebugDraw49DrawSprite(0)50end function515253private function Ring_DebugSpawn54CreateTempObject(TypeName[Ring], 0, object.xpos, object.ypos)55object[tempObjectPos].drawOrder = 456end function575859// ========================60// Events61// ========================6263event ObjectUpdate64// Bug Details:65// - The loop doesn't check to see if the ring's been obtained already, so66// if two players touch the ring at the same time, then the ring will count twice67// - (The CNZ ring properly checks for that.. so why doesn't the normal version have the fix?..)68foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)6970// Bug Details:71// -> While this top check works fine in singleplayer, as well as 2013's online VS, this doesn't work quite as fairly in Origins's local 2PVS72// It puts P2 at a direct disadvantage, since it blocks them from picking up any rings while P1 is recoiling73// On the other hand, however, P1 can still pick up rings even when P2 is recoiling74CheckEqual(player[0].state, Player_State_Hurt)75temp0 = checkResult7677CheckEqual(player[currentPlayer].state, Player_State_Hurt)78temp0 = checkResult79CheckEqual(player[currentPlayer].state, Player_State_GotHit)80temp0 |= checkResult8182if temp0 == false83// All checks passed, see if the player is touching the ring8485BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)86if checkResult == true87// Player is touching ring - collect it8889// Turn this object into a sparkle90object.type = TypeName[Ring Sparkle]9192// Set this object to the same drawOrder as the player93object.drawOrder = player[currentPlayer].currentPlane9495// Add it to the player's ring count96if player[currentPlayer].isSidekick == true97// P2 Tails in normal gameplay (not VS)98// So add it to P1's ring count99player[0].rings++100if player[0].rings > 999101player[0].rings = 999102end if103else104// Either P2 in VS or P1 in any mode105// In any case, give the ring to the player that collected it106player[currentPlayer].rings++107if player[currentPlayer].rings > 999108player[currentPlayer].rings = 999109end if110end if111112// Check if the player should get an extra life113// (Always checking against P1? Doesn't look like P2 can get an extra life with rings in VS..)114if player[0].rings >= ringExtraLife115// Not in time attack?116if options.gameMode != MODE_TIMEATTACK117// Give the player an extra life/coin and play the music118#platform: USE_ORIGINS119if game.coinMode == false120player.lives++121else122CallNativeFunction2(NotifyCallback, NOTIFY_ADD_COIN, 1)123end if124#endplatform125#platform: USE_STANDALONE126player.lives++127#endplatform128PlaySfx(SfxName[Life], false)129PauseMusic()130ResetObjectEntity(SLOT_MUSICEVENT_CHANGE, TypeName[Music Event], MUSICEVENT_TRANSITION, 0, 0)131object[SLOT_MUSICEVENT_CHANGE].priority = PRIORITY_ACTIVE132end if133134ringExtraLife += 100135if ringExtraLife > 300136ringExtraLife = 1000137end if138end if139140if options.vsMode == true141if vs.playerID == 0 // Player 1 on the server side142if currentPlayer == 0 // Player 1 on the client's side143vs.totalRings1P++144else145vs.totalRings2P++146end if147else148if currentPlayer == 1 // Player 2 on the client's side149vs.totalRings1P++150else151vs.totalRings2P++152end if153end if154end if155156// Play the ring sound157if ringPan == 0158PlaySfx(SfxName[Ring L], false)159SetSfxAttributes(SfxName[Ring L], -1, -100)160ringPan = 1161else162PlaySfx(SfxName[Ring R], false)163SetSfxAttributes(SfxName[Ring R], -1, 100)164ringPan = 0165end if166else167// Check if the ring should get attracted168if object.state == RING_IDLE169if player[currentPlayer].shield == SHIELD_LIGHTNING170BoxCollisionTest(C_TOUCH, object.entityPos, -64, -64, 64, 64, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)171if checkResult == true172// Make the ring attracted to the player173object.state = RING_ATTRACTED174object.targetPlayer = currentPlayer175end if176end if177end if178end if179end if180next181182if object.state == RING_ATTRACTED183arrayPos0 = object.targetPlayer184185if player[arrayPos0].shield != SHIELD_LIGHTNING186// If the player lost their shield, then make this ring dropped187object.type = TypeName[Lose Ring]188object.animationSpeed = 128189object.alpha = 256190else191arrayPos0 = object.targetPlayer192193// Move closer to the player194if object.xpos > player[arrayPos0].xpos195if object.xvel > 0196object.xvel -= 0xC000197else198object.xvel -= 0x3000199end if200else201if object.xvel < 0202object.xvel += 0xC000203else204object.xvel += 0x3000205end if206end if207208if object.ypos > player[arrayPos0].ypos209if object.yvel > 0210object.yvel -= 0xC000211else212object.yvel -= 0x3000213end if214else215if object.yvel < 0216object.yvel += 0xC000217else218object.yvel += 0x3000219end if220end if221222object.xpos += object.xvel223object.ypos += object.yvel224end if225end if226end event227228229event ObjectDraw230// All rings use the same frame231// (Animation is handled by Stage Setup object)232DrawSprite(ringFrame)233end event234235236event ObjectStartup237LoadSpriteSheet("Global/Items.gif")238239// (Doesn't mean much, but this is one of the few times in v4 scripts that a code is between LoadSpriteSheet and SpriteFrames)240foreach (TypeName[Ring], arrayPos0, ALL_ENTITIES)241object[arrayPos0].drawOrder = 4242next243244// Ring frames245SpriteFrame(-8, -8, 16, 16, 1, 1)246SpriteFrame(-8, -8, 16, 16, 1, 18)247SpriteFrame(-8, -8, 16, 16, 1, 35)248SpriteFrame(-8, -8, 16, 16, 1, 52)249SpriteFrame(-8, -8, 16, 16, 1, 69)250SpriteFrame(-8, -8, 16, 16, 1, 86)251SpriteFrame(-8, -8, 16, 16, 1, 103)252SpriteFrame(-8, -8, 16, 16, 1, 120)253254// Add the Ring to the debug mode object list255SetTableValue(TypeName[Ring], DebugMode_ObjCount, DebugMode_TypesTable)256SetTableValue(Ring_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)257SetTableValue(Ring_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)258DebugMode_ObjCount++259end event260261262// ========================263// Editor Events264// ========================265266event RSDKEdit267if editor.returnVariable == true268switch editor.variableID269case EDIT_VAR_PROPVAL // property value270checkResult = object.propertyValue271break272273case 0 // type274checkResult = object.propertyValue275break276277end switch278else279switch editor.variableID280case EDIT_VAR_PROPVAL // property value281object.propertyValue = editor.variableValue282break283284case 0 // type285object.propertyValue = editor.variableValue286break287288end switch289end if290end event291292293event RSDKDraw294DrawSprite(0)295end event296297298event RSDKLoad299LoadSpriteSheet("Global/Items.gif")300SpriteFrame(-8, -8, 16, 16, 1, 1)301302AddEditorVariable("type")303SetActiveVariable("type")304AddEnumVariable("Normal", 0)305//AddEnumVariable("Not required by Sonic for perfect bonus", 1) // The score tally system seems to be a bit broken, so while it looks like this is how it was *supposed* to be, this is effectively useless306AddEnumVariable("Not required by all characters for perfect bonus", 2)307end event308309310