mirror of
https://git.planet-casio.com/Slyvtt/Collab_RPG.git
synced 2024-12-29 13:03:43 +01:00
npc : Ajout de npc_stack et réecriture des fonctions + Résolution de warnings
This commit is contained in:
parent
6c47d5d83c
commit
fd28af1005
5 changed files with 125 additions and 61 deletions
|
@ -1,5 +1,9 @@
|
|||
#include "events.h"
|
||||
|
||||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h> /*debug*/
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -17,9 +21,9 @@ int events_bind_variable(EventHandler *handler, int *var, char *name) {
|
|||
|
||||
char op_chars[OP_AMOUNT + 1] = " =+-/*%";
|
||||
|
||||
int _op_null(int a, int b) { return 0; }
|
||||
int _op_null(GUNUSED int a, GUNUSED int b) { return 0; }
|
||||
|
||||
int _op_set(int a, int b) { return b; }
|
||||
int _op_set(GUNUSED int a, int b) { return b; }
|
||||
|
||||
int _op_add(int a, int b) { return a + b; }
|
||||
|
||||
|
|
40
src/game.c
40
src/game.c
|
@ -84,14 +84,14 @@ void game_render_indicator(Game *game) {
|
|||
/* nothing to do for the player so we quit */
|
||||
if(game->player.canDoSomething)
|
||||
dimage(5, 5, &SignAction_img);
|
||||
int i;
|
||||
uint32_t i;
|
||||
Player *player = &game->player;
|
||||
for(i = 0; i < game->map_level->nbPortal; i++) {
|
||||
Portal *portal = &game->map_level->portals[i];
|
||||
if(player->x >= portal->collider.x1 * PXSIZE &&
|
||||
player->x < portal->collider.x2 * PXSIZE &&
|
||||
player->y >= portal->collider.y1 * PXSIZE &&
|
||||
player->y < portal->collider.y2 * PXSIZE) {
|
||||
if(player->x >= (int)portal->collider.x1 * PXSIZE &&
|
||||
player->x < (int)portal->collider.x2 * PXSIZE &&
|
||||
player->y >= (int)portal->collider.y1 * PXSIZE &&
|
||||
player->y < (int)portal->collider.y2 * PXSIZE) {
|
||||
dimage(5, 5, &SignAction_img);
|
||||
break;
|
||||
}
|
||||
|
@ -107,7 +107,8 @@ void game_draw(Game *game) {
|
|||
map_render_by_layer(game, FOREGROUND);
|
||||
game_render_indicator(game);
|
||||
/*DEBUG*/
|
||||
dprint(8, 8, C_BLACK, "Lifes: %d", game->player.life);
|
||||
extern uint32_t npc_count;
|
||||
dprint(8, 8, C_BLACK, "npc_count: %d", npc_count);
|
||||
dprint(8, 16, C_BLACK, "Mana: %d", game->mana);
|
||||
dprint(8, 24, C_BLACK, "X: %d Y: %d", game->player.x, game->player.y);
|
||||
}
|
||||
|
@ -145,13 +146,13 @@ void game_get_inputs(Game *game) {
|
|||
}
|
||||
Player *player = &game->player;
|
||||
if(keydown(KEY_SHIFT)) {
|
||||
int i;
|
||||
uint32_t i;
|
||||
for(i = 0; i < game->map_level->nbPortal; i++) {
|
||||
Portal *portal = &game->map_level->portals[i];
|
||||
if(player->x >= portal->collider.x1 * PXSIZE &&
|
||||
player->x < portal->collider.x2 * PXSIZE &&
|
||||
player->y >= portal->collider.y1 * PXSIZE &&
|
||||
player->y < portal->collider.y2 * PXSIZE) {
|
||||
if(player->x >= (int)portal->collider.x1 * PXSIZE &&
|
||||
player->x < (int)portal->collider.x2 * PXSIZE &&
|
||||
player->y >= (int)portal->collider.y1 * PXSIZE &&
|
||||
player->y < (int)portal->collider.y2 * PXSIZE) {
|
||||
Portal *dest_portal = (Portal *)portal->portal;
|
||||
Collider dest_collider = dest_portal->collider;
|
||||
Map *dest_map = (Map *)portal->map;
|
||||
|
@ -167,6 +168,23 @@ void game_get_inputs(Game *game) {
|
|||
}
|
||||
}
|
||||
|
||||
/*Temp debug*/
|
||||
if(keydown(KEY_F1)) {
|
||||
NPC *mynpc = npc_create();
|
||||
if(mynpc) {
|
||||
mynpc->curx = player->x;
|
||||
mynpc->cury = player->y;
|
||||
mynpc->x = 0;
|
||||
mynpc->y = 0;
|
||||
mynpc->hasPath = 0;
|
||||
mynpc->face = 0;
|
||||
mynpc->paused = 0;
|
||||
mynpc->has_dialog = 0;
|
||||
dprint(0, 50, 0, "succes");
|
||||
dupdate();
|
||||
}
|
||||
}
|
||||
|
||||
/* Display Debug Information on screen */
|
||||
#if DEBUGMODE
|
||||
if(keydown(KEY_F1)) {
|
||||
|
|
91
src/npc.c
91
src/npc.c
|
@ -16,8 +16,29 @@ extern bopti_image_t tiny_npc_female;
|
|||
extern bopti_image_t tiny_npc_milkman;
|
||||
extern bopti_image_t tiny_npc_police;
|
||||
|
||||
// NPC *npcRPG;
|
||||
// uint32_t nbNPC = 0;
|
||||
#define NPC_STACK_SIZE 256
|
||||
|
||||
NPC npc_stack[NPC_STACK_SIZE];
|
||||
uint32_t npc_count;
|
||||
|
||||
NPC *npc_create() {
|
||||
if(npc_count == 256)
|
||||
return NULL;
|
||||
|
||||
return &npc_stack[npc_count++];
|
||||
}
|
||||
|
||||
void npc_remove(NPC *npc) {
|
||||
uint32_t pos = (uint32_t)npc - (uint32_t)npc_stack;
|
||||
|
||||
if(pos == npc_count) {
|
||||
npc_count--;
|
||||
return;
|
||||
}
|
||||
memmove(npc, npc + sizeof(NPC), sizeof(NPC) * (npc_count - pos));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float length(float x, float y) { return sqrtf(x * x + y * y); }
|
||||
|
||||
|
@ -51,6 +72,7 @@ void as_clean(uint8_t *visited, uint8_t *gscore, uint8_t *fscore) {
|
|||
free(fscore);
|
||||
}
|
||||
|
||||
// TODO : Fix
|
||||
int as_reconstruct_path(int16_t *came_from, int w, int h, int16_t spos,
|
||||
int16_t dest, NPC *npc) {
|
||||
if(npc_clear_path(npc))
|
||||
|
@ -100,9 +122,8 @@ as_recons_fail:
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Returns non zero error code on failure
|
||||
// Custom a* implemetation
|
||||
// Unoptimized, may become an issue
|
||||
/* Custom a* implemetation
|
||||
* Unoptimized, may become an issue */
|
||||
int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
|
||||
int32_t i, j;
|
||||
|
||||
|
@ -150,7 +171,8 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
|
|||
|
||||
for(int iter = 0; iter < 64; iter++) {
|
||||
bscore = 255;
|
||||
// Cheapest known tile
|
||||
/* Cheapest known tile */
|
||||
/* Could be improved with a priority queue*/
|
||||
for(i = 0; i <= w * h; i++) {
|
||||
if(visited[i])
|
||||
continue;
|
||||
|
@ -203,8 +225,12 @@ int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc) {
|
|||
|
||||
// Refactoring to make adding complexity cleaner
|
||||
void update_npcs(Game *game) {
|
||||
for(uint32_t u = 0; u < game->map_level->nbNPC; u++) {
|
||||
update_npc(&game->map_level->npcs[u]);
|
||||
uint32_t i;
|
||||
for(i = 0; i < game->map_level->nbNPC; i++) {
|
||||
update_npc(&game->map_level->npcs[i]);
|
||||
}
|
||||
for(i = 0; i < npc_count; i++) {
|
||||
update_npc(&npc_stack[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,45 +257,52 @@ void update_npc(NPC *npc) {
|
|||
npc->cury += vecY * (float)(1 << PRECISION);
|
||||
}
|
||||
|
||||
void npc_draw(Game *game) {
|
||||
Player *pl = &game->player;
|
||||
size_t i;
|
||||
const bopti_image_t *npc_sprites[FACES] = {
|
||||
&tiny_npc_male, &tiny_npc_female, &tiny_npc_milkman, &tiny_npc_police};
|
||||
bopti_image_t *npc_sprites[FACES] = {&tiny_npc_male, &tiny_npc_female,
|
||||
&tiny_npc_milkman, &tiny_npc_police};
|
||||
|
||||
for(uint32_t u = 0; u < game->map_level->nbNPC; u++) {
|
||||
NPC *Data = &game->map_level->npcs[u];
|
||||
void npc_draw_single(NPC *npc, Player *pl) {
|
||||
|
||||
/* Render the path if in debug*/
|
||||
/* Render the path if in debug and it has one*/
|
||||
#if DEBUGMODE
|
||||
if(!Data->hasPath)
|
||||
continue; /* this NPC has a trajectory */
|
||||
int NbPoints = Data->path_length + 1;
|
||||
if(npc->hasPath) {
|
||||
int NbPoints = npc->path_length + 1;
|
||||
for(int v = 0; v < NbPoints; v++) {
|
||||
|
||||
int16_t deltaX1 =
|
||||
((int16_t)(Data->x + Data->xpath[v % NbPoints]) * PXSIZE) -
|
||||
((int16_t)(npc->x + npc->xpath[v % NbPoints]) * PXSIZE) -
|
||||
(int16_t)pl->wx;
|
||||
int16_t deltaY1 =
|
||||
((int16_t)(Data->y + Data->ypath[v % NbPoints]) * PXSIZE) -
|
||||
((int16_t)(npc->y + npc->ypath[v % NbPoints]) * PXSIZE) -
|
||||
(int16_t)pl->wy;
|
||||
int16_t deltaX2 =
|
||||
((int16_t)(Data->x + Data->xpath[(v + 1) % NbPoints]) *
|
||||
PXSIZE) -
|
||||
((int16_t)(npc->x + npc->xpath[(v + 1) % NbPoints]) * PXSIZE) -
|
||||
(int16_t)pl->wx;
|
||||
int16_t deltaY2 =
|
||||
((int16_t)(Data->y + Data->ypath[(v + 1) % NbPoints]) *
|
||||
PXSIZE) -
|
||||
((int16_t)(npc->y + npc->ypath[(v + 1) % NbPoints]) * PXSIZE) -
|
||||
(int16_t)pl->wy;
|
||||
|
||||
dline(pl->px + deltaX1, pl->py + deltaY1, pl->px + deltaX2,
|
||||
pl->py + deltaY2, PATH_COLOR);
|
||||
}
|
||||
#endif // DEBUGMODE
|
||||
}
|
||||
#endif /* DEBUGMODE */
|
||||
|
||||
int16_t delX = ((Data->curx * PXSIZE) >> PRECISION) - (int16_t)pl->x;
|
||||
int16_t delY = ((Data->cury * PXSIZE) >> PRECISION) - (int16_t)pl->y;
|
||||
bopti_image_t *face = npc_sprites[Data->face];
|
||||
int16_t delX = ((npc->curx * PXSIZE) >> PRECISION) - (int16_t)pl->x;
|
||||
int16_t delY = ((npc->cury * PXSIZE) >> PRECISION) - (int16_t)pl->y;
|
||||
bopti_image_t *face = npc_sprites[npc->face];
|
||||
dimage(pl->px - P_WIDTH / 2 + delX, pl->py - P_HEIGHT / 2 + delY, face);
|
||||
}
|
||||
|
||||
void npc_draw(Game *game) {
|
||||
Player *pl = &game->player;
|
||||
|
||||
uint32_t u;
|
||||
for(u = 0; u < game->map_level->nbNPC; u++) {
|
||||
npc_draw_single(&game->map_level->npcs[u], pl);
|
||||
}
|
||||
for(u = 0; u < npc_count; u++) {
|
||||
npc_draw_single(&npc_stack[u], pl);
|
||||
}
|
||||
}
|
||||
|
||||
void npc_reload(GUNUSED Game *game) { npc_count = 0; }
|
||||
|
|
43
src/npc.h
43
src/npc.h
|
@ -16,34 +16,41 @@ enum {
|
|||
|
||||
};
|
||||
|
||||
// Frees then malloc()s a new path to npc
|
||||
// Useful if you want to safely edit a path
|
||||
int npc_clear_path(NPC *npc);
|
||||
/* /!\ Warning /!\
|
||||
* Do not keep hard references to non-static NPCs, as they will likely move
|
||||
* in the stack */
|
||||
|
||||
// Adds point x,y to the path of npc
|
||||
// Won't work on static NPCs, use npc_clear_path before or make them on the heap
|
||||
int npc_append_path(uint16_t x, uint16_t y, NPC *npc);
|
||||
|
||||
// Clears the NPCs path and creates a new one going to dest,
|
||||
// avoiding non-walkable tiles
|
||||
// Returns non-zero on failure
|
||||
int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc);
|
||||
|
||||
// realloc()s npcRPG to adequate size and returns a pointer to the new element
|
||||
// Returns NULL on failure
|
||||
/* Creates a new NPC in the NPC stack (Needs to be set to valid values !)
|
||||
* Returns NULL on failure */
|
||||
NPC *npc_create();
|
||||
|
||||
// Pops the NPC from npcRPG
|
||||
/* Pops the NPC from the NPC stack
|
||||
* Consider this as a free */
|
||||
void npc_remove(NPC *npc);
|
||||
|
||||
/* Frees then malloc()s a new path to npc
|
||||
* Useful if you want to safely edit a path */
|
||||
int npc_clear_path(NPC *npc);
|
||||
|
||||
/* Adds point x,y to the path of npc
|
||||
* Won't work on static NPCs, use npc_clear_path before or make them on the
|
||||
* heap */
|
||||
int npc_append_path(uint16_t x, uint16_t y, NPC *npc);
|
||||
|
||||
/* Clears the NPCs path and creates a new one going to dest,
|
||||
* avoiding non-walkable tiles
|
||||
* Returns non-zero on failure */
|
||||
int npc_pathfind(int32_t dest_x, int32_t dest_y, Map *full_map, NPC *npc);
|
||||
|
||||
/* Draws the player player. This function should be called after drawing the
|
||||
* map! */
|
||||
void npc_draw(Game *game);
|
||||
|
||||
/* Updates the static NPCs and the NPC stack */
|
||||
void update_npcs(Game *game);
|
||||
|
||||
/* Updates the singular NPC npc. Be careful with it ! */
|
||||
void update_npc(NPC *npc);
|
||||
|
||||
void reload_npc(Game *game);
|
||||
/* Inits/Clears the NPC stack*/
|
||||
void npc_reload(Game *game);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -106,6 +106,8 @@ void player_move(Game *game, Direction direction) {
|
|||
if(target->y < game->map_level->y) {
|
||||
player->y = target->h * T_HEIGHT;
|
||||
}
|
||||
npc_reload(game);
|
||||
|
||||
game->map_level = target;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue