Path: blob/master/SonicMania/Objects/TMZ/CrimsonEye.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: CrimsonEye Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectCrimsonEye *CrimsonEye;1011void CrimsonEye_Update(void)12{13RSDK_THIS(CrimsonEye);1415StateMachine_Run(self->state);16}1718void CrimsonEye_LateUpdate(void) {}1920void CrimsonEye_StaticUpdate(void) {}2122void CrimsonEye_Draw(void)23{24RSDK_THIS(CrimsonEye);2526StateMachine_Run(self->stateDraw);27}2829void CrimsonEye_Create(void *data)30{31RSDK_THIS(CrimsonEye);3233if (!SceneInfo->inEditor) {34if (globals->gameMode < MODE_TIMEATTACK) {35if (data)36self->type = VOID_TO_INT(data);3738switch (self->type) {39case CRIMSONEYE_CONTAINER:40self->active = ACTIVE_BOUNDS;41self->visible = true;42self->drawGroup = Zone->objectDrawGroup[0] + 1;4344RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 0, &self->animator, true, 0);4546self->updateRange.x = 0x800000;47self->updateRange.y = 0x800000;48CrimsonEye->containerPos.x = self->position.x;49CrimsonEye->containerPos.y = self->position.y - 0xA00000;5051self->state = CrimsonEye_StateContainer_SetupArena;52self->stateDraw = CrimsonEye_Draw_Container;53break;5455case CRIMSONEYE_CORE:56self->active = ACTIVE_NEVER;57self->visible = true;58self->drawGroup = Zone->objectDrawGroup[0] + 1;5960RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &self->animator, true, 0);61self->originPos = self->position;6263self->state = CrimsonEye_StateCore_ContainerActive;64self->stateDraw = CrimsonEye_Draw_Core;6566self->updateRange.x = 0x800000;67self->updateRange.y = 0x800000;68break;6970case CRIMSONEYE_BALL:71self->drawFX = FX_SCALE;72self->active = ACTIVE_NEVER;73self->visible = true;74self->drawGroup = Zone->objectDrawGroup[0] + 1;7576RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 2, &self->animator, true, 0);77self->scale.x = 0x200;78self->scale.y = 0x200;7980self->state = CrimsonEye_StateBall_Spinning;81self->stateDraw = CrimsonEye_Draw_Simple;8283self->updateRange.x = 0x800000;84self->updateRange.y = 0x800000;85break;8687case CRIMSONEYE_ARROW:88self->active = ACTIVE_BOUNDS;89self->visible = true;90self->drawGroup = Zone->objectDrawGroup[0];9192RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 3, &self->animator, true, 0);93self->scale.x = 0x200;94self->scale.y = 0x200;9596self->state = CrimsonEye_State_Arrow;97self->stateDraw = CrimsonEye_Draw_Arrow;9899self->updateRange.x = 0x800000;100self->updateRange.y = 0x800000;101break;102103case CRIMSONEYE_SPIKE:104self->active = ACTIVE_NORMAL;105self->visible = true;106self->drawGroup = Zone->objectDrawGroup[0] + 1;107108RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 2, &self->animator, true, 0);109110self->state = CrimsonEye_StateSpike_Harmful;111self->stateDraw = CrimsonEye_Draw_Simple;112113self->updateRange.x = 0x800000;114self->updateRange.y = 0x800000;115break;116117case CRIMSONEYE_SHOT:118self->active = ACTIVE_NORMAL;119self->visible = true;120self->drawGroup = Zone->objectDrawGroup[0] + 1;121122RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 4, &self->animator, true, 0);123124self->state = CrimsonEye_State_Shot;125self->stateDraw = CrimsonEye_Draw_Simple;126127self->updateRange.x = 0x800000;128self->updateRange.y = 0x800000;129break;130131default: break;132}133}134else {135destroyEntity(self);136}137}138}139140void CrimsonEye_StageLoad(void)141{142CrimsonEye->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/CrimsonEye.bin", SCOPE_STAGE);143144CrimsonEye->hitboxEye.left = -12;145CrimsonEye->hitboxEye.top = -12;146CrimsonEye->hitboxEye.right = 12;147CrimsonEye->hitboxEye.bottom = 12;148149CrimsonEye->hitboxBall.left = -16;150CrimsonEye->hitboxBall.top = -16;151CrimsonEye->hitboxBall.right = 16;152CrimsonEye->hitboxBall.bottom = 16;153154CrimsonEye->hitboxOrb.left = -3;155CrimsonEye->hitboxOrb.top = -3;156CrimsonEye->hitboxOrb.right = 3;157CrimsonEye->hitboxOrb.bottom = 3;158159CrimsonEye->hitboxBlock.left = -21;160CrimsonEye->hitboxBlock.top = -23;161CrimsonEye->hitboxBlock.right = 21;162CrimsonEye->hitboxBlock.bottom = 23;163164CrimsonEye->hitboxElecOrb.left = -6;165CrimsonEye->hitboxElecOrb.top = -6;166CrimsonEye->hitboxElecOrb.right = 6;167CrimsonEye->hitboxElecOrb.bottom = 6;168169CrimsonEye->hitboxUnused1.left = -14;170CrimsonEye->hitboxUnused1.top = -32;171CrimsonEye->hitboxUnused1.right = 14;172CrimsonEye->hitboxUnused1.bottom = -23;173174CrimsonEye->hitboxUnused2.left = -14;175CrimsonEye->hitboxUnused2.top = 23;176CrimsonEye->hitboxUnused2.right = 14;177CrimsonEye->hitboxUnused2.bottom = 32;178179CrimsonEye->health = 17;180CrimsonEye->invincibilityTimer = 0;181CrimsonEye->ballSpinAngleX = 0;182CrimsonEye->ballSpinRadius = 0x4800;183CrimsonEye->ballOffsetY = 0;184CrimsonEye->elevatorSpeed = 0;185CrimsonEye->targetElevatorSpeed = -0x8000;186CrimsonEye->elevatorGravity = 0x800;187CrimsonEye->destroyedBallCount = 0;188CrimsonEye->shotsRemaining = 0;189190CrimsonEye->liftBackground = RSDK.GetTileLayer(RSDK.GetTileLayerID("Lift Background"));191192CrimsonEye->sfxHit = RSDK.GetSfx("Stage/BossHit.wav");193CrimsonEye->sfxExplosion = RSDK.GetSfx("Stage/Explosion2.wav");194CrimsonEye->sfxHover = RSDK.GetSfx("TMZ1/Hover.wav");195CrimsonEye->sfxHover2 = RSDK.GetSfx("TMZ1/Hover2.wav");196CrimsonEye->sfxElevator = RSDK.GetSfx("TMZ1/Elevator.wav");197CrimsonEye->sfxShot = RSDK.GetSfx("Stage/Shot.wav");198CrimsonEye->sfxBeep = RSDK.GetSfx("Stage/Beep4.wav");199CrimsonEye->sfxHullClose = RSDK.GetSfx("Stage/HullClose.wav");200CrimsonEye->sfxButton = RSDK.GetSfx("Stage/Button.wav");201CrimsonEye->sfxImpact = RSDK.GetSfx("Stage/Impact5.wav");202}203204void CrimsonEye_Explode(void)205{206RSDK_THIS(CrimsonEye);207208if (!(Zone->timer & 3)) {209RSDK.PlaySfx(CrimsonEye->sfxExplosion, false, 255);210211int32 x = self->position.x;212int32 y = self->position.y;213214if (CrimsonEye->health) {215x += RSDK.Rand(-32, 33) << 16;216y += RSDK.Rand(-32, 33) << 16;217}218else {219x += RSDK.Rand(-19, 20) << 16;220y += RSDK.Rand(-24, 25) << 16;221}222223EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(((RSDK.Rand(0, 256) > 192) + EXPLOSION_BOSS)), x, y);224explosion->drawGroup = Zone->objectDrawGroup[1] + 2;225}226}227228void CrimsonEye_Hit(void)229{230RSDK_THIS(CrimsonEye);231232if (CrimsonEye->health)233CrimsonEye->health--;234235if (CrimsonEye->health) {236if (CrimsonEye->health == 9) {237CrimsonEye_DestroyBall();238RSDK.PlaySfx(CrimsonEye->sfxExplosion, false, 0xFF);239self->timer = 120;240self->state = CrimsonEye_StateCore_BreakOut;241}242else {243CrimsonEye_DestroyBall();244RSDK.PlaySfx(CrimsonEye->sfxHit, false, 0xFF);245CrimsonEye->invincibilityTimer = 48;246}247}248else {249RSDK.PlaySfx(CrimsonEye->sfxExplosion, false, 0xFF);250self->timer = 120;251252EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);253RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &debris->animator, true, 14);254debris->velocity.x = -0x30000;255debris->velocity.y = -0x40000;256debris->gravityStrength = 0x3800;257debris->drawGroup = Zone->objectDrawGroup[1];258debris->updateRange.x = 0x400000;259debris->updateRange.y = 0x400000;260debris->delay = 120;261262debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);263RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &debris->animator, true, 15);264debris->velocity.x = 0x30000;265debris->velocity.y = -0x40000;266debris->gravityStrength = 0x3800;267debris->drawGroup = Zone->objectDrawGroup[1];268debris->updateRange.x = 0x400000;269debris->updateRange.y = 0x400000;270debris->delay = 120;271272debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);273RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &debris->animator, true, 16);274debris->velocity.x = -0x20000;275debris->velocity.y = -0x20000;276debris->gravityStrength = 0x3800;277debris->drawGroup = Zone->objectDrawGroup[1];278debris->updateRange.x = 0x400000;279debris->updateRange.y = 0x400000;280debris->delay = 120;281282debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);283RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &debris->animator, true, 17);284debris->velocity.x = 0x20000;285debris->velocity.y = -0x20000;286debris->gravityStrength = 0x3800;287debris->drawGroup = Zone->objectDrawGroup[1];288debris->updateRange.x = 0x400000;289debris->updateRange.y = 0x400000;290debris->delay = 120;291292debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);293RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &debris->animator, true, 12);294debris->velocity.x = 0;295debris->velocity.y = -0x30000;296debris->gravityStrength = 0x3800;297debris->drawGroup = Zone->objectDrawGroup[1];298debris->updateRange.x = 0x400000;299debris->updateRange.y = 0x400000;300301debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);302RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &debris->animator, true, 13);303debris->velocity.x = 0;304debris->velocity.y = 0;305debris->gravityStrength = 0x3800;306debris->drawGroup = Zone->objectDrawGroup[1];307debris->updateRange.x = 0x400000;308debris->updateRange.y = 0x400000;309310debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x - 0x160000, self->position.y);311RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &debris->animator, true, 4);312debris->drawFX = FX_ROTATE;313debris->rotation = self->rotation;314debris->velocity.x = -0x20000;315debris->velocity.y = -0x20000;316debris->gravityStrength = 0x3800;317debris->drawGroup = Zone->objectDrawGroup[1];318debris->updateRange.x = 0x400000;319debris->updateRange.y = 0x400000;320321debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x + 0x160000, self->position.y);322RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &debris->animator, true, 5);323debris->drawFX = FX_ROTATE;324debris->rotation = 0x1FF - self->rotation;325debris->velocity.x = 0x20000;326debris->velocity.y = -0x20000;327debris->gravityStrength = 0x3800;328debris->drawGroup = Zone->objectDrawGroup[1];329debris->updateRange.x = 0x400000;330debris->updateRange.y = 0x400000;331332int32 velX = RSDK.Rand(-6, 6) << 15;333int32 velY = RSDK.Rand(-10, -6) << 15;334335debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, CrimsonEye->eyePositions[0].x, CrimsonEye->eyePositions[0].y);336RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &debris->animator, true, 1);337debris->velocity.x = velX;338debris->velocity.y = velY;339debris->gravityStrength = 0x3800;340debris->drawGroup = Zone->objectDrawGroup[1];341debris->updateRange.x = 0x400000;342debris->updateRange.y = 0x400000;343debris->delay = 60;344345debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, CrimsonEye->eyePositions[1].x, CrimsonEye->eyePositions[1].y);346RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &debris->animator, true, 2);347debris->velocity.x = velX;348debris->velocity.y = velY;349debris->gravityStrength = 0x3800;350debris->drawGroup = Zone->objectDrawGroup[1];351debris->updateRange.x = 0x400000;352debris->updateRange.y = 0x400000;353debris->delay = 60;354355debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, CrimsonEye->eyePositions[2].x, CrimsonEye->eyePositions[2].y);356RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &debris->animator, true, 3);357debris->velocity.x = velX;358debris->velocity.y = velY;359debris->gravityStrength = 0x3800;360debris->drawGroup = Zone->objectDrawGroup[1];361debris->updateRange.x = 0x400000;362debris->updateRange.y = 0x400000;363debris->delay = 60;364365SceneInfo->timeEnabled = false;366Player_GiveScore(RSDK_GET_ENTITY(SLOT_PLAYER1, Player), 1000);367self->visible = false;368self->state = CrimsonEye_StateCore_Explode;369}370}371372void CrimsonEye_SetupBG2Layer(void)373{374for (int32 y = 0; y < 48; ++y) {375uint16 tile = RSDK.GetTile(1, 0, y + 24 * (2 - y / 24));376377RSDK.SetTile(1, 0, y, tile);378RSDK.SetTile(1, 31, y, tile);379380for (int32 x = 1; x < 31; ++x) RSDK.SetTile(1, x, y, -1);381}382383TileLayer *bg2Layer = RSDK.GetTileLayer(1);384for (int32 i = 0; i < bg2Layer->scrollInfoCount; ++i) {385bg2Layer->scrollInfo[i].parallaxFactor = 0x200;386bg2Layer->scrollInfo[i].scrollPos = -0x1C0000;387}388389bg2Layer->drawGroup[0] = Zone->hudDrawGroup - 1;390bg2Layer->parallaxFactor = 0x200;391CrimsonEye->bg2Layer = bg2Layer;392393RSDK.SetDrawGroupProperties(Zone->hudDrawGroup - 1, false, CrimsonEye_DrawHook_EnableFGSilhouette);394RSDK.SetDrawGroupProperties(Zone->hudDrawGroup, false, CrimsonEye_DrawHook_DisableFGSilhouette);395}396397// Manages the black strucures that move in the foreground398void CrimsonEye_DrawHook_DisableFGSilhouette(void) { RSDK.SetActivePalette(0, 0, ScreenInfo->size.y); }399void CrimsonEye_DrawHook_EnableFGSilhouette(void) { RSDK.SetActivePalette(5, 0, ScreenInfo->size.y); }400401void CrimsonEye_SetArrowDir(int32 type)402{403foreach_active(CrimsonEye, boss)404{405if (boss->stateDraw == CrimsonEye_Draw_Arrow)406boss->type = type;407}408}409410void CrimsonEye_StateContainer_SetupArena(void)411{412RSDK_THIS(CrimsonEye);413414if (++self->timer >= 2) {415self->timer = 0;416417Zone->playerBoundActiveR[0] = true;418Zone->playerBoundActiveB[0] = true;419Zone->cameraBoundsR[0] = (self->position.x >> 16) + ScreenInfo->center.x + 80;420Zone->cameraBoundsB[0] = (self->position.y >> 16) + 124;421Zone->cameraBoundsT[0] = Zone->cameraBoundsB[0] - ScreenInfo->size.y;422423self->active = ACTIVE_NORMAL;424CREATE_ENTITY(TMZ1Setup, NULL, 0, 0);425426RSDK_GET_ENTITY(SceneInfo->entitySlot + 1, CrimsonEye)->active = ACTIVE_NORMAL;427for (int32 i = 2; i < 14; ++i) {428EntityCrimsonEye *child = RSDK_GET_ENTITY(SceneInfo->entitySlot + i, CrimsonEye);429child->active = ACTIVE_NORMAL;430if (i < 10)431child->angle = 32 * (9 - i);432}433434self->state = CrimsonEye_StateContainer_AwaitPlayer;435}436}437438void CrimsonEye_StateContainer_AwaitPlayer(void)439{440RSDK_THIS(CrimsonEye);441442CrimsonEye->ballSpinAngleX += 4;443444Zone->playerBoundActiveL[0] = true;445Zone->cameraBoundsL[0] = ScreenInfo->position.x;446447EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);448449if (!self->timer && ScreenInfo->position.x + ScreenInfo->center.x > (self->position.x >> 16) - 256) {450CrimsonEye_SetupBG2Layer();451self->timer = 1;452}453454if (player1->position.x > self->position.x - 0x500000) {455Zone->playerBoundActiveL[0] = true;456Zone->cameraBoundsL[0] = (self->position.x >> 16) - ScreenInfo->center.x - 80;457458Music_TransitionTrack(TRACK_MINIBOSS, 0.0125);459RSDK.PlaySfx(CrimsonEye->sfxElevator, false, 255);460461EntityCamera *camera = RSDK_GET_ENTITY(SLOT_CAMERA1, Camera);462if (!camera->shakePos.y)463camera->shakePos.y = 4;464465self->timer = 15;466self->state = CrimsonEye_StateContainer_StartFight;467}468}469470void CrimsonEye_StateContainer_StartFight(void)471{472RSDK_THIS(CrimsonEye);473474CrimsonEye->ballSpinAngleX += 4;475476if (!--self->timer) {477self->stateEye = CrimsonEye_StateEye_EnterBalls;478self->state = CrimsonEye_StateContainer_CoreActive;479}480}481482void CrimsonEye_StateContainer_CoreActive(void)483{484RSDK_THIS(CrimsonEye);485486StateMachine_Run(self->stateEye);487488if (CrimsonEye->elevatorSpeed == CrimsonEye->targetElevatorSpeed && CrimsonEye->elevatorGravity != 0x800 && CrimsonEye->health) {489if (--self->timer == 30) {490RSDK.PlaySfx(CrimsonEye->sfxBeep, false, 255);491492if (CrimsonEye->targetElevatorSpeed) {493CrimsonEye->nextTargetElevatorSpeed = 0;494CrimsonEye_SetArrowDir(CE_ARROW_OFF);495}496else if (RSDK.Rand(0, 3)) {497CrimsonEye->nextTargetElevatorSpeed = -0x80000;498CrimsonEye_SetArrowDir(CE_ARROW_UP);499}500else {501CrimsonEye->nextTargetElevatorSpeed = 0x80000;502CrimsonEye_SetArrowDir(CE_ARROW_DOWN);503}504}505506if (self->timer <= 0) {507RSDK.PlaySfx(CrimsonEye->sfxElevator, false, 255);508509Camera_ShakeScreen(0, 4, 8);510511RSDK.PlaySfx(CrimsonEye->sfxHullClose, false, 255);512513self->timer = RSDK.Rand(120, 180);514CrimsonEye->targetElevatorSpeed = CrimsonEye->nextTargetElevatorSpeed;515516EntityCrimsonEye *child = RSDK_GET_ENTITY(SceneInfo->entitySlot + 1, CrimsonEye);517518if (CrimsonEye->targetElevatorSpeed != -0x80000) {519if (!CrimsonEye->targetElevatorSpeed) {520child->velocity.y = -CrimsonEye->elevatorSpeed;521CrimsonEye->elevatorSpeed = 0;522}523else {524if (CrimsonEye->targetElevatorSpeed == 0x80000)525child->velocity.y = CrimsonEye->elevatorSpeed >> 2;526}527}528else529child->velocity.y = CrimsonEye->elevatorSpeed >> 2;530}531}532533// Same code as CrimsonEye_StateContainer_HandleElevator() but using CrimsonEye->elevatorGravity instead of 0x800534if (CrimsonEye->elevatorSpeed != CrimsonEye->targetElevatorSpeed) {535if (CrimsonEye->elevatorSpeed >= CrimsonEye->targetElevatorSpeed) {536CrimsonEye->elevatorSpeed -= CrimsonEye->elevatorGravity;537538if (CrimsonEye->elevatorSpeed < CrimsonEye->targetElevatorSpeed)539CrimsonEye->elevatorSpeed = CrimsonEye->targetElevatorSpeed;540}541else {542CrimsonEye->elevatorSpeed += CrimsonEye->elevatorGravity;543544if (CrimsonEye->elevatorSpeed > CrimsonEye->targetElevatorSpeed)545CrimsonEye->elevatorSpeed = CrimsonEye->targetElevatorSpeed;546}547}548549for (int32 i = 0; i < PLAYER_COUNT; ++i) {550EntityPlayer *player = RSDK_GET_ENTITY(i, Player);551// NOTE:552// according to IDA, the original code is553// if (player->classID)554// but this crashes the game when super & without a sidekick so this fix will stay555if (player->classID == Player->classID)556player->gravityStrength = 0x3800 - CrimsonEye->elevatorSpeed / 0x30;557}558559TileLayer *elevatorLayer = CrimsonEye->liftBackground;560elevatorLayer->scrollPos = -0x800000;561for (int32 i = 0; i < elevatorLayer->scrollInfoCount; ++i) {562elevatorLayer->scrollInfo[i].scrollSpeed = elevatorLayer->scrollInfo[i].parallaxFactor * (CrimsonEye->elevatorSpeed / 24);563}564565CrimsonEye->bg2Layer->scrollSpeed = 6 * CrimsonEye->elevatorSpeed;566//567568if (CrimsonEye->health == 9)569self->stateEye = StateMachine_None;570571if (CrimsonEye->health == 8 && !self->animator.frameID) {572self->animator.frameID = 1;573self->drawGroup = Zone->objectDrawGroup[0];574575// Destroy Container576EntityDebris *debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);577RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 0, &debris->animator, true, 2);578debris->velocity.x = -0x20000;579debris->velocity.y = -0x20000;580debris->gravityStrength = 0x3800;581debris->drawGroup = Zone->objectDrawGroup[1];582debris->updateRange.x = 0x400000;583debris->updateRange.y = 0x400000;584debris->delay = 60;585586debris = CREATE_ENTITY(Debris, Debris_State_FallAndFlicker, self->position.x, self->position.y);587RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 0, &debris->animator, true, 3);588debris->velocity.x = 0x20000;589debris->velocity.y = -0x20000;590debris->gravityStrength = 0x3800;591debris->drawGroup = Zone->objectDrawGroup[1];592debris->updateRange.x = 0x400000;593debris->updateRange.y = 0x400000;594debris->delay = 60;595}596597if (self->drawGroup > Zone->objectDrawGroup[0]) {598foreach_active(Ring, ring)599{600if (ring->drawGroup == Zone->objectDrawGroup[0])601ring->drawGroup++;602}603}604605if (!CrimsonEye->health) {606CrimsonEye->targetElevatorSpeed = 0;607self->timer = 0;608self->state = CrimsonEye_StateContainer_HandleElevator;609610foreach_active(CrimsonEye, part)611{612if (part->stateDraw == CrimsonEye_Draw_Arrow)613part->type = CE_ARROW_OFF;614}615}616}617618void CrimsonEye_StateContainer_HandleElevator(void)619{620if (CrimsonEye->elevatorSpeed != CrimsonEye->targetElevatorSpeed) {621if (CrimsonEye->elevatorSpeed >= CrimsonEye->targetElevatorSpeed) {622CrimsonEye->elevatorSpeed -= 0x800;623624if (CrimsonEye->elevatorSpeed < CrimsonEye->targetElevatorSpeed)625CrimsonEye->elevatorSpeed = CrimsonEye->targetElevatorSpeed;626}627else {628CrimsonEye->elevatorSpeed += 0x800;629630if (CrimsonEye->elevatorSpeed > CrimsonEye->targetElevatorSpeed)631CrimsonEye->elevatorSpeed = CrimsonEye->targetElevatorSpeed;632}633}634635for (int32 i = 0; i < PLAYER_COUNT; ++i) {636EntityPlayer *player = RSDK_GET_ENTITY(i, Player);637// NOTE:638// according to IDA, the original code is639// if (player->classID)640// but this crashes the game when super & without a sidekick so this fix will stay641if (player->classID == Player->classID)642player->gravityStrength = 0x3800 - CrimsonEye->elevatorSpeed / 0x30;643}644645TileLayer *elevatorLayer = CrimsonEye->liftBackground;646elevatorLayer->scrollPos = -0x800000;647for (int32 i = 0; i < elevatorLayer->scrollInfoCount; ++i) {648elevatorLayer->scrollInfo[i].scrollSpeed = elevatorLayer->scrollInfo[i].parallaxFactor * (CrimsonEye->elevatorSpeed / 24);649}650651CrimsonEye->bg2Layer->scrollSpeed = 6 * CrimsonEye->elevatorSpeed;652}653654void CrimsonEye_StateContainer_Explode(void)655{656RSDK_THIS(CrimsonEye);657658if (self->timer < 48) {659if (!(Zone->timer & 3)) {660RSDK.PlaySfx(ItemBox->sfxDestroy, false, 255);661662int32 x = self->position.x + RSDK.Rand(-0x200000, 0x200000);663int32 y = self->position.y + RSDK.Rand(-0x800000, 0x800000);664EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), x, y);665666explosion->drawGroup = Zone->objectDrawGroup[1] + 2;667}668}669670if (++self->timer == 48) {671Debris_CreateFromEntries(CrimsonEye->aniFrames, CrimsonEye->debrisInfo, 5);672self->visible = false;673Camera_ShakeScreen(0, 0, 4);674self->state = CrimsonEye_StateContainer_MoveElevatorToTMZ2Entry;675}676}677678void CrimsonEye_StateContainer_MoveElevatorToTMZ2Entry(void)679{680if (CrimsonEye->elevatorSpeed != CrimsonEye->targetElevatorSpeed) {681if (CrimsonEye->elevatorSpeed >= CrimsonEye->targetElevatorSpeed) {682CrimsonEye->elevatorSpeed -= 0x800;683684if (CrimsonEye->elevatorSpeed < CrimsonEye->targetElevatorSpeed)685CrimsonEye->elevatorSpeed = CrimsonEye->targetElevatorSpeed;686}687else {688CrimsonEye->elevatorSpeed += 0x800;689690if (CrimsonEye->elevatorSpeed > CrimsonEye->targetElevatorSpeed)691CrimsonEye->elevatorSpeed = CrimsonEye->targetElevatorSpeed;692}693}694695TileLayer *liftLayer = CrimsonEye->liftBackground;696liftLayer->scrollPos = -0x800000;697for (int32 i = 0; i < liftLayer->scrollInfoCount; ++i) {698liftLayer->scrollInfo[i].scrollSpeed = liftLayer->scrollInfo[i].parallaxFactor * (CrimsonEye->elevatorSpeed / 24);699}700701CrimsonEye->bg2Layer->scrollSpeed = 6 * CrimsonEye->elevatorSpeed;702703TileLayer *moveLayer = RSDK.GetTileLayer(Zone->moveLayer);704moveLayer->scrollSpeed = (CrimsonEye->elevatorSpeed / 24) << 6;705}706707void CrimsonEye_Draw_Container(void)708{709RSDK_THIS(CrimsonEye);710711if (!self->animator.frameID && (CrimsonEye->invincibilityTimer & 1))712RSDK.SetPaletteEntry(0, 128, 0xE0E0E0);713714RSDK.DrawSprite(&self->animator, NULL, false);715716RSDK.SetPaletteEntry(0, 128, 0x000000);717}718719void CrimsonEye_StateEye_EnterBalls(void)720{721RSDK_THIS(CrimsonEye);722723CrimsonEye->ballSpinAngleX += 4;724CrimsonEye->ballOffsetY += 0x40000;725726if (CrimsonEye->ballOffsetY >= 0x800000) {727CrimsonEye->ballOffsetY = 0x800000;728self->stateEye = CrimsonEye_StateEye_SpinningBalls;729}730731if (!(Zone->timer % 36))732RSDK.PlaySfx(CrimsonEye->sfxHover, false, 255);733}734735void CrimsonEye_StateEye_SpinningBalls(void)736{737RSDK_THIS(CrimsonEye);738739CrimsonEye->ballSpinAngleX += 4;740741if (++self->ballTimer == 120) {742self->ballTimer = 0;743self->stateEye = CrimsonEye_StateEye_LowerBalls;744}745746if (!(Zone->timer % 36))747RSDK.PlaySfx(CrimsonEye->sfxHover, false, 255);748}749750void CrimsonEye_StateEye_LowerBalls(void)751{752RSDK_THIS(CrimsonEye);753754CrimsonEye->ballSpinAngleX += 4;755CrimsonEye->ballOffsetY += self->velocity.y;756757self->velocity.y += 0x3800;758759if (CrimsonEye->ballOffsetY >= 0xEC0000) {760CrimsonEye->ballOffsetY = 0xEC0000;761762self->velocity.y = (self->velocity.y >> 3) - (self->velocity.y >> 1);763764if (self->velocity.y > -0x10000)765self->stateEye = CrimsonEye_StateEye_LoweredBalls;766}767768if (!(Zone->timer % 36))769RSDK.PlaySfx(CrimsonEye->sfxHover, false, 255);770}771772void CrimsonEye_StateEye_LoweredBalls(void)773{774RSDK_THIS(CrimsonEye);775776CrimsonEye->ballSpinAngleX += 4;777778if (++self->ballTimer == 120) {779self->ballTimer = 0;780self->stateEye = CrimsonEye_StateEye_ExtendBallAttack;781}782783if (!(Zone->timer % 36))784RSDK.PlaySfx(CrimsonEye->sfxHover, false, 255);785}786787void CrimsonEye_StateEye_ExtendBallAttack(void)788{789RSDK_THIS(CrimsonEye);790791CrimsonEye->ballSpinAngleX += 4;792self->ballRadiusTimer = (self->ballRadiusTimer + 1) & 0x7F;793794CrimsonEye->ballSpinRadius = 80 * RSDK.Sin256(self->ballRadiusTimer) + 0x4800;795796if (!self->ballRadiusTimer)797self->stateEye = CrimsonEye_StateEye_FinishExtendAttack;798799if (!(Zone->timer % 36))800RSDK.PlaySfx(CrimsonEye->sfxHover, false, 255);801}802803void CrimsonEye_StateEye_FinishExtendAttack(void)804{805RSDK_THIS(CrimsonEye);806807CrimsonEye->ballSpinAngleX += 4;808809if (++self->ballTimer == 120) {810self->ballTimer = 0;811self->stateEye = CrimsonEye_StateEye_RaiseBalls;812}813814if (!(Zone->timer % 36))815RSDK.PlaySfx(CrimsonEye->sfxHover, false, 255);816}817818void CrimsonEye_StateEye_RaiseBalls(void)819{820RSDK_THIS(CrimsonEye);821822CrimsonEye->ballSpinAngleX += 4;823CrimsonEye->ballOffsetY -= 0x40000;824825if (CrimsonEye->ballOffsetY <= 0x800000) {826CrimsonEye->ballOffsetY = 0x800000;827self->stateEye = CrimsonEye_StateEye_SpinningBalls;828}829830if (!(Zone->timer % 36))831RSDK.PlaySfx(CrimsonEye->sfxHover, false, 255);832}833834void CrimsonEye_ShootShot(void)835{836RSDK_THIS(CrimsonEye);837838EntityCrimsonEye *child = CREATE_ENTITY(CrimsonEye, INT_TO_VOID(CRIMSONEYE_SHOT), self->position.x + 0x260000, self->position.y);839child->velocity.x = 0x280 * RSDK.Cos512(self->rotation);840child->velocity.y = -0x280 * RSDK.Sin512(self->rotation);841child->position.y += self->rotation < 0x100 ? -0x110000 : 0x110000;842843child = CREATE_ENTITY(CrimsonEye, INT_TO_VOID(CRIMSONEYE_SHOT), self->position.x - 0x260000, self->position.y);844child->velocity.x = -0x280 * RSDK.Cos512(self->rotation);845child->velocity.y = -0x280 * RSDK.Sin512(self->rotation);846child->position.y += self->rotation < 0x100 ? -0x110000 : 0x110000;847RSDK.PlaySfx(CrimsonEye->sfxShot, false, 255);848}849850void CrimsonEye_SetupEyePositions(void)851{852RSDK_THIS(CrimsonEye);853854EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);855856// Eyeball857CrimsonEye->eyePositions[0].x = self->position.x;858CrimsonEye->eyePositions[0].y = self->position.y;859860CrimsonEye->eyePositions[0].x += CLAMP(10 * ((player1->position.x - self->position.x) >> 8), -0xC0000, 0xC0000);861CrimsonEye->eyePositions[0].x &= 0xFFFF0000;862863// Eye shine864CrimsonEye->eyePositions[2] = CrimsonEye->eyePositions[0];865866// Iris thingy867CrimsonEye->eyePositions[1] = CrimsonEye->eyePositions[0];868CrimsonEye->eyePositions[1].x += CLAMP(3 * ((player1->position.x - self->position.x) >> 8), -0x30000, 0x30000);869CrimsonEye->eyePositions[1].x &= 0xFFFF0000;870}871872void CrimsonEye_DestroyBall(void)873{874if (CrimsonEye->destroyedBallCount < 8) {875EntityCrimsonEye *child = RSDK_GET_ENTITY(SceneInfo->entitySlot + CrimsonEye->ballDestroyOrder[CrimsonEye->destroyedBallCount], CrimsonEye);876child->state = CrimsonEye_StateBall_Destroyed;877child->timer = 30;878child->drawGroup = Zone->objectDrawGroup[0];879child->scale.y = 0x200;880child->scale.x = 0x200;881882++CrimsonEye->destroyedBallCount;883}884}885886void CrimsonEye_CheckPlayerCollisions(void)887{888RSDK_THIS(CrimsonEye);889890if (CrimsonEye->invincibilityTimer) {891CrimsonEye->invincibilityTimer--;892}893else {894Vector2 storePos = self->position;895foreach_active(Player, player)896{897self->position = CrimsonEye->eyePositions[0];898if (Player_CheckBadnikTouch(player, self, &CrimsonEye->hitboxEye) && Player_CheckBossHit(player, self)) {899self->position = storePos;900CrimsonEye_Hit();901foreach_break;902}903}904self->position = storePos;905}906}907908void CrimsonEye_StateCore_ContainerActive(void)909{910CrimsonEye_SetupEyePositions();911CrimsonEye_CheckPlayerCollisions();912}913914void CrimsonEye_StateCore_BreakOut(void)915{916RSDK_THIS(CrimsonEye);917918CrimsonEye_SetupEyePositions();919CrimsonEye_Explode();920921if (--self->timer <= 0) {922self->timer = 90;923--CrimsonEye->health;924self->drawGroup = Zone->objectDrawGroup[0];925self->state = CrimsonEye_StateCore_BrokenOut;926}927}928929void CrimsonEye_StateCore_BrokenOut(void)930{931RSDK_THIS(CrimsonEye);932933CrimsonEye_SetupEyePositions();934CrimsonEye_Explode();935936if (--self->timer <= 0) {937CrimsonEye->elevatorGravity = 0x4000;938939self->velocity.x = -0x10000;940self->timer = 90;941self->drawGroup = Zone->objectDrawGroup[0] + 1;942self->state = CrimsonEye_StateCore_Hovering;943}944}945946void CrimsonEye_StateCore_Hovering(void)947{948RSDK_THIS(CrimsonEye);949950self->position.x += self->velocity.x;951952if (abs(self->velocity.y) <= 0x10000) {953if (self->originPos.y <= (Zone->cameraBoundsB[0] - 144) << 16) {954self->originPos.y += 0x10000;955956if (self->originPos.y > (Zone->cameraBoundsB[0] - 144) << 16)957self->originPos.y = (Zone->cameraBoundsB[0] - 144) << 16;958}959else {960self->originPos.y -= 0x10000;961962if (self->originPos.y < (Zone->cameraBoundsB[0] - 144) << 16)963self->originPos.y = (Zone->cameraBoundsB[0] - 144) << 16;964}965}966967self->originPos.y -= self->velocity.y;968969self->position.y = BadnikHelpers_Oscillate(self->originPos.y, 2, 10);970if (self->position.x <= (Zone->cameraBoundsL[0] + 64) << 16 || self->position.x >= (Zone->cameraBoundsR[0] - 64) << 16) {971self->velocity.x = -self->velocity.x;972}973974int32 storeY = self->position.y;975self->position.y = self->originPos.y;976977foreach_active(InvisibleBlock, block)978{979int32 side = RSDK.CheckObjectCollisionBox(block, &block->hitbox, self, &CrimsonEye->hitboxBlock, true);980if (side == C_TOP) {981if (self->velocity.y < 0)982self->velocity.y = 0;983984self->rotation = 0x40;985CrimsonEye->shotsRemaining = 8;986CrimsonEye->shotTimer = 15;987988self->state = CrimsonEye_StateCore_ImpactLift;989990RSDK.PlaySfx(CrimsonEye->sfxButton, false, 0xFF);991RSDK.PlaySfx(CrimsonEye->sfxImpact, false, 0xFF);992}993else if (side == C_BOTTOM) {994if (self->velocity.y > 0)995self->velocity.y = 0;996997self->rotation = 0x1C0;998CrimsonEye->shotsRemaining = 8;999CrimsonEye->shotTimer = 15;10001001self->state = CrimsonEye_StateCore_ImpactLift;10021003RSDK.PlaySfx(CrimsonEye->sfxButton, false, 0xFF);1004RSDK.PlaySfx(CrimsonEye->sfxImpact, false, 0xFF);1005}1006}10071008self->originPos.y = self->position.y;1009self->position.y = storeY;10101011CrimsonEye_SetupEyePositions();1012CrimsonEye_CheckPlayerCollisions();10131014if (!(Zone->timer & 0x3F))1015RSDK.PlaySfx(CrimsonEye->sfxHover2, false, 255);1016}10171018void CrimsonEye_StateCore_ImpactLift(void)1019{1020RSDK_THIS(CrimsonEye);10211022if (--CrimsonEye->shotTimer <= 0) {1023CrimsonEye->shotTimer = 15;10241025if (--CrimsonEye->shotsRemaining != 0xFF)1026CrimsonEye_ShootShot();1027else1028self->state = CrimsonEye_StateCore_Hovering;1029}10301031CrimsonEye_SetupEyePositions();1032CrimsonEye_CheckPlayerCollisions();1033}10341035void CrimsonEye_StateCore_Explode(void)1036{1037RSDK_THIS(CrimsonEye);10381039CrimsonEye_Explode();10401041if (--self->timer <= 0) {1042Music_TransitionTrack(TRACK_STAGE, 0.0125);1043self->state = CrimsonEye_StateCore_SpawnSignPost;1044}1045}10461047void CrimsonEye_StateCore_SpawnSignPost(void)1048{1049RSDK_THIS(CrimsonEye);10501051if (++self->timer == 48) {1052foreach_all(SignPost, signPost)1053{1054signPost->position.x = self->position.x;1055signPost->position.y = (ScreenInfo->position.y - 64) << 16;1056signPost->state = SignPost_State_Falling;1057RSDK.PlaySfx(SignPost->sfxTwinkle, false, 255);1058}10591060destroyEntity(self);1061}1062}10631064void CrimsonEye_Draw_Core(void)1065{1066RSDK_THIS(CrimsonEye);10671068if (CrimsonEye->invincibilityTimer & 1)1069RSDK.SetPaletteEntry(0, 128, 0xE0E0E0);10701071if (self->state != CrimsonEye_StateCore_ContainerActive && self->state != CrimsonEye_StateCore_BreakOut) {1072self->animator.frameID = 12;1073RSDK.DrawSprite(&self->animator, NULL, false);10741075self->animator.frameID = 13;1076RSDK.DrawSprite(&self->animator, NULL, false);10771078self->drawFX |= FX_ROTATE;1079Vector2 drawPos = self->position;1080drawPos.x = self->position.x - 0x160000;1081self->animator.frameID = 4;1082RSDK.DrawSprite(&self->animator, &drawPos, false);10831084self->rotation = 0x1FF - self->rotation;1085drawPos.x += 0x2C0000;1086self->animator.frameID = 5;1087RSDK.DrawSprite(&self->animator, &drawPos, false);10881089self->drawFX &= ~FX_ROTATE;1090self->rotation = 0x1FF - self->rotation;1091self->animator.frameID = 0;1092RSDK.DrawSprite(&self->animator, NULL, false);1093}10941095self->animator.frameID = 1;1096RSDK.DrawSprite(&self->animator, &CrimsonEye->eyePositions[0], false);10971098self->animator.frameID = 2;1099RSDK.DrawSprite(&self->animator, &CrimsonEye->eyePositions[1], false);11001101self->inkEffect = INK_ALPHA;1102self->alpha = 0xC0;1103self->animator.frameID = 3;1104RSDK.DrawSprite(&self->animator, &CrimsonEye->eyePositions[2], false);11051106self->inkEffect = INK_NONE;1107RSDK.SetPaletteEntry(0, 128, 0x000000);1108}11091110void CrimsonEye_CheckPlayerCollisions_Ball(void)1111{1112RSDK_THIS(CrimsonEye);11131114foreach_active(Player, player)1115{1116if (Player_CheckCollisionTouch(player, self, &CrimsonEye->hitboxBall)) {1117#if MANIA_USE_PLUS1118if (!Player_CheckMightyUnspin(player, 0x600, 2, &player->uncurlTimer))1119#endif1120Player_Hurt(player, self);1121}1122}1123}11241125void CrimsonEye_StateBall_Spinning(void)1126{1127RSDK_THIS(CrimsonEye);11281129uint8 angle = ((self->angle & 0xFF) + CrimsonEye->ballSpinAngleX);11301131self->position.x = CrimsonEye->ballSpinRadius * RSDK.Cos256(angle) + CrimsonEye->containerPos.x;1132self->position.y = (RSDK.Sin256(CrimsonEye->ballSpinAngleY) << 13) + CrimsonEye->containerPos.y + CrimsonEye->ballOffsetY;11331134if (angle <= 0x80) {1135self->drawGroup = Zone->objectDrawGroup[0];1136self->animator.frameID = 0;1137self->scale.x = 2 * abs(angle - 0x40) + 0x182;1138self->scale.y = 2 * abs(angle - 0x40) + 0x182;1139}1140else {1141self->animator.frameID = 1;1142self->drawGroup = Zone->objectDrawGroup[0] + 1;1143self->scale.x = 2 * (0x13F - abs(angle - 0xC0));1144self->scale.y = 2 * (0x13F - abs(angle - 0xC0));11451146CrimsonEye_CheckPlayerCollisions_Ball();1147}1148}11491150void CrimsonEye_StateBall_Destroyed(void)1151{1152RSDK_THIS(CrimsonEye);11531154self->position.y -= 0x18000;11551156CrimsonEye_CheckPlayerCollisions_Ball();11571158if (--self->timer <= 0) {1159RSDK.PlaySfx(CrimsonEye->sfxExplosion, false, 255);1160CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSS), self->position.x, self->position.y)->drawGroup = Zone->objectDrawGroup[1] + 2;11611162int32 angle = 0;1163for (int32 i = 0; i < 8; ++i) {1164EntityCrimsonEye *spike = CREATE_ENTITY(CrimsonEye, INT_TO_VOID(CRIMSONEYE_SPIKE), self->position.x, self->position.y);1165spike->animator.frameID = i + 2;1166spike->velocity.x = RSDK.Cos256(angle) << 9;1167spike->velocity.y = RSDK.Sin256(angle) << 9;1168angle += 32;1169}11701171destroyEntity(self);1172}1173}11741175void CrimsonEye_Draw_Simple(void)1176{1177RSDK_THIS(CrimsonEye);11781179RSDK.DrawSprite(&self->animator, NULL, false);1180}11811182void CrimsonEye_StateSpike_Harmful(void)1183{1184RSDK_THIS(CrimsonEye);11851186self->position.x += self->velocity.x;1187self->position.y += self->velocity.y;11881189foreach_active(Player, player)1190{1191if (Player_CheckCollisionTouch(player, self, &CrimsonEye->hitboxOrb)) {1192#if MANIA_USE_PLUS1193if (!Player_CheckMightyUnspin(player, 0x600, 2, &player->uncurlTimer))1194#endif1195Player_Hurt(player, self);1196}1197}11981199if (!RSDK.CheckOnScreen(self, &self->updateRange))1200destroyEntity(self);1201}12021203void CrimsonEye_StateSpike_Debris(void)1204{1205RSDK_THIS(CrimsonEye);12061207self->position.x += self->velocity.x;1208self->position.y += self->velocity.y;1209self->velocity.y += 0x3800;12101211self->visible ^= true;12121213if (!RSDK.CheckOnScreen(self, &self->updateRange))1214destroyEntity(self);1215}12161217void CrimsonEye_State_Shot(void)1218{1219RSDK_THIS(CrimsonEye);12201221RSDK.ProcessAnimation(&self->animator);12221223self->position.x += self->velocity.x;1224self->position.y += self->velocity.y;12251226foreach_active(Player, player)1227{1228if (Player_CheckCollisionTouch(player, self, &CrimsonEye->hitboxElecOrb)) {1229Player_ElementHurt(player, self, SHIELD_LIGHTNING);1230}1231}12321233if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x80000, true)1234|| RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_ROOF, 0, 0, -0x80000, true)) {1235self->velocity.y = -self->velocity.y;1236}12371238if (!RSDK.CheckOnScreen(self, &self->updateRange))1239destroyEntity(self);1240}12411242void CrimsonEye_State_Arrow(void)1243{1244// hi poe1245}12461247void CrimsonEye_Draw_Arrow(void)1248{1249RSDK_THIS(CrimsonEye);12501251self->animator.frameID = 0;1252RSDK.DrawSprite(&self->animator, NULL, false);12531254self->animator.frameID = self->type;1255if (self->type != CE_ARROW_OFF)1256RSDK.DrawSprite(&self->animator, NULL, false);1257}12581259#if GAME_INCLUDE_EDITOR1260void CrimsonEye_EditorDraw(void)1261{1262RSDK_THIS(CrimsonEye);12631264switch (self->type) {1265case CRIMSONEYE_CONTAINER:1266self->drawGroup = Zone->objectDrawGroup[0] + 1;12671268RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 0, &self->animator, true, 0);12691270self->updateRange.x = 0x800000;1271self->updateRange.y = 0x800000;1272CrimsonEye->containerPos.x = self->position.x;1273CrimsonEye->containerPos.y = self->position.y - 0xA00000;12741275self->stateDraw = CrimsonEye_Draw_Container;1276break;12771278case CRIMSONEYE_CORE:1279self->drawGroup = Zone->objectDrawGroup[0] + 1;12801281RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 1, &self->animator, true, 0);12821283self->originPos = self->position;1284self->stateDraw = CrimsonEye_Draw_Core;1285self->updateRange.x = 0x800000;1286self->updateRange.y = 0x800000;12871288// Eyeball1289CrimsonEye->eyePositions[0].x = self->position.x & 0xFFFF0000;1290CrimsonEye->eyePositions[0].y = self->position.y;12911292// Iris thingy1293CrimsonEye->eyePositions[1] = CrimsonEye->eyePositions[0];12941295// Eye shine1296CrimsonEye->eyePositions[2] = CrimsonEye->eyePositions[0];1297break;12981299case CRIMSONEYE_BALL:1300self->drawFX = FX_SCALE;1301self->drawGroup = Zone->objectDrawGroup[0] + 1;13021303RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 2, &self->animator, true, 0);1304self->scale.x = 0x200;1305self->scale.y = 0x200;13061307self->stateDraw = CrimsonEye_Draw_Simple;1308self->updateRange.x = 0x800000;1309self->updateRange.y = 0x800000;1310break;13111312case CRIMSONEYE_ARROW:1313self->drawGroup = Zone->objectDrawGroup[0];13141315RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 3, &self->animator, true, 0);1316self->scale.x = 0x200;1317self->scale.y = 0x200;13181319self->stateDraw = CrimsonEye_Draw_Arrow;1320self->updateRange.x = 0x800000;1321self->updateRange.y = 0x800000;1322break;13231324case CRIMSONEYE_SPIKE:1325self->drawGroup = Zone->objectDrawGroup[0] + 1;13261327RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 2, &self->animator, true, 0);13281329self->stateDraw = CrimsonEye_Draw_Simple;1330self->updateRange.x = 0x800000;1331self->updateRange.y = 0x800000;1332break;13331334case CRIMSONEYE_SHOT:1335self->drawGroup = Zone->objectDrawGroup[0] + 1;13361337RSDK.SetSpriteAnimation(CrimsonEye->aniFrames, 4, &self->animator, true, 0);13381339self->stateDraw = CrimsonEye_Draw_Simple;1340self->updateRange.x = 0x800000;1341self->updateRange.y = 0x800000;1342break;13431344default: break;1345}13461347StateMachine_Run(self->stateDraw);13481349if (showGizmos() && self->type == CRIMSONEYE_CONTAINER) {1350RSDK_DRAWING_OVERLAY(true);13511352DrawHelpers_DrawArenaBounds(-WIDE_SCR_XCENTER - 80, -SCREEN_YSIZE, WIDE_SCR_XCENTER + 80, 124, 1 | 2 | 4 | 8, 0x00C0F0);13531354for (int32 s = SceneInfo->entitySlot + 1, i = 0; i < 9; ++i) {1355Entity *child = RSDK_GET_ENTITY_GEN(s + i);1356if (!child)1357continue;13581359DrawHelpers_DrawArrow(self->position.x, self->position.y, child->position.x, child->position.y, 0xE0E0E0, INK_NONE, 0xFF);1360}13611362RSDK_DRAWING_OVERLAY(false);1363}1364}13651366void CrimsonEye_EditorLoad(void)1367{1368CrimsonEye->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/CrimsonEye.bin", SCOPE_STAGE);13691370RSDK_ACTIVE_VAR(CrimsonEye, type);1371RSDK_ENUM_VAR("Container", CRIMSONEYE_CONTAINER);1372RSDK_ENUM_VAR("Core", CRIMSONEYE_CORE);1373RSDK_ENUM_VAR("Ball", CRIMSONEYE_BALL);1374RSDK_ENUM_VAR("Arrow", CRIMSONEYE_ARROW);1375}1376#endif13771378void CrimsonEye_Serialize(void) { RSDK_EDITABLE_VAR(CrimsonEye, VAR_ENUM, type); }137913801381