crocparty/game/game_npc.c

171 lines
4.4 KiB
C
Raw Permalink Normal View History

2024-02-29 03:42:03 +00:00
#include <assert.h>
2024-02-29 20:08:50 +00:00
#include "art/game_hud.h"
2024-02-29 03:42:03 +00:00
#include "art/game_npcs.h"
2024-02-29 05:07:17 +00:00
#include "device/device.h"
2024-02-29 03:42:03 +00:00
#include "sys/sys.h"
#include "game.h"
// If this isn't enough, raise the number
#define GAME_NPCS_N 32
typedef struct {
uint8_t main;
// alt0 and alt1 are ramps
uint8_t alt0_0; uint8_t alt0_1;
uint8_t alt1_0; uint8_t alt1_1;
uint8_t eye_0; uint8_t eye_1;
uint8_t pupil;
uint8_t adornment;
uint8_t shine;
} game_npc_palette;
2024-02-29 21:20:18 +00:00
game_npc_palette game_npc_palettes[5] = {
{14, 13, 12, 6, 7, 6, 7, 0, 8, 7},
{4, 2, 3, 6, 7, 9, 10, 0, 4, 7},
{13, 0, 1, 1, 13, 11, 10, 0, 13, 7},
{7, 14, 7, 14, 7, 14, 7, 0, 14, 7},
{12, 1, 13, 12, 6, 8, 7, 0, 8, 7}
2024-02-29 03:42:03 +00:00
};
#define GAME_NPC_N_PALETTES (sizeof(game_npc_palettes)/sizeof(game_npc_palettes[0]))
sys_i32 game_npc_next = 0;
game_npc game_npcs[GAME_NPCS_N];
game_npc* game_npc_create(sys_i32 x, sys_i32 y) {
assert(game_npc_next < GAME_NPCS_N && "too many NPCs");
sys_i32 id = game_npc_next++;
game_npc npc = {
.x = x,
.y = y,
.sprite_id = 0,
.palette_id = 0,
.inflict_id = 0,
.face_left = false,
2024-02-29 21:20:18 +00:00
.flip = false,
2024-02-29 03:42:03 +00:00
.n_dialogues = 0,
.no_cake_dialogue = NULL,
/* .dialogues = { doesn't matter }, */
.present = true,
.n_dialogues_seen = 0,
2024-02-29 20:08:50 +00:00
.received_cake = false,
2024-02-29 03:42:03 +00:00
};
game_npcs[id] = npc;
return &game_npcs[id];
}
2024-02-29 05:07:17 +00:00
void game_npc_trigger_dialogue(sys_i32 npc_id);
void game_npcs_update(bool* allow_input) {
if (!*allow_input) { return; }
// check collision with player
sys_i32 player_x, player_y;
game_player_get_center(&player_x, &player_y);
for (sys_i32 i = 0; i < game_npc_next; i++) {
game_npc* n = &game_npcs[i];
if (!n->present) { continue; }
sys_i32 r_distcheck = 21 * PIXEL_SZ_MICROPIXEL;
int64_t dx = player_x - n->x;
int64_t dy = player_y - n->y;
if (
sys_btnp(DEVICE_BUTTON_0, false) &&
dx * dx + dy * dy <= r_distcheck * r_distcheck
) {
n->face_left = dx < 0;
game_npc_trigger_dialogue(i);
*allow_input = false;
}
}
}
void game_npc_trigger_dialogue(sys_i32 npc_id) {
const char* dialogue;
// TODO: Make it possible for the player to have the cake
game_npc* npc = &game_npcs[npc_id];
2024-02-29 20:08:50 +00:00
if (
!npc->received_cake &&
2024-02-29 21:20:18 +00:00
game_player_collectibles.n_cake <= 0 &&
2024-02-29 20:08:50 +00:00
npc->no_cake_dialogue != NULL
) {
2024-02-29 05:07:17 +00:00
dialogue = npc->no_cake_dialogue;
} else if (npc->n_dialogues_seen < npc->n_dialogues) {
dialogue = npc->dialogues[npc->n_dialogues_seen++];
} else if (npc->n_dialogues > 0) {
dialogue = npc->dialogues[npc->n_dialogues - 1];
} else {
// nothing to do with this npc
return;
}
2024-02-29 20:08:50 +00:00
// give the NPC cake if possible
if (!npc->received_cake && game_player_collectibles.n_cake > 0) {
npc->received_cake = true;
game_player_collectibles.n_cake -= 1;
2024-02-29 22:31:44 +00:00
if (npc->inflict_id != 0) {
game_inflict_enqueue(npc->inflict_id);
}
2024-02-29 20:08:50 +00:00
}
2024-02-29 22:31:44 +00:00
game_dialogue_display(dialogue, false);
2024-02-29 03:42:03 +00:00
}
void game_npcs_draw() {
for (sys_i32 i = 0; i < game_npc_next; i++) {
game_npc* n = &game_npcs[i];
if (!n->present) { continue; }
game_npc_palette palette =
2024-02-29 20:08:50 +00:00
game_npc_palettes[n->palette_id % GAME_NPC_N_PALETTES];
if (n->received_cake) {
sys_sprite_draw_ext(
spr_game_hud,
0,
n->x / PIXEL_SZ_MICROPIXEL - 4,
n->y / PIXEL_SZ_MICROPIXEL - 18,
1,
1,
!n->face_left,
false
);
}
2024-02-29 03:42:03 +00:00
sys_dpal_set(14, palette.main);
2024-02-29 21:20:18 +00:00
sys_dpal_set(13, palette.alt0_0);
sys_dpal_set(12, palette.alt0_1);
2024-02-29 03:42:03 +00:00
sys_dpal_set(6, palette.alt1_0);
sys_dpal_set(7, palette.alt1_1);
sys_dpal_set(9, palette.eye_0);
sys_dpal_set(10, palette.eye_1);
sys_dpal_set(1, palette.pupil);
sys_dpal_set(8, palette.adornment);
sys_dpal_set(11, palette.shine);
// TODO: Palette
sys_sprite_draw_ext(
spr_game_npcs,
n->sprite_id,
n->x / PIXEL_SZ_MICROPIXEL - 8,
n->y / PIXEL_SZ_MICROPIXEL - 8,
2,
2,
n->face_left,
2024-02-29 21:20:18 +00:00
n->flip
2024-02-29 03:42:03 +00:00
);
sys_dpal_reset();
}
}