Path: blob/master/SonicMania/Objects/OOZ/OOZSetup.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: OOZSetup Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectOOZSetup *OOZSetup;1011void OOZSetup_Update(void) {}1213void OOZSetup_LateUpdate(void) {}1415void OOZSetup_StaticUpdate(void)16{17foreach_all(OOZSetup, setup) { RSDK.AddDrawListRef(Zone->playerDrawGroup[0] + 1, RSDK.GetEntitySlot(setup)); }1819OOZSetup->palTimer += 128;20if (OOZSetup->palTimer >= 256) {21OOZSetup->palTimer -= 256;2223RSDK.RotatePalette(3, 216, 223, false);24RSDK.RotatePalette(4, 216, 223, false);25RSDK.RotatePalette(5, 216, 223, false);26RSDK.RotatePalette(6, 216, 223, false);27}2829RSDK.SetLimitedFade(1, 3, 4, OOZSetup->palTimer, 216, 223);30RSDK.SetLimitedFade(2, 5, 6, OOZSetup->palTimer, 216, 223);31RSDK.CopyPalette(1, 216, 0, 216, 8);3233if (!(Zone->timer & 3)) {34++OOZSetup->background1->deformationOffset;3536OOZSetup->oilAniTimer += 16;37OOZSetup->oilAniTimer %= 160;3839RSDK.DrawAniTiles(OOZSetup->aniTiles, 760, 0, OOZSetup->oilAniTimer, 128, 16);40RSDK.DrawAniTiles(OOZSetup->aniTiles, 757, 136, OOZSetup->oilAniTimer, 16, 16);41RSDK.DrawAniTiles(OOZSetup->aniTiles, 758, 128, OOZSetup->oilAniTimer, 32, 16);42}4344if (--OOZSetup->glowLightAniTimer <= 0) {45++OOZSetup->glowLightAniFrame;4647OOZSetup->glowLightAniFrame &= 7;48OOZSetup->glowLightAniTimer = OOZSetup->glowLightAniDurations[OOZSetup->glowLightAniFrame];4950RSDK.DrawAniTiles(OOZSetup->aniTiles, 756, 16 * OOZSetup->glowLightAniFrame, 160, 16, 16);51}5253OOZSetup->swimmingPlayerCount = 0;54foreach_active(Player, player)55{56int32 playerID = RSDK.GetEntitySlot(player);57if (player->state != Player_State_Static) {58Hitbox *playerHitbox = Player_GetHitbox(player);59uint16 tile =60RSDK.GetTile(Zone->fgLayer[0], player->position.x >> 20, ((playerHitbox->bottom << 16) + player->position.y - 0x10000) >> 20);61if (tile == (uint16)-1)62tile = RSDK.GetTile(Zone->fgLayer[1], player->position.x >> 20, ((playerHitbox->bottom << 16) + player->position.y - 0x10000) >> 20);6364int32 tileFlags = RSDK.GetTileFlags(tile, player->collisionPlane);65if (tileFlags != OOZ_TFLAGS_NORMAL) {66if (player->shield == SHIELD_FIRE && player->superState != SUPERSTATE_SUPER && tileFlags != OOZ_TFLAGS_OILFALL) {67int32 tx = (player->position.x & 0xFFF00000) + 0x70000;68int32 ty = player->position.y + ((playerHitbox->bottom + 8) << 16);69if (tileFlags == OOZ_TFLAGS_OILPOOL) {70ty &= 0xFFF00000;71ty -= 0xC0000;72if (OOZSetup_StartFire(tx, ty, player->angle)) {73EntitySol *sol = CREATE_ENTITY(Sol, INT_TO_VOID(true), tx - 0x10000, ty);74sol->velocity.x = -0x40000;75RSDK.SetSpriteAnimation(Sol->aniFrames, 3, &sol->mainAnimator, true, 0);76sol->state = Sol_State_OilFlame;7778sol = CREATE_ENTITY(Sol, INT_TO_VOID(true), tx + 0x10000, ty);79sol->velocity.x = 0x40000;80RSDK.SetSpriteAnimation(Sol->aniFrames, 3, &sol->mainAnimator, true, 0);81sol->state = Sol_State_OilFlame;82}83}84else if (player->onGround) {85ty &= 0xFFFF0000;86if (OOZSetup_StartFire(tx, ty, player->angle)) {87ty -= 0x80000;88EntitySol *sol = CREATE_ENTITY(Sol, INT_TO_VOID(true), tx - 0x10000, ty);89sol->velocity.x = -0x40000;90RSDK.SetSpriteAnimation(Sol->aniFrames, 3, &sol->mainAnimator, true, 0);91sol->state = Sol_State_FireballOilFlame;9293sol = CREATE_ENTITY(Sol, INT_TO_VOID(true), tx + 0x10000, ty);94sol->velocity.x = 0x40000;95RSDK.SetSpriteAnimation(Sol->aniFrames, 3, &sol->mainAnimator, true, 0);96sol->state = Sol_State_FireballOilFlame;97}98}99}100101switch (tileFlags) {102case OOZ_TFLAGS_NORMAL:103default: OOZSetup->activePlayers &= ~(1 << playerID); break;104105case OOZ_TFLAGS_OILPOOL:106if (!player->sidekick)107OOZSetup->swimmingPlayerCount++;108OOZSetup->activePlayers &= ~(1 << playerID);109if (player->velocity.y < 0) {110player->velocity.y += 0x3800;111}112else {113player->interaction = true;114player->tileCollisions = TILECOLLISION_DOWN;115player->state = OOZSetup_PlayerState_OilPool;116}117break;118119case OOZ_TFLAGS_OILSTRIP:120if (player->state != Player_State_BubbleBounce121#if MANIA_USE_PLUS122&& player->state != Player_State_MightyHammerDrop123#endif124) {125OOZSetup->activePlayers &= ~(1 << playerID);126if (player->onGround) {127player->interaction = true;128player->tileCollisions = TILECOLLISION_DOWN;129player->state = OOZSetup_PlayerState_OilStrip;130}131}132break;133134case OOZ_TFLAGS_OILSLIDE:135if (player->state != Player_State_BubbleBounce136#if MANIA_USE_PLUS137&& player->state != Player_State_MightyHammerDrop138#endif139) {140OOZSetup->activePlayers &= ~(1 << playerID);141if (player->onGround) {142player->interaction = true;143player->tileCollisions = TILECOLLISION_DOWN;144if (!player->angle)145player->state = OOZSetup_PlayerState_OilStrip;146else147player->state = OOZSetup_PlayerState_OilSlide;148}149}150break;151152case OOZ_TFLAGS_OILFALL:153if (!player->sidekick)154OOZSetup->swimmingPlayerCount++;155156OOZSetup->activePlayers |= 1 << playerID;157player->interaction = true;158player->tileCollisions = TILECOLLISION_DOWN;159if (player->velocity.y < 0)160player->velocity.y += 0xC000;161else162player->state = OOZSetup_PlayerState_OilFall;163break;164}165}166else {167OOZSetup->activePlayers &= ~(1 << playerID);168}169}170}171172if (OOZSetup->useSmogEffect && SceneInfo->timeEnabled) {173if (OOZSetup->smogTimer < 0x10000)174OOZSetup->smogTimer++;175}176else {177if (OOZSetup->smogTimer > 0)178OOZSetup->smogTimer -= 32;179}180181#if MANIA_USE_PLUS182foreach_active(Ring, ring)183{184if (ring->state == Ring_State_Lost) {185uint16 tile = RSDK.GetTile(Zone->fgLayer[0], ring->position.x >> 20, (ring->position.y + 0xE0000) >> 20);186if (tile == (uint16)-1)187tile = RSDK.GetTile(Zone->fgLayer[1], ring->position.x >> 20, (ring->position.y + 0xE0000) >> 20);188189if (RSDK.GetTileFlags(tile, ring->collisionPlane) == OOZ_TFLAGS_OILPOOL) {190ring->velocity.x -= ring->velocity.x >> 4;191ring->velocity.y = 0x2800;192ring->drawGroup = Zone->objectDrawGroup[1];193if (ring->alpha > 0x40) {194ring->alpha = 0x40;195ring->inkEffect = INK_ALPHA;196}197}198}199}200#endif201202OOZSetup_HandleActiveFlames();203204#if MANIA_USE_PLUS205RSDK.ProcessAnimation(&OOZSetup->animator);206#endif207}208209void OOZSetup_Draw(void)210{211RSDK_THIS(OOZSetup);212213#if MANIA_USE_PLUS214if (SceneInfo->currentDrawGroup != self->drawGroup) {215foreach_active(Player, player)216{217if ((1 << RSDK.GetEntitySlot(player)) & OOZSetup->activePlayers)218RSDK.DrawSprite(&OOZSetup->animator, &player->position, false);219}220}221#endif222223if (self->type)224RSDK.FillScreen(0xC0C0E8, OOZSetup->smogTimer >> 5, OOZSetup->smogTimer >> 5, OOZSetup->smogTimer >> 4);225else226OOZSetup_Draw_Flames();227}228229void OOZSetup_Create(void *data)230{231RSDK_THIS(OOZSetup);232233self->active = ACTIVE_ALWAYS;234self->visible = true;235self->drawFX = FX_ROTATE;236self->drawGroup = self->type ? 14 : Zone->objectDrawGroup[0];237}238239void OOZSetup_StageLoad(void)240{241OOZSetup->aniTiles = RSDK.LoadSpriteSheet("OOZ/AniTiles.gif", SCOPE_STAGE);242243OOZSetup->background1 = RSDK.GetTileLayer(0);244for (int32 i = 0; i < 0x400; ++i) {245OOZSetup->background1->deformationData[i] = OOZSetup->deformData[i & 0x3F];246}247248OOZSetup->smogTimer = 0;249OOZSetup->useSmogEffect = true;250OOZSetup->swimmingPlayerCount = 0;251252Animals->animalTypes[0] = ANIMAL_ROCKY;253Animals->animalTypes[1] = ANIMAL_PECKY;254255memset(OOZSetup->flameTimers, 0, sizeof(OOZSetup->flameTimers));256memset(OOZSetup->flameTimerPtrs, 0, sizeof(OOZSetup->flameTimerPtrs));257OOZSetup->flameCount = 0;258259OOZSetup->solFrames = RSDK.LoadSpriteAnimation("OOZ/Sol.bin", SCOPE_STAGE);260RSDK.SetSpriteAnimation(OOZSetup->solFrames, 3, &OOZSetup->flameAnimator, true, 0);261262#if MANIA_USE_PLUS263OOZSetup->splashFrames = RSDK.LoadSpriteAnimation("OOZ/Splash.bin", SCOPE_STAGE);264RSDK.SetSpriteAnimation(OOZSetup->splashFrames, 0, &OOZSetup->animator, true, 0);265#endif266267if (RSDK.CheckSceneFolder("OOZ2")) {268foreach_all(OOZ1Outro, cutscene)269{270OOZSetup->cutscenePtr = (Entity *)cutscene;271foreach_break;272}273274GenericTrigger->callbacks[OOZ_GENERICTRIGGER_ACHIEVEMENT] = OOZSetup_Trigger_AwardAchievement;275276if (!StarPost->postIDs[0])277Zone->cameraBoundsB[0] = 1600;278279if (isMainGameMode() && globals->enableIntro) {280if (!CutsceneRules_CheckStageReload()) {281SaveGame_LoadPlayerState();282globals->suppressAutoMusic = true;283globals->suppressTitlecard = true;284}285}286287#if MANIA_USE_PLUS288if (isMainGameMode() && CutsceneRules_IsAct2())289Zone->stageFinishCallback = OOZ2Outro_StageFinish_EndAct2;290291if (SceneInfo->filter & FILTER_ENCORE) {292RSDK.LoadPalette(0, "EncoreOOZ2.act", 0b0000000011111111);293RSDK.LoadPalette(2, "EncoreOOZSmog.act", 0b0000000011111111);294295RSDK.CopyPalette(0, 128, 1, 128, 128);296RSDK.CopyPalette(0, 128, 3, 128, 128);297RSDK.CopyPalette(0, 128, 4, 128, 128);298RSDK.RotatePalette(4, 215, 223, false);299300RSDK.CopyPalette(2, 128, 5, 128, 128);301RSDK.CopyPalette(2, 128, 6, 128, 128);302RSDK.RotatePalette(6, 215, 223, false);303}304#endif305}306#if MANIA_USE_PLUS307else if (SceneInfo->filter & FILTER_ENCORE) {308RSDK.LoadPalette(0, "EncoreOOZ1.act", 0b0000000011111111);309RSDK.CopyPalette(0, 128, 1, 128, 80);310RSDK.CopyPalette(0, 128, 3, 128, 80);311}312#endif313314int32 sfxID = Soundboard_LoadSfx("OOZ/Slide.wav", 12382, OOZSetup_SfxCheck_Slide, StateMachine_None);315if (sfxID >= 0)316Soundboard->sfxFadeOutDuration[sfxID] = 30;317318sfxID = Soundboard_LoadSfx("OOZ/OilSwim.wav", true, OOZSetup_SfxCheck_OilSwim, StateMachine_None);319if (sfxID >= 0)320Soundboard->sfxFadeOutDuration[sfxID] = 30;321322sfxID = Soundboard_LoadSfx("Stage/Flame2.wav", true, OOZSetup_SfxCheck_Flame2, StateMachine_None);323if (sfxID >= 0)324Soundboard->sfxFadeOutDuration[sfxID] = 30;325}326327bool32 OOZSetup_SfxCheck_Flame2(void)328{329int32 count = 0;330331foreach_active(Sol, sol)332{333if (sol->isFlameFX)334count++;335}336337for (int32 i = 0; i < OOZSetup->flameCount; ++i) {338if (OOZSetup->flameTimerPtrs[i])339count++;340}341342return count > 0;343}344345bool32 OOZSetup_SfxCheck_Slide(void)346{347int32 count = 0;348349foreach_active(Player, player)350{351if (!player->sidekick) {352if (player->state == OOZSetup_PlayerState_OilSlide || player->state == OOZSetup_PlayerState_OilStrip)353++count;354}355}356357return count > 0;358}359360bool32 OOZSetup_SfxCheck_OilSwim(void) { return OOZSetup->swimmingPlayerCount > 0; }361362void OOZSetup_Draw_Flames(void)363{364RSDK_THIS(OOZSetup);365366for (int32 i = 0; i < OOZSetup->flameCount; ++i) {367if (OOZSetup->flameTimerPtrs[i]) {368self->rotation = 2 * (OOZSetup->flamePositions[i].x & 0xFF);369OOZSetup->flameAnimator.frameID = OOZSetup->flamePositions[i].y & 0xFF;370RSDK.DrawSprite(&OOZSetup->flameAnimator, &OOZSetup->flamePositions[i], false);371}372}373}374375void OOZSetup_HandleActiveFlames(void)376{377RSDK_THIS(OOZSetup);378379for (int32 i = 0; i < OOZSetup->flameCount; ++i) {380if (OOZSetup->flameTimerPtrs[i]) {381--(*OOZSetup->flameTimerPtrs[i]);382383if (!*OOZSetup->flameTimerPtrs[i]) {384OOZSetup->flameTimerPtrs[i] = NULL;385EntitySol *sol = CREATE_ENTITY(Sol, INT_TO_VOID(true), OOZSetup->flamePositions[i].x, OOZSetup->flamePositions[i].y);386sol->isFlameFX = true;387sol->rotation = 2 * (OOZSetup->flamePositions[i].x & 0xFF);388RSDK.SetSpriteAnimation(Sol->aniFrames, 2, &sol->mainAnimator, true, 0);389sol->state = Sol_State_FlameDissipate;390}391else {392int32 frame = OOZSetup->flamePositions[i].y & 0xFF;393int32 frameTimer = (OOZSetup->flamePositions[i].y >> 8) & 0xFF;394395if (++frameTimer >= 3) {396frameTimer = 0;397if (++frame > 10)398frame = 1;399}400401// likewise, this too is evil, using the lower 2 bytes to store frame info402OOZSetup->flamePositions[i].y = frame | (frameTimer << 8) | (OOZSetup->flamePositions[i].y & 0xFFFF0000);403}404405Vector2 storePos = self->position;406foreach_active(Player, player)407{408self->position = OOZSetup->flamePositions[i];409if (Player_CheckCollisionTouch(player, self, &Sol->hitboxBadnik)) {410self->position = storePos;411Player_ElementHurt(player, self, SHIELD_FIRE);412}413}414self->position = storePos;415}416}417}418419bool32 OOZSetup_StartFire(int32 posX, int32 posY, int32 angle)420{421RSDK_THIS(OOZSetup);422423int32 pos = (posX >> 20) + (posY >> 20 << 10);424425if (pos < 0x20000) {426if (!OOZSetup->flameTimers[pos]) {427int32 i = 0;428for (; i < 399; ++i) {429if (!OOZSetup->flameTimerPtrs[i])430break;431}432// if we get to 399 active flames just use that slot over and over433434OOZSetup->flameTimerPtrs[i] = &OOZSetup->flameTimers[pos];435OOZSetup->flamePositions[i].x = posX;436OOZSetup->flamePositions[i].y = posY;437OOZSetup->flamePositions[i].x &= 0xFFFF0000;438OOZSetup->flamePositions[i].y &= 0xFFFF0000;439// this is so evil, using the bottom byte of the XPos to store the angle440OOZSetup->flamePositions[i].x |= angle;441442if (i + 1 > OOZSetup->flameCount)443OOZSetup->flameCount = i + 1;444445OOZSetup->flameTimers[pos] = 0xF0;446CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSS), self->position.x, self->position.y - 0x60000)->drawGroup = self->drawGroup;447448return true;449}450}451452return false;453}454455void OOZSetup_Trigger_AwardAchievement(void)456{457if (!OOZSetup->hasAchievement) {458API_UnlockAchievement(&achievementList[ACH_OOZ]);459OOZSetup->hasAchievement = true;460}461}462463void OOZSetup_PlayerState_OilPool(void)464{465RSDK_THIS(Player);466467int32 top = self->topSpeed;468int32 acc = self->acceleration;469self->topSpeed = (self->topSpeed >> 1) + (self->topSpeed >> 3);470self->acceleration = (self->acceleration >> 1) + (self->acceleration >> 3);471472if (self->groundVel <= 0) {473if (self->groundVel < -self->topSpeed) {474self->groundVel += 0x3800;475}476}477else if (self->groundVel > self->topSpeed) {478self->groundVel -= 0x3800;479}480481self->position.y += 0x10000;482483self->up = false;484self->down = false;485self->onGround = true;486487Player_State_Ground();488489self->topSpeed = top;490self->acceleration = acc;491}492493void OOZSetup_PlayerState_OilStrip(void)494{495RSDK_THIS(Player);496497int32 acc = self->acceleration;498int32 top = self->topSpeed;499int32 skid = self->skidSpeed;500int32 dec = self->deceleration;501502Animator animator;503memcpy(&animator, &self->animator, sizeof(Animator));504505self->position.y += 0x10000;506507self->skidSpeed = self->skidSpeed >> 3;508self->topSpeed = (self->topSpeed >> 1) + (self->topSpeed >> 2);509self->acceleration = 0x400;510self->deceleration = self->deceleration >> 3;511512self->up = false;513self->down = false;514self->skidding = 0;515self->onGround = true;516517Player_State_Ground();518519#if MANIA_USE_PLUS520if ((animator.animationID == ANI_HURT || animator.animationID == ANI_FLUME) && self->groundedStore && self->onGround) {521#else522if (animator.animationID == ANI_HURT && self->groundedStore && self->onGround) {523#endif524if (abs(self->groundVel) >= 0x20000) {525memcpy(&self->animator, &animator, sizeof(Animator));526if (self->animator.timer >= 3)527self->animator.timer = 256;528529if (self->angle == 0x40 || self->angle == 0xC0) {530self->onGround = false;531self->state = Player_State_Air;532}533}534}535536self->acceleration = acc;537self->topSpeed = top;538self->skidSpeed = skid;539self->deceleration = dec;540}541542void OOZSetup_PlayerState_OilSlide(void)543{544RSDK_THIS(Player);545546if (!self->onGround) {547self->state = Player_State_Air;548Player_HandleAirMovement();549}550else {551Player_Gravity_False();552553if (self->angle) {554if (self->angle <= 0x80) {555if (self->groundVel < 0x80000)556self->groundVel += 0x4000;557}558else {559if (self->groundVel > -0x80000)560self->groundVel -= 0x4000;561}562}563564self->groundVel += RSDK.Sin256(self->angle) << 13 >> 8;565self->controlLock = 30;566self->direction = self->groundVel < 0;567568#if MANIA_USE_PLUS569RSDK.SetSpriteAnimation(self->aniFrames, ANI_FLUME, &self->animator, false, 0);570#else571RSDK.SetSpriteAnimation(self->aniFrames, ANI_HURT, &self->animator, false, 2);572#endif573}574575if (self->jumpPress) {576Player_Action_Jump(self);577578if (self->angle <= 0x80) {579if (self->velocity.x < 0)580self->velocity.x += ((self->jumpStrength + (self->jumpStrength >> 1)) * RSDK.Sin256(self->angle)) >> 8;581}582else {583if (self->velocity.x > 0)584self->velocity.x += ((self->jumpStrength + (self->jumpStrength >> 1)) * RSDK.Sin256(self->angle)) >> 8;585}586}587}588589void OOZSetup_PlayerState_OilFall(void)590{591RSDK_THIS(Player);592593int32 top = self->topSpeed;594int32 acc = self->acceleration;595596self->topSpeed = (self->topSpeed >> 2) + (self->topSpeed >> 3);597self->acceleration = (self->acceleration >> 2) + (self->acceleration >> 3);598599if (self->groundVel <= 0) {600if (self->groundVel < -self->topSpeed)601self->groundVel += 0x3800;602}603else {604if (self->groundVel > self->topSpeed)605self->groundVel -= 0x3800;606}607608self->up = false;609self->down = false;610self->groundedStore = false;611self->onGround = false;612self->velocity.y = 0x10000;613614if (abs(self->velocity.x) > 0x20000) {615if (self->velocity.x <= 0)616self->velocity.x += 0xC000;617else618self->velocity.x -= 0xC000;619}620621if (!self->left && !self->right)622self->velocity.x -= self->velocity.x >> 4;623624RSDK.SetSpriteAnimation(self->aniFrames, ANI_JUMP, &self->animator, false, 0);625626Player_HandleGroundMovement();627628if (self->camera)629self->camera->disableYOffset = false;630631self->jumpAbilityState = 0;632self->nextAirState = Player_State_Air;633634if (self->jumpPress) {635Player_Action_Jump(self);636637self->jumpAbilityState = 0;638self->timer = 0;639}640641self->topSpeed = top;642self->acceleration = acc;643}644645#if GAME_INCLUDE_EDITOR646void OOZSetup_EditorDraw(void) {}647648void OOZSetup_EditorLoad(void)649{650RSDK_ACTIVE_VAR(OOZSetup, type);651RSDK_ENUM_VAR("Manage Flames", OOZSETUP_FLAMES);652RSDK_ENUM_VAR("Manage Fade", OOZSETUP_FADE);653654RSDK_ACTIVE_VAR(WarpDoor, effect);655RSDK_ENUM_VAR("None", WARPDOOR_EFFECT_NONE);656RSDK_ENUM_VAR("To Sub", OOZ_WARPDOOR_EFFECT_TO_SUB);657RSDK_ENUM_VAR("From Sub", OOZ_WARPDOOR_EFFECT_FROM_SUB);658659RSDK_ACTIVE_VAR(GenericTrigger, triggerID);660RSDK_ENUM_VAR("Award Achievement", OOZ_GENERICTRIGGER_ACHIEVEMENT);661}662#endif663664void OOZSetup_Serialize(void) { RSDK_EDITABLE_VAR(OOZSetup, VAR_UINT8, type); }665666667