Types have color + can now change player's type

This commit is contained in:
bgiraudr 2022-05-16 23:57:25 +02:00
parent dfbdb84327
commit 83920a57bc
20 changed files with 220 additions and 103 deletions

View File

@ -48,6 +48,7 @@ set(SOURCES
src/inventory.c
src/item.c
src/type.c
src/draw_util.c
)
set(ASSETS_cg

View File

@ -22,6 +22,8 @@ def convert(input, output, params, target):
elif params["custom-type"] == "table_type":
convert_table_type(input, output, params, target)
return 0
elif params["custom-type"] == "test":
test(input, output, params, target)
else:
return 1
@ -331,21 +333,28 @@ def convert_table_type(input, output, params, target):
type = fxconv.Structure()
type += fxconv.string(i["type"])
type += fxconv.u32(list(i).index(i["type"]))
taille = len(i)
taille = len(i)-1 #-1 because of the "color" column
b,l,n = [],[],[]
for j in i:
id = list(i).index(j)
if(i[j]=="2"): b.append(id)
if(i[j]=="0,5"): l.append(id)
if(i[j]=="0"): n.append(id)
if(j=="Couleur"): color=i[j]
for a in range(len(b),taille):b.append(0)
for a in range(len(l),taille):l.append(0)
for a in range(len(n),taille):n.append(0)
if(color == None):
raise Exception(f"Pas de couleur pour le type: {i['type']}")
if(len(color.strip()) != 5):
raise Exception(f"Mauvaise couleur pour le type {i['type']} : {color}")
color = int(color.strip()[1:], 16)
type += b"".join(fxconv.u32(value) for value in b)
type += b"".join(fxconv.u32(value) for value in l)
type += b"".join(fxconv.u32(value) for value in n)
type += fxconv.u16(color)
table_type += fxconv.ptr(type)

View File

@ -33,7 +33,7 @@ categories.png:
battle_ui.png:
type: bopti-image
name: img_battle
profile: p4
profile: p8
player_moves.txt:
custom-type: player_moves

View File

@ -5,4 +5,4 @@
tileset_in.png:
type: bopti-image
name: img_tileset_in
profile: p4
profile: p8

View File

@ -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:Obj2"/>
<property name="text" value="Cadeau;~type:Administrateur"/>
</properties>
</object>
</objectgroup>

View File

@ -1,5 +1,5 @@
type,Administrateur,Modérateur,Rédacteur,Labélisateur
Administrateur,0,1,1,2
Modérateur,0,"0,5",2,2
Rédacteur,2,1,"0,5",1
Labélisateur,2,"0,5",1,0
type,Administrateur,Modérateur,Rédacteur,Labélisateur,Couleur
Administrateur,0,1,1,2,#F800
Modérateur,0,"0,5",2,2,#3D65
Rédacteur,2,1,"0,5",1,#341B
Labélisateur,2,"0,5",1,0,#FBA0

1 type Administrateur Modérateur Rédacteur Labélisateur Couleur
2 Administrateur 0 1 1 2 #F800
3 Modérateur 0 0,5 2 2 #3D65
4 Rédacteur 2 1 0,5 1 #341B
5 Labélisateur 2 0,5 1 0 #FBA0

5
include/draw_util.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
void draw_text(int x, int y, const int color, char const *format, ...);
void draw_change_one_color(int x, int y, bopti_image_t *image, uint16_t from, uint16_t to);
void draw_change_one_color_index(int x, int y, bopti_image_t *image, int index, uint16_t color);

View File

@ -56,4 +56,6 @@ void reset_pp(struct Player *player);
void check_level(struct Player *player, int prec_level);
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);
void add_pp(struct Player *player, int amount);
void change_type(struct Player *player, struct Type type);
int yes_no_question(char const *format, ...);

View File

@ -17,5 +17,4 @@ void draw_dialog(struct Game *game);
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);
void format_text(int x, int y, const int color, char const *format, ...);
void format_text_opt(int x, int y, int width, int height, const int color, char const *format, ...);

View File

@ -1,5 +1,6 @@
#pragma once
#include "define.h"
#include <stdint.h>
struct Type {
char* name;
@ -7,6 +8,7 @@ struct Type {
int buff[NB_TYPES+1];
int less[NB_TYPES+1];
int null[NB_TYPES+1];
const uint16_t color;
};
struct Types {

View File

@ -2,5 +2,7 @@
/*wait for a specified input key*/
void wait_for_input(int input);
int rand_range(int low, int high);
int rand_range(int low, int high);
void format_text_opt(int x, int y, int width, int height, const int color, char const *format, ...);
char *word_boundary_before(char *str, char *limit);
char *skip_spaces(char *str);

View File

@ -1,6 +1,7 @@
#include <gint/display.h>
#include <gint/keyboard.h>
#include <math.h>
#include <stdlib.h>
#include "engine.h"
#include "battle.h"
@ -9,7 +10,7 @@
#include "player.h"
#include "monster.h"
#include "talkable.h"
#include <stdlib.h>
#include "draw_util.h"
extern bopti_image_t img_dialogue;
@ -115,7 +116,7 @@ void finish_battle(int status, struct Game *game, struct Monster *monster) {
//gain d'xp
int xp = ceil((monster->stats->xp*monster->stats->level*1.5)/7);
format_text(50, DHEIGHT-47, C_BLACK, "Vous remportez %d points d'experience", xp);
draw_text(50, DHEIGHT-47, C_BLACK, "Vous remportez %d points d'experience", xp);
dupdate();
wait_for_input(KEY_SHIFT);
@ -123,7 +124,7 @@ void finish_battle(int status, struct Game *game, struct Monster *monster) {
} else if(status == LOSE) {
draw_battle(game->player, monster);
format_text(50, DHEIGHT-47, C_BLACK, "%s a eu raison de vous !", monster->name);
draw_text(50, DHEIGHT-47, C_BLACK, "%s a eu raison de vous !", monster->name);
dupdate();
wait_for_input(KEY_SHIFT);
game->player->stats.pv = 0;
@ -218,12 +219,12 @@ void draw_battle(struct Player *player, struct Monster *monster) {
void draw_executed_move(struct Move *move, struct Monster *monster, int is_monster) {
if(is_monster) {
format_text(50, DHEIGHT-47, C_BLACK, "%s lance %s !", monster->name, move->name);
draw_text(50, DHEIGHT-47, C_BLACK, "%s lance %s !", monster->name, move->name);
} else {
format_text(50, DHEIGHT-47, C_BLACK, "Vous lancez %s !", move->name);
draw_text(50, DHEIGHT-47, C_BLACK, "Vous lancez %s !", move->name);
}
}
void draw_status(char *name, char *message) {
format_text(50, DHEIGHT-47, C_BLACK, "%s %s", name, message);
draw_text(50, DHEIGHT-47, C_BLACK, "%s %s", name, message);
}

View File

@ -1,5 +1,6 @@
#include <gint/display.h>
#include <gint/keyboard.h>
#include <gint/image.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
@ -8,6 +9,7 @@
#include "capacite.h"
#include "util.h"
#include "type.h"
#include "draw_util.h"
extern struct Capacities capacities;
@ -52,7 +54,7 @@ void draw_move(int x, int y, int x2, int y2, struct Move *move) {
extern bopti_image_t img_categories;
const int font_size = 8;
dimage(x, y, &img_capacite);
draw_change_one_color(x, y, &img_capacite, 0xE6D6, getTypeFromName(move->type).color);
dsubimage(x+96, y+7, &img_categories, 20*move->categorie, 0, 20, 10, DIMAGE_NONE);
int color = move->pp > 0 ? C_BLACK : C_RED;
@ -69,7 +71,6 @@ void draw_move(int x, int y, int x2, int y2, struct Move *move) {
dprint(x+15, y2-17, C_BLACK, "ATK : %d", move->atk);
dprint(x+70, y2-17, C_BLACK, "PRE : %d", move->precision);
}
dtext(x+50, y+15, C_BLUE, move->type);
}
void draw_classic_move(int x, int y, struct Move *move) {

43
src/draw_util.c Normal file
View File

@ -0,0 +1,43 @@
#include <string.h>
#include <gint/keyboard.h>
#include <gint/display.h>
#include <gint/image.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include "draw_util.h"
#include "util.h"
void draw_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);
format_text_opt(x, y, DIALOG_WIDTH, LINE_HEIGHT, color, text_arg);
}
void draw_change_one_color(int x, int y, bopti_image_t *image, uint16_t from, uint16_t to) {
for (int i = 0; i < image->color_count; i++) {
if(image->palette[i] == from) {
image->palette[i] = to;
dimage(x, y, image);
image->palette[i] = from;
return;
}
}
}
void draw_change_one_color_index(int x, int y, bopti_image_t *image, int index, uint16_t color) {
if(index >= image->color_count) return;
uint16_t init_color = image->palette[index];
image->palette[index] = color;
dimage(x, y, image);
image->palette[index] = init_color;
}

View File

@ -7,6 +7,7 @@
#include "capacite.h"
#include "inventory.h"
#include "item.h"
#include "type.h"
bool handle_event(struct Game *game, char const *event)
{
@ -45,6 +46,15 @@ bool handle_event(struct Game *game, char const *event)
add_pp(game->player, atoi(event));
return true;
}
else if(!strncmp(event, "type:", 5)) {
event += 5;
int len=strlen(event);
char name[20];
strncpy(name,event,len);
name[len] = '\0';
change_type(game->player, getTypeFromName(name));
return true;
}
else if(!strncmp(event, "move:", 5)) {
event += 5;
add_move(game->player, get_move_id(atoi(event)));

View File

@ -10,6 +10,7 @@
#include "talkable.h"
#include "event.h"
#include "item.h"
#include "draw_util.h"
#include "game.h"
int get_first_free_space(struct Inventory *inventory) {
@ -25,14 +26,14 @@ bool add_item_to_inventory(struct Game *game, struct Inventory *inventory, struc
int index = get_first_free_space(inventory);
if(index < NB_PLAYER_ITEMS) {
format_text(50, DHEIGHT-47, C_BLACK, "Vous ajoutez %s à votre inventaire !", item->name);
draw_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 {
format_text(50, DHEIGHT-47, C_BLACK, "Plus de place pour ajouter %s à votre inventaire !", item->name);
draw_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(game, inventory, "Remplacer", false);

View File

@ -2,6 +2,8 @@
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "player.h"
#include "define.h"
@ -10,6 +12,7 @@
#include "capacite.h"
#include "util.h"
#include "talkable.h"
#include "draw_util.h"
extern struct LevelUpPlayer levelupplayer;
@ -98,12 +101,12 @@ int get_nb_moves(struct Player *player) {
void add_move(struct Player *player, struct Move move) {
int index = get_nb_moves(player);
if(index != NB_PLAYER_MOVES) {
format_text(50, DHEIGHT-47, C_BLACK, "Vous apprenez %s !", move.name);
draw_text(50, DHEIGHT-47, C_BLACK, "Vous apprenez %s !", move.name);
dupdate();
wait_for_input(KEY_SHIFT);
player->moves[index] = copy_move(move);
} else {
format_text(50, DHEIGHT-47, C_BLACK, "Vous pouvez apprendre %s !", move.name);
draw_text(50, DHEIGHT-47, C_BLACK, "Vous pouvez apprendre %s !", move.name);
dupdate();
wait_for_input(KEY_SHIFT);
replace_capacities(player, move);
@ -194,7 +197,7 @@ 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");
draw_text(50, DHEIGHT-47, C_BLACK, "Vous regagnez les PPs de l'ensemble de vos capacités");
dupdate();
wait_for_input(KEY_SHIFT);
}
@ -205,7 +208,7 @@ 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++) {
format_text(50, DHEIGHT-47, C_BLACK, "Vous passez au niveau %d !", i+1);
draw_text(50, DHEIGHT-47, C_BLACK, "Vous passez au niveau %d !", i+1);
dupdate();
wait_for_input(KEY_SHIFT);
}
@ -218,7 +221,56 @@ 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);
draw_text(50, DHEIGHT-47, C_BLACK, "Vous regagnez %d PPs sur %s", amount, player->moves[selection]->name);
dupdate();
wait_for_input(KEY_SHIFT);
}
int yes_no_question(char const *format, ...) {
char text_arg[512];
va_list args;
va_start(args, format);
vsnprintf(text_arg, 512, format, args);
va_end(args);
int selection = 0;
int buffer = keydown(KEY_SHIFT);
while(1) {
clearevents();
dclear(C_WHITE);
selection += keydown(KEY_RIGHT) - keydown(KEY_LEFT);
if(selection > 1) selection = 1;
if(selection < 0) selection = 0;
format_text_opt(95,10, 200, 13, C_BLACK, text_arg);
dtext(95,150,C_BLACK, "NON");
dtext(285,150,C_BLACK, "OUI");
dtext(95 + (selection * 190), DHEIGHT-47, C_RED, "[X]");
dupdate();
if(keydown(KEY_SHIFT)) {
if(buffer) buffer = 0;
else break;
}
if(keydown(KEY_EXIT)) {
selection = 0;
break;
}
while(keydown_any(KEY_LEFT,KEY_RIGHT, KEY_SHIFT,0)) clearevents();
}
return selection;
}
void change_type(struct Player *player, struct Type type) {
if(strcmp(player->stats.type, type.name) != 0) {
int selection = yes_no_question("Voulez vous changer votre type %s en %s ?", player->stats.type, type.name);
if(selection) player->stats.type = type.name;
} else {
draw_text(50, DHEIGHT-47, C_BLACK, "Vous êtes déjà du type %s !", type.name);
dupdate();
wait_for_input(KEY_SHIFT);
}
}

View File

@ -11,6 +11,7 @@
#include "util.h"
#include "event.h"
#include "player.h"
#include "draw_util.h"
struct Talkable default_value = {
.x = 0,
@ -19,26 +20,6 @@ struct Talkable default_value = {
.text = "default dialog"
};
/* Find the last word boundary between [str] and [limit]. If there is no word
boundary (ie. [limit] is in the first word of [str]), returns [limit].
This function always return a position *after* [str] so that we always make
progress and don't loop. */
char *word_boundary_before(char *str, char *limit)
{
char *s = limit;
while(s > str) {
if(isspace(*s) || !*s) return s;
s--;
}
return limit;
}
/* Skip spaces at the start of [str] */
char *skip_spaces(char *str)
{
return str + strspn(str, " \t\n");
}
/*draw the dialog of a specified talkable tile*/
void draw_dialog(struct Game *game) {
const char *delim = ";";
@ -55,7 +36,7 @@ void draw_dialog(struct Game *game) {
char *event = strchr(curr_line, '~');
if(event) handle_event(game, curr_line+1);
else {
format_text(50, 58, C_BLACK, curr_line);
draw_text(50, 58, C_BLACK, curr_line);
dprint(50,40, C_BLACK, "%s", talk->name);
dupdate();
@ -73,40 +54,4 @@ 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);
format_text_opt(x, y, DIALOG_WIDTH, LINE_HEIGHT, color, text_arg);
}
void format_text_opt(int x, int y, int width, int height, const int color, char const *format, ...) {
int const DIALOG_WIDTH = width, LINE_HEIGHT = height;
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;
}
}

View File

@ -11,6 +11,7 @@ extern struct Types table_type;
struct Type default_type = {
.name = "-",
.id = 0,
.color = 0xE6D6,
.buff = {},
.less = {},
.null = {}
@ -47,23 +48,19 @@ float getTypeEffect(struct Type atk, struct Type def) {
}
void drawTypeEffects(struct Type type) {
while(1) {
dclear(C_WHITE);
dprint(120,10,C_RED, "Table de %s", type.name);
dtext(55,40,C_BLUE, "Super efficace");
dtext(160,40,C_BLUE, "Peu efficace");
dtext(260,40,C_BLUE, "Non efficace");
dclear(C_WHITE);
dprint(120,10,C_RED, "Table de %s", type.name);
dtext(55,40,C_BLUE, "Super efficace");
dtext(160,40,C_BLUE, "Peu efficace");
dtext(260,40,C_BLUE, "Non efficace");
for(int i = 0; i <= 3; i++) {
for(int j = 0; j <= NB_TYPES; j++) {
if(i==0) dprint(70+100*i, 60+20*j, C_BLACK, "%s", getTypeFromId(type.buff[j]).name);
if(i==1) dprint(70+100*i, 60+20*j, C_BLACK, "%s", getTypeFromId(type.less[j]).name);
if(i==2) dprint(70+100*i, 60+20*j, C_BLACK, "%s", getTypeFromId(type.null[j]).name);
}
for(int i = 0; i <= 3; i++) {
for(int j = 0; j <= NB_TYPES; j++) {
if(i==0) dprint(70+100*i, 60+20*j, C_BLACK, "%s", getTypeFromId(type.buff[j]).name);
if(i==1) dprint(70+100*i, 60+20*j, C_BLACK, "%s", getTypeFromId(type.less[j]).name);
if(i==2) dprint(70+100*i, 60+20*j, C_BLACK, "%s", getTypeFromId(type.null[j]).name);
}
dupdate();
pollevent();
if(keydown(KEY_OPTN)) break;
}
dupdate();
wait_for_input(KEY_SHIFT);
}

View File

@ -1,5 +1,10 @@
#include <gint/keyboard.h>
#include <gint/std/stdlib.h>
#include <gint/display.h>
#include <stdlib.h>
#include <string.h>
#include <gint/cpu.h>
#include <ctype.h>
#include <stdio.h>
#include "util.h"
@ -19,4 +24,46 @@ void wait_for_input(int input) {
/**
* Random [low;high[
*/
int rand_range(int low, int high) { return (rand() % (high - low)) + low; }
int rand_range(int low, int high) { return (rand() % (high - low)) + low; }
/* Find the last word boundary between [str] and [limit]. If there is no word
boundary (ie. [limit] is in the first word of [str]), returns [limit].
This function always return a position *after* [str] so that we always make
progress and don't loop. */
char *word_boundary_before(char *str, char *limit)
{
char *s = limit;
while(s > str) {
if(isspace(*s) || !*s) return s;
s--;
}
return limit;
}
/* Skip spaces at the start of [str] */
char *skip_spaces(char *str)
{
return str + strspn(str, " \t\n");
}
void format_text_opt(int x, int y, int width, int height, const int color, char const *format, ...) {
int const DIALOG_WIDTH = width, LINE_HEIGHT = height;
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;
}
}