1 /*
2  *  Copyright (C) 2011-2016  OpenDungeons Team
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef MOVABLEGAMEENTITY_H
19 #define MOVABLEGAMEENTITY_H
20 
21 #include "entities/GameEntity.h"
22 
23 #include <OgreVector3.h>
24 
25 #include <deque>
26 #include <list>
27 
28 class Tile;
29 
30 namespace EntityAnimation
31 {
32     static const std::string idle_anim = "Idle";
33     static const std::string flee_anim = "Flee";
34     static const std::string die_anim = "Die";
35     static const std::string dig_anim = "Dig";
36     static const std::string attack_anim = "Attack1";
37     static const std::string claim_anim = "Claim";
38     static const std::string walk_anim = "Walk";
39     static const std::string sleep_anim = "Sleep";
40 };
41 
42 class MovableGameEntity : public GameEntity
43 {
44 public:
45     MovableGameEntity(GameMap* gameMap);
46 
~MovableGameEntity()47     virtual ~MovableGameEntity()
48     {}
49 
50     //! \brief Checks if the destination queue is empty
51     bool isMoving();
52 
53 
54     /*! \brief Replaces an object's current walk queue with a new path. During the
55      * walk, the entity will play walkAnim (looped). When it gets to the wanted position,
56      * it will play endAnim (looped or not depending on loopEndAnim).
57      */
58     void setWalkPath(const std::string& walkAnim, const std::string& endAnim, bool loopEndAnim,
59         bool playIdleWhenAnimationEnds, const std::vector<Ogre::Vector3>& path);
60 
61     /*! \brief Converts a tile list to a vector of Ogre::Vector3
62      *
63      * If skipFirst is true, the first tile in the list will be skipped
64      */
65     static void tileToVector3(const std::list<Tile*>& tiles, std::vector<Ogre::Vector3>& path, bool skipFirst, Ogre::Real z);
66 
67     //! \brief Clears all future destinations from the walk queue, stops the object where it is, and sets its animation state.
68     //! This is a server side function
69     void clearDestinations(const std::string& animation, bool loopAnim, bool playIdleWhenAnimationEnds);
70 
71     //! \brief Stops the object where it is, and sets its animation state.
72     virtual void stopWalking();
73 
74     //! \brief Clients side function that corrects entities moves to allow several entities
75     //! to be on the same tile
correctEntityMovePosition(Ogre::Vector3 & position)76     virtual void correctEntityMovePosition(Ogre::Vector3& position)
77     {}
78 
79     virtual void correctDropPosition(Ogre::Vector3& position) override;
80 
getMoveSpeed()81     virtual double getMoveSpeed() const
82     { return 1.0; }
83 
84     virtual void setAnimationState(const std::string& state, bool loop = true, const Ogre::Vector3& direction = Ogre::Vector3::ZERO, bool playIdleWhenAnimationEnds = true);
85 
getAnimationSpeedFactor()86     virtual double getAnimationSpeedFactor() const
87     { return 1.0; }
88 
89     //! \brief Updates the entity path, movement, and direction. Note that entities
90     //! are not expected to remove themselves or other entities from the gamemap
91     //! in the update function. If they do, it might lead to crashes as the gamemap
92     //! will iterate the movable entities vector
93     //! \param timeSinceLastFrame the elapsed time since last displayed frame in seconds.
94     virtual void update(Ogre::Real timeSinceLastFrame);
95 
96     void setWalkDirection(const Ogre::Vector3& direction);
97 
98     virtual void setPosition(const Ogre::Vector3& v) override;
99 
setAnimationState(Ogre::AnimationState * animationState)100     inline void setAnimationState(Ogre::AnimationState* animationState)
101     { mAnimationState = animationState; }
102 
getAnimationState()103     inline Ogre::AnimationState* getAnimationState() const
104     { return mAnimationState; }
105 
106     virtual void restoreEntityState() override;
107 
108     static std::string getMovableGameEntityStreamFormat();
109 
110 protected:
111     virtual void exportToStream(std::ostream& os) const override;
112     virtual bool importFromStream(std::istream& is) override;
113     virtual void exportToPacket(ODPacket& os, const Seat* seat) const override;
114     virtual void importFromPacket(ODPacket& is) override;
115 
116     std::deque<Ogre::Vector3> mWalkQueue;
117     std::string mPrevAnimationState;
118     bool mPrevAnimationStateLoop;
119 
120 private:
121     void fireObjectAnimationState(const std::string& state, bool loop, const Ogre::Vector3& direction, bool playIdleWhenAnimationEnds);
122     Ogre::AnimationState* mAnimationState;
123     std::string mDestinationAnimationState;
124     bool mDestinationAnimationLoop;
125     bool mDestinationPlayIdleWhenAnimationEnds;
126     Ogre::Vector3 mDestinationAnimationDirection;
127     Ogre::Vector3 mWalkDirection;
128     double mAnimationTime;
129 };
130 
131 
132 #endif // MOVABLEGAMEENTITY_H
133