Digimon World 3 decomp
The European version, SLES_039.36
Loading...
Searching...
No Matches
pile_effects.c
Go to the documentation of this file.
1/* CARDGAME's card effects on the hands, decks and discards: discarding,
2 drawing, taking cards and changing colour values. */
3
5
6/* Starts a count of side's hand and discards (effectStep.vars[0] and effectStep.vars[1]) */
7void CARDGAME_startHandCount(CardBattle *battle, CardScreen *screen, s32 side) {
8 battle->effectStep.state = 1;
9 battle->effectStep.time = 0;
10 battle->effectStep.vars[0] = battle->sides[side].pile.handCount;
11 battle->effectStep.vars[1] = battle->sides[side].pile.discardCount;
12 battle->effectStep.vars[2] = 0;
13}
14
15/* Counts a side's hand cards over to its discards on its panel, one every 7 frames, then moves them; 1 when done */
17 s32 done = 0;
18 s32 more;
19 s32 i;
20
21 switch (battle->effectStep.state) {
22 case 1:
24 battle->effectStep.vars[2] += GFX.funcs.getFrameTime();
25 if (battle->effectStep.vars[2] >= 7) {
26 more = 0;
27 if (battle->effectStep.vars[0] > 0) {
28 more = 1;
29 battle->effectStep.vars[0]--;
30 battle->effectStep.vars[1]++;
31 }
32 if (!more) {
33 battle->effectStep.state = 2;
34 }
35 screen->setPanelValue(screen, side, CARD_PANEL_HAND, battle->effectStep.vars[0]);
36 screen->setPanelValue(screen, side, CARD_PANEL_DISCARDS, battle->effectStep.vars[1]);
37 battle->effectStep.vars[2] -= 7;
38 }
39 break;
40 case 2:
41 for (i = 0; i < battle->sides[side].pile.handCount; i++) {
42 battle->sides[side].pile.discards[battle->sides[side].pile.discardCount] = battle->sides[side].pile.hand[i];
43 battle->sides[side].pile.discardCount++;
44 }
45 battle->sides[side].pile.handCount = 0;
46 done = 1;
47 break;
48 }
49 return done;
50}
51
52/* Starts CARDGAME_stepColorValue: amount (effectStep.vars[3], below 0 to take) one at a
53 time, one each interval frames (effectStep.vars[2]) */
54void CARDGAME_startColorChange(CardBattle *battle, CardScreen *screen, s32 amount, s32 interval) {
55 battle->effectStep.vars[2] = interval;
56 battle->effectStep.vars[3] = amount;
57 battle->effectStep.nextState = 1;
58}
59
60/* Moves a side's colour value (pile.points[color]) one step each effectStep.vars[2] frames towards using up effectStep.vars[3] (up to 99, down to 0), on its panel; 1 when done */
61s32 CARDGAME_stepColorValue(CardBattle *battle, CardScreen *screen, s32 side, s32 color) {
62 s32 done = 0;
63
64 if (battle->effectStep.nextState != 0) {
65 switch (battle->effectStep.nextState) {
66 case 1:
67 screen->setPanelFlags(screen, 1 << (color * 2) << side);
68 battle->effectStep.time = 0;
69 battle->effectStep.vars[0] = 0;
70 break;
71 case 2:
72 screen->clearPanelFlags(screen);
73 break;
74 }
75 battle->effectStep.state = battle->effectStep.nextState;
76 battle->effectStep.nextState = 0;
77 }
78 switch (battle->effectStep.state) {
79 case 1:
80 if (battle->effectStep.time == battle->effectStep.vars[2] / 2) {
81 if (battle->effectStep.vars[3] > 0) {
82 if (battle->sides[side].pile.points[color] < 99) {
83 battle->sides[side].pile.points[color]++;
84 }
85 battle->effectStep.vars[3]--;
87 } else {
88 if (battle->sides[side].pile.points[color] != 0) {
89 battle->sides[side].pile.points[color]--;
90 }
91 battle->effectStep.vars[3]++;
93 }
94 screen->setPanelValue(screen, side, color, battle->sides[side].pile.points[color]);
95 }
96 battle->effectStep.time++;
97 if (battle->effectStep.time > battle->effectStep.vars[2]) {
98 if (battle->effectStep.vars[3] == 0 || battle->sides[side].pile.points[color] == 0) {
99 battle->effectStep.nextState = 2;
100 } else {
101 battle->effectStep.nextState = 1;
102 }
103 }
104 break;
105 case 2:
106 done = 1;
107 break;
108 }
109 return done;
110}
111
112/* Starts CARDGAME_drainColorValues */
114 CARDGAME_startColorChange(battle, screen, -0x80, 0x10);
115 battle->effectStep.vars[4] = 0;
116}
117
118/* Counts both sides' colour values (pile.points) down by one each effectStep.vars[2] frames, on the panels, until they are all 0; 1 when done */
120 s32 done = 0;
121 s32 side;
122 s32 i;
123 s32 any;
124 s32 j;
125 s32 k;
126
127 if (battle->effectStep.nextState != 0) {
128 switch (battle->effectStep.nextState) {
129 case 1:
130 screen->setPanelFlags(screen, 0x3FF);
131 battle->effectStep.time = 0;
132 battle->effectStep.vars[0] = 0;
133 break;
134 case 2:
135 screen->clearPanelFlags(screen);
136 break;
137 }
138 battle->effectStep.state = battle->effectStep.nextState;
139 battle->effectStep.nextState = 0;
140 }
141 switch (battle->effectStep.state) {
142 case 1:
143 if (battle->effectStep.time == battle->effectStep.vars[2] / 2) {
144 for (side = 0; side < 2; side++) {
145 for (i = 0; i < 5; i++) {
146 if (battle->sides[side].pile.points[i] != 0) {
147 battle->sides[side].pile.points[i]--;
148 }
149 screen->setPanelValue(screen, side, i, battle->sides[side].pile.points[i]);
150 }
151 }
152 }
153 battle->effectStep.time++;
154 if (battle->effectStep.time > battle->effectStep.vars[2]) {
155 any = 0;
156 for (j = 0; j < 2; j++) {
157 for (k = 0; k < 5; k++) {
158 if (battle->sides[j].pile.points[k] != 0) {
159 any = 1;
160 }
161 }
162 }
163 if (any) {
164 battle->effectStep.nextState = 1;
165 } else {
166 battle->effectStep.nextState = 2;
167 }
168 }
169 break;
170 case 2:
171 done = 1;
172 break;
173 }
174 return done;
175}
176
177/* Closes the gauge of the card before the last one */
179 battle->effectStep.time = 0;
180 battle->effectStep.state = 1;
181 screen->closeGauge(screen, battle->record.playCount - 2);
182}
183
184/* Puts the card played before the last one (record.plays[playCount - 2]) on its side's discards once its sprite has turned; 1 when done */
186 s32 done = 0;
187 s32 side;
188 s32 n;
189 s32 i;
190
191 switch (battle->effectStep.state) {
192 case 1:
193 if (CARDGAME_stepShakeAway(battle, screen, battle->record.playCount + 10)) {
194 battle->effectStep.vars[0] = 10;
195 battle->effectStep.state = 2;
196 side = battle->record.plays[battle->record.playCount - 2].side;
197 battle->sides[side].pile.discards[battle->sides[side].pile.discardCount] = battle->record.plays[battle->record.playCount - 2].card;
198 battle->sides[side].pile.discardCount++;
199 screen->setPanelValue(screen, 0, CARD_PANEL_DISCARDS, battle->sides[0].pile.discardCount);
200 screen->setPanelValue(screen, 1, CARD_PANEL_DISCARDS, battle->sides[1].pile.discardCount);
201 }
202 break;
203 case 2:
204 battle->effectStep.vars[0] -= GFX.funcs.getFrameTime();
205 if (battle->effectStep.vars[0] <= 0) {
206 battle->effectStep.state = 3;
207 n = battle->record.playCount - 1;
208 if (n >= 2) {
209 battle->record.plays[battle->record.playCount - 3].mark = 0;
210 }
211 for (i = 0; i < 15; i++) {
212 screen->sprites[i].marks[n - 1] = 0;
213 }
214 }
215 break;
216 case 3:
217 done = 1;
218 break;
219 }
220 return done;
221}
222
223/* Keeps the last card played in keptCard (as card + 1) and counts it (keptCount);
224 1 */
226 s32 card = battle->record.plays[battle->record.playCount - 1].card;
227
228 battle->keptCount++;
229 battle->keptCard = card + 1;
230 return 1;
231}
232
233/* Shows side's card at effectStep.choice as sprite 17: of its hand (which 0) or its deck
234 (1) */
235void CARDGAME_showPileCard(CardBattle *battle, CardScreen *screen, s32 side, s32 which) {
236 s32 card;
237
238 screen->addSprite(screen, 17, 0xE500, 0x6100);
239 card = 0;
240 screen->sprites[17].scaleX = 0;
241 switch (which) {
242 case 0:
243 card = battle->sides[side].pile.hand[battle->effectStep.choice];
244 battle->effectStep.vars[4] = card;
245 break;
246 case 1:
247 card = battle->sides[side].pile.deck[battle->effectStep.choice];
248 battle->effectStep.vars[4] = card;
249 break;
250 }
251 screen->setSpriteCard(screen, 17, card);
252 screen->scaleSprite(screen, 17, 8, 0x1000, 0x1000);
253 battle->effectStep.time = 0;
254 battle->effectStep.state = 1;
255}
256
257/* Moves sprite 17 to the side's spot, then puts card effectStep.vars[4] on the side's discards and takes entry effectStep.choice out of the pile it came from (from 0: the hand, from 1: the deck after deckTop); 1 when over */
259 s32 done = 0;
260 /* the match depends on the loops of from 1 having a variable of their own */
261 s32 i, j;
262
263 switch (battle->effectStep.state) {
264 case 1:
265 battle->effectStep.time += GFX.funcs.getFrameTime();
266 if (battle->effectStep.time >= 21) {
267 screen->startMove(screen, 17, 10, CARDGAME_discardPositions[side][0], CARDGAME_discardPositions[side][1]);
268 screen->setSpriteScale(screen, 17, 0, 0);
269 battle->effectStep.state = 2;
270 }
271 break;
272 case 2:
273 if (screen->sprites[17].state == 1) {
274 battle->effectStep.state = 3;
275 battle->effectStep.time = 0;
276 battle->sides[side].pile.discards[battle->sides[side].pile.discardCount] = battle->effectStep.vars[4];
277 battle->sides[side].pile.discardCount++;
278 switch (from) {
279 case 0:
280 for (i = battle->effectStep.choice; i < battle->sides[side].pile.handCount - 1; i++) {
281 battle->sides[side].pile.hand[i] = battle->sides[side].pile.hand[i + 1];
282 }
283 screen->setPanelValue(screen, side, CARD_PANEL_HAND, --battle->sides[side].pile.handCount);
284 break;
285 case 1:
286 if (side == 0) {
287 for (i = battle->effectStep.choice; i >= battle->sides[side].pile.deckTop + 1; i--) {
288 battle->sides[side].pile.deck[i] = battle->sides[side].pile.deck[i - 1];
289 }
290 battle->sides[side].pile.deckTop++;
291 battle->sides[side].pile.deckCount--;
292 } else {
293 for (j = battle->effectStep.choice; j >= battle->sides[side].pile.deckTop + 1; j--) {
294 battle->sides[side].pile.deck[j] = battle->sides[side].pile.deck[j - 1];
295 battle->opponentDraws[j] = battle->opponentDraws[j - 1];
296 }
297 if (++battle->drawEnd >= 40) {
298 battle->drawEnd = 39;
299 }
300 if (++battle->reserveStart >= 40) {
301 battle->reserveStart = 39;
302 }
303 battle->sides[side].pile.deckTop++;
304 battle->sides[side].pile.deckCount--;
305 for (j = 0; j < 40; j++) {
306 battle->opponentDraws[j].order = j;
307 }
308 }
309 screen->setPanelValue(screen, side, CARD_PANEL_DECK, battle->sides[side].pile.deckCount);
310 break;
311 }
312 screen->setPanelValue(screen, side, CARD_PANEL_DISCARDS, battle->sides[side].pile.discardCount);
313 }
314 break;
315 case 3:
316 battle->effectStep.time += GFX.funcs.getFrameTime();
317 if (battle->effectStep.time >= 46) {
318 battle->effectStep.state = 4;
319 }
320 break;
321 case 4:
322 done = 1;
323 break;
324 }
325 return done;
326}
327
328/* Adds card effectStep.choice of a side's discards (which 4) or deck to its hand */
329void CARDGAME_takeCardToHand(CardBattle *battle, CardScreen *screen, s32 side, s32 which) {
330 s32 card;
331 s32 i;
332
333 battle->effectStep.vars[4] = battle->sides[side].pile.handCount;
334 if (which == 4) {
335 card = battle->sides[side].pile.discards[battle->effectStep.choice];
336 } else {
337 card = battle->sides[side].pile.deck[battle->effectStep.choice];
338 }
339 battle->sides[side].pile.hand[battle->sides[side].pile.handCount] = card;
340 battle->sides[side].pile.handCount++;
341 if (battle->effectStep.vars[4] != 0) {
342 if (side == 0) {
343 battle->anim.next = CARD_ANIM_SHOW_HAND;
344 } else {
346 battle->anim.faceDown = 1;
347 }
348 } else if (side == 0) {
350 } else {
352 battle->anim.faceDown = 1;
353 }
354 screen->openPanel(screen, side);
355 for (i = 0; i < 40; i++) {
356 battle->anim.dimmed[i] = 0;
357 }
358 battle->effectStep.state = 1;
359}
360
361/* Shows both sides' deck, hand and discard counts on their panels */
362static inline void showPileCounts(CardBattle *battle, CardScreen *screen) {
363 screen->setPanelValue(screen, 0, CARD_PANEL_DECK, battle->sides[0].pile.deckCount);
364 screen->setPanelValue(screen, 0, CARD_PANEL_HAND, battle->sides[0].pile.handCount);
365 screen->setPanelValue(screen, 0, CARD_PANEL_DISCARDS, battle->sides[0].pile.discardCount);
366 screen->setPanelValue(screen, 1, CARD_PANEL_DECK, battle->sides[1].pile.deckCount);
367 screen->setPanelValue(screen, 1, CARD_PANEL_HAND, battle->sides[1].pile.handCount);
368 screen->setPanelValue(screen, 1, CARD_PANEL_DISCARDS, battle->sides[1].pile.discardCount);
369}
370
371/* Takes card effectStep.choice out of side's used pile, shifting the cards
372 after it up */
373static inline void takeChosenDiscard(CardBattle *battle, s32 side) {
374 s32 i;
375
376 for (i = battle->effectStep.choice; i < battle->sides[side].pile.discardCount - 1; i++) {
377 battle->sides[side].pile.discards[i] = battle->sides[side].pile.discards[i + 1];
378 }
379 battle->sides[side].pile.discardCount--;
380}
381
382/* Takes card effectStep.choice out of side's deck (for the computer, a
383 reserve card goes from the bottom), shifting the cards above it down */
384static inline void takeChosenCard(CardBattle *battle, s32 side) {
385 s32 i;
386 s32 j;
387 s32 k;
388 s32 swap;
389
390 if (side == 0) {
391 for (j = battle->effectStep.choice; j >= battle->sides[0].pile.deckTop + 1; j--) {
392 battle->sides[0].pile.deck[j] = battle->sides[0].pile.deck[j - 1];
393 }
394 } else {
395 if (battle->effectStep.choice < battle->drawEnd) {
396 for (i = battle->effectStep.choice; i >= battle->sides[1].pile.deckTop + 1; i--) {
397 battle->sides[1].pile.deck[i] = battle->sides[1].pile.deck[i - 1];
398 battle->opponentDraws[i] = battle->opponentDraws[i - 1];
399 }
400 } else {
401 i = battle->effectStep.choice;
402 if (battle->opponentDraws[i].group == 7) {
403 for (; i >= battle->sides[1].pile.deckTop + 1; i--) {
404 battle->sides[1].pile.deck[i] = battle->sides[1].pile.deck[i - 1];
405 battle->opponentDraws[i] = battle->opponentDraws[i - 1];
406 }
407 battle->drawEnd++;
408 battle->reserveStart++;
409 } else {
410 swap = battle->sides[1].pile.deck[i];
411 battle->sides[1].pile.deck[i] = battle->sides[1].pile.deck[39];
412 battle->sides[1].pile.deck[39] = swap;
413 for (i = 39; i >= battle->sides[1].pile.deckTop + 1; i--) {
414 battle->sides[1].pile.deck[i] = battle->sides[1].pile.deck[i - 1];
415 battle->opponentDraws[i] = battle->opponentDraws[i - 1];
416 }
417 battle->drawEnd++;
418 battle->reserveStart++;
419 }
420 }
421 for (k = 0; k < 40; k++) {
422 battle->opponentDraws[k].order = k;
423 }
424 }
425 battle->sides[side].pile.deckTop++;
426 battle->sides[side].pile.deckCount--;
427}
428
429/* Moves the card just put in the hand into place, then takes card
430 effectStep.choice out of the deck (takeChosenCard), or out of the used pile
431 when which is 4 (takeChosenDiscard) */
432s32 CARDGAME_drawFromDeck(CardBattle *battle, CardScreen *screen, s32 side, s32 which) {
433 CardDrawer drawer;
434 s32 done = 0;
435 /* the match depends on a variable of its own for most states */
436 s32 ready;
437 s32 closed;
438 s32 index;
439 s32 top;
440 s32 last;
441 s32 card;
442 s32 drawn;
443 s32 x;
444
445 switch (battle->effectStep.state) {
446 case 1:
447 ready = 0;
448 if (side == 0) {
449 ready = screen->panels[0].state == 2;
450 } else if (screen->panels[1].state == 2) {
451 ready = 1;
452 }
453 last = battle->sides[side].pile.handCount - 1;
454 screen->sprites[last].x = 0x14A00;
455 if (ready && battle->anim.current == CARD_ANIM_NONE) {
456 x = screen->getHandOffset(battle->sides[side].pile.handCount, last);
457 screen->sprites[last].scaleX = 0x1000;
458 screen->startMove(screen, last, 15, x + 0x1800, 0x6100);
459 battle->effectStep.state = 2;
460 }
461 break;
462 case 2:
463 index = battle->sides[side].pile.handCount - 1;
464 if (screen->sprites[index].state == 1) {
465 if (which == 4) {
466 takeChosenDiscard(battle, side);
467 battle->effectStep.state = 4;
468 battle->effectStep.time = 45;
469 } else {
470 takeChosenCard(battle, side);
471 card = battle->sides[side].pile.hand[index];
472 initCardDrawer(&drawer);
473 drawer.setCard(battle->cards[card] + 1);
474 if (drawer.card->color < 6) {
475 battle->effectStep.state = 3;
476 screen->startBlink(screen, index);
477 } else {
478 battle->effectStep.state = 4;
479 battle->effectStep.time = 45;
480 }
481 }
482 showPileCounts(battle, screen);
483 }
484 break;
485 case 3:
486 top = battle->sides[side].pile.handCount - 1;
487 if (screen->sprites[top].state == 1) {
488 battle->effectStep.state = 4;
489 battle->effectStep.time = 45;
490 drawn = battle->sides[side].pile.hand[top];
491 initCardDrawer(&drawer);
492 drawer.setCard(battle->cards[drawn] + 1);
493 if (drawer.card->color < 6) {
494 if (battle->sides[side].pile.points[drawer.card->color - 1] < 99) {
495 battle->sides[side].pile.points[drawer.card->color - 1]++;
496 }
497 screen->setPanelValue(screen, side, drawer.card->color - 1, battle->sides[side].pile.points[drawer.card->color - 1]);
498 }
499 }
500 break;
501 case 4:
502 battle->effectStep.time -= GFX.funcs.getFrameTime();
503 if (battle->effectStep.time <= 0) {
504 battle->effectStep.state = 5;
505 screen->closePanel(screen, side);
506 battle->anim.next = battle->anim.hide;
507 }
508 break;
509 case 5:
510 closed = 0;
511 if (side == 0) {
512 closed = screen->panels[0].state == 0;
513 } else if (screen->panels[1].state == 0) {
514 closed = 1;
515 }
516 if (closed && battle->anim.current == CARD_ANIM_NONE) {
517 battle->effectStep.state = 6;
518 }
519 break;
520 case 6:
521 done = 1;
522 break;
523 }
524 return done;
525}
526
527/* Starts a count of side's discards and deck (effectStep.vars[0] and effectStep.vars[1]) */
529 battle->effectStep.time = 0;
530 battle->effectStep.vars[3] = 0;
531 battle->effectStep.vars[0] = battle->sides[side].pile.discardCount;
532 battle->effectStep.vars[1] = battle->sides[side].pile.deckCount;
533 battle->effectStep.state = 1;
534}
535
536/* Counts the panel's discards down into its deck, then puts the side's discards back
537 into its deck; 1 once done */
539 CardPile *pile;
540 s16 *deck;
541 s16 *used;
542 s32 done = 0;
543 s32 more;
544 s32 i;
545 s32 j;
546
547 switch (battle->effectStep.state) {
548 case 1:
549 battle->effectStep.time += GFX.funcs.getFrameTime();
550 battle->effectStep.vars[3] += GFX.funcs.getFrameTime();
551 if (battle->effectStep.vars[3] >= 7) {
552 more = 0;
553 if (battle->effectStep.vars[0] > 0) {
554 more = 1;
555 battle->effectStep.vars[0]--;
556 battle->effectStep.vars[1]++;
557 }
558 if (!more) {
559 battle->effectStep.state = 2;
560 }
561 screen->setPanelValue(screen, side, CARD_PANEL_DISCARDS, battle->effectStep.vars[0]);
562 screen->setPanelValue(screen, side, CARD_PANEL_DECK, battle->effectStep.vars[1]);
563 battle->effectStep.vars[3] -= 7;
564 }
565 break;
566 case 2:
567 pile = &battle->sides[side].pile;
568 deck = pile->deck;
569 used = pile->discards;
570 if (side == 0) {
571 j = pile->deckTop - 1;
572 for (i = pile->discardCount - 1; i >= 0; i--) {
573 deck[j--] = used[i];
574 pile->deckTop--;
575 pile->deckCount++;
576 }
577 pile->discardCount = 0;
578 battle->shufflePile(battle, pile->deckTop, pile->deckCount);
579 } else {
580 for (i = pile->discardCount - 1; i >= 0; i--) {
581 pile->deckTop--;
582 pile->deckCount++;
583 for (j = pile->deckTop; j < 40; j++) {
584 deck[j] = deck[j + 1];
585 battle->opponentDraws[j] = battle->opponentDraws[j + 1];
586 }
587 battle->drawEnd--;
588 battle->reserveStart--;
589 deck[39] = used[i];
590 battle->opponentDraws[39].group = 7;
591 }
592 for (i = 0; i < 40; i++) {
593 battle->opponentDraws[i].order = i;
594 }
595 pile->discardCount = 0;
596 }
597 done = 1;
598 break;
599 }
600 return done;
601}
602
603/* Starts drawing count cards (effectStep.count) */
604void CARDGAME_startDraw(CardBattle *battle, CardScreen *screen, s32 count) {
605 s32 i;
606
607 for (i = 0; i < 40; i++) {
608 battle->effectStep.marked[i] = 0;
609 }
610 battle->effectStep.count = count;
611 battle->effectStep.flags = 0;
612}
613
614/* Marks (effectStep.marked) the cards side draws from its deck: from its top for the
615 player, by the round's level (round) for the computer; effectStep.flags when the
616 deck runs out; 1 */
618 s32 i;
619 u8 n;
620 s32 k;
621 s32 m;
622
623 if (battle->effectStep.count != 0) {
624 if (side == 0) {
625 n = 0;
626 for (i = battle->sides[0].pile.deckTop; i < battle->sides[0].pile.deckTop + battle->effectStep.count; i++) {
627 if (i >= 40) {
628 battle->effectStep.flags = 1;
629 battle->effectStep.count = n;
630 break;
631 }
632 battle->effectStep.marked[i] = 1;
633 n++;
634 }
635 } else {
636 k = battle->sides[1].pile.deckTop;
637 m = 39;
638 if (battle->effectStep.count > battle->sides[1].pile.deckCount) {
639 battle->effectStep.flags = 1;
640 battle->effectStep.count = battle->sides[1].pile.deckCount;
641 }
642 for (i = 0; i < battle->effectStep.count; i++) {
643 if (battle->opponentDraws[k].group == battle->round * 2 + 2) {
644 battle->effectStep.marked[k] = 1;
645 k++;
646 } else {
647 battle->effectStep.marked[m] = 1;
648 m--;
649 }
650 }
651 }
652 }
653 return 1;
654}
655
656/* Moves side's marked deck cards to its hand and opens its panel */
657void CARDGAME_drawMarkedCards(CardBattle *battle, CardScreen *screen, s32 side) {
658 s32 i;
659 s32 card;
660 s32 j;
661
662 battle->effectStep.vars[4] = battle->sides[side].pile.handCount;
663#if VERSION_EU || VERSION_JP
664 battle->effectStep.vars[1] = 0;
665#endif
666 for (i = battle->sides[side].pile.deckTop; i < 40; i++) {
667 if (battle->effectStep.marked[i] != 0) {
668 card = battle->sides[side].pile.deck[i];
669 battle->sides[side].pile.hand[battle->sides[side].pile.handCount] = card;
670 battle->sides[side].pile.handCount++;
671#if VERSION_EU || VERSION_JP
672 battle->effectStep.vars[1] = 1;
673#endif
674 }
675 }
676 for (j = 0; j < 40; j++) {
677 battle->anim.dimmed[j] = 0;
678 }
679 if (battle->effectStep.vars[4] != 0) {
680 if (side == 0) {
681 battle->anim.next = CARD_ANIM_SHOW_HAND;
682 } else {
684 battle->anim.faceDown = 1;
685 }
686 } else {
687 if (side == 0) {
689 } else {
691 battle->anim.faceDown = 1;
692 }
693 }
694 screen->openPanel(screen, side);
695 battle->effectStep.state = 1;
696}
697
698/* Goes on to the next drawn card, or once all are in place to the deck's
699 empty message or the wait before the panel closes */
700static inline void goToNextCard(CardBattle *battle, CardScreen *screen, s32 side) {
701 battle->effectStep.vars[0]++;
702 if (battle->effectStep.vars[0] < battle->sides[side].pile.handCount) {
703 battle->effectStep.state = 2;
704 } else if (battle->effectStep.flags != 0) {
705 screen->openMessage(screen, 0x35, 0, 0, side == 0 ? 2 : 0);
706 battle->effectStep.state = 5;
707 } else {
708 battle->effectStep.time = 45;
709 battle->effectStep.state = 8;
710 }
711}
712
713/* Takes the last marked card out of side's deck (for the computer, a reserve
714 card goes from the bottom), shifting the cards above it down */
715static inline void takeMarkedCard(CardBattle *battle, s32 side) {
716 s32 found;
717 /* the match depends on a loop variable of its own for most loops */
718 s32 i;
719 s32 j;
720 s32 m;
721 s32 n;
722 s32 swap;
723
724 for (i = 39, found = 0; i >= 0; i--) {
725 if (battle->effectStep.marked[i] != 0) {
726 found = 1;
727 break;
728 }
729 }
730 if (found) {
731 battle->effectStep.marked[i] = 0;
732 if (side == 0) {
733 for (m = i; m >= battle->sides[0].pile.deckTop + 1; m--) {
734 battle->sides[0].pile.deck[m] = battle->sides[0].pile.deck[m - 1];
735 battle->effectStep.marked[m] = battle->effectStep.marked[m - 1];
736 }
737 } else {
738 if (i < battle->drawEnd) {
739 for (j = i; j >= battle->sides[1].pile.deckTop + 1; j--) {
740 battle->sides[1].pile.deck[j] = battle->sides[1].pile.deck[j - 1];
741 battle->effectStep.marked[j] = battle->effectStep.marked[j - 1];
742 battle->opponentDraws[j] = battle->opponentDraws[j - 1];
743 }
744 } else {
745 if (battle->opponentDraws[i].group == 7) {
746 for (j = i; j >= battle->sides[1].pile.deckTop + 1; j--) {
747 battle->sides[1].pile.deck[j] = battle->sides[1].pile.deck[j - 1];
748 battle->effectStep.marked[j] = battle->effectStep.marked[j - 1];
749 battle->opponentDraws[j] = battle->opponentDraws[j - 1];
750 }
751 battle->drawEnd++;
752 battle->reserveStart++;
753 } else {
754 swap = battle->sides[1].pile.deck[i];
755 battle->sides[1].pile.deck[i] = battle->sides[1].pile.deck[39];
756 battle->sides[1].pile.deck[39] = swap;
757 for (j = 39; j >= battle->sides[1].pile.deckTop + 1; j--) {
758 battle->sides[1].pile.deck[j] = battle->sides[1].pile.deck[j - 1];
759 battle->effectStep.marked[j] = battle->effectStep.marked[j - 1];
760 battle->opponentDraws[j] = battle->opponentDraws[j - 1];
761 }
762 battle->drawEnd++;
763 battle->reserveStart++;
764 }
765 }
766 for (n = 0; n < 40; n++) {
767 battle->opponentDraws[n].order = n;
768 }
769 }
770 battle->sides[side].pile.deckTop++;
771 battle->sides[side].pile.deckCount--;
772 }
773}
774
775/* Moves the cards drawn into the hand (from effectStep.vars[4] on) into place
776 one at a time (goToNextCard), counting their colours and taking each flagged
777 card (effectStep.marked) out of the deck (takeMarkedCard) */
779 CardDrawer drawer;
780 s32 done = 0;
781 s32 ready;
782 s32 closed;
783 s32 card;
784 s32 k;
785 s32 x;
786
787 switch (battle->effectStep.state) {
788 case 1:
789 ready = 0;
790 if (side == 0) {
791 ready = screen->panels[0].state == 2;
792 } else if (screen->panels[1].state == 2) {
793 ready = 1;
794 }
795 for (k = battle->effectStep.vars[4]; k < battle->sides[side].pile.handCount; k++) {
796 screen->sprites[k].x = 0x14A00;
797 }
798 if (ready && battle->anim.current == CARD_ANIM_NONE) {
799#if VERSION_US
800 battle->effectStep.state = 2;
801#elif VERSION_EU || VERSION_JP
802 if (battle->effectStep.vars[1] == 0) {
803 screen->openMessage(screen, 0x35, 0, 0, side == 0 ? 2 : 0);
804 battle->effectStep.state = 5;
805 } else {
806 battle->effectStep.state = 2;
807 }
808#endif
809 battle->effectStep.time = 0;
810 battle->effectStep.vars[0] = battle->effectStep.vars[4];
811 }
812 break;
813 case 2:
814 x = screen->getHandOffset(battle->sides[side].pile.handCount, battle->effectStep.vars[0]);
815 screen->sprites[battle->effectStep.vars[0]].scaleX = 0x1000;
816 screen->startMove(screen, battle->effectStep.vars[0], 15, x + 0x1800, 0x6100);
817 battle->effectStep.state = 3;
818 break;
819 case 3:
820 if (screen->sprites[battle->effectStep.vars[0]].state == 1) {
821 card = battle->sides[side].pile.hand[battle->effectStep.vars[0]];
822 initCardDrawer(&drawer);
823 drawer.setCard(battle->cards[card] + 1);
824 if (drawer.card->color < 6) {
825 if (battle->sides[side].pile.points[drawer.card->color - 1] < 99) {
826 battle->sides[side].pile.points[drawer.card->color - 1]++;
827 }
828 screen->setPanelValue(screen, side, drawer.card->color - 1, battle->sides[side].pile.points[drawer.card->color - 1]);
829 screen->startBlink(screen, battle->effectStep.vars[0]);
830 battle->effectStep.state = 4;
831 } else {
832 goToNextCard(battle, screen, side);
833 }
834 takeMarkedCard(battle, side);
835 }
836 break;
837 case 4:
838 if (screen->sprites[battle->effectStep.vars[0]].state == 1) {
839 goToNextCard(battle, screen, side);
840 }
841 break;
842 case 5:
843 if (screen->message.state == 2) {
844 battle->effectStep.state = 6;
845 }
846 break;
847 case 6:
849 battle->effectStep.state = 7;
850 screen->closeMessage(screen);
851 }
852 break;
853 case 7:
854 if (screen->message.state == 0) {
855 battle->effectStep.time = 45;
856 battle->effectStep.state = 8;
857 }
858 break;
859 case 8:
860 showPileCounts(battle, screen);
861 battle->effectStep.time -= GFX.funcs.getFrameTime();
862 if (battle->effectStep.time <= 0) {
863 battle->effectStep.state = 9;
864 screen->closePanel(screen, side);
865 battle->anim.next = battle->anim.hide;
866 }
867 break;
868 case 9:
869 closed = 0;
870 if (side == 0) {
871 closed = screen->panels[0].state == 0;
872 } else if (screen->panels[1].state == 0) {
873 closed = 1;
874 }
875 if (closed && battle->anim.current == CARD_ANIM_NONE) {
876 battle->effectStep.state = 10;
877 }
878 break;
879 case 10:
880 done = 1;
881 break;
882 }
883 return done;
884}
CARDGAME.PRO: the card battle (mode 0x700).
void initCardDrawer(CardDrawer *obj)
Clears a card drawer, gives it its methods and binds it.
@ CARD_ANIM_LAY_OUT_HAND
the hand laid out at once
Definition battle.h:184
@ CARD_ANIM_SHOW_HAND
the player's piles...
Definition battle.h:172
@ CARD_ANIM_LAY_OUT_OPPONENT_HAND
Definition battle.h:185
@ CARD_ANIM_SHOW_OPPONENT_HAND
...and the opponent's
Definition battle.h:178
@ CARD_ANIM_NONE
Definition battle.h:167
s32 CARDGAME_discardPositions[][2]
x, y per side
Definition cardgame_2.c:31
signed int s32
Definition common.h:11
signed short s16
Definition common.h:9
unsigned char u8
Definition common.h:8
GfxState GFX
GFX: the graphics state and its methods.
Definition display.c:209
#define PAD_CROSS
Definition pad.h:31
#define PAD_TRIANGLE
Definition pad.h:32
#define PAD_PRESSED(button)
One button of pad 1: newly pressed, auto-repeated while held, or held.
Definition pad.h:140
static void takeChosenCard(CardBattle *battle, s32 side)
Takes card effectStep.choice out of side's deck (for the computer, a reserve card goes from the botto...
void CARDGAME_startDiscardCount(CardBattle *battle, CardScreen *screen, s32 side)
Starts a count of side's discards and deck (effectStep.vars[0] and effectStep.vars[1])
s32 CARDGAME_drainColorValues(CardBattle *battle, CardScreen *screen)
Counts both sides' colour values (pile.points) down by one each effectStep.vars[2] frames,...
s32 CARDGAME_drawFromDeck(CardBattle *battle, CardScreen *screen, s32 side, s32 which)
Moves the card just put in the hand into place, then takes card effectStep.choice out of the deck (ta...
void CARDGAME_takeCardToHand(CardBattle *battle, CardScreen *screen, s32 side, s32 which)
Adds card effectStep.choice of a side's discards (which 4) or deck to its hand.
s32 CARDGAME_keepLastCard(CardBattle *battle, CardScreen *screen)
Keeps the last card played in keptCard (as card + 1) and counts it (keptCount); 1.
s32 CARDGAME_discardPickedCard(CardBattle *battle, CardScreen *screen, s32 side, s32 from)
Moves sprite 17 to the side's spot, then puts card effectStep.vars[4] on the side's discards and take...
s32 CARDGAME_returnUsedCards(CardBattle *battle, CardScreen *screen, s32 side)
Counts the panel's discards down into its deck, then puts the side's discards back into its deck; 1 o...
void CARDGAME_startDraw(CardBattle *battle, CardScreen *screen, s32 count)
Starts drawing count cards (effectStep.count)
s32 CARDGAME_markDrawnCards(CardBattle *battle, CardScreen *screen, s32 side)
Marks (effectStep.marked) the cards side draws from its deck: from its top for the player,...
static void takeMarkedCard(CardBattle *battle, s32 side)
Takes the last marked card out of side's deck (for the computer, a reserve card goes from the bottom)...
s32 CARDGAME_stepColorValue(CardBattle *battle, CardScreen *screen, s32 side, s32 color)
Moves a side's colour value (pile.points[color]) one step each effectStep.vars[2] frames towards usin...
static void takeChosenDiscard(CardBattle *battle, s32 side)
Takes card effectStep.choice out of side's used pile, shifting the cards after it up.
void CARDGAME_startColorDrain(CardBattle *battle, CardScreen *screen)
Starts CARDGAME_drainColorValues.
s32 CARDGAME_discardHand(CardBattle *battle, CardScreen *screen, s32 side)
Counts a side's hand cards over to its discards on its panel, one every 7 frames, then moves them; 1 ...
void CARDGAME_startCloseGauge(CardBattle *battle, CardScreen *screen)
Closes the gauge of the card before the last one.
static void showPileCounts(CardBattle *battle, CardScreen *screen)
Shows both sides' deck, hand and discard counts on their panels.
void CARDGAME_startColorChange(CardBattle *battle, CardScreen *screen, s32 amount, s32 interval)
Starts CARDGAME_stepColorValue: amount (effectStep.vars[3], below 0 to take) one at a time,...
s32 CARDGAME_discardPrevCard(CardBattle *battle, CardScreen *screen)
Puts the card played before the last one (record.plays[playCount - 2]) on its side's discards once it...
void CARDGAME_drawMarkedCards(CardBattle *battle, CardScreen *screen, s32 side)
Moves side's marked deck cards to its hand and opens its panel.
s32 CARDGAME_drawNewCards(CardBattle *battle, CardScreen *screen, s32 side)
Moves the cards drawn into the hand (from effectStep.vars[4] on) into place one at a time (goToNextCa...
void CARDGAME_startHandCount(CardBattle *battle, CardScreen *screen, s32 side)
Starts a count of side's hand and discards (effectStep.vars[0] and effectStep.vars[1])
Definition pile_effects.c:7
static void goToNextCard(CardBattle *battle, CardScreen *screen, s32 side)
Goes on to the next drawn card, or once all are in place to the deck's empty message or the wait befo...
void CARDGAME_showPileCard(CardBattle *battle, CardScreen *screen, s32 side, s32 which)
Shows side's card at effectStep.choice as sprite 17: of its hand (which 0) or its deck (1)
@ CARD_PANEL_HAND
Definition screen.h:200
@ CARD_PANEL_DISCARDS
Definition screen.h:201
@ CARD_PANEL_DECK
Definition screen.h:199
s32 CARDGAME_stepShakeAway(CardBattle *battle, CardScreen *screen, s32 index)
Shakes sprite index, then shrinks it to nothing; 1 once done.
SoundState SOUND
rsin and rcos (libgte) read rsin_tbl[a - 0x800] and the like: their addresses before the table fall i...
Definition sound.c:180
#define SOUND_COUNT
SYSTEM10: a number counts up or down.
Definition sound.h:45
u8 faceDown
the next pile or slots are laid out face down
Definition battle.h:198
u8 next
the one to start
Definition battle.h:195
u8 current
a CardAnimId
Definition battle.h:194
u8 hide
the one that hides what the last one showed
Definition battle.h:197
u8 dimmed[40]
by sprite
Definition battle.h:200
The card battle (CARDGAME_createBattle).
Definition battle.h:226
u8 drawEnd
the first card of the opponent's deck above the round's group
Definition battle.h:260
CardRecord record
Definition battle.h:273
s16 cards[250]
card ids, minus one (CARDGAME_loadCardImages)
Definition battle.h:228
u8 keptCount
and how many times
Definition battle.h:250
void(* shufflePile)(struct CardBattle *battle, s32 base, s32 n)
Definition battle.h:276
u8 reserveStart
the first card of the opponent's deck held back (group 7)
Definition battle.h:261
CardAnim anim
Definition battle.h:263
CardStep effectStep
Definition battle.h:262
u8 round
from 0
Definition battle.h:245
u8 keptCard
the card CARDGAME_keepLastCard kept, plus one
Definition battle.h:249
CardSide sides[2]
Definition battle.h:274
CardDraw opponentDraws[40]
by the opponent's deck card
Definition battle.h:255
u8 order
its place in the deck
Definition battle.h:103
u8 group
Definition battle.h:104
Draws the cards' images (CardImage), from files 0x7E7-0x7EB.
Definition gfx.h:193
void(* setCard)()
(id)
Definition gfx.h:205
CardImage * card
Definition gfx.h:194
u8 color
from 1
Definition gfx.h:173
u8 state
1 opening, 2 open, 4 confirmed, 5 closing
Definition screen.h:256
s16 state
Definition screen.h:137
A player's cards in a card battle (CardSide.pile)
Definition battle.h:108
s16 deckCount
the cards left in the deck
Definition battle.h:113
s16 discardCount
Definition battle.h:112
s16 deck[40]
deckTop on are left
Definition battle.h:118
s16 handCount
Definition battle.h:114
s16 deckTop
the index of the deck's top card
Definition battle.h:111
u8 points[5]
one per card colour
Definition battle.h:115
s16 discards[10]
the cards played and lost from the slots, discardCount in use
Definition battle.h:120
s16 hand[10]
handCount in use
Definition battle.h:119
s16 card
the index in the battle's card list
Definition battle.h:44
u8 side
who played it
Definition battle.h:46
s16 mark
Definition battle.h:45
s8 playCount
the plays in use
Definition battle.h:130
CardPlay plays[3]
the cards played this turn, up to three
Definition battle.h:137
The battle screen (created by CARDGAME_createScreen): the two panels, the cards on the table and the ...
Definition screen.h:263
CardMessageWindow message
Definition screen.h:274
void(* setSpriteCard)(struct CardScreen *screen, s32 sprite, s32 index)
Definition screen.h:324
void(* closePanel)(struct CardScreen *screen, s32 side)
Definition screen.h:292
void(* setPanelValue)(struct CardScreen *screen, s32 side, u32 which, s32 value)
Definition screen.h:285
void(* scaleSprite)(struct CardScreen *screen, s32 index, s32 duration, s32 scaleX, s32 scaleY)
Definition screen.h:318
void(* setPanelFlags)(struct CardScreen *screen, s32 bits)
Definition screen.h:291
void(* clearPanelFlags)(struct CardScreen *screen)
Definition screen.h:290
void(* startMove)(struct CardScreen *screen, s32 index, s32 duration, s32 x, s32 y)
Definition screen.h:311
CardSprite sprites[40]
Definition screen.h:271
void(* openMessage)(struct CardScreen *screen, s32 message, s32 prompt, s16 choice, s32 place)
Definition screen.h:302
s32(* getHandOffset)(s32 count, s32 index)
Definition screen.h:299
void(* setSpriteScale)(struct CardScreen *screen, s32 index, s32 scaleX, s32 scaleY)
Definition screen.h:317
void(* closeMessage)(struct CardScreen *screen)
Definition screen.h:303
s32(* startBlink)(struct CardScreen *screen, s32 index)
Definition screen.h:316
void(* closeGauge)(struct CardScreen *screen, s32 index)
Definition screen.h:287
s32(* addSprite)(struct CardScreen *screen, s32 index, s32 x, s32 y)
Definition screen.h:314
void(* openPanel)(struct CardScreen *screen, s32 side)
Definition screen.h:293
CardPanel panels[2]
Definition screen.h:270
CardPile pile
Definition battle.h:160
s16 scaleX
Definition screen.h:170
u8 marks[3]
the plays that apply to the card, drawn as marks
Definition screen.h:185
s32 time
a frame count, or the step's own sub-state
Definition battle.h:148
u8 count
the cards picked, or to draw
Definition battle.h:152
u8 state
the step's own state
Definition battle.h:146
s32 vars[5]
values each step uses its own way
Definition battle.h:149
u8 nextState
the state to set up first, if not 0
Definition battle.h:147
u8 flags
the step's own: the rows to pick from, the deck run out...
Definition battle.h:153
s8 marked[40]
the cards or slots picked
Definition battle.h:155
s32 choice
the card, slot or answer chosen; -1 for none
Definition battle.h:151
s32(* getFrameTime)(void)
Definition gfx.h:32
GfxFuncs funcs
Definition gfx.h:77
short(* playSound)(s32 id)
returns the voice of a key-on
Definition sound.h:187