mirror of
https://git.planet-casio.com/Slyvtt/Collab_RPG.git
synced 2025-04-20 01:47:34 +02:00
Merge pull request 'master' (#1) from Slyvtt/Collab_RPG:master into master
Reviewed-on: https://gitea.planet-casio.com/Fcalva/Collab_RPG_Fcalva/pulls/1
This commit is contained in:
commit
baf40d040e
13 changed files with 290 additions and 21 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -14,3 +14,4 @@ __pycache__/
|
||||||
.vscode
|
.vscode
|
||||||
|
|
||||||
level*.json
|
level*.json
|
||||||
|
tilesetnpp.json
|
||||||
|
|
|
@ -13,11 +13,13 @@ A ce stade, on a déjà implémenté :
|
||||||
- [x] Multiple cartes avec importation automatique des fichiers `world` issus de Tiled
|
- [x] Multiple cartes avec importation automatique des fichiers `world` issus de Tiled
|
||||||
- [x] Carte Multilayer (Background, Foreground + accessibilité / Dommages) avec transparence du calque Foreground
|
- [x] Carte Multilayer (Background, Foreground + accessibilité / Dommages) avec transparence du calque Foreground
|
||||||
- [x] Personnage
|
- [x] Personnage
|
||||||
- [x] Dialogues (sauts de lignes et mots plus grands que l'écran pas supportés)
|
- [x] Dialogues avec fichiers externes `json` et séquenceage possible de ceux-ci via un arbre d'histoire (sauts de lignes et mots plus grands que l'écran pas supportés)
|
||||||
- [ ] Fontes de caractères
|
- [x] Fontes de caractères
|
||||||
- [ ] Interaction
|
- [x] Interaction
|
||||||
- [ ] NPC
|
- [ ] NPC
|
||||||
- [x] Changement de map durant le jeu
|
- [x] Changement de map durant le jeu
|
||||||
|
- [ ] Système d'événements
|
||||||
|
|
||||||
|
|
||||||
## Crédits
|
## Crédits
|
||||||
|
|
||||||
|
|
3
TODO.txt
3
TODO.txt
|
@ -2,5 +2,4 @@
|
||||||
[OK] - corriger les tuiles 1bit pour les rivières (tiles 1 2 3 et 4) avec niveaux de diphering pour tiles 1 et 3 (gris 33% et 66%)
|
[OK] - corriger les tuiles 1bit pour les rivières (tiles 1 2 3 et 4) avec niveaux de diphering pour tiles 1 et 3 (gris 33% et 66%)
|
||||||
[OK] - ajouter face pour dialogue pour PNJ
|
[OK] - ajouter face pour dialogue pour PNJ
|
||||||
[OK] - ajouter indicateur visuel pour action joueur quand on est proche d'un PNJ ou d'un panneau
|
[OK] - ajouter indicateur visuel pour action joueur quand on est proche d'un PNJ ou d'un panneau
|
||||||
|
[OK] - faire des fonts lisibles avec le set `print` disponible intégralement
|
||||||
- faire des fonts lisibles avec le set `print` disponible intégralement
|
|
|
@ -66,7 +66,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID":6,
|
"ID":6,
|
||||||
"dialog":"On dit qu'il se passe des choses étranges par ici depuis quelques temps. Fais bien attention a Toi.",
|
"dialog":"On dit qu'il se passe des choses etranges par ici depuis quelques temps. Fais bien attention a Toi.",
|
||||||
"isQuestion":0,
|
"isQuestion":0,
|
||||||
"choice":"_",
|
"choice":"_",
|
||||||
"conclusion1":"_",
|
"conclusion1":"_",
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
"dialog":"Salut Hero, je suis le cremier. Veux tu me delester un peu ?",
|
"dialog":"Salut Hero, je suis le cremier. Veux tu me delester un peu ?",
|
||||||
"isQuestion":1,
|
"isQuestion":1,
|
||||||
"choice":"Oui$Non",
|
"choice":"Oui$Non",
|
||||||
"conclusion1":"Voici donc pour toi`$life+5``$mana+5``$power+2`",
|
"conclusion1":"Voici donc pour toi.`$life+5``$mana+5``$power+2`",
|
||||||
"next1":-1,
|
"next1":-1,
|
||||||
"conclusion2":"Bon bah casse toi ...",
|
"conclusion2":"Bon bah casse toi ...",
|
||||||
"next2":-1,
|
"next2":-1,
|
||||||
|
@ -110,7 +110,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ID":10,
|
"ID":10,
|
||||||
"dialog":"Et sa tombe est en train d'etre creusee ?",
|
"dialog":"Et une tombe est en train d'etre creusee ?",
|
||||||
"isQuestion":0,
|
"isQuestion":0,
|
||||||
"choice":"_",
|
"choice":"_",
|
||||||
"conclusion1":"_",
|
"conclusion1":"_",
|
||||||
|
@ -129,6 +129,17 @@
|
||||||
"conclusion2":"_",
|
"conclusion2":"_",
|
||||||
"next2":-1,
|
"next2":-1,
|
||||||
"nextOther":-1
|
"nextOther":-1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID":12,
|
||||||
|
"dialog":"J'attends mon fils pour dejeuner a la taverne ... Il est toujours en retard !!",
|
||||||
|
"isQuestion":0,
|
||||||
|
"choice":"_",
|
||||||
|
"conclusion1":"_",
|
||||||
|
"next1":-1,
|
||||||
|
"conclusion2":"_",
|
||||||
|
"next2":-1,
|
||||||
|
"nextOther":-1
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
"ID":1,
|
"ID":1,
|
||||||
"dialog":"Salut, je suis le gardien du Tombeau. As-tu remarque quelque chose d'etrange en venant ici ?",
|
"dialog":"Salut, je suis le gardien du Tombeau. As-tu remarque quelque chose d'etrange en venant ici ?",
|
||||||
"isQuestion":1,
|
"isQuestion":1,
|
||||||
"choice":"Rien de special$Des pas dans les bois",
|
"choice":"Non rien$Des empreintes",
|
||||||
"conclusion1":"Ok, soit prudent tout de meme",
|
"conclusion1":"Ok, soit prudent tout de meme",
|
||||||
"next1":2,
|
"next1":2,
|
||||||
"conclusion2":"Je vais finir mon tour de ronde et verifier",
|
"conclusion2":"Je vais finir mon tour de ronde et verifier",
|
||||||
|
|
|
@ -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