Path: blob/master/Sonic 1/Scripts/LZ/Eggman.txt
1483 views
// ----------------------------------1// RSDK Project: Sonic 12// Script Description: Eggman Object3// Script Author: Christian Whitehead/Simon Thomley4// Unpacked by Rubberduckycooly's script unpacker5// ----------------------------------67// Using LZEggman as a prefix here because there's like 12 "Eggman" objects in the game so its less confusing this way89// ========================10// Aliases11// ========================1213private alias object.value0 : object.originPos.x14private alias object.value1 : object.originPos.y15private alias object.value2 : object.defeated16private alias object.value3 : object.oscillateAngle.y17private alias object.value4 : object.oscillateAngle.x18private alias object.value5 : object.timer19private alias object.value6 : object.flameAnim20private alias object.value7 : object.flameAnimTimer21private alias object.value8 : object.health22private alias object.value9 : object.invincibilityTimer23private alias object.value10 : object.gotHit2425// Eggman States26private alias 0 : LZEGGMAN_AWAITPLAYER27private alias 1 : LZEGGMAN_NODE128private alias 2 : LZEGGMAN_NODE229private alias 3 : LZEGGMAN_NODE330private alias 4 : LZEGGMAN_NODE431private alias 5 : LZEGGMAN_LASTNODE32private alias 6 : LZEGGMAN_REACHEDEND33private alias 7 : LZEGGMAN_ESCAPE3435// Eggman Animations36private alias 0 : LZEGGANI_INVISIBLE37private alias 1 : LZEGGANI_IDLE38private alias 2 : LZEGGANI_LAUGH39private alias 3 : LZEGGANI_HIT40private alias 4 : LZEGGANI_DEFEATED41private alias 5 : LZEGGANI_TOASTED42private alias 6 : LZEGGANI_PANIC4344// Flame Animations45private alias 0 : FLAME_INACTIVE46private alias 1 : FLAME_ACTIVE47private alias 2 : FLAME_EXPLODE4849// Music Events50private alias 26 : SLOT_MUSICEVENT_BOSS5152private alias 0 : MUSICEVENT_FADETOBOSS53private alias 1 : MUSICEVENT_FADETOSTAGE54private alias 2 : MUSICEVENT_TRANSITION5556// Player Aliases57private alias object.xpos : player.xpos58private alias object.ypos : player.ypos59private alias object.xvel : player.xvel60private alias object.speed : player.speed61private alias object.animation : player.animation62private alias object.value40 : player.hitboxLeft63private alias object.value38 : player.hitboxTop64private alias object.value41 : player.hitboxRight65private alias object.value39 : player.hitboxBottom6667// Achievement Aliases68private alias 6 : ACHIEVEMENT_FLAWLESSPURSUIT697071// ========================72// Function Declarations73// ========================7475reserve function LZEggman_Oscillate76reserve function LZEggman_HandleMovement777879// ========================80// Tables81// ========================8283private table LZEggman_nodePositionTable[10]848586// ========================87// Function Definitions88// ========================8990private function LZEggman_Oscillate91Sin256(temp0, object.oscillateAngle.y)92temp0 <<= 1093object.ypos += temp09495object.oscillateAngle.y += 296object.oscillateAngle.y &= 0xFF97end function9899100private function LZEggman_HandleMovement101object.originPos.x += object.xvel102object.originPos.y += object.yvel103104object.xpos = object.originPos.x105object.ypos = object.originPos.y106end function107108109// ========================110// Events111// ========================112113event ObjectUpdate114#platform: USE_ORIGINS115// cool stuff116CallNativeFunction2(NotifyCallback, NOTIFY_DEBUGPRINT, object.state)117#endplatform118119switch object.state120case LZEGGMAN_AWAITPLAYER121GetTableValue(temp0, 0, LZEggman_nodePositionTable)122foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)123if player[currentPlayer].xpos >= temp0124object.xvel = 0x6000125object.yvel = -0x18000126object.originPos.y = object.ypos127object.oscillateAngle.y = 0128object.state++129object.priority = PRIORITY_ACTIVE130ResetObjectEntity(SLOT_MUSICEVENT_BOSS, TypeName[Music Event], MUSICEVENT_FADETOBOSS, 0, 0)131object[SLOT_MUSICEVENT_BOSS].priority = PRIORITY_ACTIVE132end if133next134CallFunction(LZEggman_HandleMovement)135136if object.state == LZEGGMAN_AWAITPLAYER137CallFunction(LZEggman_Oscillate)138end if139break140141case LZEGGMAN_NODE1142temp1 = -2143144GetTableValue(temp0, 1, LZEggman_nodePositionTable)145if object.originPos.x >= temp0146object.originPos.x = temp0147object.xvel = 0148temp1++149end if150151GetTableValue(temp0, 2, LZEggman_nodePositionTable)152if object.originPos.y <= temp0153object.originPos.y = temp0154object.yvel = 0155temp1++156end if157158if temp1 == 0159object.xvel = 0x14000160object.yvel = -0x20000161object.state++162end if163CallFunction(LZEggman_HandleMovement)164break165166case LZEGGMAN_NODE2167temp1 = -2168169GetTableValue(temp0, 3, LZEggman_nodePositionTable)170if object.originPos.x >= temp0171object.originPos.x = temp0172object.xvel = 0173temp1++174end if175176GetTableValue(temp0, 4, LZEggman_nodePositionTable)177if object.originPos.y <= temp0178object.originPos.y = temp0179object.yvel = 0180temp1++181end if182183if temp1 == 0184object.yvel = -0x18000185object.state++186end if187188CallFunction(LZEggman_HandleMovement)189break190191case LZEGGMAN_NODE3192GetTableValue(temp0, 5, LZEggman_nodePositionTable)193if object.originPos.y <= temp0194object.originPos.y = temp0195if object.defeated == false196object.xvel = 0x14000197object.yvel--198else199object.xvel = 0x28000200object.yvel--201end if202object.direction = FLIP_X203object.originPos.x = object.xpos204object.state++205CallFunction(LZEggman_HandleMovement)206else207object.oscillateAngle.x += 2208object.oscillateAngle.x &= 0xFF209Cos256(temp0, object.oscillateAngle.x)210if temp0 > 0211object.direction = FLIP_X212else213object.direction = FLIP_NONE214end if215Sin256(object.xpos, object.oscillateAngle.x)216object.xpos <<= 12217object.xpos += object.originPos.x218219temp0 = object.yvel220temp1 = 0x7FFFFFFF221foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)222if player[currentPlayer].ypos < temp1223temp1 = player[currentPlayer].ypos224end if225next226227temp1 -= object.originPos.y228if temp1 >= 0229temp1 -= 0x480000230if temp1 >= 0231temp0 >>= 1232temp1 -= 0x280000233if temp1 >= 0234temp0 >>= 1235temp1 -= 0x280000236if temp1 >= 0237temp0 = 0238end if239end if240end if241end if242243if object.defeated == true244temp0 <<= 1245end if246247if temp0 == 0248object.ypos = object.originPos.y249CallFunction(LZEggman_Oscillate)250else251object.originPos.y = object.ypos252object.oscillateAngle.y = 0253object.originPos.y += temp0254object.ypos = object.originPos.y255end if256end if257break258259case LZEGGMAN_NODE4260temp1 = -2261262GetTableValue(temp0, 6, LZEggman_nodePositionTable)263if object.originPos.x >= temp0264object.originPos.x = temp0265object.xvel = 0266temp1++267end if268269GetTableValue(temp0, 7, LZEggman_nodePositionTable)270if object.originPos.y <= temp0271object.originPos.y = temp0272object.yvel = 0273temp1++274end if275276if temp1 == 0277if object.defeated == false278object.direction = FLIP_NONE279end if280object.oscillateAngle.y = 0281object.state++282end if283284CallFunction(LZEggman_HandleMovement)285break286287case LZEGGMAN_LASTNODE288temp2 = 0289if object.defeated == false290// Check if player excaped to the top291GetTableValue(temp0, 8, LZEggman_nodePositionTable)292GetTableValue(temp1, 9, LZEggman_nodePositionTable)293foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)294if player[currentPlayer].xpos >= temp0295if player[currentPlayer].ypos <= temp1296temp2 = true297object.timer = 50298object.animation = LZEGGANI_DEFEATED299object.animationTimer = 32300end if301end if302next303else304temp2 = true305object.timer = 1306end if307308if temp2 == true309ResetObjectEntity(SLOT_MUSICEVENT_BOSS, TypeName[Music Event], MUSICEVENT_FADETOSTAGE, 0, 0)310object[SLOT_MUSICEVENT_BOSS].priority = PRIORITY_ACTIVE311object.state++312end if313314CallFunction(LZEggman_HandleMovement)315CallFunction(LZEggman_Oscillate)316break317318case LZEGGMAN_REACHEDEND319object.timer--320if object.timer == 0321object.timer = 0322object.xvel = 0x40000323object.yvel = -0x4000324object.priority = PRIORITY_ACTIVE325object.animation = LZEGGANI_PANIC326object.animationTimer = 0327object.flameAnim = FLAME_EXPLODE328object.originPos.y = object.ypos329object.state++330if stage.debugMode == false331if object.gotHit == false332// Grant the "Flawless Pursuit" Achievement333CallNativeFunction2(SetAchievement, ACHIEVEMENT_FLAWLESSPURSUIT, 100)334end if335end if336#platform: USE_ORIGINS337CallNativeFunction2(NotifyCallback, NOTIFY_KILL_BOSS, 0)338CallNativeFunction2(NotifyCallback, NOTIFY_BOSS_END, true)339#endplatform340else341if object.timer == 24342object.animation = LZEGGANI_IDLE343object.animationTimer = 0344object.direction = FLIP_X345end if346end if347348CallFunction(LZEggman_HandleMovement)349350if object.state == LZEGGMAN_REACHEDEND351CallFunction(LZEggman_Oscillate)352end if353break354355case LZEGGMAN_ESCAPE356if object.outOfBounds == true357ResetObjectEntity(object.entityPos, TypeName[Blank Object], 0, 0, 0)358object.defeated = false359else360CallFunction(LZEggman_HandleMovement)361end if362break363364end switch365366if object.health != 0367if object.invincibilityTimer > 0368object.invincibilityTimer--369end if370371// Check interaction with players372foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)373if object.invincibilityTimer == 0374375// CHeck if the player is in one of the following animations376CheckEqual(player[currentPlayer].animation, ANI_HURT)377temp0 = checkResult378CheckEqual(player[currentPlayer].animation, ANI_DYING)379temp0 |= checkResult380CheckEqual(player[currentPlayer].animation, ANI_DROWNING)381temp0 |= checkResult382383if temp0 != 0384// Player is in one of those animations, start laughing at them385if object.animation != LZEGGANI_LAUGH386object.animation = LZEGGANI_LAUGH387object.animationTimer = 0388end if389390if currentPlayer == 0391object.gotHit = true392end if393end if394395// Check player collision396#platform: USE_STANDALONE397BoxCollisionTest(C_TOUCH, object.entityPos, -20, -16, 20, 16, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)398#endplatform399#platform: USE_ORIGINS400BoxCollisionTest(C_TOUCH, object.entityPos, -20, -16, 20, 16, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)401#endplatform402if checkResult == true403404// See if the player should be hit or is attacking405CallFunction(Player_CheckHit)406407if checkResult == true408object.health--409if object.health == 0410#platform: USE_ORIGINS411CallNativeFunction2(NotifyCallback, NOTIFY_KILL_BOSS, 0)412CallNativeFunction2(NotifyCallback, NOTIFY_BOSS_END, 1)413#endplatform414// Final hit, increase score and start exploding415player.score += 1000416object.animation = LZEGGANI_DEFEATED417object.animationTimer = 0418object.defeated = true419else420// Simply got hit, do the hit stuff421object.animation = LZEGGANI_HIT422object.animationTimer = 0423object.invincibilityTimer = 32424PlaySfx(SfxName[Boss Hit], false)425end if426end if427end if428end if429next430end if431432if object.defeated == true433temp0 = oscillation434temp0 &= 7435if temp0 == 0436Rand(temp0, 96)437temp0 -= 48438temp0 <<= 16439temp0 += object.xpos440Rand(temp1, 48)441temp1 -= 24442temp1 <<= 16443temp1 += object.ypos444CreateTempObject(TypeName[Explosion], 0, temp0, temp1)445PlaySfx(SfxName[Explosion], false)446end if447end if448end event449450451event ObjectDraw452switch object.animation453default454case LZEGGANI_INVISIBLE455break456457case LZEGGANI_IDLE458temp0 = object.animationTimer459temp0 /= 6460object.animationTimer++461object.animationTimer %= 12462DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)463break464465case LZEGGANI_LAUGH466temp0 = object.animationTimer467temp0 %= 10468temp0 /= 5469temp0 += 9470object.animationTimer++471if object.animationTimer == 50472object.animationTimer = 0473if player[0].animation != ANI_DYING474object.animation = LZEGGANI_IDLE475end if476end if477DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)478break479480case LZEGGANI_HIT481temp0 = object.animationTimer482temp0 &= 1483temp0 += 2484object.animationTimer++485if object.animationTimer == 30486object.animationTimer = 0487object.animation = LZEGGANI_IDLE488end if489DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)490break491492case LZEGGANI_DEFEATED493temp0 = object.animationTimer494temp0 >>= 5495temp0 += 4496object.animationTimer++497object.animationTimer &= 63498DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)499break500501case LZEGGANI_TOASTED502DrawSpriteFX(6, FX_FLIP, object.xpos, object.ypos)503break504505case LZEGGANI_PANIC506temp0 = object.animationTimer507temp0 >>= 2508temp0 += 7509object.animationTimer++510object.animationTimer %= 7511DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)512break513514end switch515516switch object.flameAnim517default518case FLAME_INACTIVE519break520521case FLAME_ACTIVE522temp0 = object.flameAnimTimer523temp0 >>= 2524temp0 += 11525object.flameAnimTimer++526object.flameAnimTimer &= 7527DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)528break529530case FLAME_EXPLODE531temp0 = object.flameAnimTimer532temp0 /= 3533temp0 += 11534object.flameAnimTimer++535if object.flameAnimTimer > 21536object.flameAnimTimer = 18537end if538DrawSpriteFX(temp0, FX_FLIP, object.xpos, object.ypos)539break540541end switch542end event543544545event ObjectStartup546LoadSpriteSheet("Global/Eggman.gif")547548// Eggman frames549SpriteFrame(-28, -32, 64, 56, 1, 1)550SpriteFrame(-28, -32, 64, 56, 66, 1)551SpriteFrame(-28, -32, 64, 56, 131, 1)552SpriteFrame(-28, -32, 64, 56, 1, 58)553SpriteFrame(-28, -32, 64, 56, 1, 1)554SpriteFrame(-28, -32, 64, 56, 1, 58)555SpriteFrame(-28, -32, 64, 56, 66, 58)556SpriteFrame(-28, -32, 64, 56, 131, 58)557SpriteFrame(-28, -32, 64, 56, 66, 1)558SpriteFrame(-28, -32, 64, 56, 1, 115)559SpriteFrame(-28, -32, 64, 56, 66, 115)560SpriteFrame(34, 1, 10, 9, 196, 2)561SpriteFrame(33, 0, 15, 11, 196, 12)562SpriteFrame(34, -1, 22, 14, 213, 1)563SpriteFrame(34, -8, 32, 26, 213, 16)564SpriteFrame(34, -1, 22, 14, 213, 1)565SpriteFrame(34, -8, 32, 26, 213, 16)566SpriteFrame(34, 1, 10, 9, 196, 2)567SpriteFrame(33, 0, 15, 11, 196, 12)568569// Setup values570foreach (TypeName[Eggman], arrayPos0, ALL_ENTITIES)571572// Set position points for changing behaviours573// (Think of how he turns after reaching a certain point, etc.)574575// First Node (X only)576temp0 = -0x700000577temp0 += object[arrayPos0].xpos578SetTableValue(temp0, 0, LZEggman_nodePositionTable)579580// Node 1 (X & Y)581temp0 = 0x380000582temp0 += object[arrayPos0].xpos583SetTableValue(temp0, 1, LZEggman_nodePositionTable)584585temp0 = -0xC00000586temp0 += object[arrayPos0].ypos587SetTableValue(temp0, 2, LZEggman_nodePositionTable)588589// Node 2 (X & Y)590temp0 = 0x600000591temp0 += object[arrayPos0].xpos592SetTableValue(temp0, 3, LZEggman_nodePositionTable)593594temp0 = -0x1000000595temp0 += object[arrayPos0].ypos596SetTableValue(temp0, 4, LZEggman_nodePositionTable)597598// Node 3 (Y only)599temp0 = -0x4C00000600temp0 += object[arrayPos0].ypos601SetTableValue(temp0, 5, LZEggman_nodePositionTable)602603// Node 4 (X & Y)604temp0 = 0x13C0000605temp0 += object[arrayPos0].xpos606SetTableValue(temp0, 6, LZEggman_nodePositionTable)607608temp0 = -0x5000000609temp0 += object[arrayPos0].ypos610SetTableValue(temp0, 7, LZEggman_nodePositionTable)611612// Last Node (X & Y)613temp0 = 0xB80000614temp0 += object[arrayPos0].xpos615SetTableValue(temp0, 8, LZEggman_nodePositionTable)616617temp0 = -0x4D00000618temp0 += object[arrayPos0].ypos619SetTableValue(temp0, 9, LZEggman_nodePositionTable)620621// Store the starting position622object[arrayPos0].originPos.x = object[arrayPos0].xpos623object[arrayPos0].originPos.y = object[arrayPos0].ypos624625// Make it in the first animation state626object[arrayPos0].animation = LZEGGANI_IDLE627628#platform: USE_ORIGINS629if game.bossOneLife == false630// It takes 8 hits to drown this egg631object[arrayPos0].health = 8632else633// It takes 2 hits now?634// Normally this cheat only makes it 1, wonder what's up with that...635object[arrayPos0].health = 2636end if637#endplatform638639#platform: USE_STANDALONE640// It takes 8 hits to drown this egg641object[arrayPos0].health = 8642#endplatform643next644645end event646647648// ========================649// Editor Events650// ========================651652event RSDKDraw653DrawSprite(0)654655if editor.showGizmos == true656editor.drawingOverlay = true657658// TODO: draw node path, that'd be cool659660editor.drawingOverlay = false661end if662end event663664665event RSDKLoad666LoadSpriteSheet("Global/Eggman.gif")667SpriteFrame(-28, -32, 64, 56, 1, 1)668669SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")670end event671672673