Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/MSZ/Pinata.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: Pinata Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectPinata *Pinata;
11
12
void Pinata_Update(void)
13
{
14
RSDK_THIS(Pinata);
15
16
StateMachine_Run(self->state);
17
}
18
19
void Pinata_LateUpdate(void) {}
20
21
void Pinata_StaticUpdate(void) {}
22
23
void Pinata_Draw(void)
24
{
25
RSDK_THIS(Pinata);
26
27
RSDK.DrawSprite(&self->animator, NULL, false);
28
}
29
30
void Pinata_Create(void *data)
31
{
32
RSDK_THIS(Pinata);
33
34
self->drawGroup = self->priority != PINATA_PRIO_HIGH ? Zone->objectDrawGroup[0] : Zone->objectDrawGroup[1];
35
self->visible = true;
36
self->active = ACTIVE_BOUNDS;
37
self->updateRange.x = 0x400000;
38
self->updateRange.y = 0x400000;
39
self->state = Pinata_State_CheckPlayerCollisions;
40
41
RSDK.SetSpriteAnimation(Pinata->aniFrames, 3, &self->animator, true, 0);
42
}
43
44
void Pinata_StageLoad(void)
45
{
46
Pinata->aniFrames = RSDK.LoadSpriteAnimation("MSZ/Pinata.bin", SCOPE_STAGE);
47
48
Pinata->hitboxPinata.left = -12;
49
Pinata->hitboxPinata.top = -16;
50
Pinata->hitboxPinata.right = 12;
51
Pinata->hitboxPinata.bottom = 16;
52
53
Pinata->sfxPinata = RSDK.GetSfx("MSZ/Pinata.wav");
54
55
DEBUGMODE_ADD_OBJ(Pinata);
56
}
57
58
void Pinata_DebugDraw(void)
59
{
60
RSDK.SetSpriteAnimation(Pinata->aniFrames, 0, &DebugMode->animator, true, 0);
61
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
62
}
63
64
void Pinata_DebugSpawn(void)
65
{
66
RSDK_THIS(DebugMode);
67
68
CREATE_ENTITY(Pinata, NULL, self->position.x, self->position.y);
69
}
70
71
void Pinata_State_CheckPlayerCollisions(void)
72
{
73
RSDK_THIS(Pinata);
74
75
RSDK.ProcessAnimation(&self->animator);
76
77
foreach_active(Player, player)
78
{
79
if (player->animator.animationID != ANI_HURT && Player_CheckBadnikTouch(player, self, &Pinata->hitboxPinata)) {
80
RSDK.PlaySfx(Pinata->sfxPinata, false, 0xFF);
81
82
#if MANIA_USE_PLUS
83
if (player->state != Player_State_MightyHammerDrop) {
84
#endif
85
if (player->state == Player_State_FlyCarried)
86
RSDK_GET_ENTITY(SLOT_PLAYER2, Player)->flyCarryTimer = 30;
87
88
int32 anim = player->animator.animationID;
89
if (anim != ANI_FLY && anim != ANI_FLY_LIFT_TIRED) {
90
if (player->state != Player_State_TailsFlight) {
91
if (player->state != Player_State_DropDash)
92
player->state = Player_State_Air;
93
94
if (anim != ANI_JUMP && anim != ANI_JOG && anim != ANI_RUN && anim != ANI_DASH)
95
player->animator.animationID = ANI_WALK;
96
}
97
}
98
99
if (player->animator.animationID != ANI_FLY)
100
player->applyJumpCap = false;
101
102
if (player->velocity.y > -0x80000)
103
player->velocity.y = -0x80000;
104
105
player->onGround = false;
106
player->tileCollisions = TILECOLLISION_DOWN;
107
#if MANIA_USE_PLUS
108
}
109
#endif
110
CREATE_ENTITY(ScoreBonus, NULL, self->position.x, self->position.y)->animator.frameID = 16;
111
Player_GiveScore(player, 10);
112
CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_BOSSPUFF), self->position.x, self->position.y - 0x100000)->drawGroup =
113
Zone->objectDrawGroup[1];
114
115
for (int32 i = 0; i < 6; ++i) {
116
int32 x = self->position.x + RSDK.Rand(-0x80000, 0x80000);
117
int32 y = self->position.y + RSDK.Rand(-0x80000, 0x80000);
118
EntityDebris *debris = CREATE_ENTITY(Debris, NULL, x, y);
119
120
debris->state = Debris_State_Fall;
121
debris->gravityStrength = 0x4000;
122
debris->velocity.x = RSDK.Rand(0, 0x20000);
123
if (debris->position.x < self->position.x)
124
debris->velocity.x = -debris->velocity.x;
125
126
debris->velocity.y = RSDK.Rand(-0x40000, -0x10000);
127
debris->drawFX = FX_FLIP;
128
debris->direction = i & 3;
129
debris->drawGroup = Zone->objectDrawGroup[1];
130
RSDK.SetSpriteAnimation(Pinata->aniFrames, 0, &debris->animator, true, RSDK.Rand(0, 4));
131
}
132
133
self->state = Pinata_State_Destroyed;
134
self->visible = false;
135
self->active = ACTIVE_NORMAL;
136
}
137
}
138
}
139
140
void Pinata_State_Destroyed(void)
141
{
142
RSDK_THIS(Pinata);
143
144
Vector2 range = { TO_FIXED(256), TO_FIXED(256) };
145
if (!RSDK.CheckOnScreen(self, &range)) {
146
self->state = Pinata_State_CheckPlayerCollisions;
147
self->visible = true;
148
self->active = ACTIVE_BOUNDS;
149
}
150
}
151
152
#if GAME_INCLUDE_EDITOR
153
void Pinata_EditorDraw(void) { Pinata_Draw(); }
154
155
void Pinata_EditorLoad(void)
156
{
157
Pinata->aniFrames = RSDK.LoadSpriteAnimation("MSZ/Pinata.bin", SCOPE_STAGE);
158
159
RSDK_ACTIVE_VAR(Pinata, priority);
160
RSDK_ENUM_VAR("High", PINATA_PRIO_HIGH);
161
RSDK_ENUM_VAR("Low", PINATA_PRIO_LOW);
162
}
163
#endif
164
165
void Pinata_Serialize(void)
166
{
167
RSDK_EDITABLE_VAR(Pinata, VAR_BOOL, respawn);
168
RSDK_EDITABLE_VAR(Pinata, VAR_ENUM, priority);
169
}
170
171