You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
awesome_game/Source/TurnBasedTutorial/BasicTurnManager.cpp

152 lines
6.2 KiB

// Fill out your copyright notice in the Description page of Project Settings.
#include "BasicTurnManager.h"
#include "Templates/UnrealTemplate.h"
namespace basic_api_classes {
base_ability::base_ability(double cost_, double damage_, double max_activation_radius_, double splash_radius_, double linear_width_) :
cost(cost_), damage(damage_), max_activation_radius(max_activation_radius_), splash_radius(splash_radius_), linear_width(linear_width_) {};
bool base_ability::is_pers_hurt(double attacker_x, double attacker_y, double activation_x, double activation_y, double defender_x, double defender_y) {
{
double dist = (activation_x - defender_x) * (activation_x - defender_x) +
(activation_y - defender_y) * (activation_y - defender_y);
if (dist + 1e-6 < splash_radius * splash_radius) return true;
}
{
double dist = (attacker_x - defender_x) * (attacker_x - defender_x) +
(attacker_y - defender_y) * (attacker_y - defender_y);
double dist1 = (attacker_x - activation_x) * (attacker_x - activation_x) +
(attacker_y - activation_y) * (attacker_y - activation_y);
if (dist > dist1 + 1e-6) return false;
double height = defender_x * (activation_y - attacker_y) - defender_y * (activation_x - attacker_x) -
attacker_x * activation_y + attacker_y * activation_x;
height *= height;
return height < ((activation_y - attacker_y)* (activation_y - attacker_y) + (activation_x - attacker_x) * (activation_x - attacker_x))*
linear_width*linear_width;
}
}
base_personage::base_personage(double x_, double y_, double hp, double trav_cost, TArray<base_ability*>&& abils) : is_dead(false), x_coordinate(x_),
y_coordinate(y_), hitpoints(hp), travel_cost(trav_cost), abilities(MoveTemp(abils)) {};
FVector2D base_personage::get_personage_cords() const{
return FVector2D{ static_cast<float>(x_coordinate), static_cast<float>(y_coordinate) };
}
double base_personage::get_hitpoints() const{
return hitpoints;
}
void base_personage::move_to_position(double new_x, double new_y, double& rest_action_points) {
double dist = (new_x - x_coordinate) * (new_x - x_coordinate) + (new_y - y_coordinate) * (new_y - y_coordinate);
dist = sqrt(dist);
if (rest_action_points + 1e-6 < dist * travel_cost) {
rest_action_points -= dist * travel_cost;
x_coordinate = new_x, y_coordinate = new_y;
}
}
void base_personage::accept_damage(double damage) {
if (is_dead) return;
hitpoints -= damage;
if (hitpoints < 1e-6) {
hitpoints = 0;
is_dead = true;
}
}
bool base_personage::is_attack_startable(size_t ability_number, double attack_pos_x, double attack_pos_y, double rest_action_points) const{
if (ability_number >= abilities.Num()) return false;
base_ability* ba = abilities[ability_number];
double dist = (attack_pos_x - x_coordinate) * (attack_pos_x - x_coordinate) +
(attack_pos_y - y_coordinate) * (attack_pos_y - y_coordinate);
return dist + 1e-6 < ba->max_activation_radius * ba->max_activation_radius && ba->cost + 1e-6 < rest_action_points;
}
bool base_personage::is_pers_dead() const{
return is_dead;
}
base_player::base_player(TArray<base_personage*>&& team_) : team(MoveTemp(team_)) {};
BasicTurnManager::BasicTurnManager(base_player* player1_, base_player* player2_, double points_per_move, double x_min_, double x_max_, double y_min_, double y_max_) :
player1(player1_), player2(player2_), action_points(points_per_move), current_player_action_points(action_points), x_min(x_min_), x_max(x_max_), y_min(y_min_),
y_max(y_max_), motion_number(1), first_player_motion(true), team1_alive((player1->team).Num()), team2_alive((player2->team).Num()) {}
bool BasicTurnManager::check_correctness(double x, double y) const{
return x >= x_min && x <= x_max && y >= y_min && y <= y_max;
}
void BasicTurnManager::next_move() {
current_player_action_points = action_points;
if (!first_player_motion) ++motion_number;
first_player_motion ^= 1;
}
int BasicTurnManager::get_move_number() const{
return motion_number;
}
bool BasicTurnManager::is_first_player_move() const {
return first_player_motion;
}
size_t BasicTurnManager::first_team_alive() const {
return team1_alive;
}
size_t BasicTurnManager::second_team_alive() const {
return team2_alive;
}
void BasicTurnManager::move_command(size_t pers_num, double new_x, double new_y) {
if (!check_correctness(new_x, new_y)) return;
if (first_player_motion) {
if (pers_num >= (player1->team).Num()) return;
(player1->team)[pers_num]->move_to_position(new_x, new_y, current_player_action_points);
}
else {
if (pers_num >= (player2->team).Num()) return;
(player2->team)[pers_num]->move_to_position(new_x, new_y, current_player_action_points);
}
}
void BasicTurnManager::attack_command(size_t pers_num, size_t abil_num, double attack_x, double attack_y) {
if (!check_correctness(attack_x, attack_y)) return;
if (first_player_motion) {
if (pers_num >= (player1->team).Num()) return;
base_personage* attacker = (player1->team)[pers_num];
if (!attacker->is_attack_startable(abil_num, attack_x, attack_y, current_player_action_points)) return;
base_ability* attack = (attacker->abilities)[abil_num];
current_player_action_points -= attack->cost;
for (auto def : player2->team) {
if (def->is_pers_dead()) continue;
if (attack->is_pers_hurt(attacker->get_personage_cords().X, attacker->get_personage_cords().Y, attack_x, attack_y,
def->get_personage_cords().X, def->get_personage_cords().Y)) {
def->accept_damage(attack->damage);
if (def->is_pers_dead()) --team2_alive;
}
}
}
else {
if (pers_num >= (player2->team).Num()) return;
base_personage* attacker = (player2->team)[pers_num];
if (!attacker->is_attack_startable(abil_num, attack_x, attack_y, current_player_action_points)) return;
base_ability* attack = (attacker->abilities)[abil_num];
current_player_action_points -= attack->cost;
for (auto def : player1->team) {
if (def->is_pers_dead()) continue;
if (attack->is_pers_hurt(attacker->get_personage_cords().X, attacker->get_personage_cords().Y, attack_x, attack_y,
def->get_personage_cords().X, def->get_personage_cords().Y)) {
def->accept_damage(attack->damage);
if (def->is_pers_dead()) --team1_alive;
}
}
}
}
}