Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/GHZ/SpikeLog.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: SpikeLog Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectSpikeLog *SpikeLog;
11
12
void SpikeLog_Update(void)
13
{
14
RSDK_THIS(SpikeLog);
15
StateMachine_Run(self->state);
16
}
17
18
void SpikeLog_LateUpdate(void) {}
19
20
void SpikeLog_StaticUpdate(void) { SpikeLog->timer = Zone->timer / 3 & 0x1F; }
21
22
void SpikeLog_Draw(void)
23
{
24
RSDK_THIS(SpikeLog);
25
RSDK.DrawSprite(&self->animator, NULL, false);
26
}
27
28
void SpikeLog_Create(void *data)
29
{
30
RSDK_THIS(SpikeLog);
31
self->drawFX |= FX_FLIP;
32
self->active = ACTIVE_BOUNDS;
33
self->visible = true;
34
self->updateRange.x = 0x400000;
35
self->updateRange.y = 0x400000;
36
if (!SceneInfo->inEditor)
37
self->frame *= 4;
38
self->drawGroup = Zone->objectDrawGroup[0];
39
RSDK.SetSpriteAnimation(SpikeLog->aniFrames, 0, &self->animator, true, 0);
40
self->state = SpikeLog_State_Main;
41
}
42
43
void SpikeLog_StageLoad(void)
44
{
45
if (RSDK.CheckSceneFolder("GHZ"))
46
SpikeLog->aniFrames = RSDK.LoadSpriteAnimation("GHZ/SpikeLog.bin", SCOPE_STAGE);
47
48
SpikeLog->hitboxSpikeLog.left = -8;
49
SpikeLog->hitboxSpikeLog.top = -16;
50
SpikeLog->hitboxSpikeLog.right = 8;
51
SpikeLog->hitboxSpikeLog.bottom = 0;
52
53
SpikeLog->hitboxBurnLog.left = -9;
54
SpikeLog->hitboxBurnLog.top = -16;
55
SpikeLog->hitboxBurnLog.right = 9;
56
SpikeLog->hitboxBurnLog.bottom = 0;
57
}
58
59
void SpikeLog_State_Main(void)
60
{
61
RSDK_THIS(SpikeLog);
62
self->animator.frameID = (self->frame + SpikeLog->timer) & 0x1F;
63
foreach_active(Player, player)
64
{
65
if (player->shield != SHIELD_FIRE || player->invincibleTimer) {
66
if ((self->animator.frameID & 0xFFFFFFFC) != 8)
67
continue;
68
69
if (Player_CheckCollisionTouch(player, self, &SpikeLog->hitboxSpikeLog)) {
70
#if MANIA_USE_PLUS
71
if (player->characterID == ID_MIGHTY) {
72
int32 anim = player->animator.animationID;
73
if (anim == ANI_JUMP || anim == ANI_SPINDASH || anim == ANI_HAMMERDROP) {
74
if (!player->invincibleTimer && player->blinkTimer <= 0) {
75
if (abs(player->velocity.x) < 0x10000 || !player->groundedStore) {
76
player->velocity.y = -0x48000;
77
player->onGround = false;
78
player->applyJumpCap = false;
79
player->jumpAbilityState = 0;
80
RSDK.SetSpriteAnimation(player->aniFrames, ANI_UNSPIN, &player->animator, false, 0);
81
RSDK.PlaySfx(Player->sfxMightyUnspin, false, 255);
82
}
83
84
if (!player->uncurlTimer) {
85
player->uncurlTimer = 15;
86
RSDK.PlaySfx(Player->sfxPimPom, false, 255);
87
}
88
}
89
}
90
else if (player->animator.animationID != ANI_UNSPIN)
91
Player_Hurt(player, self);
92
}
93
else {
94
#endif
95
Player_Hurt(player, self);
96
#if MANIA_USE_PLUS
97
}
98
#endif
99
}
100
}
101
else if (Player_CheckCollisionTouch(player, self, &SpikeLog->hitboxSpikeLog)) {
102
if (!SpikeLog->hasAchievement) {
103
API_UnlockAchievement(&achievementList[ACH_GHZ]);
104
105
SpikeLog->hasAchievement = true;
106
}
107
CREATE_ENTITY(BurningLog, INT_TO_VOID(16), self->position.x, self->position.y);
108
RSDK.SetTile(Zone->fgLayer[0], self->position.x >> 20, self->position.y >> 20, -1);
109
self->frame = 8;
110
self->state = SpikeLog_State_Burn;
111
}
112
}
113
}
114
115
void SpikeLog_State_Burn(void)
116
{
117
RSDK_THIS(SpikeLog);
118
if (!--self->frame) {
119
foreach_all(SpikeLog, other)
120
{
121
if (other->state == SpikeLog_State_Main
122
&& RSDK.CheckObjectCollisionTouchBox(other, &SpikeLog->hitboxBurnLog, self, &SpikeLog->hitboxBurnLog)) {
123
CREATE_ENTITY(BurningLog, INT_TO_VOID(16), other->position.x, other->position.y);
124
RSDK.SetTile(Zone->fgLayer[0], other->position.x >> 20, other->position.y >> 20, -1);
125
other->frame = 8;
126
other->state = SpikeLog_State_Burn;
127
other->active = ACTIVE_NORMAL;
128
}
129
}
130
destroyEntity(self);
131
}
132
}
133
134
#if GAME_INCLUDE_EDITOR
135
void SpikeLog_EditorDraw(void)
136
{
137
RSDK_THIS(SpikeLog);
138
self->animator.frameID = self->frame * 4;
139
RSDK.DrawSprite(&self->animator, NULL, false);
140
}
141
142
void SpikeLog_EditorLoad(void) { SpikeLog->aniFrames = RSDK.LoadSpriteAnimation("GHZ/SpikeLog.bin", SCOPE_STAGE); }
143
#endif
144
145
void SpikeLog_Serialize(void) { RSDK_EDITABLE_VAR(SpikeLog, VAR_UINT8, frame); }
146
147