167 lines
4.3 KiB
C
167 lines
4.3 KiB
C
#include <assert.h>
|
|
#include "art/game_hud.h"
|
|
#include "art/game_npcs.h"
|
|
#include "device/device.h"
|
|
#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;
|
|
|
|
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}
|
|
};
|
|
|
|
#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,
|
|
.flip = false,
|
|
|
|
.n_dialogues = 0,
|
|
.no_cake_dialogue = NULL,
|
|
/* .dialogues = { doesn't matter }, */
|
|
|
|
.present = true,
|
|
.n_dialogues_seen = 0,
|
|
.received_cake = false,
|
|
};
|
|
game_npcs[id] = npc;
|
|
return &game_npcs[id];
|
|
}
|
|
|
|
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];
|
|
|
|
if (
|
|
!npc->received_cake &&
|
|
game_player_collectibles.n_cake <= 0 &&
|
|
npc->no_cake_dialogue != NULL
|
|
) {
|
|
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;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
game_dialogue_display(dialogue);
|
|
}
|
|
|
|
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 =
|
|
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
|
|
);
|
|
}
|
|
|
|
sys_dpal_set(14, palette.main);
|
|
sys_dpal_set(13, palette.alt0_0);
|
|
sys_dpal_set(12, palette.alt0_1);
|
|
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,
|
|
n->flip
|
|
);
|
|
|
|
sys_dpal_reset();
|
|
}
|
|
} |