Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/MSZ/MSZSpotlight.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: MSZSpotlight Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectMSZSpotlight *MSZSpotlight;
11
12
void MSZSpotlight_Update(void)
13
{
14
RSDK_THIS(MSZSpotlight);
15
16
StateMachine_Run(self->state);
17
}
18
19
void MSZSpotlight_LateUpdate(void) {}
20
21
void MSZSpotlight_StaticUpdate(void) {}
22
23
void MSZSpotlight_Draw(void)
24
{
25
RSDK_THIS(MSZSpotlight);
26
27
RSDK.DrawSprite(&self->animatorSpotlight, NULL, false);
28
}
29
30
void MSZSpotlight_Create(void *data)
31
{
32
RSDK_THIS(MSZSpotlight);
33
34
if (!SceneInfo->inEditor) {
35
self->visible = true;
36
self->drawGroup = Zone->objectDrawGroup[1];
37
self->startPos = self->position;
38
self->inkEffect = INK_ADD;
39
self->angle = RSDK.Rand(0, 256);
40
41
switch (self->color) {
42
case MSZSPOTLIGHT_RED: self->angleOffset = -4; break;
43
case MSZSPOTLIGHT_GREEN: self->angleOffset = 4; break;
44
case MSZSPOTLIGHT_BLUE: self->angleOffset = 2; break;
45
}
46
47
self->active = ACTIVE_BOUNDS;
48
self->updateRange.x = 0x800000;
49
self->updateRange.y = 0x800000;
50
RSDK.SetSpriteAnimation(MSZSpotlight->aniFrames, 9, &self->animatorSpotlight, true, self->color);
51
}
52
}
53
54
void MSZSpotlight_StageLoad(void)
55
{
56
MSZSpotlight->aniFrames = RSDK.LoadSpriteAnimation("MSZ/HeavyMystic.bin", SCOPE_STAGE);
57
58
// Yeah, this is actually here in the original
59
// This (& the one in FBZSetup) is how I found out about what these funcs do LOL
60
RSDK_ACTIVE_VAR(MSZSpotlight, color);
61
RSDK_ENUM_VAR("Red", MSZSPOTLIGHT_RED);
62
RSDK_ENUM_VAR("Green", MSZSPOTLIGHT_GREEN);
63
RSDK_ENUM_VAR("Blue", MSZSPOTLIGHT_BLUE);
64
}
65
66
void MSZSpotlight_State_Appear(void)
67
{
68
RSDK_THIS(MSZSpotlight);
69
70
self->angle = (self->angle & 0xFF) + self->angleOffset;
71
self->position.x = (RSDK.Cos256(self->angle) << 13) + self->startPos.x;
72
self->position.y = (RSDK.Sin256(self->angle) << 13) + self->startPos.y;
73
74
if (self->alpha >= 0x100)
75
self->state = MSZSpotlight_State_Circling;
76
else
77
self->alpha += 8;
78
}
79
80
void MSZSpotlight_State_Circling(void)
81
{
82
RSDK_THIS(MSZSpotlight);
83
84
self->angle = (self->angle & 0xFF) + self->angleOffset;
85
self->position.x = (RSDK.Cos256(self->angle) << 13) + self->startPos.x;
86
self->position.y = (RSDK.Sin256(self->angle) << 13) + self->startPos.y;
87
88
if (++self->timer == 120) {
89
self->timer = 0;
90
self->state = MSZSpotlight_State_Idle;
91
}
92
}
93
94
void MSZSpotlight_State_Idle(void)
95
{
96
RSDK_THIS(MSZSpotlight);
97
98
if (++self->timer == 30) {
99
self->timer = 0;
100
foreach_active(HeavyMystic, mystic)
101
{
102
if (mystic->type == MYSTIC_BOX) {
103
self->startPos.x = mystic->position.x;
104
self->startPos.y = mystic->position.y;
105
}
106
}
107
108
self->velocity.x = (self->startPos.x - self->position.x) >> 4;
109
self->velocity.y = (self->startPos.y - self->position.y) >> 4;
110
self->state = MSZSpotlight_State_MoveToBox;
111
}
112
}
113
114
void MSZSpotlight_State_MoveToBox(void)
115
{
116
RSDK_THIS(MSZSpotlight);
117
118
self->position.x += self->velocity.x;
119
self->position.y += self->velocity.y;
120
121
int32 rx = (self->startPos.x - self->position.x) >> 16;
122
int32 ry = (self->startPos.y - self->position.y) >> 16;
123
124
if (rx * rx + ry * ry < 16) {
125
foreach_active(HeavyMystic, mystic)
126
{
127
if (mystic->type == MYSTIC_BOX && mystic->state != HeavyMystic_StateBox_CloseDoors) {
128
mystic->state = HeavyMystic_StateBox_CloseDoors;
129
RSDK.PlaySfx(HeavyMystic->sfxClack, false, 255);
130
}
131
}
132
133
self->position.x = self->startPos.x;
134
self->position.y = self->startPos.y;
135
self->drawFX = FX_SCALE;
136
self->scale.x = 0x200;
137
self->scale.y = 0x200;
138
self->state = MSZSpotlight_State_Disappear;
139
}
140
}
141
142
void MSZSpotlight_State_Disappear(void)
143
{
144
RSDK_THIS(MSZSpotlight);
145
146
self->scale.x += 0x20;
147
self->scale.y += 0x20;
148
149
if (self->scale.x < 0x300)
150
self->alpha = 0x100;
151
152
if (self->alpha <= 0)
153
destroyEntity(self);
154
else
155
self->alpha -= 0x10;
156
}
157
158
#if GAME_INCLUDE_EDITOR
159
void MSZSpotlight_EditorDraw(void)
160
{
161
RSDK_THIS(MSZSpotlight);
162
163
RSDK.SetSpriteAnimation(MSZSpotlight->aniFrames, 9, &self->animatorSpotlight, true, self->color);
164
RSDK.DrawSprite(&self->animatorSpotlight, NULL, false);
165
}
166
167
void MSZSpotlight_EditorLoad(void)
168
{
169
MSZSpotlight->aniFrames = RSDK.LoadSpriteAnimation("MSZ/HeavyMystic.bin", SCOPE_STAGE);
170
171
RSDK_ACTIVE_VAR(MSZSpotlight, color);
172
RSDK_ENUM_VAR("Red", MSZSPOTLIGHT_RED);
173
RSDK_ENUM_VAR("Green", MSZSPOTLIGHT_GREEN);
174
RSDK_ENUM_VAR("Blue", MSZSPOTLIGHT_BLUE);
175
}
176
#endif
177
178
void MSZSpotlight_Serialize(void) { RSDK_EDITABLE_VAR(MSZSpotlight, VAR_UINT8, color); }
179
180