Path: blob/master/SonicMania/Objects/CPZ/CPZ1Intro.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: CPZ1Intro Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectCPZ1Intro *CPZ1Intro;1011void CPZ1Intro_Update(void)12{13RSDK_THIS(CPZ1Intro);1415if (!self->activated) {16if (!isMainGameMode() || !globals->enableIntro || CutsceneRules_CheckStageReload()) {17destroyEntity(CPZ1Intro->fxRuby);18self->active = ACTIVE_NEVER;19}20else {21self->activated = true;22CPZ1Intro_SetupCutscene();23}24}25}2627void CPZ1Intro_LateUpdate(void) {}2829void CPZ1Intro_StaticUpdate(void) {}3031void CPZ1Intro_Draw(void) {}3233void CPZ1Intro_Create(void *data)34{35RSDK_THIS(CPZ1Intro);3637INIT_ENTITY(self);38CutsceneRules_SetupEntity(self, &self->size, &self->hitbox);39self->active = ACTIVE_NORMAL;40}4142void CPZ1Intro_StageLoad(void)43{44CPZ1Intro->playerFrames = RSDK.LoadSpriteAnimation("Players/CutsceneCPZ.bin", SCOPE_STAGE);45CPZ1Intro->particleFrames = RSDK.LoadSpriteAnimation("CPZ/Particles.bin", SCOPE_STAGE);4647foreach_all(FXRuby, fxRuby)48{49CPZ1Intro->fxRuby = fxRuby;50foreach_break;51}5253CPZ1Intro->sfxChemDrop = RSDK.GetSfx("CPZ/ChemDrop.wav");54CPZ1Intro->sfxDNABurst = RSDK.GetSfx("CPZ/DNABurst.wav");55}5657void CPZ1Intro_SetupCutscene(void)58{59RSDK_THIS(CPZ1Intro);6061CutsceneSeq_StartSequence(self, CPZ1Intro_Cutscene_RubyWarp, CPZ1Intro_Cutscene_PostWarpDrop, CPZ1Intro_Cutscene_Waiting,62CPZ1Intro_Cutscene_ChemicalDrop, CPZ1Intro_Cutscene_PlayerChemicalReact, CPZ1Intro_Cutscene_ReadyStage,63StateMachine_None);6465#if MANIA_USE_PLUS66CutsceneSeq_SetSkipType(SKIPTYPE_RELOADSCN);67#endif68}6970void CPZ1Intro_Particle_ChemDrop(EntityDebris *debris)71{72debris->velocity.y += RSDK.Rand(-0x28000, -0x20000);73RSDK.SetSpriteAnimation(CPZ1Intro->particleFrames, 1, &debris->animator, true, 0);74}7576void CPZ1Intro_HandleRubyHover(EntityCutsceneSeq *cutsceneSequence, EntityPlayer *player1, EntityPlayer *player2, int32 targetY)77{78EntityPlayer *players[2];79players[0] = player1;80players[1] = player2;8182int32 id = 0;83for (int32 angle = 0; angle < 0x80; angle += 0x40) {84EntityPlayer *player = players[id++];85if (!player)86break;8788int32 velX = (player->position.x - player->position.x) >> 3;89int32 velY = (targetY + 0xA00 * RSDK.Sin256(2 * (angle + cutsceneSequence->timer - cutsceneSequence->storedTimer)) - player->position.y) >> 3;90player->position.x += velX;91player->position.y += velY;92RSDK.SetSpriteAnimation(player->aniFrames, ANI_FAN, &player->animator, false, 0);93player->state = Player_State_Static;94}95}9697bool32 CPZ1Intro_CheckSonicAnimFinish(void)98{99MANIA_GET_PLAYER(player1, player2, camera);100UNUSED(player2);101UNUSED(camera);102103return player1->animator.frameID == player1->animator.frameCount - 1 && player1->animator.timer == 30;104}105106bool32 CPZ1Intro_CheckTailsAnimFinish(int32 timer)107{108MANIA_GET_PLAYER(player1, player2, camera);109UNUSED(player2);110UNUSED(camera);111112#if MANIA_USE_PLUS113if (player1->animator.frameID == player1->animator.frameCount - 1 && player1->animator.timer == 4) {114RSDK.SetSpriteAnimation(player1->tailFrames, ANI_IDLE, &player1->tailAnimator, true, 0);115player1->animator.animationID = 0;116player1->animator.prevAnimationID = 0;117return true;118}119#else120// Same Code as 2P AI, it's unknown why tails' anim was cut in pre-plus, but it's in plus so hooray121if (timer == 60) {122RSDK.SetSpriteAnimation(player1->aniFrames, ANI_IDLE, &player1->animator, true, 0);123player1->up = false;124return true;125}126#endif127return false;128}129130bool32 CPZ1Intro_CheckKnuxAnimFinish(void)131{132MANIA_GET_PLAYER(player1, player2, camera);133UNUSED(player2);134UNUSED(camera);135136return player1->animator.frameID == player1->animator.frameCount - 1 && player1->animator.timer == 4;137}138139#if MANIA_USE_PLUS140bool32 CPZ1Intro_CheckMightyAnimFinish(void)141{142MANIA_GET_PLAYER(player1, player2, camera);143UNUSED(player2);144UNUSED(camera);145146return player1->animator.frameID == player1->animator.frameCount - 1 && player1->animator.timer == 4;147}148149bool32 CPZ1Intro_CheckRayAnimFinish(void)150{151MANIA_GET_PLAYER(player1, player2, camera);152UNUSED(player2);153UNUSED(camera);154155return player1->animator.frameID == player1->animator.frameCount - 1 && player1->animator.timer == 4;156}157#endif158159bool32 CPZ1Intro_Cutscene_RubyWarp(EntityCutsceneSeq *host)160{161MANIA_GET_PLAYER(player1, player2, camera);162163EntityFXRuby *fxRuby = CPZ1Intro->fxRuby;164if (!host->timer) {165player1->camera = NULL;166camera->position.y -= 0x40000;167camera->target = 0;168player1->stateInput = StateMachine_None;169CutsceneSeq_LockAllPlayerControl();170player1->velocity.x = 0;171player1->velocity.y = 0;172player1->onGround = false;173if (player2->classID == Player->classID) {174player2->position.x -= 0x80000;175player2->velocity.x = 0;176player2->velocity.y = 0;177player2->onGround = false;178player2->stateInput = StateMachine_None;179}180}181182camera->state = StateMachine_None;183if (fxRuby->fadeBlack > 0) {184fxRuby->fadeBlack -= 16;185}186else {187if (fxRuby->fadeWhite > 0) {188fxRuby->fadeWhite -= 16;189}190else {191if (!host->values[0]) {192PhantomRuby_PlaySfx(RUBYSFX_ATTACK4);193host->values[0] = 1;194fxRuby->state = FXRuby_State_Shrinking;195}196197if (!fxRuby->outerRadius) {198player1->state = Player_State_Air;199if (player2->classID == Player->classID)200player2->state = Player_State_Air;201fxRuby->active = ACTIVE_NEVER;202return true;203}204}205}206207CPZ1Intro_HandleRubyHover(host, player1, player2, host->activeEntity->position.y - 0x200000);208209return false;210}211212bool32 CPZ1Intro_Cutscene_PostWarpDrop(EntityCutsceneSeq *host)213{214MANIA_GET_PLAYER(player1, player2, camera);215UNUSED(host);216UNUSED(camera);217218if (player2->classID == Player->classID) {219if (player1->onGround && player2->onGround)220return true;221}222else {223if (player1->onGround)224return true;225}226227return false;228}229230bool32 CPZ1Intro_Cutscene_Waiting(EntityCutsceneSeq *host)231{232MANIA_GET_PLAYER(player1, player2, camera);233UNUSED(camera);234235if (!host->timer) {236player1->state = Player_State_Static;237if (player2->classID == Player->classID) {238player2->state = Player_State_Static;239RSDK.SetSpriteAnimation(player2->aniFrames, ANI_IDLE, &player2->animator, true, 0);240}241}242243if (host->timer == 30) {244if (CHECK_CHARACTER_ID(ID_SONIC, 1))245RSDK.SetSpriteAnimation(player1->aniFrames, ANI_BORED_2, &player1->animator, false, 0);246else247RSDK.SetSpriteAnimation(player1->aniFrames, ANI_BORED_1, &player1->animator, false, 0);248}249250return host->timer == 60;251}252253bool32 CPZ1Intro_Cutscene_ChemicalDrop(EntityCutsceneSeq *host)254{255MANIA_GET_PLAYER(player1, player2, camera);256UNUSED(camera);257258if (!host->timer) {259RSDK.PlaySfx(CPZ1Intro->sfxChemDrop, false, 255);260EntityDebris *debris = CREATE_ENTITY(Debris, NULL, player1->position.x + 0x20000, (ScreenInfo->position.y - 8) << 16);261debris->updateRange.x = 0x800000;262debris->updateRange.y = 0x800000;263debris->active = ACTIVE_NORMAL;264debris->drawGroup = Zone->playerDrawGroup[1];265debris->state = Debris_State_Fall;266debris->gravityStrength = 0x3800;267RSDK.SetSpriteAnimation(CPZ1Intro->particleFrames, 0, &debris->animator, true, 0);268CPZ1Intro->debris = debris;269}270271EntityDebris *debris = CPZ1Intro->debris;272Hitbox *playerHitbox = Player_GetHitbox(player1);273274int32 playerY = player1->position.y + ((playerHitbox->top + 2) << 16);275if (debris->position.y >= playerY) {276RSDK.PlaySfx(CPZ1Intro->sfxDNABurst, false, 255);277ParticleHelpers_SetupFallingParticles(debris->position.x, playerY, CPZ1Intro_Particle_ChemDrop);278destroyEntity(debris);279280if (CHECK_CHARACTER_ID(ID_TAILS, 2))281RSDK.SetSpriteAnimation(player2->aniFrames, ANI_SKID, &player2->animator, true, 0);282283return true;284}285286return false;287}288289bool32 CPZ1Intro_Cutscene_PlayerChemicalReact(EntityCutsceneSeq *host)290{291MANIA_GET_PLAYER(player1, player2, camera);292UNUSED(camera);293294if (!host->timer) {295switch (GET_CHARACTER_ID(1)) {296case ID_SONIC:297CPZ1Intro->playerAnimID = 0;298player1->state = Player_State_Static;299player1->tileCollisions = TILECOLLISION_NONE;300RSDK.SetSpriteAnimation(CPZ1Intro->playerFrames, CPZ1Intro->playerAnimID, &player1->animator, true, 0);301break;302303case ID_TAILS: CPZ1Intro->playerAnimID = 1;304#if MANIA_USE_PLUS305player1->state = Player_State_Static;306player1->tileCollisions = TILECOLLISION_NONE;307RSDK.SetSpriteAnimation(CPZ1Intro->playerFrames, CPZ1Intro->playerAnimID, &player1->animator, true, 0);308RSDK.SetSpriteAnimation(-1, 0, &player1->tailAnimator, true, 0);309player1->animator.animationID = 0xFF;310player1->animator.prevAnimationID = 0xFF;311#else312// Same Code as 2P AI, it's unknown why tails' anim was cut in pre-plus, but it's in plus so hooray313RSDK.SetSpriteAnimation(player1->aniFrames, ANI_LOOK_UP, &player1->animator, true, 0);314player1->up = true;315player1->state = Player_State_LookUp;316#endif317318break;319case ID_KNUCKLES:320CPZ1Intro->playerAnimID = 2;321player1->state = Player_State_Static;322player1->tileCollisions = TILECOLLISION_NONE;323RSDK.SetSpriteAnimation(CPZ1Intro->playerFrames, CPZ1Intro->playerAnimID, &player1->animator, true, 0);324break;325326#if MANIA_USE_PLUS327case ID_MIGHTY:328CPZ1Intro->playerAnimID = 3;329player1->state = Player_State_Static;330player1->tileCollisions = TILECOLLISION_NONE;331RSDK.SetSpriteAnimation(CPZ1Intro->playerFrames, CPZ1Intro->playerAnimID, &player1->animator, true, 0);332break;333334case ID_RAY:335CPZ1Intro->playerAnimID = 4;336RSDK.SetSpriteAnimation(CPZ1Intro->playerFrames, CPZ1Intro->playerAnimID, &player1->animator, true, 0);337player1->state = Player_State_Static;338player1->tileCollisions = TILECOLLISION_NONE;339break;340#endif341}342}343344if (host->timer == 60 && player2->classID == Player->classID) {345RSDK.SetSpriteAnimation(player2->aniFrames, ANI_LOOK_UP, &player2->animator, true, 0);346player2->up = true;347player2->state = Player_State_LookUp;348}349350switch (CPZ1Intro->playerAnimID) {351case 0: return CPZ1Intro_CheckSonicAnimFinish();352case 1: return CPZ1Intro_CheckTailsAnimFinish(host->timer);353case 2: return CPZ1Intro_CheckKnuxAnimFinish();354#if MANIA_USE_PLUS355case 3: return CPZ1Intro_CheckMightyAnimFinish();356case 4: return CPZ1Intro_CheckRayAnimFinish();357#endif358default: break;359}360361return false;362}363364bool32 CPZ1Intro_Cutscene_ReadyStage(EntityCutsceneSeq *host)365{366MANIA_GET_PLAYER(player1, player2, camera);367368if (!host->timer) {369RSDK.SetSpriteAnimation(player1->aniFrames, ANI_IDLE, &player1->animator, true, 0);370371if (player2->classID == Player->classID) {372RSDK.SetSpriteAnimation(player2->aniFrames, ANI_IDLE, &player2->animator, true, 0);373player2->up = false;374}375}376377if (host->timer == 30) {378player1->stateInput = Player_Input_P1;379player1->tileCollisions = TILECOLLISION_DOWN;380player1->onGround = true;381player1->state = Player_State_Ground;382player1->camera = camera;383camera->target = (Entity *)player1;384camera->state = Camera_State_FollowXY;385if (player2->classID == Player->classID) {386player2->stateInput = Player_Input_P2_AI;387player2->tileCollisions = TILECOLLISION_DOWN;388player2->onGround = true;389player2->state = Player_State_Ground;390}391392foreach_all(TitleCard, titlecard)393{394titlecard->active = ACTIVE_NORMAL;395titlecard->state = TitleCard_State_SetupBGElements;396titlecard->stateDraw = TitleCard_Draw_SlideIn;397Music_PlayTrack(TRACK_STAGE);398foreach_break;399}400401return true;402}403404return false;405}406407#if GAME_INCLUDE_EDITOR408void CPZ1Intro_EditorDraw(void)409{410RSDK_THIS(CPZ1Intro);411CutsceneRules_DrawCutsceneBounds(self, &self->size);412}413414void CPZ1Intro_EditorLoad(void) {}415#endif416417void CPZ1Intro_Serialize(void) { RSDK_EDITABLE_VAR(CPZ1Intro, VAR_VECTOR2, size); }418419420