Added the ability to restart the game after a game over.
The function that handles this is the on_exit of the game lost state. This function is not meant to be permanent, but is just a placeholder while we decide what we actually want to do when game over is reached.
This commit is contained in:
@@ -5,5 +5,5 @@ DEF_STATE_INFO(GAME_STATE_PLAYING, game_round_on_init, game_playing_on_update, _
|
||||
DEF_STATE_INFO(GAME_STATE_ROUND_END, _noop, game_round_end_on_update, game_round_end_on_exit)
|
||||
DEF_STATE_INFO(GAME_STATE_SHOP, _noop, game_shop_on_update, game_shop_on_exit)
|
||||
DEF_STATE_INFO(GAME_STATE_BLIND_SELECT, _noop, game_blind_select_on_update, game_blind_select_on_exit)
|
||||
DEF_STATE_INFO(GAME_STATE_LOSE, game_lose_on_init, game_lose_on_update, _noop)
|
||||
DEF_STATE_INFO(GAME_STATE_LOSE, game_lose_on_init, game_lose_on_update, game_lose_on_exit)
|
||||
DEF_STATE_INFO(GAME_STATE_WIN, game_win_on_init, game_win_on_update, _noop)
|
||||
+85
-23
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "tonc_memdef.h"
|
||||
#include "tonc_memmap.h"
|
||||
#include "tonc_tte.h"
|
||||
#include "util.h"
|
||||
#include "sprite.h"
|
||||
#include "card.h"
|
||||
@@ -72,11 +73,15 @@ typedef void (*SubStateActionFn)();
|
||||
// ricfehr3 did the work of determining whether a noop or a NULL check was more
|
||||
// efficient. Well, this is the answer.
|
||||
// Thanks!
|
||||
// https://github.com/cellos51/balatro-gba/issues/137#issuecomment-3322485129
|
||||
static void _noop() {}
|
||||
|
||||
// These functions need to be forward declared
|
||||
// so they're visible to the state_info array,
|
||||
// and the sub-state function tables.
|
||||
// This could be done, and maybe should be done,
|
||||
// with an X macro, but I'll leave that to the
|
||||
// reviewer(s).
|
||||
static void game_main_menu_on_init();
|
||||
static void game_main_menu_on_update();
|
||||
static void game_round_on_init();
|
||||
@@ -89,6 +94,7 @@ static void game_blind_select_on_update();
|
||||
static void game_blind_select_on_exit();
|
||||
static void game_lose_on_init();
|
||||
static void game_lose_on_update();
|
||||
static void game_lose_on_exit();
|
||||
static void game_win_on_init();
|
||||
static void game_win_on_update();
|
||||
static void game_shop_intro();
|
||||
@@ -114,11 +120,11 @@ static uint timer = 0; // This might already exist in libtonc but idk so i'm jus
|
||||
static int game_speed = 1; // BY DEFAULT IS SET TO 1, but if changed to 2 or more, should speed up all (or most) of the game aspects that should be sped up by speed, as in the original game.
|
||||
static int background = 0;
|
||||
|
||||
static const StateInfo state_info[GAME_STATE_MAX] =
|
||||
static const StateInfo state_info[] =
|
||||
{
|
||||
#define DEF_STATE_INFO(stateEnum, init_fn, update_fn, exit_fn) \
|
||||
{ .state = stateEnum, .on_init = init_fn, .on_update = update_fn, .on_exit = exit_fn },
|
||||
#include "../include/game_state_table.h"
|
||||
#include "../include/def_state_info_table.h"
|
||||
#undef DEF_STATE_INFO
|
||||
};
|
||||
|
||||
@@ -271,6 +277,18 @@ static inline Card *discard_pop()
|
||||
return discard_pile[discard_top--];
|
||||
}
|
||||
|
||||
static inline void reset_background_color()
|
||||
{
|
||||
int y = 6;
|
||||
|
||||
memset16(&se_mem[MAIN_BG_SBB][32 * (y - 1)], 0x0006, 1);
|
||||
memset16(&se_mem[MAIN_BG_SBB][1 + 32 * (y - 1)], 0x0007, 2);
|
||||
memset16(&se_mem[MAIN_BG_SBB][3 + 32 * (y - 1)], 0x0008, 1);
|
||||
memset16(&se_mem[MAIN_BG_SBB][4 + 32 * (y - 1)], 0x0009, 4);
|
||||
memset16(&se_mem[MAIN_BG_SBB][7 + 32 * (y - 1)], 0x000A, 1);
|
||||
memset16(&se_mem[MAIN_BG_SBB][8 + 32 * (y - 1)], 0x0406, 1);
|
||||
}
|
||||
|
||||
// get-functions, for other files to view game state (mainly for jokers)
|
||||
CardObject **get_hand_array(void) {
|
||||
return hand;
|
||||
@@ -1282,11 +1300,9 @@ void game_init()
|
||||
blind_select_tokens[BLIND_TYPE_BIG] = blind_token_new(BLIND_TYPE_BIG, CUR_BLIND_TOKEN_POS.x, CUR_BLIND_TOKEN_POS.y, MAX_SELECTION_SIZE + MAX_HAND_SIZE + 4);
|
||||
blind_select_tokens[BLIND_TYPE_BOSS] = blind_token_new(BLIND_TYPE_BOSS, CUR_BLIND_TOKEN_POS.x, CUR_BLIND_TOKEN_POS.y, MAX_SELECTION_SIZE + MAX_HAND_SIZE + 5);
|
||||
|
||||
obj_hide(blind_select_tokens[BLIND_TYPE_SMALL]->obj);
|
||||
obj_hide(blind_select_tokens[BLIND_TYPE_BIG]->obj);
|
||||
obj_hide(blind_select_tokens[BLIND_TYPE_BOSS]->obj);
|
||||
|
||||
game_change_state(game_state);
|
||||
obj_hide(blind_select_tokens[SMALL_BLIND]->obj);
|
||||
obj_hide(blind_select_tokens[BIG_BLIND]->obj);
|
||||
obj_hide(blind_select_tokens[BOSS_BLIND]->obj);
|
||||
}
|
||||
|
||||
void game_start()
|
||||
@@ -1572,8 +1588,6 @@ static void game_playing_discarded_cards_loop()
|
||||
if (discard_top == -1 && discarded_card_object == NULL) // If there are no more discarded cards, stop shuffling
|
||||
{
|
||||
// After HAND_SHUFFLING the round is over
|
||||
// TODO: Add call to change state here
|
||||
// after adding on_exit
|
||||
game_playing_handle_round_over();
|
||||
}
|
||||
}
|
||||
@@ -2286,13 +2300,7 @@ static void game_round_end_panel_exit()
|
||||
|
||||
if (timer == 1) // Copied from shop. Feels slightly too niche of a function for me personally to make one.
|
||||
{
|
||||
int y = 6;
|
||||
memset16(&se_mem[MAIN_BG_SBB][32 * (y - 1)], 0x0006, 1);
|
||||
memset16(&se_mem[MAIN_BG_SBB][1 + 32 * (y - 1)], 0x0007, 2);
|
||||
memset16(&se_mem[MAIN_BG_SBB][3 + 32 * (y - 1)], 0x0008, 1);
|
||||
memset16(&se_mem[MAIN_BG_SBB][4 + 32 * (y - 1)], 0x0009, 4);
|
||||
memset16(&se_mem[MAIN_BG_SBB][7 + 32 * (y - 1)], 0x000A, 1);
|
||||
memset16(&se_mem[MAIN_BG_SBB][8 + 32 * (y - 1)], 0x0406, 1);
|
||||
reset_background_color();
|
||||
}
|
||||
else if (timer == 2)
|
||||
{
|
||||
@@ -2815,13 +2823,7 @@ static void game_shop_outro()
|
||||
}
|
||||
}
|
||||
|
||||
int y = 6;
|
||||
memset16(&se_mat[MAIN_BG_SBB][y - 1][0], 0x0006, 1);
|
||||
memset16(&se_mat[MAIN_BG_SBB][y - 1][1], 0x0007, 2);
|
||||
memset16(&se_mat[MAIN_BG_SBB][y - 1][3], 0x0008, 1);
|
||||
memset16(&se_mat[MAIN_BG_SBB][y - 1][4], 0x0009, 4);
|
||||
memset16(&se_mat[MAIN_BG_SBB][y - 1][7], 0x000A, 1);
|
||||
memset16(&se_mat[MAIN_BG_SBB][y - 1][8], SE_HFLIP | 0x0006, 1);
|
||||
reset_background_color();
|
||||
}
|
||||
else if (timer == 2)
|
||||
{
|
||||
@@ -3166,6 +3168,66 @@ static void game_lose_on_update()
|
||||
{
|
||||
tte_printf("#{P:%d,%d; cx:0x%X000}GAME OVER", GAME_LOSE_MSG_TEXT_RECT.left, GAME_LOSE_MSG_TEXT_RECT.top, TTE_RED_PB);
|
||||
}
|
||||
|
||||
if (key_hit(KEY_START)) game_change_state(GAME_STATE_BLIND_SELECT);
|
||||
}
|
||||
|
||||
// This function isn't set in stone. This is just a placeholder
|
||||
// allowing the player to restart the game. Thought it would be nice to have
|
||||
// util we decide what we want to do after a game over.
|
||||
static void game_lose_on_exit()
|
||||
{
|
||||
// update blind. Will start back on whatever blind you lost on
|
||||
// setting current_blind doesn't seem to work. Jokers are also left over.
|
||||
timer = TM_ZERO;
|
||||
current_blind = SMALL_BLIND;
|
||||
blinds[0] = BLIND_CURRENT;
|
||||
blinds[1] = BLIND_UPCOMING;
|
||||
blinds[2] = BLIND_UPCOMING;
|
||||
round = 0;
|
||||
ante = 1;
|
||||
money = 4;
|
||||
score = 0;
|
||||
hands = max_hands;
|
||||
discards = max_discards;
|
||||
|
||||
for (int i = 0; i < list_get_size(jokers); i ++)
|
||||
{
|
||||
JokerObject *joker_object = list_get(jokers, i);
|
||||
joker_object_destroy(&joker_object);
|
||||
}
|
||||
|
||||
tte_erase_screen();
|
||||
|
||||
// For some reason that I haven't figured out yet,
|
||||
// if I don't destroy the blind tokens they won't
|
||||
// show up on the next run.
|
||||
sprite_destroy(&playing_blind_token);
|
||||
sprite_destroy(&round_end_blind_token);
|
||||
sprite_destroy(&blind_select_tokens[SMALL_BLIND]);
|
||||
sprite_destroy(&blind_select_tokens[BIG_BLIND]);
|
||||
sprite_destroy(&blind_select_tokens[BOSS_BLIND]);
|
||||
list_destroy(&jokers_available_to_shop);
|
||||
display_round(round);
|
||||
display_score(score);
|
||||
display_chips(chips);
|
||||
display_mult(mult);
|
||||
display_hands(hands);
|
||||
display_discards(discards);
|
||||
display_money(money);
|
||||
tte_printf(
|
||||
"#{P:%d,%d; cx:0x%X000}%d#{cx:0x%X000}/%d",
|
||||
ANTE_TEXT_RECT.left,
|
||||
ANTE_TEXT_RECT.top,
|
||||
TTE_YELLOW_PB,
|
||||
ante,
|
||||
TTE_WHITE_PB,
|
||||
MAX_ANTE
|
||||
); // Ante
|
||||
|
||||
affine_background_load_palette(affine_background_gfxPal);
|
||||
reset_background_color();
|
||||
game_init();
|
||||
}
|
||||
|
||||
static void game_win_on_update()
|
||||
|
||||
@@ -77,6 +77,7 @@ void init()
|
||||
blind_init();
|
||||
joker_init();
|
||||
game_init();
|
||||
game_change_state(GAME_STATE_SPLASH_SCREEN);
|
||||
}
|
||||
|
||||
void update()
|
||||
|
||||
Reference in New Issue
Block a user