Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/ERZ/RingField.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: RingField Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectRingField *RingField;
11
12
void RingField_Update(void)
13
{
14
RSDK_THIS(RingField);
15
16
if (self->running) {
17
bool32 inRange = false;
18
foreach_active(Player, player)
19
{
20
if (Player_CheckCollisionTouch(player, self, &self->hitbox)) {
21
inRange = true;
22
}
23
}
24
25
if (inRange) {
26
if (self->timer <= 0) {
27
Vector2 pos;
28
RingField_GetRingSpawnPos(&pos);
29
30
EntityRing *ring = CREATE_ENTITY(Ring, &pos, pos.x, pos.y);
31
ring->animator.speed = 512;
32
ring->state = Ring_State_Normal;
33
ring->drawGroup = Zone->objectDrawGroup[0];
34
ring->stateDraw = Ring_Draw_Normal;
35
ring->moveType = RING_MOVE_FIXED;
36
RSDK.SetSpriteAnimation(RingField->aniFrames, 0, &ring->animator, true, 0);
37
38
int32 sx = (ScreenInfo->center.x + ScreenInfo->position.x) << 16;
39
int32 sy = (ScreenInfo->position.y + ScreenInfo->center.y) << 16;
40
int32 x = sx + (RSDK.Rand(-ScreenInfo->center.x, ScreenInfo->center.x) << 15);
41
int32 y = sy + (RSDK.Rand(-ScreenInfo->center.y, ScreenInfo->center.y) << 15);
42
43
int32 angle = RSDK.ATan2(x - pos.x, y - pos.y);
44
ring->velocity.x = RSDK.Cos256(angle) << 9;
45
ring->velocity.y = RSDK.Sin256(angle) << 9;
46
self->timer = (self->fluctuation * RSDK.Sin256(Zone->timer) >> 8) + self->frequency;
47
}
48
else {
49
self->timer--;
50
}
51
}
52
}
53
}
54
55
void RingField_LateUpdate(void) {}
56
57
void RingField_StaticUpdate(void)
58
{
59
Vector2 range = { 0x400000, 0x400000 };
60
61
foreach_all(Ring, ring)
62
{
63
if (ring->velocity.x || ring->velocity.y) {
64
ring->position.x += ring->velocity.x;
65
ring->position.y += ring->velocity.y;
66
}
67
68
if (!RSDK.CheckOnScreen(ring, &range))
69
destroyEntity(ring);
70
}
71
}
72
73
void RingField_Draw(void) {}
74
75
void RingField_Create(void *data)
76
{
77
RSDK_THIS(RingField);
78
79
self->active = ACTIVE_NORMAL;
80
self->drawGroup = Zone->objectDrawGroup[0];
81
self->startPos = self->position;
82
self->visible = false;
83
self->drawFX = FX_FLIP;
84
self->updateRange.x = 0x800000;
85
self->updateRange.y = 0x800000;
86
87
if (!self->size.x)
88
self->size.x = 1600 << 16;
89
90
if (!self->size.y)
91
self->size.y = 480 << 16;
92
93
if (!self->frequency)
94
self->frequency = 60;
95
96
if (!self->fluctuation)
97
self->fluctuation = 20;
98
99
self->hitbox.left = -self->size.x >> 17;
100
self->hitbox.top = -self->size.y >> 17;
101
self->hitbox.right = self->size.x >> 17;
102
self->hitbox.bottom = self->size.y >> 17;
103
}
104
105
void RingField_StageLoad(void) { RingField->aniFrames = RSDK.LoadSpriteAnimation("Global/Ring.bin", SCOPE_STAGE); }
106
107
void RingField_GetRingSpawnPos(Vector2 *pos)
108
{
109
int32 rand = RSDK.Rand(0, 16) % 4;
110
int32 x = 0;
111
int32 y = 0;
112
113
switch (rand) {
114
case 0:
115
case 1:
116
y = RSDK.Rand(-ScreenInfo->size.y, ScreenInfo->size.y) << 15;
117
118
switch (rand) {
119
case 0: x += -0x100000 - (ScreenInfo->center.x << 16); break;
120
case 1: x += (ScreenInfo->center.x + 16) << 16; break;
121
case 2: y += -0x100000 - (ScreenInfo->center.y << 16); break;
122
case 3: y += (ScreenInfo->center.y + 16) << 16; break;
123
default: break;
124
}
125
break;
126
127
case 2:
128
case 3:
129
x = RSDK.Rand(-ScreenInfo->size.x, ScreenInfo->size.x) << 15;
130
131
switch (rand) {
132
case 0: x += -0x100000 - (ScreenInfo->center.x << 16); break;
133
case 1: x += (ScreenInfo->center.x + 16) << 16; break;
134
case 2: y += -0x100000 - (ScreenInfo->center.y << 16); break;
135
case 3: y += (ScreenInfo->center.y + 16) << 16; break;
136
default: break;
137
}
138
break;
139
140
default: break;
141
}
142
143
pos->x = x + ((ScreenInfo->position.x + ScreenInfo->center.x) << 16);
144
pos->y = y + ((ScreenInfo->position.y + ScreenInfo->center.y) << 16);
145
}
146
147
#if GAME_INCLUDE_EDITOR
148
void RingField_EditorDraw(void)
149
{
150
RSDK_THIS(RingField);
151
152
if (showGizmos()) {
153
RSDK_DRAWING_OVERLAY(true);
154
155
if (!self->size.x)
156
self->size.x = 1600 << 16;
157
158
if (!self->size.y)
159
self->size.y = 480 << 16;
160
161
DrawHelpers_DrawRectOutline(self->position.x, self->position.y, self->size.x, self->size.y, 0xFFFF00);
162
163
RSDK_DRAWING_OVERLAY(false);
164
}
165
}
166
167
void RingField_EditorLoad(void) {}
168
#endif
169
170
void RingField_Serialize(void)
171
{
172
RSDK_EDITABLE_VAR(RingField, VAR_VECTOR2, size);
173
RSDK_EDITABLE_VAR(RingField, VAR_ENUM, frequency);
174
RSDK_EDITABLE_VAR(RingField, VAR_ENUM, fluctuation);
175
RSDK_EDITABLE_VAR(RingField, VAR_BOOL, running);
176
}
177
178