Path: blob/master/SonicMania/Objects/Puyo/PuyoGame.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: PuyoGame Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"8#include <time.h>910ObjectPuyoGame *PuyoGame;1112void PuyoGame_Update(void)13{14RSDK_THIS(PuyoGame);1516if (!self->started) {17PuyoGame_SetupStartingEntities();18self->started = true;19}2021StateMachine_Run(self->state);2223RSDK.ProcessAnimation(&self->animator);2425if ((ControllerInfo->keyStart.press || Unknown_pausePress) && !RSDK_GET_ENTITY(SLOT_PAUSEMENU, PauseMenu)->classID) {26RSDK.ResetEntitySlot(SLOT_PAUSEMENU, PauseMenu->classID, NULL);27RSDK_GET_ENTITY(SLOT_PAUSEMENU, PauseMenu)->disableRestart = true;28RSDK.PlaySfx(PauseMenu->sfxAccept, false, 0xFF);29RSDK.SetEngineState(ENGINESTATE_FROZEN);30}31}3233void PuyoGame_LateUpdate(void) {}3435void PuyoGame_StaticUpdate(void) {}3637void PuyoGame_Draw(void) {}3839void PuyoGame_Create(void *data)40{41RSDK_THIS(PuyoGame);4243self->active = ACTIVE_NORMAL;44self->drawGroup = Zone->objectDrawGroup[0];45self->startPos = self->position;46self->visible = false;47self->drawFX = FX_FLIP;48self->updateRange.x = 0x800000;49self->updateRange.y = 0x800000;5051if (!SceneInfo->inEditor)52RSDK.AddCamera(&self->position, ScreenInfo->center.x << 16, ScreenInfo->center.y << 16, true);5354self->state = PuyoGame_State_Init;55}5657void PuyoGame_StageLoad(void)58{59PuyoGame->aniFrames = RSDK.LoadSpriteAnimation("Puyo/PuyoBeans.bin", SCOPE_STAGE);6061foreach_all(FXFade, fxFade) { PuyoGame->fxFade = fxFade; }6263String text;64Localization_GetString(&text, STR_RPC_PLAYING);65API_SetRichPresence(PRESENCE_GENERIC, &text);66destroyEntitySlot(SLOT_ZONE);67}6869void PuyoGame_SetupStartingEntities(void)70{71RSDK_THIS(PuyoGame);7273EntityMenuParam *param = MenuParam_GetParam();74EntityCompetitionSession *session = CompetitionSession_GetSession();7576ScreenInfo->position.x = (self->position.x >> 16) - ScreenInfo->center.x;77ScreenInfo->position.y = (self->position.y >> 16) - ScreenInfo->center.y;7879foreach_all(PuyoScore, score)80{81int32 playerID = score->playerID;82if (score->counter) {83PuyoGame->score2[playerID] = score;8485if (param->puyoSelection == PUYO_SELECTION_TIE_BREAKER)86score->score = session->wins[playerID];87}88else {89PuyoGame->score1[playerID] = score;90}91}9293foreach_all(PuyoLevelSelect, levelSel) { PuyoGame->levelSel[levelSel->playerID] = levelSel; }9495if (param->puyoSelection == PUYO_SELECTION_TIE_BREAKER) {96self->selectedLevels[0] = 1;97self->selectedLevels[1] = 1;98self->state = PuyoGame_State_SetupRound;99}100else {101self->state = PuyoGame_State_SelectingLevel;102}103}104105void PuyoGame_SetLoser(uint8 loser)106{107RSDK_THIS(PuyoGame);108109EntityPuyoMatch *manager = PuyoGame->managers[loser];110EntityCollapsingPlatform *platform = PuyoGame->platforms[loser];111112int32 winner = loser ^ 1;113self->determinedLoser = true;114self->roundWinner = winner;115platform->stoodPos.x = manager->position.x;116manager->timer = 7;117PuyoAI->isAI[0] = false;118PuyoAI->isAI[1] = false;119120EntityPuyoMatch *foeManager = PuyoGame->managers[winner];121EntityPuyoScore *foeScore = PuyoGame->score2[winner];122++foeScore->score;123foeScore->flashing = true;124foeManager->state = StateMachine_None;125126PuyoBean_DestroyPuyoBeans();127PuyoGame_CheckMatchFinish();128129self->timer = 0;130self->state = self->finishedMatch ? PuyoGame_State_ShowMatchResults : PuyoGame_State_ShowRoundResults;131}132133void PuyoGame_DestroyPuyoBeans(void)134{135foreach_all(PuyoBean, bean) { destroyEntity(bean); }136}137138void PuyoGame_SetupGameState(void)139{140int32 fgHighRebuild = RSDK.GetTileLayerID("FG High Rebuild");141int32 fgHigh = RSDK.GetTileLayerID("FG High");142143RSDK.CopyTileLayer(fgHigh, 0, 0, fgHighRebuild, 0, 0, 32, 16);144145EntityPuyoScore *scoreP1 = PuyoGame->score2[0];146EntityPuyoScore *scoreP2 = PuyoGame->score2[1];147148PuyoBean->comboChainCount[0] = 0;149PuyoBean->disableBeanLink[0] = false;150scoreP1->flashing = false;151152PuyoBean->comboChainCount[1] = 0;153PuyoBean->disableBeanLink[1] = false;154scoreP2->flashing = false;155156for (int32 i = 0; i < 0x100; ++i) PuyoBean->playfield[i] = NULL;157158foreach_all(PuyoMatch, match)159{160match->score = 0;161match->comboScore = 0;162match->comboCount = 0;163match->comboBeanCount = 0;164match->comboBonusTable = PuyoMatch->comboBonus;165match->concurrentBonus = 0;166match->beanBonus = 0;167match->timer = false;168match->junkDropCount = 0;169match->junkBeanCount = 0;170171PuyoGame->score1[0]->score = match->score;172}173174foreach_all(CollapsingPlatform, platform) { platform->stoodPos.x = 0; }175}176177void PuyoGame_CheckMatchFinish(void)178{179RSDK_THIS(PuyoGame);180181EntityPuyoScore *scoreP1 = PuyoGame->score2[0];182EntityPuyoScore *scoreP2 = PuyoGame->score2[1];183184int32 score = MAX(scoreP1->score, scoreP2->score);185186if (score >= 2) {187self->matchWinner = scoreP1->score <= scoreP2->score;188self->finishedMatch = true;189PuyoGame->indicators[self->matchWinner]->state = PuyoIndicator_ShowWinner;190PuyoGame->indicators[self->matchWinner ^ 1]->state = PuyoIndicator_ShowLoser;191}192}193194void PuyoGame_State_Init(void)195{196RSDK_THIS(PuyoGame);197198self->state = PuyoGame_State_Wait;199}200201void PuyoGame_State_Wait(void)202{203// Gaming(?)204}205206void PuyoGame_State_SelectingLevel(void)207{208RSDK_THIS(PuyoGame);209210EntityMenuParam *param = MenuParam_GetParam();211212EntityPuyoLevelSelect *levelSelP1 = PuyoGame->levelSel[0];213EntityPuyoLevelSelect *levelSelP2 = PuyoGame->levelSel[1];214215levelSelP1->canSelectLevels = true;216if (param->puyoSelection == PUYO_SELECTION_VS_CPU || param->puyoSelection == PUYO_SELECTION_NONE)217levelSelP2->ready = true;218219levelSelP2->canSelectLevels = true;220221if (levelSelP1->ready && levelSelP2->ready) {222levelSelP1->canSelectLevels = false;223levelSelP2->canSelectLevels = false;224self->selectedLevels[0] = levelSelP1->optionID;225self->selectedLevels[1] = levelSelP2->optionID;226self->state = PuyoGame_State_SetupRound;227}228}229230void PuyoGame_State_SetupRound(void)231{232RSDK_THIS(PuyoGame);233234if (self->timer >= 60) {235self->timer = 0;236self->state = PuyoGame_State_SetupEntities;237}238else {239if (!self->timer) {240PuyoGame_SetupGameState();241foreach_all(PuyoIndicator, indicator) { indicator->state = PuyoIndicator_ShowReady; }242int32 key = (int32)time(NULL);243int32 matchKey = RSDK.RandSeeded(0, 512, &key);244245foreach_all(PuyoMatch, match)246{247RSDK.SetSpriteAnimation(-1, 0, &match->beanLAnimator, true, 0);248RSDK.SetSpriteAnimation(-1, 0, &match->beanRAnimator, true, 0);249match->active = ACTIVE_NORMAL;250match->matchKey = matchKey;251match->selectedLevel = self->selectedLevels[match->playerID];252PuyoMatch_SetupNextBeans(match);253}254}255256++self->timer;257}258}259260void PuyoGame_State_SetupEntities(void)261{262RSDK_THIS(PuyoGame);263264EntityMenuParam *param = MenuParam_GetParam();265266self->determinedLoser = false;267self->roundWinner = 0;268269int32 matchID = 0;270foreach_all(PuyoMatch, match)271{272match->timer = true;273match->active = ACTIVE_NORMAL;274match->state = PuyoMatch_State_HandleMatch;275276if (match->playerID) {277if (param->puyoSelection == PUYO_SELECTION_VS_CPU || param->puyoSelection == PUYO_SELECTION_NONE) {278match->stateInput = PuyoAI_Input_AI;279PuyoAI->lastBeanY[match->playerID] = PUYO_PLAYFIELD_H;280PuyoAI->desiredColumn[match->playerID] = 0;281PuyoAI->desiredRotation[match->playerID] = 0;282PuyoAI->isAI[match->playerID] = true;283PuyoAI->controlInterval[match->playerID] = PuyoAI->controlIntervals[self->selectedLevels[0]];284PuyoAI->controlChance[match->playerID] = PuyoAI->controlChances[self->selectedLevels[0]];285}286}287288PuyoGame->managers[matchID++] = match;289}290291int32 indicatorID = 0;292foreach_all(PuyoIndicator, indicator)293{294indicator->state = StateMachine_None;295PuyoGame->indicators[indicatorID++] = indicator;296}297298int32 platformID = 0;299foreach_all(CollapsingPlatform, platform) { PuyoGame->platforms[platformID++] = platform; }300301self->state = PuyoGame_State_HandleRound;302PuyoGame_State_HandleRound();303}304305void PuyoGame_State_HandleRound(void)306{307for (int32 p = 0; p < 2; ++p) {308EntityPuyoMatch *match = PuyoGame->managers[p];309310PuyoGame->score1[p]->score = match->score;311if (match->state == PuyoMatch_State_Lose)312PuyoGame_SetLoser(p);313}314}315316void PuyoGame_State_ShowRoundResults(void)317{318RSDK_THIS(PuyoGame);319EntityMenuParam *param = MenuParam_GetParam();320321if (self->timer >= 60) {322int32 count = param->puyoSelection >= PUYO_SELECTION_VS_2P ? 2 : 1;323bool32 buttonPressed = false;324325RSDKControllerState *controller = &ControllerInfo[CONT_P1];326for (int32 i = 0; i < count; ++i) {327buttonPressed |= controller[i].keyA.down || controller[i].keyB.down || controller[i].keyC.down || controller[i].keyX.down328|| controller[i].keyY.down || controller[i].keyZ.down;329}330331if (buttonPressed) {332PuyoGame_DestroyPuyoBeans();333self->timer = 0;334self->state = PuyoGame_State_SetupRound;335}336}337else {338self->timer++;339}340}341342void PuyoGame_State_ShowMatchResults(void)343{344RSDK_THIS(PuyoGame);345346EntityMenuParam *param = MenuParam_GetParam();347348if (self->timer >= 60) {349int32 count = param->puyoSelection >= PUYO_SELECTION_VS_2P ? 2 : 1;350bool32 buttonPressed = false;351352RSDKControllerState *controller = &ControllerInfo[CONT_P1];353for (int32 i = 0; i < count; ++i) {354buttonPressed |= controller[i].keyA.down || controller[i].keyB.down || controller[i].keyC.down || controller[i].keyX.down355|| controller[i].keyY.down || controller[i].keyZ.down;356}357358if (buttonPressed) {359EntityFXFade *fxFade = PuyoGame->fxFade;360fxFade->timer = 0;361fxFade->speedIn = 16;362fxFade->drawGroup = 15;363fxFade->state = FXFade_State_FadeOut;364self->state = PuyoGame_State_FadeToMenu;365}366}367else {368self->timer++;369}370}371372void PuyoGame_State_FadeToMenu(void)373{374RSDK_THIS(PuyoGame);375376EntityCompetitionSession *session = CompetitionSession_GetSession();377EntityMenuParam *param = MenuParam_GetParam();378379EntityFXFade *fxFade = PuyoGame->fxFade;380if (fxFade->timer == 512) {381if (param->puyoSelection == PUYO_SELECTION_TIE_BREAKER)382session->wins[self->matchWinner]++;383384destroyEntity(self);385386RSDK.SetScene("Presentation", "Menu");387RSDK.LoadScene();388}389}390391#if GAME_INCLUDE_EDITOR392void PuyoGame_EditorDraw(void)393{394RSDK_THIS(PuyoGame);395396RSDK.SetSpriteAnimation(PuyoGame->aniFrames, 24, &self->animator, false, 0);397RSDK.DrawSprite(&self->animator, NULL, false);398}399400void PuyoGame_EditorLoad(void) { PuyoGame->aniFrames = RSDK.LoadSpriteAnimation("Puyo/PuyoBeans.bin", SCOPE_STAGE); }401#endif402403void PuyoGame_Serialize(void) {}404405406