mirror of
https://git.planet-casio.com/Slyvtt/Collab_RPG.git
synced 2025-04-19 17:37:36 +02:00
added NPCs movement along paths + adjusted interraction system to work with moving positions
This commit is contained in:
parent
126bd87d6e
commit
53663f61ec
10 changed files with 280 additions and 13 deletions
|
@ -14,7 +14,7 @@ find_package(LibProf 2.4 REQUIRED)
|
||||||
#set the color mode either to 1b or 2b
|
#set the color mode either to 1b or 2b
|
||||||
set(COLORMODE_fx 2b)
|
set(COLORMODE_fx 2b)
|
||||||
#set the color mode either to 1b, 2b or EGA64
|
#set the color mode either to 1b, 2b or EGA64
|
||||||
set(COLORMODE_cg 2b)
|
set(COLORMODE_cg EGA64)
|
||||||
|
|
||||||
fxconv_declare_converters(assets/converters.py)
|
fxconv_declare_converters(assets/converters.py)
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,17 @@
|
||||||
"conclusion2":"_",
|
"conclusion2":"_",
|
||||||
"next2":-1,
|
"next2":-1,
|
||||||
"nextOther":-1
|
"nextOther":-1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID":12,
|
||||||
|
"dialog":"J'attends mon fils pour dejeuner à la taverne ... Il est toujours en retard !!",
|
||||||
|
"isQuestion":0,
|
||||||
|
"choice":"_",
|
||||||
|
"conclusion1":"_",
|
||||||
|
"next1":-1,
|
||||||
|
"conclusion2":"_",
|
||||||
|
"next2":-1,
|
||||||
|
"nextOther":-1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="48" height="24" tilewidth="8" tileheight="8" infinite="0" nextlayerid="8" nextobjectid="12">
|
<map version="1.10" tiledversion="1.10.1" orientation="orthogonal" renderorder="right-down" width="48" height="24" tilewidth="8" tileheight="8" infinite="0" nextlayerid="8" nextobjectid="14">
|
||||||
<editorsettings>
|
<editorsettings>
|
||||||
<export target="level0.json" format="json"/>
|
<export target="level0.json" format="json"/>
|
||||||
</editorsettings>
|
</editorsettings>
|
||||||
|
@ -114,6 +114,15 @@
|
||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
|
<object id="12" name="PNJ3" type="NPC" x="267.25" y="125.75">
|
||||||
|
<properties>
|
||||||
|
<property name="dialogID" type="int" value="12"/>
|
||||||
|
<property name="hasPath" type="int" value="1"/>
|
||||||
|
<property name="needAction" type="int" value="1"/>
|
||||||
|
<property name="path" type="object" value="13"/>
|
||||||
|
</properties>
|
||||||
|
<point/>
|
||||||
|
</object>
|
||||||
<object id="2" name="PNJ2" type="NPC" x="164" y="132">
|
<object id="2" name="PNJ2" type="NPC" x="164" y="132">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="dialogID" type="int" value="5"/>
|
<property name="dialogID" type="int" value="5"/>
|
||||||
|
@ -147,7 +156,7 @@
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
<object id="9" name="Chemin Crémier" type="TRJ" x="251.967" y="164.12">
|
<object id="9" name="Chemin Crémier" type="TRJ" x="251.967" y="164.12">
|
||||||
<polyline points="0,0 -72.25,-18.5 -171.75,-19 -172.5,-99.25 -206.25,-122.75 -140.75,-114.75 -175.25,-97.5 -174.5,-33 -148.25,-20.5 -73.25,-20.25 39,-30.25 81.25,-45 79.25,-24.5"/>
|
<polyline points="0,0 -72.25,-18.5 -171.75,-19 -172.5,-99.25 -206.25,-122.75 -140.75,-114.75 -175.25,-97.5 -174.5,-33 -148.25,-20.5 -73.25,-20.25 39,-30.25 81.25,-45 34.25,-25.5"/>
|
||||||
</object>
|
</object>
|
||||||
<object id="11" name="DébutHistoire" type="INFO" x="18.6666" y="42.6667">
|
<object id="11" name="DébutHistoire" type="INFO" x="18.6666" y="42.6667">
|
||||||
<properties>
|
<properties>
|
||||||
|
@ -156,5 +165,8 @@
|
||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
|
<object id="13" name="Chemin 100pas Client Auberge" type="TRJ" x="267.25" y="126.25">
|
||||||
|
<polyline points="0,0 -30.5,16.75 -182.5,15.75 -195.25,-26 -183.25,16.5 -29.25,18.5"/>
|
||||||
|
</object>
|
||||||
</objectgroup>
|
</objectgroup>
|
||||||
</map>
|
</map>
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
#include "npc.h"
|
||||||
|
|
||||||
|
|
||||||
#define BOX_HEIGHT (F_HEIGHT/PXSIZE+8)
|
#define BOX_HEIGHT (F_HEIGHT/PXSIZE+8)
|
||||||
|
@ -65,6 +66,7 @@ int showtext_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
for(i=0;i<=BOX_HEIGHT;i++){
|
for(i=0;i<=BOX_HEIGHT;i++){
|
||||||
/* Redrawing the entire screen, because maybe there was no dialog
|
/* Redrawing the entire screen, because maybe there was no dialog
|
||||||
displayed before. */
|
displayed before. */
|
||||||
|
update_npc(game);
|
||||||
draw(game);
|
draw(game);
|
||||||
|
|
||||||
/* Fill the dialog box with white */
|
/* Fill the dialog box with white */
|
||||||
|
@ -177,6 +179,7 @@ int showtext_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
/* Run another little fancy animation if we should. */
|
/* Run another little fancy animation if we should. */
|
||||||
for(i=BOX_HEIGHT;i>0;i--){
|
for(i=BOX_HEIGHT;i>0;i--){
|
||||||
/* It is the same as the start animation. */
|
/* It is the same as the start animation. */
|
||||||
|
update_npc(game);
|
||||||
draw(game);
|
draw(game);
|
||||||
drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE);
|
drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE);
|
||||||
drect(0, i*PXSIZE, DWIDTH, (i+1)*PXSIZE, C_BLACK);
|
drect(0, i*PXSIZE, DWIDTH, (i+1)*PXSIZE, C_BLACK);
|
||||||
|
@ -297,6 +300,7 @@ int _choice_call_before_end(Game *game, unsigned int org_i) {
|
||||||
/* Make a little animation because we looove little animations ;) */
|
/* Make a little animation because we looove little animations ;) */
|
||||||
for(i=DWIDTH/8+1;i>0;i--){
|
for(i=DWIDTH/8+1;i>0;i--){
|
||||||
/* I'm drawing the same box as on the start animation */
|
/* I'm drawing the same box as on the start animation */
|
||||||
|
update_npc(game);
|
||||||
draw(game);
|
draw(game);
|
||||||
showtext_opt(game, _face, _text, NULL, false, false, NULL, 0, false,
|
showtext_opt(game, _face, _text, NULL, false, false, NULL, 0, false,
|
||||||
_i, false);
|
_i, false);
|
||||||
|
|
35
src/game.c
35
src/game.c
|
@ -14,13 +14,16 @@
|
||||||
extern bopti_image_t SignAction_img;
|
extern bopti_image_t SignAction_img;
|
||||||
|
|
||||||
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_logic(Game *game) {
|
void game_logic(Game *game) {
|
||||||
|
|
||||||
|
update_npc( game );
|
||||||
|
|
||||||
/* we check if interactions are possible close to the player */
|
/* we check if interactions are possible close to the player */
|
||||||
for( int i=0; i<game->map_level->nbextradata; i++ )
|
for( int i=0; i<game->map_level->nbextradata; i++ )
|
||||||
{
|
{
|
||||||
|
@ -31,18 +34,46 @@ void game_logic(Game *game) {
|
||||||
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
||||||
&& (abs((int) game->player.wy -
|
&& (abs((int) game->player.wy -
|
||||||
(int) game->map_level->extradata[i].y*PXSIZE )
|
(int) game->map_level->extradata[i].y*PXSIZE )
|
||||||
< MAX_INTERACTION_DISTANCE*PXSIZE) )
|
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
||||||
|
&& strcmp( game->map_level->extradata[i].type, "NPC") !=0 )
|
||||||
{
|
{
|
||||||
/* the player can do something */
|
/* the player can do something */
|
||||||
game->player.canDoSomething = true;
|
game->player.canDoSomething = true;
|
||||||
/* we mark the action for futur treatment in player_action() */
|
/* we mark the action for futur treatment in player_action() */
|
||||||
game->player.whichAction = i;
|
game->player.whichAction = i;
|
||||||
|
/* this is not an interraction with a NPC */
|
||||||
|
game->player.isInteractingWithNPC = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( int i=0; i<nbNPC; i++ )
|
||||||
|
{
|
||||||
|
/* simple distance check along X and Y axis */
|
||||||
|
/* Be careful to use world coordinates, not local (i.e.map) ones */
|
||||||
|
if ( (abs((int) game->player.wx -
|
||||||
|
(int) npcRPG[i].curx*PXSIZE )
|
||||||
|
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
||||||
|
&& (abs((int) game->player.wy -
|
||||||
|
(int) npcRPG[i].cury*PXSIZE )
|
||||||
|
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
||||||
|
&& strcmp( game->map_level->extradata[i].type, "NPC") !=0 )
|
||||||
|
{
|
||||||
|
/* the player can do something */
|
||||||
|
game->player.canDoSomething = true;
|
||||||
|
/* we mark the action for futur treatment in player_action() */
|
||||||
|
game->player.whichAction = i;
|
||||||
|
/* this is not an interraction with a NPC */
|
||||||
|
game->player.isInteractingWithNPC = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* else nothing to be done here */
|
/* else nothing to be done here */
|
||||||
game->player.canDoSomething = false;
|
game->player.canDoSomething = false;
|
||||||
game->player.whichAction = -1;
|
game->player.whichAction = -1;
|
||||||
|
game->player.isInteractingWithNPC = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,8 @@ typedef struct {
|
||||||
int32_t whichAction;
|
int32_t whichAction;
|
||||||
/* the player is doing something */
|
/* the player is doing something */
|
||||||
bool isDoingAction;
|
bool isDoingAction;
|
||||||
|
/* the player is interacting with a NPC */
|
||||||
|
bool isInteractingWithNPC;
|
||||||
} Player;
|
} Player;
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,8 +81,8 @@ typedef struct {
|
||||||
/* data for NPC's trajectories */
|
/* data for NPC's trajectories */
|
||||||
uint32_t hasPath;
|
uint32_t hasPath;
|
||||||
uint32_t path_length;
|
uint32_t path_length;
|
||||||
uint16_t *xpath;
|
int16_t *xpath;
|
||||||
uint16_t *ypath;
|
int16_t *ypath;
|
||||||
|
|
||||||
/* ... this can be extended as per needs ... */
|
/* ... this can be extended as per needs ... */
|
||||||
} ExtraData;
|
} ExtraData;
|
||||||
|
|
|
@ -4,7 +4,10 @@
|
||||||
#include <gint/timer.h>
|
#include <gint/timer.h>
|
||||||
#include <gint/cpu.h>
|
#include <gint/cpu.h>
|
||||||
|
|
||||||
|
#include <fxlibc/printf.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "npc.h"
|
||||||
|
|
||||||
#if USB_FEATURE
|
#if USB_FEATURE
|
||||||
#include <gint/usb-ff-bulk.h>
|
#include <gint/usb-ff-bulk.h>
|
||||||
|
@ -32,7 +35,7 @@ extern Map *worldRPG[];
|
||||||
/* Game data (defined in "game.h")*/
|
/* Game data (defined in "game.h")*/
|
||||||
Game game = {
|
Game game = {
|
||||||
NULL,
|
NULL,
|
||||||
{12*PXSIZE, 36*PXSIZE, 0, 0, 12*PXSIZE, 36*PXSIZE, 100, SPEED, false, 0, false},
|
{12*PXSIZE, 36*PXSIZE, 0, 0, 12*PXSIZE, 36*PXSIZE, 100, SPEED, false, 0, false, false},
|
||||||
false, false, false, 0
|
false, false, false, 0
|
||||||
|
|
||||||
/* debug variables*/
|
/* debug variables*/
|
||||||
|
@ -86,6 +89,9 @@ int update_time(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|
||||||
|
__printf_enable_fp();
|
||||||
|
|
||||||
int timer;
|
int timer;
|
||||||
timer = timer_configure(TIMER_TMU, 1000, GINT_CALL(update_time));
|
timer = timer_configure(TIMER_TMU, 1000, GINT_CALL(update_time));
|
||||||
if(timer < 0){
|
if(timer < 0){
|
||||||
|
@ -95,6 +101,7 @@ int main(void) {
|
||||||
|
|
||||||
game.map_level = worldRPG[0];
|
game.map_level = worldRPG[0];
|
||||||
|
|
||||||
|
reload_npc(&game);
|
||||||
|
|
||||||
#if USB_FEATURE
|
#if USB_FEATURE
|
||||||
usb_interface_t const *interfaces[] = {&usb_ff_bulk, NULL};
|
usb_interface_t const *interfaces[] = {&usb_ff_bulk, NULL};
|
||||||
|
|
136
src/npc.c
136
src/npc.c
|
@ -5,7 +5,10 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <gint/display.h>
|
#include <gint/display.h>
|
||||||
#include <gint/keyboard.h> /*debug*/
|
#include <gint/keyboard.h> /*debug*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
extern bopti_image_t demo_PNJ_img;
|
extern bopti_image_t demo_PNJ_img;
|
||||||
|
@ -20,7 +23,140 @@ extern bopti_image_t demo_PNJ_img;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
NPC *npcRPG;
|
||||||
|
uint32_t nbNPC = 0;
|
||||||
|
|
||||||
|
float length( float x, float y )
|
||||||
|
{
|
||||||
|
return sqrtf( x*x+y*y );
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_npc(Game *game)
|
||||||
|
{
|
||||||
|
for( uint32_t u=0; u<nbNPC; u++ )
|
||||||
|
{
|
||||||
|
/* if the NPC has a path to follow AND is not currently in pause */
|
||||||
|
/* (talking with the player) */
|
||||||
|
if (npcRPG[u].hasPath==1 && npcRPG[u].paused==false)
|
||||||
|
{
|
||||||
|
float vecX = (float) (npcRPG[u].xpath[ npcRPG[u].currentPoint ] +
|
||||||
|
npcRPG[u].x) - npcRPG[u].curx;
|
||||||
|
float vecY = (float) (npcRPG[u].ypath[ npcRPG[u].currentPoint ] +
|
||||||
|
npcRPG[u].y) - npcRPG[u].cury;
|
||||||
|
float vecN = length(vecX, vecY);
|
||||||
|
|
||||||
|
if (vecN>0.5f)
|
||||||
|
{
|
||||||
|
vecX /= vecN*2.0;
|
||||||
|
vecY /= vecN*2.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
npcRPG[u].currentPoint++;
|
||||||
|
npcRPG[u].currentPoint = npcRPG[u].currentPoint % npcRPG[u].path_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
npcRPG[u].curx += vecX;
|
||||||
|
npcRPG[u].cury += vecY;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void reload_npc(Game *game)
|
||||||
|
{
|
||||||
|
if (npcRPG!=NULL)
|
||||||
|
{
|
||||||
|
free(npcRPG);
|
||||||
|
npcRPG = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
nbNPC = 0;
|
||||||
|
|
||||||
|
|
||||||
|
for (uint32_t u=0; u<game->map_level->nbextradata; u++) //uint pour enlever un warning
|
||||||
|
{
|
||||||
|
ExtraData *Data = &game->map_level->extradata[u];
|
||||||
|
|
||||||
|
if (strcmp(Data->type, "NPC")==0) /* the current data is a NPC */
|
||||||
|
{
|
||||||
|
nbNPC++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
npcRPG = (NPC*) malloc( nbNPC * sizeof(NPC) );
|
||||||
|
int currentNPC=0;
|
||||||
|
|
||||||
|
for (uint32_t u=0; u<game->map_level->nbextradata; u++) //uint pour enlever un warning
|
||||||
|
{
|
||||||
|
ExtraData *Data = &game->map_level->extradata[u];
|
||||||
|
|
||||||
|
if (strcmp(Data->type, "NPC")==0) /* the current data is a NPC */
|
||||||
|
{
|
||||||
|
npcRPG[currentNPC].curx = (float) Data->x;
|
||||||
|
npcRPG[currentNPC].cury = (float) Data->y;
|
||||||
|
npcRPG[currentNPC].x = Data->x;
|
||||||
|
npcRPG[currentNPC].y = Data->y;
|
||||||
|
npcRPG[currentNPC].dialogID = Data->dialogID;
|
||||||
|
npcRPG[currentNPC].currentPoint = 1;
|
||||||
|
npcRPG[currentNPC].hasPath = Data->hasPath;
|
||||||
|
npcRPG[currentNPC].path_length = Data->path_length;
|
||||||
|
npcRPG[currentNPC].xpath = Data->xpath;
|
||||||
|
npcRPG[currentNPC].ypath = Data->ypath;
|
||||||
|
npcRPG[currentNPC].paused = false;
|
||||||
|
currentNPC++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void npc_draw(Game *game) {
|
void npc_draw(Game *game) {
|
||||||
|
Player *pl = &game->player;
|
||||||
|
|
||||||
|
for (uint32_t u=0; u<nbNPC; u++) //uint pour enlever un warning
|
||||||
|
{
|
||||||
|
NPC *Data = &npcRPG[u];
|
||||||
|
|
||||||
|
/* TODO : This is for debugging purpose, JUste to render the path */
|
||||||
|
/* to be followed by the NPC when this will be implemented */
|
||||||
|
#if DEBUGMODE
|
||||||
|
if (Data->hasPath==1) /* this NPC has a trajectory */
|
||||||
|
{
|
||||||
|
int NbPoints = Data->path_length+1;
|
||||||
|
for(int v=0; v<NbPoints; v++)
|
||||||
|
{
|
||||||
|
|
||||||
|
int16_t deltaX1=((int16_t) (Data->x +
|
||||||
|
Data->xpath[v % NbPoints]) * PXSIZE)
|
||||||
|
-(int16_t) pl->wx;
|
||||||
|
int16_t deltaY1=((int16_t) (Data->y +
|
||||||
|
Data->ypath[v % NbPoints]) * PXSIZE)
|
||||||
|
-(int16_t) pl->wy;
|
||||||
|
int16_t deltaX2=((int16_t) (Data->x +
|
||||||
|
Data->xpath[(v+1) % NbPoints]) * PXSIZE)
|
||||||
|
-(int16_t) pl->wx;
|
||||||
|
int16_t deltaY2=((int16_t) (Data->y +
|
||||||
|
Data->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
|
||||||
|
|
||||||
|
int16_t delX=((int16_t) (Data->curx * PXSIZE))-(int16_t) pl->wx;
|
||||||
|
int16_t delY=((int16_t) (Data->cury * PXSIZE))-(int16_t) pl->wy;
|
||||||
|
dimage( pl->px-P_WIDTH/2+delX, pl->py-P_HEIGHT/2+delY, &demo_PNJ_img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void OLD_npc_draw(Game *game) {
|
||||||
Player *player = &game->player;
|
Player *player = &game->player;
|
||||||
|
|
||||||
for (uint32_t u=0; u<game->map_level->nbextradata; u++) //uint pour enlever un warning
|
for (uint32_t u=0; u<game->map_level->nbextradata; u++) //uint pour enlever un warning
|
||||||
|
|
29
src/npc.h
29
src/npc.h
|
@ -3,16 +3,45 @@
|
||||||
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* current coordinates of the NPC */
|
||||||
|
float curx, cury;
|
||||||
|
|
||||||
|
/* initial coordinates of the NPC (needed to get absolute coordinates of path) */
|
||||||
|
uint32_t x;
|
||||||
|
uint32_t y;
|
||||||
|
/* the ID of the first element of the dialog */
|
||||||
|
/* (to be aligned with "dialogs.json" IDs)*/
|
||||||
|
uint32_t dialogID;
|
||||||
|
/* the number of the target point of the path */
|
||||||
|
/* Note: it must keep the value 0 if NPC has no path assigned */
|
||||||
|
uint32_t currentPoint;
|
||||||
|
/* data of the path */
|
||||||
|
uint32_t hasPath;
|
||||||
|
uint32_t path_length;
|
||||||
|
int16_t *xpath;
|
||||||
|
int16_t *ypath;
|
||||||
|
|
||||||
|
/* is the current NPC in pause (during dialog) */
|
||||||
|
bool paused;
|
||||||
|
} NPC;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Draws the player player. This function should be called after drawing the
|
/* Draws the player player. This function should be called after drawing the
|
||||||
* map! */
|
* map! */
|
||||||
void npc_draw(Game *game);
|
void npc_draw(Game *game);
|
||||||
|
|
||||||
|
void update_npc(Game *game);
|
||||||
|
|
||||||
|
void reload_npc(Game *game);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
43
src/player.c
43
src/player.c
|
@ -3,6 +3,7 @@
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "npc.h"
|
||||||
#include <gint/display.h>
|
#include <gint/display.h>
|
||||||
|
|
||||||
const char one_px_mov[8] = {
|
const char one_px_mov[8] = {
|
||||||
|
@ -28,6 +29,10 @@ const char damage_taken_walkable[WALKABLE_TILE_MAX] = {
|
||||||
|
|
||||||
extern bopti_image_t demo_player_img;
|
extern bopti_image_t demo_player_img;
|
||||||
|
|
||||||
|
extern NPC *npcRPG;
|
||||||
|
extern uint32_t nbNPC;
|
||||||
|
|
||||||
|
|
||||||
void player_draw(Game *game) {
|
void player_draw(Game *game) {
|
||||||
Player *player = &game->player;
|
Player *player = &game->player;
|
||||||
dimage(player->px-P_WIDTH/2, player->py-P_HEIGHT/2, &demo_player_img);
|
dimage(player->px-P_WIDTH/2, player->py-P_HEIGHT/2, &demo_player_img);
|
||||||
|
@ -86,9 +91,9 @@ extern bopti_image_t INFO_Icon_img;
|
||||||
|
|
||||||
|
|
||||||
void player_action(Game *game) {
|
void player_action(Game *game) {
|
||||||
if( game->player.isDoingAction ) return; /* alreday doing something */
|
if( game->player.isDoingAction ) return; /* alreday doing something (action IS NOT with an NPC ) */
|
||||||
|
|
||||||
if( game->player.canDoSomething ) /* we can do something */
|
if( game->player.canDoSomething && !game->player.isInteractingWithNPC ) /* we can do something */
|
||||||
{
|
{
|
||||||
/* we indicate that the player is occupied */
|
/* we indicate that the player is occupied */
|
||||||
game->player.isDoingAction = true;
|
game->player.isDoingAction = true;
|
||||||
|
@ -103,8 +108,8 @@ void player_action(Game *game) {
|
||||||
|
|
||||||
if (strcmp("INFO", currentData->type)==0)
|
if (strcmp("INFO", currentData->type)==0)
|
||||||
face = &INFO_Icon_img;
|
face = &INFO_Icon_img;
|
||||||
else if (strcmp("NPC", currentData->type)==0)
|
//else if (strcmp("NPC", currentData->type)==0)
|
||||||
face = &NPC_Icon_img;
|
// face = &NPC_Icon_img;
|
||||||
else if (strcmp("SGN", currentData->type)==0)
|
else if (strcmp("SGN", currentData->type)==0)
|
||||||
face = &SGN_Icon_img;
|
face = &SGN_Icon_img;
|
||||||
else face = &demo_player_img;
|
else face = &demo_player_img;
|
||||||
|
@ -116,6 +121,32 @@ void player_action(Game *game) {
|
||||||
/* when done we release the occupied status of the player */
|
/* when done we release the occupied status of the player */
|
||||||
game->player.isDoingAction = false;
|
game->player.isDoingAction = false;
|
||||||
}
|
}
|
||||||
|
else if( game->player.canDoSomething && game->player.isInteractingWithNPC ) /* we can do something (action IS with an NPC ) */
|
||||||
|
{
|
||||||
|
/* we indicate that the player is occupied */
|
||||||
|
game->player.isDoingAction = true;
|
||||||
|
|
||||||
|
NPC *currentNPC = &npcRPG[game->player.whichAction];
|
||||||
|
|
||||||
|
/* we use the correct image as per the class of the item */
|
||||||
|
|
||||||
|
bopti_image_t *face = &NPC_Icon_img;
|
||||||
|
uint32_t dialogStart = currentNPC->dialogID;
|
||||||
|
|
||||||
|
/* we setr this NPC to paused to avoid changing its position while talking (the rest of the NPCs pursue their action)*/
|
||||||
|
currentNPC->paused = true;
|
||||||
|
|
||||||
|
|
||||||
|
initiate_dialog_sequence( game, face, dialogStart );
|
||||||
|
|
||||||
|
/* when done we release the occupied status of the player */
|
||||||
|
game->player.isDoingAction = false;
|
||||||
|
|
||||||
|
currentNPC->paused = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool player_collision(Game *game, Direction direction,
|
bool player_collision(Game *game, Direction direction,
|
||||||
|
@ -184,6 +215,10 @@ bool player_collision(Game *game, Direction direction,
|
||||||
return true; /* He will collide with it. */
|
return true; /* He will collide with it. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we update the list of NPCs in the current map */
|
||||||
|
/* to follow the trajectories */
|
||||||
|
reload_npc( game );
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue