Commit 0bd65a57 authored by louiz’'s avatar louiz’
Browse files

Make the Dash and Concentrate abilities work as expected

parent aedda0ac
......@@ -2,6 +2,7 @@
#include <game/game_client.hpp>
#include <utils/time.hpp>
#include <world/world_callbacks.hpp>
#include <world/task.hpp>
#include "orders.pb.h"
#include "requests.pb.h"
......@@ -43,6 +44,8 @@ GameClient::GameClient(const std::shared_ptr<Screen>& screen):
*/
this->world.callbacks->entity_created =
std::bind(&GameClient::on_entity_created, this, ph::_1);
this->world.callbacks->task_changed =
std::bind(&GameClient::on_entity_task_changed, this, ph::_1, ph::_2);
this->world.callbacks->entity_deleted =
std::bind(&GameClient::on_entity_deleted, this, ph::_1);
this->world.callbacks->ability_casted =
......@@ -375,6 +378,19 @@ void GameClient::on_entity_created(const Entity* entity)
this->camera.on_new_entity(entity);
}
void GameClient::on_entity_task_changed(const Entity* entity, const Task* task)
{
switch (task->get_type())
{
case TaskType::Concentrate:
this->sounds_handler.play(SoundType::Concentrate, false, 100.f);
break;
case TaskType::Dash:
this->sounds_handler.play(SoundType::Dash, false, 100.f);
break;
}
}
void GameClient::on_entity_deleted(const Entity* entity)
{
this->camera.on_entity_deleted(entity);
......
......@@ -18,6 +18,8 @@
#include <memory>
class Task;
class GameClient: public Game, public ClientBase
{
public:
......@@ -41,6 +43,7 @@ public:
void on_ability_casted(const Entity*, const AbilityType&, const Entity*,
const Position&);
void on_impact(const Entity* entity, const Entity* target);
void on_entity_task_changed(const Entity* entity, const Task* task);
World& get_world();
Camera& get_camera();
......
......@@ -44,6 +44,9 @@ SoundsHandler::SoundsHandler():
this->load("data/sounds/invoker/EMP_target.wav", SoundType::EmpStart);
this->load("data/sounds/invoker/EMP_effect.wav", SoundType::EmpExplode);
this->load("data/sounds/tusk/Walrus_Punch_cast.wav", SoundType::Concentrate);
this->load("data/sounds/sand_king/Burrowstrike.wav", SoundType::Dash);
}
void SoundsHandler::load(const char* filename, const SoundType& type)
......
......@@ -18,6 +18,8 @@ enum class SoundType
BlinkStart,
EmpStart,
EmpExplode,
Concentrate,
Dash,
count,
};
......
......@@ -33,7 +33,6 @@ Camera::Camera(GameClient* game, Screen* screen):
fog(1920, 1080, this, &this->world())
{
this->tileset.load_from_file("test6.tmx");
}
Camera::~Camera()
......
......@@ -2,6 +2,10 @@
#include <world/entity.hpp>
#include <world/works/concentrate_work.hpp>
#include <world/works/dash_work.hpp>
#include <world/world.hpp>
#include <world/world_callbacks.hpp>
#include <world/team.hpp>
#include <world/health.hpp>
#include <logging/logging.hpp>
......@@ -11,8 +15,9 @@ const std::string NamedAbility<Dash>::name = "Dash";
template <>
const AbilityType NamedAbility<Dash>::ability_type = AbilityType::Dash;
Dash::Dash():
ActiveAbility(TargetType::Point)
Dash::Dash(const Fix16 max_distance):
ActiveAbility(TargetType::Point),
max_distance(max_distance)
{
}
......@@ -32,9 +37,25 @@ void Dash::cast(Entity* entity, World* world, const Position& pos, const bool qu
if (!task)
return;
auto concentrate_task = static_cast<ConcentrateTask*>(task);
auto value = concentrate_task->value();
log_debug("The concentrate task value is: " << value);
auto work = std::make_unique<DashWork>(entity, world, pos, 35,
nullptr, nullptr);
auto concentrate_value = concentrate_task->value();
log_debug("The concentrate task value is: " << concentrate_value);
Team* own_team = entity->get<Team>();
assert(own_team);
auto on_impact = [entity, world, concentrate_value, own_team](Entity* impacted_entity)
{
Team* team = impacted_entity->get<Team>();
// Do nothing on our teammates
if (team->get() == own_team->get())
return;
Health* health = impacted_entity->get<Health>();
if (!health)
return;
world->callbacks->impact(entity, impacted_entity);
health->add(-concentrate_value/2);
};
auto work = std::make_unique<DashWork>(entity, world, pos, 35, this->max_distance, 50,
on_impact, nullptr);
entity->set_work(std::move(work));
}
......@@ -2,15 +2,19 @@
#define DASH_HPP_INCLUDED
#include <world/abilities/active_ability.hpp>
#include <fixmath/fix16.hpp>
class Dash: public ActiveAbility<Dash>
{
public:
Dash();
Dash(const Fix16 max_distance);
~Dash() = default;
void cast(Entity* entity, World*, const Position& pos, const bool queue) override final;
void cast(Entity* entity, World*, const Position& pos,
const bool queue) override final;
private:
const Fix16 max_distance;
Dash(const Dash&) = delete;
Dash(Dash&&) = delete;
Dash& operator=(const Dash&) = delete;
......
......@@ -29,7 +29,7 @@ std::unique_ptr<Entity> EntityFactory::make_entity(const EntityType type)
if (type == 0)
{ // Default unit
entity->make_manipulable();
entity->add_component(std::make_unique<Health>(100));
entity->add_component(std::make_unique<Health>(200));
entity->add_component(std::make_unique<ManaPool>(300));
entity->add_component(std::make_unique<Vision>(700, false));
entity->add_component(std::make_unique<Location>(20, true));
......@@ -42,10 +42,9 @@ std::unique_ptr<Entity> EntityFactory::make_entity(const EntityType type)
abilities->add(1, std::make_unique<Blink>());
abilities->add(2, std::make_unique<Phase>());
abilities->add(3, std::make_unique<Emp>());
abilities->add(4, std::make_unique<Dash>());
abilities->add(4, std::make_unique<Dash>(400));
abilities->add(5, std::make_unique<Concentrate>());
entity->add_component(std::move(abilities));
}
else if (type == 1)
......
......@@ -62,13 +62,13 @@ void Mobility::follow_path(Path& path, World* world, Location* location)
location->position() = after_movement;
}
void Mobility::move_towards(const Position& goal, Location* location)
Fix16 Mobility::move_towards(const Position& goal, Location* location)
{
Vec2 movement(goal - location->position());
if (movement.length() == 0)
{
location->position() = goal;
return;
return 0;
}
if (Position::distance(goal, location->position()) < this->speed)
......@@ -77,15 +77,18 @@ void Mobility::move_towards(const Position& goal, Location* location)
movement.set_length(this->speed);
location->position() += movement;
this->last_movement = movement;
return movement.length();
}
void Mobility::move_towards(const Position& goal, Location* location, Fix16 speed)
Fix16 Mobility::move_towards(const Position& goal, Location* location, Fix16 speed)
{
auto speed_backup = this->get_speed();
this->set_speed(speed);
this->move_towards(goal, location);
auto res = this->move_towards(goal, location);
this->set_speed(speed_backup);
return res;
}
Fix16 Mobility::get_angle() const
{
return this->last_movement.angle();
......
......@@ -31,8 +31,8 @@ public:
*
* The goal is reached if after this function, the location's position == goal.
*/
void move_towards(const Position& goal, Location* location);
void move_towards(const Position& goal, Location* location, Fix16 speed);
Fix16 move_towards(const Position& goal, Location* location);
Fix16 move_towards(const Position& goal, Location* location, Fix16 speed);
/**
* Get the angle of the entity that has this mobility, based on the latest
* movement done.
......
......@@ -3,6 +3,7 @@
#include <world/world.hpp>
#include <world/world_callbacks.hpp>
#include <world/location.hpp>
#include <world/health.hpp>
#include <world/entity.hpp>
#include <world/works/projectile_work.hpp>
......
......@@ -2,14 +2,20 @@
#include <world/entity.hpp>
#include <world/location.hpp>
#include <world/mobility.hpp>
#include <world/world.hpp>
DashTask::DashTask(Entity* entity, const Position& goal, Fix16 speed, std::function<void(Entity*)> impact_cb,
DashTask::DashTask(Entity* entity, const Position& goal, Fix16 speed,
Fix16 max_distance, Fix16 impact_width, std::function<void(Entity*)> impact_cb,
std::function<void(void)> goal_cb):
Task(entity),
goal(goal),
speed(speed),
max_distance(max_distance),
impact_width(impact_width),
travelled_distance(0),
impact_callback(impact_cb),
goal_callback(goal_cb),
impacted_entities{},
mobility(entity->get<Mobility>()),
location(entity->get<Location>())
{
......@@ -19,9 +25,27 @@ DashTask::DashTask(Entity* entity, const Position& goal, Fix16 speed, std::funct
bool DashTask::tick(World* world)
{
this->mobility->move_towards(this->goal, this->location, this->speed);
// TODO check collision
if (this->goal == this->location->position())
this->travelled_distance += this->mobility->move_towards(this->goal, this->location, this->speed);
if (this->impact_callback)
{
// Check for an impact with any entity
for (const std::shared_ptr<Entity>& entity: world->entities)
{
Location* entity_location = entity->get<Location>();
if (!entity_location)
continue;
if (std::find(this->impacted_entities.begin(), this->impacted_entities.end(),
entity.get()) != this->impacted_entities.end())
continue;
if (Position::distance(entity_location->position(), this->location->position()) <= this->impact_width)
{
this->impact_callback(entity.get());
this->impacted_entities.push_back(entity.get());
}
}
}
if (this->goal == this->location->position() || this->travelled_distance >= this->max_distance)
{
// TODO adjust location to be on a valid world position
if (this->goal_callback)
......
......@@ -4,6 +4,7 @@
#include <world/task.hpp>
#include <world/position.hpp>
#include <functional>
#include <vector>
class Location;
class Mobility;
......@@ -11,7 +12,8 @@ class Mobility;
class DashTask: public Task
{
public:
DashTask(Entity* entity, const Position& goal, Fix16 speed, std::function<void(Entity*)> impact_cb,
DashTask(Entity* entity, const Position& goal, Fix16 speed,
Fix16 max_distance, Fix16 impact_width, std::function<void(Entity*)> impact_cb,
std::function<void(void)> goal_cb);
~DashTask() = default;
TaskType get_type() const
......@@ -23,6 +25,9 @@ public:
private:
const Position goal;
const Fix16 speed;
const Fix16 max_distance;
const Fix16 impact_width;
Fix16 travelled_distance;
/**
* Function called for each encountered entity
*/
......@@ -31,6 +36,12 @@ private:
* Function called when the goal is reached
*/
std::function<void(void)> goal_callback;
/**
* A list of already impacted entities, to avoid calling the callback many
* times on the same one
*/
std::vector<Entity*> impacted_entities;
Location* location;
Mobility* mobility;
......
......@@ -5,7 +5,7 @@
void Work::set_task(World* world, std::unique_ptr<Task> task)
{
world->callbacks->task_changed(this->entity, task->get_type());
world->callbacks->task_changed(this->entity, task.get());
this->task = std::move(task);
}
......
......@@ -27,7 +27,7 @@ public:
entity_created([](const Entity*){}),
entity_deleted([](const Entity*){}),
ability_casted([](const Entity*, const AbilityType&, const Entity*, const Position&){}),
task_changed([](const Entity*, const TaskType&){}),
task_changed([](const Entity*, const Task*){}),
impact([](const Entity*, const Entity*){})
{
}
......@@ -48,7 +48,7 @@ public:
/**
* Called whenever the current task of a unit has changed.
*/
std::function<void(const Entity*, const TaskType&)> task_changed;
std::function<void(const Entity*, const Task*)> task_changed;
/**
* Called whenever a projectile-like entity creates an impact.
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment