GBAlatro
A Demake of Balatro for the GBA
Loading...
Searching...
No Matches
skip_tag_effects.c
1#include "game.h"
2#include "game/blind_select.h"
3#include "game/common_ui.h"
4#include "game/shop.h"
5#include "game_variables.h"
6#include "hand.h"
7#include "joker.h"
8#include "list.h"
9#include "round_end.h"
10#include "skip_tag.h"
11#include "util.h"
12
13#include <stdlib.h>
14#include <tonc.h>
15
16#define DECLARE_SKIP_TAG_CONDITION_FUNC(tag_condition_name) static bool tag_condition_name(void);
17
18#define DECLARE_SKIP_TAG_EFFECT_FUNC(tag_effect_name) static void tag_effect_name(void);
19
20DECLARE_SKIP_TAG_CONDITION_FUNC(skip_tag_cond_true)
21DECLARE_SKIP_TAG_CONDITION_FUNC(skip_tag_cond_double)
22DECLARE_SKIP_TAG_CONDITION_FUNC(skip_tag_cond_juggle)
23DECLARE_SKIP_TAG_CONDITION_FUNC(skip_tag_cond_d6)
24DECLARE_SKIP_TAG_CONDITION_FUNC(skip_tag_cond_investment)
25
26DECLARE_SKIP_TAG_EFFECT_FUNC(skip_tag_effect_noop)
27DECLARE_SKIP_TAG_EFFECT_FUNC(skip_tag_effect_boss)
28DECLARE_SKIP_TAG_EFFECT_FUNC(skip_tag_effect_handy)
29DECLARE_SKIP_TAG_EFFECT_FUNC(skip_tag_effect_garbage)
30DECLARE_SKIP_TAG_EFFECT_FUNC(skip_tag_effect_double)
31DECLARE_SKIP_TAG_EFFECT_FUNC(skip_tag_effect_juggle)
32DECLARE_SKIP_TAG_EFFECT_FUNC(skip_tag_effect_d6)
33DECLARE_SKIP_TAG_EFFECT_FUNC(skip_tag_effect_top_up)
34DECLARE_SKIP_TAG_EFFECT_FUNC(skip_tag_effect_speed)
35DECLARE_SKIP_TAG_EFFECT_FUNC(skip_tag_effect_economy)
36
37// The index of a skip tag in the registry matches its ID.
38// clang-format off
39const SkipTagInfo skip_tag_registry[] =
40{
41 [SKIP_TAG_TYPE_INVESTMENT] = { SKIP_TAG_EVENT_ON_ROUND_END, skip_tag_cond_investment, skip_tag_effect_noop },
42 [SKIP_TAG_TYPE_BOSS] = { SKIP_TAG_EVENT_IMMEDIATE, skip_tag_cond_true, skip_tag_effect_boss },
43 [SKIP_TAG_TYPE_HANDY] = { SKIP_TAG_EVENT_IMMEDIATE, skip_tag_cond_true, skip_tag_effect_handy },
44 [SKIP_TAG_TYPE_GARBAGE] = { SKIP_TAG_EVENT_IMMEDIATE, skip_tag_cond_true, skip_tag_effect_garbage },
45 [SKIP_TAG_TYPE_DOUBLE] = { SKIP_TAG_EVENT_IMMEDIATE, skip_tag_cond_double, skip_tag_effect_double },
46 [SKIP_TAG_TYPE_JUGGLE] = { SKIP_TAG_EVENT_ON_ROUND_START, skip_tag_cond_juggle, skip_tag_effect_juggle },
47 [SKIP_TAG_TYPE_D6] = { SKIP_TAG_EVENT_ON_SHOP_INIT, skip_tag_cond_d6, skip_tag_effect_d6 },
48 [SKIP_TAG_TYPE_TOP_UP] = { SKIP_TAG_EVENT_IMMEDIATE, skip_tag_cond_true, skip_tag_effect_top_up },
49 [SKIP_TAG_TYPE_SPEED] = { SKIP_TAG_EVENT_IMMEDIATE, skip_tag_cond_true, skip_tag_effect_speed },
50 [SKIP_TAG_TYPE_ECONOMY] = { SKIP_TAG_EVENT_IMMEDIATE, skip_tag_cond_true, skip_tag_effect_economy },
51};
52// clang-format on
53
54static const size_t skip_tag_registry_size = NUM_ELEM_IN_ARR(skip_tag_registry);
55
57{
58 if (tag_type < 0 || (size_t)tag_type >= skip_tag_registry_size)
59 {
60 return NULL;
61 }
62 return &skip_tag_registry[tag_type];
63}
64
65// CONDITIONS IMPLEMENTATION
66
67static bool skip_tag_cond_true(void)
68{
69 return true;
70}
71
72static bool skip_tag_cond_investment(void)
73{
74 return g_game_vars.current_blind >= BLIND_TYPE_BOSS;
75}
76
77static bool skip_tag_cond_double(void)
78{
79 SkipTag* latest_tag = get_owned_skip_tags()->tail->data;
80 return (latest_tag != NULL) && (latest_tag->type != SKIP_TAG_TYPE_DOUBLE);
81}
82
83static bool skip_tag_cond_juggle(void)
84{
85 return g_game_vars.hand_size < MAX_HAND_SIZE;
86}
87
88static bool skip_tag_cond_d6(void)
89{
90 return shop_get_reroll_cost() > 0;
91}
92
93// EFFECTS IMPLEMENTATION
94
95static void skip_tag_effect_noop(void)
96{
97}
98
99static void skip_tag_effect_boss(void)
100{
102}
103
104static void skip_tag_effect_handy(void)
105{
106 for (int i = 0; i < HAND_TYPE_MAX; i++)
107 g_game_vars.money += g_game_vars.nb_played_hands[i];
108 display_money();
109}
110
111static void skip_tag_effect_garbage(void)
112{
113 g_game_vars.money += g_game_vars.nb_unused_discards;
114 display_money();
115}
116
117static void skip_tag_effect_double(void)
118{
119 // If the double tag can activate, then we have already checked the latest
120 // tag exists and isn't a double tag
121 SkipTag* latest_tag = get_owned_skip_tags()->tail->data;
122 SkipTag* latest_tag_copy = skip_tag_new(latest_tag->type);
123 add_skip_tag(&latest_tag_copy);
124}
125
126static void skip_tag_effect_juggle(void)
127{
128 s32 new_hand_size = g_game_vars.hand_size + 3;
129 g_game_vars.hand_size = (new_hand_size > MAX_HAND_SIZE) ? MAX_HAND_SIZE : new_hand_size;
130}
131
132static void skip_tag_effect_d6(void)
133{
135}
136
137#define TOP_UP_TAG_JOKER_BONUS 2
138static void skip_tag_effect_top_up(void)
139{
140 int available_joker_slots = MAX_JOKERS_HELD_SIZE - list_get_len(get_jokers_list());
141 if (available_joker_slots > TOP_UP_TAG_JOKER_BONUS)
142 available_joker_slots = TOP_UP_TAG_JOKER_BONUS;
143
144 for (int i = 0; i < available_joker_slots; i++)
145 {
146 int joker_id = joker_roll_id(COMMON_JOKER, RNG_SEQ_TAG_TOP_UP);
147
148 // Something went wrong, maybe there are no more Common Jokers available
149 if (joker_id == UNDEFINED)
150 break;
151
152 Joker* joker = joker_new(joker_id);
154
155 joker_set_rollable(joker_id, false);
156 item_acquire((Item*)joker_object_new(joker));
157 }
158}
159
160#define SPEED_TAG_MONEY_BONUS 5
161static void skip_tag_effect_speed(void)
162{
163 g_game_vars.money += g_game_vars.nb_skipped_rounds * SPEED_TAG_MONEY_BONUS;
164 display_money();
165}
166
167static void skip_tag_effect_economy(void)
168{
169 int added_money = 0;
170 if (g_game_vars.money > 0)
171 added_money = min(g_game_vars.money, 40);
172
173 g_game_vars.money += added_money;
174 display_money();
175}
Blind select state functions.
void blind_select_reroll_boss_from_menu(void)
Reroll the Boss Blind from inside the menu. This function is made to be used for both Vouchers and th...
Common functions to render UI elements.
Game global game variables struct definition.
Functions relative to manipulating and analyzing the contents of the Hand, a.k.a. the Cards we hold a...
void item_acquire(Item *item)
Acquires the item, adding to inventory if applicable. Called when it is purchased from the shop,...
Definition item.c:116
Functions relative to the handling of Jokers.
int joker_roll_id(enum JokerRarity joker_rarity, enum RngSequence key)
Rolls a random Joker among the available ones of a certain rarity.
Definition joker.c:384
void joker_set_rollable(int joker_id, bool rollable)
Set whether a Joker is available to be rolled for the shop, packs, etc.
Definition joker.c:345
A doubly-linked list.
int list_get_len(const List *list)
Definition list.c:214
Round end game state functions.
Shop state functions.
int shop_get_reroll_cost(void)
Get the current cost to reroll the items sold in the shop.
Definition shop.c:201
void shop_set_reroll_cost(int cost)
Set the current cost to reroll the items sold in the shop to the given value.
Definition shop.c:206
Data structures and functions related to the handling of Skip Tags.
SkipTagTypes
List of all Skip Tags, in the order they are in on their spritesheet. Not all of them are implemented...
Definition skip_tag.h:45
void add_skip_tag(SkipTag **blind_tag)
Adds the SkipTag to the owned list, snaps it into position and sets the original pointer to NULL.
Definition skip_tag.c:230
SkipTag * skip_tag_new(enum SkipTagTypes tag_type)
Create a new Skip Tag object for the given Tag ID and allocates space for it in the corresponding mem...
Definition skip_tag.c:83
const SkipTagInfo * get_skip_tag_registry_entry(enum SkipTagTypes tag_type)
Get the registry entry info for the given Skip Tag type.
List * get_owned_skip_tags(void)
Get the owned skip tags list.
Definition skip_tag.c:76
A generic interface for all items that can appear in the shop or be in the inventory....
Definition item.h:83
Definition joker.h:83
void * data
Pointer to generic data stored in this node.
Definition list.h:54
ListNode * tail
The last entry in the list.
Definition list.h:70
Data structure containing the info about a Skip Tag, namely:
Definition skip_tag.h:108
Utilities relating around number string representation and protected arithmatic helper functions.
#define NUM_ELEM_IN_ARR(arr)
Get the number of elements in an array.
Definition util.h:55
#define GBAL_RETURN_IF_NULL(param, ret_val)
Returns ret_val and prints a default error message if param is equal to NULL. Useful for checking arg...
Definition util.h:138
#define RET_NONE
An empty return value for RETURN_IF macros when used in void functions Expands to nothing because mac...
Definition util.h:146