/* core/entity.h This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2. */ #ifndef __INCLUDED_CORE_ENTITY_H__ #define __INCLUDED_CORE_ENTITY_H__ #include #include #include #include #include "model/model.h" #include "math/axis.h" #include "math/mathlib.h" namespace core { class Entity; class EntityControlable; } #include "core/extension.h" #include "core/descriptions.h" #include "core/player.h" #include "core/zone.h" namespace core { /// The base world entity. All gameworld entities must derive from this class. class Entity { friend class Extension; public: /// Entity flags enum Flags {Static = 1, Solid = 2, Bright = 4, Dockable = 8, ShowOnMap = 16}; /// Entity type constants enum Type {Default = 0, Dynamic = 1, Controlable = 2, Globe = 3}; /// Entity shape constants enum Shape {Diamond = 0, Sphere = 1, Cube = 2, Axis = 3}; /// EntityDynamic State constants enum State {Normal = 0, NoPower = 1, ImpulseInitiate = 2, Impulse = 3, JumpInitiate = 4, Jump = 5, Docked = 6, Destroyed = 7}; /// entity menus collection typedef typedef std::list Menus; /// create a new entity and add it to the registry Entity(const unsigned int flags = 0); /// create an entity from stream data Entity(std::istream & is); /// destroy an entity virtual ~Entity(); /*----- inspectors ------------------------------------------------ */ /// entity id inline const unsigned int id() const { return entity_id; } /// module type id inline const unsigned int moduletype() const { return entity_moduletypeid; } /// core type id virtual inline const unsigned int type() const { return Default; } /// entity flags inline const unsigned int flags() const { return entity_flags; } /// returns true of a flag is set inline const bool flag_is_set(const Flags flag) const { return ((entity_flags & (unsigned int)flag) == (unsigned int)flag); } /// entity label (can not contain double quotes ") inline const std::string& label() const { return entity_label; } /// entity name (can not contain double qoutes ") inline const std::string & name() const { return entity_name; } /// pointer to the model, is used client-side inline model::Model * model() { return entity_model; } /// modelname inline const std::string & modelname() const { return entity_modelname; } /// pointer to the zone the entity belongs to inline Zone *zone() const { return entity_zone; } /// the zone the entity left in case of a zone change inline Zone *oldzone() const { return entity_oldzone; } /// dirty flag inline bool dirty() const { return entity_dirty; } /// entity location inline const math::Vector3f& location() const { return entity_location; } /// local coordinate system of the entity inline const math::Axis& axis() const { return entity_axis; } /// primary color of the entity inline const math::Color& color() const { return entity_color; } /// secondary inline const math::Color& color_second() const { return entity_color_second; } /// base shape of the entity inline const Shape shape() const { return entity_shape; } /// base radius of the entity inline const float radius() const { return entity_radius; } /// current speed of the entity in game units per second inline const float speed() const { return entity_speed; } /// indicates a server-side entity inline const bool serverside() const { return entity_serverside; } /// general visibility inline const bool visible() const { return entity_visible; } /// entity menus inline Menus &menus() { return entity_menus; } /// extensions inline Extension *extension(size_t type) const { return entity_extension[type]; } /// find a menu MenuDescription *find_menu(const std::string &label); /* ---- mutators -------------------------------------------------- */ /// assign entity color inline void set_color(const math::Color &color) { entity_color.assign(color); } /// assign entity secondary color inline void set_color_second(const math::Color &color) { entity_color_second.assign(color); } /// set dirty flag inline void set_dirty(const bool dirty = true) { entity_dirty = dirty; } /// mark the entity as destroyed virtual void die(); /// runs one game frame for the entity /** * The default implementation does nothing */ virtual void frame(float seconds); /** * @brief set the zone the entity is currently in * * this fuction removes the entity from its previous zone * and removes it to the new one, if it is not 0 */ virtual void set_zone(Zone *zone); /// set the label void set_label(const char *label); /// set the label void set_label(const std::string &label); /// set the name void set_name(const char *name); /// set the name void set_name(const std::string &name); /// set visibility inline void set_visible(const bool visible = true) { entity_visible = visible; } /// set as server-side entity inline void set_serverside(const bool serverside = true) { entity_serverside = serverside; } /// set the model name and load the model void set_modelname(const std:: string &model); /// set the model void set_model(model::Model *model); /// set entity radius inline void set_radius(const float radius) { entity_radius = radius; } /* ---- actors ---------------------------------------------------- */ /// called when the entity received a docking request virtual void dock(core::Entity *entity); /// set flags inline void set_flag(Flags flag) { entity_flags |= flag; } /// unset flags inline void unset_flag(Flags flag) { entity_flags &= ~flag; } /// add an entity menu void add_menu(MenuDescription *menu); /// remove an entity menu void remove_menu(std::string const &label); /// clear all update flags virtual void clear_updates(); /** * @brief mutable reference to the location */ inline math::Vector3f& get_location() { return entity_location; } /** * @brief mutable reference to the axis */ inline math::Axis& get_axis() { return entity_axis; } /** * @brief mutable reference to the primary color */ inline math::Color& get_color() { return entity_color; } /** * @brief mutable reference to the secondary color */ inline math::Color& get_color_second() { return entity_color_second; } /* ---- deserializers -------------------------------------- */ /// receive a client-to-server update from a stream virtual void receive_client_update(std::istream &is); /// receive a server-to-client create from a stream virtual void receive_server_create(std::istream &is); /// receive a server-to-client update from a stream virtual void receive_server_update(std::istream &is); /* ---- serializers ---------------------------------------- */ /// serialize the entity to a stream virtual void serialize_server_create(std::ostream & os) const; /// serialize a client-to-server update on a stream virtual void serialize_client_update(std::ostream & os) const; /// serialize a server-to-client update on a stream virtual void serialize_server_update(std::ostream & os) const; /* ---- static --------------------------------------------- */ /// type definition for the entity registry typedef std::map Registry; /// find an entity in the registry static Entity *find(unsigned int id); /// add an entity to the registry static void add(Entity *ent, unsigned int it); /// erase an entity from the registry and delete it static void erase(unsigned int entity_id); /// list the entity registry static void list(); /// the entity registry static inline Registry & registry() { return entity_registry; } /* entity_ variables can be set by the module */ /// speed of the entity float entity_speed; Shape entity_shape; unsigned int entity_moduletypeid; bool entity_created; bool entity_destroyed; /// timestamp when entity data was received from the server float entity_servertimestamp; private: unsigned int entity_id; unsigned int entity_flags; bool entity_dirty; bool entity_visible; bool entity_serverside; math::Vector3f entity_location; math::Axis entity_axis; float entity_radius; math::Color entity_color; math::Color entity_color_second; std::string entity_name; std::string entity_label; std::string entity_modelname; model::Model* entity_model; // the zone the entity belongs to Zone* entity_zone; // the previous zone the entity belonged too Zone* entity_oldzone; Menus entity_menus; Extension* entity_extension[4]; static Registry entity_registry; static size_t entity_nextid; static void add(Entity *ent); }; /// an entity that can move around in the game world class EntityDynamic : public Entity { public: /// create a dynamic entity EntityDynamic(const unsigned int flags = 0); /// create a dynamic entity from stream data EntityDynamic(std::istream & is); virtual ~EntityDynamic(); /*----- inspectors ------------------------------------------------ */ /// core type id virtual inline const unsigned int type() const { return Entity::Dynamic; } /// event state inline const int state() const { return entity_state; } /// event state timer inline const float timer() const { return entity_timer; } /*----- serializers ----------------------------------------------- */ /// serialize the entity to a stream virtual void serialize_server_create(std::ostream & os) const; /// serialize a client-to-server update on a stream virtual void serialize_client_update(std::ostream & os) const ; /// serialize a server-to-client update on a stream virtual void serialize_server_update(std::ostream & os) const; /*----- mutators -------------------------------------------------- */ /// receive a client-to-server update from a stream virtual void receive_client_update(std::istream &is); /// receive a server-to-client create from a stream virtual void receive_server_create(std::istream &is); /// receive a server-to-client update from a stream virtual void receive_server_update(std::istream &is); /// set event state virtual void set_state(int state); /// runs one game frame for the entity /** * The default implementation will update the position() of the entity, * determined by its speed() and axis() */ virtual void frame(float seconds); protected: float entity_timer; int entity_state; }; /// an entity that can be controlled by a player class EntityControlable : public EntityDynamic { friend class Player; public: /// create a controlable entity EntityControlable(Player *owner, const unsigned int flags = 0); /// create a controlable entity from stream data EntityControlable(std::istream & is); virtual ~EntityControlable(); /*----- inspectors ------------------------------------------------ */ /// core type id virtual inline const unsigned int type() const { return Entity::Controlable; } /// owner of this entity inline Player *owner() const { return entity_owner; } /// thrust inline float thrust() const { return entity_thrust; } /// movement indicator inline float movement() const { return entity_movement; } /*----- serializers ----------------------------------------------- */ /// serialize the entity to a stream virtual void serialize_server_create(std::ostream & os) const; /// serialize a client-to-server update on a stream virtual void serialize_client_update(std::ostream & os) const; /// serialize a server-to-client update on a stream virtual void serialize_server_update(std::ostream & os) const; /*----- mutators -------------------------------------------------- */ /// receive a client-to-server update from a stream virtual void receive_client_update(std::istream &is); /// receive a server-to-client create from a stream virtual void receive_server_create(std::istream &is); /// receive a server-to-client update from a stream virtual void receive_server_update(std::istream &is); /// set the target thrust void set_thrust(float thrust); /// set the target direction void set_direction(float direction); /// set the target pitch void set_pitch(float pitch); /// set target roll void set_roll(float roll); /// set target strafe void set_strafe(float strage); /// set afterburner/reverse void set_afterburner(float afterburner); /// runs one game frame for the entity /** * The default implementation will set direction() and thrust() to the desired targets * and calls its parent frame() funcion. */ virtual void frame(float seconds); /// current thrust float entity_thrust; protected: /* target_ variables can be set by the client */ /// target thrust as set by the client float target_thrust; /// target direction as set by the client /** target_direction must be in the [-1, 1] range */ float target_direction; /// target pitch as set by the client /** target_pitch must be in the [-1, 1] range */ float target_pitch; /// target roll as set by the client /** target_roll must be in the [-1, 1] range */ float target_roll; float target_afterburner; float target_strafe; float entity_movement; private: // owner of the entity Player *entity_owner; }; /// a Globe entity class EntityGlobe : public Entity { public: EntityGlobe(const unsigned int flags = 0); EntityGlobe(std::istream & is); virtual ~EntityGlobe(); /*----- inspectors ----------------------------------------------- */ /// texture name inline const std::string &texture() const { return entity_texture; } /// rotation speed in degrees per second inline float rotationspeed() const { return entity_rotationspeed; } /*----- serializers ----------------------------------------------- */ /// serialize the entity to a stream virtual void serialize_server_create(std::ostream & os) const; /// receive a server-to-client create from a stream virtual void receive_server_create(std::istream &is); /*----- inspectors ------------------------------------------------ */ /// core type id virtual inline const unsigned int type() const { return Entity::Globe; } std::string entity_texture; /// client side, texture id unsigned int render_texture; /// rotation speed in degrees/second; float entity_rotationspeed; }; } #endif // __INCLUDED_CORE_ENTITY_H__