From d81616ad38a7a9a7e463a984a6e1b29701d60e9c Mon Sep 17 00:00:00 2001 From: SlyVTT Date: Tue, 22 Aug 2023 10:39:37 +0200 Subject: [PATCH] separated dialogs into 1 file per map with link in tmx + created dialog sequence/kinkage system + adjusted all maps data accordingly --- CMakeLists.txt | 1 - assets/{DialogsRPG.json => DialogsLvl0.json} | 0 assets/DialogsLvl1.json | 35 +++++ assets/DialogsLvl2.json | 46 +++++++ assets/DialogsLvl3.json | 59 ++++++++ assets/WorldRPG.world | 21 +++ assets/WorldRPG.world.bak | 34 ----- assets/converters.py | 30 ++++- assets/dialogs.json.bak | 134 ------------------- assets/fxconv-metadata.txt | 6 +- assets/level0.tmx | 3 + assets/level1.tmx | 21 +-- assets/level2.tmx | 24 ++-- assets/level3.tmx | 38 ++---- assets/tilesetnpp.json | 14 -- clean | 1 + src/dialogs.c | 45 +++++++ src/dialogs.h | 2 + src/game.h | 4 + src/main.c | 5 +- src/map.c | 2 +- src/player.c | 38 ++---- 22 files changed, 294 insertions(+), 269 deletions(-) rename assets/{DialogsRPG.json => DialogsLvl0.json} (100%) create mode 100644 assets/DialogsLvl1.json create mode 100644 assets/DialogsLvl2.json create mode 100644 assets/DialogsLvl3.json delete mode 100644 assets/WorldRPG.world.bak delete mode 100644 assets/dialogs.json.bak delete mode 100644 assets/tilesetnpp.json diff --git a/CMakeLists.txt b/CMakeLists.txt index be43288..65291bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,6 @@ set(SOURCES # Shared assets, fx-9860G-only assets and fx-CG-50-only assets set(ASSETS assets/WorldRPG.world - assets/DialogsRPG.json # ... ) diff --git a/assets/DialogsRPG.json b/assets/DialogsLvl0.json similarity index 100% rename from assets/DialogsRPG.json rename to assets/DialogsLvl0.json diff --git a/assets/DialogsLvl1.json b/assets/DialogsLvl1.json new file mode 100644 index 0000000..e3e6b3a --- /dev/null +++ b/assets/DialogsLvl1.json @@ -0,0 +1,35 @@ +{ "dialogs":[ + { "ID":0, + "dialog":"Le tombeau du Chevalier Legendaire", + "isQuestion":0, + "choice":"_", + "conclusion1":"_", + "next1":-1, + "conclusion2":"_", + "next2":-1, + "nextOther":1 + }, + { + "ID":1, + "dialog":"Salut, je suis le gardien du Tombeau. As-tu remarque quelque chose d'etrange en venant ici ?", + "isQuestion":1, + "choice":"Rien de special$Des pas dans les bois", + "conclusion1":"Ok, soit prudent tout de meme", + "next1":2, + "conclusion2":"Je vais finir mon tour de ronde et verifier", + "next2":2, + "nextOther":-1 + }, + { + "ID":2, + "dialog":"A bientot l'ami et prend garde aux brigands.", + "isQuestion":0, + "choice":"_", + "conclusion1":"_", + "next1":-1, + "conclusion2":"_", + "next2":-1, + "nextOther":-1 + } + ] +} \ No newline at end of file diff --git a/assets/DialogsLvl2.json b/assets/DialogsLvl2.json new file mode 100644 index 0000000..5f81e3f --- /dev/null +++ b/assets/DialogsLvl2.json @@ -0,0 +1,46 @@ +{ "dialogs":[ + { "ID":0, + "dialog":"Encore une tombe ...", + "isQuestion":0, + "choice":"_", + "conclusion1":"_", + "next1":-1, + "conclusion2":"_", + "next2":-1, + "nextOther":-1 + }, + { + "ID":1, + "dialog":"Un passage souterrain ...", + "isQuestion":0, + "choice":"_", + "conclusion1":"_", + "next1":-1, + "conclusion2":"_", + "next2":-1, + "nextOther":2 + }, + { + "ID":2, + "dialog":"Je me demande bien ou il peut conduire. Une prochaine expedition a faire peut-etre ...", + "isQuestion":0, + "choice":"_", + "conclusion1":"_", + "next1":-1, + "conclusion2":"_", + "next2":-1, + "nextOther":-1 + }, + { + "ID":3, + "dialog":"C'est la maison du gardien du cimetiere", + "isQuestion":0, + "choice":"_", + "conclusion1":"_", + "next1":-1, + "conclusion2":"_", + "next2":-1, + "nextOther":-1 + } + ] +} \ No newline at end of file diff --git a/assets/DialogsLvl3.json b/assets/DialogsLvl3.json new file mode 100644 index 0000000..6e4a4f9 --- /dev/null +++ b/assets/DialogsLvl3.json @@ -0,0 +1,59 @@ +{ + "dialogs": [ + { + "ID": 0, + "dialog": "Maison du Fermier", + "isQuestion": 0, + "choice": "_", + "conclusion1": "_", + "next1": -1, + "conclusion2": "_", + "next2": -1, + "nextOther": -1 + }, + { + "ID": 1, + "dialog": "Maison du Marechal Ferrand", + "isQuestion": 0, + "choice": "_", + "conclusion1": "_", + "next1": -1, + "conclusion2": "_", + "next2": -1, + "nextOther": -1 + }, + { + "ID": 2, + "dialog": "Maison du Boucher", + "isQuestion": 0, + "choice": "_", + "conclusion1": "_", + "next1": -1, + "conclusion2": "_", + "next2": -1, + "nextOther": -1 + }, + { + "ID": 3, + "dialog": "Maison du Boulanger", + "isQuestion": 0, + "choice": "_", + "conclusion1": "_", + "next1": -1, + "conclusion2": "_", + "next2": -1, + "nextOther": -1 + }, + { + "ID": 4, + "dialog": "Maison du Maire", + "isQuestion": 0, + "choice": "_", + "conclusion1": "_", + "next1": -1, + "conclusion2": "_", + "next2": -1, + "nextOther": -1 + } + ] +} \ No newline at end of file diff --git a/assets/WorldRPG.world b/assets/WorldRPG.world index fc910f1..7cbaa1d 100644 --- a/assets/WorldRPG.world +++ b/assets/WorldRPG.world @@ -6,6 +6,27 @@ "width": 384, "x": 0, "y": 0 + }, + { + "fileName": "level1.tmx", + "height": 192, + "width": 384, + "x": 384, + "y": 0 + }, + { + "fileName": "level2.tmx", + "height": 192, + "width": 384, + "x": 0, + "y": 192 + }, + { + "fileName": "level3.tmx", + "height": 192, + "width": 384, + "x": 384, + "y": 192 } ], "onlyShowAdjacentMaps": false, diff --git a/assets/WorldRPG.world.bak b/assets/WorldRPG.world.bak deleted file mode 100644 index 7cbaa1d..0000000 --- a/assets/WorldRPG.world.bak +++ /dev/null @@ -1,34 +0,0 @@ -{ - "maps": [ - { - "fileName": "level0.tmx", - "height": 192, - "width": 384, - "x": 0, - "y": 0 - }, - { - "fileName": "level1.tmx", - "height": 192, - "width": 384, - "x": 384, - "y": 0 - }, - { - "fileName": "level2.tmx", - "height": 192, - "width": 384, - "x": 0, - "y": 192 - }, - { - "fileName": "level3.tmx", - "height": 192, - "width": 384, - "x": 384, - "y": 192 - } - ], - "onlyShowAdjacentMaps": false, - "type": "world" -} diff --git a/assets/converters.py b/assets/converters.py index a44f06b..7b19bc8 100644 --- a/assets/converters.py +++ b/assets/converters.py @@ -21,7 +21,8 @@ def convert(input, output, params, target): convert_font(input, output, params, target) return 0 elif params["custom-type"] == "dialogs": - convert_dialogs(input, output, params, target) + print("ERROR : Asset ", params["name"], " has legacy type dialog") + #convert_dialogs(input, output, params, target) return 0 else: return 1 @@ -148,6 +149,8 @@ def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax): structMap += fxconv.ptr(walk_data) + + nbextra = 0 extradata = fxconv.Structure() @@ -161,6 +164,26 @@ def get_tile_map_data(input, output, params, target, xmin, ymin, xmax, ymax): structMap += fxconv.ptr( extradata ) + + + nameDialog = data["properties"][0]["value"] + dialogfile = "/".join(input.split("/")[:-nbRetour]) + "/" + nameDialog + print( "THE DIALOGS ARE CONTAINED IN THE FILE : ", dialogfile ) + + nbdiag = 0 + diagdata = fxconv.Structure() + + nbdiag, diagdata = convert_dialogs(dialogfile, output, params, target) + + if (nbdiag==0): + structMap += fxconv.u32( 0 ) + structMap += fxconv.u32( 0 ) + else: + structMap += fxconv.u32( int(nbdiag) ) + structMap += fxconv.ptr( diagdata ) + + + #extraction of the data contained in the layer "Background" and "Foreground" of the map @@ -353,6 +376,7 @@ def convert_dialogs(input, output, params, target): data = json.load(open(input, "r")) structDialogs = fxconv.Structure() + nbdialogs = 0 for d in data["dialogs"]: print( int(d[ "ID" ])) @@ -364,6 +388,7 @@ def convert_dialogs(input, output, params, target): # print( d[ "conclusion2" ] ) # print( int(d[ "next2" ] ) ) # print( int(d[ "nextOther" ]) ) + nbdialogs = nbdialogs + 1 structDialogs += fxconv.u32( int(d[ "ID" ] ) ) structDialogs += fxconv.string( d[ "dialog" ] ) @@ -375,5 +400,6 @@ def convert_dialogs(input, output, params, target): structDialogs += fxconv.u32( int(d[ "next2" ] ) ) structDialogs += fxconv.u32( int(d[ "nextOther" ] ) ) + return nbdialogs, structDialogs - fxconv.elf(structDialogs, output, "_" + params["name"], **target) \ No newline at end of file + #fxconv.elf(structDialogs, output, "_" + params["name"], **target) \ No newline at end of file diff --git a/assets/dialogs.json.bak b/assets/dialogs.json.bak deleted file mode 100644 index 987338b..0000000 --- a/assets/dialogs.json.bak +++ /dev/null @@ -1,134 +0,0 @@ -[ - { - "ID": 0, - "dialog": "Bienvenue a Toi, l'Ami, dans cette magnifique ville de Nabrouch. Comme tu peux le constater, les habitants ne sont pas tres nombreux et ont tendance a se terrer dans leur maison depuis la revolution. Il faut dire que les Anciens dirigeants, bien qu'exiles, exercent encore une certaine forme de pouvoir ...", - "isQuestion": 0, - "choice": "_", - "conclusion1": "_", - "next1": -1, - "conclusion2": "_", - "next2": -1, - "nextOther": 1 - }, - { - "ID": 1, - "dialog": "Depuis la mort de ton Pere, la region a bien change ... Enfin, surtout ses habitants. Tu devras te mefier de tout le monde.", - "isQuestion": 0, - "choice": "_", - "conclusion1": "_", - "next1": -1, - "conclusion2": "_", - "next2": -1, - "nextOther": 2 - }, - { - "ID": 2, - "dialog": "Tu devrais commencer par rejoindre la taverne que ton pere t'a laisse en heritage.", - "isQuestion": 0, - "choice": "_", - "conclusion1": "_", - "next1": -1, - "conclusion2": "_", - "next2": -1, - "nextOther": -1 - }, - { - "ID": 3, - "dialog": "Taverne de Pue Le Bouc", - "isQuestion": 0, - "choice": "_", - "conclusion1": "_", - "next1": -1, - "conclusion2": "_", - "next2": -1, - "nextOther": -1 - }, - { - "ID": 4, - "dialog": "Tiens !! Quelqu'un est mort ici. Tu le connais ?", - "isQuestion": 1, - "choice": "Oui$Non", - "conclusion1": "C'est bien triste mon Ami.`$life-2``$power-5`", - "next1": -1, - "conclusion2": "Dommage quand meme pour Lui.", - "next2": -1, - "nextOther": -1 - }, - { - "ID": 5, - "dialog": "Salut Hero !! Quel bon vent t'ammene ici a Nabrouch ?", - "isQuestion": 1, - "choice": "De Passage$La Famille", - "conclusion1": "Entre donc te reposer dans la taverne, c'est la seule du coin.", - "next1": -1, - "conclusion2": "Fais bien attention alors.", - "next2": 6, - "nextOther": -1 - }, - { - "ID": 6, - "dialog": "On dit qu'il se passe des choses étranges par ici depuis quelques temps. Fais bien attention a Toi.", - "isQuestion": 0, - "choice": "_", - "conclusion1": "_", - "next1": -1, - "conclusion2": "_", - "next2": -1, - "nextOther": -1 - }, - { - "ID": 7, - "dialog": "Salut Hero, je suis le cremier. Veux tu me delester un peu ?", - "isQuestion": 1, - "choice": "Oui$Non", - "conclusion1": "Voici donc pour toi`$life+5``$mana+5``$power+2`", - "next1": -1, - "conclusion2": "Bon bah casse toi ...", - "next2": -1, - "nextOther": -1 - }, - { - "ID": 8, - "dialog": "Le Sanctuaire Maudit ...", - "isQuestion": 0, - "choice": "_", - "conclusion1": "_", - "next1": -1, - "conclusion2": "_", - "next2": -1, - "nextOther": -1 - }, - { - "ID": 9, - "dialog": "Etrange ce coffre abandonne et ouvert ... Fouiller dedans ?", - "isQuestion": 1, - "choice": "Oui$Non", - "conclusion1": "Trop cool, du stuff `$life+5``$mana+5``$power+2`", - "next1": -1, - "conclusion2": "Je ferai mieux de partir loin ...", - "next2": -1, - "nextOther": -1 - }, - { - "ID": 10, - "dialog": "Et sa tombe est en train d'etre creusee ?", - "isQuestion": 0, - "choice": "_", - "conclusion1": "_", - "next1": -1, - "conclusion2": "_", - "next2": -1, - "nextOther": 11 - }, - { - "ID": 11, - "dialog": "Beaucoup de morts pour une si petite bourgade ...", - "isQuestion": 0, - "choice": "_", - "conclusion1": "_", - "next1": -1, - "conclusion2": "_", - "next2": -1, - "nextOther": -1 - } -] \ No newline at end of file diff --git a/assets/fxconv-metadata.txt b/assets/fxconv-metadata.txt index 17810e2..822cad1 100644 --- a/assets/fxconv-metadata.txt +++ b/assets/fxconv-metadata.txt @@ -2,6 +2,6 @@ WorldRPG.world: custom-type: world name: worldRPG -DialogsRPG.json: - custom-type: dialogs - name: dialogRPG +#DialogsRPG.json: +# custom-type: dialogs +# name: dialogRPG diff --git a/assets/level0.tmx b/assets/level0.tmx index 4554f3b..a5d1322 100644 --- a/assets/level0.tmx +++ b/assets/level0.tmx @@ -3,6 +3,9 @@ + + + diff --git a/assets/level1.tmx b/assets/level1.tmx index cee3aac..c3af03c 100644 --- a/assets/level1.tmx +++ b/assets/level1.tmx @@ -1,5 +1,8 @@ + + + @@ -89,27 +92,25 @@ - - - - - + + - - - - + - + + + + + diff --git a/assets/level2.tmx b/assets/level2.tmx index 6eede1e..3592373 100644 --- a/assets/level2.tmx +++ b/assets/level2.tmx @@ -1,5 +1,8 @@ + + + @@ -89,31 +92,22 @@ - - - - - + + - - - - - + + - - - - - + + diff --git a/assets/level3.tmx b/assets/level3.tmx index 9f78df7..17705ee 100644 --- a/assets/level3.tmx +++ b/assets/level3.tmx @@ -1,5 +1,8 @@ + + + @@ -89,51 +92,36 @@ - - - - - + + - - - - - + + - - - - - + + - - - - - + + - - - - - + + diff --git a/assets/tilesetnpp.json b/assets/tilesetnpp.json deleted file mode 100644 index 281733b..0000000 --- a/assets/tilesetnpp.json +++ /dev/null @@ -1,14 +0,0 @@ -{ "columns":24, - "image":"tileset.png", - "imageheight":136, - "imagewidth":192, - "margin":0, - "name":"tileset", - "spacing":0, - "tilecount":408, - "tiledversion":"1.8.0", - "tileheight":8, - "tilewidth":8, - "type":"tileset", - "version":"1.8" -} \ No newline at end of file diff --git a/clean b/clean index 968770d..445982d 100755 --- a/clean +++ b/clean @@ -1,5 +1,6 @@ cd assets rm -f level*.json +rm -f tilesetnpp.json rm -r __pycache__ cd .. rm -r build-cg diff --git a/src/dialogs.c b/src/dialogs.c index 69bf657..410fef8 100644 --- a/src/dialogs.c +++ b/src/dialogs.c @@ -6,6 +6,7 @@ #include #include "config.h" +#include "game.h" #define BOX_HEIGHT (F_HEIGHT/PXSIZE+8) @@ -329,3 +330,47 @@ int showtext_dialog_ask(Game *game, bopti_image_t *face, char *text, bool start, return showtext_opt(game, face, text, _choice_call_before_end, start, end, _choice_screen_call, 100, true, 0, true); } + + + + +void initiate_dialog_sequence(Game *game, bopti_image_t *face, uint32_t dialogNumber ) +{ + Dialog *currentDiag = &game->map_level->dialogs[ dialogNumber ]; + + /* we collect the information */ + char *text = currentDiag->dialog; + + char *choices = currentDiag->choices ; + char *conclusion1 = currentDiag->conclusion1; + int next1 = currentDiag->next1; + char *conclusion2 = currentDiag->conclusion2; + int next2 = currentDiag->next2; + int nextOther = currentDiag->nextOther; + int isQuestion = currentDiag->isQuestion; + + /* we treat the action - i.e. we show a dialog */ + if (isQuestion == 1) /* we have to manage a question */ + { + int answer = showtext_dialog_ask( game, face, text, true, true, choices, 2, 0 ); + + /* TO DO we need to split the strings conclusion1 and conclusion2 */ + /* to extract the "gift" part */ + + if (answer==0) + { + showtext_dialog( game, face, conclusion1, true, true ); + if (next1!=-1) initiate_dialog_sequence( game, face, next1 ); + } + else + { + showtext_dialog( game, face, conclusion2, true, true ); + if (next2!=-1) initiate_dialog_sequence( game, face, next2 ); + } + } + else + { + showtext_dialog( game, face, text, true, true ); + if (nextOther!=-1) initiate_dialog_sequence( game, face, nextOther ); + } +} \ No newline at end of file diff --git a/src/dialogs.h b/src/dialogs.h index ccff4be..39729b7 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -89,4 +89,6 @@ int showtext_dialog_ask(Game *game, bopti_image_t *face, char *text, bool start, bool end, char *choices, int choices_amount, int default_choice); +void initiate_dialog_sequence(Game *game, bopti_image_t *face, uint32_t dialogNumber ); + #endif diff --git a/src/game.h b/src/game.h index c7e7164..b5dbb4b 100644 --- a/src/game.h +++ b/src/game.h @@ -113,6 +113,10 @@ typedef struct { uint32_t nbextradata; ExtraData *extradata; + /* structure that contains all the dialogs for that part of the map */ + uint32_t nbdialogsdata; + Dialog *dialogs; + /* list of all the tiles to draw the background and the foreground layers */ uint16_t *layers[]; } Map; diff --git a/src/main.c b/src/main.c index 656ba64..9294a8a 100644 --- a/src/main.c +++ b/src/main.c @@ -28,7 +28,6 @@ extern bopti_image_t player_face_img; extern Map *worldRPG[]; -extern Dialog dialogRPG[]; /* Game data (defined in "game.h")*/ Game game = { @@ -158,8 +157,8 @@ int main(void) { game.map_level->extradata[i].x, game.map_level->extradata[i].y, game.map_level->extradata[i].dialogID, - dialogRPG[ game.map_level->extradata[i].dialogID ].ID, - dialogRPG[ game.map_level->extradata[i].dialogID ].conclusion1[0] ); + game.map_level->dialogs[ game.map_level->extradata[i].dialogID ].ID, + game.map_level->dialogs[ game.map_level->extradata[i].dialogID ].conclusion1[0] ); } #endif diff --git a/src/map.c b/src/map.c index 5670485..94b43ff 100644 --- a/src/map.c +++ b/src/map.c @@ -5,7 +5,7 @@ #include extern Map *worldRPG[]; -extern ExtraData *extraRPG[]; +//extern ExtraData *extraRPG[]; void render_map(Game *game) { diff --git a/src/player.c b/src/player.c index 542596f..737639b 100644 --- a/src/player.c +++ b/src/player.c @@ -27,13 +27,6 @@ const char damage_taken_walkable[WALKABLE_TILE_MAX] = { }; extern bopti_image_t demo_player_img; -extern bopti_image_t NPC_Icon_img; -extern bopti_image_t SGN_Icon_img; -extern bopti_image_t INFO_Icon_img; - - -extern Dialog dialogRPG[]; - void player_draw(Game *game) { Player *player = &game->player; @@ -86,6 +79,12 @@ void player_move(Game *game, Direction direction) { } +extern bopti_image_t demo_player_img; +extern bopti_image_t NPC_Icon_img; +extern bopti_image_t SGN_Icon_img; +extern bopti_image_t INFO_Icon_img; + + void player_action(Game *game) { if( game->player.isDoingAction ) return; /* alreday doing something */ @@ -96,10 +95,11 @@ void player_action(Game *game) { ExtraData *currentData = &game->map_level->extradata[game->player.whichAction]; - /* we collect the information */ - char *text = dialogRPG[ currentData->dialogID].dialog; /* we use the correct image as per the class of the item */ + bopti_image_t *face; + /* we use the correct image as per the class of the item */ + if (strcmp("INFO", currentData->type)==0) face = &INFO_Icon_img; @@ -109,25 +109,9 @@ void player_action(Game *game) { face = &SGN_Icon_img; else face = &demo_player_img; - /* we treat the action - i.e. we show a dialog */ - if (dialogRPG[ currentData->dialogID ].isQuestion == 1) /* we have to manage a question */ - { - char *choices = dialogRPG[ currentData->dialogID].choices ; - char *conclusion1 = dialogRPG[currentData->dialogID].conclusion1; - char *conclusion2 = dialogRPG[currentData->dialogID].conclusion2; + uint32_t dialogStart = currentData->dialogID; - int answer = showtext_dialog_ask( game, face, text, true, true, choices, 2, 0 ); - - /* TO DO we need to split the strings conclusion1 and conclusion2 */ - /* to extract the "gift" part */ - - if (answer==0) showtext_dialog( game, face, conclusion1, true, true ); - else showtext_dialog( game, face, conclusion2, true, true ); - } - else - { - showtext_dialog( game, face, text, true, true ); - } + initiate_dialog_sequence( game, face, dialogStart ); /* when done we release the occupied status of the player */ game->player.isDoingAction = false;