Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/Global/ItemBox.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: ItemBox Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectItemBox *ItemBox;
11
12
void ItemBox_Update(void)
13
{
14
RSDK_THIS(ItemBox);
15
16
StateMachine_Run(self->state);
17
18
#if MANIA_USE_PLUS
19
if (self->type == ITEMBOX_STOCK) {
20
if (self->contentsAnimator.animationID == 2 || self->contentsAnimator.animationID == 7 || self->contentsAnimator.animationID == 8) {
21
if (globals->characterFlags == 0x1F && globals->gameMode == MODE_ENCORE) {
22
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 8, &self->contentsAnimator, false, 0);
23
}
24
else {
25
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 7, &self->contentsAnimator, false, 0);
26
if (globals->gameMode == MODE_ENCORE) {
27
int32 id = 0;
28
while ((1 << self->contentsAnimator.frameID) & globals->characterFlags) {
29
if (++self->contentsAnimator.frameID > 4)
30
self->contentsAnimator.frameID = 0;
31
if (++id > 5) {
32
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 8, &self->contentsAnimator, false, 0);
33
LogHelpers_PrintText("Bad Change Item State");
34
}
35
}
36
}
37
}
38
}
39
}
40
#endif
41
}
42
43
void ItemBox_LateUpdate(void) {}
44
45
void ItemBox_StaticUpdate(void)
46
{
47
// Handle The Contents outline scrolling
48
if (!(Zone->timer & 3)) {
49
RSDK.RotatePalette(0, 60, 63, true);
50
RSDK.RotatePalette(1, 60, 63, true);
51
}
52
}
53
54
void ItemBox_Draw(void)
55
{
56
RSDK_THIS(ItemBox);
57
58
if (!self->hidden) {
59
if (self->isContents) {
60
if (SceneInfo->currentDrawGroup == Zone->playerDrawGroup[1]) {
61
self->drawFX = FX_NONE;
62
RSDK.DrawSprite(&self->contentsAnimator, &self->contentsPos, false);
63
}
64
else {
65
self->drawFX = FX_FLIP;
66
self->inkEffect = INK_NONE;
67
RSDK.DrawSprite(&self->boxAnimator, NULL, false);
68
69
RSDK.AddDrawListRef(Zone->playerDrawGroup[1], SceneInfo->entitySlot);
70
}
71
}
72
else {
73
self->inkEffect = INK_NONE;
74
RSDK.DrawSprite(&self->boxAnimator, NULL, false);
75
RSDK.DrawSprite(&self->contentsAnimator, &self->contentsPos, false);
76
77
self->inkEffect = INK_ADD;
78
RSDK.DrawSprite(&self->overlayAnimator, NULL, false);
79
80
self->inkEffect = INK_NONE;
81
RSDK.DrawSprite(&self->debrisAnimator, NULL, false);
82
}
83
}
84
}
85
86
void ItemBox_Create(void *data)
87
{
88
RSDK_THIS(ItemBox);
89
90
if (data)
91
self->type = VOID_TO_INT(data);
92
93
if (self->state != ItemBox_State_Broken) {
94
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 0, &self->boxAnimator, true, 0);
95
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 2, &self->contentsAnimator, true, 0);
96
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 3, &self->overlayAnimator, true, 0);
97
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 4, &self->debrisAnimator, true, 0);
98
99
EntityPlayer *player = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
100
switch (self->type) {
101
case ITEMBOX_1UP_SONIC:
102
case ITEMBOX_1UP_TAILS:
103
case ITEMBOX_1UP_KNUX:
104
#if MANIA_USE_PLUS
105
case ITEMBOX_1UP_MIGHTY:
106
case ITEMBOX_1UP_RAY:
107
#endif
108
if (globals->gameMode == MODE_TIMEATTACK) {
109
self->type = ITEMBOX_RING;
110
}
111
#if MANIA_USE_PLUS
112
else if (globals->gameMode == MODE_ENCORE) {
113
self->type = ITEMBOX_STOCK;
114
}
115
#endif
116
else {
117
switch (player->characterID) {
118
case ID_SONIC: self->type = ITEMBOX_1UP_SONIC; break;
119
case ID_TAILS: self->type = ITEMBOX_1UP_TAILS; break;
120
case ID_KNUCKLES: self->type = ITEMBOX_1UP_KNUX; break;
121
#if MANIA_USE_PLUS
122
case ID_MIGHTY: self->type = ITEMBOX_1UP_MIGHTY; break;
123
case ID_RAY: self->type = ITEMBOX_1UP_RAY; break;
124
#endif
125
default: break;
126
}
127
}
128
self->contentsAnimator.frameID = self->type;
129
break;
130
131
#if MANIA_USE_PLUS
132
case ITEMBOX_SWAP:
133
case ITEMBOX_RANDOM:
134
if (globals->gameMode == MODE_ENCORE || globals->gameMode == MODE_COMPETITION)
135
self->contentsAnimator.frameID = self->type;
136
else
137
destroyEntity(self);
138
#endif
139
break;
140
141
default: self->contentsAnimator.frameID = self->type; break;
142
}
143
}
144
145
self->drawFX = FX_FLIP;
146
if (!SceneInfo->inEditor) {
147
self->direction *= FLIP_Y;
148
self->active = ACTIVE_BOUNDS;
149
self->updateRange.x = TO_FIXED(64);
150
self->updateRange.y = TO_FIXED(64);
151
self->visible = true;
152
if (self->planeFilter > 0 && ((uint8)self->planeFilter - 1) & 2)
153
self->drawGroup = Zone->objectDrawGroup[1];
154
else
155
self->drawGroup = Zone->objectDrawGroup[0];
156
157
self->alpha = 0xFF;
158
if (self->state == ItemBox_State_Broken) {
159
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 1, &self->boxAnimator, true, self->boxAnimator.frameID);
160
}
161
else if (self->hidden) {
162
self->state = StateMachine_None;
163
}
164
else if (self->isFalling) {
165
self->active = ACTIVE_NORMAL;
166
self->state = ItemBox_State_Falling;
167
}
168
else if (LRZConvItem && self->lrzConvPhys) {
169
self->active = ACTIVE_NORMAL;
170
self->state = ItemBox_State_Conveyor;
171
}
172
else {
173
self->state = ItemBox_State_Idle;
174
}
175
}
176
}
177
178
void ItemBox_StageLoad(void)
179
{
180
ItemBox->aniFrames = RSDK.LoadSpriteAnimation("Global/ItemBox.bin", SCOPE_STAGE);
181
182
ItemBox->hitboxItemBox.left = -15;
183
ItemBox->hitboxItemBox.top = -16;
184
ItemBox->hitboxItemBox.right = 15;
185
ItemBox->hitboxItemBox.bottom = 16;
186
187
ItemBox->hitboxHidden.left = -15;
188
ItemBox->hitboxHidden.top = -24;
189
ItemBox->hitboxHidden.right = 15;
190
ItemBox->hitboxHidden.bottom = 16;
191
192
DEBUGMODE_ADD_OBJ(ItemBox);
193
194
if (globals->gameMode == MODE_COMPETITION) {
195
if (globals->itemMode == ITEMS_RANDOM) {
196
foreach_all(ItemBox, entity) { entity->type = ITEMBOX_RANDOM; }
197
}
198
else if (globals->itemMode == ITEMS_TELEPORT) {
199
foreach_all(ItemBox, entity) { entity->type = ITEMBOX_SWAP; }
200
}
201
}
202
203
ItemBox->sfxDestroy = RSDK.GetSfx("Global/Destroy.wav");
204
ItemBox->sfxTeleport = RSDK.GetSfx("Global/Teleport.wav");
205
ItemBox->sfxHyperRing = RSDK.GetSfx("Global/HyperRing.wav");
206
#if MANIA_USE_PLUS
207
ItemBox->sfxPowerDown = RSDK.GetSfx("Stage/PowerDown.wav");
208
ItemBox->sfxRecovery = RSDK.GetSfx("Global/Recovery.wav");
209
#endif
210
}
211
212
void ItemBox_DebugDraw(void)
213
{
214
RSDK_THIS(ItemBox);
215
216
DebugMode->itemTypeCount = ITEMBOX_COUNT;
217
218
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 0, &DebugMode->animator, true, 0);
219
RSDK.DrawSprite(&DebugMode->animator, NULL, false);
220
221
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 2, &DebugMode->animator, true, DebugMode->itemType);
222
223
Vector2 drawPos;
224
drawPos.x = self->position.x;
225
drawPos.y = self->position.y - TO_FIXED(3);
226
RSDK.DrawSprite(&DebugMode->animator, &drawPos, false);
227
}
228
void ItemBox_DebugSpawn(void)
229
{
230
RSDK_THIS(DebugMode);
231
232
EntityItemBox *itemBox = CREATE_ENTITY(ItemBox, NULL, self->position.x, self->position.y);
233
itemBox->type = DebugMode->itemType;
234
itemBox->contentsAnimator.frameID = DebugMode->itemType;
235
}
236
237
void ItemBox_State_Broken(void)
238
{
239
RSDK_THIS(ItemBox);
240
241
if (LRZConvItem)
242
LRZConvItem_HandleLRZConvPhys(self);
243
else
244
ItemBox_HandleFallingCollision();
245
}
246
void ItemBox_State_Break(void)
247
{
248
RSDK_THIS(ItemBox);
249
250
if (LRZConvItem && self->lrzConvPhys)
251
LRZConvItem_HandleLRZConvPhys(self);
252
else
253
ItemBox_HandleFallingCollision();
254
255
if (self->contentsSpeed < 0) {
256
self->contentsPos.y += self->contentsSpeed;
257
self->contentsSpeed += 0x1800;
258
}
259
260
if (self->contentsSpeed >= 0) {
261
self->contentsSpeed = 0;
262
263
ItemBox_GivePowerup();
264
265
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 5, &self->contentsAnimator, true, 0);
266
self->state = ItemBox_State_IconFinish;
267
}
268
}
269
270
void ItemBox_State_IconFinish(void)
271
{
272
RSDK_THIS(ItemBox);
273
274
if (LRZConvItem && self->lrzConvPhys)
275
LRZConvItem_HandleLRZConvPhys(self);
276
else
277
ItemBox_HandleFallingCollision();
278
279
RSDK.ProcessAnimation(&self->contentsAnimator);
280
281
if (self->contentsAnimator.frameID == self->contentsAnimator.frameCount - 1) {
282
RSDK.SetSpriteAnimation(-1, 0, &self->contentsAnimator, true, 0);
283
self->state = ItemBox_State_Broken;
284
}
285
}
286
287
void ItemBox_State_Idle(void)
288
{
289
RSDK_THIS(ItemBox);
290
291
self->contentsPos.x = self->position.x;
292
293
if (self->direction == FLIP_NONE)
294
self->contentsPos.y = self->position.y - TO_FIXED(3);
295
else
296
self->contentsPos.y = self->position.y + TO_FIXED(3);
297
298
ItemBox_HandleObjectCollisions();
299
ItemBox_CheckHit();
300
301
RSDK.ProcessAnimation(&self->overlayAnimator);
302
303
#if MANIA_USE_PLUS
304
if (self->type == ITEMBOX_STOCK) {
305
RSDK.ProcessAnimation(&self->contentsAnimator);
306
307
if (!API.CheckDLC(DLC_PLUS) && self->contentsAnimator.frameID >= 3)
308
self->contentsAnimator.frameID = 0;
309
}
310
#endif
311
312
if (self->timer) {
313
self->timer--;
314
}
315
else {
316
RSDK.ProcessAnimation(&self->debrisAnimator);
317
318
if (!self->debrisAnimator.frameID) {
319
self->timer = RSDK.Rand(1, 15);
320
self->debrisAnimator.frameDuration = RSDK.Rand(1, 32);
321
}
322
}
323
}
324
void ItemBox_State_Falling(void)
325
{
326
RSDK_THIS(ItemBox);
327
328
if (ItemBox_HandleFallingCollision())
329
self->state = ItemBox_State_Idle;
330
331
self->contentsPos.x = self->position.x;
332
if (self->direction == FLIP_NONE)
333
self->contentsPos.y = self->position.y - TO_FIXED(3);
334
else
335
self->contentsPos.y = self->position.y + TO_FIXED(3);
336
337
ItemBox_CheckHit();
338
RSDK.ProcessAnimation(&self->overlayAnimator);
339
340
#if MANIA_USE_PLUS
341
if (self->type == ITEMBOX_STOCK) {
342
RSDK.ProcessAnimation(&self->contentsAnimator);
343
344
if (!API.CheckDLC(DLC_PLUS) && self->contentsAnimator.frameID >= 3)
345
self->contentsAnimator.frameID = 0;
346
}
347
#endif
348
349
if (self->timer) {
350
self->timer--;
351
}
352
else {
353
RSDK.ProcessAnimation(&self->debrisAnimator);
354
355
if (!self->debrisAnimator.frameID) {
356
self->timer = RSDK.Rand(1, 15);
357
self->debrisAnimator.frameDuration = RSDK.Rand(1, 32);
358
}
359
}
360
}
361
void ItemBox_State_Conveyor(void)
362
{
363
RSDK_THIS(ItemBox);
364
365
self->moveOffset = LRZConvItem_HandleLRZConvPhys(self);
366
self->contentsPos.x = self->position.x;
367
if (self->direction == FLIP_NONE)
368
self->contentsPos.y = self->position.y - TO_FIXED(3);
369
else
370
self->contentsPos.y = self->position.y + TO_FIXED(3);
371
372
ItemBox_CheckHit();
373
374
RSDK.ProcessAnimation(&self->overlayAnimator);
375
376
#if MANIA_USE_PLUS
377
if (self->type == ITEMBOX_STOCK) {
378
RSDK.ProcessAnimation(&self->contentsAnimator);
379
380
if (!API.CheckDLC(DLC_PLUS) && self->contentsAnimator.frameID >= 3)
381
self->contentsAnimator.frameID = 0;
382
}
383
#endif
384
385
if (self->timer) {
386
self->timer--;
387
}
388
else {
389
RSDK.ProcessAnimation(&self->debrisAnimator);
390
391
if (!self->debrisAnimator.frameID) {
392
self->timer = RSDK.Rand(1, 15);
393
self->debrisAnimator.frameDuration = RSDK.Rand(1, 32);
394
}
395
}
396
}
397
398
void ItemBox_CheckHit(void)
399
{
400
RSDK_THIS(ItemBox);
401
402
foreach_active(Player, player)
403
{
404
if (self->planeFilter <= 0 || player->collisionPlane == (((uint8)self->planeFilter - 1) & 1)) {
405
#if MANIA_USE_PLUS
406
if (player->characterID == ID_MIGHTY && player->jumpAbilityState > 1 && !self->parent) {
407
if (RSDK.CheckObjectCollisionTouchCircle(player, TO_FIXED(256), self, TO_FIXED(16))) {
408
if (self->position.y - TO_FIXED(128) < player->position.y && self->state != ItemBox_State_Falling) {
409
self->active = ACTIVE_NORMAL;
410
if (!self->lrzConvPhys)
411
self->state = ItemBox_State_Falling;
412
self->velocity.y = -TO_FIXED(2);
413
}
414
}
415
}
416
#endif
417
418
int32 anim = player->animator.animationID;
419
bool32 attacking =
420
anim == ANI_JUMP && (player->velocity.y >= 0 || player->onGround || self->direction || player->state == Ice_PlayerState_Frozen);
421
switch (player->characterID) {
422
case ID_SONIC: attacking |= anim == ANI_DROPDASH; break;
423
case ID_KNUCKLES: attacking |= anim == ANI_GLIDE || anim == ANI_GLIDE_SLIDE; break;
424
#if MANIA_USE_PLUS
425
case ID_MIGHTY: attacking |= anim == ANI_HAMMERDROP || player->jumpAbilityState > 1; break;
426
#endif
427
}
428
429
if (attacking && !player->sidekick) {
430
if (Player_CheckBadnikTouch(player, self, &ItemBox->hitboxItemBox)) {
431
ItemBox_Break(self, player);
432
foreach_break;
433
}
434
}
435
else {
436
self->position.x -= self->moveOffset.x;
437
self->position.y -= self->moveOffset.y;
438
int32 px = player->position.x;
439
int32 py = player->position.y;
440
441
uint8 side = Player_CheckCollisionBox(player, self, &ItemBox->hitboxItemBox);
442
443
player->position.x = px;
444
player->position.y = py;
445
self->position.x += self->moveOffset.x;
446
self->position.y += self->moveOffset.y;
447
448
if (side == C_BOTTOM) {
449
self->active = ACTIVE_NORMAL;
450
451
if (!self->lrzConvPhys)
452
self->state = ItemBox_State_Falling;
453
454
self->velocity.y = -TO_FIXED(2);
455
456
if (!player->onGround)
457
player->velocity.y = TO_FIXED(2);
458
}
459
else if (side == C_TOP) {
460
player->position.x += self->moveOffset.x;
461
player->position.y += self->moveOffset.y;
462
}
463
464
if (Player_CheckCollisionBox(player, self, &ItemBox->hitboxItemBox) == C_BOTTOM) {
465
if (player->onGround) {
466
player->position.x = px;
467
player->position.y = py;
468
}
469
}
470
}
471
}
472
}
473
}
474
void ItemBox_GivePowerup(void)
475
{
476
RSDK_THIS(ItemBox);
477
478
EntityPlayer *player = (EntityPlayer *)self->storedEntity;
479
480
switch (self->type) {
481
case ITEMBOX_RING: Player_GiveRings(player, 10, true); break;
482
483
case ITEMBOX_BLUESHIELD:
484
player->shield = SHIELD_BLUE;
485
Player_ApplyShield(player);
486
RSDK.PlaySfx(Shield->sfxBlueShield, false, 255);
487
break;
488
489
case ITEMBOX_BUBBLESHIELD:
490
player->shield = SHIELD_BUBBLE;
491
Player_ApplyShield(player);
492
RSDK.PlaySfx(Shield->sfxBubbleShield, false, 255);
493
player->drownTimer = 0;
494
Music_JingleFadeOut(TRACK_DROWNING, false);
495
break;
496
497
case ITEMBOX_FIRESHIELD:
498
player->shield = SHIELD_FIRE;
499
Player_ApplyShield(player);
500
RSDK.PlaySfx(Shield->sfxFireShield, false, 255);
501
break;
502
503
case ITEMBOX_LIGHTNINGSHIELD:
504
player->shield = SHIELD_LIGHTNING;
505
Player_ApplyShield(player);
506
RSDK.PlaySfx(Shield->sfxLightningShield, false, 255);
507
break;
508
509
case ITEMBOX_INVINCIBLE:
510
if (player->superState == SUPERSTATE_NONE) {
511
EntityInvincibleStars *invincibleStars = RSDK_GET_ENTITY(Player->playerCount + RSDK.GetEntitySlot(player), InvincibleStars);
512
RSDK.ResetEntity(invincibleStars, InvincibleStars->classID, player);
513
player->invincibleTimer = 1260;
514
Music_PlayJingle(TRACK_INVINCIBLE);
515
}
516
break;
517
518
case ITEMBOX_SNEAKERS:
519
player->speedShoesTimer = 1320;
520
Player_UpdatePhysicsState(player);
521
if (player->superState == SUPERSTATE_NONE) {
522
Music_PlayJingle(TRACK_SNEAKERS);
523
EntityImageTrail *powerup = RSDK_GET_ENTITY(2 * Player->playerCount + RSDK.GetEntitySlot(player), ImageTrail);
524
RSDK.ResetEntity(powerup, ImageTrail->classID, player);
525
}
526
break;
527
528
case ITEMBOX_1UP_SONIC:
529
case ITEMBOX_1UP_TAILS:
530
case ITEMBOX_1UP_KNUX:
531
#if MANIA_USE_PLUS
532
case ITEMBOX_1UP_MIGHTY:
533
case ITEMBOX_1UP_RAY:
534
#endif
535
Player_GiveLife(player);
536
break;
537
538
case ITEMBOX_EGGMAN: Player_Hurt(player, self); break;
539
540
case ITEMBOX_HYPERRING:
541
RSDK.PlaySfx(ItemBox->sfxHyperRing, false, 255);
542
player->hyperRing = true;
543
break;
544
545
case ITEMBOX_SWAP:
546
#if MANIA_USE_PLUS
547
if (globals->gameMode == MODE_ENCORE) {
548
if (!globals->stock || player->animator.animationID == ANI_TRANSFORM) {
549
RSDK.PlaySfx(Player->sfxSwapFail, false, 255);
550
}
551
else {
552
int32 charID = player->characterID;
553
Player_ChangeCharacter(player, GET_STOCK_ID(1));
554
globals->stock >>= 8;
555
556
if (GET_STOCK_ID(1)) {
557
charID <<= 8;
558
if (GET_STOCK_ID(2))
559
charID <<= 8;
560
}
561
globals->stock |= charID;
562
EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), player->position.x, player->position.y);
563
explosion->drawGroup = Zone->objectDrawGroup[1];
564
RSDK.PlaySfx(ItemBox->sfxPowerDown, false, 255);
565
}
566
}
567
else if (globals->gameMode != MODE_COMPETITION) {
568
RSDK.PlaySfx(Player->sfxSwapFail, false, 255);
569
}
570
else {
571
#endif
572
Zone_StartTeleportAction();
573
RSDK.PlaySfx(ItemBox->sfxTeleport, false, 255);
574
#if MANIA_USE_PLUS
575
}
576
#endif
577
break;
578
579
#if MANIA_USE_PLUS
580
case ITEMBOX_RANDOM: {
581
uint8 playerIDs[5] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
582
uint8 newPlayerIDs[5] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
583
584
if (player->animator.animationID == ANI_TRANSFORM) {
585
RSDK.PlaySfx(Player->sfxSwapFail, false, 255);
586
}
587
else {
588
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
589
EntityPlayer *player2 = RSDK_GET_ENTITY(SLOT_PLAYER2, Player);
590
591
playerIDs[0] = HUD_CharacterIndexFromID(player1->characterID);
592
playerIDs[1] = HUD_CharacterIndexFromID(player2->characterID);
593
594
if (playerIDs[1] == 0xFF) {
595
RSDK.PlaySfx(Player->sfxSwapFail, false, 255);
596
}
597
else {
598
for (int32 i = 1; i < 4; ++i) {
599
if (GET_STOCK_ID(i)) {
600
playerIDs[1 + i] = HUD_CharacterIndexFromID(GET_STOCK_ID(i));
601
}
602
}
603
604
globals->stock = ID_NONE;
605
606
int32 tempStock = 0;
607
int32 p = 0;
608
for (; p < 5;) {
609
bool32 inc = true;
610
if (playerIDs[p] == 0xFF)
611
break;
612
613
newPlayerIDs[p] = RSDK.Rand(0, 5);
614
if ((1 << newPlayerIDs[p]) & globals->characterFlags) {
615
while (true) {
616
if (!((1 << newPlayerIDs[p]) & tempStock)) {
617
if (newPlayerIDs[p] != playerIDs[p]) {
618
tempStock |= 1 << newPlayerIDs[p];
619
break;
620
}
621
else if (p == 4 || playerIDs[p + 1] == 0xFF) {
622
int32 slot = RSDK.Rand(0, p);
623
int32 id = newPlayerIDs[slot];
624
newPlayerIDs[slot] = newPlayerIDs[p];
625
newPlayerIDs[p] = id;
626
tempStock |= 1 << newPlayerIDs[slot];
627
tempStock |= 1 << newPlayerIDs[p];
628
break;
629
}
630
else {
631
newPlayerIDs[p] = RSDK.Rand(0, 5);
632
if (!((1 << newPlayerIDs[p]) & globals->characterFlags)) {
633
inc = false;
634
break;
635
}
636
}
637
}
638
else {
639
newPlayerIDs[p] = RSDK.Rand(0, 5);
640
if (!((1 << newPlayerIDs[p]) & globals->characterFlags)) {
641
inc = false;
642
break;
643
}
644
}
645
}
646
647
if (inc)
648
++p;
649
}
650
}
651
652
for (int32 i = 0; i < p; ++i) {
653
switch (i) {
654
case 0: Player_ChangeCharacter(player1, 1 << newPlayerIDs[0]); break;
655
case 1: Player_ChangeCharacter(player2, 1 << newPlayerIDs[1]); break;
656
default:
657
globals->stock <<= 8;
658
globals->stock |= 1 << newPlayerIDs[i];
659
break;
660
}
661
}
662
663
EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), player1->position.x, player1->position.y);
664
explosion->drawGroup = Zone->objectDrawGroup[1];
665
666
explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), player2->position.x, player2->position.y);
667
explosion->drawGroup = Zone->objectDrawGroup[1];
668
669
RSDK.PlaySfx(ItemBox->sfxPowerDown, false, 255);
670
}
671
}
672
break;
673
}
674
#endif
675
676
case ITEMBOX_SUPER:
677
Player_GiveRings(player, 50, false);
678
Player_TryTransform(player, 0x7F);
679
break;
680
681
#if MANIA_USE_PLUS
682
case ITEMBOX_STOCK: {
683
if (self->contentsAnimator.animationID == 7) {
684
if (globals->gameMode == MODE_ENCORE) {
685
if (!((1 << self->contentsAnimator.frameID) & globals->characterFlags) && globals->characterFlags != 0x1F && !GET_STOCK_ID(3)) {
686
globals->characterFlags |= 1 << self->contentsAnimator.frameID;
687
EntityPlayer *player2 = RSDK_GET_ENTITY(SLOT_PLAYER2, Player);
688
if (player2->classID) {
689
for (int32 s = 0; s < 3; ++s) {
690
int32 id = HUD_CharacterIndexFromID(GET_STOCK_ID(1 + s));
691
if (id < 0) {
692
globals->stock |= (1 << self->contentsAnimator.frameID) << (8 * s);
693
HUD->stockFlashTimers[1 + s] = 2 * 60;
694
break;
695
}
696
}
697
}
698
else {
699
player2->classID = Player->classID;
700
Player->respawnTimer = 0;
701
EntityDust *dust = CREATE_ENTITY(Dust, INT_TO_VOID(1), player2->position.x, player2->position.y);
702
703
dust->visible = false;
704
dust->active = ACTIVE_NEVER;
705
dust->isPermanent = true;
706
dust->position.y = TO_FIXED(ScreenInfo->position.y - 128);
707
player2->playerID = 1;
708
EntityPlayer *player1 = RSDK_GET_ENTITY(SLOT_PLAYER1, Player);
709
if (player1->state == Player_State_Death || player1->state == Player_State_Drown) {
710
player2->state = Player_State_EncoreRespawn;
711
player2->velocity.x = 0;
712
player2->velocity.y = 0;
713
player2->position.x = -TO_FIXED(32);
714
player2->position.y = -TO_FIXED(32);
715
break;
716
}
717
else {
718
Player_ChangeCharacter(player2, 1 << self->contentsAnimator.frameID);
719
player2->velocity.x = 0;
720
player2->velocity.y = 0;
721
player2->groundVel = 0;
722
player2->position.x = -TO_FIXED(64);
723
player2->position.y = -TO_FIXED(64);
724
player2->angle = 0x80;
725
if (player2->characterID == ID_TAILS) {
726
player2->state = Player_State_FlyToPlayer;
727
}
728
else {
729
player2->state = Player_State_ReturnToPlayer;
730
player2->abilityValues[0] = ((ScreenInfo->position.y + ScreenInfo->size.y + 16) << 16) - player->position.y;
731
player2->drawFX |= FX_SCALE;
732
player2->scale.x = 0x400;
733
player2->scale.y = 0x400;
734
player2->velocity.y = CLAMP(player2->abilityValues[0] / -12, -0xE0000, -0x68000);
735
}
736
player2->abilityPtrs[0] = dust;
737
player2->abilityValues[0] = 0;
738
player2->nextAirState = StateMachine_None;
739
player2->nextGroundState = StateMachine_None;
740
player2->stateInput = Player_Input_P2_Delay;
741
player2->tileCollisions = TILECOLLISION_NONE;
742
player2->interaction = false;
743
player2->drawGroup = Zone->playerDrawGroup[1];
744
player2->drownTimer = 0;
745
player2->active = ACTIVE_NORMAL;
746
player2->collisionPlane = 0;
747
player2->collisionMode = CMODE_FLOOR;
748
player2->collisionLayers = Zone->collisionLayers;
749
player2->controllerID = CONT_P2;
750
player2->sidekick = true;
751
player2->drawFX = FX_FLIP | FX_ROTATE;
752
player2->visible = true;
753
HUD->stockFlashTimers[0] = 2 * 60;
754
}
755
}
756
}
757
758
RSDK.PlaySfx(ItemBox->sfxRecovery, false, 255);
759
}
760
else {
761
switch (self->contentsAnimator.frameID) {
762
case 0: Player_ChangeCharacter(player, ID_SONIC); break;
763
case 1: Player_ChangeCharacter(player, ID_TAILS); break;
764
case 2: Player_ChangeCharacter(player, ID_KNUCKLES); break;
765
case 3: Player_ChangeCharacter(player, ID_MIGHTY); break;
766
case 4: Player_ChangeCharacter(player, ID_RAY); break;
767
default: break;
768
}
769
770
EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ENEMY), player->position.x, player->position.y);
771
explosion->drawGroup = Zone->objectDrawGroup[1];
772
RSDK.PlaySfx(ItemBox->sfxPowerDown, false, 255);
773
}
774
}
775
else {
776
switch (self->contentsAnimator.frameID) {
777
case 1: self->type = ITEMBOX_BLUESHIELD; break;
778
case 2: self->type = ITEMBOX_BUBBLESHIELD; break;
779
case 3: self->type = ITEMBOX_FIRESHIELD; break;
780
case 4: self->type = ITEMBOX_LIGHTNINGSHIELD; break;
781
case 5: self->type = ITEMBOX_HYPERRING; break;
782
case 6: self->type = ITEMBOX_SWAP; break;
783
case 7: self->type = ITEMBOX_RANDOM; break;
784
default: self->type = ITEMBOX_RING; break;
785
}
786
787
player = (EntityPlayer *)self->parent;
788
if ((uint32)self->type <= ITEMBOX_STOCK)
789
ItemBox_GivePowerup();
790
}
791
break;
792
}
793
794
#endif
795
default: break;
796
}
797
}
798
void ItemBox_Break(EntityItemBox *itemBox, EntityPlayer *player)
799
{
800
if (globals->gameMode == MODE_COMPETITION) {
801
EntityCompetitionSession *session = CompetitionSession_GetSession();
802
++session->items[RSDK.GetEntitySlot(player)];
803
}
804
805
RSDK.CreateEntity(TYPE_BLANK, NULL, itemBox->position.x, itemBox->position.y);
806
807
#if MANIA_USE_PLUS
808
if (player->characterID == ID_MIGHTY && player->animator.animationID == ANI_HAMMERDROP)
809
player->velocity.y -= TO_FIXED(1);
810
else
811
#endif
812
player->velocity.y = -(player->velocity.y + 2 * player->gravityStrength);
813
814
itemBox->storedEntity = (Entity *)player;
815
itemBox->alpha = 0x100;
816
itemBox->contentsSpeed = -TO_FIXED(3);
817
itemBox->active = ACTIVE_NORMAL;
818
itemBox->velocity.y = -TO_FIXED(2);
819
itemBox->isContents = true;
820
itemBox->state = ItemBox_State_Break;
821
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 1, &itemBox->boxAnimator, true, 0);
822
itemBox->boxAnimator.frameID = ItemBox->brokenFrame++;
823
ItemBox->brokenFrame %= 3;
824
RSDK.SetSpriteAnimation(-1, 0, &itemBox->overlayAnimator, true, 0);
825
RSDK.SetSpriteAnimation(-1, 0, &itemBox->debrisAnimator, true, 0);
826
827
EntityExplosion *explosion = CREATE_ENTITY(Explosion, INT_TO_VOID(EXPLOSION_ITEMBOX), itemBox->position.x, itemBox->position.y - TO_FIXED(16));
828
explosion->drawGroup = Zone->objectDrawGroup[1];
829
830
for (int32 d = 0; d < 6; ++d) {
831
EntityDebris *debris = CREATE_ENTITY(Debris, NULL, itemBox->position.x + RSDK.Rand(-0x80000, 0x80000),
832
itemBox->position.y + RSDK.Rand(-TO_FIXED(8), TO_FIXED(8)));
833
debris->state = Debris_State_Fall;
834
debris->gravityStrength = 0x4000;
835
debris->velocity.x = RSDK.Rand(0, TO_FIXED(2));
836
if (debris->position.x < itemBox->position.x)
837
debris->velocity.x = -debris->velocity.x;
838
debris->velocity.y = RSDK.Rand(-TO_FIXED(4), -TO_FIXED(1));
839
debris->drawFX = FX_FLIP;
840
debris->direction = d & 3;
841
debris->drawGroup = Zone->objectDrawGroup[1];
842
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 6, &debris->animator, true, RSDK.Rand(0, 4));
843
}
844
845
RSDK.PlaySfx(ItemBox->sfxDestroy, false, 255);
846
847
itemBox->active = ACTIVE_NORMAL;
848
if (itemBox->type == ITEMBOX_RANDOM) {
849
#if MANIA_USE_PLUS
850
if (globals->gameMode != MODE_ENCORE) {
851
#endif
852
while (true) {
853
itemBox->type = RSDK.Rand(0, 13);
854
switch (itemBox->type) {
855
case ITEMBOX_1UP_SONIC:
856
if (globals->gameMode == MODE_TIMEATTACK)
857
continue;
858
859
switch (player->characterID) {
860
case ID_SONIC: itemBox->type = ITEMBOX_1UP_SONIC; break;
861
case ID_TAILS: itemBox->type = ITEMBOX_1UP_TAILS; break;
862
case ID_KNUCKLES: itemBox->type = ITEMBOX_1UP_KNUX; break;
863
#if MANIA_USE_PLUS
864
case ID_MIGHTY: itemBox->type = ITEMBOX_1UP_MIGHTY; break;
865
case ID_RAY: itemBox->type = ITEMBOX_1UP_RAY;
866
#endif
867
break;
868
default: break;
869
}
870
itemBox->contentsAnimator.frameID = itemBox->type;
871
break;
872
873
case ITEMBOX_1UP_TAILS:
874
case ITEMBOX_1UP_KNUX:
875
#if MANIA_USE_PLUS
876
case ITEMBOX_1UP_MIGHTY:
877
case ITEMBOX_1UP_RAY:
878
#endif
879
continue;
880
881
case ITEMBOX_SWAP:
882
if (globals->gameMode != MODE_COMPETITION)
883
continue;
884
itemBox->contentsAnimator.frameID = itemBox->type;
885
break;
886
887
default: itemBox->contentsAnimator.frameID = itemBox->type; break;
888
}
889
break;
890
}
891
#if MANIA_USE_PLUS
892
}
893
#endif
894
}
895
}
896
bool32 ItemBox_HandleFallingCollision(void)
897
{
898
RSDK_THIS(ItemBox);
899
900
if (self->direction)
901
return false;
902
903
self->moveOffset.x = -self->position.x;
904
self->moveOffset.y = -self->position.y;
905
if (self->velocity.y)
906
#if MANIA_USE_PLUS
907
self->parent = NULL;
908
#else
909
self->groundVel = 0;
910
#endif
911
912
self->position.x += self->velocity.x;
913
self->position.y += self->velocity.y;
914
self->velocity.y += 0x3800;
915
916
ItemBox_HandleObjectCollisions();
917
918
if (self->velocity.y >= 0) {
919
bool32 collided = (self->direction == FLIP_Y && self->boxAnimator.animationID == 1)
920
? RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, TO_FIXED(0), true)
921
: RSDK.ObjectTileCollision(self, Zone->collisionLayers, CMODE_FLOOR, 0, 0, TO_FIXED(16), true);
922
if (collided) {
923
self->velocity.y = 0;
924
if (self->state != ItemBox_State_IconFinish && self->state != ItemBox_State_Break)
925
self->active = ACTIVE_BOUNDS;
926
self->moveOffset.x += self->position.x;
927
self->moveOffset.y += self->position.y;
928
return true;
929
}
930
}
931
932
self->moveOffset.x += self->position.x;
933
self->moveOffset.y += self->position.y;
934
return false;
935
}
936
bool32 ItemBox_HandlePlatformCollision(void *plat)
937
{
938
RSDK_THIS(ItemBox);
939
EntityPlatform *platform = (EntityPlatform *)plat;
940
941
bool32 collided = false;
942
if (platform->state != Platform_State_Falling2 && platform->state != Platform_State_Hold) {
943
platform->position.x = platform->drawPos.x - platform->collisionOffset.x;
944
platform->position.y = platform->drawPos.y - platform->collisionOffset.y;
945
946
switch (platform->collision) {
947
case PLATFORM_C_PLATFORM:
948
collided = RSDK.CheckObjectCollisionPlatform(platform, RSDK.GetHitbox(&platform->animator, 0), self, &ItemBox->hitboxItemBox, true);
949
break;
950
case PLATFORM_C_SOLID:
951
collided = RSDK.CheckObjectCollisionBox(platform, RSDK.GetHitbox(&platform->animator, 1), self, &ItemBox->hitboxItemBox, true);
952
break;
953
954
case PLATFORM_C_TILED:
955
if (!RSDK.CheckObjectCollisionTouchBox(platform, &platform->hitbox, self, &ItemBox->hitboxItemBox))
956
break;
957
958
if (self->collisionLayers & Zone->moveLayerMask) {
959
TileLayer *move = RSDK.GetTileLayer(Zone->moveLayer);
960
move->position.x = -(platform->drawPos.x + platform->tileOrigin.x) >> 16;
961
move->position.y = -(platform->drawPos.y + platform->tileOrigin.y) >> 16;
962
}
963
964
if (self->state == ItemBox_State_Idle || self->velocity.y > 0x3800) {
965
platform->position.x = platform->centerPos.x;
966
platform->position.y = platform->centerPos.y;
967
return false;
968
}
969
970
collided = true;
971
break;
972
973
default:
974
break;
975
}
976
977
if (!collided) {
978
platform->position.x = platform->centerPos.x;
979
platform->position.y = platform->centerPos.y;
980
return false;
981
}
982
983
#if MANIA_USE_PLUS
984
self->parent = (Entity *)platform;
985
#else
986
self->groundVel = RSDK.GetEntitySlot(platform);
987
#endif
988
989
self->scale.x = (self->position.x - platform->drawPos.x) & 0xFFFF0000;
990
self->scale.y = (self->position.y - platform->drawPos.y) & 0xFFFF0000;
991
992
self->updateRange.x = platform->updateRange.x;
993
self->updateRange.y = platform->updateRange.y;
994
995
if (self->state == ItemBox_State_Falling)
996
self->state = ItemBox_State_Idle;
997
998
if (platform->state == Platform_State_Fall && !platform->timer)
999
platform->timer = 30;
1000
1001
self->velocity.y = 0;
1002
platform->stood = true;
1003
platform->position.x = platform->centerPos.x;
1004
platform->position.y = platform->centerPos.y;
1005
return collided;
1006
}
1007
1008
return false;
1009
}
1010
void ItemBox_HandleObjectCollisions(void)
1011
{
1012
RSDK_THIS(ItemBox);
1013
1014
bool32 platformCollided = false;
1015
1016
if (Platform) {
1017
#if MANIA_USE_PLUS
1018
if (self->parent) {
1019
EntityPlatform *platform = (EntityPlatform *)self->parent;
1020
#else
1021
if (self->groundVel) {
1022
EntityPlatform *platform = RSDK_GET_ENTITY(self->groundVel, Platform);
1023
#endif
1024
1025
if (platform->classID == Platform->classID) {
1026
platform->stood = true;
1027
self->position.x = self->scale.x + platform->drawPos.x;
1028
self->position.y = (self->scale.y + platform->drawPos.y) & 0xFFFF0000;
1029
self->moveOffset.x = platform->collisionOffset.x & 0xFFFF0000;
1030
self->moveOffset.y = platform->collisionOffset.y & 0xFFFF0000;
1031
self->contentsPos.x += platform->collisionOffset.x;
1032
self->contentsPos.y += platform->collisionOffset.y;
1033
self->velocity.y = 0;
1034
platformCollided = true;
1035
}
1036
}
1037
else {
1038
foreach_active(Platform, platform)
1039
{
1040
if (ItemBox_HandlePlatformCollision(platform))
1041
platformCollided = true;
1042
}
1043
}
1044
}
1045
1046
#if MANIA_USE_PLUS
1047
if (TilePlatform && self->parent) {
1048
EntityTilePlatform *tilePlatform = (EntityTilePlatform *)self->parent;
1049
if (tilePlatform->classID == TilePlatform->classID) {
1050
platformCollided = true;
1051
tilePlatform->stood = true;
1052
self->position.x = self->scale.x + tilePlatform->drawPos.x;
1053
self->position.y = (self->scale.y + tilePlatform->drawPos.y) & 0xFFFF0000;
1054
self->moveOffset.x = tilePlatform->collisionOffset.x & 0xFFFF0000;
1055
self->moveOffset.y = tilePlatform->collisionOffset.y & 0xFFFF0000;
1056
self->contentsPos.x += tilePlatform->collisionOffset.x;
1057
self->contentsPos.y += tilePlatform->collisionOffset.y;
1058
self->velocity.y = 0;
1059
}
1060
}
1061
#endif
1062
1063
if (Crate) {
1064
#if MANIA_USE_PLUS
1065
if (self->parent) {
1066
EntityCrate *crate = (EntityCrate *)self->parent;
1067
#else
1068
if (self->groundVel) {
1069
EntityCrate *crate = RSDK_GET_ENTITY(self->groundVel, Crate);
1070
#endif
1071
if (crate->classID == Crate->classID) {
1072
crate->stood = true;
1073
self->position.x = self->scale.x + crate->drawPos.x;
1074
self->position.y = (self->scale.y + crate->drawPos.y) & 0xFFFF0000;
1075
self->moveOffset.x = crate->collisionOffset.x & 0xFFFF0000;
1076
self->moveOffset.y = crate->collisionOffset.y & 0xFFFF0000;
1077
self->contentsPos.x += crate->collisionOffset.x;
1078
self->contentsPos.y += crate->collisionOffset.y;
1079
self->velocity.y = 0;
1080
}
1081
else {
1082
#if MANIA_USE_PLUS
1083
self->parent = NULL;
1084
#else
1085
self->groundVel = 0;
1086
#endif
1087
}
1088
}
1089
else {
1090
foreach_active(Crate, crate)
1091
{
1092
if (!crate->ignoreItemBox && ItemBox_HandlePlatformCollision(crate))
1093
platformCollided = true;
1094
}
1095
}
1096
}
1097
1098
if (!platformCollided)
1099
#if MANIA_USE_PLUS
1100
self->parent = NULL;
1101
#else
1102
self->groundVel = 0;
1103
#endif
1104
1105
if (Ice) {
1106
foreach_active(Ice, ice)
1107
{
1108
if (ice->stateDraw == Ice_Draw_IceBlock) {
1109
int32 storeX = ice->position.x;
1110
int32 storeY = ice->position.y;
1111
ice->position.x -= ice->playerMoveOffset.x;
1112
ice->position.y -= ice->playerMoveOffset.y;
1113
1114
if (RSDK.CheckObjectCollisionBox(ice, &ice->hitboxBlock, self, &ItemBox->hitboxItemBox, true) == C_TOP) {
1115
self->position.x += ice->playerMoveOffset.x;
1116
self->position.y += ice->playerMoveOffset.y;
1117
self->position.y &= 0xFFFF0000;
1118
1119
self->contentsPos.x += ice->playerMoveOffset.x;
1120
self->contentsPos.y += ice->playerMoveOffset.y;
1121
self->contentsPos.y &= 0xFFFF0000;
1122
1123
self->moveOffset.x = ice->playerMoveOffset.x;
1124
self->moveOffset.y = ice->playerMoveOffset.y;
1125
self->velocity.y = 0;
1126
}
1127
1128
ice->position.x = storeX;
1129
ice->position.y = storeY;
1130
}
1131
}
1132
}
1133
1134
foreach_active(Spikes, spikes)
1135
{
1136
int32 storeX = spikes->position.x;
1137
int32 storeY = spikes->position.y;
1138
1139
spikes->position.x -= spikes->collisionOffset.x;
1140
spikes->position.y -= spikes->collisionOffset.y;
1141
if (RSDK.CheckObjectCollisionBox(spikes, &spikes->hitbox, self, &ItemBox->hitboxItemBox, true) == C_TOP) {
1142
self->position.x += spikes->collisionOffset.x;
1143
self->position.y += spikes->collisionOffset.y;
1144
self->position.y &= 0xFFFF0000;
1145
1146
self->contentsPos.x += spikes->collisionOffset.x;
1147
self->contentsPos.y += spikes->collisionOffset.y;
1148
self->contentsPos.y &= 0xFFFF0000;
1149
1150
self->moveOffset.x = spikes->collisionOffset.x;
1151
self->moveOffset.y = spikes->collisionOffset.y;
1152
self->velocity.y = 0;
1153
}
1154
1155
spikes->position.x = storeX;
1156
spikes->position.y = storeY;
1157
}
1158
1159
foreach_active(ItemBox, itemBox)
1160
{
1161
if (itemBox != self) {
1162
if (self->state == ItemBox_State_Idle || self->state == ItemBox_State_Falling) {
1163
if (itemBox->state == ItemBox_State_Idle || itemBox->state == ItemBox_State_Falling) {
1164
int32 storeX = itemBox->position.x;
1165
int32 storeY = itemBox->position.y;
1166
1167
itemBox->position.x -= itemBox->moveOffset.x;
1168
itemBox->position.y -= itemBox->moveOffset.y;
1169
if (RSDK.CheckObjectCollisionBox(itemBox, &ItemBox->hitboxItemBox, self, &ItemBox->hitboxItemBox, true) == C_TOP) {
1170
self->position.x += itemBox->moveOffset.x;
1171
self->position.y += itemBox->moveOffset.y;
1172
self->position.y = TO_FIXED(self->position.y >> 16);
1173
1174
self->contentsPos.x += itemBox->moveOffset.x;
1175
self->contentsPos.y += itemBox->moveOffset.y;
1176
self->contentsPos.y = TO_FIXED(self->contentsPos.y >> 16);
1177
1178
self->moveOffset.x = itemBox->moveOffset.x;
1179
self->moveOffset.y = itemBox->moveOffset.y;
1180
self->velocity.y = 0;
1181
}
1182
1183
itemBox->position.x = storeX;
1184
itemBox->position.y = storeY;
1185
}
1186
}
1187
}
1188
}
1189
}
1190
1191
#if GAME_INCLUDE_EDITOR
1192
void ItemBox_EditorDraw(void)
1193
{
1194
RSDK_THIS(ItemBox);
1195
1196
int32 dir = self->direction;
1197
self->direction *= FLIP_Y;
1198
1199
self->contentsPos.x = self->position.x;
1200
if (self->direction == FLIP_NONE)
1201
self->contentsPos.y = self->position.y - TO_FIXED(3);
1202
else
1203
self->contentsPos.y = self->position.y + TO_FIXED(3);
1204
1205
self->inkEffect = INK_ALPHA;
1206
self->alpha = self->hidden ? 0x80 : 0x100;
1207
1208
RSDK.SetSpriteAnimation(ItemBox->aniFrames, 2, &self->contentsAnimator, true, self->type);
1209
RSDK.DrawSprite(&self->boxAnimator, NULL, false);
1210
RSDK.DrawSprite(&self->contentsAnimator, &self->contentsPos, false);
1211
1212
self->direction = dir;
1213
}
1214
1215
void ItemBox_EditorLoad(void)
1216
{
1217
ItemBox->aniFrames = RSDK.LoadSpriteAnimation("Global/ItemBox.bin", SCOPE_STAGE);
1218
1219
RSDK_ACTIVE_VAR(ItemBox, type);
1220
RSDK_ENUM_VAR("Super Ring", ITEMBOX_RING);
1221
RSDK_ENUM_VAR("Blue Shield", ITEMBOX_BLUESHIELD);
1222
RSDK_ENUM_VAR("Bubble Shield", ITEMBOX_BUBBLESHIELD);
1223
RSDK_ENUM_VAR("Fire Shield", ITEMBOX_FIRESHIELD);
1224
RSDK_ENUM_VAR("Lightning Shield", ITEMBOX_LIGHTNINGSHIELD);
1225
RSDK_ENUM_VAR("Invincibility", ITEMBOX_INVINCIBLE);
1226
RSDK_ENUM_VAR("Sneakers", ITEMBOX_SNEAKERS);
1227
RSDK_ENUM_VAR("1UP Sonic", ITEMBOX_1UP_SONIC);
1228
RSDK_ENUM_VAR("1UP Tails", ITEMBOX_1UP_TAILS);
1229
RSDK_ENUM_VAR("1UP Knux", ITEMBOX_1UP_KNUX);
1230
RSDK_ENUM_VAR("Eggman", ITEMBOX_EGGMAN);
1231
RSDK_ENUM_VAR("Hyper Ring", ITEMBOX_HYPERRING);
1232
RSDK_ENUM_VAR("Swap", ITEMBOX_SWAP);
1233
RSDK_ENUM_VAR("Random", ITEMBOX_RANDOM);
1234
RSDK_ENUM_VAR("Super", ITEMBOX_SUPER);
1235
#if MANIA_USE_PLUS
1236
RSDK_ENUM_VAR("1UP Mighty", ITEMBOX_1UP_MIGHTY);
1237
RSDK_ENUM_VAR("1UP Ray", ITEMBOX_1UP_RAY);
1238
RSDK_ENUM_VAR("Change", ITEMBOX_STOCK);
1239
#endif
1240
1241
RSDK_ACTIVE_VAR(ItemBox, planeFilter);
1242
RSDK_ENUM_VAR("None", PLANEFILTER_NONE);
1243
RSDK_ENUM_VAR("AL", PLANEFILTER_AL);
1244
RSDK_ENUM_VAR("BL", PLANEFILTER_BL);
1245
RSDK_ENUM_VAR("AH", PLANEFILTER_AH);
1246
RSDK_ENUM_VAR("BH", PLANEFILTER_BH);
1247
1248
RSDK_ACTIVE_VAR(ItemBox, direction);
1249
RSDK_ENUM_VAR("Normal", FLIP_NONE);
1250
RSDK_ENUM_VAR("Upside-Down", FLIP_X);
1251
}
1252
#endif
1253
1254
void ItemBox_Serialize(void)
1255
{
1256
RSDK_EDITABLE_VAR(ItemBox, VAR_ENUM, type);
1257
RSDK_EDITABLE_VAR(ItemBox, VAR_BOOL, isFalling);
1258
RSDK_EDITABLE_VAR(ItemBox, VAR_BOOL, hidden);
1259
RSDK_EDITABLE_VAR(ItemBox, VAR_UINT8, direction);
1260
RSDK_EDITABLE_VAR(ItemBox, VAR_ENUM, planeFilter);
1261
RSDK_EDITABLE_VAR(ItemBox, VAR_BOOL, lrzConvPhys);
1262
}
1263
1264