Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rubberduckycooly
GitHub Repository: rubberduckycooly/Sonic-Mania-Decompilation
Path: blob/master/SonicMania/Objects/CPZ/DNARiser.c
338 views
1
// ---------------------------------------------------------------------
2
// RSDK Project: Sonic Mania
3
// Object Description: DNARiser Object
4
// Object Author: Christian Whitehead/Simon Thomley/Hunter Bridges
5
// Decompiled by: Rubberduckycooly & RMGRich
6
// ---------------------------------------------------------------------
7
8
#include "Game.h"
9
10
ObjectDNARiser *DNARiser;
11
12
void DNARiser_Update(void)
13
{
14
RSDK_THIS(DNARiser);
15
16
if (self->scaleTimer)
17
self->scaleTimer--;
18
19
if (self->sfxTimer > 0)
20
self->sfxTimer--;
21
22
StateMachine_Run(self->state);
23
24
if (self->popped) {
25
if (self->popAnimator.frameID == self->popAnimator.loopIndex)
26
self->popped = false;
27
else
28
RSDK.ProcessAnimation(&self->popAnimator);
29
}
30
}
31
32
void DNARiser_LateUpdate(void) {}
33
34
void DNARiser_StaticUpdate(void)
35
{
36
foreach_active(DNARiser, entity) { RSDK.AddDrawListRef(Zone->objectDrawGroup[1], RSDK.GetEntitySlot(entity)); }
37
}
38
39
void DNARiser_Draw(void)
40
{
41
RSDK_THIS(DNARiser);
42
43
StateMachine_Run(self->stateDraw);
44
}
45
46
void DNARiser_Create(void *data)
47
{
48
RSDK_THIS(DNARiser);
49
self->visible = true;
50
self->active = ACTIVE_BOUNDS;
51
self->drawGroup = Zone->objectDrawGroup[0] + 1;
52
self->amplitude = 0x2E0000;
53
54
if (SceneInfo->inEditor) {
55
self->speed.x = 0;
56
if (!self->speed.y)
57
self->speed.y = 0x60000;
58
if (!self->height)
59
self->height = 128;
60
}
61
62
self->updateRange.x = 0x800000;
63
self->updateRange.y = 0x800000;
64
self->state = DNARiser_State_Init;
65
}
66
67
void DNARiser_StageLoad(void)
68
{
69
DNARiser->aniFrames = RSDK.LoadSpriteAnimation("CPZ/DNARiser.bin", SCOPE_STAGE);
70
71
DNARiser->hitbox.top = -16;
72
DNARiser->hitbox.bottom = 16;
73
DNARiser->hitbox.left = -16;
74
DNARiser->hitbox.right = 16;
75
76
DNARiser->active = ACTIVE_ALWAYS;
77
78
DNARiser->sfxBurst = RSDK.GetSfx("CPZ/DNABurst.wav");
79
DNARiser->sfxGrab = RSDK.GetSfx("CPZ/DNAGrab.wav");
80
DNARiser->sfxScan = RSDK.GetSfx("CPZ/DNAScan.wav");
81
DNARiser->sfxTiny[0] = RSDK.GetSfx("CPZ/DNATiny0.wav");
82
DNARiser->sfxTiny[1] = RSDK.GetSfx("CPZ/DNATiny1.wav");
83
DNARiser->sfxTiny[2] = RSDK.GetSfx("CPZ/DNATiny2.wav");
84
DNARiser->sfxTiny[3] = RSDK.GetSfx("CPZ/DNATiny3.wav");
85
DNARiser->sfxTiny[4] = RSDK.GetSfx("CPZ/DNATiny4.wav");
86
DNARiser->sfxTiny[5] = RSDK.GetSfx("CPZ/DNATiny5.wav");
87
}
88
89
void DNARiser_State_BubbleBurst(void)
90
{
91
RSDK_THIS(DNARiser);
92
93
RSDK.PlaySfx(DNARiser->sfxBurst, false, 255);
94
95
self->popPos = self->position;
96
self->popped = true;
97
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 5, &self->popAnimator, true, 0);
98
}
99
100
void DNARiser_SetupBurst(void)
101
{
102
RSDK_THIS(DNARiser);
103
104
DNARiser_State_BubbleBurst();
105
106
self->maxSpeed = self->speed;
107
self->noBubbleScaling = true;
108
self->velocity.x = 0;
109
self->velocity.y = 0;
110
self->state = DNARiser_State_HelixBurst;
111
self->timer = 0;
112
}
113
114
Vector2 DNARiser_CalculateScale(Vector2 *scalePtr)
115
{
116
RSDK_THIS(DNARiser);
117
118
Vector2 scale;
119
int32 x = 0x200;
120
int32 y = 0x200;
121
if (scalePtr) {
122
x = scalePtr->x;
123
y = scalePtr->y;
124
}
125
126
int32 timer = (30 - self->scaleTimer);
127
int32 sine = RSDK.Sin1024(((timer * (0x40000000 / ((10983 * timer + 286520) >> 7))) >> 11) & 0x3FF);
128
scale.x = (((timer - 30) * (sine << 6) / 100 + 0x10000) * x) >> 16;
129
scale.y = (((30 - timer) * (sine << 6) / 100 + 0x10000) * y) >> 16;
130
return scale;
131
}
132
133
void DNARiser_State_Init(void)
134
{
135
RSDK_THIS(DNARiser);
136
137
self->startPos = self->position;
138
self->active = ACTIVE_BOUNDS;
139
self->speed.x = 0;
140
self->velocity.x = 0;
141
self->speed.y = -abs(self->speed.y);
142
self->timer = 0;
143
self->risePos = 0;
144
self->canDestroySelf = false;
145
self->firstChild = NULL;
146
self->child = 0;
147
self->helixPos = 0;
148
self->activePlayers = 0;
149
self->noBubbleScaling = false;
150
self->lastSfxID = 0;
151
self->sfxTimer = 0;
152
self->scanSfxDir = 0;
153
self->velocity.y = 0;
154
self->stateDraw = DNARiser_Draw_Main;
155
self->state = DNARiser_State_HandleInteractions;
156
self->bubbleScale = 0x200;
157
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 0, &self->bubbleAnimator, true, 0);
158
DNARiser_State_HandleInteractions();
159
}
160
161
void DNARiser_State_HandleInteractions(void)
162
{
163
RSDK_THIS(DNARiser);
164
165
foreach_active(Player, player)
166
{
167
int32 playerID = RSDK.GetEntitySlot(player);
168
169
if (!((1 << playerID) & self->activePlayers)) {
170
if (Player_CheckCollisionTouch(player, self, &DNARiser->hitbox)) {
171
RSDK.PlaySfx(DNARiser->sfxGrab, false, 255);
172
self->scaleTimer = 30;
173
self->sfxTimer = 30;
174
RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);
175
player->groundVel = 0;
176
player->drawGroup = 1;
177
player->jumpAbilityState = 1;
178
player->onGround = false;
179
player->tileCollisions = TILECOLLISION_NONE;
180
player->state = Player_State_Static;
181
player->nextAirState = StateMachine_None;
182
player->nextGroundState = StateMachine_None;
183
self->activePlayers |= 1 << playerID;
184
}
185
}
186
187
if (((1 << playerID) & self->activePlayers)) {
188
if (player->state == Player_State_Static) {
189
player->position.x = self->position.x;
190
player->position.y = self->position.y;
191
player->velocity.x = 0;
192
player->velocity.y = 0;
193
if (!player->sidekick) {
194
self->risePos = 0;
195
self->active = ACTIVE_NORMAL;
196
self->state = DNARiser_State_HelixRise;
197
}
198
}
199
else {
200
self->activePlayers &= ~(1 << playerID);
201
}
202
}
203
}
204
}
205
206
void DNARiser_State_HelixRise(void)
207
{
208
RSDK_THIS(DNARiser);
209
if (self->risePos >= self->height << 16) {
210
DNARiser_SetupBurst();
211
}
212
else {
213
if (self->velocity.y >= abs(self->speed.y))
214
self->velocity.y = abs(self->speed.y);
215
else
216
self->velocity.y += 0x1200;
217
218
self->risePos += self->velocity.y;
219
if (self->height << 16 < self->risePos)
220
self->risePos = self->height << 16;
221
222
int32 angle = (((0x57262 * (self->risePos >> 16)) >> 16) + 250) & 0x3FF;
223
if (angle >= 0x200 && !self->scanSfxDir) {
224
self->scanSfxDir = 1;
225
RSDK.PlaySfx(DNARiser->sfxScan, false, 255);
226
}
227
else if (angle <= 0x1FF && self->scanSfxDir) {
228
self->scanSfxDir = 0;
229
RSDK.PlaySfx(DNARiser->sfxScan, false, 255);
230
}
231
232
self->position.y = self->startPos.y - self->risePos;
233
for (; self->helixPos <= (self->risePos >> 18) + 1; ++self->helixPos) {
234
if (!(self->helixPos & 1) || !(self->helixPos % 5)) {
235
if (!self->sfxTimer) {
236
int32 sfxID = 0;
237
if (!self->lastSfxID) {
238
while (sfxID == self->lastSfxID) sfxID = ZONE_RAND(0, 5);
239
}
240
241
RSDK.PlaySfx(DNARiser->sfxTiny[sfxID], false, 255);
242
self->lastSfxID = sfxID;
243
self->sfxTimer = ZONE_RAND(2, 8);
244
}
245
246
EntityDNARiser *child = CREATE_ENTITY(DNARiser, self, self->startPos.x, self->startPos.y - (self->helixPos << 18));
247
child->state = DNARiser_State_OrbSetup;
248
child->active = ACTIVE_NORMAL;
249
child->startHelixPos = self->helixPos;
250
child->parent = self;
251
child->angle = (((0x57262 * (4 * self->helixPos)) >> 16) + 100) & 0x3FF;
252
child->amplitude = 0x2E0000;
253
child->drawGroup = self->drawGroup - 1;
254
if (!self->firstChild)
255
self->firstChild = child;
256
257
if (self->child) {
258
child->lastChild = self->child;
259
self->child->sibling = child;
260
}
261
self->child = child;
262
}
263
}
264
}
265
266
bool32 popped = false;
267
self->bubbleScale = (0x10000 - 85 * ((self->risePos / self->height) >> 8)) >> 7;
268
269
foreach_active(Player, player)
270
{
271
int32 playerID = RSDK.GetEntitySlot(player);
272
if (!((1 << playerID) & self->activePlayers)) {
273
if (Player_CheckCollisionTouch(player, self, &DNARiser->hitbox)) {
274
RSDK.PlaySfx(DNARiser->sfxGrab, false, 255);
275
self->sfxTimer = 30;
276
self->scaleTimer = 30;
277
self->activePlayers |= (1 << playerID);
278
}
279
}
280
281
if ((1 << playerID) & self->activePlayers) {
282
bool32 playerActive = false;
283
if (!Player_CheckValidState(player)) {
284
self->activePlayers &= ~(1 << playerID);
285
if (self->activePlayers)
286
playerActive = true;
287
else
288
DNARiser_SetupBurst();
289
}
290
291
if (!playerActive) {
292
if (player->jumpPress) {
293
player->velocity.y = 0;
294
player->velocity.x = 0;
295
Player_Action_Jump(player);
296
DNARiser_SetupBurst();
297
}
298
299
if (self->state == DNARiser_State_HelixBurst) {
300
popped = true;
301
}
302
else {
303
RSDK.SetSpriteAnimation(player->aniFrames, ANI_JUMP, &player->animator, false, 0);
304
player->groundVel = 0;
305
player->drawGroup = 1;
306
player->jumpAbilityState = 1;
307
player->onGround = false;
308
player->tileCollisions = TILECOLLISION_NONE;
309
player->state = Player_State_Static;
310
player->nextAirState = StateMachine_None;
311
player->nextGroundState = StateMachine_None;
312
player->velocity.x = 0;
313
player->velocity.y = -self->velocity.y;
314
player->position.x = self->position.x;
315
player->position.y = self->position.y;
316
}
317
}
318
}
319
}
320
321
if (popped) {
322
foreach_active(Player, playerPtr)
323
{
324
int32 playerID = RSDK.GetEntitySlot(playerPtr);
325
if (((1 << playerID) & self->activePlayers)) {
326
playerPtr->drawGroup = Zone->playerDrawGroup[0];
327
playerPtr->tileCollisions = TILECOLLISION_DOWN;
328
playerPtr->state = Player_State_Air;
329
playerPtr->velocity.x = self->speed.x;
330
playerPtr->velocity.y = self->speed.y;
331
self->activePlayers &= ~(1 << playerID);
332
}
333
}
334
}
335
}
336
337
void DNARiser_State_HelixBurst(void)
338
{
339
RSDK_THIS(DNARiser);
340
341
if (self->timer <= 0) {
342
if (!self->timer) {
343
if (!self->canDestroySelf) {
344
EntityDNARiser *child = self->child;
345
if (child) {
346
self->canDestroySelf = true;
347
child->timer = 0;
348
child->velocity.x = 0;
349
child->state = DNARiser_State_OrbFall;
350
child->velocity.y = self->maxSpeed.y >> 1;
351
child->maxSpeed.y = self->maxSpeed.y >> 1;
352
}
353
}
354
if (self->position.y < self->startPos.y) {
355
self->velocity.y += 0x38000;
356
self->position.y += self->velocity.y;
357
}
358
359
int32 posY = self->startPos.y;
360
if (self->position.y < self->startPos.y)
361
posY = self->position.y;
362
363
self->position.y = posY;
364
self->risePos = self->startPos.y - posY;
365
if (posY == self->startPos.y) {
366
self->state = DNARiser_State_ResetRiser;
367
self->timer = 60;
368
}
369
}
370
}
371
else {
372
self->timer--;
373
}
374
}
375
376
void DNARiser_State_ResetRiser(void)
377
{
378
RSDK_THIS(DNARiser);
379
380
if (!self->firstChild) {
381
if (self->timer <= 0) {
382
if (RSDK.CheckOnScreen(self, &self->updateRange)) {
383
DNARiser_State_BubbleBurst();
384
DNARiser_State_Init();
385
self->scaleTimer = 30;
386
}
387
else {
388
self->state = DNARiser_State_Init;
389
}
390
}
391
else {
392
self->timer--;
393
}
394
}
395
}
396
397
void DNARiser_State_OrbSetup(void)
398
{
399
RSDK_THIS(DNARiser);
400
401
self->active = ACTIVE_NORMAL;
402
self->stateDraw = DNARiser_Draw_Helix;
403
self->state = DNARiser_State_OrbIdle;
404
}
405
406
void DNARiser_State_OrbIdle(void)
407
{
408
// 20220614 rdc said i could come back and comment these >:]
409
}
410
411
void DNARiser_State_OrbFall(void)
412
{
413
RSDK_THIS(DNARiser);
414
EntityDNARiser *parent = self->parent;
415
416
if (self->timer <= 0) {
417
if (self->canDestroySelf) {
418
if (!RSDK.CheckOnScreen(self, &self->updateRange))
419
destroyEntity(self);
420
}
421
else {
422
EntityDNARiser *child = self->lastChild;
423
self->canDestroySelf = true;
424
if (child) {
425
while (true) {
426
if (RSDK.CheckOnScreen(child, &child->updateRange)) {
427
child->velocity.y = 0;
428
child->timer = 1;
429
child->state = DNARiser_State_OrbFall;
430
child->velocity.x = 0;
431
child->velocity.y = (self->maxSpeed.y >> 1) + (self->maxSpeed.y >> 2);
432
child->maxSpeed.y = (self->maxSpeed.y >> 1) + (self->maxSpeed.y >> 2);
433
break;
434
}
435
else {
436
EntityDNARiser *grandChild = child->lastChild;
437
438
if (child == parent->child)
439
parent->child = grandChild;
440
destroyEntity(child);
441
442
child = grandChild;
443
if (!grandChild)
444
break;
445
}
446
}
447
}
448
449
if (!child)
450
parent->firstChild = NULL;
451
452
if (self->canDestroySelf) {
453
if (!RSDK.CheckOnScreen(self, &self->updateRange))
454
destroyEntity(self);
455
}
456
}
457
}
458
else {
459
self->timer--;
460
}
461
462
self->velocity.y += 0x3800;
463
self->position.y += self->velocity.y;
464
self->amplitude += 0x20000;
465
}
466
467
void DNARiser_Draw_Main(void)
468
{
469
RSDK_THIS(DNARiser);
470
471
bool32 isYellowBig = false;
472
int32 angle = ((0x57262 * (self->risePos >> 16)) >> 16) + 100;
473
474
Animator orbAnimator;
475
memset(&orbAnimator, 0, sizeof(orbAnimator));
476
if ((uint32)((angle & 0x3FF) - 0x100) <= 0x200)
477
isYellowBig = true;
478
479
int32 sineOff = (RSDK.Sin1024(angle & 0x3FF) << 6) * (self->amplitude >> 16);
480
self->alpha = 0x100;
481
self->inkEffect = INK_NONE;
482
483
Vector2 drawPos;
484
drawPos = self->position;
485
486
self->scale.x = 0x200;
487
self->scale.y = 0x200;
488
self->drawFX = FX_NONE;
489
if (SceneInfo->currentDrawGroup == Zone->objectDrawGroup[1]) {
490
if (isYellowBig) {
491
drawPos.x = sineOff + self->position.x;
492
drawPos.y = self->position.y;
493
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 4, &orbAnimator, true, 0);
494
}
495
else {
496
drawPos.x = self->position.x - sineOff;
497
drawPos.y = self->position.y;
498
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 2, &orbAnimator, true, 0);
499
}
500
501
RSDK.DrawSprite(&orbAnimator, &drawPos, false);
502
if (!self->noBubbleScaling) {
503
drawPos = self->position;
504
self->drawFX = FX_SCALE;
505
self->inkEffect = INK_BLEND;
506
self->alpha = 0x80;
507
Vector2 scale;
508
scale.x = self->bubbleScale;
509
scale.y = self->bubbleScale;
510
self->scale = DNARiser_CalculateScale(&scale);
511
RSDK.DrawSprite(&self->bubbleAnimator, &drawPos, false);
512
}
513
514
if (self->popped) {
515
drawPos = self->popPos;
516
self->scale.x = 0x200;
517
self->scale.y = 0x200;
518
self->drawFX = FX_NONE;
519
self->inkEffect = INK_NONE;
520
RSDK.DrawSprite(&self->popAnimator, &drawPos, false);
521
}
522
}
523
else {
524
if (isYellowBig) {
525
drawPos.y = self->position.y;
526
drawPos.x = self->position.x - sineOff;
527
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 2, &orbAnimator, true, 0);
528
}
529
else {
530
drawPos.x = sineOff + self->position.x;
531
drawPos.y = self->position.y;
532
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 4, &orbAnimator, true, 0);
533
}
534
RSDK.DrawSprite(&orbAnimator, &drawPos, false);
535
}
536
}
537
538
void DNARiser_Draw_Helix(void)
539
{
540
RSDK_THIS(DNARiser);
541
542
bool32 isYellowBig = false;
543
EntityDNARiser *parent = self->parent;
544
545
Animator orbAnimator;
546
memset(&orbAnimator, 0, sizeof(orbAnimator));
547
if ((uint32)(self->angle - 0x100) <= 0x200)
548
isYellowBig = true;
549
550
int32 sineOff = (RSDK.Sin1024(self->angle) << 6) * (self->amplitude >> 16);
551
self->alpha = 0x100;
552
self->inkEffect = INK_NONE;
553
554
Vector2 drawPos;
555
drawPos = self->position;
556
557
self->scale.x = 0x200;
558
self->scale.y = 0x200;
559
self->drawFX = FX_NONE;
560
self->drawFX = INK_NONE;
561
if (SceneInfo->currentDrawGroup != Zone->objectDrawGroup[1] && !(self->startHelixPos & 1)) {
562
if (isYellowBig) {
563
drawPos.x = self->position.x - sineOff;
564
drawPos.y = self->position.y;
565
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 2, &orbAnimator, true, 0);
566
}
567
else {
568
drawPos.x = self->position.x + sineOff;
569
drawPos.y = self->position.y;
570
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 4, &orbAnimator, true, 0);
571
}
572
RSDK.DrawSprite(&orbAnimator, &drawPos, false);
573
}
574
575
if (!(self->startHelixPos % 5)) {
576
int32 distance = (parent->helixPos - self->startHelixPos >= 8) ? 4 : ((parent->helixPos - self->startHelixPos) / 2);
577
int32 sine = (RSDK.Sin1024(self->angle) << 6) * ((self->amplitude >> 16) - 12);
578
drawPos.y = self->position.y;
579
if (isYellowBig)
580
drawPos.x = self->position.x - sine;
581
else
582
drawPos.x = self->position.x + sine;
583
int32 startX = drawPos.x;
584
sine = 2 * sine / 7;
585
586
bool32 drawFlags[8];
587
drawFlags[0] = distance >= 1;
588
drawFlags[1] = distance >= 2;
589
drawFlags[2] = distance >= 3;
590
drawFlags[3] = distance >= 4;
591
drawFlags[4] = drawFlags[3];
592
drawFlags[5] = drawFlags[2];
593
drawFlags[6] = drawFlags[1];
594
drawFlags[7] = drawFlags[0];
595
596
for (int32 i = 0; i < 8; ++i) {
597
bool32 isYellowSmall = (isYellowBig && i <= 3) || (!isYellowBig && i >= 4);
598
bool32 canDraw = SceneInfo->currentDrawGroup == Zone->objectDrawGroup[1]
599
? ((isYellowBig && !isYellowSmall) || (!isYellowBig && isYellowSmall))
600
: ((isYellowBig && isYellowSmall) || (!isYellowBig && !isYellowSmall));
601
602
if (drawFlags[i] && canDraw) {
603
if (!isYellowSmall)
604
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 3, &orbAnimator, true, 0);
605
else
606
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 1, &orbAnimator, true, 0);
607
drawPos.x = startX + sine * i * (2 * isYellowBig - 1);
608
RSDK.DrawSprite(&orbAnimator, &drawPos, false);
609
}
610
}
611
}
612
613
if (SceneInfo->currentDrawGroup == Zone->objectDrawGroup[1] && !(self->startHelixPos & 1)) {
614
if (isYellowBig) {
615
drawPos.x = self->position.x + sineOff;
616
drawPos.y = self->position.y;
617
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 4, &orbAnimator, true, 0);
618
}
619
else {
620
drawPos.x = self->position.x - sineOff;
621
drawPos.y = self->position.y;
622
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 2, &orbAnimator, true, 0);
623
}
624
RSDK.DrawSprite(&orbAnimator, &drawPos, false);
625
}
626
}
627
628
#if GAME_INCLUDE_EDITOR
629
void DNARiser_EditorDraw(void)
630
{
631
RSDK_THIS(DNARiser);
632
633
self->startPos = self->position;
634
self->active = ACTIVE_BOUNDS;
635
self->speed.x = 0;
636
self->velocity.x = 0;
637
self->speed.y = -abs(self->speed.y);
638
self->timer = 0;
639
self->risePos = self->height << 16;
640
self->canDestroySelf = false;
641
self->firstChild = NULL;
642
self->child = 0;
643
self->helixPos = 0;
644
self->activePlayers = 0;
645
self->noBubbleScaling = false;
646
self->lastSfxID = 0;
647
self->sfxTimer = 0;
648
self->scanSfxDir = 0;
649
self->velocity.y = 0;
650
self->bubbleScale = 0x200;
651
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 0, &self->bubbleAnimator, true, 0);
652
653
int32 group = SceneInfo->currentDrawGroup;
654
655
SceneInfo->currentDrawGroup = -1;
656
DNARiser_Draw_Main();
657
658
SceneInfo->currentDrawGroup = Zone->objectDrawGroup[1];
659
DNARiser_Draw_Main();
660
661
SceneInfo->currentDrawGroup = group;
662
663
if (showGizmos()) {
664
RSDK_DRAWING_OVERLAY(true);
665
666
Vector2 drawPos;
667
drawPos.x = self->position.x;
668
drawPos.y = self->position.y - self->risePos;
669
670
RSDK.SetSpriteAnimation(DNARiser->aniFrames, 5, &self->bubbleAnimator, true, 0);
671
RSDK.DrawSprite(&self->bubbleAnimator, &drawPos, false);
672
673
DrawHelpers_DrawArrow(self->position.x, self->position.y, drawPos.x, drawPos.y, 0xFFFF00, INK_NONE, 0xFF);
674
675
RSDK_DRAWING_OVERLAY(false);
676
}
677
}
678
679
void DNARiser_EditorLoad(void) { DNARiser->aniFrames = RSDK.LoadSpriteAnimation("CPZ/DNARiser.bin", SCOPE_STAGE); }
680
#endif
681
682
void DNARiser_Serialize(void)
683
{
684
RSDK_EDITABLE_VAR(DNARiser, VAR_UINT32, height);
685
RSDK_EDITABLE_VAR(DNARiser, VAR_VECTOR2, speed);
686
}
687
688