Path: blob/master/SonicMania/Objects/AIZ/MonkeyDude.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: MonkeyDude Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectMonkeyDude *MonkeyDude;1011void MonkeyDude_Update(void)12{13RSDK_THIS(MonkeyDude);14StateMachine_Run(self->state);15#if !MANIA_USE_PLUS16for (self->armNodeID = 0; self->armNodeID < MonkeyDude_ArmJointCount; ++self->armNodeID) {17StateMachine_Run(self->armStates[self->armNodeID]);18}19#endif20}2122void MonkeyDude_LateUpdate(void) {}2324void MonkeyDude_StaticUpdate(void) {}2526void MonkeyDude_Draw(void)27{28RSDK_THIS(MonkeyDude);29#if MANIA_USE_PLUS30if (self->state == MonkeyDude_State_Coconut) {31RSDK.DrawSprite(&self->bodyAnimator, NULL, false);32}33else {34#endif35Vector2 drawPos;3637if (!self->direction)38drawPos.x = self->position.x - 0xD0000;39else40drawPos.x = self->position.x + 0xD0000;4142if (!self->bodyAnimator.frameID)43drawPos.y = self->position.y + -0x20000;44else45drawPos.y = self->position.y + -0x40000;46RSDK.DrawSprite(&MonkeyDude->armAnimator, &drawPos, false);4748for (self->armNodeID = 0; self->armNodeID < MonkeyDude_ArmJointCount; ++self->armNodeID) {49if (self->direction)50drawPos.x += RSDK.Sin256(self->armAngles[self->armNodeID]) << 11;51else52drawPos.x -= RSDK.Sin256(self->armAngles[self->armNodeID]) << 11;5354drawPos.y += RSDK.Cos256(self->armAngles[self->armNodeID]) << 11;5556Animator *animator = NULL;57if (self->armNodeID == MonkeyDude_ArmJointCount - 1) {58if (self->throwCount >= 4)59animator = &self->handAnimator;60else61animator = &MonkeyDude->coconutAnimator;62}63else {64animator = &MonkeyDude->armAnimator;65}66RSDK.DrawSprite(animator, &drawPos, false);67}6869RSDK.DrawSprite(&self->bodyAnimator, NULL, false);7071drawPos.x = self->position.x;72drawPos.y = self->armY;73RSDK.DrawSprite(&MonkeyDude->tailAnimator, &drawPos, false);74#if MANIA_USE_PLUS75}76#endif77}7879void MonkeyDude_Create(void *data)80{81RSDK_THIS(MonkeyDude);82self->visible = true;83self->drawGroup = Zone->objectDrawGroup[0];84self->drawFX |= FX_FLIP;85self->startPos = self->position;86self->startDir = self->direction;87self->active = ACTIVE_BOUNDS;88self->updateRange.x = 0x800000;89self->updateRange.y = 0x800000;9091#if MANIA_USE_PLUS92if (!self->nummoves)93self->nummoves = 3;9495if (data) {96RSDK.SetSpriteAnimation(MonkeyDude->aniFrames, 4, &self->bodyAnimator, true, 0);97self->state = MonkeyDude_State_Coconut;98}99else {100#endif101RSDK.SetSpriteAnimation(MonkeyDude->aniFrames, 0, &self->bodyAnimator, true, 0);102RSDK.SetSpriteAnimation(MonkeyDude->aniFrames, 3, &self->handAnimator, true, 0);103self->state = MonkeyDude_State_Init;104#if MANIA_USE_PLUS105}106#endif107}108109void MonkeyDude_StageLoad(void)110{111#if MANIA_USE_PLUS112MonkeyDude->aniFrames = RSDK.LoadSpriteAnimation("AIZ/MonkeyDude.bin", SCOPE_STAGE);113114MonkeyDude->hitboxBadnik.left = -10;115MonkeyDude->hitboxBadnik.top = -21;116MonkeyDude->hitboxBadnik.right = 7;117MonkeyDude->hitboxBadnik.bottom = 4;118119MonkeyDude->hitboxCoconut.left = -4;120MonkeyDude->hitboxCoconut.top = -4;121MonkeyDude->hitboxCoconut.right = 4;122MonkeyDude->hitboxCoconut.bottom = 4;123#else124MonkeyDude->aniFrames = RSDK.LoadSpriteAnimation("Blueprint/MonkeyDude.bin", SCOPE_STAGE);125126// strange hitbox, doesn't match either one above lol127MonkeyDude->hitboxBadnik.left = -8;128MonkeyDude->hitboxBadnik.top = -8;129MonkeyDude->hitboxBadnik.right = 8;130MonkeyDude->hitboxBadnik.bottom = 8;131#endif132133RSDK.SetSpriteAnimation(MonkeyDude->aniFrames, 2, &MonkeyDude->armAnimator, true, 0);134RSDK.SetSpriteAnimation(MonkeyDude->aniFrames, 1, &MonkeyDude->tailAnimator, true, 0);135RSDK.SetSpriteAnimation(MonkeyDude->aniFrames, 4, &MonkeyDude->coconutAnimator, true, 0);136137#if MANIA_USE_PLUS138MonkeyDude->sfxDrop = RSDK.GetSfx("Stage/Drop.wav");139#endif140141DEBUGMODE_ADD_OBJ(MonkeyDude);142}143144void MonkeyDude_DebugDraw(void)145{146#if MANIA_USE_PLUS147RSDK_THIS(MonkeyDude);148149RSDK.SetSpriteAnimation(MonkeyDude->aniFrames, 0, &self->bodyAnimator, true, 0);150RSDK.DrawSprite(&self->bodyAnimator, NULL, false);151#endif152}153154void MonkeyDude_DebugSpawn(void)155{156#if MANIA_USE_PLUS157RSDK_THIS(MonkeyDude);158159EntityMonkeyDude *monkeyDude = CREATE_ENTITY(MonkeyDude, NULL, self->position.x, self->position.y);160monkeyDude->direction = self->direction;161monkeyDude->startDir = self->direction;162#endif163}164165void MonkeyDude_State_Init(void)166{167RSDK_THIS(MonkeyDude);168self->armY = self->position.y;169self->active = ACTIVE_NORMAL;170self->velocity.y = 0x10000;171self->moveCount = 1;172self->timer = 1;173self->angleVel = 4;174self->activeArmNodes = 0;175self->throwCount = 0;176self->state = MonkeyDude_State_Laugh;177#if MANIA_USE_PLUS178RSDK.ProcessAnimation(&self->bodyAnimator);179#else180self->bodyAnimator.frameID = (self->coconutFrame++ >> 3) & 1;181#endif182if (--self->timer <= 0) {183self->coconutFrame = 0;184self->timer = 8;185self->state = MonkeyDude_State_MoveArm;186}187#if MANIA_USE_PLUS188MonkeyDude_HandleStates();189#endif190191int32 delay = 0;192for (int32 i = 0; i < MonkeyDude_ArmJointCount; ++i) {193self->armAngles[i] = 0;194self->armTimers[i] = delay;195self->armStates[i] = MonkeyDude_StateBody_ArmRaise;196197delay += 24 / (MonkeyDude_ArmJointCount - 1);198}199}200201void MonkeyDude_HandleBodyPart(void)202{203RSDK_THIS(MonkeyDude);204self->armTimers[self->armNodeID] = self->armNodeID;205switch (self->throwCount) {206case 0:207case 4:208self->angleVel = 4;209self->armTimers[self->armNodeID] *= 4;210self->armMoveDir[self->armNodeID] ^= 1;211212if (!self->armNodeID) {213self->currentAngle = self->armAngles[0];214if (self->armMoveDir[0]) {215self->currentAngle -= RSDK.Rand(0, 96);216if (self->currentAngle < 32)217self->currentAngle = 32;218}219else {220self->currentAngle += RSDK.Rand(0, 96);221if (self->currentAngle > 128)222self->currentAngle = 128;223}224}225if (self->armNodeID == MonkeyDude_ArmJointCount - 1)226self->activeArmNodes = 0;227break;228229case 1:230self->angleVel = 5;231self->armTimers[self->armNodeID] *= 2;232self->currentAngle = 176;233self->armMoveDir[self->armNodeID] = 0;234if (self->armNodeID == MonkeyDude_ArmJointCount - 1) {235++self->throwCount;236self->activeArmNodes = 0;237}238break;239240case 2:241self->armTimers[self->armNodeID] *= 2;242self->currentAngle = 96;243self->armMoveDir[self->armNodeID] = 1;244if (self->armNodeID == MonkeyDude_ArmJointCount - 1) {245++self->throwCount;246self->activeArmNodes = 0;247}248break;249}250251if (self->armNodeID == MonkeyDude_ArmJointCount - 1)252self->activeArmNodes = 0;253}254255#if MANIA_USE_PLUS256void MonkeyDude_HandleStates(void)257{258RSDK_THIS(MonkeyDude);259foreach_active(Player, player)260{261if (Player_CheckBadnikTouch(player, self, &MonkeyDude->hitboxBadnik))262Player_CheckBadnikBreak(player, self, true);263}264265if (self->classID) {266if (self->throwCount) {267if (self->throwCount == 3 && self->armAngles[MonkeyDude_ArmJointCount - 1] <= 164) {268int32 spawnX = self->position.x + 0xD0000;269if (!self->direction)270spawnX = self->position.x - 0xD0000;271int32 spawnY = self->position.y;272273for (int32 i = 0; i < MonkeyDude_ArmJointCount; ++i) {274if (self->direction)275spawnX += RSDK.Sin256(self->armAngles[i]) << 11;276else277spawnX -= RSDK.Sin256(self->armAngles[i]) << 11;278spawnY += (RSDK.Cos256(self->armAngles[i]) << 11);279}280281EntityMonkeyDude *coconut = CREATE_ENTITY(MonkeyDude, INT_TO_VOID(1), spawnX, spawnY);282if (!self->direction)283coconut->velocity.x = -0x20000;284else285coconut->velocity.x = 0x20000;286coconut->velocity.y = -0x40000;287coconut->direction = self->direction;288RSDK.PlaySfx(MonkeyDude->sfxDrop, false, 0xFF);289++self->throwCount;290}291}292else {293EntityPlayer *target = Player_GetNearestPlayer();294if (!self->direction) {295if (target->position.x < self->position.x) {296if (abs(self->position.x - target->position.x) <= 0x800000) {297if (target->position.y > self->position.y - 0x200000 && target->position.y - self->position.y <= 0x800000298&& self->onScreen == 1) {299self->throwCount = 1;300self->currentAngle = self->armAngles[0];301}302}303}304}305}306307for (self->armNodeID = 0; self->armNodeID < MonkeyDude_ArmJointCount; ++self->armNodeID) {308StateMachine_Run(self->armStates[self->armNodeID]);309}310311if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {312self->position = self->startPos;313self->direction = self->startDir;314MonkeyDude_Create(NULL);315}316}317}318#endif319320void MonkeyDude_State_Laugh(void)321{322RSDK_THIS(MonkeyDude);323#if MANIA_USE_PLUS324RSDK.ProcessAnimation(&self->bodyAnimator);325#else326self->bodyAnimator.frameID = (self->coconutFrame++ >> 3) & 1;327#endif328if (--self->timer <= 0) {329self->coconutFrame = 0;330self->timer = 8;331self->state = MonkeyDude_State_MoveArm;332}333#if MANIA_USE_PLUS334MonkeyDude_HandleStates();335#endif336}337338void MonkeyDude_State_MoveArm(void)339{340RSDK_THIS(MonkeyDude);341self->armY += self->velocity.y;342self->bodyAnimator.frameID = 0;343if (--self->timer <= 0) {344self->timer = 8;345self->state = MonkeyDude_State_MoveBody;346}347#if MANIA_USE_PLUS348MonkeyDude_HandleStates();349#endif350}351352void MonkeyDude_State_MoveBody(void)353{354RSDK_THIS(MonkeyDude);355self->position.y += self->velocity.y;356if (--self->timer <= 0) {357if (--self->moveCount > 0) {358self->timer = 8;359self->state = MonkeyDude_State_MoveArm;360}361else {362self->timer = 60;363self->velocity.y = -self->velocity.y;364self->moveCount = self->nummoves;365self->state = MonkeyDude_State_Laugh;366}367}368#if MANIA_USE_PLUS369MonkeyDude_HandleStates();370#endif371}372373void MonkeyDude_StateBody_ArmRaise(void)374{375RSDK_THIS(MonkeyDude);376if (self->activeArmNodes == ((1 << MonkeyDude_ArmJointCount) - 1)) {377self->armStates[self->armNodeID] = MonkeyDude_StateBody_Throw;378MonkeyDude_HandleBodyPart();379}380381if (self->armTimers[self->armNodeID]) {382self->armTimers[self->armNodeID]--;383}384else if (self->armAngles[self->armNodeID] >= 128) {385self->activeArmNodes |= (1 << self->armNodeID);386}387else {388self->armAngles[self->armNodeID] += self->angleVel;389}390}391392void MonkeyDude_StateBody_Throw(void)393{394RSDK_THIS(MonkeyDude);395if (self->activeArmNodes == ((1 << MonkeyDude_ArmJointCount) - 1))396MonkeyDude_HandleBodyPart();397398if (self->armTimers[self->armNodeID]) {399self->armTimers[self->armNodeID]--;400}401else {402if (self->armMoveDir[self->armNodeID]) {403if (self->armAngles[self->armNodeID] <= self->currentAngle) {404self->activeArmNodes |= (1 << self->armNodeID);405}406else {407self->armAngles[self->armNodeID] -= self->angleVel;408}409}410else {411if (self->armAngles[self->armNodeID] >= self->currentAngle) {412self->activeArmNodes |= (1 << self->armNodeID);413}414else {415self->armAngles[self->armNodeID] += self->angleVel;416}417}418}419}420421#if MANIA_USE_PLUS422void MonkeyDude_State_Coconut(void)423{424RSDK_THIS(MonkeyDude);425426self->position.x += self->velocity.x;427self->position.y += self->velocity.y;428self->velocity.y += 0x3800;429430if (RSDK.CheckOnScreen(self, NULL)) {431RSDK.ProcessAnimation(&self->bodyAnimator);432foreach_active(Player, player)433{434if (Player_CheckCollisionTouch(player, self, &MonkeyDude->hitboxCoconut))435Player_ProjectileHurt(player, self);436}437}438else {439destroyEntity(self);440}441}442#endif443444#if GAME_INCLUDE_EDITOR445void MonkeyDude_EditorDraw(void) { MonkeyDude_Draw(); }446447void MonkeyDude_EditorLoad(void)448{449#if MANIA_USE_PLUS450MonkeyDude->aniFrames = RSDK.LoadSpriteAnimation("AIZ/MonkeyDude.bin", SCOPE_STAGE);451#else452MonkeyDude->aniFrames = RSDK.LoadSpriteAnimation("Blueprint/MonkeyDude.bin", SCOPE_STAGE);453#endif454}455#endif456457void MonkeyDude_Serialize(void) { RSDK_EDITABLE_VAR(MonkeyDude, VAR_ENUM, nummoves); }458459460