239 lines
6.7 KiB
C++
239 lines
6.7 KiB
C++
#include <iostream>
|
|
#include <vector>
|
|
#include <string>
|
|
#include "utilities.h"
|
|
#include "../define.h"
|
|
#include "player.h"
|
|
#include "ennemy.h"
|
|
#include "combat.h"
|
|
#include "../interface/interfaces.h"
|
|
#include "spells.h"
|
|
|
|
const std::vector<std::string> elements = {"Fire", "Air", "Water", "Earth", "Eather"};
|
|
const std::vector<std::string> arrows = {"↑", "→", "↓", "←"};
|
|
|
|
void init_spell(Spell& spell_arg, const std::string& name_arg, int damage_arg, int cost_arg, float precision_arg, bool zone_arg, std::vector<Elements> elements_arg, std::vector<int> combinaison_arg) {
|
|
spell_arg.name = name_arg;
|
|
spell_arg.damage = damage_arg;
|
|
spell_arg.cost_mana = cost_arg;
|
|
spell_arg.cost_health = 0;
|
|
spell_arg.precision = precision_arg;
|
|
spell_arg.zone = zone_arg;
|
|
spell_arg.elements = elements_arg;
|
|
spell_arg.combinaison = combinaison_arg;
|
|
}
|
|
|
|
void init_spells(std::vector<Spell>& spell_book_arg) {
|
|
Spell fire_ball;
|
|
init_spell(
|
|
fire_ball,
|
|
"Fire Ball",
|
|
10,
|
|
5,
|
|
0.8,
|
|
1,
|
|
std::vector<Elements>{FIRE},
|
|
std::vector<int>{UP, RIGHT, UP}
|
|
);
|
|
spell_book_arg.push_back(fire_ball);
|
|
|
|
Spell tsunami;
|
|
init_spell(
|
|
tsunami,
|
|
"Tsunami",
|
|
15,
|
|
8,
|
|
1,
|
|
1,
|
|
std::vector<Elements>{WATER},
|
|
std::vector<int>{UP, DOWN, RIGHT}
|
|
);
|
|
spell_book_arg.push_back(tsunami);
|
|
|
|
Spell tailwind_css;
|
|
init_spell(
|
|
tailwind_css,
|
|
"Tailwind CSS",
|
|
8,
|
|
4,
|
|
0.8,
|
|
0,
|
|
std::vector<Elements>{AIR},
|
|
std::vector<int>{UP, UP, UP}
|
|
);
|
|
spell_book_arg.push_back(tailwind_css);
|
|
|
|
Spell rolling_rock;
|
|
init_spell(
|
|
rolling_rock,
|
|
"Rolling Rock",
|
|
15,
|
|
13,
|
|
0.7,
|
|
0,
|
|
std::vector<Elements>{EARTH},
|
|
std::vector<int>{DOWN, UP, LEFT}
|
|
);
|
|
spell_book_arg.push_back(rolling_rock);
|
|
|
|
Spell lightning;
|
|
init_spell(
|
|
lightning,
|
|
"Lightning",
|
|
20,
|
|
10,
|
|
0.8,
|
|
0,
|
|
std::vector<Elements>{AIR, FIRE},
|
|
std::vector<int>{DOWN, UP, LEFT, UP}
|
|
);
|
|
spell_book_arg.push_back(lightning);
|
|
|
|
Spell bubble;
|
|
init_spell(
|
|
bubble,
|
|
"Bubble",
|
|
5,
|
|
2,
|
|
1,
|
|
0,
|
|
std::vector<Elements>{AIR, WATER},
|
|
std::vector<int>{UP, UP, UP, UP}
|
|
);
|
|
spell_book_arg.push_back(bubble);
|
|
}
|
|
|
|
//Return -1 if no spells, 0 if a spell is totally completed and the only possible, else the number of spells possible
|
|
int possible_spell(const std::vector<Spell>& spell_book_arg, const std::vector<int>& spell_arg) {
|
|
int spells_count = 0;
|
|
for (const Spell& spell: spell_book_arg) {
|
|
if (spell.combinaison.size() >= spell_arg.size()) {
|
|
std::vector<int> actual_spell(spell.combinaison.begin(), spell.combinaison.begin() + spell_arg.size());
|
|
if (actual_spell == spell_arg) {
|
|
spells_count++;
|
|
}
|
|
}
|
|
}
|
|
return spells_count;
|
|
}
|
|
|
|
Spell find_spell_by_combinaison(const std::vector<Spell>& spell_book_arg, const std::vector<int>& spell_arg) {
|
|
for (const Spell& spell: spell_book_arg) {
|
|
if (spell.combinaison == spell_arg) {
|
|
return spell;
|
|
}
|
|
}
|
|
return spell_book_arg[0];
|
|
}
|
|
|
|
//Return true if the player casts a spell
|
|
bool cast_spell(Player& player_arg, Player_stats& player_stats_arg, std::vector<int>& spell_arg, int spell_segment_arg, std::vector<Ennemy>& ennemies_arg, std::vector<Ennemy_stats>& ennemies_stats_arg) {
|
|
std::vector<Spell> spell_book = player_arg.spell_book;
|
|
|
|
if (spell_segment_arg == END_SPELL) {
|
|
Spell casted_spell = find_spell_by_combinaison(spell_book, spell_arg);
|
|
if (spell_arg.size() == casted_spell.combinaison.size()) {
|
|
use_spell(casted_spell, player_arg, player_stats_arg, ennemies_arg, ennemies_stats_arg);
|
|
}
|
|
return 1;
|
|
} else {
|
|
spell_arg.push_back(spell_segment_arg);
|
|
int count_spell = possible_spell(spell_book, spell_arg);
|
|
if (count_spell <= 1) {
|
|
if (count_spell == 1) {
|
|
Spell casted_spell = find_spell_by_combinaison(spell_book, spell_arg);
|
|
if (spell_arg.size() == casted_spell.combinaison.size()) {
|
|
use_spell(casted_spell, player_arg, player_stats_arg, ennemies_arg, ennemies_stats_arg);
|
|
} else {
|
|
return 0;
|
|
}
|
|
} else if (count_spell == 0) {
|
|
std::cout << "Spell doesn't exist" << std::endl;
|
|
}
|
|
spell_arg = {};
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void use_spell(const Spell& spell_arg, Player& player_arg, Player_stats& player_stats_arg, std::vector<Ennemy>& ennemies_arg, std::vector<Ennemy_stats>& ennemies_stats_arg) {
|
|
if (player_arg.mana - spell_arg.cost_mana >= 0) {
|
|
inc_health(player_arg, -spell_arg.cost_health);
|
|
inc_mana(player_arg, -spell_arg.cost_mana);
|
|
if(spell_arg.zone) {
|
|
for(Ennemy& ennemy: ennemies_arg) {
|
|
spell_damage(ennemy, spell_arg);
|
|
}
|
|
} else {
|
|
Ennemy& ennemy = choose_target(player_arg, player_stats_arg, ennemies_arg, ennemies_stats_arg);
|
|
spell_damage(ennemy, spell_arg);
|
|
}
|
|
std::cout << player_arg.name<< " casts " << spell_arg.name << std::endl;
|
|
} else {
|
|
std::cout << "Not enough mana" << std::endl;
|
|
}
|
|
}
|
|
|
|
void spell_damage(Ennemy& ennemy_arg, const Spell& spell_arg) {
|
|
if(ennemy_arg.shield >= spell_arg.damage) {
|
|
inc_shield(ennemy_arg, -spell_arg.damage);
|
|
} else if(ennemy_arg.shield > 0) {
|
|
inc_health(ennemy_arg, ennemy_arg.shield - spell_arg.damage);
|
|
inc_shield(ennemy_arg, -ennemy_arg.shield);
|
|
} else if(ennemy_arg.health >= spell_arg.damage) {
|
|
inc_health(ennemy_arg, -spell_arg.damage);
|
|
} else {
|
|
inc_health(ennemy_arg, -ennemy_arg.health);
|
|
}
|
|
}
|
|
|
|
void ennemy_use_spell(const Spell& spell_arg, Player& player_arg, Ennemy& ennemy_arg) {
|
|
inc_health(ennemy_arg, -spell_arg.cost_health);
|
|
|
|
if(random_success(spell_arg.precision)) {
|
|
if(player_arg.shield >= spell_arg.damage) {
|
|
inc_shield(player_arg, -spell_arg.damage);
|
|
} else if(player_arg.shield > 0) {
|
|
inc_health(player_arg, player_arg.shield - spell_arg.damage);
|
|
inc_shield(player_arg, -player_arg.shield);
|
|
} else if(player_arg.health >= spell_arg.damage) {
|
|
inc_health(player_arg, -spell_arg.damage);
|
|
} else {
|
|
inc_health(player_arg, -player_arg.health);
|
|
}
|
|
std::cout << ennemy_arg.name<< " casts " << spell_arg.name << std::endl;
|
|
} else {
|
|
std::cout << ennemy_arg.name<< " fails " << spell_arg.name << std::endl;
|
|
}
|
|
}
|
|
|
|
void print_spell(const Spell& spell_arg) {
|
|
std::cout << spell_arg.name << std::endl;
|
|
std::cout << "Damage : " << spell_arg.damage << std::endl;
|
|
std::cout << "Mana cost : " << spell_arg.cost_mana << std::endl;
|
|
if(spell_arg.cost_health > 0) {
|
|
std::cout << "Health cost : " << spell_arg.cost_health << std::endl;
|
|
}
|
|
std::cout << "Precision : " << spell_arg.damage << std::endl;
|
|
std::cout << "Elements : ";
|
|
for (int element: spell_arg.elements) {
|
|
std::cout << elements[element] << " ";
|
|
}
|
|
std::cout << std::endl;
|
|
if (spell_arg.zone) {
|
|
std::cout << "Zone" << std::endl;
|
|
}
|
|
std::cout << "Combinaison : ";
|
|
|
|
for (int arrow: spell_arg.combinaison) {
|
|
std::cout << arrows[arrow] << " ";
|
|
}
|
|
std::cout << std::endl << std::endl;
|
|
}
|
|
|
|
void print_spell_book(const std::vector<Spell>& spell_book_arg) {
|
|
for (Spell spell: spell_book_arg) {
|
|
print_spell(spell);
|
|
}
|
|
} |