Path: blob/master/SonicMania/Objects/GHZ/Newtron.c
338 views
// ---------------------------------------------------------------------1// RSDK Project: Sonic Mania2// Object Description: Newtron Object3// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges4// Decompiled by: Rubberduckycooly & RMGRich5// ---------------------------------------------------------------------67#include "Game.h"89ObjectNewtron *Newtron;1011void Newtron_Update(void)12{13RSDK_THIS(Newtron);14StateMachine_Run(self->state);15}1617void Newtron_LateUpdate(void) {}1819void Newtron_StaticUpdate(void) {}2021void Newtron_Draw(void)22{23RSDK_THIS(Newtron);24RSDK.DrawSprite(&self->animator, NULL, false);25if (self->state == Newtron_State_Fly)26RSDK.DrawSprite(&self->flameAnimator, NULL, false);27}2829void Newtron_Create(void *data)30{31RSDK_THIS(Newtron);32if (!SceneInfo->inEditor) {33self->drawFX |= FX_FLIP;34self->startPos = self->position;35self->visible = true;3637if (data == INT_TO_VOID(NEWTRON_FLY)) {38self->type = NEWTRON_FLY;39self->active = ACTIVE_BOUNDS;40self->updateRange.x = 0x800000;41self->updateRange.y = 0x800000;42}43else if (data) {44self->inkEffect = INK_ADD;45self->alpha = 0xC0;46RSDK.SetSpriteAnimation(Newtron->aniFrames, 6, &self->animator, true, 0);47self->state = Newtron_State_Projectile;48self->active = ACTIVE_NORMAL;49self->updateRange.x = 0x200000;50self->updateRange.y = 0x200000;51self->drawGroup = Zone->objectDrawGroup[1];52return;53}5455self->inkEffect = INK_ALPHA;56self->alpha = 0x00;57self->active = ACTIVE_BOUNDS;58self->updateRange.x = 0x800000;59self->updateRange.y = 0x800000;60if (self->type == NEWTRON_FLY) {61RSDK.SetSpriteAnimation(Newtron->aniFrames, 2, &self->animator, true, 0);62self->drawGroup = Zone->objectDrawGroup[0];63}64else {65RSDK.SetSpriteAnimation(Newtron->aniFrames, 0, &self->animator, true, 0);66self->drawGroup = Zone->objectDrawGroup[1];67}68RSDK.SetSpriteAnimation(Newtron->aniFrames, 5, &self->flameAnimator, true, 0);69self->state = Newtron_State_Init;70}71}7273void Newtron_StageLoad(void)74{75if (RSDK.CheckSceneFolder("GHZ"))76Newtron->aniFrames = RSDK.LoadSpriteAnimation("GHZ/Newtron.bin", SCOPE_STAGE);7778Newtron->hitboxShoot.left = -12;79Newtron->hitboxShoot.top = -14;80Newtron->hitboxShoot.right = 12;81Newtron->hitboxShoot.bottom = 14;8283// hitbox for the flying variant84// goes unused in this object because..... ???85// at least GHZ/CheckerBall uses it86Newtron->hitboxFly.left = -16;87Newtron->hitboxFly.top = -8;88Newtron->hitboxFly.right = 16;89Newtron->hitboxFly.bottom = 8;9091Newtron->hitboxProjectile.left = -6;92Newtron->hitboxProjectile.top = -6;93Newtron->hitboxProjectile.right = 6;94Newtron->hitboxProjectile.bottom = 6;9596Newtron->hitboxRange.left = -128;97Newtron->hitboxRange.top = -64;98Newtron->hitboxRange.right = 128;99Newtron->hitboxRange.bottom = 64;100101DEBUGMODE_ADD_OBJ(Newtron);102}103104void Newtron_DebugDraw(void)105{106RSDK.SetSpriteAnimation(Newtron->aniFrames, 0, &DebugMode->animator, true, 0);107RSDK.DrawSprite(&DebugMode->animator, NULL, false);108}109110void Newtron_DebugSpawn(void)111{112RSDK_THIS(DebugMode);113114CREATE_ENTITY(Newtron, NULL, self->position.x, self->position.y);115}116117void Newtron_CheckPlayerCollisions(void)118{119RSDK_THIS(Newtron);120121foreach_active(Player, player)122{123if (Player_CheckBadnikTouch(player, self, &Newtron->hitboxShoot))124Player_CheckBadnikBreak(player, self, true);125}126}127128void Newtron_CheckOffScreen(void)129{130RSDK_THIS(Newtron);131132if (!RSDK.CheckOnScreen(self, NULL) && !RSDK.CheckPosOnScreen(&self->startPos, &self->updateRange)) {133self->position = self->startPos;134self->velocity.x = 0;135self->velocity.y = 0;136self->timer = 0;137Newtron_Create(NULL);138}139}140141void Newtron_GetTargetDir(void)142{143RSDK_THIS(Newtron);144145EntityPlayer *targetPlayer = NULL;146foreach_active(Player, player)147{148if (targetPlayer) {149if (abs(player->position.x - self->position.x) < abs(targetPlayer->position.x - self->position.x))150targetPlayer = player;151}152else {153targetPlayer = player;154}155}156157if (targetPlayer)158self->direction = targetPlayer->position.x < self->position.x;159}160161void Newtron_State_Init(void)162{163RSDK_THIS(Newtron);164165self->active = ACTIVE_NORMAL;166167self->state = Newtron_State_CheckPlayerInRange;168Newtron_State_CheckPlayerInRange();169}170171void Newtron_State_CheckPlayerInRange(void)172{173RSDK_THIS(Newtron);174175foreach_active(Player, player)176{177if (Player_CheckCollisionTouch(player, self, &Newtron->hitboxRange))178self->state = Newtron_State_Appear;179}180181Newtron_CheckOffScreen();182}183184void Newtron_State_Appear(void)185{186RSDK_THIS(Newtron);187188if (self->alpha >= 0xF8) {189self->alpha = 0xFF;190if (self->type == NEWTRON_FLY) {191self->state = Newtron_State_StartFly;192RSDK.SetSpriteAnimation(Newtron->aniFrames, 3, &self->animator, true, 0);193}194else195self->state = Newtron_State_Shoot;196}197else {198self->alpha += 4;199if (self->type == NEWTRON_FLY)200Newtron_GetTargetDir();201}202203RSDK.ProcessAnimation(&self->animator);204205Newtron_CheckOffScreen();206}207208void Newtron_State_StartFly(void)209{210RSDK_THIS(Newtron);211212Newtron_GetTargetDir();213214if (self->animator.frameID >= 2) {215self->position.y += self->velocity.y;216self->velocity.y += 0x3800;217218if (RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x80000, 8)) {219self->velocity.y = 0;220if (self->direction == FLIP_NONE)221self->velocity.x = 0x20000;222else223self->velocity.x = -0x20000;224RSDK.SetSpriteAnimation(Newtron->aniFrames, 4, &self->animator, true, 0);225self->state = Newtron_State_Fly;226}227}228229RSDK.ProcessAnimation(&self->animator);230231Newtron_CheckPlayerCollisions();232Newtron_CheckOffScreen();233}234235void Newtron_State_Fly(void)236{237RSDK_THIS(Newtron);238239self->position.x += self->velocity.x;240RSDK.ObjectTileGrip(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, 0x80000, 8);241242RSDK.ProcessAnimation(&self->animator);243RSDK.ProcessAnimation(&self->flameAnimator);244245Newtron_CheckPlayerCollisions();246Newtron_CheckOffScreen();247}248249void Newtron_State_Shoot(void)250{251RSDK_THIS(Newtron);252253switch (++self->timer) {254case 30:255RSDK.SetSpriteAnimation(Newtron->aniFrames, 1, &self->animator, true, 0);256if (self->direction)257CREATE_ENTITY(Newtron, INT_TO_VOID(NEWTRON_PROJECTILE), self->position.x - 0x140000, self->position.y - 0x80000)->velocity.x =258-0x20000;259else260CREATE_ENTITY(Newtron, INT_TO_VOID(NEWTRON_PROJECTILE), self->position.x + 0x140000, self->position.y - 0x80000)->velocity.x =2610x20000;262break;263264case 45: RSDK.SetSpriteAnimation(Newtron->aniFrames, 0, &self->animator, true, 0); break;265266case 90: self->state = Newtron_State_FadeAway; break;267}268269RSDK.ProcessAnimation(&self->animator);270271Newtron_CheckPlayerCollisions();272Newtron_CheckOffScreen();273}274275void Newtron_State_FadeAway(void)276{277RSDK_THIS(Newtron);278279RSDK.ProcessAnimation(&self->animator);280Newtron_CheckOffScreen();281282if (self->alpha <= 0)283destroyEntity(self);284else285self->alpha -= 4;286}287288void Newtron_State_Projectile(void)289{290RSDK_THIS(Newtron);291292self->position.x += self->velocity.x;293294if (!RSDK.CheckOnScreen(self, NULL)) {295destroyEntity(self);296}297else {298RSDK.ProcessAnimation(&self->animator);299300foreach_active(Player, player)301{302if (Player_CheckCollisionTouch(player, self, &Newtron->hitboxProjectile))303Player_ProjectileHurt(player, self);304}305}306}307308#if GAME_INCLUDE_EDITOR309void Newtron_EditorDraw(void)310{311RSDK_THIS(Newtron);312313self->drawFX = FX_FLIP;314if (self->type == NEWTRON_FLY)315RSDK.SetSpriteAnimation(Newtron->aniFrames, 2, &self->animator, true, 0);316else317RSDK.SetSpriteAnimation(Newtron->aniFrames, 0, &self->animator, true, 0);318RSDK.SetSpriteAnimation(Newtron->aniFrames, 5, &self->flameAnimator, true, 0);319320Newtron_Draw();321}322323void Newtron_EditorLoad(void)324{325Newtron->aniFrames = RSDK.LoadSpriteAnimation("GHZ/Newtron.bin", SCOPE_STAGE);326327RSDK_ACTIVE_VAR(Newtron, type);328RSDK_ENUM_VAR("Shoot", NEWTRON_SHOOT);329RSDK_ENUM_VAR("Fly", NEWTRON_FLY);330331// Only for "Shoot" Variant, fly variant direction is based on the target's position332RSDK_ACTIVE_VAR(Newtron, direction);333RSDK_ENUM_VAR("Right", FLIP_NONE);334RSDK_ENUM_VAR("Left", FLIP_X);335}336#endif337338void Newtron_Serialize(void)339{340RSDK_EDITABLE_VAR(Newtron, VAR_UINT8, type);341RSDK_EDITABLE_VAR(Newtron, VAR_UINT8, direction);342}343344345