mirror of https://github.com/bgiraudr/Adoranda.git
change the way dialogs work
update converters.py thanks to Lephenixnoir now dialogs are inside the map directly on Tiled
This commit is contained in:
parent
0477f1210c
commit
39648a7353
|
@ -23,7 +23,7 @@ add_custom_command(
|
|||
|
||||
set(SOURCES
|
||||
src/main.c
|
||||
src/character.c
|
||||
src/talkable.c
|
||||
src/vec2.c
|
||||
src/game.c
|
||||
src/engine.c
|
||||
|
@ -39,12 +39,6 @@ set(ASSETS_cg
|
|||
assets-cg/maps/testCarte.json
|
||||
assets-cg/maps/inside/interior_1.json
|
||||
assets-cg/spritesheet.png
|
||||
assets-cg/characters/Tituya.char
|
||||
assets-cg/characters/Lephenixnoir.char
|
||||
assets-cg/characters/KikooDX.char
|
||||
assets-cg/characters/Massena.char
|
||||
assets-cg/characters/Tituya2.char
|
||||
assets-cg/characters/PancarteVille.char
|
||||
)
|
||||
|
||||
fxconv_declare_assets(${ASSETS} ${ASSETS_fx} ${ASSETS_cg} WITH_METADATA)
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
41
|
||||
10
|
||||
KikooDX
|
||||
Je te rassure, pas de Pokemon !
|
|
@ -1,4 +0,0 @@
|
|||
50
|
||||
30
|
||||
Lephenixnoir
|
||||
Regarde ! Je n'ai pas de reflet !
|
|
@ -1,4 +0,0 @@
|
|||
2
|
||||
9
|
||||
Massena
|
||||
C'est une belle ville non ?
|
|
@ -1,4 +0,0 @@
|
|||
10
|
||||
20
|
||||
Planete City
|
||||
90+E FTW
|
|
@ -1,4 +0,0 @@
|
|||
37
|
||||
32
|
||||
Tituya
|
||||
J'ai toujours aimé ce pont;Pas toi ?
|
|
@ -1,4 +0,0 @@
|
|||
52
|
||||
2
|
||||
Tituya
|
||||
La belle montagne !
|
|
@ -1,3 +0,0 @@
|
|||
*.char:
|
||||
custom-type: character
|
||||
name_regex: (.*)\.char character_\1
|
|
@ -5,9 +5,6 @@ def convert(input, output, params, target):
|
|||
if params["custom-type"] == "map":
|
||||
convert_map(input, output, params, target)
|
||||
return 0
|
||||
elif params["custom-type"] == "character":
|
||||
convert_character(input, output, params, target)
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
|
||||
|
@ -16,7 +13,7 @@ def convert_map(input, output, params, target):
|
|||
TILE_SOLID = 1
|
||||
TILE_DOOR_IN = 2
|
||||
TILE_DOOR_OUT = 3
|
||||
TILE_CHARACTER = 4
|
||||
TILE_TALKABLE = 4
|
||||
|
||||
TILE_BRIDGE = -1 #only for bridge detection to avoid solid behind
|
||||
|
||||
|
@ -52,8 +49,8 @@ def convert_map(input, output, params, target):
|
|||
value = TILE_DOOR_IN
|
||||
elif type == "door_out":
|
||||
value = TILE_DOOR_OUT
|
||||
elif type == "character":
|
||||
value = TILE_CHARACTER
|
||||
elif type == "talkable":
|
||||
value = TILE_TALKABLE
|
||||
elif type == "bridge":
|
||||
value = TILE_BRIDGE
|
||||
else:
|
||||
|
@ -65,11 +62,40 @@ def convert_map(input, output, params, target):
|
|||
|
||||
#Extract from the json the width, height and layers of the map
|
||||
w, h = data["width"], data["height"]
|
||||
nblayer = len(data["layers"])
|
||||
indexObjectlayer = None
|
||||
|
||||
o = fxconv.ObjectData()
|
||||
o += fxconv.u32(w) + fxconv.u32(h) + fxconv.u32(nblayer)
|
||||
o += fxconv.ref(f"img_{nameTilesetFree}")
|
||||
nbTilelayer = len(data["layers"])
|
||||
for i in range(nbTilelayer):
|
||||
try:
|
||||
data["layers"][i]["data"]
|
||||
#nbTileLayer is the number of "true" layers (without ObjectsLayer)
|
||||
nbTilelayer = i+1
|
||||
except KeyError:
|
||||
indexObjectlayer = i
|
||||
break
|
||||
|
||||
if indexObjectlayer != None:
|
||||
nbDialog = len(data["layers"][indexObjectlayer]["objects"])
|
||||
else:
|
||||
nbDialog = 0
|
||||
|
||||
structMap = fxconv.Structure()
|
||||
structMap += fxconv.u32(w) + fxconv.u32(h) + fxconv.u32(nbTilelayer) + fxconv.u32(nbDialog)
|
||||
structMap += fxconv.ref(f"img_{nameTilesetFree}")
|
||||
|
||||
dialogs = fxconv.Structure()
|
||||
if indexObjectlayer != None:
|
||||
#generate all of the dialog
|
||||
for i in data["layers"][indexObjectlayer]["objects"]:
|
||||
dialogs += fxconv.u32(int(i["x"]/i["width"]))
|
||||
#Tiled seem to start at the bottom y of the object
|
||||
#So if tile is 16 px wide, you would start at line y = 1
|
||||
dialogs += fxconv.u32(int(i["y"]/i["width"])-1)
|
||||
for j in i["properties"]:
|
||||
if(j["value"] == ""): j["value"] = " "
|
||||
dialogs += fxconv.string(j["value"])
|
||||
|
||||
structMap += fxconv.ptr(dialogs)
|
||||
|
||||
#generation of the collision map (take the maximum of the layer except for bridges)
|
||||
#bridges are always walkable
|
||||
|
@ -78,7 +104,7 @@ def convert_map(input, output, params, target):
|
|||
maxValue = 0
|
||||
bridge = False
|
||||
for x in range(w*h):
|
||||
for i in range(nblayer):
|
||||
for i in range(nbTilelayer):
|
||||
value = tile_value.get(data["layers"][i]["data"][x])
|
||||
if value == None: value = TILE_AIR
|
||||
if value > maxValue: maxValue = value
|
||||
|
@ -91,27 +117,16 @@ def convert_map(input, output, params, target):
|
|||
info_map += fxconv.u16(maxValue)
|
||||
maxValue = 0
|
||||
bridge = False
|
||||
o += fxconv.ref(info_map)
|
||||
structMap += fxconv.ref(info_map)
|
||||
|
||||
#generate the array of tiles from the layer
|
||||
for layer in data["layers"]:
|
||||
for i in range(nbTilelayer):
|
||||
layer_data = bytes()
|
||||
|
||||
layer = data["layers"][i]
|
||||
for tile in layer["data"]:
|
||||
layer_data += fxconv.u16(tile)
|
||||
|
||||
o += fxconv.ref(layer_data)
|
||||
|
||||
structMap += fxconv.ref(layer_data)
|
||||
|
||||
#generate !
|
||||
fxconv.elf(o, output, "_" + params["name"], **target)
|
||||
|
||||
def convert_character(input, output, params, target):
|
||||
with open(input,"r") as dialog:
|
||||
file = dialog.read().splitlines()
|
||||
|
||||
o = fxconv.ObjectData()
|
||||
o += fxconv.u32((int)(file[0])) + fxconv.u32((int)(file[1]))
|
||||
o += fxconv.ref(bytes(file[2], 'utf-8') + bytes(1)) #bytes(1) is necessary to end a char
|
||||
o += fxconv.ref(bytes(file[3], 'utf-8') + bytes(1))
|
||||
|
||||
fxconv.elf(o, output, "_" + params["name"], **target)
|
||||
fxconv.elf(structMap, output, "_" + params["name"], **target)
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.5" tiledversion="1.7.2" orientation="orthogonal" renderorder="right-down" width="12" height="10" tilewidth="16" tileheight="16" infinite="0" nextlayerid="10" nextobjectid="25">
|
||||
<map version="1.5" tiledversion="1.7.2" orientation="orthogonal" renderorder="right-down" width="12" height="10" tilewidth="16" tileheight="16" infinite="0" nextlayerid="11" nextobjectid="30">
|
||||
<editorsettings>
|
||||
<export target="interior_1.json" format="json"/>
|
||||
</editorsettings>
|
||||
|
@ -46,4 +46,12 @@
|
|||
0,0,0,0,0,0,0,0,0,0,0,0
|
||||
</data>
|
||||
</layer>
|
||||
<objectgroup id="10" name="dialog">
|
||||
<object id="25" gid="267" x="112" y="112" width="16" height="16">
|
||||
<properties>
|
||||
<property name="name" value="Tituya"/>
|
||||
<property name="text" value="Salutation !"/>
|
||||
</properties>
|
||||
</object>
|
||||
</objectgroup>
|
||||
</map>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.5" tiledversion="1.7.2" orientation="orthogonal" renderorder="right-down" width="100" height="38" tilewidth="16" tileheight="16" infinite="0" nextlayerid="9" nextobjectid="25">
|
||||
<map version="1.5" tiledversion="1.7.2" orientation="orthogonal" renderorder="right-down" width="100" height="38" tilewidth="16" tileheight="16" infinite="0" nextlayerid="11" nextobjectid="38">
|
||||
<editorsettings>
|
||||
<export target="testCarte.json" format="json"/>
|
||||
</editorsettings>
|
||||
|
@ -88,4 +88,36 @@
|
|||
294,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,381,382,383,381,382,383,381,382,383,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||
</data>
|
||||
</layer>
|
||||
<objectgroup id="10" name="text">
|
||||
<object id="33" gid="267" x="592" y="528" width="16" height="16">
|
||||
<properties>
|
||||
<property name="name" value="Tituya"/>
|
||||
<property name="text" value="J'ai toujours aimé ce pont;Pas toi ?"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="34" gid="267" x="704" y="368" width="16" height="16">
|
||||
<properties>
|
||||
<property name="name" value="Pancarte"/>
|
||||
<property name="text" value="Ne vous aventurez pas trop loin !"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="35" gid="267" x="720" y="368" width="16" height="16">
|
||||
<properties>
|
||||
<property name="name" value=""/>
|
||||
<property name="text" value="Une belle pancarte <3"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="36" gid="267" x="800" y="496" width="16" height="16">
|
||||
<properties>
|
||||
<property name="name" value="Lephenixnoir"/>
|
||||
<property name="text" value="Regarde ! Je n'ai pas de reflet !"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="37" gid="267" x="656" y="176" width="16" height="16">
|
||||
<properties>
|
||||
<property name="name" value="KikooDX"/>
|
||||
<property name="text" value="Je te rassure, pas de Pokémon !"/>
|
||||
</properties>
|
||||
</object>
|
||||
</objectgroup>
|
||||
</map>
|
||||
|
|
|
@ -19,13 +19,13 @@
|
|||
<tile id="45" type="solid"/>
|
||||
<tile id="46" type="solid"/>
|
||||
<tile id="47" type="solid"/>
|
||||
<tile id="48" type="character"/>
|
||||
<tile id="49" type="solid"/>
|
||||
<tile id="48" type="talkable"/>
|
||||
<tile id="49" type="talkable"/>
|
||||
<tile id="52" type="solid"/>
|
||||
<tile id="53" type="solid"/>
|
||||
<tile id="54" type="solid"/>
|
||||
<tile id="56" type="character"/>
|
||||
<tile id="57" type="character"/>
|
||||
<tile id="56" type="talkable"/>
|
||||
<tile id="57" type="talkable"/>
|
||||
<tile id="78" type="solid"/>
|
||||
<tile id="79" type="solid"/>
|
||||
<tile id="80" type="solid"/>
|
||||
|
@ -88,6 +88,12 @@
|
|||
<tile id="263" type="solid"/>
|
||||
<tile id="264" type="solid"/>
|
||||
<tile id="265" type="solid"/>
|
||||
<tile id="266" type="text">
|
||||
<properties>
|
||||
<property name="name" value=""/>
|
||||
<property name="text" value=""/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="268" type="solid"/>
|
||||
<tile id="269" type="solid"/>
|
||||
<tile id="270" type="solid"/>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
@ -1,17 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
struct Character {
|
||||
/*the position of the character*/
|
||||
int x, y;
|
||||
/*the name*/
|
||||
char *name;
|
||||
/*the text to say*/
|
||||
char *dialog;
|
||||
};
|
||||
|
||||
/*draw the dialog of a specified character*/
|
||||
void draw_dialog(struct Character *character);
|
||||
/*find the character using the player's position*/
|
||||
struct Character* get_character_xy(struct Character *characters[], int x, int y);
|
||||
/*get the characters for a specified map*/
|
||||
struct Character** get_map_characters(int id);
|
|
@ -6,8 +6,6 @@ struct Game {
|
|||
struct Map *map;
|
||||
/*the player*/
|
||||
struct Player *player;
|
||||
/*list of all the characters on the map*/
|
||||
struct Character **characters;
|
||||
/*the camera*/
|
||||
struct Camera camera;
|
||||
/*the background color*/
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
|
||||
struct Map {
|
||||
/*width, height and the number of layer of the map (max 2)*/
|
||||
int w, h, nb_layers;
|
||||
int w, h, nb_layers, dialog_count;
|
||||
/*the tileset to use*/
|
||||
bopti_image_t *tileset;
|
||||
/*list of all the dialog*/
|
||||
struct Talkable *dialogs;
|
||||
/*state of each tile on the map (solid, air ...)*/
|
||||
short *info_map;
|
||||
/*list of all the tiles*/
|
||||
|
@ -19,7 +21,7 @@ enum map_state {
|
|||
TILE_SOLID = 1,
|
||||
TILE_DOOR_IN = 2,
|
||||
TILE_DOOR_OUT = 3,
|
||||
TILE_CHARACTER = 4,
|
||||
TILE_TALKABLE = 4,
|
||||
};
|
||||
|
||||
/*check if a tile is walkable*/
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
#include "map.h"
|
||||
struct Talkable {
|
||||
/*the position of the tile*/
|
||||
int x, y;
|
||||
/*the name*/
|
||||
char *name;
|
||||
/*the text to display*/
|
||||
char *text;
|
||||
};
|
||||
|
||||
/*draw the dialog of a specified talkable tile*/
|
||||
void draw_dialog(struct Talkable *character);
|
||||
/*find the talkable tile using the player's position*/
|
||||
struct Talkable* get_dialog_xy(struct Map *map, int x, int y);
|
|
@ -1,66 +0,0 @@
|
|||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
#include <string.h>
|
||||
#include "character.h"
|
||||
#include "engine.h"
|
||||
#include "map.h"
|
||||
#include "util.h"
|
||||
|
||||
struct Character character_default = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.name = "default name",
|
||||
.dialog = "default dialog"
|
||||
};
|
||||
|
||||
/*draw the dialog of a specified character*/
|
||||
void draw_dialog(struct Character *character) {
|
||||
const char *delim = ";";
|
||||
|
||||
char *str = strdup(character->dialog);
|
||||
char *curr_line = strtok(str, delim);
|
||||
|
||||
while(curr_line != NULL) {
|
||||
drect(20,10,370,80,C_WHITE);
|
||||
dprint(25,20, C_BLACK, "%s", character->name);
|
||||
dprint(25,40, C_BLACK, "%s", curr_line);
|
||||
dupdate();
|
||||
curr_line = strtok(NULL, delim);
|
||||
wait_for_input(KEY_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
/*find the character using the player's position*/
|
||||
struct Character* get_character_xy(struct Character *characters[], int x, int y) {
|
||||
int i = 0;
|
||||
while(strcmp(characters[i]->name,"default name") != 0) {
|
||||
if(characters[i]->x == x && characters[i]->y == y) return characters[i];
|
||||
i++;
|
||||
}
|
||||
return &character_default;
|
||||
}
|
||||
|
||||
/*get the characters for a specified map*/
|
||||
struct Character** get_map_characters(int id) {
|
||||
if(id == 1) {
|
||||
extern struct Character character_Tituya;
|
||||
extern struct Character character_Lephenixnoir;
|
||||
extern struct Character character_Tituya2;
|
||||
extern struct Character character_KikooDX;
|
||||
extern struct Character character_Massena;
|
||||
extern struct Character character_PancarteVille;
|
||||
|
||||
static struct Character *characters[] = {
|
||||
&character_Tituya,
|
||||
&character_Lephenixnoir,
|
||||
&character_Massena,
|
||||
&character_Tituya2,
|
||||
&character_KikooDX,
|
||||
&character_PancarteVille,
|
||||
&character_default,
|
||||
};
|
||||
return characters;
|
||||
}
|
||||
static struct Character *characters[] = {};
|
||||
return characters;
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
#include "player.h"
|
||||
#include "animation.h"
|
||||
#include "define.h"
|
||||
#include "character.h"
|
||||
#include "talkable.h"
|
||||
#include "camera.h"
|
||||
#include "vec2.h"
|
||||
|
||||
|
@ -107,11 +107,11 @@ void engine_set_background(struct Game *game, int color) {
|
|||
/*make an interaction with something*/
|
||||
void engine_action(struct Game const *game, int action) {
|
||||
if(action == ACTION_SHIFT) {
|
||||
if(player_facing(game) == TILE_CHARACTER) {
|
||||
if(player_facing(game) == TILE_TALKABLE) {
|
||||
int direction = game->player->direction;
|
||||
int dx = (direction == DIR_RIGHT) - (direction == DIR_LEFT);
|
||||
int dy = (direction == DIR_DOWN) - (direction == DIR_UP);
|
||||
draw_dialog(get_character_xy(game->characters, game->player->pos.x + dx, game->player->pos.y + dy));
|
||||
draw_dialog(get_dialog_xy(game->map, game->player->pos.x + dx, game->player->pos.y + dy));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "engine.h"
|
||||
#include "player.h"
|
||||
#include "animation.h"
|
||||
#include "character.h"
|
||||
#include "camera.h"
|
||||
#include "define.h"
|
||||
|
||||
|
@ -44,7 +43,6 @@ int main(void) {
|
|||
.camera = camera_new(&player.pos_visual),
|
||||
.background = C_WHITE
|
||||
};
|
||||
game.characters = get_map_characters(1);
|
||||
|
||||
/*Timer*/
|
||||
static volatile int tick = 1;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
int map_walkable(struct Map const *map, int x, int y) {
|
||||
int tile = map->info_map[x + map->w * y];
|
||||
if(x < 0 || x > map->w-1 || y < 0 || y > map->h-1) return 0;
|
||||
return (tile != TILE_SOLID && tile != TILE_CHARACTER);
|
||||
return (tile != TILE_SOLID && tile != TILE_TALKABLE);
|
||||
}
|
||||
|
||||
/*get the tile under the player*/
|
||||
|
@ -20,7 +20,6 @@ void generate_interior_map(struct Game *game) {
|
|||
extern struct Map in_1;
|
||||
game->map = &in_1;
|
||||
set_player_xy(game->player, 3,3);
|
||||
//game->camera.target = &VEC2F(DWIDTH/2, DHEIGHT/2);
|
||||
game->camera.pos.x = in_1.w/2 * TILE_SIZE + game->player->x_mid;
|
||||
game->camera.pos.y = in_1.h/2 * TILE_SIZE + game->player->y_mid;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
#include <string.h>
|
||||
#include "talkable.h"
|
||||
#include "engine.h"
|
||||
#include "map.h"
|
||||
#include "util.h"
|
||||
|
||||
struct Talkable default_value = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.name = "default name",
|
||||
.text = "default dialog"
|
||||
};
|
||||
|
||||
/*draw the dialog of a specified talkable tile*/
|
||||
void draw_dialog(struct Talkable *talkable) {
|
||||
const char *delim = ";";
|
||||
|
||||
char *str = strdup(talkable->text);
|
||||
char *curr_line = strtok(str, delim);
|
||||
|
||||
while(curr_line != NULL) {
|
||||
drect(20,10,370,80,C_WHITE);
|
||||
dprint(25,20, C_BLACK, "%s", talkable->name);
|
||||
dprint(25,40, C_BLACK, "%s", curr_line);
|
||||
dupdate();
|
||||
curr_line = strtok(NULL, delim);
|
||||
wait_for_input(KEY_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
/*find the talkable tile using the player's position*/
|
||||
struct Talkable* get_dialog_xy(struct Map *map, int x, int y) {
|
||||
int i = 0;
|
||||
while(i < map->dialog_count) {
|
||||
if(map->dialogs[i].x == x && map->dialogs[i].y == y) return &map->dialogs[i];
|
||||
i++;
|
||||
}
|
||||
return &default_value;
|
||||
}
|
Loading…
Reference in New Issue