Added greedy joker and refactor joker system
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 864 B After Width: | Height: | Size: 1.5 KiB |
+3
-3
@@ -8,8 +8,8 @@
|
||||
|
||||
// Card suits
|
||||
#define HEARTS 0
|
||||
#define DIAMONDS 1
|
||||
#define CLUBS 2
|
||||
#define CLUBS 1
|
||||
#define DIAMONDS 2
|
||||
#define SPADES 3
|
||||
#define NUM_SUITS 4
|
||||
|
||||
@@ -66,6 +66,6 @@ CardObject *card_object_new(Card *card);
|
||||
void card_object_destroy(CardObject **card_object);
|
||||
void card_object_update(CardObject *card_object); // Update the card object position and scale
|
||||
void card_object_set_sprite(CardObject *card_object, int layer);
|
||||
void card_object_score(CardObject *card_object, mm_word sound_id); // This doesn't actually score anything, it just performs an animation and plays a sound effect
|
||||
void card_object_shake(CardObject *card_object, mm_word sound_id); // This doesn't actually score anything, it just performs an animation and plays a sound effect
|
||||
|
||||
#endif // CARD_H
|
||||
+4
-13
@@ -62,16 +62,7 @@ typedef struct // These jokers are triggered after the played hand has finished
|
||||
int xmult;
|
||||
int money;
|
||||
bool retrigger; // Retrigger played hand (e.g. "Dusk" joker, even though on the wiki it says "On Scored" it makes more sense to have it here)
|
||||
} IndependentEffect;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int chips;
|
||||
int mult;
|
||||
int xmult;
|
||||
int money;
|
||||
bool retrigger; // Retrigger scored card
|
||||
} OnScoredEffect;
|
||||
} JokerEffect;
|
||||
|
||||
void joker_init();
|
||||
|
||||
@@ -80,12 +71,12 @@ void joker_destroy(Joker **joker);
|
||||
|
||||
// Unique effects like "Four Fingers" or "Credit Card" will be hard coded into game.c with a conditional check for the joker ID from the players owned jokers
|
||||
// game.c should probably be restructured so most of the variables in it are moved to some sort of global variable header file so they can be easily accessed and modified for the jokers
|
||||
IndependentEffect joker_independent_effect(Joker *joker);
|
||||
OnScoredEffect joker_on_scored(Joker *joker, Card *scored_card);
|
||||
JokerEffect joker_get_score_effect(Joker *joker, Card *scored_card);
|
||||
|
||||
JokerObject *joker_object_new(Joker *joker);
|
||||
void joker_object_destroy(JokerObject **joker_object);
|
||||
void joker_object_update(JokerObject *joker_object);
|
||||
void joker_object_score(JokerObject *joker_object, mm_word sound_id); // This doesn't actually score anything, it just performs an animation and plays a sound effect
|
||||
void joker_object_shake(JokerObject *joker_object, mm_word sound_id); // This doesn't actually score anything, it just performs an animation and plays a sound effect
|
||||
bool joker_object_score(JokerObject *joker_object, Card* scored_card, int *chips, int *mult, int *xmult, int *money, bool *retrigger); // This scores the joker and returns true if it was scored successfully (Card = NULL means the joker is independent and not scored by a card)
|
||||
|
||||
#endif // JOKER_H
|
||||
+1
-1
@@ -153,7 +153,7 @@ void card_object_set_sprite(CardObject *card_object, int layer)
|
||||
card_object->sprite = sprite_new(ATTR0_SQUARE | ATTR0_4BPP | ATTR0_AFF, ATTR1_SIZE_32, card_sprite_lut[card_object->card->suit][card_object->card->rank], 0, layer);
|
||||
}
|
||||
|
||||
void card_object_score(CardObject *card_object, mm_word sound_id)
|
||||
void card_object_shake(CardObject *card_object, mm_word sound_id)
|
||||
{
|
||||
card_object->vscale = float2fx(0.3f); // Scale down the card when it's scored
|
||||
card_object->vrotation = float2fx(8.0f); // Rotate the card when it's scored
|
||||
|
||||
+45
-55
@@ -1549,82 +1549,70 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection
|
||||
{
|
||||
// So pretend "played_selections" is now called "scored_cards" and it counts the number of cards that have been scored
|
||||
int scored_cards = 0;
|
||||
for (int j = played_top; j >= 0; j--)
|
||||
for (int j = 0; j <= played_top; j++)
|
||||
{
|
||||
if (played[played_top - j]->selected)
|
||||
tte_erase_rect_wrapper(PLAYED_CARDS_SCORES_RECT);
|
||||
|
||||
if (*played_selections > 0)
|
||||
{
|
||||
scored_cards++;
|
||||
for (int k = 0; k <= jokers_top; k++)
|
||||
{
|
||||
if (joker_object_score(jokers[k], played[*played_selections - 1]->card, &chips, &mult, NULL, &money, NULL)) // NULLs aren't implemented yet
|
||||
{
|
||||
set_chips(chips);
|
||||
set_mult(mult);
|
||||
set_money(money);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (played[j]->selected)
|
||||
{
|
||||
scored_cards = j + 1; // Count the number of cards that have been scored
|
||||
if (scored_cards > *played_selections)
|
||||
{
|
||||
tte_erase_rect_wrapper(PLAYED_CARDS_SCORES_RECT);
|
||||
tte_set_pos(fx2int(played[played_top - j]->x) + 8, 48); // Offset of 16 pixels to center the text on the card
|
||||
for (int k = 0; k <= jokers_top; k++)
|
||||
{
|
||||
if (jokers[k] != NULL)
|
||||
{
|
||||
jokers[k]->joker->processed = false; // Reset the joker's processed state for the next score
|
||||
}
|
||||
}
|
||||
|
||||
tte_set_pos(fx2int(played[j]->x) + 8, 48); // Offset of 16 pixels to center the text on the card
|
||||
tte_set_special(0xD000); // Set text color to blue from background memory
|
||||
|
||||
// Write the score to a character buffer variable
|
||||
char score_buffer[5]; // Assuming the maximum score is 99, we need 4 characters (2 digits + null terminator)
|
||||
snprintf(score_buffer, sizeof(score_buffer), "+%d", card_get_value(played[played_top - j]->card));
|
||||
snprintf(score_buffer, sizeof(score_buffer), "+%d", card_get_value(played[j]->card));
|
||||
tte_write(score_buffer);
|
||||
|
||||
*played_selections = scored_cards;
|
||||
card_object_score(played[played_top - j], SFX_CARD_SELECT);
|
||||
card_object_shake(played[j], SFX_CARD_SELECT);
|
||||
|
||||
// Relocated card scoring logic here
|
||||
chips += card_get_value(played[played_top - j]->card);
|
||||
chips += card_get_value(played[j]->card);
|
||||
set_chips(chips);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == 0 && scored_cards == *played_selections) // Check if it's the last card
|
||||
if (j == played_top && scored_cards == *played_selections) // Check if it's the last card
|
||||
{
|
||||
tte_erase_rect_wrapper(PLAYED_CARDS_SCORES_RECT);
|
||||
|
||||
for (int k = 0; k <= jokers_top; k++)
|
||||
for (int k = 0; k <= jokers_top; k++) // Independent joker scoring loop
|
||||
{
|
||||
if (jokers[k]->joker->processed == false)
|
||||
{
|
||||
IndependentEffect joker_effect = joker_independent_effect(jokers[k]->joker);
|
||||
IndependentEffect zero_effect = {0};
|
||||
if (joker_object_score(jokers[k], NULL, &chips, &mult, NULL, &money, NULL)) // NULLs aren't implemented yet
|
||||
{
|
||||
set_chips(chips);
|
||||
set_mult(mult);
|
||||
set_money(money);
|
||||
|
||||
if (memcmp(&joker_effect, &zero_effect, sizeof(IndependentEffect)) != 0)
|
||||
{
|
||||
chips += joker_effect.chips;
|
||||
set_chips(chips);
|
||||
mult += joker_effect.mult;
|
||||
set_mult(mult);
|
||||
// TODO: XMult
|
||||
money += joker_effect.money;
|
||||
set_money(money);
|
||||
// TODO: Retrigger
|
||||
|
||||
|
||||
tte_set_pos(fx2int(jokers[k]->x) + 8, 48); // Offset of 16 pixels to center the text on the card
|
||||
|
||||
char score_buffer[12];
|
||||
|
||||
if (joker_effect.chips > 0)
|
||||
{
|
||||
tte_set_special(0xD000); // Blue
|
||||
snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.chips);
|
||||
}
|
||||
else if (joker_effect.mult > 0)
|
||||
{
|
||||
tte_set_special(0xE000); // Red
|
||||
snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.mult);
|
||||
}
|
||||
else if (joker_effect.money > 0)
|
||||
{
|
||||
tte_set_special(0xC000); // Yellow
|
||||
snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.money);
|
||||
}
|
||||
|
||||
tte_write(score_buffer);
|
||||
|
||||
jokers[k]->joker->processed = true; // Mark the joker as processed
|
||||
joker_object_score(jokers[k], SFX_CARD_SELECT);
|
||||
|
||||
return; // Returning was just the easiest way to break out of the loop
|
||||
}
|
||||
return; // Returning was just the easiest way to break out of the loop
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1805,7 +1793,9 @@ static void game_shop_create_items(JokerObject *shop_jokers[], bool first_time)
|
||||
joker_object_destroy(&shop_jokers[i]); // Destroy the joker object if it exists
|
||||
}
|
||||
|
||||
shop_jokers[i] = joker_object_new(joker_new(DEFAULT_JOKER_ID));
|
||||
u8 joker_id = random() % MAX_JOKERS;
|
||||
|
||||
shop_jokers[i] = joker_object_new(joker_new(joker_id));
|
||||
shop_jokers[i]->x = int2fx(120 + i * 32);
|
||||
shop_jokers[i]->y = int2fx(160);
|
||||
shop_jokers[i]->tx = shop_jokers[i]->x;
|
||||
@@ -1818,7 +1808,7 @@ static void game_shop_create_items(JokerObject *shop_jokers[], bool first_time)
|
||||
if (first_time == false)
|
||||
{
|
||||
shop_jokers[i]->y = shop_jokers[i]->ty; // If it's not the first time, set the y position to the target position
|
||||
joker_object_score(shop_jokers[i], UNDEFINED); // Give the joker a little wiggle animation
|
||||
joker_object_shake(shop_jokers[i], UNDEFINED); // Give the joker a little wiggle animation
|
||||
}
|
||||
|
||||
sprite_position(shop_jokers[i]->sprite, fx2int(shop_jokers[i]->x), fx2int(shop_jokers[i]->y));
|
||||
|
||||
+56
-5
@@ -4,9 +4,11 @@
|
||||
#include "joker_gfx.h"
|
||||
#include "graphic_utils.h"
|
||||
#include "card.h"
|
||||
#include "soundbank.h"
|
||||
|
||||
#include <maxmod.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
const static u8 joker_data_lut[MAX_JOKERS][2] = // Rarity, Value
|
||||
{
|
||||
@@ -58,17 +60,21 @@ void joker_destroy(Joker **joker)
|
||||
*joker = NULL;
|
||||
}
|
||||
|
||||
IndependentEffect joker_independent_effect(Joker *joker)
|
||||
JokerEffect joker_get_score_effect(Joker *joker, Card *scored_card)
|
||||
{
|
||||
IndependentEffect effect = {0};
|
||||
JokerEffect effect = {0};
|
||||
|
||||
switch (joker->id)
|
||||
{
|
||||
case DEFAULT_JOKER_ID: // Default Joker
|
||||
if (scored_card != NULL) break; // Joker is independent, no effect
|
||||
effect.mult = 4;
|
||||
break;
|
||||
case GREEDY_JOKER_ID: // Greedy Joker
|
||||
// Nothing because this joker is a scored type
|
||||
if (scored_card->suit == DIAMONDS) // If the scored card is a diamond
|
||||
{
|
||||
effect.mult = 3;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -139,8 +145,53 @@ void joker_object_update(JokerObject *joker_object)
|
||||
card_object_update(card_object);
|
||||
}
|
||||
|
||||
void joker_object_score(JokerObject *joker_object, mm_word sound_id) // Another derived function of card_object
|
||||
void joker_object_shake(JokerObject *joker_object, mm_word sound_id)
|
||||
{
|
||||
CardObject *card_object = (CardObject *)joker_object;
|
||||
card_object_score(card_object, sound_id);
|
||||
card_object_shake(card_object, sound_id);
|
||||
}
|
||||
|
||||
bool joker_object_score(JokerObject *joker_object, Card* scored_card, int *chips, int *mult, int *xmult, int *money, bool *retrigger)
|
||||
{
|
||||
if (joker_object->joker->processed == true) return false; // If the joker has already been processed, return false
|
||||
|
||||
JokerEffect joker_effect = joker_get_score_effect(joker_object->joker, scored_card);
|
||||
|
||||
if (memcmp(&joker_effect, &(JokerEffect){0}, sizeof(JokerEffect)) != 0)
|
||||
{
|
||||
*chips += joker_effect.chips;
|
||||
*mult += joker_effect.mult;
|
||||
// TODO: XMult
|
||||
*money += joker_effect.money;
|
||||
// TODO: Retrigger
|
||||
|
||||
tte_set_pos(fx2int(joker_object->x) + 8, 48); // Offset of 16 pixels to center the text on the card
|
||||
|
||||
char score_buffer[12];
|
||||
|
||||
if (joker_effect.chips > 0)
|
||||
{
|
||||
tte_set_special(0xD000); // Blue
|
||||
snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.chips);
|
||||
}
|
||||
else if (joker_effect.mult > 0)
|
||||
{
|
||||
tte_set_special(0xE000); // Red
|
||||
snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.mult);
|
||||
}
|
||||
else if (joker_effect.money > 0)
|
||||
{
|
||||
tte_set_special(0xC000); // Yellow
|
||||
snprintf(score_buffer, sizeof(score_buffer), "+%d", joker_effect.money);
|
||||
}
|
||||
|
||||
tte_write(score_buffer);
|
||||
|
||||
joker_object->joker->processed = true; // Mark the joker as processed
|
||||
joker_object_shake(joker_object, SFX_CARD_SELECT); // TODO: Add a sound effect for scoring the joker
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user