Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

commented some stuff

File size: 11.6 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
38namespace orxonox
39{
40    /**
41    @brief
42        ActionpointController is a state machine with states:
43            1) NONE
44            2) FLY: fly towards a point
45            3) FIGHT: fight enemies that are in attackRange_ (see FightingController)
46            4) PROTECT: follow this->protect_
47            5) FIGHTALL: fight all enemies on the map
48            6) ATTACK: fight a specific spaceship
49        This controller always executes an action that is in the back of the vector being used.
50        After current this->action_ is completed, next action becomes the top action (one that will
51        be returned by someVector.back()), and current action either will be removed (if not looping),
52        or moved to the top (if looping).
53
54        Every second action(), which is once in two seconds, this searches the area for enemies that are in attack range, if finds anyone,
55        pushes Action::FIGHT to the stack. That makes spaceship fight enemies inside of a sphere, and when all enemies in range are dead,
56        Action::FIGHT is removed from the stack, and spaceship resumes doing whatever action was being executed before.
57
58        In XML one has to attack Actionpoints in order to achieve any complex behaviour, but in Controller all actionpoints are effectively
59        being stored in an array of type Point::Value.
60    */
61    namespace Action
62    { 
63        enum Value
64        {
65            NONE, FLY, FIGHT, PROTECT, FIGHTALL, ATTACK
66        };
67       
68    }
69   
70    struct Point {
71        Action::Value action;
72        std::string name;
73        Vector3 position;
74        bool inLoop;
75    } ;
76    namespace PickupType
77    {
78        enum Value
79        { 
80            NONE, DAMAGE, HEALTH, SPEED, PORTAL
81        };
82    }
83
84    class _OrxonoxExport ActionpointController : public FightingController, public Tickable
85    {
86        public:
87            ActionpointController(Context* context);
88            virtual ~ActionpointController();
89            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);         
90               
91            virtual void tick(float dt);
92            /**
93            @brief
94                XML method, example XML usage:
95                <SpaceShip position="-2000, 1500, -1000" lookat="0,0,0" team=0 name="ss2">
96                  <templates>
97                    <Template link=spaceshipassff />
98                  </templates>
99                  <controller>
100                    <DivisionController team=0 formationMode="finger4">
101                      <actionpoints>
102                        <Actionpoint position="0,0,0" action="FLY" />
103                        <Actionpoint position="-1000,750,-500" action="ATTACK" attack="attack" />
104                        <Actionpoint position="-1000,750,-500" action="PROTECt" protectMe=true />
105                        <Actionpoint position="-1000,750,-500" action="PROTECt" protect="protect" />
106                        <Actionpoint position="-1000,750,-500" action="FIGHTALL" />
107                       </actionpoints>
108                    </DivisionController>
109                  </controller>
110                </SpaceShip>
111               
112                Full description:
113                Adds an Actionpoint to this->actionpoints_. Actionpoint can take arguments like action="attack" attack="name".
114                For documentation on Actionpoint XML arguments, check out Actionpoint.h class
115                If any WorldEntity that is not Actionpoint or its child being sent to actionpoints through XML,
116                action would be assumed to be Action::FLY and target position to be position of the entity. Also, if not Actionpoint
117                is passed, it is assumed to be in a loop. How it works is: in <actionpoints> first all Actionpoints between
118                first Actionpoint with loopStart=true and first following Actionpoint with loopEnd=true are included in a single loop.
119                If they are adjacent (in the input array) with WorldEntity, then WorldEntity is also in a loop.
120                All the Worldentities are assumed to be in loop.
121               
122                Loop example:
123                <SpaceShip position="-1500, 1500, -1000" lookat="0,0,0" team=0 name="ss1">
124                  <templates>
125                    <Template link=spaceshipassff />
126                  </templates>
127                  <controller>
128                    <DivisionController team=0 formationMode="wall">
129                      <actionpoints>
130                        <Actionpoint position="  0,2000,-600" action="FLY" loopStart=true/>
131                        <Actionpoint position="  0,2000,-1000" action="FLY"  />
132                        <Actionpoint position="400,2000,-1000" action="FLY" />
133                        <Actionpoint position="400,2000,-600" action="FLY" loopEnd=true />
134                      </actionpoints>
135                    </DivisionController>
136                  </controller>
137                </SpaceShip>
138               
139                other loop example:
140                <SpaceShip position="-1500, -1500, -1500" lookat="0,0,0" team=0 name="ss1">
141                  <templates>
142                    <Template link=spaceshipassff />
143                  </templates>
144                  <controller>
145                    <DivisionController team=0 formationMode="diamond">
146                      <actionpoints>
147                        <Model mesh="cube.mesh" scale=8 position="  0,2000,-600" />
148                        <Model mesh="cube.mesh" scale=8 position="  0,2000,-1000" />
149                        <Model mesh="cube.mesh" scale=8 position="400,2000,-1000" />
150                        <Model mesh="cube.mesh" scale=8 position="400,2000,-600" />
151                      </actionpoints>
152                    </DivisionController>
153                  </controller>
154                </SpaceShip>
155
156            @note
157                Don't use several loops, and don't use WorldEntities as input to <actionpoints> as I didn't test it well, but you
158                can try if feeling lucky. 
159            */
160            void addActionpoint(WorldEntity* actionpoint); 
161            WorldEntity* getActionpoint(unsigned int index) const;           
162            virtual void stayNearProtect();
163            virtual void action(); //<! action() is called in regular intervals managing the bot's behaviour.
164            virtual void takeActionpoints (const std::vector<Point>& vector, const std::vector<Point>& loop, bool b);
165
166            virtual Action::Value getAction ();
167            virtual std::string getActionName();
168
169            void setAction (Action::Value action);
170            void setAction (Action::Value action, ControllableEntity* target);
171            void setAction (Action::Value action, const Vector3& target);
172            void setAction (Action::Value action, const Vector3& target,  const Quaternion& orient );
173
174            virtual bool setWingman(ActionpointController* wingman)
175                { return false; }
176            virtual bool hasWingman()
177                { return true; }
178            virtual bool setFollower(ActionpointController* myFollower)
179                { return false; }
180            virtual bool hasFollower()
181                { return true; }
182
183        protected:
184                void startAttackingEnemiesThatAreClose();
185                WeakPtr<ActionpointController> myWingman_;
186                WeakPtr<ActionpointController> myFollower_;
187                WeakPtr<ActionpointController> myDivisionLeader_;
188            //----[Actionpoint information]----
189                Action::Value action_;
190                std::string protectName_;
191                std::string targetName_;
192                std::vector<WeakPtr<WorldEntity> > actionpoints_;
193                float squaredaccuracy_;
194                std::vector<Point > parsedActionpoints_;//<! actionpoints as they are stored here after being parsed from XML
195                std::vector<Point > loopActionpoints_;  //<! actionpoints that are to be looped
196                bool bInLoop_;
197                bool bLoop_;                            //<! is state machine looping?
198                bool bEndLoop_;                   
199                bool bTakenOver_;                       //<! are actionpoints taken over from the leader when he died? if yes, top actionpoint
200                                                        //<! is to be executed for the state machine to start working
201            //----[/Actionpoint information]----
202                void setProtect (ControllableEntity* protect);
203                ControllableEntity* getProtect (); 
204                WeakPtr<ControllableEntity> protect_;   //<! entity that is to be protected if this->action_ == Action::PROTECT
205                void fillLoop();                        //<! moves actionpoints that are should be in loop from parsedActionpoints_ to loopActionpoints_
206                void fillLoopReversed();
207                void moveBackToTop();                   //<! analog of removing back actionpoint for loopActionpoints_: instead of removing it,
208                                                        //<! move it to the top, so that it will be executed later on.
209                void setClosestTarget();
210                Pawn* closestTarget();
211            //----[Actionpoint methods]----
212                /**
213                @brief
214                    Sets this->target_, this->targetPosition_, this->protect_ and this->action_ depending
215                    on the current actionpoint in the vector parsedActionpoints_ if not looping or
216                    loopActionpoints_ if looping.
217                @note
218                */
219                void executeActionpoint(); 
220                /**
221                @brief
222                    If this->bLoop_, move back action to top (back is the current one, top is the last),
223                    otherwise remove back actionpoint.
224                @note
225                    actionpoints_ is only used for XML, real state stacks are parsedActionpoints_ and loopActionpoints_
226                */           
227                void nextActionpoint();                 
228            //----[Actionpoint methods]----         
229                bool bFirstTick_; 
230
231                void setSpawners();
232                Vector3 bestHealthPickup (float searchRadius);
233                // Point closestPickup(PickupType::Value pickupType);
234                std::multimap <int, std::pair<PickupSpawner*, bool> > healthSpawners_; 
235                std::multimap <int, std::pair<PickupSpawner*, bool> > damageSpawners_; 
236                std::multimap <int, std::pair<PickupSpawner*, bool> > speedSpawners_; 
237
238        private:
239           
240    };
241}
242
243#endif /* _ActionpointController_H__ */
Note: See TracBrowser for help on using the repository browser.