Compare commits

...

3 Commits

Author SHA1 Message Date
bgiraudr 90503c7e97 Areas can now handle events 5 months ago
bgiraudr 53bf0daaa3 add some events 5 months ago
bgiraudr 8c3138209b Items can have events 5 months ago
  1. 1
      CMakeLists.txt
  2. 38
      assets-cg/converters.py
  3. 6
      assets-cg/items/1.json
  4. 5
      assets-cg/items/2.json
  5. 15
      assets-cg/maps/testCarte.tmx
  6. 22
      include/inventory.h
  7. 22
      include/item.h
  8. 1
      include/map.h
  9. 4
      include/player.h
  10. 3
      include/talkable.h
  11. 11
      src/engine.c
  12. 28
      src/event.c
  13. 38
      src/inventory.c
  14. 38
      src/item.c
  15. 8
      src/monster.c
  16. 55
      src/player.c
  17. 42
      src/talkable.c

@ -46,6 +46,7 @@ set(SOURCES
src/monster.c
src/event.c
src/inventory.c
src/item.c
)
set(ASSETS_cg

@ -189,28 +189,25 @@ def parseZone(layer):
zone += fxconv.u32(origin[1])
zone += fxconv.u32(to[0])
zone += fxconv.u32(to[1])
zone += fxconv.string(i["properties"][0]["value"]) #event
print(i["properties"][0]["value"])
monsters = bytes()
try:
zone += fxconv.u32(i["properties"][0]["value"])
monster_list_raw = i["properties"][1]["value"].split(";")
monster_list = []
#x-y notation generate an array
for i in monster_list_raw:
if "-" in i:
a = i.split("-")
monster_list.extend(list(range(int(a[0]),int(a[1])+1)))
else:
monster_list.append(int(i))
zone += fxconv.u32(len(monster_list))
for j in monster_list:
monsters += fxconv.u16(int(j))
except IndexError:
raise Exception(f"parseZone() : La zone {origin};{to} n'a pas de monstres associés")
except KeyError:
print(f"parseZone() : Zone {origin};{to} sans niveau de référence, passage automatique à -1")
zone += fxconv.u32(-1)
zone += fxconv.u32(int(i["properties"][1]["value"]) if i["properties"][1]["value"] != "" else -1) #level
monster_list_raw = []
if i["properties"][2]["value"] != "": monster_list_raw = i["properties"][2]["value"].split(";") #monster list
monster_list = []
#x-y notation generate an array
for i in monster_list_raw:
if "-" in i:
a = i.split("-")
monster_list.extend(list(range(int(a[0]),int(a[1])+1)))
else:
monster_list.append(int(i))
zone += fxconv.u32(len(monster_list))
for j in monster_list:
monsters += fxconv.u16(int(j))
zone += fxconv.ptr(monsters)
return zone
@ -313,6 +310,7 @@ def convert_items(input, output, params, target):
item += fxconv.u32(data["id"])
item += fxconv.string(data["description"])
item += fxconv.ptr(f"img_{data['sprite']}")
item += fxconv.string(";".join(data["action"]))
items += fxconv.ptr(item)
except KeyError:
raise Exception(f"convert_items() : L'item {data['name']} est mal configuré")

@ -2,5 +2,9 @@
"name":"Test1",
"id":1,
"sprite":"item",
"description":"test1"
"description":"Redonne 20HP",
"action":[
"pp:all",
"give:Obj2*3"
]
}

@ -2,5 +2,8 @@
"name":"Obj2",
"id":2,
"sprite":"item2",
"description":"test2"
"description":"test2",
"action":[
"pp:3"
]
}

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.8" tiledversion="1.8.4" orientation="orthogonal" renderorder="right-down" width="100" height="38" tilewidth="16" tileheight="16" infinite="0" nextlayerid="14" nextobjectid="63">
<map version="1.8" tiledversion="1.8.4" orientation="orthogonal" renderorder="right-down" width="100" height="38" tilewidth="16" tileheight="16" infinite="0" nextlayerid="14" nextobjectid="65">
<editorsettings>
<export target="testCarte.json" format="json"/>
</editorsettings>
@ -188,7 +188,7 @@
<object id="62" gid="267" x="448" y="432" width="16" height="16">
<properties>
<property name="name" value="Pancarte"/>
<property name="text" value="Cadeau;~give:1"/>
<property name="text" value="Cadeau;~give:Obj2"/>
</properties>
</object>
</objectgroup>
@ -216,12 +216,21 @@
<objectgroup id="13" name="zone">
<object id="57" x="400" y="464" width="32" height="48">
<properties>
<property name="event" value=""/>
<property name="level" type="int" value="30"/>
<property name="monsters" value="1"/>
</properties>
</object>
<object id="58" x="304" y="560" width="112" height="32">
<object id="58" x="256" y="464" width="112" height="32">
<properties>
<property name="event" value="xp:30"/>
<property name="level" value=""/>
<property name="monsters" value=""/>
</properties>
</object>
<object id="64" x="304" y="560" width="112" height="32">
<properties>
<property name="event" value=""/>
<property name="level" type="int" value="5"/>
<property name="monsters" value="1;2"/>
</properties>

@ -1,27 +1,15 @@
#pragma once
#include "define.h"
#include <gint/display.h>
struct Item {
char *name;
int id;
char *description;
bopti_image_t *sprite;
};
struct Items {
int nbItems;
struct Item *items[];
};
#include "game.h"
#include <stdbool.h>
struct Inventory {
int nbItems;
struct Item *items[NB_PLAYER_ITEMS];
};
struct Item *get_item_id(int id);
bool add_item_to_inventory(struct Inventory *inventory, struct Item *item);
bool add_item_to_inventory(struct Game *game, struct Inventory *inventory, struct Item *item);
int get_first_free_space(struct Inventory *inventory);
void remove_item_pos(struct Inventory *inventory, int pos);
void display_inventory(struct Inventory *inventory);
int open_inventory(struct Inventory *inventory, char* context);
int open_inventory(struct Game *game, struct Inventory *inventory, char* context, bool keep_open);

@ -0,0 +1,22 @@
#pragma once
#include "game.h"
#include "inventory.h"
#include <gint/display.h>
struct Item {
char *name;
int id;
char *description;
bopti_image_t *sprite;
char *action;
};
struct Items {
int nbItems;
struct Item *items[];
};
struct Item *get_item_id(int id);
void select_item(struct Game *game, int pos);
void remove_item_pos(struct Inventory *inventory, int pos);
struct Item *get_item_from_name(const char *name);

@ -11,6 +11,7 @@ struct Teleporter {
struct Zone {
int start_x, start_y;
int end_x, end_y;
char *event;
int level;
int nbMonsters;
short *monsters;

@ -52,4 +52,6 @@ void draw_ui(struct Player *player);
int get_nb_moves(struct Player *player);
void reset_pp(struct Player *player);
void check_level(struct Player *player, int prec_level);
void add_xp(struct Player *player, int xp);
void add_xp(struct Player *player, int xp);
int select_capacity(struct Player *player, char* context, bool allow_back);
void add_pp(struct Player *player, int amount);

@ -16,4 +16,5 @@ void draw_dialog(struct Game *game);
/*find the talkable tile using the player's position*/
struct Talkable* get_dialog_xy(struct Map *map, int x, int y);
char *word_boundary_before(char *str, char *limit);
char *skip_spaces(char *str);
char *skip_spaces(char *str);
void format_text(int x, int y, const int color, char const *format, ...);

@ -1,5 +1,6 @@
#include <gint/display.h>
#include <gint/keyboard.h>
#include <string.h>
#include "engine.h"
#include "game.h"
@ -14,6 +15,8 @@
#include "capacite.h"
#include "util.h"
#include "inventory.h"
#include "item.h"
#include "event.h"
/*draw the current state of the game*/
void engine_draw(struct Game const *game) {
@ -127,10 +130,10 @@ void engine_action(struct Game *game, int action) {
if(action == ACTION_F1) {
/*game->player->sprint = game->player->sprint ? 0 : 1;
add_move(game->player, get_move_id(3));*/
open_inventory(&game->player->inventory, "Consultation");
open_inventory(game, &game->player->inventory, "Consultation", true);
}
if(action == ACTION_F2) {
add_item_to_inventory(&game->player->inventory, get_item_id(1));
add_item_to_inventory(game, &game->player->inventory, get_item_id(1));
}
if(action == ACTION_OPTN) {
draw_stats(game->player->stats);
@ -144,6 +147,10 @@ void engine_action(struct Game *game, int action) {
void engine_check_position(struct Game *game) {
static struct Map *old_map;
static struct Vec2 old_pos;
if(is_in_zone(game->player, game->map)) {
struct Zone zone = get_zone(game->player, game->map);
if(strcmp(zone.event, "")) handle_event(game, zone.event);
}
int player_curr_tile = map_get_player_tile(game);
if(player_curr_tile == TILE_DOOR_IN) {

@ -6,6 +6,7 @@
#include "player.h"
#include "capacite.h"
#include "inventory.h"
#include "item.h"
bool handle_event(struct Game *game, char const *event)
{
@ -14,8 +15,14 @@ bool handle_event(struct Game *game, char const *event)
// Isoler le nom et la quantité
int len=strlen(event), qty=1;
char *star = strchr(event, '*');
char name[20];
if(star) len=star-event, qty=atoi(star+1);
add_item_to_inventory(&game->player->inventory,get_item_id(2));
strncpy(name,event,len);
name[len] = '\0';
while(qty) {
add_item_to_inventory(game, &game->player->inventory, get_item_from_name(name));
qty--;
}
return true;
}
else if(!strncmp(event, "xp:", 3)) {
@ -23,14 +30,25 @@ bool handle_event(struct Game *game, char const *event)
add_xp(game->player, atoi(event));
return true;
}
else if(!strncmp(event, "hp:", 3)) {
event += 3;
game->player->stats.pv += atoi(event);
if(game->player->stats.pv > game->player->stats.max_pv) game->player->stats.pv = game->player->stats.max_pv;
return true;
}
else if(!strcmp(event, "pp:all")) {
reset_pp(game->player);
return true;
}
else if(!strncmp(event, "pp:", 3)) {
event += 3;
add_pp(game->player, atoi(event));
return true;
}
else if(!strncmp(event, "move:", 5)) {
event += 5;
add_move(game->player, get_move_id(atoi(event)));
return true;
}
else if(!strcmp(event, "test:test")) {
// etc, n'importe quoi de compliqué
return true;
}
return false;
}

@ -1,3 +1,4 @@
#include <stdio.h>
#include <gint/display.h>
#include <gint/keyboard.h>
#include <stdbool.h>
@ -6,15 +7,10 @@
#include "util.h"
#include "define.h"
#include "vec2.h"
extern struct Items items;
struct Item *get_item_id(int id) {
for(int i = 0; i < items.nbItems; i++) {
if(items.items[i]->id == id) return items.items[i];
}
return items.items[0];
}
#include "talkable.h"
#include "event.h"
#include "item.h"
#include "game.h"
int get_first_free_space(struct Inventory *inventory) {
for(int i = 0; i < NB_PLAYER_ITEMS; i++) {
@ -25,24 +21,21 @@ int get_first_free_space(struct Inventory *inventory) {
return NB_PLAYER_ITEMS;
}
bool add_item_to_inventory(struct Inventory *inventory, struct Item *item) {
bool add_item_to_inventory(struct Game *game, struct Inventory *inventory, struct Item *item) {
int index = get_first_free_space(inventory);
extern bopti_image_t img_dialogue;
dimage(42,DHEIGHT-75,&img_dialogue);
if(index < NB_PLAYER_ITEMS) {
dprint(50,DHEIGHT-47,C_BLACK,"Vous ajoutez %s à votre inventaire !", item->name);
format_text(50, DHEIGHT-47, C_BLACK, "Vous ajoutez %s à votre inventaire !", item->name);
dupdate();
wait_for_input(KEY_SHIFT);
inventory->items[index] = item;
inventory->nbItems++;
return true;
} else {
dprint(50,DHEIGHT-47,C_BLACK,"Plus de place pour ajouter %s à votre inventaire !", item->name);
format_text(50, DHEIGHT-47, C_BLACK, "Plus de place pour ajouter %s à votre inventaire !", item->name);
dupdate();
wait_for_input(KEY_SHIFT);
int pos = open_inventory(inventory, "Remplacer");
int pos = open_inventory(game, inventory, "Remplacer", false);
if(pos != -1) {
inventory->items[pos] = item;
inventory->nbItems++;
@ -52,11 +45,6 @@ bool add_item_to_inventory(struct Inventory *inventory, struct Item *item) {
return false;
}
void remove_item_pos(struct Inventory *inventory, int pos) {
inventory->items[pos] = NULL;
inventory->nbItems--;
}
void display_inventory(struct Inventory *inventory) {
for(int i = 0 ; i < NB_PLAYER_ITEMS ; i++) {
int x = i%10;
@ -69,7 +57,7 @@ void display_inventory(struct Inventory *inventory) {
}
}
int open_inventory(struct Inventory *inventory, char* context) {
int open_inventory(struct Game *game, struct Inventory *inventory, char* context, bool keep_open) {
int buffer = keydown(KEY_SHIFT);
struct Vec2 cursor = VEC2(0,0);
int pos = 0;
@ -103,7 +91,11 @@ int open_inventory(struct Inventory *inventory, char* context) {
if(keydown(KEY_SHIFT)) {
if(buffer) buffer = 0;
else if(inventory->items[pos] != NULL) {
if(!suppression) break;
if(!suppression && !keep_open) break;
else if(!suppression) {
select_item(game, pos);
remove_item_pos(inventory, pos);
}
else remove_item_pos(inventory, pos);
}
}

@ -0,0 +1,38 @@
#include "item.h"
#include "player.h"
#include "util.h"
#include <gint/keyboard.h>
#include <gint/display.h>
#include <string.h>
#include "event.h"
extern struct Items items;
struct Item *get_item_id(int id) {
for(int i = 0; i < items.nbItems; i++) {
if(items.items[i]->id == id) return items.items[i];
}
return items.items[0];
}
void remove_item_pos(struct Inventory *inventory, int pos) {
inventory->items[pos] = NULL;
inventory->nbItems--;
}
void select_item(struct Game *game, int pos) {
const char *delim = ";";
char *str = strdup(game->player->inventory.items[pos]->action);
char *curr_line = strtok(str, delim);
while(curr_line != NULL) {
handle_event(game, curr_line);
curr_line = strtok(NULL, delim);
}
}
struct Item *get_item_from_name(const char *name) {
for(int i = 0; i < items.nbItems; i++) {
if(!strcmp(items.items[i]->name, name)) return items.items[i];
}
return items.items[0];
}

@ -31,8 +31,12 @@ struct Monster *generate_monster(struct Game *game) {
struct Monster *monster;
if(is_in_zone(game->player, game->map)) {
struct Zone zone = get_zone(game->player, game->map);
monster = copyMonster(get_monster_id(zone.monsters[rand_range(0,zone.nbMonsters)]));
level_zone = zone.level;
if(zone.nbMonsters != 0) {
monster = copyMonster(get_monster_id(zone.monsters[rand_range(0,zone.nbMonsters)]));
} else {
monster = copyMonster(get_monster_id(0));
}
level_zone = zone.level != -1 ? zone.level : game->player->stats.level;
} else {
monster = copyMonster(get_monster_id(0));
level_zone = game->player->stats.level;

@ -1,5 +1,6 @@
#include <gint/keyboard.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include "player.h"
@ -8,6 +9,8 @@
#include "stats.h"
#include "capacite.h"
#include "util.h"
#include "talkable.h"
extern struct LevelUpPlayer levelupplayer;
extern bopti_image_t img_dialogue;
@ -93,14 +96,13 @@ int get_nb_moves(struct Player *player) {
void add_move(struct Player *player, struct Move move) {
int index = get_nb_moves(player);
dimage(42,DHEIGHT-75,&img_dialogue);
if(index != NB_PLAYER_MOVES) {
dprint(50,DHEIGHT-47,C_BLACK,"Vous apprenez %s !", move.name);
format_text(50, DHEIGHT-47, C_BLACK, "Vous apprenez %s !", move.name);
dupdate();
wait_for_input(KEY_SHIFT);
player->moves[index] = copy_move(move);
} else {
dprint(50,DHEIGHT-47,C_BLACK,"Vous pouvez apprendre %s !", move.name);
format_text(50, DHEIGHT-47, C_BLACK, "Vous pouvez apprendre %s !", move.name);
dupdate();
wait_for_input(KEY_SHIFT);
replace_capacities(player, move);
@ -125,6 +127,7 @@ void replace_capacities(struct Player *player, struct Move move) {
if(selection > NB_PLAYER_MOVES-1) selection = NB_PLAYER_MOVES-1;
if(selection < 0) selection = 0;
dtext(180,15,C_BLACK, "Remplacer");
draw_classic_move(200,DHEIGHT/2-30, &move);
draw_player_moves(player);
@ -147,6 +150,36 @@ void replace_capacities(struct Player *player, struct Move move) {
}
}
int select_capacity(struct Player *player, char* context, bool allow_back) {
int selection = 0;
int buffer = keydown(KEY_SHIFT);
while(1) {
clearevents();
dclear(C_WHITE);
selection += keydown(KEY_DOWN) - keydown(KEY_UP);
if(selection > NB_PLAYER_MOVES-1) selection = NB_PLAYER_MOVES-1;
if(selection < 0) selection = 0;
dtext(180,10,C_BLACK,context);
draw_player_moves(player);
dtext(105, 42+65*selection , C_RED, "[X]");
dupdate();
if(keydown(KEY_SHIFT)) {
if(buffer) buffer = 0;
else break;
}
if(keydown(KEY_EXIT) && allow_back) {
selection = -1;
break;
}
while(keydown_any(KEY_DOWN,KEY_UP, KEY_SHIFT,0)) clearevents();
}
return selection;
}
void draw_ui(struct Player *player) {
int index = get_nb_moves(player);
@ -160,6 +193,9 @@ void reset_pp(struct Player *player) {
for(int i = 0; i < index; i++) {
player->moves[i]->pp = player->moves[i]->init_pp;
}
format_text(50, DHEIGHT-47, C_BLACK, "Vous regagnez les PPs de l'ensemble de vos capacités");
dupdate();
wait_for_input(KEY_SHIFT);
}
void add_xp(struct Player *player, int xp) {
@ -168,13 +204,20 @@ void add_xp(struct Player *player, int xp) {
//niveau suivant une progession N³
int calc_level = (int)pow(player->stats.xp, 0.33);
for(int i = player->stats.level; i < calc_level; i++) {
// draw_battle(game->player, monster);
dimage(42,DHEIGHT-75,&img_dialogue);
dprint(50,DHEIGHT-47,C_BLACK,"Vous passez au niveau %d !", i+1);
format_text(50, DHEIGHT-47, C_BLACK, "Vous passez au niveau %d !", i+1);
dupdate();
wait_for_input(KEY_SHIFT);
}
int prec = player->stats.level;
player->stats.level = calc_level;
check_level(player, prec);
}
void add_pp(struct Player *player, int amount) {
int selection = select_capacity(player, "Choisir une capacité", false);
player->moves[selection]->pp += amount;
if(player->moves[selection]->pp > player->moves[selection]->init_pp) player->moves[selection]->pp = player->moves[selection]->init_pp;
format_text(50, DHEIGHT-47, C_BLACK, "Vous regagnez %d PPs sur %s", amount, player->moves[selection]->name);
dupdate();
wait_for_input(KEY_SHIFT);
}

@ -3,6 +3,9 @@
#include <gint/cpu.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "talkable.h"
#include "util.h"
@ -40,7 +43,6 @@ char *skip_spaces(char *str)
/*draw the dialog of a specified talkable tile*/
void draw_dialog(struct Game *game) {
extern bopti_image_t img_dialogue;
const char *delim = ";";
int direction = game->player->direction;
@ -55,21 +57,9 @@ void draw_dialog(struct Game *game) {
char *event = strchr(curr_line, '~');
if(event) handle_event(game, curr_line+1);
else {
dimage(43,31,&img_dialogue);
format_text(50, 58, C_BLACK, curr_line);
dprint(50,40, C_BLACK, "%s", talk->name);
int const DIALOG_WIDTH = 295, LINE_HEIGHT = 13;
int y = 45 + LINE_HEIGHT;
while(*curr_line) {
char *end = (char *)drsize(curr_line, NULL, DIALOG_WIDTH, NULL);
char *last_word = word_boundary_before(curr_line, end);
dtext_opt(50, y, C_BLACK, C_NONE, DTEXT_LEFT, DTEXT_TOP,
curr_line, last_word - curr_line);
curr_line = skip_spaces(last_word);
y += LINE_HEIGHT;
}
dupdate();
wait_for_input(KEY_SHIFT);
}
@ -85,4 +75,28 @@ struct Talkable* get_dialog_xy(struct Map *map, int x, int y) {
i++;
}
return &default_value;
}
void format_text(int x, int y, const int color, char const *format, ...) {
int const DIALOG_WIDTH = 295, LINE_HEIGHT = 13;
extern bopti_image_t img_dialogue;
dimage(x-7,y-26,&img_dialogue);
char text_arg[512];
va_list args;
va_start(args, format);
vsnprintf(text_arg, 512, format, args);
va_end(args);
char *text = (char *)malloc(strlen(text_arg)+1);
strcpy(text,text_arg);
while(*text) {
char *end = (char *)drsize(text, NULL, DIALOG_WIDTH, NULL);
char *last_word = word_boundary_before(text, end);
dtext_opt(x, y, color, C_NONE, DTEXT_LEFT, DTEXT_TOP,
text, last_word - text);
text = skip_spaces(last_word);
y += LINE_HEIGHT;
}
}
Loading…
Cancel
Save