Path: blob/master/Sonic 2/Scripts/Enemies/Crawlton.txt
1483 views
// ----------------------------------1// RSDK Project: Sonic 22// Script Description: Crawlton Object3// Script Author: Christian Whitehead/Simon Thomley4// Unpacked by Rubberduckycooly's script unpacker5// ----------------------------------67// ========================8// Aliases9// ========================1011private alias object.value0 : object.timer12private alias object.value1 : object.extend.length13private alias object.value2 : object.extend.x14private alias object.value3 : object.extend.y15private alias object.value4 : object.head.x16private alias object.value5 : object.head.y17private alias object.value6 : object.target.distance18private alias object.value7 : object.target.entityPos1920// States21private alias 0 : CRAWLTON_AWAITPLAYER22private alias 1 : CRAWLTON_EXTENDDELAY23private alias 2 : CRAWLTON_EXTEND24private alias 3 : CRAWLTON_RETRACTDELAY25private alias 4 : CRAWLTON_RETRACT2627// Player Aliases28private alias object.xpos : player.xpos29private alias object.ypos : player.ypos3031private alias object.value40 : player.hitboxLeft32private alias object.value38 : player.hitboxTop33private alias object.value41 : player.hitboxRight34private alias object.value39 : player.hitboxBottom353637// ========================38// Function Declarations39// ========================4041reserve function Crawlton_DebugDraw42reserve function Crawlton_DebugSpawn43reserve function Crawlton_CheckPlayerDist444546// ========================47// Function Definitions48// ========================4950private function Crawlton_DebugDraw51DrawSpriteFX(0, FX_FLIP, object.xpos, object.ypos)52end function535455private function Crawlton_DebugSpawn56CreateTempObject(TypeName[Crawlton], 0, object.xpos, object.ypos)57end function585960private function Crawlton_CheckPlayerDist61// This function calculates the total distance of player from Crawlton,62// `object.target.distance` is like the function's "return value" of sorts6364temp0 = player[currentPlayer].xpos65temp0 -= object.xpos66temp0 >>= 1667object.target.distance = temp068object.target.distance *= temp06970temp0 = player[currentPlayer].ypos71temp0 -= object.ypos72temp0 >>= 1673temp1 = temp074temp1 *= temp07576object.target.distance += temp177end function787980// ========================81// Events82// ========================8384event ObjectUpdate85switch object.state86case CRAWLTON_AWAITPLAYER87foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)88if object.state == CRAWLTON_AWAITPLAYER // It may seem redundant with the switch-case, but this is making sure a target player hasn't been found already from previous loops of this foreach89if player[currentPlayer].xpos < object.xpos90object.direction = FLIP_NONE91else92object.direction = FLIP_X93end if9495CallFunction(Crawlton_CheckPlayerDist)96if object.target.distance < 0x400097object.target.entityPos = currentPlayer98object.state = CRAWLTON_EXTENDDELAY99end if100end if101next102break103104case CRAWLTON_EXTENDDELAY105currentPlayer = object.target.entityPos106107// Turn to face the target player if needed108if player[currentPlayer].xpos < object.xpos109object.direction = FLIP_NONE110else111object.direction = FLIP_X112end if113114object.timer++115if object.timer == 32116CallFunction(Crawlton_CheckPlayerDist)117if object.target.distance < 0x4000118object.extend.x = player[currentPlayer].xpos119object.extend.x -= object.xpos120object.extend.x /= 0x12000121122object.extend.y = player[currentPlayer].ypos123object.extend.y -= object.ypos124object.extend.y /= 0x12000125else126temp0 = player[currentPlayer].xpos127temp0 -= object.xpos128129temp1 = player[currentPlayer].ypos130temp1 -= object.ypos131132ATan2(temp2, temp0, temp1)133134Cos256(object.extend.x, temp2)135Sin256(object.extend.y, temp2)136137object.extend.x *= 224138object.extend.y *= 224139140object.extend.x >>= 9141object.extend.y >>= 9142end if143144object.timer = 0145object.state = CRAWLTON_EXTEND146end if147break148149case CRAWLTON_EXTEND150if object.extend.length < 0x1C0000151object.extend.length += 0x10000152else153object.state = CRAWLTON_RETRACTDELAY154end if155break156157case CRAWLTON_RETRACTDELAY158object.timer++159if object.timer == 32160object.timer = 0161object.state = CRAWLTON_RETRACT162end if163break164165case CRAWLTON_RETRACT166if object.extend.length > 0167object.extend.length -= 0x10000168else169object.state = CRAWLTON_AWAITPLAYER170end if171break172173end switch174175// Calculate head position176object.head.x = object.extend.x177object.head.x *= object.extend.length178object.head.x /= 28179object.head.x += object.xpos180181object.head.y = object.extend.y182object.head.y *= object.extend.length183object.head.y /= 28184object.head.y += object.ypos185186// Backup the object position and move the object to its head pos for collision checks187temp6 = object.xpos188temp7 = object.ypos189190object.xpos = object.head.x191object.ypos = object.head.y192193foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)194BoxCollisionTest(C_TOUCH, object.entityPos, -10, -8, 10, 8, currentPlayer, player[currentPlayer].hitboxLeft, player[currentPlayer].hitboxTop, player[currentPlayer].hitboxRight, player[currentPlayer].hitboxBottom)195196if checkResult == true197CallFunction(Player_BadnikBreak)198end if199next200201// If the badnik was broken it'd be an Animal object now, which is why this check is here to202// make sure the Freed Animal doesn't teleport203if object.type == TypeName[Crawlton]204// The object is still a Crawlton, it's safe to move it back205object.xpos = temp6206object.ypos = temp7207if object.outOfBounds == true208// Dunno why this condition is here though, if it's just empty209end if210end if211end event212213214event ObjectDraw215// Draw a body piece at the object base regardless of state216DrawSpriteFX(1, FX_FLIP, object.xpos, object.ypos)217218// Then, draw extra body pieces depending on what the Crawlton is doing219switch object.state220case CRAWLTON_EXTEND221temp0 = object.extend.length222temp0 &= 0x3FFFF223while temp0 < object.extend.length224temp1 = object.extend.x225temp1 *= temp0226temp1 /= 28227temp1 += object.xpos228229temp2 = object.extend.y230temp2 *= temp0231temp2 /= 28232temp2 += object.ypos233234DrawSpriteFX(1, FX_FLIP, temp1, temp2)235temp0 += 0x40000236loop237break238239case CRAWLTON_RETRACTDELAY240case CRAWLTON_RETRACT241temp0 = 0x40000242while temp0 < object.extend.length243temp1 = object.extend.x244temp1 *= temp0245temp1 /= 28246temp1 += object.xpos247248temp2 = object.extend.y249temp2 *= temp0250temp2 /= 28251temp2 += object.ypos252253DrawSpriteFX(1, FX_FLIP, temp1, temp2)254temp0 += 0x40000255loop256break257258end switch259260// And draw the head regardless of state too261DrawSpriteFX(0, FX_FLIP, object.head.x, object.head.y)262end event263264265event ObjectStartup266CheckCurrentStageFolder("Zone06")267if checkResult == true268LoadSpriteSheet("MCZ/Objects.gif")269SpriteFrame(-16, -8, 24, 16, 152, 114) // 0 - Head Frame270SpriteFrame(-8, -8, 16, 15, 135, 114) // 1 - Body Frame271else272// Note - even if these are spriteframes for MBZ, they're broken with values copied directly from MCZ's sheet273// Using these sheet positions results in the middle of CPZ's chemical dropper and CNZ's boss electricity274LoadSpriteSheet("MBZ/Objects.gif")275SpriteFrame(-16, -8, 24, 16, 152, 114)276SpriteFrame(-8, -8, 16, 15, 135, 114)277end if278279SetTableValue(TypeName[Crawlton], DebugMode_ObjCount, DebugMode_TypesTable)280SetTableValue(Crawlton_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)281SetTableValue(Crawlton_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)282DebugMode_ObjCount++283end event284285286// ========================287// Editor Events288// ========================289290event RSDKDraw291DrawSpriteFX(1, FX_FLIP, object.xpos, object.ypos)292DrawSpriteFX(0, FX_FLIP, object.xpos, object.ypos)293end event294295296event RSDKLoad297CheckCurrentStageFolder("Zone06")298if checkResult == true299LoadSpriteSheet("MCZ/Objects.gif")300SpriteFrame(-16, -8, 24, 16, 152, 114)301SpriteFrame(-8, -8, 16, 15, 135, 114)302else303LoadSpriteSheet("MBZ/Objects.gif")304// Decomp note - using fixed frames here305SpriteFrame(-16, -8, 24, 16, 534, 289)306SpriteFrame(-8, -8, 16, 15, 559, 289)307end if308309SetVariableAlias(ALIAS_VAR_PROPVAL, "unused")310end event311312313