mirror of
https://git.planet-casio.com/Slyvtt/Collab_RPG.git
synced 2024-12-29 13:03:43 +01:00
npc : Début d'ajout d'IA
This commit is contained in:
parent
3c6a2faf99
commit
e37bf141c2
6 changed files with 123 additions and 23 deletions
|
@ -309,15 +309,15 @@ def convert_map(input: str, output: str, params: dict, target):
|
||||||
npc_struct += fxconv.u32(i["position"][0])
|
npc_struct += fxconv.u32(i["position"][0])
|
||||||
npc_struct += fxconv.u32(i["position"][1])
|
npc_struct += fxconv.u32(i["position"][1])
|
||||||
npc_struct += fxconv.u16(i["face"])
|
npc_struct += fxconv.u16(i["face"])
|
||||||
npc_struct += fxconv.u8(0)
|
npc_struct += fxconv.u8(0) #paused
|
||||||
npc_struct += fxconv.u8(i["hasDialog"])
|
npc_struct += fxconv.u8(i["hasDialog"])
|
||||||
npc_struct += fxconv.u32(i["dialogID"])
|
npc_struct += fxconv.u32(i["dialogID"])
|
||||||
npc_struct += fxconv.u32(i["needAction"])
|
npc_struct += fxconv.u32(i["needAction"])
|
||||||
npc_struct += fxconv.string(i["name"])
|
npc_struct += fxconv.string(i["name"])
|
||||||
npc_struct += fxconv.u8(len(i["path"]) > 2)
|
npc_struct += fxconv.u8(len(i["path"]) > 2)
|
||||||
npc_struct += fxconv.u8(0)
|
npc_struct += fxconv.u8(0) #owns_path
|
||||||
npc_struct += fxconv.u8(len(i["path"])//2)
|
npc_struct += fxconv.u8(len(i["path"])//2)
|
||||||
npc_struct += fxconv.u8(0)
|
npc_struct += fxconv.u8(0) #current_point
|
||||||
|
|
||||||
xpath = bytes()
|
xpath = bytes()
|
||||||
ypath = bytes()
|
ypath = bytes()
|
||||||
|
@ -330,9 +330,11 @@ def convert_map(input: str, output: str, params: dict, target):
|
||||||
npc_struct += fxconv.ptr(xpath)
|
npc_struct += fxconv.ptr(xpath)
|
||||||
npc_struct += fxconv.ptr(ypath)
|
npc_struct += fxconv.ptr(ypath)
|
||||||
|
|
||||||
npc_struct += fxconv.u32(0) # TODO: Type
|
npc_struct += fxconv.u16(0) # Type - leave as
|
||||||
npc_struct += fxconv.u8(0) # TODO: Group
|
npc_struct += fxconv.u8(0) # TODO: Group
|
||||||
npc_struct += fxconv.u8(0) # TODO: Hostile to
|
npc_struct += fxconv.u8(0) # Hostile to - leave as
|
||||||
|
npc_struct += fxconv.u8(0) # state - leave as
|
||||||
|
npc_struct += fxconv.u8(0) # Padding
|
||||||
npc_struct += fxconv.u16(0) # Padding
|
npc_struct += fxconv.u16(0) # Padding
|
||||||
map_struct += fxconv.ptr(npc_struct)
|
map_struct += fxconv.ptr(npc_struct)
|
||||||
# Load signs
|
# Load signs
|
||||||
|
|
13
src/game.c
13
src/game.c
|
@ -11,18 +11,21 @@
|
||||||
#include <gint/keyboard.h>
|
#include <gint/keyboard.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
extern bopti_image_t SignAction_img;
|
extern bopti_image_t SignAction_img;
|
||||||
extern bopti_image_t player_male_img;
|
extern bopti_image_t player_male_img;
|
||||||
extern bopti_image_t tiny_npc_male;
|
extern bopti_image_t tiny_npc_male;
|
||||||
|
|
||||||
extern Dialog *dialogRPG;
|
extern Dialog *dialogRPG;
|
||||||
// extern NPC *npcRPG;
|
|
||||||
// extern uint32_t nbNPC;
|
|
||||||
|
|
||||||
#define MAX_INTERACTION_DISTANCE 12
|
#define MAX_INTERACTION_DISTANCE 12
|
||||||
|
|
||||||
void game_init(Game *game) {
|
void game_init(Game *game) {
|
||||||
|
/*Seed the stdlib rand() function*/
|
||||||
|
uint32_t randseed = time(NULL);
|
||||||
|
srand(randseed);
|
||||||
|
|
||||||
game->map_level = worldRPG[0];
|
game->map_level = worldRPG[0];
|
||||||
/* NPC animation */
|
/* NPC animation */
|
||||||
animation_new(&game->npc_animation, &tiny_npc_male, 3, 250);
|
animation_new(&game->npc_animation, &tiny_npc_male, 3, 250);
|
||||||
|
@ -279,9 +282,15 @@ void game_get_inputs(Game *game) {
|
||||||
mynpc->xpath = NULL;
|
mynpc->xpath = NULL;
|
||||||
mynpc->ypath = NULL;
|
mynpc->ypath = NULL;
|
||||||
}
|
}
|
||||||
|
while(keydown(KEY_F1)){
|
||||||
|
clearevents();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(keydown(KEY_F2)) {
|
if(keydown(KEY_F2)) {
|
||||||
npc_remove_pos(0);
|
npc_remove_pos(0);
|
||||||
|
while(keydown(KEY_F2)){
|
||||||
|
clearevents();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display Debug Information on screen */
|
/* Display Debug Information on screen */
|
||||||
|
|
|
@ -143,16 +143,21 @@ typedef struct {
|
||||||
|
|
||||||
/* data for NPC's trajectories */
|
/* data for NPC's trajectories */
|
||||||
uint8_t hasPath;
|
uint8_t hasPath;
|
||||||
uint8_t owns_path;
|
uint8_t owns_path; /*If the NPCs path is malloc()ed*/
|
||||||
uint8_t path_length;
|
uint8_t path_length;
|
||||||
uint8_t currentPoint;
|
uint8_t currentPoint;
|
||||||
int16_t *xpath;
|
int16_t *xpath;
|
||||||
int16_t *ypath;
|
int16_t *ypath;
|
||||||
|
|
||||||
int type : 32;
|
/*Should be one of NPC_ - 0 for static NPCs*/
|
||||||
|
uint16_t type;
|
||||||
|
|
||||||
|
/*The follwing should be one of NPC_T*/
|
||||||
uint8_t current_group;
|
uint8_t current_group;
|
||||||
uint8_t hostile_to_group;
|
uint8_t hostile_to_group;
|
||||||
|
/*state should be one of NPC_S*/
|
||||||
|
uint8_t state;
|
||||||
|
uint8_t __temp;
|
||||||
|
|
||||||
/* uint16_t to keep the struct aligned */
|
/* uint16_t to keep the struct aligned */
|
||||||
uint16_t __padding;
|
uint16_t __padding;
|
||||||
|
|
|
@ -124,6 +124,7 @@ int main(void) {
|
||||||
_message_buffer = NULL;
|
_message_buffer = NULL;
|
||||||
_message_buffer = malloc(MESSAGE_BUFFER_SZ);
|
_message_buffer = malloc(MESSAGE_BUFFER_SZ);
|
||||||
if(!_message_buffer) {
|
if(!_message_buffer) {
|
||||||
|
dclear(C_WHITE);
|
||||||
dtext(64, 64, C_BLACK,
|
dtext(64, 64, C_BLACK,
|
||||||
"Failed to allocate the message buffer: not "
|
"Failed to allocate the message buffer: not "
|
||||||
"enough RAM available. Press any key to quit.");
|
"enough RAM available. Press any key to quit.");
|
||||||
|
@ -131,6 +132,7 @@ int main(void) {
|
||||||
getkey();
|
getkey();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
game_init(&game);
|
game_init(&game);
|
||||||
|
|
||||||
#if USB_FEATURE
|
#if USB_FEATURE
|
||||||
|
@ -144,11 +146,6 @@ int main(void) {
|
||||||
dgray(DGRAY_ON);
|
dgray(DGRAY_ON);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DEBUGMODE
|
|
||||||
dupdate();
|
|
||||||
getkey();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* render the map */
|
/* render the map */
|
||||||
game_draw(&game);
|
game_draw(&game);
|
||||||
|
|
68
src/npc.c
68
src/npc.c
|
@ -18,6 +18,32 @@ extern bopti_image_t tiny_npc_female;
|
||||||
extern bopti_image_t tiny_npc_milkman;
|
extern bopti_image_t tiny_npc_milkman;
|
||||||
extern bopti_image_t tiny_npc_police;
|
extern bopti_image_t tiny_npc_police;
|
||||||
|
|
||||||
|
NPC_TypeData npc_typedat[NPC_Type_Count] = {
|
||||||
|
/*NPC_Static*/
|
||||||
|
{0, 0, 0, 0},
|
||||||
|
/*NPC_Guard*/
|
||||||
|
{
|
||||||
|
.agressivity = 75,
|
||||||
|
.cowardice = 85,
|
||||||
|
.lazyness = 50,
|
||||||
|
.wanderlust = 150
|
||||||
|
},
|
||||||
|
/*NPC_Bandit*/
|
||||||
|
{
|
||||||
|
.agressivity = 110,
|
||||||
|
.cowardice = 85,
|
||||||
|
.lazyness = 40,
|
||||||
|
.wanderlust = 60
|
||||||
|
},
|
||||||
|
/*NPC_Monster*/
|
||||||
|
{
|
||||||
|
.agressivity = 170,
|
||||||
|
.cowardice = 50,
|
||||||
|
.lazyness = 40,
|
||||||
|
.wanderlust = 80
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
NPC npc_stack[NPC_STACK_SIZE];
|
NPC npc_stack[NPC_STACK_SIZE];
|
||||||
uint32_t npc_count;
|
uint32_t npc_count;
|
||||||
|
|
||||||
|
@ -340,16 +366,50 @@ void update_npcs(Game *game) {
|
||||||
}
|
}
|
||||||
for(i = 0; i < npc_count; i++) {
|
for(i = 0; i < npc_count; i++) {
|
||||||
update_npc(&npc_stack[i], game);
|
update_npc(&npc_stack[i], game);
|
||||||
/*Temp debug*/
|
}
|
||||||
game->mana = npc_pathfind(game->player.x, game->player.y,
|
}
|
||||||
game->map_level, &npc_stack[i]);
|
|
||||||
|
void npc_ai(NPC *npc, Game *game){
|
||||||
|
NPC_TypeData *tdat = &npc_typedat[npc->type];
|
||||||
|
|
||||||
|
uint32_t idle_chance = 0;
|
||||||
|
uint32_t wander_chance = 0;
|
||||||
|
uint32_t flee_chance = 0;
|
||||||
|
uint32_t attack_chance = 0;
|
||||||
|
|
||||||
|
switch(npc->state){
|
||||||
|
case NPC_S_IDLE : {
|
||||||
|
/*TODO : Expand conditions to switch states*/
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NPC_S_WANDER : {
|
||||||
|
/*TODO : Choose a random close point to pathfind to */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NPC_S_FLEE : {
|
||||||
|
/*TODO : Pathfind to a point away from the player*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NPC_S_ATTACK : {
|
||||||
|
/*TODO : Attack !*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default : {
|
||||||
|
/*Get real*/
|
||||||
|
npc->state = NPC_S_IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const short int walkable_speed[WALKABLE_TILE_MAX];
|
extern const short int walkable_speed[WALKABLE_TILE_MAX];
|
||||||
|
|
||||||
void update_npc(NPC *npc, Game *game) {
|
void update_npc(NPC *npc, Game *game) {
|
||||||
/* if the NPC has no path or is paused, skip it */
|
if(npc->type != NPC_Static)
|
||||||
|
npc_ai(npc, game);
|
||||||
|
|
||||||
|
/* if the NPC has no path or is paused, skip the moving part */
|
||||||
if(!npc->hasPath || npc->paused == true)
|
if(!npc->hasPath || npc->paused == true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
37
src/npc.h
37
src/npc.h
|
@ -16,13 +16,40 @@
|
||||||
|
|
||||||
#define npc_to_curxy(a) (((a)*PXSIZE) << PRECISION)
|
#define npc_to_curxy(a) (((a)*PXSIZE) << PRECISION)
|
||||||
|
|
||||||
enum {
|
typedef struct {
|
||||||
|
|
||||||
NPC_NONE = 0,
|
/*TODO : Stats*/
|
||||||
NPC_FRIENDLY = 1, // The player's team
|
|
||||||
NPC_HOSTILE = 2, // to the player
|
/*AI weights - Values on 255*/
|
||||||
NPC_ALL = 3
|
uint8_t agressivity; /*Attack*/
|
||||||
|
uint8_t cowardice; /*Flee*/
|
||||||
|
uint8_t lazyness; /*Idle*/
|
||||||
|
uint8_t wanderlust; /*Wandering*/
|
||||||
|
|
||||||
|
} NPC_TypeData;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NPC_Static = 0, /*~= none, disqualifies from all AI*/
|
||||||
|
NPC_Guard = 1,
|
||||||
|
NPC_Bandit = 2,
|
||||||
|
NPC_Monster = 3,
|
||||||
|
NPC_Type_Count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NPC_T_NONE = 0,
|
||||||
|
NPC_T_FRIENDLY = 1, /* The player's team */
|
||||||
|
NPC_T_HOSTILE = 2, /* to the player */
|
||||||
|
NPC_T_ALL = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NPC_S_IDLE = 0,
|
||||||
|
NPC_S_ATTACK = 1,
|
||||||
|
NPC_S_FLEE = 2,
|
||||||
|
NPC_S_WANDER = 3
|
||||||
|
};
|
||||||
|
|
||||||
/* /!\ Warning /!\
|
/* /!\ Warning /!\
|
||||||
* Do not keep hard references to non-static NPCs, as they will likely move
|
* Do not keep hard references to non-static NPCs, as they will likely move
|
||||||
* in the stack */
|
* in the stack */
|
||||||
|
|
Loading…
Reference in a new issue