ekku@198: #ifndef PLAYER_HH ekku@198: #define PLAYER_HH ekku@198: ekku@198: class Player; saiam@199: class LocalPlayer; saiam@199: class RemotePlayer; ekku@198: terom@233: #include "Weapon.hh" saiam@308: #include "Projectile.hh" saiam@199: #include "GameState.hh" ekku@198: #include "PhysicsObject.hh" terom@205: #include "Input.hh" ekku@225: #include "Rope.hh" terom@296: #include "Types.hh" terom@412: terom@411: #include "Graphics/Drawable.hh" terom@411: nireco@212: #include ekku@198: terom@283: /** terom@283: * A Player is a PhysicsObject that represents a player - a remote client on the server, a local singleplayer player, a terom@283: * local network-client player, a remote network-client player, etc. terom@283: */ ekku@198: class Player : public PhysicsObject { ekku@228: friend class Rope; ekku@228: saiam@275: public: saiam@275: GameState &state; nireco@212: saiam@275: protected: saiam@275: // XXX: not used saiam@275: bool visible; saiam@275: saiam@275: // our weapons saiam@275: std::vector weapons; saiam@275: saiam@275: // the index of the currently selected weapon saiam@275: unsigned int selectedWeapon; terom@239: saiam@275: // we have a rope saiam@275: Rope rope; terom@296: terom@296: /** Our current health */ terom@296: Health health; ekku@295: terom@300: /** Our respawn-timer */ terom@300: Timer respawn_timer; terom@300: CL_Slot respawn_slot; terom@300: terom@393: // XXX: updated where? saiam@275: int animation_step; nireco@219: saiam@306: //Player stats saiam@306: uint16_t kills; saiam@306: uint16_t deaths; saiam@306: terom@276: /** terom@276: * Default constructor for use with virtual inheritance... it's not defined, and must not be called terom@276: */ terom@276: Player (void); terom@274: terom@276: /** terom@276: * Initialize params, and add ourselves to GameState terom@276: */ terom@276: Player (GameState &state, Vector position, bool visible); saiam@275: terom@276: /** terom@276: * Remove player from state players list terom@276: */ terom@276: ~Player (void); terom@300: terom@300: /** terom@300: * Move the worm to the given position, removeGround to dig a hole there, and enable ourselves terom@300: */ terom@300: virtual void spawn (Vector position); terom@300: terom@300: /** terom@300: * We die. Disable and prepare respawn_timer terom@300: */ terom@302: virtual void die (bool start_timer = true); terom@300: terom@300: /** terom@300: * Calculate a new position for the worm, and respawn there. Also set health back to 100% terom@300: */ terom@302: virtual void respawn (TimeMS dt); terom@236: ekku@295: /** saiam@275: * Used by the network code to execute various actions saiam@275: */ saiam@275: virtual void handleDig (Vector position, float radius); terom@276: virtual void handleFireWeapon (Weapon *weapon, Vector position, Vector velocity); saiam@275: virtual void handleChangeWeapon (unsigned int weaponIndex); nireco@212: saiam@275: // Called by rope to handle state changes, these don't do anything by default saiam@275: virtual void handleRopeState (RopeState state); saiam@275: virtual void handleRopeLength (float length); terom@276: terom@276: public: terom@276: /** terom@276: * Called when a weapon is fired, this should apply recoil and reload the weapon terom@276: */ terom@276: void weaponFired (Weapon *weapon); saiam@275: terom@276: /** terom@276: * Get the currently selected weapon terom@276: * terom@276: * @return A pointer to the Weapon object saiam@275: */ saiam@275: Weapon* getCurrentWeapon(); terom@221: terom@276: /** terom@276: * Get the weapon with the given index terom@276: * terom@276: * @return A pointer to a Weapon object if found, NULL otherwise terom@276: */ terom@276: Weapon* getWeapon (WeaponID id); terom@276: ekku@295: /** saiam@275: * Prints random things via Engine::log saiam@275: */ saiam@275: void printDebugInfo (); terom@220: ekku@295: /** saiam@275: * Overrides PhysicsObject::tick to also advance game state saiam@275: */ saiam@275: virtual void tick (TimeMS dt); saiam@275: ekku@295: /** ekku@295: * This is called when the player collides with the terrain or with some other object. ekku@295: */ ekku@295: void onCollision (Vector collisionPoint, PhysicsObject *other); ekku@295: terom@296: /** terom@296: * We have been hit by something, and therefore take some damage. terom@296: * terom@296: * XXX: should this take the Projectile instead or somesuch? terom@296: */ saiam@308: void takeDamage (Projectile *source); saiam@308: saiam@308: /** ekku@322: * If the player has a pivot calculate the force it causes. ekku@322: */ ekku@322: Vector getPivotForce (void); ekku@322: ekku@322: /** nireco@312: * Gives player's health in percents from maximum nireco@312: */ nireco@312: float getHealthPercent() const; nireco@312: nireco@312: /** saiam@308: * Increment player killcounter by one. saiam@308: */ saiam@308: void addKill (); terom@296: saiam@275: /* saiam@275: * Drawing requires the skin texture, which is loaded on-demand when draw is called saiam@275: */ saiam@275: static bool skin_loaded; saiam@275: static CL_Surface skin_surface; terom@411: terom@411: /** terom@411: * Draw this player terom@411: */ terom@412: virtual void draw (graphics::Display &display, PixelCoordinate camera); terom@412: terom@412: /** terom@412: * Returns statistics on the number of kills for this player terom@412: */ terom@412: uint16_t getKills() { return kills; } terom@296: terom@412: /** terom@412: * Returns statistics on the number of deaths for this player terom@412: */ nireco@325: uint16_t getDeaths() { return deaths; } ekku@198: }; ekku@198: terom@283: /** terom@283: * A LocalPlayer is a Player that we handle input for - so this is our own player on the client/singleplayer, or all terom@283: * the remote clients on a server - the name is a bit misleading. terom@283: * terom@283: * This inherits virtually from Player so that subclasses can also define custom behaviour for the base Player class. terom@283: */ terom@209: class LocalPlayer : public virtual Player { saiam@275: private: nireco@312: /** saiam@275: * Calculates projectil position/velocity and calls handleCreateProjectile saiam@275: */ saiam@275: void fireWeapon (Weapon *weapon); terom@237: nireco@312: /** saiam@275: * Change weapon index, should be negative or positive 1 saiam@275: */ saiam@275: void changeWeapon (int delta); terom@223: saiam@275: public: nireco@312: /** saiam@275: * Called to invoke some action on this player that we control, either by Graphics or NetworkServer. saiam@275: * saiam@275: * NetworkClientLocalPlayer overrides this to send the input to the server, which then handles it saiam@275: */ saiam@275: virtual void handleInput (PlayerInput input, TimeMS dt); terom@233: nireco@312: /** saiam@275: * As Player, but also draws the current weapon name if displayWeapon saiam@275: */ terom@412: virtual void draw (graphics::Display &display, bool displayWeapon, PixelCoordinate camera); ekku@198: }; ekku@198: terom@283: /** terom@283: * A RemotePlayer is a Player that we don't handle input for - they are a remote client connected to a remote server. terom@283: * terom@283: * This inherits virtually from Player so that subclasses can also define custom behaviour for the base Player class. terom@283: */ terom@283: terom@209: class RemotePlayer : public virtual Player { saiam@275: protected: ekku@198: }; ekku@198: ekku@198: ekku@198: #endif