Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/TMZ/LargeGear.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: LargeGear Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectLargeGear *LargeGear;
11
12
void LargeGear_Update(void)
13
{
14
RSDK_THIS(LargeGear);
15
16
self->angle = self->rotOffset + self->rotSpeed * Zone->timer;
17
18
int32 storeX = self->position.x;
19
int32 storeY = self->position.y;
20
21
foreach_active(Player, player)
22
{
23
int32 playerID = RSDK.GetEntitySlot(player);
24
25
int32 id = 0;
26
int32 storedID = -1;
27
bool32 collided = false;
28
29
for (int32 angle = 0x180; angle < 0x380; angle += 0x40) {
30
int32 ang = angle + self->angle;
31
int32 x = (storeX + 0x2400 * RSDK.Cos512(ang)) & 0xFFFF0000;
32
int32 y = (storeY + 0x2400 * RSDK.Sin512(ang)) & 0xFFFF0000;
33
34
if (((1 << playerID) & self->activePlayers) && self->playerIDs[playerID] == id) {
35
player->position.x += x - self->positions[id].x;
36
player->position.y += y - self->positions[id].y;
37
}
38
39
self->position.x = x;
40
self->position.y = y;
41
42
if (Player_CheckCollisionBox(player, self, &LargeGear->hitboxTooth) == C_TOP) {
43
collided = true;
44
storedID = id;
45
}
46
47
self->positions[id].x = x;
48
self->positions[id++].y = y;
49
}
50
51
self->position.x = storeX;
52
self->position.y = storeY;
53
54
if (Player_CheckCollisionBox(player, self, &LargeGear->hitboxBase) == C_TOP) {
55
collided = true;
56
storedID = -1;
57
self->activePlayers |= 1 << playerID;
58
}
59
else {
60
if (collided)
61
self->activePlayers |= 1 << playerID;
62
else
63
self->activePlayers &= ~(1 << playerID);
64
}
65
66
self->playerIDs[playerID] = storedID;
67
if (collided) {
68
Hitbox *playerHitbox = Player_GetHitbox(player);
69
70
RSDK.ObjectTileCollision(player, player->collisionLayers, CMODE_RWALL, self->collisionPlane, playerHitbox->left << 16, 0, true);
71
RSDK.ObjectTileCollision(player, player->collisionLayers, CMODE_LWALL, self->collisionPlane, playerHitbox->right << 16, 0, true);
72
RSDK.ObjectTileCollision(player, player->collisionLayers, CMODE_FLOOR, self->collisionPlane, playerHitbox->bottom << 16, 0, true);
73
}
74
}
75
76
self->position.x = storeX;
77
self->position.y = storeY;
78
79
RSDK.ProcessAnimation(&self->baseAnimator);
80
}
81
82
void LargeGear_LateUpdate(void) {}
83
84
void LargeGear_StaticUpdate(void) {}
85
86
void LargeGear_Draw(void)
87
{
88
RSDK_THIS(LargeGear);
89
90
for (int32 i = 0; i < 0x200; i += 0x40) {
91
self->rotation = i + self->angle;
92
93
RSDK.SetSpriteAnimation(LargeGear->aniFrames, 1, &self->toothAnimator, true, 7 - abs(RSDK.Sin512(self->rotation) / 73));
94
95
RSDK.DrawSprite(&self->toothAnimator, NULL, false);
96
RSDK.Cos512(self->rotation + 0x180);
97
RSDK.Sin512(self->rotation + 0x180);
98
self->rotation = 0;
99
}
100
101
self->rotation = 0;
102
RSDK.DrawSprite(&self->baseAnimator, NULL, false);
103
104
self->rotation = self->angle;
105
RSDK.DrawSprite(&self->centerAnimator, NULL, false);
106
107
self->rotation = 0;
108
RSDK.DrawSprite(&self->axleAnimator, NULL, false);
109
110
for (int32 i = 0; i < 0x200; i += 0x80) {
111
int32 angle = i + self->angle;
112
113
Vector2 drawPos = self->position;
114
115
drawPos.x += 0x1300 * RSDK.Cos512(angle);
116
drawPos.y += 0x1300 * RSDK.Sin512(angle);
117
RSDK.DrawSprite(&self->rivetAnimator, &drawPos, false);
118
}
119
}
120
121
void LargeGear_Create(void *data)
122
{
123
RSDK_THIS(LargeGear);
124
125
self->active = ACTIVE_BOUNDS;
126
self->drawGroup = Zone->objectDrawGroup[0];
127
self->origin = self->position;
128
self->visible = true;
129
self->drawFX = FX_ROTATE | FX_FLIP;
130
self->updateRange.x = 0x800000;
131
self->updateRange.y = 0x800000;
132
133
RSDK.SetSpriteAnimation(LargeGear->aniFrames, 0, &self->baseAnimator, true, 0);
134
RSDK.SetSpriteAnimation(LargeGear->aniFrames, 1, &self->toothAnimator, true, 0);
135
RSDK.SetSpriteAnimation(LargeGear->aniFrames, 2, &self->axleAnimator, true, 0);
136
RSDK.SetSpriteAnimation(LargeGear->aniFrames, 3, &self->centerAnimator, true, 0);
137
RSDK.SetSpriteAnimation(LargeGear->aniFrames, 4, &self->rivetAnimator, true, 0);
138
139
self->angle = self->rotOffset;
140
}
141
142
void LargeGear_StageLoad(void)
143
{
144
LargeGear->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/LargeGear.bin", SCOPE_STAGE);
145
146
LargeGear->hitboxTooth.left = -10;
147
LargeGear->hitboxTooth.top = -10;
148
LargeGear->hitboxTooth.right = 10;
149
LargeGear->hitboxTooth.bottom = 10;
150
151
LargeGear->hitboxBase.left = -8;
152
LargeGear->hitboxBase.top = -64;
153
LargeGear->hitboxBase.right = 8;
154
LargeGear->hitboxBase.bottom = 64;
155
}
156
157
#if GAME_INCLUDE_EDITOR
158
void LargeGear_EditorDraw(void)
159
{
160
RSDK_THIS(LargeGear);
161
162
self->origin = self->position;
163
self->angle = self->rotOffset;
164
165
LargeGear_Draw();
166
}
167
168
void LargeGear_EditorLoad(void) { LargeGear->aniFrames = RSDK.LoadSpriteAnimation("TMZ1/LargeGear.bin", SCOPE_STAGE); }
169
#endif
170
171
void LargeGear_Serialize(void)
172
{
173
RSDK_EDITABLE_VAR(LargeGear, VAR_INT32, rotSpeed);
174
RSDK_EDITABLE_VAR(LargeGear, VAR_INT32, rotOffset);
175
}
176
177