2022-01-24 23:57:07 +01:00
|
|
|
#include <gint/keyboard.h>
|
2022-02-15 21:46:53 +01:00
|
|
|
#include <stdlib.h>
|
2022-04-23 00:47:27 +02:00
|
|
|
#include <stdbool.h>
|
2022-04-02 01:57:54 +02:00
|
|
|
#include <math.h>
|
2022-05-16 23:57:25 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2022-01-24 23:57:07 +01:00
|
|
|
|
2021-08-08 01:43:26 +02:00
|
|
|
#include "player.h"
|
2021-08-25 01:30:30 +02:00
|
|
|
#include "define.h"
|
2021-08-08 01:43:26 +02:00
|
|
|
#include "map.h"
|
2022-01-23 00:53:07 +01:00
|
|
|
#include "stats.h"
|
2022-01-24 15:15:12 +01:00
|
|
|
#include "capacite.h"
|
2022-01-24 23:57:07 +01:00
|
|
|
#include "util.h"
|
2022-04-23 00:47:27 +02:00
|
|
|
#include "talkable.h"
|
2022-05-16 23:57:25 +02:00
|
|
|
#include "draw_util.h"
|
2022-05-26 18:47:58 +02:00
|
|
|
#include "animation.h"
|
2021-08-27 02:11:05 +02:00
|
|
|
|
2022-03-23 01:16:24 +01:00
|
|
|
extern struct LevelUpPlayer levelupplayer;
|
2022-04-02 01:57:54 +02:00
|
|
|
extern bopti_image_t img_dialogue;
|
2022-03-23 01:16:24 +01:00
|
|
|
|
2021-08-27 02:11:05 +02:00
|
|
|
struct Player init_player(void) {
|
2022-01-23 00:53:07 +01:00
|
|
|
|
2022-02-13 21:46:52 +01:00
|
|
|
struct Stats bstats = {
|
|
|
|
.atk = 15,
|
|
|
|
.def = 15,
|
2022-04-16 01:06:24 +02:00
|
|
|
.spe_atk = 15,
|
|
|
|
.spe_def = 15,
|
2022-02-13 21:46:52 +01:00
|
|
|
.level = 1,
|
|
|
|
.pv = 30,
|
|
|
|
};
|
|
|
|
|
2022-01-23 00:53:07 +01:00
|
|
|
struct Stats stats = {
|
|
|
|
.level = 1,
|
2022-05-11 00:37:56 +02:00
|
|
|
.xp = 0,
|
2022-05-26 18:47:58 +02:00
|
|
|
.type = "Rédacteur",
|
2022-01-23 00:53:07 +01:00
|
|
|
};
|
|
|
|
|
2022-04-18 00:06:32 +02:00
|
|
|
struct Inventory inventory = {
|
|
|
|
.nbItems = 0
|
|
|
|
};
|
|
|
|
|
2021-08-27 02:11:05 +02:00
|
|
|
struct Player player = {
|
2022-05-26 18:47:58 +02:00
|
|
|
.pos = VEC2(7, 8),
|
|
|
|
.pos_visual = VEC2F(7*TILE_SIZE, 8*TILE_SIZE),
|
2022-02-13 21:46:52 +01:00
|
|
|
.base_stats = bstats,
|
2022-01-23 00:53:07 +01:00
|
|
|
.stats = stats,
|
2022-04-18 00:06:32 +02:00
|
|
|
.inventory = inventory,
|
2021-08-27 02:11:05 +02:00
|
|
|
.x_mid = 6,
|
|
|
|
.y_mid = 1,
|
|
|
|
.show_x = 12,
|
|
|
|
.show_y = 7,
|
|
|
|
.direction = DIR_DOWN,
|
|
|
|
.anim.function = anim_player_idle,
|
|
|
|
.anim.dir = DIR_DOWN
|
|
|
|
};
|
|
|
|
player.idle = !anim_player_idle(&player.anim, 1);
|
2022-04-16 01:06:24 +02:00
|
|
|
player.moves[0] = copy_move(get_move_id(0));
|
|
|
|
player.moves[1] = copy_move(get_move_id(4));
|
2021-08-27 02:11:05 +02:00
|
|
|
|
2022-02-13 21:46:52 +01:00
|
|
|
set_stats_level_from(&player.base_stats, &player.stats);
|
2022-05-26 18:47:58 +02:00
|
|
|
player.stats.pv = player.stats.max_pv;
|
2021-08-27 02:11:05 +02:00
|
|
|
return player;
|
|
|
|
}
|
2021-08-08 01:43:26 +02:00
|
|
|
|
2022-03-23 01:16:24 +01:00
|
|
|
void check_level(struct Player *player, int prec_level) {
|
|
|
|
for(int i = 0; i < levelupplayer.nbLevelUp; i++) {
|
|
|
|
if(player->stats.level >= levelupplayer.levelup[i]->level
|
|
|
|
&& prec_level < levelupplayer.levelup[i]->level) {
|
|
|
|
add_move(player, get_move_id(levelupplayer.levelup[i]->id_move));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-08 01:43:26 +02:00
|
|
|
/*
|
|
|
|
return the info tile value the player is facing to
|
|
|
|
TILE_SOLID by default (out of bound)
|
|
|
|
*/
|
2021-08-15 03:46:49 +02:00
|
|
|
int player_facing(struct Game const *game) {
|
2021-08-08 01:43:26 +02:00
|
|
|
int direction = game->player->direction;
|
|
|
|
int dx = (direction == DIR_RIGHT) - (direction == DIR_LEFT);
|
|
|
|
int dy = (direction == DIR_DOWN) - (direction == DIR_UP);
|
|
|
|
|
2021-08-25 01:01:43 +02:00
|
|
|
int index = game->player->pos.x + dx + game->map->w * (game->player->pos.y + dy);
|
|
|
|
if(game->player->pos.x + dx >= 0 &&
|
|
|
|
game->player->pos.x + dx <= game->map->w &&
|
|
|
|
game->player->pos.y + dy >= 0 &&
|
|
|
|
game->player->pos.y + dy <= game->map->h) {
|
2021-08-08 01:43:26 +02:00
|
|
|
return game->map->info_map[index];
|
|
|
|
}
|
|
|
|
return TILE_SOLID;
|
2022-01-24 15:15:12 +01:00
|
|
|
}
|
|
|
|
|
2022-01-27 23:53:10 +01:00
|
|
|
int get_nb_moves(struct Player *player) {
|
|
|
|
for(int i = 0; i < NB_PLAYER_MOVES; i++) {
|
2022-02-15 21:46:53 +01:00
|
|
|
if(player->moves[i] == NULL) {
|
2022-01-27 23:53:10 +01:00
|
|
|
return i;
|
|
|
|
}
|
2022-01-24 15:15:12 +01:00
|
|
|
}
|
2022-01-27 23:53:10 +01:00
|
|
|
return NB_PLAYER_MOVES;
|
|
|
|
}
|
|
|
|
|
2022-05-22 16:46:31 +02:00
|
|
|
bool has_move(struct Player *player, struct Move move) {
|
|
|
|
int index = get_nb_moves(player);
|
|
|
|
for(int i = 0; i < index; i++) {
|
|
|
|
if(player->moves[i]->id == move.id) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-01-27 23:53:10 +01:00
|
|
|
void add_move(struct Player *player, struct Move move) {
|
|
|
|
int index = get_nb_moves(player);
|
2022-05-22 16:46:31 +02:00
|
|
|
if(!has_move(player, move)) {
|
|
|
|
if(index != NB_PLAYER_MOVES) {
|
|
|
|
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 {
|
|
|
|
draw_text(50, DHEIGHT-47, C_BLACK, "Vous pouvez apprendre %s !", move.name);
|
|
|
|
dupdate();
|
|
|
|
wait_for_input(KEY_SHIFT);
|
|
|
|
replace_capacities(player, move);
|
|
|
|
}
|
2022-04-02 01:57:54 +02:00
|
|
|
} else {
|
2022-05-22 16:46:31 +02:00
|
|
|
draw_text(50, DHEIGHT-47, C_BLACK, "Vous connaissez déjà la capacité %s !", move.name);
|
2022-04-02 01:57:54 +02:00
|
|
|
dupdate();
|
|
|
|
wait_for_input(KEY_SHIFT);
|
|
|
|
}
|
2022-01-24 21:27:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void draw_player_moves(struct Player *player) {
|
2022-01-27 23:53:10 +01:00
|
|
|
int index = get_nb_moves(player);
|
|
|
|
for(int i = 0; i < index; i++) {
|
2022-04-02 01:57:54 +02:00
|
|
|
draw_classic_move(20,65*i+15,player->moves[i]);
|
2022-01-24 21:27:51 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-24 23:57:07 +01:00
|
|
|
void replace_capacities(struct Player *player, struct Move move) {
|
|
|
|
int selection = 0;
|
|
|
|
int buffer = keydown(KEY_SHIFT);
|
|
|
|
while(1) {
|
|
|
|
clearevents();
|
2022-04-02 01:57:54 +02:00
|
|
|
dclear(C_WHITE);
|
2022-01-24 23:57:07 +01:00
|
|
|
|
2022-01-27 23:53:10 +01:00
|
|
|
selection += keydown(KEY_DOWN) - keydown(KEY_UP);
|
|
|
|
if(selection > NB_PLAYER_MOVES-1) selection = NB_PLAYER_MOVES-1;
|
2022-01-24 23:57:07 +01:00
|
|
|
if(selection < 0) selection = 0;
|
|
|
|
|
2022-04-23 01:53:08 +02:00
|
|
|
dtext(180,15,C_BLACK, "Remplacer");
|
2022-02-19 01:21:38 +01:00
|
|
|
draw_classic_move(200,DHEIGHT/2-30, &move);
|
2022-04-02 01:57:54 +02:00
|
|
|
draw_player_moves(player);
|
2022-01-24 23:57:07 +01:00
|
|
|
|
2022-04-02 01:57:54 +02:00
|
|
|
dtext(105, 42+65*selection , C_RED, "[X]");
|
2022-01-24 23:57:07 +01:00
|
|
|
dupdate();
|
|
|
|
|
|
|
|
if(keydown(KEY_SHIFT)) {
|
|
|
|
if(buffer) buffer = 0;
|
|
|
|
else break;
|
|
|
|
}
|
|
|
|
if(keydown(KEY_EXIT)) {
|
|
|
|
selection = -1;
|
|
|
|
break;
|
|
|
|
}
|
2022-01-27 23:53:10 +01:00
|
|
|
while(keydown_any(KEY_DOWN,KEY_UP, KEY_SHIFT,0)) clearevents();
|
2022-01-24 23:57:07 +01:00
|
|
|
}
|
|
|
|
if(selection >= 0) {
|
2022-02-15 21:46:53 +01:00
|
|
|
free(player->moves[selection]);
|
|
|
|
player->moves[selection] = copy_move(move);
|
2022-01-24 23:57:07 +01:00
|
|
|
}
|
2022-01-25 22:20:10 +01:00
|
|
|
}
|
|
|
|
|
2022-04-23 00:47:27 +02:00
|
|
|
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;
|
|
|
|
|
2022-04-23 01:53:08 +02:00
|
|
|
dtext(180,10,C_BLACK,context);
|
2022-04-23 00:47:27 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-05-22 16:46:31 +02:00
|
|
|
void draw_ui(struct Player *player, int curr_select) {
|
2022-01-27 23:53:10 +01:00
|
|
|
int index = get_nb_moves(player);
|
|
|
|
|
|
|
|
for(int i = 0; i < index; i++) {
|
2022-05-22 16:46:31 +02:00
|
|
|
draw_special_move(2+132*i,DHEIGHT-70, player->moves[i], i == curr_select);
|
2022-01-25 22:20:10 +01:00
|
|
|
}
|
2022-02-17 01:04:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void reset_pp(struct Player *player) {
|
|
|
|
int index = get_nb_moves(player);
|
|
|
|
for(int i = 0; i < index; i++) {
|
|
|
|
player->moves[i]->pp = player->moves[i]->init_pp;
|
|
|
|
}
|
2022-05-16 23:57:25 +02:00
|
|
|
draw_text(50, DHEIGHT-47, C_BLACK, "Vous regagnez les PPs de l'ensemble de vos capacités");
|
2022-04-23 00:47:27 +02:00
|
|
|
dupdate();
|
|
|
|
wait_for_input(KEY_SHIFT);
|
2022-04-02 01:57:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void add_xp(struct Player *player, int xp) {
|
|
|
|
player->stats.xp += 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++) {
|
2022-05-26 18:47:58 +02:00
|
|
|
player->stats.pv = player->stats.pv + player->stats.max_pv * 0.2;
|
2022-05-16 23:57:25 +02:00
|
|
|
draw_text(50, DHEIGHT-47, C_BLACK, "Vous passez au niveau %d !", i+1);
|
2022-04-02 01:57:54 +02:00
|
|
|
dupdate();
|
|
|
|
wait_for_input(KEY_SHIFT);
|
|
|
|
}
|
|
|
|
int prec = player->stats.level;
|
|
|
|
player->stats.level = calc_level;
|
|
|
|
check_level(player, prec);
|
2022-04-23 00:47:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2022-05-16 23:57:25 +02:00
|
|
|
draw_text(50, DHEIGHT-47, C_BLACK, "Vous regagnez %d PPs sur %s", amount, player->moves[selection]->name);
|
2022-04-23 00:47:27 +02:00
|
|
|
dupdate();
|
|
|
|
wait_for_input(KEY_SHIFT);
|
2022-05-16 23:57:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2022-05-22 16:46:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int get_nb_eventzone(struct Player *player) {
|
2022-05-22 23:58:00 +02:00
|
|
|
for(int i = 0; i < NB_STO_ZONE; i++) {
|
2022-05-22 16:46:31 +02:00
|
|
|
if(player->eventListZone[i] == 0) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-05-22 23:58:00 +02:00
|
|
|
int get_nb_eventdialog(struct Player *player) {
|
|
|
|
for(int i = 0; i < NB_STO_DIALOG; i++) {
|
|
|
|
if(player->eventListDialog[i] == 0) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-05-22 16:46:31 +02:00
|
|
|
bool check_eventzone(struct Player *player, int id) {
|
2022-05-22 23:58:00 +02:00
|
|
|
for(int i = 0; i < NB_STO_ZONE; i++) {
|
2022-05-22 16:46:31 +02:00
|
|
|
if(player->eventListZone[i] == id) return true;
|
|
|
|
if(player->eventListZone[i] == 0) return false;
|
|
|
|
}
|
|
|
|
return false;
|
2022-05-22 23:58:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool check_eventdialog(struct Player *player, int id) {
|
|
|
|
for(int i = 0; i < NB_STO_DIALOG; i++) {
|
|
|
|
if(player->eventListDialog[i] == id) return true;
|
|
|
|
if(player->eventListDialog[i] == 0) return false;
|
|
|
|
}
|
|
|
|
return false;
|
2022-05-26 18:47:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void player_step_back(struct Player *player) {
|
|
|
|
int direction = player->direction;
|
|
|
|
int dx = (direction == DIR_RIGHT) - (direction == DIR_LEFT);
|
|
|
|
int dy = (direction == DIR_DOWN) - (direction == DIR_UP);
|
|
|
|
player->pos.x = player->pos.x - dx;
|
|
|
|
player->pos.y = player->pos.y - dy;
|
|
|
|
player->idle = !anim_player_idle(&player->anim, 1);
|
2022-01-24 23:57:07 +01:00
|
|
|
}
|