Path: blob/master/Sonic 2/Scripts/Enemies/Grabber.txt
1480 views
// ----------------------------------1// RSDK Project: Sonic 22// Script Description: Grabber Object3// Script Author: Christian Whitehead/Simon Thomley4// Unpacked by Rubberduckycooly's script unpacker5// ----------------------------------67// ========================8// Aliases9// ========================1011private alias object.value0 : object.startPos.x12private alias object.value1 : object.startPos.y13private alias object.value2 : object.turnTimer14private alias object.value3 : object.timer15private alias object.value4 : object.drawingIndex16private alias object.value6 : object.clampFrame17private alias object.value7 : object.wheelFrame18private alias object.value8 : object.targetPlayer19private alias object.value9 : object.struggleDelay20private alias object.value10 : object.struggleTimer21private alias object.value11 : object.struggleFlags22private alias object.value12 : object.explodeTimer2324// States25private alias 0 : GRABBER_MOVING26private alias 1 : GRABBER_TRYGRAB27private alias 2 : GRABBER_GRABDELAY28private alias 3 : GRABBER_MISSEDGRAB29private alias 4 : GRABBER_GRABBED30private alias 5 : GRABBER_STRUGGLE31private alias 6 : GRABBER_ESCAPED3233// Animations34private alias 0 : GRABBER_ANI_IDLE35private alias 1 : GRABBER_ANI_OPENCLAMP36private alias 2 : GRABBER_ANI_GRABBED3738// Player Aliases39private alias object.state : player.state40private alias object.xpos : player.xpos41private alias object.ypos : player.ypos42private alias object.xvel : player.xvel43private alias object.yvel : player.yvel44private alias object.speed : player.speed45private alias object.direction : player.direction46private alias object.gravity : player.gravity47private alias object.animation : player.animation48private alias object.left : player.left49private alias object.right : player.right50private alias object.value1 : player.timer51private alias object.value40 : player.hitboxLeft52private alias object.value38 : player.hitboxTop53private alias object.value41 : player.hitboxRight54private alias object.value39 : player.hitboxBottom555657// ========================58// Function Declarations59// ========================6061reserve function Grabber_Setup62reserve function Grabber_DebugDraw63reserve function Grabber_DebugSpawn646566// ========================67// Function Definitions68// ========================6970private function Grabber_Setup71object[arrayPos0].xpos = object[arrayPos0].startPos.x72object[arrayPos0].ypos = object[arrayPos0].startPos.y73object[arrayPos0].turnTimer = 25674object[arrayPos0].timer = 075object[arrayPos0].drawingIndex = 076object[arrayPos0].targetPlayer = -177object[arrayPos0].struggleDelay = 078object[arrayPos0].struggleTimer = 079object[arrayPos0].struggleFlags = 080object[arrayPos0].animation = GRABBER_ANI_IDLE81object[arrayPos0].state = GRABBER_MOVING82if object[arrayPos0].propertyValue == 083object[arrayPos0].direction = FLIP_NONE84object[arrayPos0].xvel = -0x400085else86object[arrayPos0].direction = FLIP_X87object[arrayPos0].xvel = 0x400088end if89object[arrayPos0].priority = PRIORITY_BOUNDS90end function919293private function Grabber_DebugDraw94temp0 = object.ypos95temp0 -= 0xC000096DrawSpriteFX(3, FX_FLIP, object.xpos, temp0)97DrawSpriteFX(0, FX_FLIP, object.xpos, object.ypos)98DrawSpriteFX(5, FX_FLIP, object.xpos, object.ypos)99end function100101102private function Grabber_DebugSpawn103CreateTempObject(TypeName[Grabber], temp0, object.xpos, object.ypos)104object[tempObjectPos].startPos.x = object.xpos105object[tempObjectPos].startPos.y = object.ypos106arrayPos0 = object[tempObjectPos].entityPos107object[tempObjectPos].propertyValue = object.direction108CallFunction(Grabber_Setup)109end function110111112// ========================113// Events114// ========================115116event ObjectUpdate117object.priority = PRIORITY_ACTIVE118switch object.state119case GRABBER_MOVING120object.turnTimer--121if object.turnTimer <= 0122object.turnTimer = 256123FlipSign(object.xvel)124object.direction ^= FLIP_X125end if126127object.xpos += object.xvel128129foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)130BoxCollisionTest(C_TOUCH, object.entityPos, -64, 0, 64, 128, currentPlayer, 1, 1, 1, 1)131if checkResult == true132object.state = GRABBER_GRABDELAY133object.timer = 16134end if135next136break137138case GRABBER_GRABDELAY139object.timer--140if object.timer < 0141object.timer = 32142object.state = GRABBER_TRYGRAB143object.animation = GRABBER_ANI_OPENCLAMP144end if145break146147case GRABBER_TRYGRAB148object.timer--149if object.timer < 0150object.state = GRABBER_MISSEDGRAB151end if152153object.ypos += 0x20000154break155156case GRABBER_MISSEDGRAB157object.timer++158if object.timer >= 32159object.timer = 0160object.state = GRABBER_MOVING161object.animation = GRABBER_ANI_IDLE162end if163164object.ypos -= 0x20000165break166167case GRABBER_GRABBED168object.timer++169if object.timer >= 32170object.turnTimer = 1171object.timer = 16172object.animation = GRABBER_ANI_GRABBED173object.state++174end if175176object.ypos -= 0x20000177currentPlayer = object.targetPlayer178player[currentPlayer].xpos = object.xpos179player[currentPlayer].ypos = object.ypos180player[currentPlayer].ypos += 0x100000181break182183case GRABBER_STRUGGLE184if object.targetPlayer != -1185currentPlayer = object.targetPlayer186if object.struggleFlags != 0187object.struggleDelay--188if object.struggleDelay == 0189object.struggleTimer = 0190object.struggleFlags = 0191end if192193temp0 = 0194if player[currentPlayer].left != false195temp0 |= 1196end if197198if player[currentPlayer].right != false199temp0 |= 2200end if201202if temp0 != 0203if temp0 != 3204if temp0 != object.struggleFlags205object.struggleFlags = temp0206object.struggleTimer++207if object.struggleTimer >= 4208#platform: USE_STANDALONE209player[currentPlayer].state = Player_State_Air210#endplatform211#platform: USE_ORIGINS212player[currentPlayer].state = Player_State_Air_NoDropDash213#endplatform214object.targetPlayer = -1215object.explodeTimer = 16216object.state = GRABBER_ESCAPED217else218object.struggleDelay = 32219end if220end if221end if222end if223else224if player[currentPlayer].left != false225object.struggleFlags |= 1226object.struggleDelay = 32227end if228if player[currentPlayer].right != false229object.struggleFlags |= 2230object.struggleDelay = 32231end if232end if233234player[currentPlayer].xpos = object.xpos235player[currentPlayer].ypos = object.ypos236player[currentPlayer].ypos += 0x100000237end if238break239240case GRABBER_ESCAPED241break242243end switch244245if object.outOfBounds == true246temp0 = object.xpos247temp1 = object.ypos248object.xpos = object.startPos.x249object.ypos = object.startPos.y250if object.outOfBounds == true251arrayPos0 = object.entityPos252CallFunction(Grabber_Setup)253else254object.xpos = temp0255object.ypos = temp1256end if257end if258259if object.explodeTimer > 0260object.explodeTimer--261end if262263temp7 = object.targetPlayer264foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)265if currentPlayer != temp7266if object.targetPlayer == -1267if player[currentPlayer].state != Player_State_Static268if object.animation == GRABBER_ANI_OPENCLAMP269BoxCollisionTest(C_TOUCH, object.entityPos, -8, 0, 8, 16, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)270if checkResult == true271object.state = GRABBER_GRABBED272object.animation = GRABBER_ANI_IDLE273object.targetPlayer = currentPlayer274player[currentPlayer].xvel = 0275player[currentPlayer].yvel = 0276player[currentPlayer].speed = 0277player[currentPlayer].timer = 0278player[currentPlayer].state = Player_State_Static279player[currentPlayer].gravity = GRAVITY_AIR280player[currentPlayer].animation = ANI_GRABBED281player[currentPlayer].direction = object.direction282player[currentPlayer].direction ^= FLIP_X283checkResult = true284end if285else286checkResult = false287end if288end if289end if290291if player[currentPlayer].state != Player_State_Static292if object.explodeTimer == 0293if checkResult == false294BoxCollisionTest(C_TOUCH, object.entityPos, -8, -8, 8, 8, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)295if checkResult == true296CallFunction(Player_BadnikBreak)297end if298end if299end if300end if301end if302next303304switch object.animation305case GRABBER_ANI_IDLE306object.frame = 0307object.clampFrame = 5308GetBit(object.wheelFrame, object.turnTimer, 2)309object.wheelFrame += 3310break311312case GRABBER_ANI_OPENCLAMP313object.animationTimer++314object.animationTimer &= 15315object.frame = object.animationTimer316object.frame >>= 3317object.clampFrame = object.frame318object.clampFrame += 5319break320321case GRABBER_ANI_GRABBED322object.turnTimer--323if object.turnTimer == 0324if object.frame == 0325object.frame = 2326else327object.frame = 0328end if329330object.turnTimer = object.timer331object.timer--332if object.timer == 0333if object.targetPlayer != -1334currentPlayer = object.targetPlayer335if player[currentPlayer].state == Player_State_Static336CallFunction(Player_Hit)337if player[currentPlayer].state != Player_State_GotHit338#platform: USE_STANDALONE339player[currentPlayer].state = Player_State_Air340#endplatform341#platform: USE_ORIGINS342player[currentPlayer].state = Player_State_Air_NoDropDash343#endplatform344end if345346object.targetPlayer = -1347temp7 = -1348end if349end if350351ResetObjectEntity(object.entityPos, TypeName[Smoke Puff], 0, object.xpos, object.ypos)352object.drawOrder = 4353PlaySfx(SfxName[Destroy], false)354end if355end if356break357358end switch359360if object.type != TypeName[Grabber]361if temp7 != -1362currentPlayer = temp7363#platform: USE_STANDALONE364player[currentPlayer].state = Player_State_Air365#endplatform366#platform: USE_ORIGINS367player[currentPlayer].state = Player_State_Air_NoDropDash368#endplatform369end if370end if371#platform: USE_ORIGINS372object.drawingIndex = 0 // Added in Origins, prevents Grabber from flickering in 2PVS Splitscreen.373#endplatform374end event375376377event ObjectDraw378if object.drawingIndex == 0379temp0 = object.startPos.y380temp0 -= 0x80000381temp1 = object.ypos382temp1 -= object.startPos.y383temp1 >>= 20384temp1 += 7385DrawSpriteFX(temp1, FX_FLIP, object.xpos, temp0)386temp0 -= 0x40000387DrawSpriteFX(object.wheelFrame, FX_FLIP, object.xpos, temp0)388DrawSpriteFX(object.frame, FX_FLIP, object.xpos, object.ypos)389AddDrawListEntityRef(5, object.entityPos)390else391DrawSpriteFX(object.clampFrame, FX_FLIP, object.xpos, object.ypos)392end if393394object.drawingIndex ^= 1395end event396397398event ObjectStartup399// This sheet's loaded here regardless of the current stage folder, and then the proper sheet is loaded again later anyway...400LoadSpriteSheet("CPZ/Objects.gif")401402CheckCurrentStageFolder("Zone02")403if checkResult == true404LoadSpriteSheet("CPZ/Objects.gif") // Kinda redundant for the reason up above405406// Body Frames407SpriteFrame(-27, -8, 40, 32, 5, 74)408SpriteFrame(-27, -8, 43, 31, 5, 107)409410// Flashing Body Frame411SpriteFrame(-27, -8, 40, 32, 73, 41)412413// Wheel Frames414// They're labelled as "Unused Projectile Frames" in the S2 3.0.1 leftover dev data, but that doesn't seem like quite the right name...415SpriteFrame(-4, -4, 8, 8, 46, 74)416SpriteFrame(-4, -4, 8, 8, 114, 42)417418// Front Clamp Frames419SpriteFrame(-6, 8, 23, 16, 5, 140)420SpriteFrame(-6, 8, 30, 15, 29, 140)421422// String Frames423SpriteFrame(-1, 0, 1, 16, 2, 74)424SpriteFrame(-1, 0, 1, 32, 2, 74)425SpriteFrame(-1, 0, 1, 48, 2, 74)426SpriteFrame(-1, 0, 1, 64, 2, 74)427SpriteFrame(-1, 0, 1, 80, 2, 74)428SpriteFrame(-1, 0, 1, 96, 2, 74)429SpriteFrame(-1, 0, 1, 112, 2, 74)430SpriteFrame(-1, 0, 1, 128, 2, 74)431SpriteFrame(-1, 0, 1, 128, 2, 74)432SpriteFrame(0, 0, 1, 1, 1, 74)433else434LoadSpriteSheet("MBZ/Objects.gif") // Even if the CPZ sheet has been loaded, load the MBZ sheet too435436// Body Frames437SpriteFrame(-27, -8, 40, 32, 131, 280)438SpriteFrame(-27, -8, 43, 31, 172, 280)439440// Flashing Body Frame441SpriteFrame(-27, -8, 40, 32, 217, 280)442443// Wheel Frames444// They're labelled as "Unused Projectile Frames" in the S2 3.0.1 leftover data, but that doesn't seem like quite the right name...445SpriteFrame(-4, -4, 8, 8, 102, 302)446SpriteFrame(-4, -4, 8, 8, 145, 334)447448// Front Clamp Frames449SpriteFrame(-6, 8, 23, 16, 154, 313)450SpriteFrame(-6, 8, 30, 15, 178, 313)451452// String Frames453SpriteFrame(-1, 0, 1, 16, 124, 501)454SpriteFrame(-1, 0, 1, 32, 124, 501)455SpriteFrame(-1, 0, 1, 48, 124, 501)456SpriteFrame(-1, 0, 1, 64, 124, 501)457SpriteFrame(-1, 0, 1, 80, 124, 501)458SpriteFrame(-1, 0, 1, 112, 124, 501)459SpriteFrame(-1, 0, 1, 96, 124, 501)460SpriteFrame(-1, 0, 1, 128, 124, 501)461SpriteFrame(-1, 0, 1, 128, 124, 501)462SpriteFrame(0, 0, 1, 1, 123, 501)463end if464465foreach (TypeName[Grabber], arrayPos0, ALL_ENTITIES)466object[arrayPos0].startPos.x = object[arrayPos0].xpos467object[arrayPos0].startPos.y = object[arrayPos0].ypos468CallFunction(Grabber_Setup)469next470471SetTableValue(TypeName[Grabber], DebugMode_ObjCount, DebugMode_TypesTable)472SetTableValue(Grabber_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)473SetTableValue(Grabber_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)474DebugMode_ObjCount++475end event476477478// ========================479// Editor Events480// ========================481482event RSDKEdit483if editor.returnVariable == true484switch editor.variableID485case EDIT_VAR_PROPVAL // property value486checkResult = object.propertyValue487checkResult &= 1488break489490case 0 // direction491GetBit(checkResult, object.propertyValue, 0)492break493494end switch495else496switch editor.variableID497case EDIT_VAR_PROPVAL // property value498object.propertyValue = editor.variableValue499object.propertyValue &= 1500break501502case 0 // direction503CheckNotEqual(editor.variableValue, false)504SetBit(object.propertyValue, 0, checkResult)505break506507end switch508end if509end event510511512event RSDKDraw513if object.propertyValue == 0514object.direction = FLIP_NONE515else516object.direction = FLIP_X517end if518519temp0 = object.ypos520temp0 -= 0xC0000521DrawSpriteFX(1, FX_FLIP, object.xpos, temp0)522DrawSpriteFX(0, FX_FLIP, object.xpos, object.ypos)523DrawSpriteFX(2, FX_FLIP, object.xpos, object.ypos)524end event525526527event RSDKLoad528CheckCurrentStageFolder("Zone02")529if checkResult == true530LoadSpriteSheet("CPZ/Objects.gif")531SpriteFrame(-27, -8, 40, 32, 5, 74)532SpriteFrame(-4, -4, 8, 8, 46, 74)533SpriteFrame(-6, 8, 23, 16, 5, 140)534else535LoadSpriteSheet("MBZ/Objects.gif")536SpriteFrame(-27, -8, 40, 32, 131, 280)537SpriteFrame(-4, -4, 8, 8, 145, 334)538SpriteFrame(-6, 8, 30, 15, 178, 313)539end if540541AddEditorVariable("direction")542SetActiveVariable("direction")543AddEnumVariable("Left", 0)544AddEnumVariable("Right", 1)545end event546547548