[Feature] Implement Joker descriptions in the Shop when holding B (#530)
* WIP * WIP * WIP * WIP * Tags are bugged but it's looking good * Centering is bugged, almost there * WIP * Fixed centeriiiing, yaaaay * good progress * add proper '\n' support * WIP descriptions * All descriptions are there ^^ * missing 9-patch for pretty display * WIP * fix rebase issues * Fix minor Run Setup screen issues * Almost done, only one fix to go * Aaaalmooost doooneeeee * make desc frame size adaptative * add rarity color and text * final cleanup * clang format * clang format * clang format * clang format * clang format * Fix Joker update loop index * Fix const and Bull description * Fix unwanted button SFX * fix tte colors * Add misprint description * Fix justified line length computation * Add safeguards to tag parsing loop * clang format * Fix Ante bugged display at boss blind end * Tweak suit colors * Final fixes * Simplified the way we print descriptions * simplify further * get rid of weird macro * Fix Onwed joker price when holding A after showing its description --------- Co-authored-by: MathisMartin31 <mathis.martin31@gmail.com>
@@ -1 +1 @@
|
||||
-gB8 -mR8 -mLs -mRtf -pe 160
|
||||
-gB8 -mR8 -mLs -mRtf -pe 64
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.8 KiB |
@@ -1 +1 @@
|
||||
-gB8 -mR8 -mLs -mRtf -pe 160
|
||||
-gB8 -mR8 -mLs -mRtf -pe 64
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
@@ -1 +1 @@
|
||||
-gB8 -mR8 -mLs -mRtf -pn 160
|
||||
-gB8 -mR8 -mLs -mRtf -pn 64
|
||||
|
||||
@@ -1 +1 @@
|
||||
-gB8 -mR8 -mLs -mRtf -pe 160
|
||||
-gB8 -mR8 -mLs -mRtf -pe 64
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1 @@
|
||||
-gB4 -g! -m! -pn 16
|
||||
|
After Width: | Height: | Size: 566 B |
@@ -26,7 +26,7 @@
|
||||
* @def AFFINE_BG_PB
|
||||
* @brief The starting index of the background palette.
|
||||
*/
|
||||
#define AFFINE_BG_PB (PAL_ROW_LEN * 10)
|
||||
#define AFFINE_BG_PB (PAL_ROW_LEN * 15)
|
||||
|
||||
/**
|
||||
* @brief An ID to specify background rendering types.
|
||||
|
||||
@@ -79,6 +79,7 @@ void game_reset(void);
|
||||
|
||||
void game_update(void);
|
||||
void game_change_state(enum GameState new_game_state);
|
||||
enum GameState game_get_state(void);
|
||||
|
||||
CardObject** get_played_array(void);
|
||||
int get_played_top(void);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#ifndef GAME_SHOP_H
|
||||
#define GAME_SHOP_H
|
||||
|
||||
#include "joker.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
@@ -14,6 +16,13 @@
|
||||
*/
|
||||
void game_shop_reset(void);
|
||||
|
||||
/**
|
||||
* @brief Get a pointer to the Card we are currently showing the description of.
|
||||
*
|
||||
* @return JokerObject*
|
||||
*/
|
||||
JokerObject* game_shop_get_description_card(void);
|
||||
|
||||
/**
|
||||
* @brief Set whether a Joker can appear in the shop.
|
||||
*
|
||||
|
||||
@@ -63,20 +63,32 @@
|
||||
/** @def TTE_BIT_ON_CLR_IDX */
|
||||
#define TTE_BIT_ON_CLR_IDX TTE_BIT_UNPACK_OFFSET + 1
|
||||
|
||||
/** @def TTE_GREEN_PB */
|
||||
#define TTE_GREEN_PB 6 // 0x6
|
||||
|
||||
/** @def TTE_PURPLE_PB */
|
||||
#define TTE_PURPLE_PB 7 // 0x7
|
||||
|
||||
/** @def TTE_DARK_GREEN_PB */
|
||||
#define TTE_DARK_GREEN_PB 8 // 0x8
|
||||
|
||||
/** @def TTE_DARK_BLUE_PB */
|
||||
#define TTE_DARK_BLUE_PB 9 // 0x9
|
||||
|
||||
/** @def TTE_BLACK_PB */
|
||||
#define TTE_BLACK_PB 0 // 0x0
|
||||
#define TTE_BLACK_PB 10 // 0xA
|
||||
|
||||
/** @def TTE_YELLOW_PB */
|
||||
#define TTE_YELLOW_PB 12 // 0xC
|
||||
#define TTE_YELLOW_PB 11 // 0xB
|
||||
|
||||
/** @def TTE_BLUE_PB */
|
||||
#define TTE_BLUE_PB 13 // 0xD
|
||||
#define TTE_BLUE_PB 12 // 0xC
|
||||
|
||||
/** @def TTE_RED_PB */
|
||||
#define TTE_RED_PB 14 // 0xE
|
||||
#define TTE_RED_PB 13 // 0xD
|
||||
|
||||
/** @def TTE_WHITE_PB */
|
||||
#define TTE_WHITE_PB 15 // 0xF
|
||||
#define TTE_WHITE_PB 14 // 0xE
|
||||
|
||||
/** @def TTE_SPECIAL_PB_MULT_OFFSET */
|
||||
#define TTE_SPECIAL_PB_MULT_OFFSET 0x1000
|
||||
@@ -90,12 +102,74 @@
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name TTE Text formatting Tags
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @def TTE_GREEN_TAG */
|
||||
#define TTE_GREEN_TAG "#{cx:0x6000}"
|
||||
|
||||
/** @def TTE_PURPLE_TAG */
|
||||
#define TTE_PURPLE_TAG "#{cx:0x7000}"
|
||||
|
||||
/** @def TTE_GREEN_TAG */
|
||||
#define TTE_DARK_GREEN_TAG "#{cx:0x8000}"
|
||||
|
||||
/** @def TTE_PURPLE_TAG */
|
||||
#define TTE_DARK_BLUE_TAG "#{cx:0x9000}"
|
||||
|
||||
/** @def TTE_BLACK_TAG */
|
||||
#define TTE_BLACK_TAG "#{cx:0xA000}"
|
||||
|
||||
/** @def TTE_YELLOW_TAG */
|
||||
#define TTE_YELLOW_TAG "#{cx:0xB000}"
|
||||
|
||||
/** @def TTE_BLUE_TAG */
|
||||
#define TTE_BLUE_TAG "#{cx:0xC000}"
|
||||
|
||||
/** @def TTE_RED_TAG */
|
||||
#define TTE_RED_TAG "#{cx:0xD000}"
|
||||
|
||||
/** @def TTE_WHITE_TAG */
|
||||
#define TTE_WHITE_TAG "#{cx:0xE000}"
|
||||
|
||||
/** @def TTE_DIAMOND_TAG */
|
||||
#define TTE_DIAMOND_TAG TTE_YELLOW_TAG "Diamond "
|
||||
|
||||
/** @def TTE_HEART_TAG */
|
||||
#define TTE_HEART_TAG TTE_RED_TAG "Hearts "
|
||||
|
||||
/** @def TTE_SPADE_TAG */
|
||||
#define TTE_SPADE_TAG TTE_DARK_BLUE_TAG "Spade "
|
||||
|
||||
/** @def TTE_CLUB_TAG */
|
||||
#define TTE_CLUB_TAG TTE_DARK_GREEN_TAG "Club "
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Text colors
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @def TEXT_CLR_GREEN */
|
||||
#define TEXT_CLR_GREEN RGB15(10, 27, 16)
|
||||
|
||||
/** @def TEXT_CLR_PURPLE */
|
||||
#define TEXT_CLR_PURPLE RGB15(25, 15, 31)
|
||||
|
||||
/** @def TEXT_CLR_DARK_GREEN */
|
||||
#define TEXT_CLR_DARK_GREEN RGB15(0, 14, 8)
|
||||
|
||||
/** @def TEXT_CLR_DARK_BLUE */
|
||||
#define TEXT_CLR_DARK_BLUE RGB15(10, 5, 15)
|
||||
|
||||
/** @def TEXT_CLR_BLACK */
|
||||
#define TEXT_CLR_BLACK RGB15(3, 5, 5) // ~ 0x1483
|
||||
|
||||
/** @def TEXT_CLR_YELLOW */
|
||||
#define TEXT_CLR_YELLOW RGB15(31, 20, 0) // 0x029F
|
||||
|
||||
@@ -147,6 +221,12 @@ enum OverflowDir
|
||||
OVERFLOW_RIGHT = SCREEN_RIGHT
|
||||
};
|
||||
|
||||
enum TextJustifyFlag
|
||||
{
|
||||
JUSTIFY_LEFT,
|
||||
JUSTIFY_CENTER
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
// When making this, missed that it already exists in tonc_math.h
|
||||
@@ -183,6 +263,19 @@ typedef struct NinePatchRect
|
||||
Rect margins;
|
||||
} NinePatchRect;
|
||||
|
||||
INLINE void tte_colors_setup(void)
|
||||
{
|
||||
pal_bg_bank[TTE_GREEN_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_GREEN;
|
||||
pal_bg_bank[TTE_PURPLE_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_PURPLE;
|
||||
pal_bg_bank[TTE_DARK_GREEN_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_DARK_GREEN;
|
||||
pal_bg_bank[TTE_DARK_BLUE_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_DARK_BLUE;
|
||||
pal_bg_bank[TTE_BLACK_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_BLACK;
|
||||
pal_bg_bank[TTE_YELLOW_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_YELLOW;
|
||||
pal_bg_bank[TTE_BLUE_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_BLUE;
|
||||
pal_bg_bank[TTE_RED_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_RED;
|
||||
pal_bg_bank[TTE_WHITE_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_WHITE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the width of a rectangle
|
||||
*
|
||||
@@ -422,4 +515,36 @@ void toggle_windows(bool win0, bool win1);
|
||||
*/
|
||||
void reset_top_left_panel_bottom_row(void);
|
||||
|
||||
/**
|
||||
* @brief Justify a text with custom formatting tags according to the given
|
||||
* justification and bias direction tags
|
||||
*
|
||||
* - The raw_text will be divided into Words, separated by 1 space, and 1 space only.
|
||||
* - Each Word can have one or more formatting `{TAGS}` attached to it, and they MUST be right
|
||||
* next to each other. It might not apply correctly otherwise if the line wraps.
|
||||
* - `{TAGS}` must be one of TTE_BLACK_TAG, TTE_YELLOW_TAG, etc.
|
||||
*
|
||||
* @param raw_text The unformatted text. The '\n' character and custom formatting `{TAGS}` will
|
||||
* not count towards the computed line widths, as they won't appear on screen.
|
||||
* @param dst_rect Rectangle the justified text must fit into. Will overflow at the bottom if
|
||||
* text is too long. Size in tiles
|
||||
* @param justify_direction Align the text either to the left or center.
|
||||
* @param bias_direction Used with `JUSTIFY_CENTER` only. Determines if lines that cannot be
|
||||
* centered are to be slightly to the left or to the right.
|
||||
* @param do_print does not actually print anything, only does the calculations to determine
|
||||
* the number of lines taken by the paragraph
|
||||
*
|
||||
* @returns the number of lines the wrapped paragraph takes
|
||||
*
|
||||
* @sa update_text_rect_to_center_str
|
||||
* @sa TTE_BLACK_TAG
|
||||
*/
|
||||
int tte_printf_justified_in_rect(
|
||||
const char* raw_text,
|
||||
Rect dst_rect,
|
||||
enum TextJustifyFlag justify_direction,
|
||||
enum ScreenHorzDir bias_direction,
|
||||
bool do_print
|
||||
);
|
||||
|
||||
#endif // GRAPHIC_UTILS_H
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* @file joker.h
|
||||
*
|
||||
* @brief Functions relative to the handling of Jokers
|
||||
*/
|
||||
#ifndef JOKER_H
|
||||
#define JOKER_H
|
||||
|
||||
@@ -37,6 +42,8 @@
|
||||
#define RARE_JOKER 2
|
||||
#define LEGENDARY_JOKER 3
|
||||
|
||||
#define MAX_RARITIES (LEGENDARY_JOKER + 1)
|
||||
|
||||
// Percent chance to get a joker of each rarity
|
||||
// Note that this deviates slightly from the Balatro wiki to allow legendary
|
||||
// jokers to appear without spectral cards implemented
|
||||
@@ -132,10 +139,16 @@ typedef u32 (*JokerEffectFunc)(
|
||||
JokerEffect** joker_effect
|
||||
);
|
||||
|
||||
typedef int (*JokerDescFunc)(Joker* joker, Rect dest_rect);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char* name;
|
||||
u8 rarity;
|
||||
u8 base_value;
|
||||
bool is_desc_dynamic; // Is the little variable description at the bottom dynamic?
|
||||
// Only used by the Misprint joker for now
|
||||
JokerDescFunc joker_print_desc;
|
||||
JokerEffectFunc joker_effect_func;
|
||||
} JokerInfo;
|
||||
const JokerInfo* get_joker_registry_entry(int joker_id);
|
||||
@@ -156,6 +169,28 @@ u32 joker_get_score_effect(
|
||||
enum JokerEvent joker_event,
|
||||
JokerEffect** joker_effect
|
||||
);
|
||||
|
||||
const char* joker_get_rarity_string(u8 rarity);
|
||||
|
||||
/**
|
||||
* @brief Get Joker rarity panel color.
|
||||
*
|
||||
* The colors are organized in the `card_rarity_pal_gfx.png` file which is organized like this:
|
||||
* - 0 -> transparency
|
||||
* - 1,2 -> Common Joker
|
||||
* - 3,4 -> Uncommon Joker
|
||||
* - 5,6 -> Rare Joker
|
||||
* - 7,8 -> Legendary Joker / Tarot Card
|
||||
* - 9,10 -> Planet Card
|
||||
* - 11,12 -> Spectral Card
|
||||
* - 13,14 -> Voucher
|
||||
*
|
||||
* @param rarity Value of the rarity (Common, Rare...)
|
||||
* @param main_color Whether we want the main or shadow color
|
||||
* @return u16 value of the color, not a pointer
|
||||
*/
|
||||
u16 joker_get_rarity_color(u8 rarity, bool main_color);
|
||||
|
||||
int joker_get_sell_value(const Joker* joker);
|
||||
|
||||
JokerObject* joker_object_new(Joker* joker);
|
||||
|
||||
@@ -18,9 +18,11 @@ static const BG_POINT HELD_JOKERS_POS = {108, 10};
|
||||
// Rects left top right bottom
|
||||
static const Rect TOP_LEFT_PANEL_ANIM_RECT = {0, 0, 8, 4};
|
||||
static const Rect POP_MENU_ANIM_RECT = {9, 7, 24, 31};
|
||||
static const Rect DECK_ANIM_RECT = {25, 14, 28, 23}; // Can be used for the Shop and Blind Select screen
|
||||
static const Rect TOP_LEFT_ITEM_SRC_RECT = {0, 20, 8, 25};
|
||||
static const Rect BLIND_REWARD_RECT = {40, 32, 64, 40};
|
||||
static const Rect BLIND_REQ_TEXT_RECT = {32, 24, 64, 32};
|
||||
static const Rect PLAYING_SCREEN_RECT = {72, 0, 240, 160};
|
||||
static const Rect HAND_SIZE_RECT = {128, 128, 152, 160}; // Seems to include both SELECT and PLAYING
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -376,6 +376,19 @@ static inline Card* discard_pop()
|
||||
return discard_pile[discard_top--];
|
||||
}
|
||||
|
||||
static inline void display_ante(void)
|
||||
{
|
||||
tte_printf(
|
||||
"#{P:%d,%d; cx:0x%X000}%ld#{cx:0x%X000}/%d",
|
||||
ANTE_TEXT_RECT.left,
|
||||
ANTE_TEXT_RECT.top,
|
||||
TTE_YELLOW_PB,
|
||||
g_game_vars.ante,
|
||||
TTE_WHITE_PB,
|
||||
MAX_ANTE
|
||||
);
|
||||
}
|
||||
|
||||
void game_init()
|
||||
{
|
||||
state_machine_remove(&game_sm);
|
||||
@@ -437,15 +450,7 @@ void game_reset()
|
||||
display_discards();
|
||||
display_money();
|
||||
// Ante
|
||||
tte_printf(
|
||||
"#{P:%d,%d; cx:0x%X000}%ld#{cx:0x%X000}/%d",
|
||||
ANTE_TEXT_RECT.left,
|
||||
ANTE_TEXT_RECT.top,
|
||||
TTE_YELLOW_PB,
|
||||
g_game_vars.ante,
|
||||
TTE_WHITE_PB,
|
||||
MAX_ANTE
|
||||
);
|
||||
display_ante();
|
||||
|
||||
affine_background_load_palette(affine_background_gfxPal);
|
||||
}
|
||||
@@ -490,8 +495,10 @@ static inline void held_jokers_update_loop(void)
|
||||
int i = 0;
|
||||
while ((joker = list_itr_next(&itr)))
|
||||
{
|
||||
joker->sprite_object->tx = hand_x - int2fx(spacing_lut[jokers_top][i++]);
|
||||
|
||||
// Let the Shop handle the position of this Joker
|
||||
if (joker != game_shop_get_description_card())
|
||||
joker->sprite_object->tx = hand_x - int2fx(spacing_lut[jokers_top][i]);
|
||||
i++;
|
||||
joker_object_update(joker);
|
||||
}
|
||||
}
|
||||
@@ -558,6 +565,11 @@ void game_change_state(enum GameState new_game_state)
|
||||
state_machine_change_state(&game_sm, new_game_state);
|
||||
}
|
||||
|
||||
enum GameState game_get_state(void)
|
||||
{
|
||||
return game_sm.state;
|
||||
}
|
||||
|
||||
CardObject** get_played_array(void)
|
||||
{
|
||||
return played;
|
||||
@@ -761,17 +773,6 @@ void display_mult(void)
|
||||
check_flaming_score();
|
||||
}
|
||||
|
||||
static inline void display_ante(int value)
|
||||
{
|
||||
tte_printf(
|
||||
"#{P:%d,%d; cx:0xC000}%d#{cx:0xF000}/%d",
|
||||
ANTE_TEXT_RECT.left,
|
||||
ANTE_TEXT_RECT.top,
|
||||
value,
|
||||
MAX_ANTE
|
||||
);
|
||||
}
|
||||
|
||||
// Returns true if the card is *considered* a face card
|
||||
bool card_is_face(Card* card)
|
||||
{
|
||||
@@ -972,9 +973,10 @@ void display_round(void)
|
||||
void display_hands(void)
|
||||
{
|
||||
tte_printf(
|
||||
"#{P:%d,%d; cx:0xD000}%ld",
|
||||
"#{P:%d,%d; cx:0x%X000}%ld",
|
||||
HANDS_TEXT_RECT.left,
|
||||
HANDS_TEXT_RECT.top,
|
||||
TTE_BLUE_PB,
|
||||
g_game_vars.hands
|
||||
);
|
||||
}
|
||||
@@ -982,9 +984,10 @@ void display_hands(void)
|
||||
void display_discards(void)
|
||||
{
|
||||
tte_printf(
|
||||
"#{P:%d,%d; cx:0xE000}%ld",
|
||||
"#{P:%d,%d; cx:0x%X000}%ld",
|
||||
DISCARDS_TEXT_RECT.left,
|
||||
DISCARDS_TEXT_RECT.top,
|
||||
TTE_RED_PB,
|
||||
g_game_vars.discards
|
||||
);
|
||||
}
|
||||
@@ -1382,7 +1385,8 @@ static inline void game_playing_handle_round_over(void)
|
||||
{
|
||||
if (g_game_vars.ante < MAX_ANTE)
|
||||
{
|
||||
display_ante(++g_game_vars.ante);
|
||||
g_game_vars.ante++;
|
||||
display_ante();
|
||||
|
||||
// mark current boss blind as beaten and allow for reroll
|
||||
set_blind_beaten(g_game_vars.next_boss_blind);
|
||||
@@ -2549,6 +2553,7 @@ static void game_playing_on_update(void)
|
||||
void game_start(void)
|
||||
{
|
||||
affine_background_change_background(AFFINE_BG_GAME);
|
||||
tte_colors_setup();
|
||||
|
||||
g_game_vars.hands = MAX_HANDS;
|
||||
g_game_vars.discards = MAX_DISCARDS;
|
||||
@@ -2587,16 +2592,7 @@ void game_start(void)
|
||||
display_discards(); // Discard
|
||||
|
||||
display_money(); // Set the money display
|
||||
|
||||
tte_printf(
|
||||
"#{P:%d,%d; cx:0x%X000}%ld#{cx:0x%X000}/%d",
|
||||
ANTE_TEXT_RECT.left,
|
||||
ANTE_TEXT_RECT.top,
|
||||
TTE_YELLOW_PB,
|
||||
g_game_vars.ante,
|
||||
TTE_WHITE_PB,
|
||||
MAX_ANTE
|
||||
); // Ante
|
||||
display_ante();
|
||||
|
||||
game_change_state(GAME_STATE_BLIND_SELECT);
|
||||
}
|
||||
|
||||
@@ -768,6 +768,7 @@ static int seed_play_get_row_size(void)
|
||||
*/
|
||||
static void seed_play_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection)
|
||||
{
|
||||
if (key_hit(SELECT_CARD))
|
||||
button_press(&choose_deck_bottom_buttons[selection->x]);
|
||||
}
|
||||
|
||||
@@ -1004,13 +1005,18 @@ static inline Button* choose_seed_get_button_from_sel(const Selection* sel)
|
||||
/**
|
||||
* @brief Handle button imputs in `choose_seed_selection_grid`
|
||||
*
|
||||
* Always register A press, but only B press when we are on a keyboard row
|
||||
*
|
||||
* @param selection_grid pointer to `choose_seed_selection_grid`
|
||||
* @param selection Selected button in `choose_seed_selection_grid`
|
||||
*/
|
||||
static void choose_seed_row_on_key_transit(SelectionGrid* selection_grid, Selection* selection)
|
||||
{
|
||||
if (key_hit(SELECT_CARD) || key_hit(DESELECT_CARDS))
|
||||
if (key_hit(SELECT_CARD) ||
|
||||
(selection->y <= RUN_SETUP_SEED_ROW_KEY3 && key_hit(DESELECT_CARDS)))
|
||||
{
|
||||
button_press(choose_seed_get_button_from_sel(selection));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1133,7 +1139,6 @@ static inline void toggle_seed_enabled(bool enable)
|
||||
*/
|
||||
static void use_seed_on_pressed(void)
|
||||
{
|
||||
if (key_hit(SELECT_CARD))
|
||||
toggle_seed_enabled(!use_seed);
|
||||
}
|
||||
|
||||
@@ -1142,7 +1147,7 @@ static void use_seed_on_pressed(void)
|
||||
*/
|
||||
static void seed_on_pressed(void)
|
||||
{
|
||||
if (key_hit(SELECT_CARD) && use_seed)
|
||||
if (use_seed)
|
||||
state_machine_change_state(&run_setup_sm, RUN_SETUP_SUBSTATE_CHOOSE_SEED);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,13 +24,17 @@
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// Timer defs
|
||||
#define TM_END_GAME_SHOP_INTRO 12
|
||||
#define TM_CREATE_SHOP_ITEMS_WAIT 1
|
||||
#define TM_SHIFT_SHOP_ICON_WAIT 7
|
||||
#define TM_SHOW_CARD_DESC_WAIT 12
|
||||
|
||||
// Pixel sized
|
||||
#define ITEM_SHOP_Y 71
|
||||
#define OWNED_CARDS_HIDE_Y_OFFSET 50
|
||||
|
||||
// Shop
|
||||
#define REROLL_BASE_COST 5 // Base cost for rerolling the shop items
|
||||
@@ -47,6 +51,8 @@
|
||||
#define SHOP_LIGHTS_3_PAL_IDX 17
|
||||
#define SHOP_LIGHTS_4_PAL_IDX 22
|
||||
#define SHOP_BOTTOM_PANEL_BORDER_PAL_IDX 26
|
||||
#define SHOP_DESC_RARITY_MAIN_COLOR_PAL_IDX 27
|
||||
#define SHOP_DESC_RARITY_SHADOW_COLOR_PAL_IDX 28
|
||||
|
||||
#define SHOP_LIGHTS_1_CLR 0xFFFF
|
||||
#define SHOP_LIGHTS_2_CLR 0x32BE
|
||||
@@ -54,13 +60,31 @@
|
||||
#define SHOP_LIGHTS_4_CLR 0x5F9F
|
||||
|
||||
// clang-format off
|
||||
static const Rect SHOP_ICON_FROM_RECT = { 0, 26, 8, 26 };
|
||||
static const BG_POINT SHOP_ICON_TO_POS = { 0, 0 };
|
||||
static const Rect SHOP_PRICES_TEXT_RECT = { 72, 56, 192, 160 };
|
||||
static const Rect SHOP_REROLL_RECT = { 88, 96, UNDEFINED, UNDEFINED };
|
||||
// Positions in tiles
|
||||
static const BG_POINT SHOP_CLEAR_3X3_SRC_POS = { 29, 0};
|
||||
static const Rect SHOP_ICON_FROM_RECT = { 0, 26, 8, 26};
|
||||
static const BG_POINT SHOP_ICON_TO_POS = { 0, 0};
|
||||
static const BG_POINT OWNED_CARDS_PANEL_3X3_SRC_POS = { 29, 21};
|
||||
static const Rect OWNED_JOKERS_PANEL_RECT = { 9, 1, 21, 5};
|
||||
static const Rect OWNED_CONSUMABLES_PANEL_RECT = { 23, 1, 28, 5};
|
||||
static const Rect OWNED_CARDS_PANEL_RECT = { 9, 1, 28, 5};
|
||||
static const Rect CARD_DESC_9_PTCH_TO_RECT = { 9, 6, 28, 18};
|
||||
static const NinePatchRect CARD_DESC_9_PTCH_SRC = {
|
||||
.patch_rect = { 27, 25, 31, 31},
|
||||
.margins = { 2, 3, 2, 3}
|
||||
};
|
||||
static const int CARD_DESC_MAX_TEXT_HEIGHT = CARD_DESC_9_PTCH_TO_RECT.bottom -
|
||||
CARD_DESC_9_PTCH_TO_RECT.top + 1 -
|
||||
CARD_DESC_9_PTCH_SRC.margins.top -
|
||||
CARD_DESC_9_PTCH_SRC.margins.bottom;
|
||||
static const Rect CARD_DESC_TEXT_RECT = { 11, 9, 26, 18};
|
||||
static const Rect CARD_NAME_TEXT_RECT = { 10, 7, 27, 7};
|
||||
|
||||
// Positions in pixels
|
||||
static const BG_POINT SHOP_JOKER_SPRITES_INIT_POS = {120, 160};
|
||||
static const BG_POINT CARD_DESCRIPTION_SPRITE_POS = {135, 9};
|
||||
static const Rect SHOP_PRICES_TEXT_RECT = { 72, 56, 192, 160 };
|
||||
static const Rect SHOP_REROLL_RECT = { 88, 96, UNDEFINED, UNDEFINED };
|
||||
// clang-format on
|
||||
|
||||
static List s_shop_jokers_list = LIST_DEFAULT;
|
||||
@@ -70,17 +94,23 @@ enum GameShopStates
|
||||
{
|
||||
GAME_SHOP_INTRO,
|
||||
GAME_SHOP_ACTIVE,
|
||||
GAME_SHOP_SHOW_CARD_DESC,
|
||||
GAME_SHOP_HIDE_CARD_DESC,
|
||||
GAME_SHOP_EXIT,
|
||||
GAME_SHOP_MAX
|
||||
};
|
||||
|
||||
static void game_shop_intro(void);
|
||||
static void game_shop_process_user_input(void);
|
||||
static void game_shop_show_card_desc(void);
|
||||
static void game_shop_hide_card_desc(void);
|
||||
static void game_shop_outro(void);
|
||||
|
||||
static StateInfo shop_state_actions[] = {
|
||||
static StateInfo shop_state_actions[GAME_SHOP_MAX] = {
|
||||
STATE_INFO_UPDATE_FN_ONLY(game_shop_intro),
|
||||
STATE_INFO_UPDATE_FN_ONLY(game_shop_process_user_input),
|
||||
STATE_INFO_UPDATE_FN_ONLY(game_shop_show_card_desc),
|
||||
STATE_INFO_UPDATE_FN_ONLY(game_shop_hide_card_desc),
|
||||
STATE_INFO_UPDATE_FN_ONLY(game_shop_outro),
|
||||
};
|
||||
|
||||
@@ -139,6 +169,17 @@ static int timer;
|
||||
|
||||
static int reroll_cost = REROLL_BASE_COST;
|
||||
|
||||
// Variables relative to the Card we are showing the description of
|
||||
static JokerObject* description_card = NULL;
|
||||
static FIXED description_card_original_x_pos = UNDEFINED;
|
||||
static FIXED description_card_original_y_pos = UNDEFINED;
|
||||
static List* description_card_original_list = NULL;
|
||||
|
||||
JokerObject* game_shop_get_description_card(void)
|
||||
{
|
||||
return description_card;
|
||||
}
|
||||
|
||||
static inline void reset_shop_jokers(void)
|
||||
{
|
||||
int num_jokers = get_joker_registry_size();
|
||||
@@ -533,9 +574,9 @@ static bool shop_reroll_row_on_selection_changed(
|
||||
* @brief Reroll items up for sale in the Shop.
|
||||
* Reroll cost will go up by a rate that increases by 1 each reroll.
|
||||
*/
|
||||
static inline void game_shop_reroll(int* reroll_cost)
|
||||
static inline void game_shop_reroll(void)
|
||||
{
|
||||
g_game_vars.money -= *reroll_cost;
|
||||
g_game_vars.money -= reroll_cost;
|
||||
display_money(); // Update the money display
|
||||
|
||||
List* shop_jokers_list = &s_shop_jokers_list;
|
||||
@@ -570,13 +611,13 @@ static inline void game_shop_reroll(int* reroll_cost)
|
||||
}
|
||||
}
|
||||
|
||||
(*reroll_cost)++;
|
||||
reroll_cost++;
|
||||
tte_printf(
|
||||
"#{P:%d,%d; cx:0x%X000}$%d",
|
||||
SHOP_REROLL_RECT.left,
|
||||
SHOP_REROLL_RECT.top,
|
||||
TTE_WHITE_PB,
|
||||
*reroll_cost
|
||||
reroll_cost
|
||||
);
|
||||
}
|
||||
|
||||
@@ -606,7 +647,7 @@ static void next_round_on_pressed(void)
|
||||
static void reroll_on_pressed(void)
|
||||
{
|
||||
// TODO: Add money sound effect
|
||||
game_shop_reroll(&reroll_cost);
|
||||
game_shop_reroll();
|
||||
}
|
||||
|
||||
static bool reroll_can_be_pressed(void)
|
||||
@@ -617,16 +658,270 @@ static bool reroll_can_be_pressed(void)
|
||||
/**
|
||||
* @brief Handle user inputs logic in the Shop though a SelectionGrid.
|
||||
*/
|
||||
static void game_shop_process_user_input()
|
||||
static void game_shop_process_user_input(void)
|
||||
{
|
||||
selection_grid_process_input(&shop_selection_grid);
|
||||
|
||||
static JokerObject* tmp_card = NULL;
|
||||
|
||||
// Determine the Joker we would show the description of
|
||||
switch (shop_selection_grid.selection.y)
|
||||
{
|
||||
// Owned Joker
|
||||
case 0:
|
||||
{
|
||||
description_card_original_list = get_jokers_list();
|
||||
tmp_card = list_get_at_idx(get_jokers_list(), shop_selection_grid.selection.x);
|
||||
break;
|
||||
}
|
||||
|
||||
// Jokers for sale
|
||||
case 1:
|
||||
{
|
||||
description_card_original_list = &s_shop_jokers_list;
|
||||
tmp_card = (shop_selection_grid.selection.x > 0)
|
||||
? list_get_at_idx(&s_shop_jokers_list, shop_selection_grid.selection.x - 1)
|
||||
: NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO: handle Consumables and Vouchers when implemented
|
||||
|
||||
default:
|
||||
{
|
||||
description_card_original_list = NULL;
|
||||
tmp_card = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Show description of selected card when pressing B.
|
||||
// Always wait for the card in question to be immobile to avoid accumulating
|
||||
// errors when pressing and releasing B in quick succession.
|
||||
if (tmp_card != NULL && tmp_card->sprite_object->vx == 0 && tmp_card->sprite_object->vy == 0 &&
|
||||
key_held(DESELECT_CARDS))
|
||||
{
|
||||
description_card = tmp_card;
|
||||
description_card_original_x_pos = description_card->sprite_object->x;
|
||||
description_card_original_y_pos = description_card->sprite_object->y;
|
||||
|
||||
timer = TM_ZERO;
|
||||
state_machine_change_state(&shop_sm, GAME_SHOP_SHOW_CARD_DESC);
|
||||
}
|
||||
}
|
||||
|
||||
static void game_shop_show_card_desc(void)
|
||||
{
|
||||
// Anim start
|
||||
if (timer == 1)
|
||||
{
|
||||
// Erase shop text and disable transparency window
|
||||
|
||||
tte_erase_rect_wrapper(PLAYING_SCREEN_RECT);
|
||||
toggle_windows(false, true);
|
||||
|
||||
// Move all other Jokers offscreen
|
||||
|
||||
JokerObject* joker_object = NULL;
|
||||
|
||||
// Owned Jokers
|
||||
ListItr itr = list_itr_create(get_jokers_list());
|
||||
while ((joker_object = list_itr_next(&itr)))
|
||||
{
|
||||
if (joker_object != description_card)
|
||||
joker_object->sprite_object->ty -= int2fx(OWNED_CARDS_HIDE_Y_OFFSET);
|
||||
}
|
||||
|
||||
// Shop Jokers
|
||||
itr = list_itr_create(&s_shop_jokers_list);
|
||||
while ((joker_object = list_itr_next(&itr)))
|
||||
{
|
||||
if (joker_object != description_card)
|
||||
joker_object->sprite_object->ty = int2fx(SHOP_JOKER_SPRITES_INIT_POS.y + TILE_SIZE);
|
||||
}
|
||||
|
||||
// Set description_card new target position
|
||||
|
||||
description_card->sprite_object->tx = int2fx(CARD_DESCRIPTION_SPRITE_POS.x);
|
||||
description_card->sprite_object->ty = int2fx(CARD_DESCRIPTION_SPRITE_POS.y);
|
||||
}
|
||||
|
||||
// First 12 anim frames
|
||||
if (timer <= TM_SHOW_CARD_DESC_WAIT)
|
||||
{
|
||||
// Hide Deck (last 5 frames only)
|
||||
if (TM_SHOW_CARD_DESC_WAIT - timer < 5)
|
||||
main_bg_se_move_rect_1_tile_vert(DECK_ANIM_RECT, SCREEN_DOWN);
|
||||
// Hide shop panel
|
||||
main_bg_se_move_rect_1_tile_vert(POP_MENU_ANIM_RECT, SCREEN_DOWN);
|
||||
// Hide Owned Cards panels
|
||||
main_bg_se_move_rect_1_tile_vert(OWNED_CARDS_PANEL_RECT, SCREEN_UP);
|
||||
}
|
||||
|
||||
// Anim end
|
||||
else if (timer == TM_SHOW_CARD_DESC_WAIT + 1)
|
||||
{
|
||||
// Compute needed space for the description
|
||||
const JokerInfo* info = get_joker_registry_entry(description_card->joker->id);
|
||||
int desc_bottom_offset =
|
||||
CARD_DESC_MAX_TEXT_HEIGHT -
|
||||
info->joker_print_desc(description_card->joker, CARD_DESC_TEXT_RECT);
|
||||
|
||||
// Print Rarity and change color or the panel
|
||||
// Do it before drawing the panel so the color is already set
|
||||
const char* rarity_str = joker_get_rarity_string(info->rarity);
|
||||
tte_printf(
|
||||
TTE_WHITE_TAG "#{P:%d,%d}%*s%s",
|
||||
CARD_DESC_TEXT_RECT.left * TILE_SIZE,
|
||||
(CARD_DESC_TEXT_RECT.bottom - desc_bottom_offset - 1) * TILE_SIZE,
|
||||
(rect_width(&CARD_DESC_TEXT_RECT) - strlen(rarity_str)) / 2,
|
||||
"",
|
||||
rarity_str
|
||||
);
|
||||
pal_bg_mem[SHOP_DESC_RARITY_MAIN_COLOR_PAL_IDX] =
|
||||
joker_get_rarity_color(info->rarity, true);
|
||||
pal_bg_mem[SHOP_DESC_RARITY_SHADOW_COLOR_PAL_IDX] =
|
||||
joker_get_rarity_color(info->rarity, false);
|
||||
|
||||
// Draw description panel
|
||||
Rect actual_dest_rect = CARD_DESC_9_PTCH_TO_RECT;
|
||||
actual_dest_rect.bottom -= desc_bottom_offset;
|
||||
main_bg_se_copy_expand_9_patch(actual_dest_rect, &CARD_DESC_9_PTCH_SRC);
|
||||
|
||||
// Print joker name
|
||||
tte_printf(
|
||||
TTE_WHITE_TAG "#{P:%d,%d}%*s%s",
|
||||
CARD_NAME_TEXT_RECT.left * TILE_SIZE,
|
||||
CARD_NAME_TEXT_RECT.top * TILE_SIZE,
|
||||
(rect_width(&CARD_NAME_TEXT_RECT) - strlen(info->name)) / 2,
|
||||
"",
|
||||
info->name
|
||||
);
|
||||
}
|
||||
|
||||
// Actively wait for the B button to be released, but only if the described card has stopped
|
||||
// moving
|
||||
else if (description_card->sprite_object->vx == 0 && description_card->sprite_object->vy == 0 &&
|
||||
!key_held(DESELECT_CARDS))
|
||||
{
|
||||
timer = TM_ZERO;
|
||||
state_machine_change_state(&shop_sm, GAME_SHOP_HIDE_CARD_DESC);
|
||||
}
|
||||
}
|
||||
|
||||
static void game_shop_hide_card_desc(void)
|
||||
{
|
||||
// just so we don't print the price of an owned Joker too many times
|
||||
static bool owned_joker_price_printed = false;
|
||||
|
||||
// Anim start
|
||||
if (timer == 1)
|
||||
{
|
||||
// Erase shop text and Joker Description frame
|
||||
tte_erase_rect_wrapper(PLAYING_SCREEN_RECT);
|
||||
main_bg_se_copy_expand_3x3_rect(CARD_DESC_9_PTCH_TO_RECT, SHOP_CLEAR_3X3_SRC_POS);
|
||||
|
||||
// Enable transparency window
|
||||
toggle_windows(false, true);
|
||||
|
||||
// Redraw Jokers/Consumables frames
|
||||
main_bg_se_copy_expand_3x3_rect(OWNED_JOKERS_PANEL_RECT, OWNED_CARDS_PANEL_3X3_SRC_POS);
|
||||
main_bg_se_copy_expand_3x3_rect(
|
||||
OWNED_CONSUMABLES_PANEL_RECT,
|
||||
OWNED_CARDS_PANEL_3X3_SRC_POS
|
||||
);
|
||||
|
||||
// Move Jokers back to their positions
|
||||
JokerObject* joker_object = NULL;
|
||||
|
||||
// Owned Jokers
|
||||
ListItr itr = list_itr_create(get_jokers_list());
|
||||
while ((joker_object = list_itr_next(&itr)))
|
||||
{
|
||||
if (joker_object != description_card)
|
||||
joker_object->sprite_object->ty = int2fx(HELD_JOKERS_POS.y);
|
||||
}
|
||||
|
||||
// Shop Jokers
|
||||
itr = list_itr_create(&s_shop_jokers_list);
|
||||
while ((joker_object = list_itr_next(&itr)))
|
||||
{
|
||||
if (joker_object != description_card)
|
||||
joker_object->sprite_object->ty = int2fx(ITEM_SHOP_Y);
|
||||
}
|
||||
|
||||
description_card->sprite_object->tx = description_card_original_x_pos;
|
||||
description_card->sprite_object->ty = description_card_original_y_pos;
|
||||
}
|
||||
|
||||
// First 12 anim frames
|
||||
if (timer <= TM_SHOW_CARD_DESC_WAIT)
|
||||
{
|
||||
// Show Deck (last 5 frames only)
|
||||
if (TM_SHOW_CARD_DESC_WAIT - timer < 5)
|
||||
main_bg_se_move_rect_1_tile_vert(DECK_ANIM_RECT, SCREEN_UP);
|
||||
// Show shop panel
|
||||
main_bg_se_move_rect_1_tile_vert(POP_MENU_ANIM_RECT, SCREEN_UP);
|
||||
}
|
||||
|
||||
// Last anim frame (no need to wait for the Joker to have stopped for this):
|
||||
else if (timer == TM_SHOW_CARD_DESC_WAIT + 1)
|
||||
{
|
||||
// Need to account for the description_card being selected if it came from the shop.
|
||||
if (description_card_original_list == &s_shop_jokers_list)
|
||||
description_card->sprite_object->ty += int2fx(TILE_SIZE);
|
||||
|
||||
// Print price under shop Jokers
|
||||
JokerObject* joker_object = NULL;
|
||||
ListItr itr = list_itr_create(&s_shop_jokers_list);
|
||||
while ((joker_object = list_itr_next(&itr)))
|
||||
{
|
||||
sprite_object_print_price_under(
|
||||
joker_object->sprite_object,
|
||||
joker_object->joker->value
|
||||
);
|
||||
}
|
||||
|
||||
if (description_card_original_list == &s_shop_jokers_list)
|
||||
description_card->sprite_object->ty -= int2fx(TILE_SIZE);
|
||||
|
||||
// Print Reroll prince
|
||||
tte_printf(
|
||||
"#{P:%d,%d; cx:0x%X000}$%d",
|
||||
SHOP_REROLL_RECT.left,
|
||||
SHOP_REROLL_RECT.top,
|
||||
TTE_WHITE_PB,
|
||||
reroll_cost
|
||||
);
|
||||
}
|
||||
|
||||
// Cleanup and change state
|
||||
else if (description_card->sprite_object->vx == 0 && description_card->sprite_object->vy == 0)
|
||||
{
|
||||
owned_joker_price_printed = false;
|
||||
description_card = NULL;
|
||||
timer = TM_ZERO;
|
||||
state_machine_change_state(&shop_sm, GAME_SHOP_ACTIVE);
|
||||
}
|
||||
|
||||
// At any point after the other prices have been printed, and while the card is still moving,
|
||||
// if we are NOT pressing A, print the price under it.
|
||||
else if (!owned_joker_price_printed && !key_held(SELECT_CARD) &&
|
||||
description_card_original_list == get_jokers_list())
|
||||
{
|
||||
owned_joker_price_printed = true;
|
||||
sprite_object_print_price_under(
|
||||
description_card->sprite_object,
|
||||
description_card->joker->value
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Outro sequence substate update.
|
||||
* This makes the menu and shop icon go out of frame.
|
||||
*/
|
||||
static void game_shop_outro()
|
||||
static void game_shop_outro(void)
|
||||
{
|
||||
// Shift the shop panel
|
||||
main_bg_se_move_rect_1_tile_vert(POP_MENU_ANIM_RECT, SCREEN_DOWN);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "layout.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <tonc_core.h>
|
||||
#include <tonc_math.h>
|
||||
@@ -507,3 +508,138 @@ void reset_top_left_panel_bottom_row(void)
|
||||
top_left_panel_bottom_row_pos.y += rect_height(&TOP_LEFT_ITEM_SRC_RECT) - 1;
|
||||
main_bg_se_copy_rect(TOP_LEFT_PANEL_BOTTOM_ROW_RESET_RECT, top_left_panel_bottom_row_pos);
|
||||
}
|
||||
|
||||
// Width of the screen, in nb of tiles
|
||||
#define MAX_LINE_TEXT_LENGTH 30
|
||||
|
||||
int tte_printf_justified_in_rect(
|
||||
const char* raw_text,
|
||||
Rect dst_rect,
|
||||
enum TextJustifyFlag justify_direction,
|
||||
enum ScreenHorzDir bias_direction,
|
||||
bool do_print
|
||||
)
|
||||
{
|
||||
// These are the actual lengths of the line/token, which take the {TAGS} into account
|
||||
|
||||
int raw_text_len = strlen(raw_text);
|
||||
|
||||
int line_start = 0;
|
||||
int token_start = 0;
|
||||
int token_len = 0;
|
||||
|
||||
// These lengths correspond to what will be visible on screen
|
||||
|
||||
int max_line_text_len = rect_width(&dst_rect);
|
||||
|
||||
int line_text_len = 0;
|
||||
int token_text_len = 0;
|
||||
|
||||
int line_x = 0;
|
||||
int line_y = 0;
|
||||
|
||||
// Will exit when there are no more words
|
||||
while (line_start < raw_text_len)
|
||||
{
|
||||
// Need to do everything by hand, as it seems tte_printf does NOT stop at \0
|
||||
token_len = 0;
|
||||
token_text_len = 0;
|
||||
|
||||
// Parse the `raw_text` and
|
||||
while (line_text_len <= max_line_text_len && token_start < raw_text_len)
|
||||
{
|
||||
int current_char = token_start + token_len;
|
||||
|
||||
// Handle tags
|
||||
if (raw_text[current_char] == '#' && (current_char + 1) < raw_text_len &&
|
||||
raw_text[current_char + 1] == '{')
|
||||
{
|
||||
while (current_char < raw_text_len && raw_text[current_char] != '}')
|
||||
{
|
||||
token_len++;
|
||||
current_char++;
|
||||
}
|
||||
|
||||
if (current_char < raw_text_len)
|
||||
{
|
||||
token_len++;
|
||||
current_char++;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle special cases
|
||||
|
||||
// End of word/text detected
|
||||
if (raw_text[current_char] == ' ' || raw_text[current_char] == '\0')
|
||||
{
|
||||
token_start = current_char + 1;
|
||||
// Set these to -1 so that it becomes 0 when incremented for the
|
||||
// next iteration since we need to continue.
|
||||
token_len = -1;
|
||||
token_text_len = -1;
|
||||
}
|
||||
// Early end of line detected, interrupt parsing immediately
|
||||
else if (raw_text[current_char] == '\n')
|
||||
{
|
||||
token_start = current_char + 1;
|
||||
// Set to 0, no need to compensate for continuing the loops since
|
||||
// we're breaking early from it.
|
||||
token_len = 0;
|
||||
token_text_len = 0;
|
||||
line_text_len++;
|
||||
break;
|
||||
}
|
||||
|
||||
token_len++;
|
||||
token_text_len++;
|
||||
line_text_len++;
|
||||
};
|
||||
|
||||
// Do not print anything if we only need to compute the paragraph's total height
|
||||
if (do_print)
|
||||
{
|
||||
// Length of the raw slice for this line (includes formatting tags)
|
||||
int line_len = token_start - line_start;
|
||||
|
||||
// Trim trailing whitespace/newlines from the raw slice
|
||||
while (line_len > 0)
|
||||
{
|
||||
char c = raw_text[line_start + line_len - 1];
|
||||
if (c == ' ' || c == '\n' || c == '\0')
|
||||
line_len--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Remove the overflowing token's visible length from this line
|
||||
line_text_len = line_text_len - token_text_len - 1;
|
||||
if (line_text_len < 0)
|
||||
line_text_len = 0;
|
||||
|
||||
// useful DEBUG
|
||||
// tte_printf("#{P:0,%d}line %d - %d", 40 + (dst_rect.top + line_y) * TILE_SIZE, line_y,
|
||||
// line_text_len);
|
||||
|
||||
// Now, we can print the chars from line_start to token_start
|
||||
line_x = 0;
|
||||
if (justify_direction == JUSTIFY_CENTER)
|
||||
{
|
||||
line_x = (max_line_text_len - line_text_len) / 2;
|
||||
}
|
||||
|
||||
tte_printf(
|
||||
"#{P:%d,%d}%.*s",
|
||||
(dst_rect.left + line_x) * TILE_SIZE,
|
||||
(dst_rect.top + line_y) * TILE_SIZE,
|
||||
line_len,
|
||||
raw_text + line_start
|
||||
);
|
||||
}
|
||||
|
||||
line_start = token_start;
|
||||
line_text_len = 0;
|
||||
line_y++;
|
||||
}
|
||||
|
||||
return line_y;
|
||||
}
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
#include "card.h"
|
||||
#include "game_variables.h"
|
||||
#include "graphic_utils.h"
|
||||
#include "joker_gfx.h"
|
||||
#include "pool.h"
|
||||
#include "random.h"
|
||||
#include "soundbank.h"
|
||||
#include "util.h"
|
||||
|
||||
// Tiles and palettes
|
||||
#include "card_rarity_pal_gfx.h"
|
||||
#include "joker_gfx.h"
|
||||
|
||||
#include <maxmod.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -88,6 +91,11 @@ static int spritesheet_idx_to_starting_joker_id[] = {
|
||||
0, 18, 20, 22, 27, 32, 36, 40, 42, 44,
|
||||
45, 46, 47, 48, 49, 50, 51, 52
|
||||
};
|
||||
|
||||
// Lookup table of Joker Rarity strings. Used to display at the bottom of the description screen.
|
||||
static const char* joker_rarity_strings_lut[MAX_RARITIES] = {
|
||||
"Common", "Uncommon", "Rare", "Legendary"
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static int s_get_num_spritesheets(void);
|
||||
@@ -152,6 +160,24 @@ u32 joker_get_score_effect(
|
||||
return jinfo->joker_effect_func(joker, scored_card, joker_event, joker_effect);
|
||||
}
|
||||
|
||||
const char* joker_get_rarity_string(u8 rarity)
|
||||
{
|
||||
if (rarity >= MAX_RARITIES)
|
||||
return NULL;
|
||||
|
||||
return joker_rarity_strings_lut[rarity];
|
||||
}
|
||||
|
||||
u16 joker_get_rarity_color(u8 rarity, bool main_color)
|
||||
{
|
||||
if (rarity >= MAX_RARITIES)
|
||||
return 0x0;
|
||||
|
||||
// +1 to account for the transparency
|
||||
// odd indices are the main colors, even ones are the shadows
|
||||
return card_rarity_pal_gfxPal[1 + 2 * rarity + (main_color ? 0 : 1)];
|
||||
}
|
||||
|
||||
int joker_get_sell_value(const Joker* joker)
|
||||
{
|
||||
if (joker == NULL)
|
||||
|
||||
@@ -7,10 +7,23 @@
|
||||
#include "random.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MISPRINT_MAX_MULT 23
|
||||
|
||||
#define REGISTER_JOKER_DESC_FUNC(joker_desc_name) \
|
||||
static int joker_desc_name(Joker* joker, Rect dest_rect);
|
||||
|
||||
#define REGISTER_JOKER_EFFECT_FUNC(joker_effect_name) \
|
||||
static u32 joker_effect_name( \
|
||||
Joker* joker, \
|
||||
Card* scored_card, \
|
||||
enum JokerEvent joker_event, \
|
||||
JokerEffect** joker_effect \
|
||||
);
|
||||
|
||||
#define SCORE_ON_EVENT_ONLY_WITH_CARD(scored_card, restricted_event, checked_event) \
|
||||
if (checked_event != restricted_event || scored_card == NULL) \
|
||||
{ \
|
||||
@@ -24,15 +37,63 @@
|
||||
|
||||
static JokerEffect shared_joker_effect = {0};
|
||||
|
||||
// Joker Effect functions
|
||||
// Joker Descriptions
|
||||
|
||||
#define REGISTER_JOKER_EFFECT_FUNC(joker_effect_name) \
|
||||
static u32 joker_effect_name( \
|
||||
Joker* joker, \
|
||||
Card* scored_card, \
|
||||
enum JokerEvent joker_event, \
|
||||
JokerEffect** joker_effect \
|
||||
);
|
||||
REGISTER_JOKER_DESC_FUNC(default_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(greedy_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(lusty_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(wrathful_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(gluttonous_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(jolly_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(zany_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(mad_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(crazy_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(droll_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(sly_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(wily_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(clever_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(devious_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(crafty_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(half_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(stencil_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(misprint_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(walkie_talkie_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(fibonnaci_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(banner_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(mystic_summit_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(blackboard_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(blue_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(raised_fist_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(reserved_parking_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(business_card_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(scholar_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(scary_face_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(abstract_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(bull_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(smiley_face_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(even_steven_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(odd_todd_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(acrobat_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(hanging_chad_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(the_duo_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(the_trio_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(the_family_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(the_order_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(the_tribe_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(bootstraps_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(shoot_the_moon_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(pareidolia_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(photograph_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(dusk_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(shortcut_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(blueprint_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(brainstorm_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(hack_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(four_fingers_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(seltzer_joker_desc)
|
||||
REGISTER_JOKER_DESC_FUNC(sock_and_buskin_joker_desc)
|
||||
|
||||
// Joker Effect functions
|
||||
|
||||
static u32 sinful_joker_effect(
|
||||
Card* scored_card,
|
||||
@@ -94,80 +155,85 @@ REGISTER_JOKER_EFFECT_FUNC(sock_and_buskin_joker_effect)
|
||||
|
||||
// clang-format off
|
||||
/* The index of a joker in the registry matches its ID.
|
||||
*
|
||||
* The joker sprites are matched by ID so the position in the registry
|
||||
* determines the joker's sprite.
|
||||
*
|
||||
* Each consecutive NUM_JOKERS_PER_SPRITESHEET (defined in joker.c) jokers
|
||||
* share a spritesheet and thus a color palette.
|
||||
*
|
||||
* To make better use of color palettes jokers may be rearranged here
|
||||
* (and put together in the matching spritesheet) to share a color palette.
|
||||
* Otherwise the order is similar to the wiki.
|
||||
*
|
||||
* TODO: move Name and Description printing out of this when the CardInstance is implemented.
|
||||
*/
|
||||
// clang-format off
|
||||
const JokerInfo joker_registry[] =
|
||||
{
|
||||
// Spritesheet 0
|
||||
{ COMMON_JOKER, 2, default_joker_effect }, // DEFAULT_JOKER_ID = 0
|
||||
{ COMMON_JOKER, 4, abstract_joker_effect }, // 1
|
||||
{ COMMON_JOKER, 5, half_joker_effect }, // 2
|
||||
{ COMMON_JOKER, 4, misprint_joker_effect }, // 3
|
||||
{ COMMON_JOKER, 4, scary_face_joker_effect }, // 4
|
||||
{ UNCOMMON_JOKER, 6, sock_and_buskin_joker_effect }, // 5
|
||||
{ UNCOMMON_JOKER, 6, acrobat_joker_effect }, // 6
|
||||
{ UNCOMMON_JOKER, 8, fibonnaci_joker_effect }, // 7
|
||||
{ COMMON_JOKER, 4, scholar_joker_effect }, // 8
|
||||
{ COMMON_JOKER, 4, crafty_joker_effect }, // 9
|
||||
{ COMMON_JOKER, 4, droll_joker_effect }, // 10
|
||||
{ COMMON_JOKER, 5, raised_fist_joker_effect }, // 11
|
||||
{ COMMON_JOKER, 6, reserved_parking_joker_effect }, // 12
|
||||
{ COMMON_JOKER, 4, business_card_joker_effect }, // 13
|
||||
{ COMMON_JOKER, 4, hanging_chad_joker_effect }, // 14
|
||||
{ UNCOMMON_JOKER, 8, stencil_joker_effect }, // 15
|
||||
{ COMMON_JOKER, 5, banner_joker_effect }, // 16
|
||||
{ COMMON_JOKER, 5, shoot_the_moon_joker_effect, }, // 17
|
||||
{ "Joker", COMMON_JOKER, 2, false, default_joker_desc, default_joker_effect }, // DEFAULT_JOKER_ID = 0
|
||||
{ "Abstract Joker", COMMON_JOKER, 4, false, abstract_joker_desc, abstract_joker_effect }, // 1
|
||||
{ "Half Joker", COMMON_JOKER, 5, false, half_joker_desc, half_joker_effect }, // 2
|
||||
{ "Misprint", COMMON_JOKER, 4, true, misprint_joker_desc, misprint_joker_effect }, // 3
|
||||
{ "Scary Face", COMMON_JOKER, 4, false, scary_face_joker_desc, scary_face_joker_effect }, // 4
|
||||
{ "Sock and Buskin", UNCOMMON_JOKER, 6, false, sock_and_buskin_joker_desc, sock_and_buskin_joker_effect }, // 5
|
||||
{ "Acrobat", UNCOMMON_JOKER, 6, false, acrobat_joker_desc, acrobat_joker_effect }, // 6
|
||||
{ "Fibonacci", UNCOMMON_JOKER, 8, false, fibonnaci_joker_desc, fibonnaci_joker_effect }, // 7
|
||||
{ "Scholar", COMMON_JOKER, 4, false, scholar_joker_desc, scholar_joker_effect }, // 8
|
||||
{ "Crafty Joker", COMMON_JOKER, 4, false, crafty_joker_desc, crafty_joker_effect }, // 9
|
||||
{ "Droll Joker", COMMON_JOKER, 4, false, droll_joker_desc, droll_joker_effect }, // 10
|
||||
{ "Raised Fist", COMMON_JOKER, 5, false, raised_fist_joker_desc, raised_fist_joker_effect }, // 11
|
||||
{ "Reserved Parking", COMMON_JOKER, 6, false, reserved_parking_joker_desc, reserved_parking_joker_effect }, // 12
|
||||
{ "Business Card", COMMON_JOKER, 4, false, business_card_joker_desc, business_card_joker_effect }, // 13
|
||||
{ "Hanging Chad", COMMON_JOKER, 4, false, hanging_chad_joker_desc, hanging_chad_joker_effect }, // 14
|
||||
{ "Joker Stencil", UNCOMMON_JOKER, 8, false, stencil_joker_desc, stencil_joker_effect }, // 15
|
||||
{ "Banner", COMMON_JOKER, 5, false, banner_joker_desc, banner_joker_effect }, // 16
|
||||
{ "Shoot the Moon", COMMON_JOKER, 5, false, shoot_the_moon_joker_desc, shoot_the_moon_joker_effect, }, // 17
|
||||
// Spritesheet 1
|
||||
{ COMMON_JOKER, 5, greedy_joker_effect }, // 18
|
||||
{ COMMON_JOKER, 5, lusty_joker_effect }, // 19
|
||||
{ "Greedy Joker", COMMON_JOKER, 5, false, greedy_joker_desc, greedy_joker_effect }, // 18
|
||||
{ "Lusty Joker", COMMON_JOKER, 5, false, lusty_joker_desc, lusty_joker_effect }, // 19
|
||||
// Spritesheet 2
|
||||
{ COMMON_JOKER, 5, wrathful_joker_effect }, // 20
|
||||
{ COMMON_JOKER, 5, gluttonous_joker_effect }, // 21
|
||||
{ "Wrathful Joker", COMMON_JOKER, 5, false, wrathful_joker_desc, wrathful_joker_effect }, // 20
|
||||
{ "Gluttonous Joker", COMMON_JOKER, 5, false, gluttonous_joker_desc, gluttonous_joker_effect }, // 21
|
||||
// Spritesheet 3
|
||||
{ COMMON_JOKER, 4, crazy_joker_effect }, // 22
|
||||
{ COMMON_JOKER, 4, mad_joker_effect }, // 23
|
||||
{ COMMON_JOKER, 4, clever_joker_effect }, // 24
|
||||
{ COMMON_JOKER, 4, devious_joker_effect }, // 25
|
||||
{ COMMON_JOKER, 4, even_steven_joker_effect }, // 26
|
||||
{ "Crazy Joker", COMMON_JOKER, 4, false, crazy_joker_desc, crazy_joker_effect }, // 22
|
||||
{ "Mad Joker", COMMON_JOKER, 4, false, mad_joker_desc, mad_joker_effect }, // 23
|
||||
{ "Clever Joker", COMMON_JOKER, 4, false, clever_joker_desc, clever_joker_effect }, // 24
|
||||
{ "Devious Joker", COMMON_JOKER, 4, false, devious_joker_desc, devious_joker_effect }, // 25
|
||||
{ "Even Steven", COMMON_JOKER, 4, false, even_steven_joker_desc, even_steven_joker_effect }, // 26
|
||||
// Spritesheet 4
|
||||
{ UNCOMMON_JOKER, 6, blackboard_joker_effect }, // 27
|
||||
{ COMMON_JOKER, 5, mystic_summit_joker_effect }, // 28
|
||||
{ COMMON_JOKER, 4, walkie_talkie_joker_effect }, // 29
|
||||
{ COMMON_JOKER, 4, zany_joker_effect }, // 30
|
||||
{ COMMON_JOKER, 4, wily_joker_effect }, // 31
|
||||
{ "Blackboard", UNCOMMON_JOKER, 6, false, blackboard_joker_desc, blackboard_joker_effect }, // 27
|
||||
{ "Mystic Summit", COMMON_JOKER, 5, false, mystic_summit_joker_desc, mystic_summit_joker_effect }, // 28
|
||||
{ "Walkie Talkie", COMMON_JOKER, 4, false, walkie_talkie_joker_desc, walkie_talkie_joker_effect }, // 29
|
||||
{ "Zany Joker", COMMON_JOKER, 4, false, zany_joker_desc, zany_joker_effect }, // 30
|
||||
{ "Wily Joker", COMMON_JOKER, 4, false, wily_joker_desc, wily_joker_effect }, // 31
|
||||
// Spritesheet 5
|
||||
{ COMMON_JOKER, 3, sly_joker_effect }, // 32
|
||||
{ COMMON_JOKER, 3, jolly_joker_effect }, // 33
|
||||
{ COMMON_JOKER, 5, blue_joker_effect }, // 34
|
||||
{ COMMON_JOKER, 4, odd_todd_joker_effect }, // 35
|
||||
{ "Sly Joker", COMMON_JOKER, 3, false, sly_joker_desc, sly_joker_effect }, // 32
|
||||
{ "Jolly Joker", COMMON_JOKER, 3, false, jolly_joker_desc, jolly_joker_effect }, // 33
|
||||
{ "Blue Joker", COMMON_JOKER, 5, false, blue_joker_desc, blue_joker_effect }, // 34
|
||||
{ "Odd Todd", COMMON_JOKER, 4, false, odd_todd_joker_desc, odd_todd_joker_effect }, // 35
|
||||
// Spritesheet 6
|
||||
{ RARE_JOKER, 8, the_duo_joker_effect }, // 36
|
||||
{ RARE_JOKER, 8, the_trio_joker_effect }, // 37
|
||||
{ RARE_JOKER, 8, the_order_joker_effect }, // 38
|
||||
{ RARE_JOKER, 8, the_tribe_joker_effect }, // 39
|
||||
{ "The Duo", RARE_JOKER, 8, false, the_duo_joker_desc, the_duo_joker_effect }, // 36
|
||||
{ "The Trio", RARE_JOKER, 8, false, the_trio_joker_desc, the_trio_joker_effect }, // 37
|
||||
{ "The Order", RARE_JOKER, 8, false, the_order_joker_desc, the_order_joker_effect }, // 38
|
||||
{ "The Tribe", RARE_JOKER, 8, false, the_tribe_joker_desc, the_tribe_joker_effect }, // 39
|
||||
// Spritesheet 7
|
||||
{ RARE_JOKER, 8, the_family_joker_effect }, // 40
|
||||
{ RARE_JOKER, 10, blueprint_brainstorm_joker_effect }, // 41 Brainstorm
|
||||
{ "The Family", RARE_JOKER, 8, false, the_family_joker_desc, the_family_joker_effect }, // 40
|
||||
{ "Brainstorm", RARE_JOKER, 10, false, brainstorm_joker_desc, blueprint_brainstorm_joker_effect }, // 41 Brainstorm
|
||||
// Spritesheet 8
|
||||
{ COMMON_JOKER, 4, smiley_face_joker_effect }, // 42
|
||||
{ UNCOMMON_JOKER, 6, bull_joker_effect }, // 43
|
||||
{ "Smiley Face", COMMON_JOKER, 4, false, smiley_face_joker_desc, smiley_face_joker_effect }, // 42
|
||||
{ "Bull", UNCOMMON_JOKER, 6, false, bull_joker_desc, bull_joker_effect }, // 43
|
||||
// Individual Jokers (for now :3)
|
||||
{ COMMON_JOKER, 5, photograph_joker_effect, }, // 44
|
||||
{ UNCOMMON_JOKER, 6, hack_joker_effect }, // 45
|
||||
{ UNCOMMON_JOKER, 5, joker_effect_noop }, // 46 Pareidolia
|
||||
{ UNCOMMON_JOKER, 7, bootstraps_joker_effect }, // 47
|
||||
{ UNCOMMON_JOKER, 7, joker_effect_noop, }, // 48 Shortcut
|
||||
{ UNCOMMON_JOKER, 5, dusk_joker_effect }, // 49
|
||||
{ UNCOMMON_JOKER, 7, joker_effect_noop, }, // 50 Four Fingers
|
||||
{ UNCOMMON_JOKER, 6, seltzer_joker_effect, }, // 51
|
||||
{ RARE_JOKER, 10, blueprint_brainstorm_joker_effect }, // 52 Blueprint
|
||||
{ "Photograph", COMMON_JOKER, 5, false, photograph_joker_desc, photograph_joker_effect, }, // 44
|
||||
{ "Hack", UNCOMMON_JOKER, 6, false, hack_joker_desc, hack_joker_effect }, // 45
|
||||
{ "Pareidolia", UNCOMMON_JOKER, 5, false, pareidolia_joker_desc, joker_effect_noop }, // 46 Pareidolia
|
||||
{ "Bootstraps", UNCOMMON_JOKER, 7, false, bootstraps_joker_desc, bootstraps_joker_effect }, // 47
|
||||
{ "Shortcut", UNCOMMON_JOKER, 7, false, shortcut_joker_desc, joker_effect_noop, }, // 48 Shortcut
|
||||
{ "Dusk", UNCOMMON_JOKER, 5, false, dusk_joker_desc, dusk_joker_effect }, // 49
|
||||
{ "Four Fingers", UNCOMMON_JOKER, 7, false, four_fingers_joker_desc, joker_effect_noop, }, // 50 Four Fingers
|
||||
{ "Seltzer", UNCOMMON_JOKER, 6, false, seltzer_joker_desc, seltzer_joker_effect, }, // 51
|
||||
{ "Blueprint", RARE_JOKER, 10, false, blueprint_joker_desc, blueprint_brainstorm_joker_effect }, // 52 Blueprint
|
||||
|
||||
// The following jokers don't have sprites yet,
|
||||
// uncomment them when their sprites are added.
|
||||
@@ -192,6 +258,465 @@ size_t get_joker_registry_size(void)
|
||||
return joker_registry_size;
|
||||
}
|
||||
|
||||
#pragma region JOKER DESCRIPTIONS
|
||||
|
||||
static int default_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_RED_TAG "+4 " TTE_BLACK_TAG "Mult";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int greedy_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Played cards with " TTE_DIAMOND_TAG TTE_BLACK_TAG "suit give " TTE_RED_TAG
|
||||
"+3 " TTE_BLACK_TAG "Mult when scored";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int lusty_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Played cards with " TTE_HEART_TAG TTE_BLACK_TAG "suit give " TTE_RED_TAG
|
||||
"+3 " TTE_BLACK_TAG "Mult when scored";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int wrathful_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Played cards with " TTE_SPADE_TAG TTE_BLACK_TAG "suit give " TTE_RED_TAG
|
||||
"+3 " TTE_BLACK_TAG "Mult when scored";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int gluttonous_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Played cards with " TTE_CLUB_TAG TTE_BLACK_TAG "suit give " TTE_RED_TAG
|
||||
"+3 " TTE_BLACK_TAG "Mult when scored";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int jolly_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_RED_TAG "+8 " TTE_BLACK_TAG "Mult if played hand contains a " TTE_YELLOW_TAG "Pair";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int zany_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_RED_TAG
|
||||
"+12 " TTE_BLACK_TAG "Mult if played hand contains a " TTE_YELLOW_TAG "Three of a Kind";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int mad_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_RED_TAG
|
||||
"+10 " TTE_BLACK_TAG "Mult if played hand contains a " TTE_YELLOW_TAG "Two Pair";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int crazy_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_RED_TAG
|
||||
"+12 " TTE_BLACK_TAG "Mult if played hand contains a " TTE_YELLOW_TAG "Straight";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int droll_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_RED_TAG "+10 " TTE_BLACK_TAG "Mult if played hand contains a " TTE_YELLOW_TAG "Flush";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int sly_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLUE_TAG "+50 " TTE_BLACK_TAG "Chips if played hand contains a " TTE_YELLOW_TAG "Pair";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int wily_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_BLUE_TAG
|
||||
"+100 " TTE_BLACK_TAG "Chips if played hand contains a " TTE_YELLOW_TAG "Three of a Kind";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int clever_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_BLUE_TAG
|
||||
"+80 " TTE_BLACK_TAG "Chips if played hand contains a " TTE_YELLOW_TAG "Two Pair";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int devious_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_BLUE_TAG
|
||||
"+100 " TTE_BLACK_TAG "Chips if played hand contains a " TTE_YELLOW_TAG "Straight";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int crafty_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLUE_TAG "+80 " TTE_BLACK_TAG "Chips if played hand contains a " TTE_YELLOW_TAG "Flush";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int half_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_RED_TAG "+20 " TTE_BLACK_TAG "Mult if played hand contains " TTE_YELLOW_TAG
|
||||
"3 " TTE_BLACK_TAG "or fewer cards";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int stencil_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc_format[] =
|
||||
TTE_RED_TAG "X1 " TTE_BLACK_TAG
|
||||
"Mult for each empty Joker slot Joker Stencil included\n\n(Now " TTE_RED_TAG
|
||||
"X%ld " TTE_BLACK_TAG "Mult)";
|
||||
const u32 desc_max_size = 130;
|
||||
|
||||
List* jokers = get_jokers_list();
|
||||
u32 stencil_bonus = MAX_JOKERS_HELD_SIZE - list_get_len(jokers);
|
||||
|
||||
ListItr itr = list_itr_create(jokers);
|
||||
JokerObject* joker_object;
|
||||
while ((joker_object = list_itr_next(&itr)))
|
||||
{
|
||||
if (joker_object->joker->id == STENCIL_JOKER_ID)
|
||||
stencil_bonus++;
|
||||
}
|
||||
|
||||
char desc[desc_max_size];
|
||||
snprintf(desc, desc_max_size, desc_format, stencil_bonus);
|
||||
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int misprint_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
// TODO: print glitchy desc with occasional next card reveal
|
||||
char desc[] = TTE_YELLOW_TAG "Random" TTE_BLACK_TAG " Mult between " TTE_RED_TAG
|
||||
"+0" TTE_BLACK_TAG " and " TTE_RED_TAG "+23";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int walkie_talkie_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Each played " TTE_YELLOW_TAG "10 " TTE_BLACK_TAG "or " TTE_YELLOW_TAG
|
||||
"4 " TTE_BLACK_TAG "gives " TTE_BLUE_TAG "+10 " TTE_BLACK_TAG
|
||||
"Chips and " TTE_RED_TAG "+4 " TTE_BLACK_TAG "Mult when scored";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int fibonnaci_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Each played\n" TTE_YELLOW_TAG "Ace" TTE_BLACK_TAG ", " TTE_YELLOW_TAG
|
||||
"2" TTE_BLACK_TAG ", " TTE_YELLOW_TAG "3" TTE_BLACK_TAG ", " TTE_YELLOW_TAG
|
||||
"5" TTE_BLACK_TAG ", " TTE_YELLOW_TAG "8\n" TTE_BLACK_TAG "gives " TTE_RED_TAG
|
||||
"+8 " TTE_BLACK_TAG "Mult when scored";
|
||||
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int banner_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLUE_TAG "+30 " TTE_BLACK_TAG "Chips for each remaining " TTE_YELLOW_TAG "discard";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int mystic_summit_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_RED_TAG "+15 " TTE_BLACK_TAG "Mult when " TTE_YELLOW_TAG
|
||||
"0 " TTE_BLACK_TAG "discards remaining ";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int blackboard_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_RED_TAG
|
||||
"X3 " TTE_BLACK_TAG "Mult if all cards held in hand are " TTE_SPADE_TAG TTE_BLACK_TAG
|
||||
"or " TTE_CLUB_TAG;
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int blue_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc_format[] =
|
||||
TTE_BLUE_TAG "+2 " TTE_BLACK_TAG "Chips for each remaining card in " TTE_YELLOW_TAG
|
||||
"deck" TTE_BLACK_TAG "\n\n(Now " TTE_BLUE_TAG "+%ld" TTE_BLACK_TAG " Chips)";
|
||||
const u32 desc_max_size = 139;
|
||||
|
||||
u32 blue_bonus = (get_deck_top() + 1) * 2;
|
||||
|
||||
char desc[desc_max_size];
|
||||
snprintf(desc, desc_max_size, desc_format, blue_bonus);
|
||||
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int raised_fist_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Adds " TTE_YELLOW_TAG "double" TTE_BLACK_TAG " the rank of " TTE_YELLOW_TAG
|
||||
"lowest" TTE_BLACK_TAG " ranked card held in hand to Mult";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int reserved_parking_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_BLACK_TAG
|
||||
"Each " TTE_YELLOW_TAG "face" TTE_BLACK_TAG " card held in hand has a " TTE_GREEN_TAG
|
||||
"1 in 2" TTE_BLACK_TAG " chance to give " TTE_YELLOW_TAG "$1";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int business_card_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_BLACK_TAG
|
||||
"Played " TTE_YELLOW_TAG "face" TTE_BLACK_TAG " cards have a " TTE_GREEN_TAG
|
||||
"1 in 2" TTE_BLACK_TAG " chance to give " TTE_YELLOW_TAG "$2" TTE_BLACK_TAG " when scored";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int scholar_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_BLACK_TAG
|
||||
"Played " TTE_YELLOW_TAG "Aces" TTE_BLACK_TAG " give " TTE_BLUE_TAG "+20" TTE_BLACK_TAG
|
||||
" Chips and " TTE_RED_TAG "+4" TTE_BLACK_TAG " Mult when scored";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int scary_face_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Played " TTE_YELLOW_TAG "face" TTE_BLACK_TAG " cards give " TTE_BLUE_TAG
|
||||
"+30" TTE_BLACK_TAG " Chips when scored";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int abstract_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc_format[] =
|
||||
TTE_RED_TAG "+3" TTE_BLACK_TAG " Mult for each " TTE_YELLOW_TAG "Joker" TTE_BLACK_TAG
|
||||
" card\n\n(Now " TTE_RED_TAG "+%ld" TTE_BLACK_TAG " Mult)";
|
||||
const u32 desc_max_size = 125;
|
||||
|
||||
u32 abstract_bonus = list_get_len(get_jokers_list()) * 3;
|
||||
|
||||
char desc[desc_max_size];
|
||||
snprintf(desc, desc_max_size, desc_format, abstract_bonus);
|
||||
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int bull_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc_format[] =
|
||||
TTE_BLUE_TAG "+2" TTE_BLACK_TAG " Chips for each " TTE_YELLOW_TAG "$1" TTE_BLACK_TAG
|
||||
" you have\n\n(Now " TTE_BLUE_TAG "+%ld" TTE_BLACK_TAG " Chips)";
|
||||
const u32 desc_max_size = 127;
|
||||
|
||||
u32 bull_bonus = (g_game_vars.money > 0) ? g_game_vars.money * 2 : 0;
|
||||
|
||||
char desc[desc_max_size];
|
||||
snprintf(desc, desc_max_size, desc_format, bull_bonus);
|
||||
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int smiley_face_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Played " TTE_YELLOW_TAG "face" TTE_BLACK_TAG " cards give " TTE_RED_TAG
|
||||
"+5" TTE_BLACK_TAG " Mult when scored";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int even_steven_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Played cards with " TTE_YELLOW_TAG "even rank give " TTE_RED_TAG
|
||||
"+4" TTE_BLACK_TAG " Mult when scored\n(10, 8, 6, 4, 2)";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int odd_todd_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Played cards with " TTE_YELLOW_TAG "odd rank give " TTE_BLUE_TAG
|
||||
"+31" TTE_BLACK_TAG " Chips when scored\n(A, 9, 7, 5, 3)";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int acrobat_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_RED_TAG "X3" TTE_BLACK_TAG " Mult on " TTE_YELLOW_TAG
|
||||
"final hand" TTE_BLACK_TAG " of round";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int hanging_chad_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_BLACK_TAG "Retrigger " TTE_YELLOW_TAG "first" TTE_BLACK_TAG
|
||||
" played card used in scoring " TTE_YELLOW_TAG
|
||||
"2" TTE_BLACK_TAG " additional times ";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int the_duo_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_RED_TAG "X2" TTE_BLACK_TAG " Mult if played hand contains a " TTE_YELLOW_TAG "Pair";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int the_trio_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_RED_TAG
|
||||
"X3" TTE_BLACK_TAG " Mult if played hand contains a " TTE_YELLOW_TAG "Three of a Kind";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int the_family_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_RED_TAG
|
||||
"X4" TTE_BLACK_TAG " Mult if played hand contains a " TTE_YELLOW_TAG "Four of a Kind";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int the_order_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_RED_TAG "X3" TTE_BLACK_TAG " Mult if played hand contains a " TTE_YELLOW_TAG "Straight";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int the_tribe_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_RED_TAG "X2" TTE_BLACK_TAG " Mult if played hand contains a " TTE_YELLOW_TAG "Flush";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int bootstraps_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc_format[] =
|
||||
TTE_RED_TAG "+2" TTE_BLACK_TAG " Mult for every " TTE_YELLOW_TAG "$5" TTE_BLACK_TAG
|
||||
" you have\n\n(Now " TTE_RED_TAG "+%ld" TTE_BLACK_TAG " Mult)";
|
||||
const u32 desc_max_size = 125;
|
||||
|
||||
u32 bootstrap_bonus = (g_game_vars.money > 0) ? (g_game_vars.money / 5) * 2 : 0;
|
||||
|
||||
char desc[desc_max_size];
|
||||
snprintf(desc, desc_max_size, desc_format, bootstrap_bonus);
|
||||
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int shoot_the_moon_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Each " TTE_YELLOW_TAG "Queen" TTE_BLACK_TAG
|
||||
" held in hand gives " TTE_RED_TAG "+13" TTE_BLACK_TAG " Mult";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int photograph_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "First played " TTE_YELLOW_TAG "face" TTE_BLACK_TAG " card gives " TTE_RED_TAG
|
||||
"X2" TTE_BLACK_TAG " Mult when scored";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int dusk_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_BLACK_TAG "Retrigger all played cards in " TTE_YELLOW_TAG
|
||||
"final hand" TTE_BLACK_TAG " of the round";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int blueprint_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Copies ability of the leftmost " TTE_YELLOW_TAG "Joker";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int brainstorm_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Copies ability of " TTE_YELLOW_TAG "Joker" TTE_BLACK_TAG " to the right";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int hack_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] = TTE_BLACK_TAG
|
||||
"Retrigger each played " TTE_YELLOW_TAG "2" TTE_BLACK_TAG ", " TTE_YELLOW_TAG
|
||||
"3" TTE_BLACK_TAG ", " TTE_YELLOW_TAG "4" TTE_BLACK_TAG ", or " TTE_YELLOW_TAG "5";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int seltzer_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc_format[] = TTE_BLACK_TAG
|
||||
"Retrigger all cards played for the next " TTE_YELLOW_TAG "%ld" TTE_BLACK_TAG " hands";
|
||||
const u32 desc_max_size = 94;
|
||||
|
||||
char desc[desc_max_size];
|
||||
snprintf(desc, desc_max_size, desc_format, joker->persistent_state);
|
||||
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int sock_and_buskin_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Retrigger all played " TTE_YELLOW_TAG "face" TTE_BLACK_TAG " cards";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int pareidolia_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "All cards are considered " TTE_YELLOW_TAG "face" TTE_BLACK_TAG " cards";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int shortcut_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "Allows " TTE_YELLOW_TAG "Straights" TTE_BLACK_TAG
|
||||
" to be made with gaps of " TTE_YELLOW_TAG "1 rank" TTE_BLACK_TAG
|
||||
"\n\n(ex: " TTE_YELLOW_TAG "10 8 6 5 3" TTE_BLACK_TAG ")";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
static int four_fingers_joker_desc(Joker* joker, Rect dest_rect)
|
||||
{
|
||||
static const char desc[] =
|
||||
TTE_BLACK_TAG "All " TTE_YELLOW_TAG "Flushes" TTE_BLACK_TAG " and " TTE_YELLOW_TAG
|
||||
"Straights" TTE_BLACK_TAG " can be made with 4 cards";
|
||||
return tte_printf_justified_in_rect(desc, dest_rect, JUSTIFY_CENTER, SCREEN_LEFT, true);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region JOKER EFFECTS
|
||||
|
||||
static u32 joker_effect_noop(
|
||||
Joker* joker,
|
||||
Card* scored_card,
|
||||
@@ -1505,3 +2030,5 @@ static u32 sock_and_buskin_joker_effect(
|
||||
|
||||
return effect_flags_ret;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
// Graphics
|
||||
#include "affine_background_gfx.h"
|
||||
#include "background_gfx.h"
|
||||
#include "graphic_utils.h"
|
||||
|
||||
// Audio
|
||||
#include "audio_utils.h"
|
||||
@@ -52,11 +53,9 @@ void init()
|
||||
tte_erase_screen();
|
||||
tte_init_con();
|
||||
|
||||
// TTE palette setup
|
||||
pal_bg_bank[TTE_YELLOW_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_YELLOW;
|
||||
pal_bg_bank[TTE_BLUE_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_BLUE;
|
||||
pal_bg_bank[TTE_RED_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_RED;
|
||||
pal_bg_bank[TTE_WHITE_PB][TTE_BIT_ON_CLR_IDX] = TEXT_CLR_WHITE;
|
||||
// Will need to be called when starting the game, as some colors will have
|
||||
// been overwritten by the logo and its whopping 10 palettes
|
||||
tte_colors_setup();
|
||||
|
||||
// Set up the video mode
|
||||
// BG0 is the TTE text layer
|
||||
|
||||
@@ -15,14 +15,16 @@ void splash_screen_on_init(void)
|
||||
{
|
||||
timer = 0;
|
||||
|
||||
tte_printf("#{P:72,8; cx:0xF000}DISCLAIMER");
|
||||
tte_printf("#{P:72,8; cx:0x%X000}DISCLAIMER", TTE_WHITE_PB);
|
||||
tte_printf(
|
||||
"#{P:8,24; cx:0xF000}This project is NOT endorsed \n by or affiliated with \n Playstack or "
|
||||
"#{P:8,24; cx:0x%X000}This project is NOT endorsed \n by or affiliated with \n Playstack "
|
||||
"or "
|
||||
"LocalThunk.\n\n If you have paid for this, \n you have been scammed \n and should request "
|
||||
"a refund \n IMMEDIATELY. \n\n The only official place \n to obtain this is from: \n\n "
|
||||
"'github.com/\n GBALATRO/balatro-gba'"
|
||||
"'github.com/\n GBALATRO/balatro-gba'",
|
||||
TTE_WHITE_PB
|
||||
);
|
||||
tte_printf("#{P:8,144; cx:0xF000}(Press any key to skip)");
|
||||
tte_printf("#{P:8,144; cx:0x%X000}(Press any key to skip)", TTE_WHITE_PB);
|
||||
}
|
||||
|
||||
void splash_screen_on_update(void)
|
||||
@@ -33,9 +35,10 @@ void splash_screen_on_update(void)
|
||||
{
|
||||
tte_erase_rect_wrapper(COUNTDOWN_TIMER_RECT);
|
||||
tte_printf(
|
||||
"#{P:%d,%d; cx:0xF000}%d",
|
||||
"#{P:%d,%d; cx:0x%X000}%d",
|
||||
COUNTDOWN_TIMER_RECT.left,
|
||||
COUNTDOWN_TIMER_RECT.top,
|
||||
TTE_WHITE_PB,
|
||||
1 + (SPLASH_DURATION_FRAMES - timer) / SPLASH_FPS
|
||||
);
|
||||
|
||||
|
||||