diff --git a/assets-cg/converters.py b/assets-cg/converters.py index 753e2dd..2c5af47 100644 --- a/assets-cg/converters.py +++ b/assets-cg/converters.py @@ -26,6 +26,7 @@ def convert_map(input, output, params, target): DIALOG_LAYOUT = "dialog" TELEPORTER_LAYOUT = "teleporter" + ZONE_LAYOUT = "zone" data = json.load(open(input, "r")) @@ -79,9 +80,11 @@ def convert_map(input, output, params, target): nbDialog = 0 nbTelep = 0 + nbZone = 0 structMap = fxconv.Structure() dialogs = fxconv.Structure() teleporter = fxconv.Structure() + zone = fxconv.Structure() for layer in objectLayers: if layer.get("name") == DIALOG_LAYOUT: @@ -90,14 +93,18 @@ def convert_map(input, output, params, target): elif layer.get("name") == TELEPORTER_LAYOUT: nbTelep = len(layer["objects"]) teleporter = parseTeleporter(layer) + elif layer.get("name") == ZONE_LAYOUT: + nbZone = len(layer["objects"]) + zone = parseZone(layer) else: print("UNKNOWN LAYOUT FOUND : " + layer.get("name")) - structMap += fxconv.u32(w) + fxconv.u32(h) + fxconv.u32(nbTilelayer) + fxconv.u32(nbDialog) + fxconv.u32(nbTelep) + structMap += fxconv.u32(w) + fxconv.u32(h) + fxconv.u32(nbTilelayer) + fxconv.u32(nbDialog) + fxconv.u32(nbTelep) + fxconv.u32(nbZone) structMap += fxconv.ref(f"img_{nameTilesetFree}") structMap += fxconv.u32(tileset_size) structMap += fxconv.ptr(dialogs) structMap += fxconv.ptr(teleporter) + structMap += fxconv.ptr(zone) #generation of the collision map (take the maximum of the layer except for bridges) #bridges are always walkable @@ -168,6 +175,24 @@ def parseTeleporter(layer): raise Exception("parseTeleporter() : Un téléporteur est mal configuré") return teleporter +def parseZone(layer): + zone = fxconv.Structure() + for i in layer["objects"]: + origin = (int(i['x']/16), int(i['y']/16)) + to = (int(origin[0]+i['width']/16)-1, int(origin[1]+i['height']/16)-1) + + zone += fxconv.u32(origin[0]) + zone += fxconv.u32(origin[1]) + zone += fxconv.u32(to[0]) + zone += fxconv.u32(to[1]) + + try: + zone += fxconv.u32(i["properties"][0]["value"]) + except KeyError: + print("parseZone() : Zone sans niveau de référence, passage automatique à -1") + zone += fxconv.u32(-1) + return zone + def convert_capa(input, output, params, target): with open(input, "r") as file: capacities = fxconv.Structure() diff --git a/assets-cg/maps/inside/2.tmx b/assets-cg/maps/inside/2.tmx index d9a6bb1..29be832 100644 --- a/assets-cg/maps/inside/2.tmx +++ b/assets-cg/maps/inside/2.tmx @@ -1,5 +1,5 @@ - + diff --git a/assets-cg/maps/testCarte.tmx b/assets-cg/maps/testCarte.tmx index 5be6415..9a7016a 100644 --- a/assets-cg/maps/testCarte.tmx +++ b/assets-cg/maps/testCarte.tmx @@ -1,5 +1,5 @@ - + @@ -201,4 +201,16 @@ + + + + + + + + + + + + diff --git a/include/map.h b/include/map.h index d7e85fa..24ce39a 100644 --- a/include/map.h +++ b/include/map.h @@ -8,15 +8,22 @@ struct Teleporter { int x2, y2; }; +struct Zone { + int start_x, start_y; + int end_x, end_y; + int level; +}; + struct Map { /*width, height and the number of layer of the map*/ - int w, h, nb_layers, dialog_count, teleporter_count; + int w, h, nb_layers, dialog_count, teleporter_count, zone_count; /*the tileset to use*/ bopti_image_t *tileset; int tileset_size; /*list of all the dialog*/ struct Talkable *dialogs; struct Teleporter *teleporters; + struct Zone *zones; /*state of each tile on the map (solid, air ...)*/ short *info_map; /*list of all the tiles*/ @@ -44,4 +51,6 @@ void set_map(struct Game *game, int id); struct Vec2 locate_tile(struct Map const *map, int tile); -struct Teleporter get_teleporter_xy(struct Map *map, struct Vec2 pos); \ No newline at end of file +struct Teleporter get_teleporter_xy(struct Map *map, struct Vec2 pos); + +int get_level_zone(struct Player *player, struct Map *map); \ No newline at end of file diff --git a/src/battle.c b/src/battle.c index 421fb81..f264c96 100644 --- a/src/battle.c +++ b/src/battle.c @@ -13,6 +13,9 @@ extern bopti_image_t img_dialogue; +/** + * create a new battle + */ void create_battle(struct Game *game) { game->player->stats.pv = game->player->stats.max_pv; struct Monster *monster = generate_monster(game); @@ -21,6 +24,9 @@ void create_battle(struct Game *game) { finish_battle(status, game, monster); } +/** + * Launch the battle + */ int battle(struct Player *player, struct Monster *monster) { int tour = 0; int selection = 0; @@ -73,6 +79,42 @@ int battle(struct Player *player, struct Monster *monster) { return LOSE; } +/*When a battle is finish, compute xp gain and gain level*/ +void finish_battle(int status, struct Game *game, struct Monster *monster) { + if(status == WIN) { + //gain d'xp + int xp = ceil((monster->stats->xp*monster->stats->level*1.5)/7); + + dimage(42,DHEIGHT-75,&img_dialogue); + + dprint(50,DHEIGHT-75/2-10, C_BLACK, "Vous remportez %d points d'experience", xp); + dupdate(); + wait_for_input(KEY_SHIFT); + + game->player->stats.xp += xp; + + //niveau suivant une progession N³ + int calc_level = (int)pow(game->player->stats.xp, 0.33); + for(int i = game->player->stats.level; i < calc_level; i++) { + draw_battle(game->player, monster); + dimage(42,DHEIGHT-75,&img_dialogue); + dprint(50,DHEIGHT-75/2-10,C_BLACK,"Vous passez au niveau %d !", i+1); + dupdate(); + wait_for_input(KEY_SHIFT); + } + game->player->stats.level = calc_level; + set_stats_level_from(&game->player->base_stats, &game->player->stats); + + } else if(status == LOSE) { + game->player->stats.pv = 0; + } + + free_monster(monster); +} + +/** + * Select a move in the list + */ int select_move(struct Player *player, struct Monster *monster, int prec_selected) { const int nbMove = get_nb_moves(player); int selection = prec_selected; @@ -157,36 +199,4 @@ void draw_executed_move(struct Move *move, struct Monster *monster, int is_monst void draw_crit() { dimage(42,DHEIGHT-75,&img_dialogue); dprint(50,DHEIGHT-75/2-10, C_BLACK, "Coup critique !"); -} - -void finish_battle(int status, struct Game *game, struct Monster *monster) { - if(status == WIN) { - //gain d'xp - int xp = ceil((monster->stats->xp*monster->stats->level*1.5)/7); - - dimage(42,DHEIGHT-75,&img_dialogue); - - dprint(50,DHEIGHT-75/2-10, C_BLACK, "Vous remportez %d points d'experience", xp); - dupdate(); - wait_for_input(KEY_SHIFT); - - game->player->stats.xp += xp; - - //niveau suivant une progession N³ - int calc_level = (int)pow(game->player->stats.xp, 0.33); - for(int i = game->player->stats.level; i < calc_level; i++) { - draw_battle(game->player, monster); - dimage(42,DHEIGHT-75,&img_dialogue); - dprint(50,DHEIGHT-75/2-10,C_BLACK,"Vous passez au niveau %d !", i+1); - dupdate(); - wait_for_input(KEY_SHIFT); - } - game->player->stats.level = calc_level; - set_stats_level_from(&game->player->base_stats, &game->player->stats); - - } else if(status == LOSE) { - game->player->stats.pv = 0; - } - - free_monster(monster); } \ No newline at end of file diff --git a/src/map.c b/src/map.c index d4611cd..7b7a738 100644 --- a/src/map.c +++ b/src/map.c @@ -65,4 +65,14 @@ struct Teleporter get_teleporter_xy(struct Map *map, struct Vec2 pos) { i++; } return map->teleporters[0]; +} + +int get_level_zone(struct Player *player, struct Map *map) { + const int posx = player->pos.x; + const int posy = player->pos.y; + for(int i = 0; i < map->zone_count; i++) { + const struct Zone zone = map->zones[i]; + if(zone.start_x <= posx && zone.start_y <= posy && zone.end_x >= posx && zone.end_y >= posy) return zone.level; + } + return -1; } \ No newline at end of file diff --git a/src/monster.c b/src/monster.c index c2a02c9..4aa8fa2 100644 --- a/src/monster.c +++ b/src/monster.c @@ -5,14 +5,21 @@ #include "stats.h" #include "capacite.h" #include "player.h" +#include "map.h" struct Monster *generate_monster(struct Game *game) { extern struct Monster monster_test; struct Monster *monster = copyMonster(&monster_test); - // TODO formule pour niveau du monstre adverse - monster->stats->level = game->player->stats.level; + + int level_zone = get_level_zone(game->player, game->map); + //En cas d'erreur / aucune zone trouvée + if(level_zone == -1) { + level_zone = game->player->stats.level; + } + + monster->stats->level = level_zone; set_stats_level(monster->stats); monster->stats->pv = monster->stats->max_pv; return monster;