mirror of
https://git.planet-casio.com/Slyvtt/Collab_RPG.git
synced 2024-12-28 04:23:42 +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"][1])
|
||||
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.u32(i["dialogID"])
|
||||
npc_struct += fxconv.u32(i["needAction"])
|
||||
npc_struct += fxconv.string(i["name"])
|
||||
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(0)
|
||||
npc_struct += fxconv.u8(0) #current_point
|
||||
|
||||
xpath = 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(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: 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
|
||||
map_struct += fxconv.ptr(npc_struct)
|
||||
# Load signs
|
||||
|
|
13
src/game.c
13
src/game.c
|
@ -11,18 +11,21 @@
|
|||
#include <gint/keyboard.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
extern bopti_image_t SignAction_img;
|
||||
extern bopti_image_t player_male_img;
|
||||
extern bopti_image_t tiny_npc_male;
|
||||
|
||||
extern Dialog *dialogRPG;
|
||||
// extern NPC *npcRPG;
|
||||
// extern uint32_t nbNPC;
|
||||
|
||||
#define MAX_INTERACTION_DISTANCE 12
|
||||
|
||||
void game_init(Game *game) {
|
||||
/*Seed the stdlib rand() function*/
|
||||
uint32_t randseed = time(NULL);
|
||||
srand(randseed);
|
||||
|
||||
game->map_level = worldRPG[0];
|
||||
/* NPC animation */
|
||||
animation_new(&game->npc_animation, &tiny_npc_male, 3, 250);
|
||||
|
@ -279,9 +282,15 @@ void game_get_inputs(Game *game) {
|
|||
mynpc->xpath = NULL;
|
||||
mynpc->ypath = NULL;
|
||||
}
|
||||
while(keydown(KEY_F1)){
|
||||
clearevents();
|
||||
}
|
||||
}
|
||||
if(keydown(KEY_F2)) {
|
||||
npc_remove_pos(0);
|
||||
while(keydown(KEY_F2)){
|
||||
clearevents();
|
||||
}
|
||||
}
|
||||
|
||||
/* Display Debug Information on screen */
|
||||
|
|
|
@ -143,16 +143,21 @@ typedef struct {
|
|||
|
||||
/* data for NPC's trajectories */
|
||||
uint8_t hasPath;
|
||||
uint8_t owns_path;
|
||||
uint8_t owns_path; /*If the NPCs path is malloc()ed*/
|
||||
uint8_t path_length;
|
||||
uint8_t currentPoint;
|
||||
int16_t *xpath;
|
||||
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 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 __padding;
|
||||
|
|
|
@ -124,6 +124,7 @@ int main(void) {
|
|||
_message_buffer = NULL;
|
||||
_message_buffer = malloc(MESSAGE_BUFFER_SZ);
|
||||
if(!_message_buffer) {
|
||||
dclear(C_WHITE);
|
||||
dtext(64, 64, C_BLACK,
|
||||
"Failed to allocate the message buffer: not "
|
||||
"enough RAM available. Press any key to quit.");
|
||||
|
@ -131,6 +132,7 @@ int main(void) {
|
|||
getkey();
|
||||
return 0;
|
||||
}
|
||||
|
||||
game_init(&game);
|
||||
|
||||
#if USB_FEATURE
|
||||
|
@ -144,11 +146,6 @@ int main(void) {
|
|||
dgray(DGRAY_ON);
|
||||
#endif
|
||||
|
||||
#if DEBUGMODE
|
||||
dupdate();
|
||||
getkey();
|
||||
#endif
|
||||
|
||||
do {
|
||||
/* render the map */
|
||||
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_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];
|
||||
uint32_t npc_count;
|
||||
|
||||
|
@ -340,16 +366,50 @@ void update_npcs(Game *game) {
|
|||
}
|
||||
for(i = 0; i < npc_count; i++) {
|
||||
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];
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
|
|
37
src/npc.h
37
src/npc.h
|
@ -16,13 +16,40 @@
|
|||
|
||||
#define npc_to_curxy(a) (((a)*PXSIZE) << PRECISION)
|
||||
|
||||
enum {
|
||||
typedef struct {
|
||||
|
||||
NPC_NONE = 0,
|
||||
NPC_FRIENDLY = 1, // The player's team
|
||||
NPC_HOSTILE = 2, // to the player
|
||||
NPC_ALL = 3
|
||||
/*TODO : Stats*/
|
||||
|
||||
/*AI weights - Values on 255*/
|
||||
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 /!\
|
||||
* Do not keep hard references to non-static NPCs, as they will likely move
|
||||
* in the stack */
|
||||
|
|
Loading…
Reference in a new issue