Path: blob/master/SonicMania/Objects/Global/Animals.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Animals Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectAnimals *Animals;1011void Animals_Update(void)12{13RSDK_THIS(Animals);1415StateMachine_Run(self->state);1617if (!self->behaviour && !RSDK.CheckOnScreen(self, NULL))18destroyEntity(self);19}2021void Animals_LateUpdate(void) {}2223void Animals_StaticUpdate(void) {}2425void Animals_Draw(void)26{27RSDK_THIS(Animals);2829RSDK.DrawSprite(&self->animator, NULL, false);30}3132void Animals_Create(void *data)33{34RSDK_THIS(Animals);3536if (self->behaviour == ANIMAL_BEHAVE_FIXED)37self->active = ACTIVE_BOUNDS;38else39self->active = ACTIVE_NORMAL;4041self->drawFX |= FX_FLIP;42self->visible = true;43self->updateRange.x = TO_FIXED(64);44self->updateRange.y = TO_FIXED(64);45self->drawGroup = Zone->objectDrawGroup[0];4647int32 type = ANIMAL_POCKY;48#if MANIA_USE_PLUS49if (!(globals->secrets & SECRET_RICKYMODE))50#endif51type = VOID_TO_INT(data);5253if (!self->type && ZONE_RAND(0, 256) == 21) {54type = ANIMAL_POCKY;55self->velocity.y = -TO_FIXED(4);56self->type = type - 1;57self->state = Animals_State_Fall;58self->hitboxAnimal.top = -Animals->hitboxes[self->type] >> 16;59self->hitboxAnimal.left = -4;60self->hitboxAnimal.right = 4;61self->hitboxAnimal.bottom = Animals->hitboxes[self->type] >> 16;62RSDK.SetSpriteAnimation(Animals->aniFrames, 2 * self->type, &self->animator, true, 0);63}64else if (type) {65self->velocity.y = -TO_FIXED(4);66self->type = type - 1;67self->state = Animals_State_Fall;6869self->hitboxAnimal.top = -FROM_FIXED(Animals->hitboxes[self->type]);70self->hitboxAnimal.left = -4;71self->hitboxAnimal.right = 4;72self->hitboxAnimal.bottom = FROM_FIXED(Animals->hitboxes[self->type]);7374RSDK.SetSpriteAnimation(Animals->aniFrames, 2 * self->type, &self->animator, true, 0);75}76else if (self->behaviour == ANIMAL_BEHAVE_FOLLOW) {77self->active = ACTIVE_BOUNDS;78switch (self->type) {79case ANIMAL_FLICKY:80case ANIMAL_CUCKY:81case ANIMAL_LOCKY: self->state = Animals_State_Fly; break;8283case ANIMAL_RICKY:84case ANIMAL_POCKY:85case ANIMAL_PECKY:86case ANIMAL_PICKY:87case ANIMAL_ROCKY:88case ANIMAL_BECKY:89case ANIMAL_TOCKY:90case ANIMAL_WOCKY:91case ANIMAL_MICKY: self->state = Animals_State_Bounce; break;9293default: break;94}9596Animals_CheckDirection();97self->velocity.y = Animals->yVelocity[self->type];98if (self->direction == FLIP_NONE)99self->velocity.x = -Animals->xVelocity[self->type];100else101self->velocity.x = Animals->xVelocity[self->type];102RSDK.SetSpriteAnimation(Animals->aniFrames, 2 * self->type + 1, &self->animator, true, 0);103}104else {105self->state = Animals_State_Placed;106}107}108109void Animals_StageLoad(void)110{111Animals->aniFrames = RSDK.LoadSpriteAnimation("Global/Animals.bin", SCOPE_STAGE);112113if (RSDK.FindObject("Platform"))114Animals->hasPlatform = true;115116if (RSDK.FindObject("Bridge"))117Animals->hasBridge = true;118}119120void Animals_CheckDirection(void)121{122RSDK_THIS(Animals);123124switch (self->behaviour) {125default:126case ANIMAL_BEHAVE_FREE: self->direction = FLIP_X; break;127128case ANIMAL_BEHAVE_FOLLOW: {129EntityPlayer *player = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);130if (!player) {131self->direction = FLIP_NONE;132}133else if (self->position.x < player->position.x) {134self->direction = FLIP_NONE;135}136else {137self->direction = FLIP_X;138}139break;140}141142case ANIMAL_BEHAVE_FIXED: self->direction = ZONE_RAND(0, 2); break;143}144145if (!self->direction)146self->velocity.x = -Animals->xVelocity[self->type];147else148self->velocity.x = Animals->xVelocity[self->type];149}150151bool32 Animals_CheckPlatformCollision(void *p)152{153RSDK_THIS(Animals);154EntityPlatform *platform = (EntityPlatform *)p;155156bool32 collided = false;157if (platform->state != Platform_State_Falling2 && platform->state != Platform_State_Hold) {158platform->position.x = platform->drawPos.x - platform->collisionOffset.x;159platform->position.y = platform->drawPos.y - platform->collisionOffset.y;160161if (platform->collision <= PLATFORM_C_SOLID) {162collided = RSDK.CheckObjectCollisionPlatform(platform, RSDK.GetHitbox(&platform->animator, 0), self, &self->hitboxAnimal, true);163}164else if (platform->collision == PLATFORM_C_TILED165&& RSDK.CheckObjectCollisionTouchBox(platform, &platform->hitbox, self, &self->hitboxAnimal)) {166if (self->collisionLayers & Zone->moveLayerMask) {167TileLayer *move = RSDK.GetTileLayer(Zone->moveLayer);168move->position.x = -(platform->drawPos.x + platform->tileOrigin.x) >> 16;169move->position.y = -(platform->drawPos.y + platform->tileOrigin.y) >> 16;170}171172if (self->velocity.y >= 0x3800)173collided = true;174}175platform->position.x = platform->centerPos.x;176platform->position.y = platform->centerPos.y;177}178179return collided;180}181182bool32 Animals_CheckGroundCollision(void)183{184RSDK_THIS(Animals);185186if (self->velocity.y <= 0)187return false;188189if (RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, Animals->hitboxes[self->type], false))190return true;191192if (Animals->hasPlatform) {193foreach_active(Platform, platform)194{195if (Animals_CheckPlatformCollision(platform))196return true;197}198}199200if (Animals->hasBridge) {201foreach_active(Bridge, bridge)202{203bool32 collided = Bridge_HandleCollisions(self, bridge, &self->hitboxAnimal, false, false);204if (collided) {205foreach_return true;206}207}208}209return false;210}211212void Animals_State_Fall(void)213{214RSDK_THIS(Animals);215216self->position.y += self->velocity.y;217self->velocity.y += 0x3800;218219RSDK.ProcessAnimation(&self->animator);220221if (Animals_CheckGroundCollision()) {222RSDK.SetSpriteAnimation(Animals->aniFrames, 2 * self->type + 1, &self->animator, true, 0);223switch (self->type) {224case ANIMAL_FLICKY:225case ANIMAL_CUCKY:226case ANIMAL_LOCKY: self->state = Animals_State_Fly; break;227228case ANIMAL_RICKY:229case ANIMAL_POCKY:230case ANIMAL_PECKY:231case ANIMAL_PICKY:232case ANIMAL_ROCKY:233case ANIMAL_BECKY:234case ANIMAL_TOCKY:235case ANIMAL_WOCKY:236case ANIMAL_MICKY: self->state = Animals_State_Bounce; break;237238default: break;239}240241Animals_CheckDirection();242self->velocity.y = Animals->yVelocity[self->type];243}244}245246void Animals_State_Bounce(void)247{248RSDK_THIS(Animals);249250self->position.x += self->velocity.x;251self->position.y += self->velocity.y;252self->velocity.y += Animals->gravityStrength[self->type];253254if (Animals_CheckGroundCollision()) {255Animals_CheckDirection();256self->velocity.y = Animals->yVelocity[self->type];257}258259self->animator.frameID = self->velocity.y < 0;260}261262void Animals_State_Fly(void)263{264RSDK_THIS(Animals);265266self->position.x += self->velocity.x;267self->position.y += self->velocity.y;268self->velocity.y += Animals->gravityStrength[self->type];269270if (Animals_CheckGroundCollision()) {271Animals_CheckDirection();272self->velocity.y = Animals->yVelocity[self->type];273}274275RSDK.ProcessAnimation(&self->animator);276}277278void Animals_State_Placed(void)279{280RSDK_THIS(Animals);281282if (self->timer <= 0)283self->state = Animals_State_Fall;284else285self->timer--;286}287288#if GAME_INCLUDE_EDITOR289void Animals_EditorDraw(void)290{291RSDK_THIS(Animals);292293switch (self->behaviour) {294default: break;295case ANIMAL_BEHAVE_FREE: RSDK.SetSpriteAnimation(Animals->aniFrames, 2 * self->type, &self->animator, true, 0); break;296case ANIMAL_BEHAVE_FOLLOW:297case ANIMAL_BEHAVE_FIXED: RSDK.SetSpriteAnimation(Animals->aniFrames, 2 * self->type + 1, &self->animator, true, 0); break;298}299300RSDK.DrawSprite(&self->animator, NULL, false);301}302303void Animals_EditorLoad(void)304{305Animals->aniFrames = RSDK.LoadSpriteAnimation("Global/Animals.bin", SCOPE_STAGE);306307RSDK_ACTIVE_VAR(Animals, type);308RSDK_ENUM_VAR("Flicky", ANIMAL_FLICKY);309RSDK_ENUM_VAR("Ricky", ANIMAL_RICKY);310RSDK_ENUM_VAR("Pocky", ANIMAL_POCKY);311RSDK_ENUM_VAR("Pecky", ANIMAL_PECKY);312RSDK_ENUM_VAR("Picky", ANIMAL_PICKY);313RSDK_ENUM_VAR("Cucky", ANIMAL_CUCKY);314RSDK_ENUM_VAR("Rocky", ANIMAL_ROCKY);315RSDK_ENUM_VAR("Becky", ANIMAL_BECKY);316RSDK_ENUM_VAR("Locky", ANIMAL_LOCKY);317RSDK_ENUM_VAR("Tocky", ANIMAL_TOCKY);318RSDK_ENUM_VAR("Wocky", ANIMAL_WOCKY);319RSDK_ENUM_VAR("Mickey", ANIMAL_MICKY);320321RSDK_ACTIVE_VAR(Animals, behaviour);322RSDK_ENUM_VAR("Free", ANIMAL_BEHAVE_FREE);323RSDK_ENUM_VAR("Follow", ANIMAL_BEHAVE_FOLLOW);324RSDK_ENUM_VAR("Fixed", ANIMAL_BEHAVE_FIXED);325}326#endif327328void Animals_Serialize(void)329{330RSDK_EDITABLE_VAR(Animals, VAR_ENUM, type);331RSDK_EDITABLE_VAR(Animals, VAR_ENUM, behaviour);332}333334335