Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/ERZ/PhantomShield.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: PhantomShield Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectPhantomShield *PhantomShield;
11
12
void PhantomShield_Update(void)
13
{
14
RSDK_THIS(PhantomShield);
15
16
if (self->parent) {
17
self->position.x = self->parent->position.x;
18
self->position.y = self->parent->position.y;
19
}
20
21
if (self->blendAmount > 0)
22
self->blendAmount -= 0x20;
23
24
StateMachine_Run(self->state);
25
}
26
27
void PhantomShield_LateUpdate(void) {}
28
29
void PhantomShield_StaticUpdate(void) {}
30
31
void PhantomShield_Draw(void)
32
{
33
RSDK_THIS(PhantomShield);
34
35
if (self->blendAmount > 0)
36
RSDK.SetLimitedFade(0, 1, 3, self->blendAmount, 136, 143);
37
38
self->direction = RSDK.GetFrameID(&self->animator) == 'b' ? FLIP_Y : FLIP_NONE;
39
RSDK.DrawSprite(&self->animator, NULL, false);
40
41
if (self->blendAmount > 0)
42
RSDK.CopyPalette(1, 136, 0, 136, 8);
43
}
44
45
void PhantomShield_Create(void *data)
46
{
47
RSDK_THIS(PhantomShield);
48
49
if (!SceneInfo->inEditor) {
50
self->visible = true;
51
self->drawGroup = Zone->objectDrawGroup[0];
52
self->parent = (Entity *)data;
53
self->active = ACTIVE_NORMAL;
54
self->drawFX = FX_FLIP;
55
self->inkEffect = INK_ADD;
56
self->alpha = 0x100;
57
self->scale.x = 0x200;
58
self->scale.y = 0x200;
59
self->updateRange.x = 0x800000;
60
self->updateRange.y = 0x800000;
61
self->state = PhantomShield_State_Appear;
62
RSDK.SetSpriteAnimation(PhantomShield->aniFrames, 0, &self->animator, true, 0);
63
}
64
}
65
66
void PhantomShield_StageLoad(void)
67
{
68
PhantomShield->aniFrames = RSDK.LoadSpriteAnimation("Phantom/EggShield.bin", SCOPE_STAGE);
69
70
PhantomShield->hitbox.left = -32;
71
PhantomShield->hitbox.top = -32;
72
PhantomShield->hitbox.right = 32;
73
PhantomShield->hitbox.bottom = 32;
74
}
75
76
void PhantomShield_State_Appear(void)
77
{
78
RSDK_THIS(PhantomShield);
79
80
RSDK.ProcessAnimation(&self->animator);
81
if (!self->shieldActive) {
82
self->shieldActive = true;
83
RSDK.PlaySfx(PhantomEgg->sfxShield, false, 255);
84
}
85
86
if (self->animator.frameID == self->animator.frameCount - 1) {
87
RSDK.SetSpriteAnimation(PhantomShield->aniFrames, 1, &self->animator, true, 0);
88
self->shieldActive = false;
89
self->state = PhantomShield_State_Active;
90
}
91
}
92
93
void PhantomShield_State_Active(void)
94
{
95
RSDK_THIS(PhantomShield);
96
97
RSDK.ProcessAnimation(&self->animator);
98
99
foreach_active(Player, player)
100
{
101
if (self->playerTimer[player->playerID])
102
self->playerTimer[player->playerID]--;
103
104
if (Player_CheckCollisionTouch(player, self, &PhantomShield->hitbox)) {
105
if (Player_CheckAttacking(player, self)) {
106
self->blendAmount = 256;
107
if (!self->playerTimer[player->playerID]) {
108
RSDK.PlaySfx(PhantomEgg->sfxRepel, false, 255);
109
self->playerTimer[player->playerID] = 16;
110
}
111
112
int32 angle = RSDK.ATan2(player->position.x - self->position.x, player->position.y - self->position.y);
113
int32 velX = 0x500 * RSDK.Cos256(angle);
114
int32 velY = 0x500 * RSDK.Sin256(angle);
115
116
if (player->state == Player_State_FlyCarried)
117
RSDK_GET_ENTITY(SLOT_PLAYER2, Player)->flyCarryTimer = 30;
118
119
int32 anim = player->animator.animationID;
120
if (anim != ANI_FLY && anim != ANI_FLY_LIFT_TIRED) {
121
if (player->state != Player_State_TailsFlight) {
122
if (player->state != Player_State_DropDash)
123
player->state = Player_State_Air;
124
if (anim != ANI_JUMP && anim != ANI_JOG && anim != ANI_RUN && anim != ANI_DASH)
125
player->animator.animationID = ANI_WALK;
126
}
127
}
128
129
if (player->characterID == ID_KNUCKLES && player->animator.animationID == ANI_GLIDE) {
130
RSDK.SetSpriteAnimation(player->aniFrames, ANI_GLIDE_DROP, &player->animator, false, 0);
131
player->state = Player_State_KnuxGlideDrop;
132
}
133
134
player->groundVel = velX;
135
player->velocity.x = velX;
136
player->velocity.y = velY;
137
player->applyJumpCap = false;
138
player->onGround = false;
139
player->tileCollisions = TILECOLLISION_DOWN;
140
}
141
else {
142
Player_Hurt(player, self);
143
}
144
}
145
}
146
}
147
148
void PhantomShield_State_Disappear(void)
149
{
150
RSDK_THIS(PhantomShield);
151
152
RSDK.ProcessAnimation(&self->animator);
153
if (self->animator.frameID == self->animator.frameCount - 1)
154
destroyEntity(self);
155
}
156
157
#if GAME_INCLUDE_EDITOR
158
void PhantomShield_EditorDraw(void)
159
{
160
RSDK_THIS(PhantomShield);
161
RSDK.SetSpriteAnimation(PhantomShield->aniFrames, 1, &self->animator, true, 0);
162
163
self->direction = RSDK.GetFrameID(&self->animator) == 'b' ? FLIP_Y : FLIP_NONE;
164
RSDK.DrawSprite(&self->animator, NULL, false);
165
}
166
167
void PhantomShield_EditorLoad(void) { PhantomShield->aniFrames = RSDK.LoadSpriteAnimation("Phantom/EggShield.bin", SCOPE_STAGE); }
168
#endif
169
170
void PhantomShield_Serialize(void) {}
171
172