Merge branch 'main' into jokers_refactors
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
|
||||
+5
-14
@@ -36,7 +36,7 @@ typedef struct
|
||||
u8 modifier; // base, foil, holo, poly, negative
|
||||
u8 value;
|
||||
u8 rarity;
|
||||
bool proccessed;
|
||||
bool processed;
|
||||
} Joker;
|
||||
|
||||
typedef struct // copy of CardObject in card.h
|
||||
@@ -66,16 +66,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();
|
||||
|
||||
@@ -84,12 +75,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
|
||||
|
||||
+160
-142
@@ -30,6 +30,7 @@ static int background = 0;
|
||||
static enum GameState game_state = GAME_BLIND_SELECT; // The current game state, this is used to determine what the game is doing at any given time
|
||||
static enum HandState hand_state = HAND_DRAW;
|
||||
static enum PlayState play_state = PLAY_PLAYING;
|
||||
static int state = 0; // General state variable, used for switch statements in each game state related function
|
||||
|
||||
static enum HandType hand_type = NONE;
|
||||
|
||||
@@ -63,8 +64,7 @@ static int hand_size = 8; // Default hand size is 8
|
||||
static int cards_drawn = 0;
|
||||
static int hand_selections = 0;
|
||||
|
||||
static int card_focused = 0;
|
||||
static int previous_card_focused = 0;
|
||||
static int selection_x = 0;
|
||||
static int selection_y = 0;
|
||||
|
||||
static bool sort_by_suit = false;
|
||||
@@ -422,12 +422,13 @@ void change_background(int id)
|
||||
}
|
||||
else if (id == BG_ID_CARD_SELECTING)
|
||||
{
|
||||
tte_erase_rect_wrapper(HAND_SIZE_RECT_PLAYING);
|
||||
REG_WIN0V = (REG_WIN0V << 8) | 0x80; // Set window 0 top to 128
|
||||
|
||||
if (background == BG_ID_CARD_PLAYING)
|
||||
{
|
||||
int offset = 11;
|
||||
memcpy16(&se_mem[MAIN_BG_SBB][SE_ROW_LEN * offset], &background_gfxMap[SE_ROW_LEN * offset], SE_ROW_LEN * 8);
|
||||
tte_erase_rect_wrapper(HAND_SIZE_RECT_PLAYING);
|
||||
REG_WIN0V = (REG_WIN0V << 8) | 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -438,8 +439,6 @@ void change_background(int id)
|
||||
GRIT_CPY(&tile8_mem[MAIN_BG_CBB], background_gfxTiles); // Deadass i have no clue how any of these memory things work but I just messed with them until stuff worked
|
||||
GRIT_CPY(&se_mem[MAIN_BG_SBB], background_gfxMap);
|
||||
|
||||
tte_erase_rect_wrapper(HAND_SIZE_RECT_PLAYING);
|
||||
|
||||
if (current_blind == BIG_BLIND) // Change text and palette depending on blind type
|
||||
{
|
||||
main_bg_se_copy_rect(BIG_BLIND_TITLE_SRC_RECT, TOP_LEFT_BLIND_TITLE_POINT);
|
||||
@@ -469,7 +468,7 @@ void change_background(int id)
|
||||
background = BG_ID_CARD_PLAYING;
|
||||
}
|
||||
|
||||
REG_WIN0V = (REG_WIN0V << 8) | 0xA0;
|
||||
REG_WIN0V = (REG_WIN0V << 8) | 0xA0; // Set window 0 bottom to 160
|
||||
|
||||
for (int i = 0; i <= 2; i++)
|
||||
{
|
||||
@@ -480,7 +479,7 @@ void change_background(int id)
|
||||
}
|
||||
else if (id == BG_ID_ROUND_END)
|
||||
{
|
||||
if (background != BG_ID_CARD_SELECTING || background != BG_ID_CARD_PLAYING)
|
||||
if (background != BG_ID_CARD_SELECTING && background != BG_ID_CARD_PLAYING)
|
||||
{
|
||||
change_background(BG_ID_CARD_SELECTING);
|
||||
background = BG_ID_ROUND_END;
|
||||
@@ -638,15 +637,31 @@ void set_temp_score(int value)
|
||||
|
||||
void set_score(int value)
|
||||
{
|
||||
if (value == 0) // Clear if 0
|
||||
// Clear the existing text before redrawing
|
||||
tte_erase_rect_wrapper(SCORE_RECT);
|
||||
|
||||
char score_suffix = ' ';
|
||||
int display_value = value;
|
||||
|
||||
if(value >= 10000)
|
||||
{
|
||||
Rect rect = SCORE_RECT;
|
||||
rect.left += 1;
|
||||
tte_erase_rect_wrapper(rect);
|
||||
score_suffix = 'k';
|
||||
display_value = value / 1000; // 12,986 = 12k
|
||||
}
|
||||
|
||||
int x_offset = 32;
|
||||
tte_printf("#{P:%d,48; cx:0xF000}%d", x_offset, value);
|
||||
|
||||
// Calculate text width: digits + suffix character (if 'k')
|
||||
int num_digits = get_digits(display_value);
|
||||
int text_width = num_digits * TILE_SIZE;
|
||||
if(score_suffix == 'k')
|
||||
{
|
||||
text_width += TILE_SIZE; // Add width for 'k' suffix
|
||||
}
|
||||
|
||||
// Calculate center position within SCORE_RECT
|
||||
int rect_width = SCORE_RECT.right - SCORE_RECT.left;
|
||||
int x_offset = SCORE_RECT.left + (rect_width - text_width) / 2;
|
||||
|
||||
tte_printf("#{P:%d,48; cx:0xF000}%d%c", x_offset, display_value, score_suffix);
|
||||
}
|
||||
|
||||
void set_money(int value)
|
||||
@@ -806,7 +821,7 @@ void card_draw()
|
||||
void hand_set_focus(int index)
|
||||
{
|
||||
if (index < 0 || index > hand_top || hand_state != HAND_SELECT) return;
|
||||
card_focused = index;
|
||||
selection_x = index;
|
||||
|
||||
mm_sound_effect sfx_focus = {{SFX_CARD_FOCUS}, 1024 + rand() % 512, 0, 255, 128,};
|
||||
mmEffectEx(&sfx_focus);
|
||||
@@ -814,11 +829,11 @@ void hand_set_focus(int index)
|
||||
|
||||
void hand_select()
|
||||
{
|
||||
if (hand_state != HAND_SELECT || hand[card_focused] == NULL) return;
|
||||
if (hand_state != HAND_SELECT || hand[selection_x] == NULL) return;
|
||||
|
||||
if (hand[card_focused]->selected)
|
||||
if (hand[selection_x]->selected)
|
||||
{
|
||||
hand[card_focused]->selected = false;
|
||||
hand[selection_x]->selected = false;
|
||||
hand_selections--;
|
||||
|
||||
mm_sound_effect sfx_select = {{SFX_CARD_SELECT}, 1024, 0, 255, 128,};
|
||||
@@ -826,7 +841,7 @@ void hand_select()
|
||||
}
|
||||
else if (hand_selections < MAX_SELECTION_SIZE)
|
||||
{
|
||||
hand[card_focused]->selected = true;
|
||||
hand[selection_x]->selected = true;
|
||||
hand_selections++;
|
||||
|
||||
mm_sound_effect sfx_deselect = {{SFX_CARD_DESELECT}, 1024, 0, 255, 128,};
|
||||
@@ -924,9 +939,27 @@ void game_round_init()
|
||||
|
||||
Rect blind_req_text_rect = BLIND_REQ_TEXT_RECT;
|
||||
int blind_requirement = blind_get_requirement(current_blind, ante);
|
||||
|
||||
char score_suffix = ' ';
|
||||
if(blind_requirement >= 10000)
|
||||
{
|
||||
// clear existing text
|
||||
tte_erase_rect_wrapper(blind_req_text_rect);
|
||||
|
||||
score_suffix = 'k';
|
||||
blind_requirement /= 1000; // 11,000 = 11k
|
||||
}
|
||||
|
||||
// Update text rect for right alignment AFTER shortening the number
|
||||
update_text_rect_to_right_align_num(&blind_req_text_rect, blind_requirement, OVERFLOW_RIGHT);
|
||||
|
||||
tte_printf("#{P:%d,%d; cx:0xE000}%d", blind_req_text_rect.left, blind_req_text_rect.top, blind_requirement); // Blind requirement
|
||||
// If we added a suffix, adjust position to account for the extra character
|
||||
if(score_suffix == 'k')
|
||||
{
|
||||
blind_req_text_rect.left -= TILE_SIZE; // Move left by one character width to make room for 'k'
|
||||
}
|
||||
|
||||
tte_printf("#{P:%d,%d; cx:0xE000}%d%c", blind_req_text_rect.left, blind_req_text_rect.top, blind_requirement, score_suffix); // Blind requirement
|
||||
tte_printf("#{P:%d,%d; cx:0xC000}$%d", BLIND_REWARD_RECT.left, BLIND_REWARD_RECT.top, blind_get_reward(current_blind)); // Blind reward
|
||||
|
||||
deck_shuffle(); // Shuffle the deck at the start of the round
|
||||
@@ -1007,80 +1040,81 @@ static void game_playing_process_input_and_state()
|
||||
{
|
||||
if (hand_state == HAND_SELECT)
|
||||
{
|
||||
static bool discard_button_highlighted = false; // true = play button highlighted, false = discard button highlighted
|
||||
|
||||
if (key_hit(KEY_LEFT))
|
||||
{
|
||||
if (selection_y == 0)
|
||||
{
|
||||
hand_set_focus(card_focused + 1); // The reason why this adds 1 is because the hand is drawn from right to left. There is no particular reason for this, it's just how I did it.
|
||||
hand_set_focus(selection_x + 1); // The reason why this adds 1 is because the hand is drawn from right to left. There is no particular reason for this, it's just how I did it.
|
||||
}
|
||||
else
|
||||
{
|
||||
card_focused = -2; // Play button
|
||||
discard_button_highlighted = false; // Play button
|
||||
}
|
||||
}
|
||||
else if (key_hit(KEY_RIGHT))
|
||||
{
|
||||
if (selection_y == 0)
|
||||
{
|
||||
hand_set_focus(card_focused - 1);
|
||||
hand_set_focus(selection_x - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
card_focused = -3; // Discard button
|
||||
discard_button_highlighted = true; // Discard button
|
||||
}
|
||||
}
|
||||
else if (key_hit(KEY_UP) && selection_y != 0)
|
||||
{
|
||||
selection_y = 0;
|
||||
card_focused = previous_card_focused;
|
||||
}
|
||||
else if (key_hit(KEY_DOWN) && selection_y != 1)
|
||||
{
|
||||
selection_y = 1;
|
||||
previous_card_focused = card_focused;
|
||||
|
||||
if (card_focused > hand_top / 2)
|
||||
if (selection_x > hand_top / 2)
|
||||
{
|
||||
card_focused = -2; // Play button
|
||||
discard_button_highlighted = false; // Play button
|
||||
}
|
||||
else
|
||||
{
|
||||
card_focused = -3; // Discard button
|
||||
discard_button_highlighted = true; // Discard button
|
||||
}
|
||||
}
|
||||
|
||||
if (card_focused == -2) // Play button logic
|
||||
if (selection_y == 1) // On row of play/discard buttons
|
||||
{
|
||||
memset16(&pal_bg_mem[1], 0xFFFF, 1);
|
||||
memcpy16(&pal_bg_mem[9], &pal_bg_mem[12], 1);
|
||||
|
||||
if (key_hit(SELECT_CARD) && hands > 0 && hand_play())
|
||||
if (discard_button_highlighted == false) // Play button logic
|
||||
{
|
||||
hand_state = HAND_PLAY;
|
||||
card_focused = 0;
|
||||
selection_y = 0;
|
||||
previous_card_focused = 0;
|
||||
set_hands(--hands);
|
||||
memset16(&pal_bg_mem[1], 0xFFFF, 1);
|
||||
memcpy16(&pal_bg_mem[9], &pal_bg_mem[12], 1);
|
||||
|
||||
if (key_hit(SELECT_CARD) && hands > 0 && hand_play())
|
||||
{
|
||||
hand_state = HAND_PLAY;
|
||||
selection_x = 0;
|
||||
selection_y = 0;
|
||||
set_hands(--hands);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (card_focused == -3) // Discard button logic
|
||||
{
|
||||
memcpy16(&pal_bg_mem[1], &pal_bg_mem[7], 1);
|
||||
memset16(&pal_bg_mem[9], 0xFFFF, 1);
|
||||
|
||||
if (key_hit(SELECT_CARD) && discards > 0 && hand_discard())
|
||||
else // Discard button logic
|
||||
{
|
||||
hand_state = HAND_DISCARD;
|
||||
card_focused = 0;
|
||||
selection_y = 0;
|
||||
previous_card_focused = 0;
|
||||
set_hands(--discards);
|
||||
set_hand();
|
||||
tte_printf("#{P:%d,%d; cx:0xE000}%d", DISCARDS_TEXT_RECT.left, DISCARDS_TEXT_RECT.top, discards);
|
||||
memcpy16(&pal_bg_mem[1], &pal_bg_mem[7], 1);
|
||||
memset16(&pal_bg_mem[9], 0xFFFF, 1);
|
||||
|
||||
if (key_hit(SELECT_CARD) && discards > 0 && hand_discard())
|
||||
{
|
||||
hand_state = HAND_DISCARD;
|
||||
selection_x = 0;
|
||||
selection_y = 0;
|
||||
set_hands(--discards);
|
||||
set_hand();
|
||||
tte_printf("#{P:%d,%d; cx:0xE000}%d", DISCARDS_TEXT_RECT.left, DISCARDS_TEXT_RECT.top, discards);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (card_focused >= 0)
|
||||
if (selection_y == 0) // On row of cards
|
||||
{
|
||||
memcpy16(&pal_bg_mem[1], &pal_bg_mem[7], 1); // Play button highlight color
|
||||
memcpy16(&pal_bg_mem[9], &pal_bg_mem[12], 1); // Discard button highlight color
|
||||
@@ -1229,20 +1263,22 @@ static void cards_in_hand_update_loop(bool* discarded_card, int* played_selectio
|
||||
hand_x = hand_x + (int2fx(i) - int2fx(hand_top) / 2) * -spacing_lut[hand_top];
|
||||
break;
|
||||
case HAND_SELECT:
|
||||
if (i == card_focused && !hand[i]->selected)
|
||||
bool is_focused = (i == selection_x && selection_y == 0);
|
||||
|
||||
if (is_focused && !hand[i]->selected)
|
||||
{
|
||||
hand_y -= int2fx(10);
|
||||
}
|
||||
else if (i != card_focused && hand[i]->selected)
|
||||
else if (!is_focused && hand[i]->selected)
|
||||
{
|
||||
hand_y -= int2fx(15);
|
||||
}
|
||||
else if (i == card_focused && hand[i]->selected)
|
||||
else if (is_focused && hand[i]->selected)
|
||||
{
|
||||
hand_y -= int2fx(20);
|
||||
}
|
||||
|
||||
if (i != card_focused && hand[i]->y > hand_y)
|
||||
if (i != selection_x && hand[i]->y > hand_y)
|
||||
{
|
||||
hand[i]->y = hand_y;
|
||||
hand[i]->vy = 0;
|
||||
@@ -1547,82 +1583,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->proccessed == 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->proccessed = 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1630,7 +1654,7 @@ static void played_cards_update_loop(bool* discarded_card, int* played_selection
|
||||
{
|
||||
if (jokers[k] != NULL)
|
||||
{
|
||||
jokers[k]->joker->proccessed = false; // Reset the joker's processed state for the next round
|
||||
jokers[k]->joker->processed = false; // Reset the joker's processed state for the next round
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1803,7 +1827,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;
|
||||
@@ -1816,7 +1842,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));
|
||||
@@ -1871,8 +1897,6 @@ void game_round_end_cleanup()
|
||||
|
||||
void game_round_end()
|
||||
{
|
||||
static int state = 0;
|
||||
|
||||
static int blind_reward = 0;
|
||||
static int hand_reward = 0;
|
||||
static int interest_reward = 0;
|
||||
@@ -2127,9 +2151,6 @@ void game_round_end()
|
||||
void game_shop()
|
||||
{
|
||||
change_background(BG_ID_SHOP);
|
||||
|
||||
// TODO: Later move these static variables somewhere else so they can be reused for each game state
|
||||
static int state = 0;
|
||||
|
||||
static JokerObject *shop_jokers[MAX_SHOP_JOKERS] = {NULL};
|
||||
|
||||
@@ -2144,10 +2165,6 @@ void game_shop()
|
||||
const int reroll_base_cost = 5; // Base cost for rerolling the shop items
|
||||
static int reroll_cost = reroll_base_cost;
|
||||
|
||||
// these are for controlling the shop menu
|
||||
static bool top_row = true;
|
||||
static ushort selection_x = 0;
|
||||
|
||||
// temp variables for future implementation
|
||||
const ushort max_items_top = MAX_SHOP_JOKERS;
|
||||
const ushort max_items_bottom = 0;
|
||||
@@ -2221,7 +2238,7 @@ void game_shop()
|
||||
// Shop input logic
|
||||
if (key_hit(KEY_UP))
|
||||
{
|
||||
top_row = true;
|
||||
selection_y = 0;
|
||||
|
||||
if (selection_x > max_items_top)
|
||||
{
|
||||
@@ -2230,7 +2247,7 @@ void game_shop()
|
||||
}
|
||||
else if (key_hit(KEY_DOWN))
|
||||
{
|
||||
top_row = false;
|
||||
selection_y = 1;
|
||||
|
||||
if (selection_x > max_items_bottom)
|
||||
{
|
||||
@@ -2246,11 +2263,11 @@ void game_shop()
|
||||
}
|
||||
else if (key_hit(KEY_RIGHT))
|
||||
{
|
||||
if (top_row && selection_x < max_items_top)
|
||||
if (selection_y == 0 && selection_x < max_items_top)
|
||||
{
|
||||
selection_x++;
|
||||
}
|
||||
else if (!top_row && selection_x < max_items_bottom)
|
||||
else if (selection_y == 1 && selection_x < max_items_bottom)
|
||||
{
|
||||
selection_x++;
|
||||
}
|
||||
@@ -2260,7 +2277,7 @@ void game_shop()
|
||||
memcpy16(&pal_bg_mem[5], &pal_bg_mem[16], 1);
|
||||
|
||||
// Shop selection logic
|
||||
if (selection_x == 0 && top_row)
|
||||
if (selection_x == 0 && selection_y == 0)
|
||||
{
|
||||
memset16(&pal_bg_mem[5], 0xFFFF, 1);
|
||||
|
||||
@@ -2278,7 +2295,7 @@ void game_shop()
|
||||
// And I don't care enough to fix it right now.
|
||||
}
|
||||
}
|
||||
else if (selection_x == 0 && !top_row)
|
||||
else if (selection_x == 0 && selection_y == 1)
|
||||
{
|
||||
memset16(&pal_bg_mem[7], 0xFFFF, 1);
|
||||
|
||||
@@ -2298,7 +2315,7 @@ void game_shop()
|
||||
{
|
||||
if (shop_jokers[i] != NULL)
|
||||
{
|
||||
if (i == selection_x - 1 && top_row)
|
||||
if (i == selection_x - 1 && selection_y == 0)
|
||||
{
|
||||
shop_jokers[i]->ty = int2fx(61);
|
||||
|
||||
@@ -2376,7 +2393,7 @@ void game_shop()
|
||||
reroll_cost = reroll_base_cost;
|
||||
|
||||
selection_x = 0; // Reset the selection
|
||||
top_row = true; // Reset the top row selection
|
||||
selection_y = 0; // Reset the selection
|
||||
|
||||
for (int i = 0; i < MAX_SHOP_JOKERS; i++)
|
||||
{
|
||||
@@ -2392,10 +2409,6 @@ void game_shop()
|
||||
|
||||
void game_blind_select()
|
||||
{
|
||||
static int state = 0;
|
||||
|
||||
static bool top_row = true; // There's only one row in this game state, but this is here for consistency with the shop state if we make these variables global or something
|
||||
|
||||
switch (state) // I'm only using magic numbers here for the sake of simplicity since it's just sequential, but you can replace them with named constants or enums if it makes it clearer
|
||||
{
|
||||
case 0: // Intro sequence (menu coming into frame)
|
||||
@@ -2418,18 +2431,23 @@ void game_blind_select()
|
||||
}
|
||||
case 1: // Blind select input and selection
|
||||
{
|
||||
if (timer == 1 && current_blind == BOSS_BLIND)
|
||||
{
|
||||
selection_y = 0;
|
||||
}
|
||||
|
||||
// Blind select input logic
|
||||
if (key_hit(KEY_UP))
|
||||
{
|
||||
top_row = true;
|
||||
selection_y = 0;
|
||||
}
|
||||
else if (key_hit(KEY_DOWN))
|
||||
else if (key_hit(KEY_DOWN) && current_blind != BOSS_BLIND)
|
||||
{
|
||||
top_row = false;
|
||||
selection_y = 1;
|
||||
}
|
||||
else if (key_hit(SELECT_CARD))
|
||||
{
|
||||
if (top_row) // Blind selected
|
||||
if (selection_y == 0) // Blind selected
|
||||
{
|
||||
state++;
|
||||
timer = 0;
|
||||
@@ -2457,7 +2475,7 @@ void game_blind_select()
|
||||
}
|
||||
}
|
||||
|
||||
if (top_row)
|
||||
if (selection_y == 0)
|
||||
{
|
||||
memset16(&pal_bg_mem[18], 0xFFFF, 1);
|
||||
memcpy16(&pal_bg_mem[10], &pal_bg_mem[5], 1);
|
||||
@@ -2546,7 +2564,7 @@ void game_blind_select()
|
||||
default:
|
||||
state = 0;
|
||||
timer = 0;
|
||||
top_row = true;
|
||||
selection_y = 0;
|
||||
background = UNDEFINED;
|
||||
game_set_state(GAME_PLAYING);
|
||||
break;
|
||||
|
||||
@@ -26,7 +26,7 @@ static void clip_se_rect_to_screenblock(Rect* rect)
|
||||
|
||||
u16 main_bg_se_get_tile(BG_POINT pos)
|
||||
{
|
||||
return se_mem[MAIN_BG_SBB][pos.x + SE_ROW_LEN * pos.y];
|
||||
return se_mat[MAIN_BG_SBB][pos.y][pos.x];
|
||||
}
|
||||
|
||||
// Clips a rect of screenblock entries to be within one step of
|
||||
@@ -55,7 +55,7 @@ void main_bg_se_clear_rect(Rect se_rect)
|
||||
|
||||
for (int y = se_rect.top; y < se_rect.bottom; y++)
|
||||
{
|
||||
memset16(&(se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * y]), 0x0000, rect_width(&se_rect));
|
||||
memset16(&(se_mat[MAIN_BG_SBB][y][se_rect.left]), 0x0000, rect_width(&se_rect));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,14 +77,14 @@ static void main_bg_se_copy_or_move_rect_1_tile_vert(Rect se_rect, int direction
|
||||
|
||||
for (int y = start; y != end - direction; y -= direction)
|
||||
{
|
||||
memcpy16(&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * (y + direction)],
|
||||
&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * y],
|
||||
memcpy16(&(se_mat[MAIN_BG_SBB][y + direction][se_rect.left]),
|
||||
&se_mat[MAIN_BG_SBB][y][se_rect.left],
|
||||
rect_width(&se_rect));
|
||||
}
|
||||
|
||||
if (move)
|
||||
{
|
||||
memset16(&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * (end)], 0x0000, rect_width(&se_rect));
|
||||
memset16(&se_mat[MAIN_BG_SBB][end][se_rect.left], 0x0000, rect_width(&se_rect));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ void main_bg_se_copy_rect(Rect se_rect, BG_POINT pos)
|
||||
|
||||
for (int sy = 0; sy < height; sy++)
|
||||
{
|
||||
memcpy16(&se_mem[MAIN_BG_SBB][pos.x + SE_ROW_LEN * (pos.y + sy)],
|
||||
memcpy16(&se_mat[MAIN_BG_SBB][pos.y + sy][pos.x],
|
||||
&tile_map[sy][0],
|
||||
width);
|
||||
}
|
||||
@@ -143,7 +143,7 @@ void main_bg_se_copy_tile_to_rect(u16 tile, Rect se_rect)
|
||||
|
||||
for (int sy = 0; sy < height; sy++)
|
||||
{
|
||||
memset16(&se_mem[MAIN_BG_SBB][se_rect.left + SE_ROW_LEN * (se_rect.top + sy)], tile, width);
|
||||
memset16(&se_mat[MAIN_BG_SBB][se_rect.top + sy][se_rect.left], tile, width);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,11 +155,11 @@ void tte_erase_rect_wrapper(Rect rect)
|
||||
void update_text_rect_to_right_align_num(Rect* rect, int num, int overflow_direction)
|
||||
{
|
||||
int num_digits = get_digits(num);
|
||||
if (overflow_direction == OVERFLOW_RIGHT)
|
||||
if (overflow_direction == OVERFLOW_LEFT)
|
||||
{
|
||||
rect->left = max(0, rect->right - num_digits * TILE_SIZE);
|
||||
}
|
||||
else if (overflow_direction == OVERFLOW_LEFT)
|
||||
else if (overflow_direction == OVERFLOW_RIGHT)
|
||||
{
|
||||
int num_fitting_digits = rect_width(rect) / TILE_SIZE;
|
||||
if (num_digits < num_fitting_digits)
|
||||
|
||||
+57
-6
@@ -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
|
||||
{
|
||||
@@ -46,7 +48,7 @@ Joker *joker_new(u8 id)
|
||||
joker->modifier = BASE_EDITION; // TODO: Make this random later
|
||||
joker->value = joker_data_lut[id][1] + edition_price_lut[joker->modifier]; // Base value + edition price
|
||||
joker->rarity = joker_data_lut[id][0];
|
||||
joker->proccessed = false;
|
||||
joker->processed = false;
|
||||
|
||||
return joker;
|
||||
}
|
||||
@@ -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 != NULL && scored_card->suit == DIAMONDS) // If the scored card is a diamond
|
||||
{
|
||||
effect.mult = 3;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -140,8 +146,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