Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/campaignHS15/src/orxonox/controllers/ActionpointController.h @ 10915

Last change on this file since 10915 was 10915, checked in by gania, 9 years ago

little fix

File size: 12.5 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Gani Aliguzhinov
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#ifndef _ActionpointController_H__
30#define _ActionpointController_H__
31
32#include "controllers/FightingController.h"
33#include "tools/Timer.h"
34#include "tools/interfaces/Tickable.h"
35#include "../modules/pickup/PickupSpawner.h"
36#include <map>
37
38
39
40namespace orxonox
41{
42    /**
43    @brief
44        ActionpointController is a state machine with states:
45            1) NONE
46            2) FLY: fly towards a point
47            3) FIGHT: fight enemies that are in attackRange_ (see FightingController)
48            4) PROTECT: follow this->protect_
49            5) FIGHTALL: fight all enemies on the map
50            6) ATTACK: fight a specific spaceship
51        This controller always executes an action that is in the back of the vector being used.
52        After current this->action_ is completed, next action becomes the top action (one that will
53        be returned by someVector.back()), and current action either will be removed (if not looping),
54        or moved to the top (if looping).
55
56        Every second action(), which is once in two seconds, this searches the area for enemies that are in attack range, if finds anyone,
57        pushes Action::FIGHT to the stack. That makes spaceship fight enemies inside of a sphere, and when all enemies in range are dead,
58        Action::FIGHT is removed from the stack, and spaceship resumes doing whatever action was being executed before.
59
60        In XML one has to attack Actionpoints in order to achieve any complex behaviour, but in Controller all actionpoints are effectively
61        being stored in an array of type Point::Value.
62    */
63    namespace Action
64    { 
65        enum Value
66        {
67            NONE, FLY, FIGHT, PROTECT, FIGHTALL, ATTACK
68        };
69       
70    }
71   
72    struct Point {
73        Action::Value action;
74        std::string name;
75        Vector3 position;
76        bool inLoop;
77    } ;
78    namespace PickupType
79    {
80        enum Value
81        { 
82            NONE, DAMAGE, HEALTH, SPEED, PORTAL
83        };
84    }
85
86    class _OrxonoxExport ActionpointController : public FightingController, public Tickable
87    {
88        public:
89           
90            ActionpointController(Context* context);
91            virtual ~ActionpointController();
92            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);         
93               
94            virtual void tick(float dt);
95            /**
96            @brief
97                XML method, example XML usage:
98                <SpaceShip position="-2000, 1500, -1000" lookat="0,0,0" team=0 name="ss2">
99                  <templates>
100                    <Template link=spaceshipassff />
101                  </templates>
102                  <controller>
103                    <DivisionController team=0 formationMode="finger4">
104                      <actionpoints>
105                        <Actionpoint position="0,0,0" action="FLY" />
106                        <Actionpoint position="-1000,750,-500" action="ATTACK" attack="attack" />
107                        <Actionpoint position="-1000,750,-500" action="PROTECt" protectMe=true />
108                        <Actionpoint position="-1000,750,-500" action="PROTECt" protect="protect" />
109                        <Actionpoint position="-1000,750,-500" action="FIGHTALL" />
110                       </actionpoints>
111                    </DivisionController>
112                  </controller>
113                </SpaceShip>
114               
115                Full description:
116                Adds an Actionpoint to this->actionpoints_. Actionpoint can take arguments like action="attack" attack="name".
117                For documentation on Actionpoint XML arguments, check out Actionpoint.h class
118                If any WorldEntity that is not Actionpoint or its child being sent to actionpoints through XML,
119                action would be assumed to be Action::FLY and target position to be position of the entity. Also, if not Actionpoint
120                is passed, it is assumed to be in a loop. How it works is: in <actionpoints> first all Actionpoints between
121                first Actionpoint with loopStart=true and first following Actionpoint with loopEnd=true are included in a single loop.
122                If they are adjacent (in the input array) with WorldEntity, then WorldEntity is also in a loop.
123                All the Worldentities are assumed to be in loop.
124               
125                Loop example:
126                <SpaceShip position="-1500, 1500, -1000" lookat="0,0,0" team=0 name="ss1">
127                  <templates>
128                    <Template link=spaceshipassff />
129                  </templates>
130                  <controller>
131                    <DivisionController team=0 formationMode="wall">
132                      <actionpoints>
133                        <Actionpoint position="  0,2000,-600" action="FLY" loopStart=true/>
134                        <Actionpoint position="  0,2000,-1000" action="FLY"  />
135                        <Actionpoint position="400,2000,-1000" action="FLY" />
136                        <Actionpoint position="400,2000,-600" action="FLY" loopEnd=true />
137                      </actionpoints>
138                    </DivisionController>
139                  </controller>
140                </SpaceShip>
141               
142                other loop example:
143                <SpaceShip position="-1500, -1500, -1500" lookat="0,0,0" team=0 name="ss1">
144                  <templates>
145                    <Template link=spaceshipassff />
146                  </templates>
147                  <controller>
148                    <DivisionController team=0 formationMode="diamond">
149                      <actionpoints>
150                        <Model mesh="cube.mesh" scale=8 position="  0,2000,-600" />
151                        <Model mesh="cube.mesh" scale=8 position="  0,2000,-1000" />
152                        <Model mesh="cube.mesh" scale=8 position="400,2000,-1000" />
153                        <Model mesh="cube.mesh" scale=8 position="400,2000,-600" />
154                      </actionpoints>
155                    </DivisionController>
156                  </controller>
157                </SpaceShip>
158
159            @note
160                Don't use several loops, and don't use WorldEntities as input to <actionpoints> as I didn't test it well, but you
161                can try if feeling lucky. 
162            */
163            void addActionpoint(WorldEntity* actionpoint); 
164            WorldEntity* getActionpoint(unsigned int index) const;   
165            void setDefaultFightAll(bool value)
166                { this->bDefaultFightAll_ = value; }
167            bool getDefaultFightAll ()
168                { return this->bDefaultFightAll_; }
169            void setDefaultPatrol(bool value)
170                { this->bDefaultPatrol_ = value; }
171            bool getDefaultPatrol ()
172                { return this->bDefaultPatrol_; }
173                 // Trigger interface
174            // bool stop(bool bTriggered, BaseObject* trigger);
175            // bool go(bool bTriggered, BaseObject* trigger);
176            // virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
177
178            virtual void stayNearProtect();
179            virtual void action(); //<! action() is called in regular intervals managing the bot's behaviour.
180            virtual void takeActionpoints (const std::vector<Point>& vector, const std::vector<Point>& loop, bool b);
181
182            virtual Action::Value getAction ();
183            virtual std::string getActionName();
184
185            void setAction (Action::Value action);
186            void setAction (Action::Value action, ControllableEntity* target);
187            void setAction (Action::Value action, const Vector3& target);
188            void setAction (Action::Value action, const Vector3& target,  const Quaternion& orient );
189
190            virtual bool setWingman(ActionpointController* wingman)
191                { return false; }
192            virtual bool hasWingman()
193                { return true; }
194            virtual bool setFollower(ActionpointController* myFollower)
195                { return false; }
196            virtual bool hasFollower()
197                { return true; }
198
199
200        protected:
201                void startAttackingEnemiesThatAreClose();
202                WeakPtr<ActionpointController> myWingman_;
203                WeakPtr<ActionpointController> myFollower_;
204                WeakPtr<ActionpointController> myDivisionLeader_;
205            //----[Actionpoint information]----
206                Action::Value action_;
207                std::string protectName_;
208                std::string targetName_;
209                std::vector<WeakPtr<WorldEntity> > actionpoints_;
210                float squaredaccuracy_;
211                std::vector<Point > parsedActionpoints_;//<! actionpoints as they are stored here after being parsed from XML
212                std::vector<Point > loopActionpoints_;  //<! actionpoints that are to be looped
213                bool bInLoop_;
214                bool bLoop_;                            //<! is state machine looping?
215                bool bEndLoop_;                   
216                bool bTakenOver_;                       //<! are actionpoints taken over from the leader when he died? if yes, top actionpoint
217                                                        //<! is to be executed for the state machine to start working
218            //----[/Actionpoint information]----
219                void setProtect (ControllableEntity* protect);
220                ControllableEntity* getProtect (); 
221                WeakPtr<ControllableEntity> protect_;   //<! entity that is to be protected if this->action_ == Action::PROTECT
222                void fillLoop();                        //<! moves actionpoints that are should be in loop from parsedActionpoints_ to loopActionpoints_
223                void fillLoopReversed();
224                void moveBackToTop();                   //<! analog of removing back actionpoint for loopActionpoints_: instead of removing it,
225                                                        //<! move it to the top, so that it will be executed later on.
226                void setClosestTarget();
227                Pawn* closestTarget();
228            //----[Actionpoint methods]----
229                /**
230                @brief
231                    Sets this->target_, this->targetPosition_, this->protect_ and this->action_ depending
232                    on the current actionpoint in the vector parsedActionpoints_ if not looping or
233                    loopActionpoints_ if looping.
234                @note
235                */
236                void executeActionpoint(); 
237                /**
238                @brief
239                    If this->bLoop_, move back action to top (back is the current one, top is the last),
240                    otherwise remove back actionpoint.
241                @note
242                    actionpoints_ is only used for XML, real state stacks are parsedActionpoints_ and loopActionpoints_
243                */           
244                void nextActionpoint();                 
245            //----[Actionpoint methods]----         
246                bool bFirstTick_; 
247
248                void setSpawners();
249                Vector3 bestHealthPickup (float searchRadius);
250                // Point closestPickup(PickupType::Value pickupType);
251                std::multimap <int, std::pair<PickupSpawner*, bool> > healthSpawners_; 
252                std::multimap <int, std::pair<PickupSpawner*, bool> > damageSpawners_; 
253                std::multimap <int, std::pair<PickupSpawner*, bool> > speedSpawners_; 
254
255                float timeOffset_;
256                bool bActionCalled_;
257                bool bManeuverCalled_;
258                bool bDefaultFightAll_;
259
260                bool bActive_;
261                bool bPatrolling_;
262                bool bDefaultPatrol_;
263                bool stop_;
264
265        private:
266           
267    };
268}
269
270#endif /* _ActionpointController_H__ */
Note: See TracBrowser for help on using the repository browser.