Path: blob/main/Scripts/Special/UFO.txt
1319 views
//--------------------Sonic CD UFO Script---------------------//1//--------Scripted by Christian Whitehead 'The Taxman'--------//2//-------Unpacked By Rubberduckycooly's Script Unpacker-------//34// Aliases5#alias Object.YPos : Object.ZPos67#alias Object.Value0 : Object.TargetNode8#alias Object.Value1 : Object.XVelocity9#alias Object.Value2 : Object.ZVelocity10#alias Object.Value3 : Object.Timer11#alias Object.Value4 : Object.ScreenXPos // Difference from the center of the camera (which is where Sonic is always located)12#alias Object.Value5 : Object.ScreenDepth1314// HUD Alias15#alias Object.Value0 : HUD.UFOsCount // Initially set via a loop in the UFO script16#alias Object.Value1 : HUD.TimeSeconds // Displayed time17#alias Object.Value3 : HUD.Rings18#alias Object.Value4 : HUD.LastUFOType // Used by UFOs for ring streak bonus19#alias Object.Value5 : HUD.SpeedShoesTimer // Used to transmit between player and UFO20#alias Object.Value6 : HUD.BonusUFONo // "No" akin to Entity No, not as in "is there no UFO?"2122// UFOPowerUp Aliases23#alias Object.Value0 : UFOPowerUp.ExplosionDir24#alias Object.Value1 : UFOPowerUp.ExplosionXVel25#alias Object.Value2 : UFOPowerUp.ExplosionYVel26#alias Object.Value4 : UFOPowerUp.YVelocity27#alias Object.Value5 : UFOPowerUp.ScreenDepth28#alias Object.Value7 : UFOPowerUp.StartResults2930// SFX Aliases31#alias 1 : SFX_G_RING3233// Property Value34#alias 0 : UFO_CONTENTS_RINGS35#alias 1 : UFO_CONTENTS_SPEEDSHOES36#alias 2 : UFO_CONTENTS_TIME3738// Priority39#alias 1 : PRIORITY_ACTIVE404142sub ObjectMain43// Update movement44if Object.Timer == 045ArrayPos0 = Object.TargetNode46if Object[ArrayPos0].Type != TypeName[UFO Node]47Object.TargetNode = Object.EntityNo48Object.TargetNode++49ArrayPos0 = Object.TargetNode50end if5152Object.XPos = Object[ArrayPos0].XPos53Object.ZPos = Object[ArrayPos0].ZPos54Object.Timer = Object[ArrayPos0].PropertyValue55Object.Timer *= 25657ArrayPos0++58Object.TargetNode++59if Object[ArrayPos0].Type != TypeName[UFO Node]60Object.TargetNode = Object.EntityNo61Object.TargetNode++62ArrayPos0 = Object.TargetNode63end if6465Object.XVelocity = Object[ArrayPos0].XPos66Object.XVelocity -= Object.XPos67Object.XVelocity /= Object.Timer6869Object.ZVelocity = Object[ArrayPos0].ZPos70Object.ZVelocity -= Object.ZPos71Object.ZVelocity /= Object.Timer72else73// Following a node - just update movement for now7475Object.Timer--76Object.XPos += Object.XVelocity77Object.ZPos += Object.ZVelocity78end if7980// Check player interaction in this (rather lengthy) process8182// X difference83TempValue0 = Object.XPos84TempValue0 -= TileLayer[0].XPos85TempValue0 >>= 88687// Z mutliplier88TempValue1 = Object.ZPos89TempValue1 -= TileLayer[0].ZPos90TempValue1 >>= 89192// Calculating the X difference93Sin(TempValue2, TileLayer[0].Angle)94TempValue2 *= TempValue195Cos(TempValue3, TileLayer[0].Angle)96TempValue3 *= TempValue097Object.ScreenXPos = TempValue298Object.ScreenXPos -= TempValue399Object.ScreenXPos >>= 9100101// Calculating the Z difference102Cos(TempValue2, TileLayer[0].Angle)103TempValue2 *= TempValue1104Sin(TempValue3, TileLayer[0].Angle)105TempValue3 *= TempValue0106Object.ScreenDepth = TempValue2107Object.ScreenDepth += TempValue3108Object.ScreenDepth >>= 9109110// Long list of checks for the hitbox detection111112// The Player has to be more than 54 pixels off the ground, but lower than 122 pixels towards the sky113if Player.YPos > 0x360000114if Player.YPos < 0x7A0000115116// The UFO has to be within the 2100 range from the player, who's at a depth of 0x5800 normally117if Object.ScreenDepth < 0x58C8118if Object.ScreenDepth > 0x5094119120// The UFO has to be between -0.125 and +0.125 pixels away from the screen centre121if Object.ScreenXPos > -0x2000122if Object.ScreenXPos < 0x2000123124// All those checks passed, let's destroy this UFO!125126TempValue0 = Object.ScreenXPos127TempValue0 *= 192128TempValue0 /= Object.ScreenDepth129TempValue0 += Screen.CenterX130TempValue0 <<= 16131132TempValue1 = TileLayer[0].YPos133TempValue1 >>= 8134TempValue1 -= 0x6000135TempValue1 *= 96136TempValue1 /= Object.ScreenDepth137TempValue1 += 128138TempValue1 <<= 16139140// Play the ring SFX141PlaySfx(SFX_G_RING, false)142143#platform: Use_Haptics144// Do shake index 55 to really sell the impact of hitting a floating UFO145HapticEffect(55, 0, 0, 0)146#endplatform147148switch Object.PropertyValue149case UFO_CONTENTS_RINGS150// Decrease the UFO count and give some bonus rings151HUD[4].UFOsCount--152if HUD[4].LastUFOType == Object.PropertyValue153// If the last UFO caught was a rings variant too, then double the player's rings rather than adding 20154HUD[4].Rings <<= 1155else156HUD[4].Rings += 20157end if158break159160case UFO_CONTENTS_SPEEDSHOES161// Decrease the UFO count and give the player some new faster shoes162HUD[4].UFOsCount--163HUD[4].SpeedShoesTimer = 600164break165166case UFO_CONTENTS_TIME167// Aadd some time to the clock168// (Not decreasing the UFO count because time UFOs don't count towards the whole)169HUD[4].TimeSeconds += 30170break171172end switch173174HUD[4].LastUFOType = Object.PropertyValue175176// Create the UFO powerup icon177CreateTempObject(TypeName[UFO PowerUp], Object.PropertyValue, TempValue0, TempValue1)178Rand(UFOPowerUp[TempObjectPos].ExplosionDir, 100)179UFOPowerUp[TempObjectPos].ExplosionXVel = TempValue0180UFOPowerUp[TempObjectPos].ExplosionYVel = TempValue1181UFOPowerUp[TempObjectPos].YVelocity = -0x40000182UFOPowerUp[TempObjectPos].ScreenDepth = 0x58C8183184// If the last UFO was just destroyed, then signal that to the PowerUp object too185if HUD[4].UFOsCount == 0186UFOPowerUp[TempObjectPos].StartResults = true187end if188189// Blank this UFO object since it's been190ResetObjectEntity(Object.EntityNo, TypeName[Blank Object], 0, 0, 0)191192// And now, close a whole lotta end if's...193194end if195end if196end if197end if198end if199end if200201end sub202203204sub ObjectDraw205if Object.ScreenDepth > 256 // Don't draw if the UFO is too close to the screen206207// Do some maths to find the position & scale the UFO should be at208209Object.Scale = 0xC00000210Object.Scale /= Object.ScreenDepth211212TempValue0 = 768213TempValue0 -= Object.Scale214TempValue0 /= 6215216TempValue1 = Object.ScreenDepth217TempValue1 >>= 12218219if TempValue0 > 0220Object.Scale += TempValue0221Object.Scale -= TempValue1222end if223224TempValue0 = Object.ScreenXPos225TempValue0 *= 192226TempValue0 /= Object.ScreenDepth227TempValue0 += Screen.CenterX228229TempValue1 = TileLayer[0].YPos230TempValue1 >>= 8231TempValue1 -= 0x6000232TempValue1 *= 96233TempValue1 /= Object.ScreenDepth234TempValue1 += 128235236// Draw the UFO now237DrawSpriteScreenFX(Object.PropertyValue, FX_SCALE, TempValue0, TempValue1)238239// Find the ground position240TempValue1 = TileLayer[0].YPos241TempValue1 >>= 8242TempValue1 *= 96243TempValue1 /= Object.ScreenDepth244TempValue1 += 128245246// Draw the shadow on the ground247DrawSpriteScreenFX(3, FX_SCALE, TempValue0, TempValue1)248249end if250251end sub252253254sub ObjectStartup255256LoadSpriteSheet("Special/Objects.gif")257258// UFO Frames259260// 0 - 10 Rings Variant261SpriteFrame(-40, -28, 80, 56, 1, 1)262263// 1 - Speed Shoes Variant264SpriteFrame(-40, -28, 80, 56, 82, 1)265266// 2 - Extra Time Variant267SpriteFrame(-40, -28, 80, 56, 163, 1)268269// 3 - UFO Shadow Frame270SpriteFrame(-40, -8, 80, 16, 1, 117)271272// Cycle through all UFO objects in the scene and set them up273ArrayPos0 = 32274while ArrayPos0 < 1056275if Object[ArrayPos0].Type == TypeName[UFO]276277// Set the UFO to always be active278Object[ArrayPos0].Priority = PRIORITY_ACTIVE279280if Object[ArrayPos0].PropertyValue < 2281282// Increase the UFO count283HUD[4].UFOsCount++284285else286287// Bonus UFO Spawn point, delete the UFO for right now and store its EntityPos into the HUD value288// (We need to make sure the Time UFO is spawned in the correct slot because of its Nodes)289290Object[ArrayPos0].Type = TypeName[Blank Object]291HUD[4].BonusUFONo = ArrayPos0292293end if294end if295296ArrayPos0++297loop298299end sub300301302// ========================303// Editor Subs304// ========================305306sub RSDKEdit307if Editor.ReturnVariable == true308switch Editor.VariableID309case EDIT_VAR_PROPVAL // Property Value310CheckResult = Object.PropertyValue311break312case 0 // Contents313CheckResult = Object.PropertyValue314break315end switch316else317switch Editor.VariableID318case EDIT_VAR_PROPVAL // Property Value319Object.PropertyValue = Editor.VariableValue320break321case 0 // Contents322Object.PropertyValue = Editor.VariableValue323break324end switch325end if326end sub327328329sub RSDKDraw330DrawSprite(Object.PropertyValue)331332if Editor.ShowGizmos == true333// Draw arrows to show the network of UFO nodes334335Editor.DrawingOverlay = true336337ArrayPos1 = Object.EntityNo338ArrayPos0 = Object.EntityNo339ArrayPos0++340341// TODO: change this to "UFO Node" once GetObjectType works with spaces342GetObjectType(TempValue0, "UFONode")343344while Object[ArrayPos0].Type == TempValue0345DrawArrow(Object[ArrayPos1].XPos, Object[ArrayPos1].ZPos, Object[ArrayPos0].XPos, Object[ArrayPos0].ZPos, 255, 255, 0)346ArrayPos0++347ArrayPos1++348loop349350ArrayPos0 = Object.EntityNo351ArrayPos0++352if ArrayPos1 != Object.EntityNo353DrawArrow(Object[ArrayPos1].XPos, Object[ArrayPos1].ZPos, Object[ArrayPos0].XPos, Object[ArrayPos0].ZPos, 255, 255, 0)354end if355356Editor.DrawingOverlay = false357end if358end sub359360361sub RSDKLoad362LoadSpriteSheet("Special/Objects.gif")363SpriteFrame(-40, -28, 80, 56, 1, 1)364SpriteFrame(-40, -28, 80, 56, 82, 1)365SpriteFrame(-40, -28, 80, 56, 163, 1)366367AddEditorVariable("Contents")368SetActiveVariable("Contents")369AddEnumVariable("10 Rings", UFO_CONTENTS_RINGS)370AddEnumVariable("Speed Shoes", UFO_CONTENTS_SPEEDSHOES)371AddEnumVariable("Extra Time", UFO_CONTENTS_TIME)372end sub373374375