// 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&& 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(x_coordinate), static_cast(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&& 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; } } } } }