1 /************************************************************************
2  *                                                                      *
3  *  FreeSynd - a remake of the classic Bullfrog game "Syndicate".       *
4  *                                                                      *
5  *   Copyright (C) 2005  Stuart Binge  <skbinge@gmail.com>              *
6  *   Copyright (C) 2005  Joost Peters  <joostp@users.sourceforge.net>   *
7  *   Copyright (C) 2006  Trent Waddington <qg@biodome.org>              *
8  *   Copyright (C) 2006  Tarjei Knapstad <tarjei.knapstad@gmail.com>    *
9  *   Copyright (C) 2010  Bohdan Stelmakh <chamel@users.sourceforge.net> *
10  *   Copyright (C) 2013  Benoit Blancard <benblan@users.sourceforge.net>*
11  *                                                                      *
12  *    This program is free software;  you can redistribute it and / or  *
13  *  modify it  under the  terms of the  GNU General  Public License as  *
14  *  published by the Free Software Foundation; either version 2 of the  *
15  *  License, or (at your option) any later version.                     *
16  *                                                                      *
17  *    This program is  distributed in the hope that it will be useful,  *
18  *  but WITHOUT  ANY WARRANTY;  without even  the implied  warranty of  *
19  *  MERCHANTABILITY  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  *
20  *  General Public License for more details.                            *
21  *                                                                      *
22  *    You can view the GNU  General Public License, online, at the GNU  *
23  *  project's  web  site;  see <http://www.gnu.org/licenses/gpl.html>.  *
24  *  The full text of the license is also included in the file COPYING.  *
25  *                                                                      *
26  ************************************************************************/
27 
28 #ifndef PED_H
29 #define PED_H
30 
31 #include <map>
32 #include <set>
33 
34 #include "common.h"
35 #include "mapobject.h"
36 #include "modowner.h"
37 #include "gfx/spritemanager.h"
38 #include "model/weaponholder.h"
39 #include "weapon.h"
40 #include "ipastim.h"
41 #include "ia/actions.h"
42 #include "ia/behaviour.h"
43 
44 class Agent;
45 class Mission;
46 class Squad;
47 class VehicleInstance;
48 class Vehicle;
49 
50 #define NUM_ANIMS 10
51 
52 /*!
53  * Pedestrian class.
54  */
55 class Ped {
56 public:
57     Ped();
~Ped()58     virtual ~Ped() {}
59 
setStandAnim(Weapon::WeaponAnimIndex weapon,int anim)60     void setStandAnim(Weapon::WeaponAnimIndex weapon, int anim) {
61         assert(weapon < NUM_ANIMS);
62         stand_anims_[weapon] = anim;
63     }
64 
setWalkAnim(Weapon::WeaponAnimIndex weapon,int anim)65     void setWalkAnim(Weapon::WeaponAnimIndex weapon, int anim) {
66         assert(weapon < NUM_ANIMS);
67         walk_anims_[weapon] = anim;
68     }
69 
setStandFireAnim(Weapon::WeaponAnimIndex weapon,int anim)70     void setStandFireAnim(Weapon::WeaponAnimIndex weapon, int anim) {
71         assert(weapon < NUM_ANIMS);
72         stand_fire_anims_[weapon] = anim;
73     }
74 
setWalkFireAnim(Weapon::WeaponAnimIndex weapon,int anim)75     void setWalkFireAnim(Weapon::WeaponAnimIndex weapon, int anim) {
76         assert(weapon < NUM_ANIMS);
77         walk_fire_anims_[weapon] = anim;
78     }
79 
setDieAgentAnim(int anim)80     void setDieAgentAnim(int anim) { die_agent_anim_ = anim; }
setDeadAgentAnim(int anim)81     void setDeadAgentAnim(int anim) { dead_agent_anim_ = anim; }
setDieAnim(int anim)82     void setDieAnim(int anim) { die_anim_ = anim; }
setDeadAnim(int anim)83     void setDeadAnim(int anim) { dead_anim_ = anim; }
setHitAnim(int anim)84     void setHitAnim(int anim) { hit_anim_ = anim; }
setPickupAnim(int anim)85     void setPickupAnim(int anim) { pickup_anim_ = anim; }
86 
setVaporizeAnim(int anim)87     void setVaporizeAnim(int anim) { vaporize_anim_ = anim; }
setSinkAnim(int anim)88     void setSinkAnim(int anim) { sink_anim_ = anim; }
setStandBurnAnim(int anim)89     void setStandBurnAnim(int anim) { stand_burn_anim_ = anim; }
setWalkBurnAnim(int anim)90     void setWalkBurnAnim(int anim) { walk_burn_anim_ = anim; }
setDieBurnAnim(int anim)91     void setDieBurnAnim(int anim) { die_burn_anim_ = anim; }
setSmokeBurnAnim(int anim)92     void setSmokeBurnAnim(int anim) { smoke_burn_anim_ = anim; }
setDeadBurnAnim(int anim)93     void setDeadBurnAnim(int anim) { dead_burn_anim_ = anim; }
94 
setPersuadeAnim(int anim)95     void setPersuadeAnim(int anim) { persuade_anim_ = anim; }
96 
97     bool drawStandFrame(int x, int y, int dir, int frame,
98             Weapon::WeaponAnimIndex weapon = Weapon::Unarmed_Anim);
99     int lastStandFrame(int dir, Weapon::WeaponAnimIndex weapon);
100     bool drawWalkFrame(int x, int y, int dir, int frame,
101             Weapon::WeaponAnimIndex weapon = Weapon::Unarmed_Anim);
102     int lastWalkFrame(int dir, Weapon::WeaponAnimIndex weapon);
103     bool drawStandFireFrame(int x, int y, int dir, int frame,
104             Weapon::WeaponAnimIndex weapon);
105     int lastStandFireFrame(int dir, Weapon::WeaponAnimIndex weapon);
106     bool drawWalkFireFrame(int x, int y, int dir, int frame,
107             Weapon::WeaponAnimIndex weapon);
108     int lastWalkFireFrame(int dir, Weapon::WeaponAnimIndex weapon);
109     bool drawDieFrame(int x, int y, int frame);
110     int lastDieFrame();
111 
112     void drawDeadFrame(int x, int y, int frame);
113     void drawDeadAgentFrame(int x, int y, int frame);
114 
115     void drawHitFrame(int x, int y, int dir, int frame);
116     int lastHitFrame(int dir);
117     void drawPickupFrame(int x, int y, int frame);
118     int lastPickupFrame();
119     void drawVaporizeFrame(int x, int y, int dir, int frame);
120     int lastVaporizeFrame(int dir);
121     void drawSinkFrame(int x, int y, int frame);
122     int lastSinkFrame();
123 
124     void drawStandBurnFrame(int x, int y, int frame);
125     void drawWalkBurnFrame(int x, int y, int frame);
126     void drawDieBurnFrame(int x, int y, int frame);
127     int lastDieBurnFrame();
128     void drawSmokeBurnFrame(int x, int y, int frame);
129     void drawDeadBurnFrame(int x, int y, int frame);
130 
131     void drawPersuadeFrame(int x, int y, int frame);
132     int lastPersuadeFrame();
133 
134 protected:
135     int stand_anims_[NUM_ANIMS];
136     int walk_anims_[NUM_ANIMS];
137     int stand_fire_anims_[NUM_ANIMS];
138     int walk_fire_anims_[NUM_ANIMS];
139     int die_agent_anim_;
140     int dead_agent_anim_;
141     int die_anim_;
142     int dead_anim_;
143     // has 4 directions
144     int hit_anim_;
145     int pickup_anim_;
146 
147     // has 4 directions
148     int vaporize_anim_;
149     int sink_anim_;
150     int stand_burn_anim_;
151     int walk_burn_anim_;
152     int die_burn_anim_;
153     int smoke_burn_anim_;
154     int dead_burn_anim_;
155 
156     int persuade_anim_;
157 };
158 
159 /*!
160  * Pedestrian instance class.
161  */
162 class PedInstance : public ShootableMovableMapObject, public WeaponHolder,
163     public ModOwner
164 {
165 public:
166     //! starting health for agents
167     static const int kAgentMaxHealth;
168     //! Default time for a ped between two shoots
169     static const int kDefaultShootReactionTime;
170     //! Id of the group for the player's agents
171     static const uint32 kPlayerGroupId;
172     /*!
173      * Type of Ped.
174      */
175     enum PedType {
176         kPedTypeCivilian = 0x01,
177         kPedTypeAgent = 0x02,
178         kPedTypePolice = 0x04,
179         kPedTypeGuard = 0x08,
180         kPedTypeCriminal = 0x10
181     } ;
182 
183     enum pedDescStateMasks {
184         pd_smUndefined = 0x0,
185         pd_smControlled = 0x0001,
186         pd_smArmed = 0x0002,
187         // no active action should be done, ex. persuaded ped will shoot target
188         // of persuader only if persuader shoots at it
189         pd_smSupporter = 0x0004,
190         pd_smEnemyInSight = 0x0008,
191         // only if all weapon has no ammunition, persuadatron excludes this
192         // should not be used for hostile_desc_
193         pd_smNoAmmunition = 0x0010,
194         // all non-player controllled peds should have this set
195         pd_smAutoAction = 0x0020,
196         /*! When a mission's objective is to kill a ped and this ped has
197         escaped, this value is used to indicate he's escaped.*/
198         pd_smEscaped = 0x0080,
199         pd_smAll = 0xFFFF
200     };
201 
202     PedInstance(Ped *ped, uint16 id, int m, bool isOur);
203     ~PedInstance();
204 
205     //*************************************
206     // Properties
207     //*************************************
208     //! Returns true if the agent is one of us.
isOurAgent()209     bool isOurAgent() { return is_our_; }
210     //! Return the type of Ped
type()211     PedType type() { return type_; }
212     void setTypeFromValue(uint8 value);
213     //! Returns the ped's behaviour
behaviour()214     Behaviour & behaviour() { return behaviour_; }
215     //! Return true if ped has escaped the map
hasEscaped()216     bool hasEscaped() { return IS_FLAG_SET(desc_state_, pd_smEscaped); }
217     //! Indicate that the ped has escaped
escape()218     void escape() { SET_FLAG(desc_state_, pd_smEscaped); }
219     //! Return true if ped don't panic
isPanicImmuned()220     bool isPanicImmuned() { return panicImmuned_; }
221     //! Tells the ped not to panic
setPanicImmuned()222     void setPanicImmuned() { panicImmuned_ = true; }
223 
224     typedef enum {
225         ad_NoAnimation,
226         ad_HitAnim,
227         ad_DieAnim,
228         ad_DeadAnim,
229         ad_DeadAgentAnim,
230         ad_PickupAnim,
231         ad_PutdownAnim,
232         ad_WalkAnim,
233         ad_StandAnim,
234         ad_WalkFireAnim,
235         ad_StandFireAnim,
236         ad_VaporizeAnim,
237         ad_SinkAnim,
238         ad_StandBurnAnim,
239         ad_WalkBurnAnim,
240         ad_DieBurnAnim,
241         ad_SmokeBurnAnim,
242         ad_DeadBurnAnim,
243         ad_PersuadedAnim
244     } AnimationDrawn;
245 
246     //! MapObject::state_
247     enum pedActionStateMasks {
248         pa_smNone = 0x0,
249         pa_smStanding = 0x0001,
250         pa_smWalking = 0x0002,
251         pa_smHit = 0x0004,
252         pa_smFiring = 0x0008,
253         pa_smFollowing = 0x0010,
254         pa_smPickUp = 0x0020,
255         pa_smPutDown = 0x0040,
256         pa_smBurning = 0x0080,
257         pa_smGetInCar = 0x0100,
258         // only driver can have this set after finished
259         pa_smUsingCar = 0x0200,
260         // passenger only
261         pa_smInCar = 0x0400,
262         pa_smHitByPersuadotron = 0x0800,
263         pa_smDead = 0x1000,
264         // this object should be ignored in all Ai procedures
265         pa_smUnavailable = 0x2000,
266         //! When a ped is hit by a laser
267         pa_smHitByLaser = 0x4000,
268         //! When a ped is walking and burning
269         pa_smWalkingBurning = 0x8000,
270         pa_smCheckExcluded = pa_smDead | pa_smUnavailable,
271         pa_smAll = 0xFFFF
272     };
273 
274     void draw(int x, int y);
275 
setFrame(int f)276     void setFrame(int f) { frame_ = f; }
277 
setSightRange(int new_sight_range)278     void setSightRange(int new_sight_range) { sight_range_ = new_sight_range; }
sightRange()279     int sightRange() { return sight_range_; }
280 
281     void showPath(int scrollX, int scrollY);
282 
283     bool switchActionStateTo(uint32 as);
284     bool switchActionStateFrom(uint32 as);
285     void synchDrawnAnimWithActionState(void);
286     bool animate(int elapsed, Mission *mission);
287 
288     void drawSelectorAnim(int x, int y);
289     //! Update frame to render
290     bool updateAnimation(int elapsed);
291     //! Set state for ped (replace switchActionStateTo)
292     void goToState(uint32 as);
293     //! Quit state for ped (replace switchActionStateFrom)
294     void leaveState(uint32 as);
295 
296     //*************************************
297     // Action management
298     //*************************************
299     //! Adds the given action to the list of actions
300     void addMovementAction(MovementAction *pAction, bool appendAction);
301     //! Adds the given action to the list of default scripted actions
302     void addToDefaultActions(MovementAction *pToAdd);
303     //! Adds the given action to the list of alternative scripted actions
304     void addToAltActions(MovementAction *pToAdd);
305     //! Returns the ped's current movement action
currentAction()306     MovementAction * currentAction() { return currentAction_; }
307     //! Returns the ped's first default action (can be null)
defaultAction()308     MovementAction * defaultAction() { return defaultAction_; }
309     //! Returns true if ped's current action is from given source
isCurrentActionFromSource(Action::ActionSource source)310     bool isCurrentActionFromSource(Action::ActionSource source) {
311         return currentAction_ != NULL &&
312                 currentAction_->source() == source;
313     }
314     //! Returns the ped's first alternative action (can be null)
altAction()315     MovementAction * altAction() { return altAction_; }
316     //! Removes all ped's actions : current + scripted
317     void destroyAllActions(bool includeScripted = true);
318     //! Removes ped's action of using weapon
319     void destroyUseWeaponAction();
320     //! Execute the current action if any
321     bool executeAction(int elapsed, Mission *pMission);
322     //! Execute a weapon action if any
323     bool executeUseWeaponAction(int elapsed, Mission *pMission);
324     //! Restart the actions of given source and set as current action
325     void resetActions(Action::ActionSource source);
326     //! Switch to the given source of action
327     void changeSourceOfActions(Action::ActionSource source);
328 
329     //! Adds action to walk to a given destination
330     void addActionWalk(const TilePoint &destPosT, bool appendAction);
331 
332     //! Adds action to follow a ped
333     void addActionFollowPed(PedInstance *pPed);
334     //! Adds action to put down weapon on the ground
335     void addActionPutdown(uint8 weaponIndex, bool appendAction);
336     //! Adds action to pick up weapon from the ground
337     MovementAction * createActionPickup(WeaponInstance *pWeapon);
338     //! Creates actions to walk and enter a given vehicle
339     MovementAction * createActionEnterVehicle(Vehicle *pVehicle);
340     //! Adds action to drive vehicle to destination
341     void addActionDriveVehicle(
342            VehicleInstance *pVehicle, const TilePoint &destination, bool appendAction);
343     //! Return true if ped can use a weapon
344     bool canAddUseWeaponAction(WeaponInstance *pWeapon = NULL);
345     //! Adds action to shoot somewhere
346     uint8 addActionShootAt(const WorldPoint &aimedPt);
347     //! Adds action to use medikit
348     void addActionUseMedikit();
349     //! Creates and insert a HitAction for the ped
350     void insertHitAction(DamageInflictType &d);
351 
352     //*************************************
353     // Movement management
354     //*************************************
355     //! Set the destination to reach at given speed (todo : replace setDestinationP())
356     bool setDestination(Mission *m, const TilePoint &locT, int newSpeed = -1);
357 
358     void setDestinationP(Mission *m, int x, int y, int z,
359         int ox = 128, int oy = 128);
360 
361     bool movementP(Mission *m, int elapsed);
362 
363     //*************************************
364     // Weapon management
365     //*************************************
366     WeaponInstance * dropWeapon(uint8 index);
367     void dropAllWeapons();
368     void destroyAllWeapons();
369     bool wePickupWeapon();
370 
371     //*************************************
372     // Shoot & Damage management
373     //*************************************
374     //! Return true if ped is currently using a weapon (ie there's an active action)
isUsingWeapon()375     bool isUsingWeapon() { return pUseWeaponAction_ != NULL; }
376     //! Make the ped stop using weapon (mainly for automatic weapon)
377     void stopUsingWeapon();
378     //! Update the ped's shooting target
379     void updateShootingTarget(const WorldPoint &aimedPt);
380     //! Adjust aimed point with user accuracy and weapon max range
381     void adjustAimedPtWithRangeAndAccuracy(Weapon *pWeaponClass, WorldPoint *pAimedLocW);
382     //! Gets the time before a ped can shoot again
383     int getTimeBetweenShoots(WeaponInstance *pWeapon);
384 
385     //! Forces agent to kill himself
386     void commitSuicide();
387 
388     //! Return the damage after applying protection of Mod
389     int getRealDamage(ShootableMapObject::DamageInflictType &d);
390     //! Method called when object is hit by a weapon shot.
391     void handleHit(ShootableMapObject::DamageInflictType &d);
392     //! Method called to check if ped has died
393     bool handleDeath(Mission *pMission, ShootableMapObject::DamageInflictType &d);
394 
395     //*************************************
396     // Persuasion
397     //*************************************
398     //! Return true if ped is persuaded
isPersuaded()399     bool isPersuaded() { return IS_FLAG_SET(desc_state_, pd_smControlled); }
400     //! Returns true if this ped can persuade that ped
401     bool canPersuade(PedInstance *pOtherPed);
402     //! Return owner of persuaded
owner()403     PedInstance * owner() { return owner_; }
404     //! Adds given ped to the list of persuaded peds by this agent
405     void addPersuaded(PedInstance *p);
406     //! Removes given ped to the list of persuaded peds by this agent
407     void rmvPersuaded(PedInstance *p);
408     //! Method called when an agent persuads this ped
409     void handlePersuadedBy(PedInstance *pAgent);
410     //! Change the owner of the ped
411     void setNewOwner(PedInstance *pPed);
412 
413     bool inSightRange(MapObject *t);
414     VehicleInstance * inVehicle() const;
415 
416     void putInVehicle(VehicleInstance *v, pedActionStateMasks add_state);
417     void leaveVehicle();
418 
419     int map();
420     AnimationDrawn drawnAnim(void);
421     void setDrawnAnim(AnimationDrawn drawn_anim);
422     bool handleDrawnAnim(int elapsed);
423 
424     uint8 moveToDir(Mission *m, int elapsed, DirMoveType &dir_move,
425         int dir = -1, int t_posx = -1, int t_posy = -1, int *dist = NULL,
426         bool set_dist = false);
427 
setAllAdrenaLevels(uint8 amount,uint8 depend,uint8 effect)428     void setAllAdrenaLevels(uint8 amount, uint8 depend, uint8 effect) {
429         adrenaline_->setLevels256(amount, depend, effect);
430     }
431 
setAllInteliLevels(uint8 amount,uint8 depend,uint8 effect)432     void setAllInteliLevels(uint8 amount, uint8 depend, uint8 effect) {
433         intelligence_->setLevels256(amount, depend, effect);
434     }
435 
setAllPercepLevels(uint8 amount,uint8 depend,uint8 effect)436     void setAllPercepLevels(uint8 amount, uint8 depend, uint8 effect) {
437         perception_->setLevels256(amount, depend, effect);
438     }
updtIPATime(int elapsed)439     void updtIPATime(int elapsed) {
440         adrenaline_->processTicks(elapsed);
441         perception_->processTicks(elapsed);
442         intelligence_->processTicks(elapsed);
443     }
444 
setDescStateMasks(unsigned int desc_state)445     void setDescStateMasks(unsigned int desc_state) {
446         desc_state_ = desc_state;
447     }
descStateMasks()448     unsigned int descStateMasks() { return desc_state_; }
449 
setHostileDesc(unsigned int hostile_desc)450     void setHostileDesc(unsigned int hostile_desc) {
451         hostile_desc_ = hostile_desc;
452     }
hostileDesc()453     unsigned int hostileDesc() { return hostile_desc_; }
454 
setObjGroupDef(unsigned int obj_group_def)455     void setObjGroupDef(unsigned int obj_group_def) {
456         obj_group_def_ = obj_group_def;
457     }
objGroupDef()458     unsigned int objGroupDef() { return obj_group_def_; }
459 
setObjGroupID(unsigned int obj_group_id)460     void setObjGroupID(unsigned int obj_group_id) {
461         obj_group_id_ = obj_group_id;
462     }
objGroupID()463     unsigned int objGroupID() { return obj_group_id_; }
464 
setTimeBeforeCheck(int32 tm)465     void setTimeBeforeCheck(int32 tm) { tm_before_check_ = tm; }
setBaseModAcc(double mod_acc)466     void setBaseModAcc(double mod_acc) { base_mod_acc_ = mod_acc; }
467 
468     class Mmuu32_t: public std::multimap<uint32, uint32> {
469     public:
Mmuu32_t()470         Mmuu32_t() {}
~Mmuu32_t()471         ~Mmuu32_t() {}
472         void rm(uint32 first, uint32 second = 0) {
473             Mmuu32_t::iterator it = this->find(first);
474             if (it == this->end())
475                 return;
476             if (second == 0) {
477                 // removing all of this id
478                 Mmuu32_t::iterator its = it;
479                 do {
480                     ++it;
481                 } while (it->first == first && it != this->end());
482                 this->erase(its, it);
483             } else {
484                 do {
485                     if (it->second == second) {
486                         this->erase(it);
487                         break;
488                     }
489                     ++it;
490                 } while (it->first == first && it != this->end());
491             }
492         }
493         void add(uint32 first, uint32 second = 0) {
494             Mmuu32_t::iterator it = this->find(first);
495             if (it != this->end()) {
496                 if (second == 0) {
497                     if (it->second != 0) {
498                         // non-zeros should be removed, second value equal zero
499                         // should be the only present
500                         this->rm(first);
501                         this->insert(std::pair<uint32, uint32>(first, second));
502                     }
503                 } else {
504                     bool found = false;
505                     do {
506                         if (it->first != first)
507                             break;
508                         if (it->second == second) {
509                             found = true;
510                             break;
511                         }
512                         ++it;
513                     } while (it != this->end());
514                     if (!found)
515                         this->insert(std::pair<uint32, uint32>(first, second));
516                 }
517             } else
518                 this->insert(std::pair<uint32, uint32>(first, second));
519         }
520         bool isIn(uint32 first, uint32 second = 0) {
521             Mmuu32_t::iterator it = this->find(first);
522             bool found = false;
523             if (it != this->end()) {
524                 if (second == 0 || it->second == 0)
525                     found = true;
526                 else {
527                     do {
528                         if (it->second == second) {
529                             found = true;
530                             break;
531                         }
532                         ++it;
533                     } while (it != this->end() && it->first == first);
534                 }
535             }
536             return found;
537         }
isIn_KeyOnly(Mmuu32_t & mm)538         bool isIn_KeyOnly(Mmuu32_t &mm) {
539             if (mm.empty() || this->empty())
540                 return false;
541             bool found = false;
542             Mmuu32_t::iterator it_this = this->begin();
543             uint32 first_value = it_this->first;
544             do {
545                 Mmuu32_t::iterator it_mm = mm.find(first_value);
546                 found = it_mm != mm.end();
547                 if (found)
548                     break;
549                 if (it_this->first != first_value)
550                     first_value = it_this->first;
551                 else {
552                     ++it_this;
553                     continue;
554                 }
555             } while (it_this != this->end());
556             return found;
557         }
isIn_All(Mmuu32_t & mm)558         bool isIn_All(Mmuu32_t &mm) {
559             if (mm.empty() || this->empty())
560                 return false;
561             bool found = false;
562             Mmuu32_t::iterator it_this = this->begin();
563             uint32 first_value = it_this->first;
564             uint32 second_value = it_this->second;
565             do {
566                 Mmuu32_t::iterator it_mm = mm.find(first_value);
567                 found = it_mm != mm.end();
568                 if (found) {
569                     if (second_value == 0 || it_mm->second == 0)
570                         break;
571                     std::pair<Mmuu32_t::iterator, Mmuu32_t::iterator> rng =
572                         mm.equal_range(first_value);
573                     found = false;
574                     for (Mmuu32_t::iterator it = rng.first;
575                         it != rng.second; ++it)
576                     {
577                         if (it->second == second_value) {
578                             found = true;
579                             break;
580                         }
581                     }
582                 }
583                 if (!found) {
584                     if (it_this->first != first_value) {
585                         first_value = it_this->first;
586                         second_value = it_this->second;
587                     } else {
588                         if (it_this->second != second_value)
589                             second_value = it_this->second;
590                         ++it_this;
591                         continue;
592                     }
593                 }
594             } while (it_this != this->end());
595             return found;
596         }
597     };
598 
599     void addEnemyGroupDef(uint32 eg_id, uint32 eg_def = 0);
600     void rmEnemyGroupDef(uint32 eg_id, uint32 eg_def = 0);
601     bool isInEnemyGroupDef(uint32 eg_id, uint32 eg_def = 0);
602 
603     void addEmulatedGroupDef(uint32 eg_id, uint32 eg_def = 0);
604     void rmEmulatedGroupDef(uint32 eg_id, uint32 eg_def = 0);
605     bool isInEmulatedGroupDef(uint32 eg_id, uint32 eg_def = 0);
606     bool isInEmulatedGroupDef(Mmuu32_t &r_egd,
607         bool id_only = true);
emulatedGroupDefsEmpty()608     bool emulatedGroupDefsEmpty() { return emulated_group_defs_.size() == 0; }
609 
610     typedef std::pair<ShootableMapObject *, double> Pairsmod_t;
611     typedef std::map <ShootableMapObject *, double> Msmod_t;
isInHostilesFound(ShootableMapObject * hostile_found)612     bool isInHostilesFound(ShootableMapObject * hostile_found) {
613         return hostiles_found_.find(hostile_found)
614             != hostiles_found_.end();
615     }
616     void verifyHostilesFound(Mission *m);
getHostilesFoundIt(Msmod_t::iterator & it_s,Msmod_t::iterator & it_e)617     bool getHostilesFoundIt(Msmod_t::iterator &it_s, Msmod_t::iterator &it_e)
618     {
619         if (hostiles_found_.empty())
620             return false;
621         it_s = hostiles_found_.begin();
622         it_e = hostiles_found_.end();
623         return true;
624     }
625     //! Verify hostility between this Ped and the object
626     bool isHostileTo(ShootableMapObject *obj,
627         unsigned int hostile_desc_alt = 0);
628     //! Verify if this ped is friend with the given ped
629     bool isFriendWith(PedInstance *p);
630 
631     typedef enum {
632         og_dmUndefined = 0x0,
633         og_dmPedestrian = 0x01,
634         og_dmCivilian = 0x01,
635         og_dmAgent = 0x02,
636         og_dmPolice = 0x04,
637         og_dmGuard = 0x08,
638         og_dmCriminal = 0x10
639     } objGroupDefMasks;
640 
641     //! Returns ped's speed under normal conditions
642     int getDefaultSpeed();
643     int getSpeedOwnerBoost();
644 
645     void getAccuracy(double &base_acc);
646     bool hasAccessCard();
647 
cpyEnemyDefs(Mmuu32_t & eg_defs)648     void cpyEnemyDefs(Mmuu32_t &eg_defs) { eg_defs = enemy_group_defs_; }
isArmed()649     bool isArmed() { return (desc_state_ & pd_smArmed) != 0; }
650 
651     IPAStim *adrenaline_;
652     IPAStim *perception_;
653     IPAStim *intelligence_;
654 protected:
655     /*!
656      * Called before a weapon is selected to check if weapon can be selected.
657      * \param wi The weapon to select
658      */
659     bool canSelectWeapon(WeaponInstance *pNewWeapon);
660     /*!
661      * Called when a weapon has been deselected.
662      * \param wi The deselected weapon
663      */
664     void handleWeaponDeselected(WeaponInstance * wi);
665     //! See WeaponHolder::handleWeaponSelected()
666     void handleWeaponSelected(WeaponInstance * wi, WeaponInstance * previousWeapon);
667 
668     //! Returns the number of points an agent must have to persuade a ped of given type
669     uint16 getRequiredPointsToPersuade(PedType type);
670     //! When a ped dies, changes the persuaded owner/persuaded_group relation.
671     void updatePersuadedRelations(Squad *pSquad);
672 protected:
673     //! Distance to persuade a ped
674     static const int kMaxDistanceForPersuadotron;
675 
676     Ped *ped_;
677     //! Type of Ped
678     PedType type_;
679 
680     /*! Ped's behaviour.*/
681     Behaviour behaviour_;
682     /*! Current action*/
683     MovementAction *currentAction_;
684     /*!
685      * Default and Alternative actions define the behaviour of non player controlled peds.
686      * Default actions come from a mission file and alternative actions are used by ped
687      * to react in certain situations (like fight).
688      * Those actions are not deleted when finished.
689      */
690     MovementAction *defaultAction_;
691     MovementAction *altAction_;
692     /*! Current action of using a weapon.*/
693     UseWeaponAction *pUseWeaponAction_;
694 
695     // (pedDescStateMasks)
696     uint32 desc_state_;
697     // this inherits definition from desc_state_
698     // ((target checked)desc_state_ & hostile_desc_) != 0 kill him
699     uint32 hostile_desc_;
700     Mmuu32_t enemy_group_defs_;
701     // if object is not hostile here, enemy_group_defs_ check
702     // is skipped, but not hostiles_found_ or desc_state_
703     Mmuu32_t emulated_group_defs_;
704     // not set anywhere but used
705     Mmuu32_t friend_group_defs_;
706     //! dicovered hostiles are set here, only within sight range
707     Msmod_t hostiles_found_;
708     //! used by police officers, for now friends forever mode
709     std::set <ShootableMapObject *> friends_found_;
710     //! from this list they will move to friends_found_ if in sight
711     std::set <ShootableMapObject *> friends_not_seen_;
712     //! defines group obj belongs to (objGroupDefMasks), not unique
713     uint32 obj_group_def_;
714     uint32 old_obj_group_def_;
715 
716     //! a unique group identification number, 0 - all group IDs
717     uint32 obj_group_id_;
718     uint32 old_obj_group_id_;
719 
720     //! time wait before checking enviroment (enemies, friends etc)
721     int32 tm_before_check_;
722 
723     //! base value that influences accuracy during fire
724     double base_mod_acc_;
725 
726     AnimationDrawn drawn_anim_;
727 
728     int sight_range_;
729     VehicleInstance *in_vehicle_;
730     //! This flag tells if this is our agent, assuming it's an agent.
731     bool is_our_;
732     //! controller of ped - for persuaded
733     PedInstance *owner_;
734     //! Points obtained by agents for persuading peds
735     uint16 totalPersuasionPoints_;
736     //! The group of peds that this ped has persuaded
737     std::set <PedInstance *> persuadedSet_;
738     //! Tells whether the panic can react to panic or not
739     bool panicImmuned_;
740 
walkable(int x,int y,int z)741     bool walkable(int x, int y, int z) { return true; }
742 
743 private:
744     inline int getClosestDirs(int dir, int& closest, int& closer);
745 };
746 
747 #endif
748