Added joker selling (still no animation) + fixed SpriteObject constructor focused bug
This commit is contained in:
+2
-1
@@ -23,6 +23,7 @@
|
|||||||
#define PEEK_DECK KEY_L // Not implemented
|
#define PEEK_DECK KEY_L // Not implemented
|
||||||
#define SORT_HAND KEY_R
|
#define SORT_HAND KEY_R
|
||||||
#define PAUSE_GAME KEY_START // Not implemented
|
#define PAUSE_GAME KEY_START // Not implemented
|
||||||
|
#define SELL_KEY KEY_L
|
||||||
|
|
||||||
enum GameState
|
enum GameState
|
||||||
{
|
{
|
||||||
@@ -90,4 +91,4 @@ List* get_jokers(void);
|
|||||||
|
|
||||||
int get_num_discards_remaining(void);
|
int get_num_discards_remaining(void);
|
||||||
|
|
||||||
#endif // GAME_H
|
#endif // GAME_H
|
||||||
|
|||||||
@@ -34,11 +34,16 @@
|
|||||||
#define SE_COL_LEN 32
|
#define SE_COL_LEN 32
|
||||||
|
|
||||||
// Since y direction goes from the top of the screen to the bottom
|
// Since y direction goes from the top of the screen to the bottom
|
||||||
#define SE_UP -1
|
#define SCREEN_UP -1
|
||||||
#define SE_DOWN 1
|
#define SCREEN_DOWN 1
|
||||||
|
#define SCREEN_LEFT -1
|
||||||
|
#define SCREEN_RIGHT 1
|
||||||
|
|
||||||
#define OVERFLOW_LEFT -1
|
#define SE_UP SCREEN_UP
|
||||||
#define OVERFLOW_RIGHT 1
|
#define SE_DOWN SCREEN_DOWN
|
||||||
|
|
||||||
|
#define OVERFLOW_LEFT SCREEN_LEFT
|
||||||
|
#define OVERFLOW_RIGHT SCREEN_RIGHT
|
||||||
|
|
||||||
// Tile size in pixels, both height and width as tiles are square
|
// Tile size in pixels, both height and width as tiles are square
|
||||||
#define TILE_SIZE 8
|
#define TILE_SIZE 8
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ void joker_destroy(Joker **joker);
|
|||||||
// Unique effects like "Four Fingers" or "Credit Card" will be hard coded into game.c with a conditional check for the joker ID from the players owned jokers
|
// Unique effects like "Four Fingers" or "Credit Card" will be hard coded into game.c with a conditional check for the joker ID from the players owned jokers
|
||||||
// game.c should probably be restructured so most of the variables in it are moved to some sort of global variable header file so they can be easily accessed and modified for the jokers
|
// game.c should probably be restructured so most of the variables in it are moved to some sort of global variable header file so they can be easily accessed and modified for the jokers
|
||||||
JokerEffect joker_get_score_effect(Joker *joker, Card *scored_card);
|
JokerEffect joker_get_score_effect(Joker *joker, Card *scored_card);
|
||||||
|
int joker_get_sell_value(const Joker* joker);
|
||||||
|
|
||||||
JokerObject *joker_object_new(Joker *joker);
|
JokerObject *joker_object_new(Joker *joker);
|
||||||
void joker_object_destroy(JokerObject **joker_object);
|
void joker_object_destroy(JokerObject **joker_object);
|
||||||
|
|||||||
+94
-32
@@ -91,13 +91,6 @@ static int deck_top = -1;
|
|||||||
static Card *discard_pile[MAX_DECK_SIZE] = {NULL};
|
static Card *discard_pile[MAX_DECK_SIZE] = {NULL};
|
||||||
static int discard_top = -1;
|
static int discard_top = -1;
|
||||||
|
|
||||||
// Joker stack using List
|
|
||||||
static inline void joker_push(JokerObject *joker)
|
|
||||||
{
|
|
||||||
if (list_get_size(jokers) >= MAX_JOKERS_HELD_SIZE) return;
|
|
||||||
list_append(jokers, joker);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Played stack
|
// Played stack
|
||||||
static inline void played_push(CardObject *card_object)
|
static inline void played_push(CardObject *card_object)
|
||||||
{
|
{
|
||||||
@@ -229,6 +222,9 @@ static const Rect ROUND_END_NUM_HANDS_RECT = {88, 116, UNDEFINED, UNDEF
|
|||||||
static const Rect HAND_REWARD_RECT = {168, UNDEFINED, UNDEFINED, UNDEFINED };
|
static const Rect HAND_REWARD_RECT = {168, UNDEFINED, UNDEFINED, UNDEFINED };
|
||||||
static const Rect CASHOUT_RECT = {88, 72, UNDEFINED, UNDEFINED };
|
static const Rect CASHOUT_RECT = {88, 72, UNDEFINED, UNDEFINED };
|
||||||
static const Rect SHOP_REROLL_RECT = {88, 96, UNDEFINED, UNDEFINED };
|
static const Rect SHOP_REROLL_RECT = {88, 96, UNDEFINED, UNDEFINED };
|
||||||
|
|
||||||
|
static const BG_POINT HELD_JOKERS_POS = {108, 10};
|
||||||
|
|
||||||
#define ITEM_SHOP_Y 71 // TODO: Needs to be a rect?
|
#define ITEM_SHOP_Y 71 // TODO: Needs to be a rect?
|
||||||
|
|
||||||
//TODO: Properly define and use
|
//TODO: Properly define and use
|
||||||
@@ -1782,15 +1778,13 @@ static void held_jokers_update_loop()
|
|||||||
{40, 20, 0, -20, -40}
|
{40, 20, 0, -20, -40}
|
||||||
};
|
};
|
||||||
|
|
||||||
FIXED hand_x = int2fx(108);
|
FIXED hand_x = int2fx(HELD_JOKERS_POS.x);
|
||||||
FIXED hand_y = int2fx(10);
|
|
||||||
|
|
||||||
int jokers_top = list_get_size(jokers) - 1;
|
int jokers_top = list_get_size(jokers) - 1;
|
||||||
for (int i = jokers_top; i >= 0; i--)
|
for (int i = jokers_top; i >= 0; i--)
|
||||||
{
|
{
|
||||||
JokerObject *joker = list_get(jokers, i);
|
JokerObject *joker = list_get(jokers, i);
|
||||||
joker->sprite_object->tx = hand_x - int2fx(spacing_lut[jokers_top][i]);
|
joker->sprite_object->tx = hand_x - int2fx(spacing_lut[jokers_top][i]);
|
||||||
joker->sprite_object->ty = hand_y;
|
|
||||||
|
|
||||||
joker_object_update(joker);
|
joker_object_update(joker);
|
||||||
}
|
}
|
||||||
@@ -2147,6 +2141,25 @@ static int reroll_cost = REROLL_BASE_COST;
|
|||||||
#define REROLL_BTN_FRAME_PAL_IDX 7
|
#define REROLL_BTN_FRAME_PAL_IDX 7
|
||||||
#define REROLL_BTN_PAL_IDX 3
|
#define REROLL_BTN_PAL_IDX 3
|
||||||
|
|
||||||
|
void print_price_under_sprite_object(SpriteObject *sprite_object, int price)
|
||||||
|
{
|
||||||
|
int x = fx2int(sprite_object->tx) + TILE_SIZE - (get_digits_even(price) - 1) * TILE_SIZE;
|
||||||
|
int y = fx2int(sprite_object->ty) + CARD_SPRITE_SIZE + TILE_SIZE; // TODO: Should probably extract the sprite size
|
||||||
|
tte_printf("#{P:%d,%d; cx:0xC000}$%d", x, y, price);
|
||||||
|
}
|
||||||
|
|
||||||
|
void erase_price_under_sprite_object(SpriteObject *sprite_object)
|
||||||
|
{
|
||||||
|
Rect price_rect;
|
||||||
|
price_rect.left = fx2int(sprite_object->tx);
|
||||||
|
price_rect.top = fx2int(sprite_object->ty) + CARD_SPRITE_SIZE + TILE_SIZE;
|
||||||
|
// TODO: Should probably extract the size from the sprite
|
||||||
|
|
||||||
|
price_rect.right = price_rect.left + TILE_SIZE * 3;
|
||||||
|
price_rect.bottom = price_rect.top + 2*TILE_SIZE; // Taking 2 tiles down so the highlighted case is also covered
|
||||||
|
tte_erase_rect_wrapper(price_rect);
|
||||||
|
}
|
||||||
|
|
||||||
static void game_shop_create_items()
|
static void game_shop_create_items()
|
||||||
{
|
{
|
||||||
tte_erase_rect_wrapper(SHOP_PRICES_TEXT_RECT);
|
tte_erase_rect_wrapper(SHOP_PRICES_TEXT_RECT);
|
||||||
@@ -2172,9 +2185,7 @@ static void game_shop_create_items()
|
|||||||
joker_object->sprite_object->tx = joker_object->sprite_object->x;
|
joker_object->sprite_object->tx = joker_object->sprite_object->x;
|
||||||
joker_object->sprite_object->ty = int2fx(ITEM_SHOP_Y);
|
joker_object->sprite_object->ty = int2fx(ITEM_SHOP_Y);
|
||||||
|
|
||||||
int x = fx2int(joker_object->sprite_object->tx) + TILE_SIZE - (get_digits_even(joker_object->joker->value) - 1) * TILE_SIZE;
|
print_price_under_sprite_object(joker_object->sprite_object, joker_object->joker->value);
|
||||||
int y = fx2int(joker_object->sprite_object->ty) + CARD_SPRITE_SIZE + TILE_SIZE;
|
|
||||||
tte_printf("#{P:%d,%d; cx:0xC000}$%d", x, y, joker_object->joker->value);
|
|
||||||
|
|
||||||
sprite_position(joker_object_get_sprite(joker_object), fx2int(joker_object->sprite_object->x), fx2int(joker_object->sprite_object->y));
|
sprite_position(joker_object_get_sprite(joker_object), fx2int(joker_object->sprite_object->x), fx2int(joker_object->sprite_object->y));
|
||||||
list_append(shop_jokers, joker_object);
|
list_append(shop_jokers, joker_object);
|
||||||
@@ -2247,28 +2258,80 @@ static void game_shop_reroll(int *reroll_cost)
|
|||||||
tte_printf("#{P:%d,%d; cx:0xF000}$%d", SHOP_REROLL_RECT.left, SHOP_REROLL_RECT.top, *reroll_cost);
|
tte_printf("#{P:%d,%d; cx:0xF000}$%d", SHOP_REROLL_RECT.left, SHOP_REROLL_RECT.top, *reroll_cost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int jokers_sel_row_get_size()
|
||||||
|
{
|
||||||
|
return list_get_size(jokers);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void jokers_sel_row_on_selection_changed(SelectionGrid *selection_grid,
|
||||||
|
int row_idx,
|
||||||
|
const Selection *prev_selection,
|
||||||
|
const Selection *new_selection)
|
||||||
|
{
|
||||||
|
if (prev_selection->y == row_idx)
|
||||||
|
{
|
||||||
|
JokerObject* joker_object = list_get(jokers, prev_selection->x);
|
||||||
|
erase_price_under_sprite_object(joker_object->sprite_object);
|
||||||
|
sprite_object_set_focus(joker_object->sprite_object, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_selection->y == row_idx)
|
||||||
|
{
|
||||||
|
JokerObject* joker_object = list_get(jokers, new_selection->x);
|
||||||
|
sprite_object_set_focus(joker_object->sprite_object, true);
|
||||||
|
print_price_under_sprite_object(joker_object->sprite_object, joker_get_sell_value(joker_object->joker));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void game_sell_joker(int joker_idx)
|
||||||
|
{
|
||||||
|
if (joker_idx < 0 || joker_idx > list_get_size(jokers))
|
||||||
|
return;
|
||||||
|
|
||||||
|
JokerObject *joker_object = list_get(jokers, joker_idx);
|
||||||
|
money += joker_get_sell_value(joker_object->joker);
|
||||||
|
display_money(money);
|
||||||
|
erase_price_under_sprite_object(joker_object->sprite_object);
|
||||||
|
|
||||||
|
list_remove_by_idx(jokers, joker_idx);
|
||||||
|
int_list_append(jokers_available_to_shop, (intptr_t)joker_object->joker->id);
|
||||||
|
|
||||||
|
// TODO: Discard animation
|
||||||
|
joker_object_destroy(&joker_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void jokers_sel_row_on_key_hit(SelectionGrid* selection_grid, Selection* selection)
|
||||||
|
{
|
||||||
|
if (!key_hit(SELL_KEY))
|
||||||
|
return;
|
||||||
|
|
||||||
|
game_sell_joker(selection->x);
|
||||||
|
// Move the selection away from the jokers so it doesn't point to an invalid place
|
||||||
|
selection_grid_move_selection_vert(selection_grid, SCREEN_DOWN);
|
||||||
|
}
|
||||||
|
|
||||||
// Shop input
|
// Shop input
|
||||||
static int shop_top_row_get_size()
|
static int shop_top_row_get_size()
|
||||||
{
|
{
|
||||||
return list_get_size(shop_jokers) + 1; // + 1 to account for next round button
|
return list_get_size(shop_jokers) + 1; // + 1 to account for next round button
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_joker(JokerObject *joker_object)
|
||||||
|
{
|
||||||
|
list_append(jokers, joker_object);
|
||||||
|
joker_object->sprite_object->ty = int2fx(HELD_JOKERS_POS.y);
|
||||||
|
}
|
||||||
|
|
||||||
static void game_shop_buy_joker(int shop_joker_idx)
|
static void game_shop_buy_joker(int shop_joker_idx)
|
||||||
{
|
{
|
||||||
JokerObject *joker_object = list_get(shop_jokers, shop_joker_idx);
|
JokerObject *joker_object = list_get(shop_jokers, shop_joker_idx);
|
||||||
joker_push(joker_object);
|
|
||||||
money -= joker_object->joker->value; // Deduct the money spent on the joker
|
money -= joker_object->joker->value; // Deduct the money spent on the joker
|
||||||
display_money(money); // Update the money display
|
display_money(money); // Update the money display
|
||||||
|
erase_price_under_sprite_object(joker_object->sprite_object);
|
||||||
|
sprite_object_set_focus(joker_object->sprite_object, false);
|
||||||
|
|
||||||
Rect joker_price_rect;
|
add_joker(joker_object);
|
||||||
joker_price_rect.left = fx2int(joker_object->sprite_object->tx);
|
|
||||||
// 2*TILE_SIZE because the item is highlighted and raised by 1 additional tile
|
|
||||||
joker_price_rect.top = fx2int(joker_object->sprite_object->ty) + CARD_SPRITE_SIZE + 2 * TILE_SIZE;
|
|
||||||
joker_price_rect.right = joker_price_rect.left + TILE_SIZE * 3;
|
|
||||||
joker_price_rect.bottom = joker_price_rect.top + TILE_SIZE;
|
|
||||||
|
|
||||||
tte_erase_rect_wrapper(joker_price_rect);
|
|
||||||
|
|
||||||
list_remove_by_idx(shop_jokers, shop_joker_idx); // Remove the joker from the shop
|
list_remove_by_idx(shop_jokers, shop_joker_idx); // Remove the joker from the shop
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2347,12 +2410,12 @@ static void shop_top_row_on_selection_changed(SelectionGrid* selection_grid, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int shop_bottom_row_get_size()
|
static int shop_reroll_row_get_size()
|
||||||
{
|
{
|
||||||
return 1; // Currently only the reroll button
|
return 1; // Only the reroll button
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shop_bottom_row_on_selection_changed(SelectionGrid* selection_grid, int row_idx, const Selection* prev_selection, const Selection* new_selection)
|
static void shop_reroll_row_on_selection_changed(SelectionGrid* selection_grid, int row_idx, const Selection* prev_selection, const Selection* new_selection)
|
||||||
{
|
{
|
||||||
if (row_idx == prev_selection->y)
|
if (row_idx == prev_selection->y)
|
||||||
{
|
{
|
||||||
@@ -2365,7 +2428,7 @@ static void shop_bottom_row_on_selection_changed(SelectionGrid* selection_grid,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shop_bottom_row_on_key_hit(SelectionGrid* selection_grid, Selection* selection)
|
static void shop_reroll_row_on_key_hit(SelectionGrid* selection_grid, Selection* selection)
|
||||||
{
|
{
|
||||||
if (money >= reroll_cost)
|
if (money >= reroll_cost)
|
||||||
{
|
{
|
||||||
@@ -2375,11 +2438,12 @@ static void shop_bottom_row_on_key_hit(SelectionGrid* selection_grid, Selection*
|
|||||||
|
|
||||||
SelectionGridRow shop_selection_rows[] =
|
SelectionGridRow shop_selection_rows[] =
|
||||||
{
|
{
|
||||||
{0, shop_top_row_get_size, shop_top_row_on_selection_changed, shop_top_row_on_key_hit},
|
{0, jokers_sel_row_get_size, jokers_sel_row_on_selection_changed, jokers_sel_row_on_key_hit},
|
||||||
{1, shop_bottom_row_get_size, shop_bottom_row_on_selection_changed, shop_bottom_row_on_key_hit}
|
{1, shop_top_row_get_size, shop_top_row_on_selection_changed, shop_top_row_on_key_hit},
|
||||||
|
{2, shop_reroll_row_get_size, shop_reroll_row_on_selection_changed, shop_reroll_row_on_key_hit}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const Selection SHOP_INIT_SEL = {-1, 0};
|
static const Selection SHOP_INIT_SEL = {-1, 1};
|
||||||
|
|
||||||
SelectionGrid shop_selection_grid = {shop_selection_rows, NUM_ELEM_IN_ARR(shop_selection_rows), SHOP_INIT_SEL};
|
SelectionGrid shop_selection_grid = {shop_selection_rows, NUM_ELEM_IN_ARR(shop_selection_rows), SHOP_INIT_SEL};
|
||||||
|
|
||||||
@@ -2530,8 +2594,6 @@ void game_shop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void game_blind_select()
|
void game_blind_select()
|
||||||
{
|
{
|
||||||
switch (state) // I'm only using magic numbers here for the sake of simplicity since it's just sequential, but you can replace them with named constants or enums if it makes it clearer
|
switch (state) // I'm only using magic numbers here for the sake of simplicity since it's just sequential, but you can replace them with named constants or enums if it makes it clearer
|
||||||
|
|||||||
+10
-1
@@ -181,6 +181,16 @@ JokerEffect joker_get_score_effect(Joker *joker, Card *scored_card)
|
|||||||
return jinfo->effect(joker, scored_card);
|
return jinfo->effect(joker, scored_card);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int joker_get_sell_value(const Joker* joker)
|
||||||
|
{
|
||||||
|
if (joker == NULL)
|
||||||
|
{
|
||||||
|
return UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return joker->value/2;
|
||||||
|
}
|
||||||
|
|
||||||
// JokerObject methods
|
// JokerObject methods
|
||||||
JokerObject *joker_object_new(Joker *joker)
|
JokerObject *joker_object_new(Joker *joker)
|
||||||
{
|
{
|
||||||
@@ -320,7 +330,6 @@ bool joker_object_score(JokerObject *joker_object, Card* scored_card, int *chips
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void joker_object_set_selected(JokerObject* joker_object, bool selected)
|
void joker_object_set_selected(JokerObject* joker_object, bool selected)
|
||||||
{
|
{
|
||||||
if (joker_object == NULL)
|
if (joker_object == NULL)
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ void selection_grid_move_selection_vert(SelectionGrid *selection_grid, int direc
|
|||||||
&& new_selection.y < selection_grid->num_rows)
|
&& new_selection.y < selection_grid->num_rows)
|
||||||
{
|
{
|
||||||
int new_row_size = selection_grid->rows[new_selection.y].get_size();
|
int new_row_size = selection_grid->rows[new_selection.y].get_size();
|
||||||
|
if (new_row_size <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (selection.x >= new_row_size)
|
if (selection.x >= new_row_size)
|
||||||
{
|
{
|
||||||
// TODO: Maintain relative horizontal position
|
// TODO: Maintain relative horizontal position
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ SpriteObject* sprite_object_new()
|
|||||||
sprite_object->sprite = NULL;
|
sprite_object->sprite = NULL;
|
||||||
sprite_object_reset_transform(sprite_object);
|
sprite_object_reset_transform(sprite_object);
|
||||||
sprite_object->selected = false;
|
sprite_object->selected = false;
|
||||||
|
sprite_object->focused = false;
|
||||||
|
|
||||||
return sprite_object;
|
return sprite_object;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user