Path: blob/master/SonicMania/Objects/Pinball/PBL_Flipper.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: PBL_Flipper Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89#if MANIA_USE_PLUS10ObjectPBL_Flipper *PBL_Flipper;1112void PBL_Flipper_Update(void)13{14RSDK_THIS(PBL_Flipper);1516if (self->direction) {17self->buttonPress = TriggerInfoL[CONT_P1].keyBumper.press || ControllerInfo[CONT_P1].keyA.press || ControllerInfo[CONT_P1].keyX.press18|| ControllerInfo[CONT_P1].keyC.press;1920self->buttonDown = TriggerInfoL[CONT_P1].keyBumper.down || ControllerInfo[CONT_P1].keyA.down || ControllerInfo[CONT_P1].keyX.down21|| ControllerInfo[CONT_P1].keyC.down;22}23else {24self->buttonPress = TriggerInfoR[CONT_P1].keyBumper.press || ControllerInfo[CONT_P1].keyA.press || ControllerInfo[CONT_P1].keyB.press25|| ControllerInfo[CONT_P1].keyC.press;2627self->buttonDown = TriggerInfoR[CONT_P1].keyBumper.down || ControllerInfo[CONT_P1].keyA.down || ControllerInfo[CONT_P1].keyB.down28|| ControllerInfo[CONT_P1].keyC.down;29}3031StateMachine_Run(self->state);3233if (self->retractable) {34foreach_active(PBL_Player, player)35{36if (player->position.y >= self->position.y - 0x100000 || self->minCraneID > PBL_Setup->sectorID) {37if (player->position.y > self->position.y + 0x100000)38self->flipperActive = false;39}40else {41self->flipperActive = true;42}43}4445if (self->flipperActive) {46if (self->scale.y < 0x100)47self->scale.y += 0x10;48}49else if (self->scale.y > 0) {50self->scale.y -= 0x10;51}52}53}5455void PBL_Flipper_LateUpdate(void)56{57RSDK_THIS(PBL_Flipper);5859int32 z = self->position.y;60int32 y = self->height;61int32 x = self->position.x;6263Matrix *m = &PBL_Camera->matWorld;64self->zdepth = m->values[2][1] * (y >> 16) + m->values[2][2] * (z >> 16) + m->values[2][0] * (x >> 16) + m->values[2][3];6566if (self->zdepth >= 0x4000) {67int32 depth = ((m->values[0][3] << 8) + ((m->values[0][2] * (z >> 8)) & 0xFFFFFF00) + ((m->values[0][0] * (x >> 8)) & 0xFFFFFF00)68+ ((m->values[0][1] * (self->height >> 8)) & 0xFFFFFF00));69depth /= self->zdepth;70self->visible = abs(depth) < 0x100;71}72}7374void PBL_Flipper_StaticUpdate(void) {}7576void PBL_Flipper_Draw(void)77{78RSDK_THIS(PBL_Flipper);7980if (self->zdepth >= 0x4000 && self->minCraneID <= PBL_Setup->sectorID) {81RSDK.Prepare3DScene(PBL_Flipper->sceneIndex);8283RSDK.MatrixScaleXYZ(&self->matTransform, self->scale.x, self->scale.y, 0x100);84RSDK.MatrixTranslateXYZ(&self->matTransform, self->position.x, self->height, self->position.y, false);85RSDK.MatrixRotateY(&self->matNormal, self->angle >> 8);8687RSDK.MatrixMultiply(&self->matWorld, &self->matNormal, &self->matTransform);88RSDK.MatrixMultiply(&self->matWorld, &self->matWorld, &PBL_Camera->matWorld);8990if (PBL_Camera->useAltMatNormal)91RSDK.MatrixMultiply(&self->matNormal, &self->matNormal, &PBL_Camera->matNormal);92else93RSDK.MatrixMultiply(&self->matNormal, &self->matNormal, &PBL_Camera->matNormalItem);9495RSDK.AddModelTo3DScene(PBL_Flipper->modelFrames, PBL_Flipper->sceneIndex, PBL_Flipper->drawType, &self->matWorld, &self->matNormal, 0xFFFFFF);9697RSDK.Draw3DScene(PBL_Flipper->sceneIndex);98}99}100101void PBL_Flipper_Create(void *data)102{103RSDK_THIS(PBL_Flipper);104if (!SceneInfo->inEditor) {105self->visible = true;106self->scale.x = self->direction == FLIP_NONE ? 0x100 : -0x100;107self->drawGroup = 4;108self->active = ACTIVE_BOUNDS;109self->updateRange.x = 0x400000;110self->updateRange.y = 0x400000;111self->angle = -0x4000;112self->scale.y = 0x100;113self->flipperActive = true;114self->state = PBL_Flipper_State_AwaitFlip;115116RSDK.SetModelAnimation(PBL_Flipper->modelFrames, &self->animator, 96, 0, true, 0);117}118}119120void PBL_Flipper_StageLoad(void)121{122PBL_Flipper->modelFrames = RSDK.LoadMesh("Pinball/Flipper.bin", SCOPE_STAGE);123124PBL_Flipper->sceneIndex = RSDK.Create3DScene("View:Pinball", 0x1000, SCOPE_STAGE);125126PBL_Flipper->drawType = S3D_SOLIDCOLOR_SHADED_BLENDED_SCREEN;127128PBL_Flipper->hitbox.left = -52;129PBL_Flipper->hitbox.top = -8;130PBL_Flipper->hitbox.right = 12;131PBL_Flipper->hitbox.bottom = 8;132133PBL_Flipper->hitboxUnused.left = -52;134PBL_Flipper->hitboxUnused.top = -24;135PBL_Flipper->hitboxUnused.right = 12;136PBL_Flipper->hitboxUnused.bottom = 8;137138PBL_Flipper->sfxFlipperStage = RSDK.GetSfx("Stage/Flipper.wav");139PBL_Flipper->sfxFlipper = RSDK.GetSfx("Pinball/Flipper.wav");140}141142void PBL_Flipper_HandlePlayerInteractions(void)143{144RSDK_THIS(PBL_TargetBumper);145146if (self->scale.y >= 0x80) {147int32 angle = self->angle >> 10;148int32 negAngle = 0;149if (self->direction == FLIP_X) {150negAngle = angle;151angle = -angle;152}153else {154negAngle = -angle;155angle = angle;156}157158Vector2 originVel = { 0, 0 };159foreach_active(PBL_Player, player)160{161int32 posX = player->position.x;162int32 posY = player->position.y;163int32 velStoreX = player->velocity.x;164int32 velStoreY = player->velocity.y;165166Zone_RotateOnPivot(&player->position, &self->position, angle);167Zone_RotateOnPivot(&player->velocity, &originVel, angle);168169int32 velX = player->velocity.x;170int32 velY = player->velocity.y;171172int32 distance = 0;173if (self->direction == FLIP_NONE)174distance = self->position.x - player->position.x;175else176distance = player->position.x - self->position.x;177int32 force = CLAMP((distance + 0x80000) >> 13, 16, 256);178179switch (RSDK.CheckObjectCollisionBox(self, &PBL_Flipper->hitbox, player, &PBL_Player->outerBox, true)) {180case C_NONE:181player->position.x = posX;182player->position.y = posY;183player->velocity.x = velStoreX;184player->velocity.y = velStoreY;185break;186187case C_TOP:188if (velY < 0) {189player->velocity.x = velStoreX;190player->velocity.y = velStoreY;191Zone_RotateOnPivot(&player->position, &self->position, negAngle);192}193else {194if (velY > 0)195velY >>= 2;196if (velY > 0x80000)197velY = 0x80000;198199player->onGround = false;200201if (velY > 0x40000)202player->velocity.x >>= 2;203204if (self->state == PBL_Flipper_State_RiseFlipper && self->velocity.y == 0x2000) {205player->velocity.y -= (0xE0000 * force) >> 8;206player->onGround = false;207player->angle = 0;208}209210Zone_RotateOnPivot(&player->position, &self->position, negAngle);211Zone_RotateOnPivot(&player->velocity, &originVel, negAngle);212}213break;214215case C_LEFT:216if (velX < 0) {217player->velocity.x = velX;218}219else {220player->velocity.x = -(velX >> 2);221222if (player->velocity.x <= -0x10000) {223if (player->velocity.x < -0x80000)224player->velocity.x = -0x80000;225226player->velocity.y -= 0x20000;227}228else {229player->velocity.x = -0x10000;230player->velocity.y -= 0x20000;231}232233Zone_RotateOnPivot(&player->position, &self->position, negAngle);234Zone_RotateOnPivot(&player->velocity, &originVel, negAngle);235}236break;237238case C_RIGHT:239if (velX > 0) {240player->velocity.x = velX;241}242else {243player->velocity.x = -(velX >> 2);244245if (player->velocity.x >= 0x10000) {246if (player->velocity.x > 0x80000)247player->velocity.x = 0x80000;248249player->velocity.y -= 0x20000;250}251else {252player->velocity.x = 0x10000;253player->velocity.y -= 0x20000;254}255}256257Zone_RotateOnPivot(&player->position, &self->position, negAngle);258Zone_RotateOnPivot(&player->velocity, &originVel, negAngle);259break;260261case C_BOTTOM:262player->velocity.y = -(velY >> 2);263264Zone_RotateOnPivot(&player->position, &self->position, negAngle);265Zone_RotateOnPivot(&player->velocity, &originVel, negAngle);266break;267268default: break;269}270}271}272}273274void PBL_Flipper_State_AwaitFlip(void)275{276RSDK_THIS(PBL_Flipper);277278if (self->buttonDown) {279self->velocity.y = 0x2000;280self->state = PBL_Flipper_State_RiseFlipper;281RSDK.PlaySfx(PBL_Flipper->sfxFlipper, false, 255);282}283284PBL_Flipper_HandlePlayerInteractions();285}286287void PBL_Flipper_State_RiseFlipper(void)288{289RSDK_THIS(PBL_Flipper);290291self->angle += self->velocity.y;292293if (self->angle < 0x4000 || self->velocity.y < 0) {294if (self->velocity.y < 0x2000)295self->velocity.y += 0x400;296}297else {298self->angle = 0x4000;299self->velocity.y = -(self->velocity.y >> 2);300301if (!self->buttonDown) {302self->velocity.y = -0x2000;303self->state = PBL_Flipper_State_LowerFlipper;304}305}306307PBL_Flipper_HandlePlayerInteractions();308}309310void PBL_Flipper_State_LowerFlipper(void)311{312RSDK_THIS(PBL_Flipper);313314self->angle += self->velocity.y;315316if (self->angle > -0x4000 || self->velocity.y > 0) {317if (self->velocity.y > -0x2000)318self->velocity.y -= 0x400;319}320else {321self->angle = -0x4000;322self->velocity.y = -(self->velocity.y >> 2);323324if (self->velocity.y < 0x800) {325self->velocity.y = 0;326self->state = PBL_Flipper_State_AwaitFlip;327}328}329330PBL_Flipper_HandlePlayerInteractions();331}332333#if GAME_INCLUDE_EDITOR334void PBL_Flipper_EditorDraw(void) {}335336void PBL_Flipper_EditorLoad(void)337{338RSDK_ACTIVE_VAR(PBL_Flipper, direction);339RSDK_ENUM_VAR("Left", FLIP_NONE);340RSDK_ENUM_VAR("Right", FLIP_X);341}342#endif343344void PBL_Flipper_Serialize(void)345{346RSDK_EDITABLE_VAR(PBL_Flipper, VAR_UINT8, direction);347RSDK_EDITABLE_VAR(PBL_Flipper, VAR_UINT8, minCraneID);348RSDK_EDITABLE_VAR(PBL_Flipper, VAR_BOOL, retractable);349}350#endif351352353