Lamthai/game/logic/spells.cpp

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);
}
}