#pragma once #include #include #include #include #include #include #include "missile.hpp" #include "planet.hpp" #include "state_update_event.hpp" #define ENERGY_PER_DT 0.3 // 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; class Player; class Ship; class Trace; class Explosion; class IdGenerator { public: IdGenerator() : m_nextId(0) { } size_t makeNextId() { return m_nextId++; if (m_nextId == 0) { std::cerr << "note: id counter just wrapped to 0, " "funny things can happen now." << std::endl; } } private: size_t m_nextId; }; class State { public: /*************************************************************************/ /* State management */ /*************************************************************************/ // called to setup the state (randomize planets, kill // traces/missiles/ships etc.) void init(int numPlanets=15); // main method to advance the simulation by the given timestamp in // seconds. void advance(float dt); /*************************************************************************/ /* Network / Input */ /*************************************************************************/ // The upper layer (network/renderer) calling these three functions // should keep id's unique and give one (network) input an id. size_t addPlayer(); void clear(size_t playerId); void setName(size_t playerId, std::string name); void setSpeed(size_t playerId, double speed); void quitPlayer(size_t playerId); void commandForPlayer(size_t playerId, Command *cmd); // lookup. return nullptr on invalid playerId Player *playerForId(size_t playerId); /*************************************************************************/ /* Mixed stuff */ // distance after which missiles get lost in space (and explode) float maxMissileDistance() const { return m_maxMissileDistance; } // each ship has the same radius float shipRadius() const { return m_shipRadius; } // add a trace to the state void addTrace(Trace *trace); // add a missile to the state void addMissile(Missile *missile); // add a ship to the state void addShip(Ship *ship); // delete traces with this command void deleteTrace(Trace *trace); // using a pointer // get the current time float timestamp() const { return m_time; } // check if game is in dev. mode. // custom commands will then work etc. bool developerMode() const { return m_developerMode; } // change the mode. void setDeveloperMode(bool on) { std::cout<<"[state] developer mode is: " << (on ? "on" : "off") << std::endl; m_developerMode = on; } // called when the rendering window changes // TODO: give dpi as information too void setPlayingFieldSize(int width, int height); void setPlayingFieldCenter(int width, int height); size_t generateId(); void applyAndClearAllOldStateUpdates(); // delete the items for events that are to be removed in proper way // after the events were given to other parts of the application. const std::list ¤tStateUpdateEvents() const; /*************************************************************************/ /* Rendering */ /*************************************************************************/ // TODO: hide and replace by events // Game items which should be rendered are here: // (access missiles by iterating over player's missiles attribute) std::vector planets; std::list ships; std::list players; std::list traces; std::list explosions; private: /*************************************************************************/ /* Internal */ /*************************************************************************/ void playerKillsPlayer(Player *killer, Player *victim); void addExplosionFromHit(const Missile::Event *evt); bool findPlanetSpawnPosition(bool planetIsSun, float radius, glm::vec2 *pos); void advanceTraceAges(float dt); void advanceExplosions(float dt); void advancePlayerShipSpawns(float dt); void advancePlayerCommands(float dt); void advancePlayerMissiles(float dt); void setupPlanets(int numPlanets); Planet::Material materialForStandardPlanetDistribution(int index); // try to spawn a ship for this player. // return true on success, false on failure to find a spot. bool spawnShipForPlayer(Player *player); // find some place where nothing is placed nearby (ships/planets). // usefule for spanwing things bool findFreePositionWithRadius(float r, glm::vec2 &pos); float m_maxMissileDistance; float m_playerRespawnTime; float m_shipRadius; float m_defaultEnergy; int m_maxNumTraces; IdGenerator m_ids; float m_time; bool m_developerMode; glm::vec2 m_playingFieldCenter; glm::vec2 m_playingFieldSize; std::list m_nextEvents; std::list m_allEvents; }; }