- Rework Behaviour and added BehaviourComponent
authorbenblan <benblan@3ce38193-f967-438d-acd5-fc4e68e0da95>
Mon, 28 Jul 2014 08:29:12 +0000 (08:29 +0000)
committerbenblan <benblan@3ce38193-f967-438d-acd5-fc4e68e0da95>
Mon, 28 Jul 2014 08:29:12 +0000 (08:29 +0000)
- Code refactoring around ped initialization

freesynd/branches/rework-actions/src/ia/behaviour.cpp
freesynd/branches/rework-actions/src/ia/behaviour.h
freesynd/branches/rework-actions/src/missionmanager.cpp
freesynd/branches/rework-actions/src/ped.cpp
freesynd/branches/rework-actions/src/ped.h
freesynd/branches/rework-actions/src/pedmanager.cpp
freesynd/branches/rework-actions/src/pedmanager.h

index 1f98b26e91706ca9050f52a3b8907010d35dbbac..50d5936ae51c20625d43635f2e0cf5323091e617 100644 (file)
 #include "ped.h"
 #include "mission.h"
 
-const int AgentBehaviour::kMaxDistanceForPersuadotron = 50;
-const int AgentBehaviour::kRegeratesHealthStep = 1;
+const int PersuaderBehaviourComponent::kMaxDistanceForPersuadotron = 50;
+const int CommonAgentBehaviourComponent::kRegeratesHealthStep = 1;
 
-AgentBehaviour::AgentBehaviour(PedInstance *pPed) : Behaviour(pPed), healthTimer_(0) {
-    doRegenerates_ = false;
-    healthTimer_.reset(pPed->getHealthRegenerationPeriod());
-    doUsePersuadotron_ = false;
+Behaviour::~Behaviour() {
+    while(compLst_.size() != 0) {
+        BehaviourComponent *pComp = compLst_.front();
+        compLst_.pop_front();
+        delete pComp;
+    }
 }
 
-void AgentBehaviour::handleBehaviourEvent(BehaviourEvent evtType) {
-    switch(evtType) {
-    case kBehvEvtPersuadotronActivated:
-        doUsePersuadotron_ = true;
-        break;
-    case kBehvEvtPersuadotronDeactivated:
-        doUsePersuadotron_ = false;
-    case kBehvEvtHit:
-        if (pThisPed_->hasMinimumVersionOfMod(Mod::MOD_CHEST, Mod::MOD_V2)) {
-            doRegenerates_ = true;
+void Behaviour::handleBehaviourEvent(BehaviourEvent evtType) {
+    for (std::list < BehaviourComponent * >::iterator it = compLst_.begin();
+            it != compLst_.end(); it++) {
+        BehaviourComponent *pComp = *it;
+        if (pComp->isEnabled()) {
+            pComp->handleBehaviourEvent(evtType, pThisPed_);
         }
-        break;
     }
 }
 
-void AgentBehaviour::execute(int elapsed, Mission *pMission) {
+void Behaviour::addComponent(BehaviourComponent *pComp) {
+    compLst_.push_back(pComp);
+}
+
+/*!
+ * Run the execute method  of each component listed in the behaviour.
+ * Component must be enabled.
+ * \param elapsed Time elapsed since last frame
+ * \param pMission Mission data
+ */
+void Behaviour::execute(int elapsed, Mission *pMission) {
     if (pThisPed_->isDead()) {
         return;
     }
 
+    for (std::list < BehaviourComponent * >::iterator it = compLst_.begin();
+            it != compLst_.end(); it++) {
+        BehaviourComponent *pComp = *it;
+        if (pComp->isEnabled()) {
+            pComp->execute(elapsed, pMission, pThisPed_);
+        }
+    }
+}
+
+CommonAgentBehaviourComponent::CommonAgentBehaviourComponent(PedInstance *pPed):
+        BehaviourComponent(), healthTimer_(pPed->getHealthRegenerationPeriod()) {
+    doRegenerates_ = false;
+}
+
+/*!
+ * 
+ * \param elapsed Time elapsed since last frame
+ * \param pMission Mission data
+ * \param pPed The owner of the behaviour
+ */
+void CommonAgentBehaviourComponent::execute(int elapsed, Mission *pMission, PedInstance *pPed) {
     // If Agent is equiped with right chest, his health periodically updates
     if (doRegenerates_ && healthTimer_.update(elapsed)) {
-        if (pThisPed_->increaseHealth(kRegeratesHealthStep)) {
+        if (pPed->increaseHealth(kRegeratesHealthStep)) {
             doRegenerates_ = false;
         }
     }
+}
+
+void CommonAgentBehaviourComponent::handleBehaviourEvent(Behaviour::BehaviourEvent evtType, PedInstance *pPed) {
+    switch(evtType) {
+    case Behaviour::kBehvEvtHit:
+        if (pPed->hasMinimumVersionOfMod(Mod::MOD_CHEST, Mod::MOD_V2)) {
+            doRegenerates_ = true;
+        }
+        break;
+    }
+}
+
+PersuaderBehaviourComponent::PersuaderBehaviourComponent():
+        BehaviourComponent() {
+    doUsePersuadotron_ = false;
+}
+
+void PersuaderBehaviourComponent::execute(int elapsed, Mission *pMission, PedInstance *pPed) {
     // Check if Agent has selected his Persuadotron
     if (doUsePersuadotron_) {
         for (size_t i = 0; i < pMission->numPeds(); i++) {
             PedInstance *pOtherPed = pMission->ped(i);
             // Agent can only persuad peds from another group
-            if (pThisPed_->objGroupID() != pOtherPed->objGroupID() &&
+            if (pPed->objGroupID() != pOtherPed->objGroupID() &&
                     pOtherPed->isAlive() &&
-                    pThisPed_->isCloseTo(pOtherPed, kMaxDistanceForPersuadotron)) {
-                        pOtherPed->handlePersuadedBy(pThisPed_);
+                    pPed->isCloseTo(pOtherPed, kMaxDistanceForPersuadotron)) {
+                        pOtherPed->handlePersuadedBy(pPed);
             }
         }
     }
-}
\ No newline at end of file
+}
+
+void PersuaderBehaviourComponent::handleBehaviourEvent(Behaviour::BehaviourEvent evtType, PedInstance *pPed) {
+    switch(evtType) {
+    case Behaviour::kBehvEvtPersuadotronActivated:
+        doUsePersuadotron_ = true;
+        break;
+    case Behaviour::kBehvEvtPersuadotronDeactivated:
+        doUsePersuadotron_ = false;
+    }
+}
index 5916325b865247c3059a8e5b7ed78434c4a48fb2..cad4469b7eba15963d921c77fad611c3c220d3fb 100644 (file)
 #ifndef IA_BEHAVIOUR_H_
 #define IA_BEHAVIOUR_H_
 
+#include <list>
+
 #include "utils/timer.h"
 
 class Mission;
 class PedInstance;
+class BehaviourComponent;
+
 /*!
- * A behaviour is used to determine default actions for ped.
+ * A Behaviour drives the ped's reactions.
+ * It is composed of a set of components, each one 
+ * responsible for an aspect of the reaction.
+ * Behaviour reacts to events and modify the ped's
+ * actions.
  */
 class Behaviour {
 public:
@@ -45,53 +53,80 @@ public:
         kBehvEvtHit
     };
 
-    Behaviour(PedInstance *pPed) { pThisPed_ = pPed; }
-    virtual ~Behaviour() {}
+    virtual ~Behaviour();
 
-    virtual void execute(int elapsed, Mission *pMission) = 0;
+    void setOwner(PedInstance *pPed) { pThisPed_ = pPed; }
+    //! Adds a component to the behaviour
+    void addComponent(BehaviourComponent *pComp);
 
-    virtual void handleBehaviourEvent(BehaviourEvent evtType) = 0;
+    virtual void execute(int elapsed, Mission *pMission);
 
+    virtual void handleBehaviourEvent(BehaviourEvent evtType);
 protected:
     /*! The ped that use this behaviour.*/
     PedInstance *pThisPed_;
+    /*! List of behaviour components.*/
+    std::list <BehaviourComponent *> compLst_;
 };
 
 /*!
- * This behaviour if for development purpose.
+ * Abstract class that represent an aspect of a behaviour.
+ * A component may be disabled according to certain types of events.
  */
-class NopeBehaviour : public Behaviour {
+class BehaviourComponent {
 public:
-    NopeBehaviour(PedInstance *pPed) : Behaviour(pPed) {}
+    BehaviourComponent() { enabled_ = true; }
+    virtual ~BehaviourComponent() {}
+
+    bool isEnabled() { return enabled_; }
+    void setEnabled(bool val) { enabled_ = val; }
 
-    void execute(int elapsed, Mission *pMission) {}
+    virtual void execute(int elapsed, Mission *pMission, PedInstance *pPed) = 0;
 
-    void handleBehaviourEvent(BehaviourEvent evtType) {}
+    virtual void handleBehaviourEvent(Behaviour::BehaviourEvent evtType, PedInstance *pPed){};
+
+protected:
+    bool enabled_;
 };
 
 /*!
  * This class defines commons behaviours for all agents (good or bad).
+ * It is responsible for :
+ * - regenerating life for agents that are hurt
  */
-class AgentBehaviour : public Behaviour {
+class CommonAgentBehaviourComponent : public BehaviourComponent {
 public:
-    //! Distance under whom an agent is close enough to persuade a ped
-    static const int kMaxDistanceForPersuadotron;
     //! Amount of health regenerated each period
     static const int kRegeratesHealthStep;
 
-    AgentBehaviour(PedInstance *pPed);
+    CommonAgentBehaviourComponent(PedInstance *pPed);
 
-    void execute(int elapsed, Mission *pMission);
+    void execute(int elapsed, Mission *pMission, PedInstance *pPed);
 
-    void handleBehaviourEvent(BehaviourEvent evtType);
-
-protected:
+    void handleBehaviourEvent(Behaviour::BehaviourEvent evtType, PedInstance *pPed);
+private:
     /*! Flag to indicate whether ped can regenerate his health.*/
     bool doRegenerates_;
-    /*! Flag to indicate an agent can use his persuadotron.*/
-    bool doUsePersuadotron_;
     //! used for health regeneration
     fs_utils::Timer healthTimer_;
 };
 
+/*!
+ * Component for user of Persuadotron. Only our agents use this component.
+ */
+class PersuaderBehaviourComponent : public BehaviourComponent {
+public:
+    //! Amount of health regenerated each period
+    static const int kMaxDistanceForPersuadotron;
+
+    PersuaderBehaviourComponent();
+
+    void execute(int elapsed, Mission *pMission, PedInstance *pPed);
+
+    void handleBehaviourEvent(Behaviour::BehaviourEvent evtType, PedInstance *pPed);
+private:
+    /*! Flag to indicate an agent can use his persuadotron.*/
+    bool doUsePersuadotron_;
+};
+
 #endif // IA_BEHAVIOUR_H_
\ No newline at end of file
index 80742bde39e58f84630874b9c335dd43e4dbe904..cae8ddd2b28652b5bfb0105c2088ec59bbb54f65 100644 (file)
@@ -595,22 +595,17 @@ void MissionManager::createPeds(const LevelData::LevelDataAll &level_data, DataI
     obj_ids[4] = "Policemen";
     obj_ids[5] = "Civilians";
 #endif
-    ModOwner mods_enemy;
-    // enemies get top version of mods
-    mods_enemy.addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_LEGS));
-    mods_enemy.addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_ARMS));
-    mods_enemy.addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_CHEST));
-    mods_enemy.addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_HEART));
-    mods_enemy.addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_EYES));
-    mods_enemy.addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_BRAIN));
     
     PedManager peds;
     for (uint16 i = 0; i < 256; i++) {
         const LevelData::People & pedref = level_data.people[i];
         
         PedInstance *p =
-            peds.loadInstance(pedref, i, pMission->mapId());
+            peds.loadInstance(pedref, i, pMission->mapId(), pMission->playersGroupID());
         if (p) {
+            di.pindx[i] = pMission->numPeds();
+            pMission->addPed(p);
+
             if (pedref.location == LevelData::kPeopleLocInVehicle) {
                 uint16 vid = 0xFFFF;  // Id of the vehicle
                 bool setDriver = false;  // Tells if ped should be the driver
@@ -638,13 +633,8 @@ void MissionManager::createPeds(const LevelData::LevelDataAll &level_data, DataI
                     pCar->forceSetDriver(p);
                 }
             }
-            di.pindx[i] = pMission->numPeds();
-            pMission->addPed(p);
 
-            if (i < AgentManager::kMaxSlot) {
-                // We're loading one of our agents
-                Agent *pAg = g_gameCtrl.agents().squadMember(i);
-                p->initAsAgent(pAg, pMission->playersGroupID());
+            if (p->isOurAgent()) {
                 // adds all agent's weapons to the mission weapons
                 for (int wi=0; wi<p->numWeapons(); wi++) {
                     pMission->addWeapon(p->weapon(wi));
@@ -652,49 +642,8 @@ void MissionManager::createPeds(const LevelData::LevelDataAll &level_data, DataI
                 // adds the agent to the mission squad
                 pMission->getSquad()->setMember(i, p);
             } else {
-                unsigned int mt = p->type();
-                p->setObjGroupDef(mt);
-                if (mt == PedInstance::og_dmAgent) {
-                    p->setObjGroupID(2);
-                    p->addEnemyGroupDef(1);
-                    p->setBaseSpeed(256);
-                    *((ModOwner *)p) = mods_enemy;
-                    p->setTimeBeforeCheck(400);
-                    p->setBaseModAcc(0.5);
-                    p->setPersuasionPoints(32);
-                } else if (mt == PedInstance::og_dmGuard) {
-                    p->setObjGroupID(3);
-                    p->addEnemyGroupDef(1);
-                    p->setBaseSpeed(192);
-                    p->setTimeBeforeCheck(300);
-                    p->setBaseModAcc(0.45);
-                    p->setPersuasionPoints(4);
-                } else if (mt == PedInstance::og_dmPolice) {
-                    p->setObjGroupID(4);
-                    p->setHostileDesc(PedInstance::pd_smArmed);
-                    p->setBaseSpeed(160);
-                    p->setTimeBeforeCheck(400);
-                    p->setBaseModAcc(0.4);
-                    p->setPersuasionPoints(8);
-                } else if (mt == PedInstance::og_dmCivilian) {
-                    p->setObjGroupID(5);
-                    p->addEnemyGroupDef(6);
-                    p->setHostileDesc(PedInstance::pd_smArmed);
-                    p->setBaseSpeed(128);
-                    p->setTimeBeforeCheck(600);
-                    p->setBaseModAcc(0.2);
-                    p->setPersuasionPoints(1);
-                } else if (mt == PedInstance::og_dmCriminal) {
-                    p->setObjGroupID(6);
-                    p->setBaseSpeed(128);
-                    p->setTimeBeforeCheck(500);
-                    p->setBaseModAcc(0.2);
-                    p->setPersuasionPoints(1);
-                }
-                p->setSightRange(7 * 256);
-                // TODO: set scenarios
-                
-               if (p->useNewAnimation()) {
+                // Set scenarios
+                if (p->useNewAnimation()) {
                     createScriptedActionsForPed(pMission, di, level_data, p);
                 } else {
                     uint16 offset_start = READ_LE_UINT16(pedref.offset_scenario_start);
index b9ca76203c3c8a9f500b3cd4b18c36a05e3f0551..03e4c20174259f346455731b5c4ae61ec1333ab5 100644 (file)
@@ -409,7 +409,7 @@ bool PedInstance::updateAnimation(int elapsed) {
  */
 bool PedInstance::animate2(int elapsed, Mission *mission) {
     // Execute current behaviour
-    pBehaviour_->execute(elapsed, mission);
+    behaviour_.execute(elapsed, mission);
 
     // Execute any active action
     bool update = executeAction(elapsed, mission);
@@ -2058,7 +2058,8 @@ void PedInstance::showPath(int scrollX, int scrollY) {
     }
 }
 
-PedInstance::PedInstance(Ped *ped, uint16 id, int m) : ShootableMovableMapObject(id, m, MapObject::kNaturePed),
+PedInstance::PedInstance(Ped *ped, uint16 id, int m, bool isOur) :
+    ShootableMovableMapObject(id, m, MapObject::kNaturePed),
     ped_(ped), action_grp_id_(1),
     desc_state_(PedInstance::pd_smUndefined),
     hostile_desc_(PedInstance::pd_smUndefined),
@@ -2073,7 +2074,7 @@ PedInstance::PedInstance(Ped *ped, uint16 id, int m) : ShootableMovableMapObject
     rcv_damage_def_ = MapObject::ddmg_Ped;
     state_ = PedInstance::pa_smNone;
     drop_actions_ = false;
-    is_our_ = false;
+    is_our_ = isOur;
     
     adrenaline_  = new IPAStim(IPAStim::Adrenaline);
     perception_  = new IPAStim(IPAStim::Perception);
@@ -2083,8 +2084,7 @@ PedInstance::PedInstance(Ped *ped, uint16 id, int m) : ShootableMovableMapObject
     base_mod_acc_ = 0.1;
     last_firing_target_.desc = 0;
 
-    // Todo : adds a behaviour for the type of ped
-    pBehaviour_ = new NopeBehaviour(this);
+    behaviour_.setOwner(this);
     currentAction_ = NULL;
     pUseWeaponAction_ = NULL;
 }
@@ -2101,44 +2101,10 @@ PedInstance::~PedInstance()
     delete intelligence_;
     intelligence_ = NULL;
 
-    delete pBehaviour_;
-    pBehaviour_ = NULL;
     destroyAllActions();
     destroyUseWeaponAction();
 }
 
-/*!
- * Initialize the ped instance as one of our agent.
- * \param p_agent The agent reference
- * \param obj_group_id Id of the agent's group.
- */
-void PedInstance::initAsAgent(Agent *p_agent, unsigned int obj_group_id) {
-    // not in all missions our agents health is 16, this fixes it
-    setHealth(kAgentMaxHealth);
-    setStartHealth(kAgentMaxHealth);
-    while (p_agent->numWeapons()) {
-        WeaponInstance *wi = p_agent->removeWeaponAtIndex(0);
-        addWeapon(wi);
-        wi->setOwner(this);
-    }
-    set_is_our(true);
-    *((ModOwner *)this) = *((ModOwner *)p_agent);
-
-    setObjGroupID(obj_group_id);
-    setObjGroupDef(PedInstance::og_dmAgent);
-    addEnemyGroupDef(2);
-    addEnemyGroupDef(3);
-    setHostileDesc(PedInstance::pd_smArmed);
-    setSightRange(7 * 256);
-    setBaseSpeed(256);
-    setTimeBeforeCheck(400);
-    setBaseModAcc(0.5);
-
-    // sets AgentBehaviour here because earlier we don't know if ped is an agent
-    delete pBehaviour_;
-    pBehaviour_ = new AgentBehaviour(this);
-}
-
 void PedInstance::draw(int x, int y) {
 
     // ensure on map
@@ -2311,7 +2277,7 @@ void PedInstance::handleWeaponDeselected(WeaponInstance * wi) {
     desc_state_ &= (pd_smAll ^ (pd_smArmed | pd_smNoAmmunition));
 
     if (wi->getWeaponType() == Weapon::Persuadatron) {
-        pBehaviour_->handleBehaviourEvent(Behaviour::kBehvEvtPersuadotronDeactivated);
+        behaviour_.handleBehaviourEvent(Behaviour::kBehvEvtPersuadotronDeactivated);
     }
 }
 
@@ -2348,7 +2314,7 @@ void PedInstance::handleWeaponSelected(WeaponInstance * wi) {
         addActionUseMedikit();
         break;
     case Weapon::Persuadatron:
-        pBehaviour_->handleBehaviourEvent(Behaviour::kBehvEvtPersuadotronActivated);
+        behaviour_.handleBehaviourEvent(Behaviour::kBehvEvtPersuadotronActivated);
         break;
     }
 }
@@ -2622,7 +2588,7 @@ void PedInstance::handleHit(DamageInflictType &d) {
         }
 
         // Alert behaviour
-        pBehaviour_->handleBehaviourEvent(Behaviour::kBehvEvtHit);
+        behaviour_.handleBehaviourEvent(Behaviour::kBehvEvtHit);
     }
 }
 
index 9c425f28d82f7f151f711b868eb72239015fbd6b..a017f817891f6d581b43385fb68a24c0c253af39 100644 (file)
@@ -39,9 +39,9 @@
 #include "weapon.h"
 #include "ipastim.h"
 #include "ia/actions.h"
+#include "ia/behaviour.h"
 
 class Agent;
-class Behaviour;
 class Mission;
 class VehicleInstance;
 class Vehicle;
@@ -196,25 +196,22 @@ public:
         pd_smAll = 0xFFFF
     };
 
-    PedInstance(Ped *ped, uint16 id, int m);
+    PedInstance(Ped *ped, uint16 id, int m, bool isOur);
     ~PedInstance();
 
     //! Temporary method
     bool useNewAnimation();
 
-    //! Initialize the ped instance as an agent
-    void initAsAgent(Agent *p_agent, unsigned int obj_group_id);
-
     //*************************************
     // Properties
     //*************************************
     //! Returns true if the agent is one of us.
     bool isOurAgent() { return is_our_; }
-    //! Sets if the agent is one of us or not
-    void set_is_our(bool is_our) { is_our_ = is_our; }
     //! Return the type of Ped
     PedType type() { return type_; }
     void setTypeFromValue(uint8 value);
+    //! Returns the ped's behaviour
+    Behaviour & behaviour() { return behaviour_; }
     //! Return true if ped has escaped the map
     bool hasEscaped() { return IS_FLAG_SET(desc_state_, pd_smEscaped); }
     //! Indicate that the ped has escaped
@@ -907,7 +904,7 @@ protected:
     std::vector <actionQueueGroupType> default_actions_;
 
     /*! Ped's behaviour.*/
-    Behaviour *pBehaviour_;
+    Behaviour behaviour_;
     /*! Current action*/
     fs_actions::MovementAction *currentAction_;
     /*! Current action of using a weapon.*/
index b251e5bd2b190dcf597737b0e1d16b9b354630c5..213089265d9ac0cf841efae2f05449a15dfb652a 100644 (file)
@@ -34,7 +34,7 @@ PedManager::PedManager()
 {
 }
 
-void PedManager::setPed(Ped *pedanim, unsigned short baseAnim)
+void PedManager::initAnimation(Ped *pedanim, unsigned short baseAnim)
 {
     if (baseAnim == 1) {
         pedanim->setStandAnim(Weapon::Unarmed_Anim, 0 + baseAnim);
@@ -143,14 +143,15 @@ void PedManager::setPed(Ped *pedanim, unsigned short baseAnim)
  * \param map id of the map
  * \return NULL if the ped could not be created.
  */
-PedInstance *PedManager::loadInstance(const LevelData::People & gamdata, uint16 ped_idx, int map)
+PedInstance *PedManager::loadInstance(const LevelData::People & gamdata, uint16 ped_idx, int map, uint32 playerGroupId)
 {
     if(gamdata.type == 0x0 || 
         gamdata.location == LevelData::kPeopleLocNotVisible || 
         gamdata.location == LevelData::kPeopleLocAboveWalkSurf)
         return NULL;
 
-    if (ped_idx < 4 && !g_gameCtrl.agents().isSquadSlotActive(ped_idx)) {
+    bool isOurAgent = ped_idx < AgentManager::kMaxSlot;
+    if (isOurAgent && !g_gameCtrl.agents().isSquadSlotActive(ped_idx)) {
         // Creates agent only if he's active
         return NULL;
     }if (ped_idx >= 4 && ped_idx < 8) {
@@ -160,12 +161,17 @@ PedInstance *PedManager::loadInstance(const LevelData::People & gamdata, uint16
     }
 
     Ped *pedanim = new Ped();
-    setPed(pedanim, READ_LE_UINT16(gamdata.index_base_anim));
-    PedInstance *newped = new PedInstance(pedanim, ped_idx, map);
+    initAnimation(pedanim, READ_LE_UINT16(gamdata.index_base_anim));
+    PedInstance *newped = new PedInstance(pedanim, ped_idx, map, isOurAgent);
 
     int hp = READ_LE_INT16(gamdata.health);
-    if (hp <= 0)
+    if (isOurAgent) {
+        // not in all missions our agents health is 16, this fixes it
+        hp = PedInstance::kAgentMaxHealth;
+    }else if (hp <= 0) {
         hp = 2;
+    }
+
     newped->setStartHealth(hp);
 
     newped->setDirection(gamdata.orientation);
@@ -207,5 +213,138 @@ PedInstance *PedManager::loadInstance(const LevelData::People & gamdata, uint16
     newped->setAllPercepLevels(gamdata.percep_amount,
         gamdata.percep_dependency, gamdata.percep_effect);
 
+    if (isOurAgent) {
+        // We're loading one of our agents
+        Agent *pAg = g_gameCtrl.agents().squadMember(ped_idx);
+        initOurAgent(pAg, playerGroupId, newped);
+    } else {
+        unsigned int mt = newped->type();
+        newped->setObjGroupDef(mt);
+        if (mt == PedInstance::og_dmAgent) {
+            initEnemyAgent(newped);
+        } else if (mt == PedInstance::og_dmGuard) {
+            initGuard(newped);
+        } else if (mt == PedInstance::og_dmPolice) {
+            initPolice(newped);
+        } else if (mt == PedInstance::og_dmCivilian) {
+            initCivilian(newped);
+        } else if (mt == PedInstance::og_dmCriminal) {
+            initCriminal(newped);
+        }
+        newped->setSightRange(7 * 256);
+    }
+
     return newped;
 }
+
+/*!
+ * Initialize the ped instance as one of our agent.
+ * \param p_agent The agent reference
+ * \param obj_group_id Id of the agent's group.
+ * \param pPed The ped to initialize
+ */
+void PedManager::initOurAgent(Agent *p_agent, unsigned int obj_group_id, PedInstance *pPed) {
+    while (p_agent->numWeapons()) {
+        WeaponInstance *wi = p_agent->removeWeaponAtIndex(0);
+        pPed->addWeapon(wi);
+        wi->setOwner(pPed);
+    }
+    *((ModOwner *)pPed) = *((ModOwner *)p_agent);
+
+    pPed->setObjGroupID(obj_group_id);
+    pPed->setObjGroupDef(PedInstance::og_dmAgent);
+    pPed->addEnemyGroupDef(2);
+    pPed->addEnemyGroupDef(3);
+    pPed->setHostileDesc(PedInstance::pd_smArmed);
+    pPed->setSightRange(7 * 256);
+    pPed->setBaseSpeed(256);
+    pPed->setTimeBeforeCheck(400);
+    pPed->setBaseModAcc(0.5);
+
+    // Set components of behaviour for our agent
+    pPed->behaviour().addComponent(new CommonAgentBehaviourComponent(pPed));
+    pPed->behaviour().addComponent(new PersuaderBehaviourComponent());
+}
+
+/*!
+ * Initialize the ped instance as an enemy agent.
+ * \param p_agent The agent reference
+ * \param obj_group_id Id of the agent's group.
+ * \param pPed The ped to initialize
+ */
+void PedManager::initEnemyAgent(PedInstance *pPed) {
+    pPed->setObjGroupID(2);
+    pPed->addEnemyGroupDef(1);
+    pPed->setBaseSpeed(256);
+    // enemies get top version of mods
+    pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_LEGS));
+    pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_LEGS));
+    pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_ARMS));
+    pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_CHEST));
+    pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_HEART));
+    pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_EYES));
+    pPed->addMod(g_gameCtrl.mods().getHighestVersion(Mod::MOD_BRAIN));
+    pPed->setTimeBeforeCheck(400);
+    pPed->setBaseModAcc(0.5);
+    pPed->setPersuasionPoints(32);
+}
+
+/*!
+ * Initialize the ped instance as a guard.
+ * \param p_agent The agent reference
+ * \param obj_group_id Id of the agent's group.
+ * \param pPed The ped to initialize
+ */
+void PedManager::initGuard(PedInstance *pPed) {
+    pPed->setObjGroupID(3);
+    pPed->addEnemyGroupDef(1);
+    pPed->setBaseSpeed(192);
+    pPed->setTimeBeforeCheck(300);
+    pPed->setBaseModAcc(0.45);
+    pPed->setPersuasionPoints(4);
+}
+
+/*!
+ * Initialize the ped instance as a police.
+ * \param p_agent The agent reference
+ * \param obj_group_id Id of the agent's group.
+ * \param pPed The ped to initialize
+ */
+void PedManager::initPolice(PedInstance *pPed) {
+    pPed->setObjGroupID(4);
+    pPed->setHostileDesc(PedInstance::pd_smArmed);
+    pPed->setBaseSpeed(160);
+    pPed->setTimeBeforeCheck(400);
+    pPed->setBaseModAcc(0.4);
+    pPed->setPersuasionPoints(8);
+} 
+
+/*!
+ * Initialize the ped instance as a civilian.
+ * \param p_agent The agent reference
+ * \param obj_group_id Id of the agent's group.
+ * \param pPed The ped to initialize
+ */
+void PedManager::initCivilian(PedInstance *pPed) {
+    pPed->setObjGroupID(5);
+    pPed->addEnemyGroupDef(6);
+    pPed->setHostileDesc(PedInstance::pd_smArmed);
+    pPed->setBaseSpeed(128);
+    pPed->setTimeBeforeCheck(600);
+    pPed->setBaseModAcc(0.2);
+    pPed->setPersuasionPoints(1);
+} 
+
+/*!
+ * Initialize the ped instance as a criminal.
+ * \param p_agent The agent reference
+ * \param obj_group_id Id of the agent's group.
+ * \param pPed The ped to initialize
+ */
+void PedManager::initCriminal(PedInstance *pPed) {
+    pPed->setObjGroupID(6);
+    pPed->setBaseSpeed(128);
+    pPed->setTimeBeforeCheck(500);
+    pPed->setBaseModAcc(0.2);
+    pPed->setPersuasionPoints(1);
+}
index c38a4922f6c4cd7343eaa3d09085e6ba15deb03d..d0580d5915e49db40731b6200532ebf0a2a6c832 100644 (file)
@@ -42,21 +42,21 @@ public:
     PedManager();
     virtual ~PedManager() {}
 
-    void setPed(Ped *pedanim, unsigned short baseAnim);
-
-    int numPeds() { return peds_.size(); }
-
-    Ped *ped(int n) {
-        assert(n < (int) peds_.size());
-        return peds_[n];
-    }
-
-    PedInstance *loadInstance(const LevelData::People & ped_data, uint16 ped_idx, int map);
-
+    PedInstance *loadInstance(const LevelData::People & ped_data, uint16 ped_idx, int map, uint32 playerGroupId);
 protected:
-    // TODO: remove this everywhere(?)
-    // this class loads peds data and sets animation
-    std::vector<Ped *> peds_;
+    void initAnimation(Ped *pedanim, unsigned short baseAnim);
+    //! Initialize the ped instance as our agent
+    void initOurAgent(Agent *p_agent, unsigned int obj_group_id, PedInstance *pPed);
+    //! Initialize the ped instance as an enemy agent
+    void initEnemyAgent(PedInstance *pPed);
+    //! Initialize the ped instance as a guard
+    void initGuard(PedInstance *pPed);
+    //! Initialize the ped instance as a police
+    void initPolice(PedInstance *pPed);
+    //! Initialize the ped instance as a civilian
+    void initCivilian(PedInstance *pPed);
+    //! Initialize the ped instance as a criminal
+    void initCriminal(PedInstance *pPed);
 };
 
 #endif