diff --git a/game/game.cpp b/game/game.cpp index 38fcc0c..a6b96d9 100644 --- a/game/game.cpp +++ b/game/game.cpp @@ -9,7 +9,7 @@ Game::Game() { // advance simulation with 100 Hz - m_time_step = 1.0 / 100.0; + m_time_step = 1.0 / 100.0; m_time_for_next_step = 0.0; m_state = new game::State(); @@ -33,13 +33,9 @@ bool Game::cycle(float dt) float a = 2.0 * M_PI * util::randf_0_1(); float speed = 0.005; - m_state->players[0]->addCommand(new game::ShootCommand(a, speed)); - } -#if 1 - if (dt >= 10.0) { - //std::cout<<"time to big: " << dt << std::endl; - dt = m_time_step; + m_state->players[0]->addCommand(new game::SetSpeedCommand(speed)); + m_state->players[0]->addCommand(new game::ShootCommand(a)); } //std::cout<<"adding dt: " << dt << std::endl; @@ -57,11 +53,4 @@ bool Game::cycle(float dt) //std::cout << m_time_for_next_step << " s remaining time, " << steps << " steps taken." << std::endl; return true; -#else - (void) dt; - - m_state->advance(dt); - - return true; -#endif } diff --git a/game/state/commands.cpp b/game/state/commands.cpp index b84a214..2b82f27 100644 --- a/game/state/commands.cpp +++ b/game/state/commands.cpp @@ -10,23 +10,55 @@ namespace game { // TODO: idea // shoot multiple rockets at once or from different positions after // level up / upgrade ... - Missile *missile = new Missile(player, player->ship->position, m_angle, m_speed); + Missile *missile = new Missile(player, player->ship->position, m_angle, player->speed); Trace *trace = new Trace(missile); missile->trace = trace; - player->energy -= m_speed; + player->energy -= player->speed; player->missiles.push_back(missile); state->addTrace(trace); } - bool ShootCommand::allowed(const Player *player, const State *state) const + bool ShootCommand::ready(const Player *player, const State *state) const { (void) state; // TODO - return player->alive && player->energy >= m_speed; + return player->alive && player->energy >= player->speed; //return player->alive; } + + void ChangeNameCommand::apply(Player *player, State *state) const + { + // discard if not unique + for (const Player *other : state->players) { + if (m_name == other->name) { + std::cout << "name '" << m_name << "' already given to player #" << other->id << std::endl; + return; + } + } + + player->name = m_name; + } + + void SetSpeedCommand::apply(Player *player, State *state) const + { + (void) state; + player->speed = m_speed; + } + + void ClearTracesCommand::apply(Player *player, State *state) const + { + size_t i = 0; + while(i < state->traces.size()) { + Trace *trace = state->traces[i]; + if (trace->missile == nullptr && trace->missile->player == player) { + state->deleteTrace(trace); + } else { + i++; + } + } + } } diff --git a/game/state/commands.hpp b/game/state/commands.hpp index 5c8ff97..4ed914f 100644 --- a/game/state/commands.hpp +++ b/game/state/commands.hpp @@ -9,6 +9,10 @@ #include namespace game { + /** + * Base class for commands. + * must derive from this. + */ class Command { public: Command() @@ -19,7 +23,11 @@ namespace game { { } - virtual bool allowed(const Player *player, const State *state) const + // check whether the command is ready to execute. + // if not, wait. + // note: stuff like for admin should be done in execute() to discard the + // command and not block the queue. + virtual bool ready(const Player *player, const State *state) const { (void) player; (void) state; @@ -38,19 +46,74 @@ namespace game { virtual std::string name() const { return ""; } }; + /**********************************************************************/ + /* Implemented commands */ + /**********************************************************************/ + + /* + * Shoot at angle and optional speed. + * TODO + */ class ShootCommand : public Command { public: - ShootCommand(float angle, float speed) : m_angle(angle), m_speed(speed) + ShootCommand(float angle) : m_angle(angle) { } std::string name() const { return ""; } - void apply( Player *player, State *state) const; - bool allowed(const Player *player, const State *state) const; + void apply( Player *player, State *state) const; + bool ready(const Player *player, const State *state) const; private: float m_angle; + }; + + /** + * Change the name of the player if it will be uniuqe. + */ + class ChangeNameCommand : public Command { + public: + ChangeNameCommand(const std::string &name) : m_name(name) + { + } + + std::string name() const { return ""; } + + void apply(Player *player, State *state) const; + + private: + std::string m_name; + }; + + /** + * clear all traces of this player that are done + */ + class ClearTracesCommand : public Command { + public: + ClearTracesCommand() + { + } + + std::string name() const { return ""; } + + void apply(Player *player, State *state) const; + }; + + /** + * Set default speed of next shots for this player. + */ + class SetSpeedCommand : public Command { + public: + SetSpeedCommand(float speed) : m_speed(speed) + { + } + + std::string name() const { return ""; } + + void apply(Player *player, State *state) const; + + private: float m_speed; }; } diff --git a/game/state/player.hpp b/game/state/player.hpp index 199a411..3a6aeb4 100644 --- a/game/state/player.hpp +++ b/game/state/player.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -15,12 +16,14 @@ namespace game { public: int id; bool alive; + float speed; float energy; float deadTimeCounter; Ship *ship; + std::string name; std::vector missiles; - Player(int id) : id(id), alive(true), energy(0.0), ship(nullptr) + Player(int id) : id(id), alive(true), speed(0.01), energy(0.0), ship(nullptr), name("") { } diff --git a/game/state/state.cpp b/game/state/state.cpp index d84364d..71572e6 100644 --- a/game/state/state.cpp +++ b/game/state/state.cpp @@ -108,7 +108,7 @@ namespace game { // try to execute as much queued commands as possible. while (player->hasCommandInQueue()) { Command *command = player->peekCommand(); - if (!command->allowed(player, this)) { + if (!command->ready(player, this)) { break; } @@ -290,6 +290,20 @@ namespace game { traces.push_back(trace); } + void State::deleteTrace(Trace *trace) + { + // TODO: if traces of running missile is deleted it is dangerous + + size_t i = 0; + while(i < traces.size()) { + if (traces[i] == trace) { + delete(trace); + traces.erase(traces.begin()+i); + break; + } + } + } + void State::addExplosionFromHit(const Missile::Event *evt) { if (evt->hit == Hit::Nothing || evt->hit == Hit::BorderOfUniverse) { diff --git a/game/state/state.hpp b/game/state/state.hpp index 3fa7781..42d0659 100644 --- a/game/state/state.hpp +++ b/game/state/state.hpp @@ -9,6 +9,18 @@ #include "missile.hpp" +// TODO: +// give points for equipment / better weapons / more energy when: +// - player discovers the universe +// +// - the shot which made a kill was much longer than the direkt line between +// player and his target +// +// - add wormholes +// - add blackholes +// - shoot through suns which add a fire mantle to the rocket to make it more +// thick and dangerous but it gets destroyed after some time. + namespace game { // forward declarations class Command; @@ -56,6 +68,7 @@ namespace game { // add a trace to the list of traces. void addTrace(Trace *trace); + void deleteTrace(Trace *trace); /*************************************************************************/ /* Rendering */ diff --git a/game/state/trace.cpp b/game/state/trace.cpp index 4d93d2c..392076e 100644 --- a/game/state/trace.cpp +++ b/game/state/trace.cpp @@ -24,4 +24,9 @@ namespace game { points.push_back(TracePoint(missile)); } } + + void Trace::finish() + { + missile = nullptr; + } } diff --git a/game/state/trace.hpp b/game/state/trace.hpp index ab33b2f..7af85dc 100644 --- a/game/state/trace.hpp +++ b/game/state/trace.hpp @@ -21,6 +21,10 @@ namespace game { // the missile) in case the fidelityCounter would skip the current position. void addPointFromMissile(bool forceAdd=false); + // call this to mark the trace as finish and disconnect it from the + // missile. + void finish(); + // TODO: add extendLastPointToPosition() method for saving points / // optimization later on