]> github.com/historicalsource and other repositories - freesynd.git/commitdiff
- Added new EscapeAction for scenario type 7
authorbenblan <benblan@3ce38193-f967-438d-acd5-fc4e68e0da95>
Mon, 21 Jul 2014 07:52:27 +0000 (07:52 +0000)
committerbenblan <benblan@3ce38193-f967-438d-acd5-fc4e68e0da95>
Mon, 21 Jul 2014 07:52:27 +0000 (07:52 +0000)
- Added new state pd_smEscaped in pedDescStateMasks enumeration
- ObjAssassinate now checks the PedInstance::hasEscaped() instead of checking if ped is outside borders
- Added IS_FLAG_SET and SET_FLAG macros to improve readability with flags
- modified MissionManager to handle vehicles and escape scenarios

freesynd/branches/rework-actions/src/common.h
freesynd/branches/rework-actions/src/ia/action.cpp
freesynd/branches/rework-actions/src/ia/actions.h
freesynd/branches/rework-actions/src/menus/squadselection.cpp
freesynd/branches/rework-actions/src/missionmanager.cpp
freesynd/branches/rework-actions/src/missionmanager.h
freesynd/branches/rework-actions/src/model/leveldata.h
freesynd/branches/rework-actions/src/model/objectivedesc.cpp
freesynd/branches/rework-actions/src/ped.h
freesynd/branches/rework-actions/src/pedactions.cpp

index 7ab8adcbf680622b8f73fe58b6c28c90398f6770..9654ff9b81fe55efbb74bc0c93bd2d7bf1f75c7f 100644 (file)
@@ -170,4 +170,7 @@ inline void boxify(int &left, int &width, int x1, int x2)
     left = (x1 < x2) ? x1 : x2;
 }
 
+#define IS_FLAG_SET(field, flags) (field & flags) != 0
+#define SET_FLAG(field, flags) field |= flags
+
 #endif
index d601ed8881ac53d92f686c57671d1c0d32963fa2..e7b7bfdc6371bce5f814c5a5e39b40a8ae051071 100644 (file)
@@ -137,6 +137,7 @@ MovementAction(kActTypeWalk, origin) {
     dest_.setOffX(smo->offX());
     dest_.setOffY(smo->offY());
     dest_.setOffZ(smo->offZ());
+    targetState_ = PedInstance::pa_smWalking;
 }
 
 void WalkAction::doStart(Mission *pMission, PedInstance *pPed) {
@@ -169,10 +170,12 @@ WalkToDirectionAction::WalkToDirectionAction(CreatOrigin origin, const PathNode
 MovementAction(kActTypeWalk, origin) {
     maxDistanceToWalk_ = 0;
     dest.convertPosToXYZ(&dest_);
+    targetState_ = PedInstance::pa_smWalking;
 }
 
 void WalkToDirectionAction::doStart(Mission *pMission, PedInstance *pPed) {
     moveDirdesc_.clear();
+    moveDirdesc_.bounce = true;
     pPed->setSpeed(pPed->getDefaultSpeed());
 }
 
@@ -191,7 +194,7 @@ bool WalkToDirectionAction::doExecute(int elapsed, Mission *pMission, PedInstanc
     int maxDistanceToWalk = (int)sqrt((double)(diffx * diffx + diffy * diffy));
 
     if (maxDistanceToWalk > 0) {
-        pPed->moveToDir(pMission, 
+        uint8 res = pPed->moveToDir(pMission, 
                         elapsed,
                         moveDirdesc_,
                         -1,
@@ -244,6 +247,17 @@ bool TriggerAction::doExecute(int elapsed, Mission *pMission, PedInstance *pPed)
     return false;
 }
 
+/*!
+ * This action only sets the ped's state to "Escaped".
+ * \param elapsed Time elapsed since last frame
+ * \param pMission Mission data
+ * \param pPed The ped executing the action.
+ */
+bool EscapeAction::doExecute(int elapsed, Mission *pMission, PedInstance *pPed) {
+    pPed->escape();
+    return true;
+}
+
 /*!
  * Class constructor.
  * \param pTarget The ped to follow.
@@ -369,7 +383,8 @@ bool PickupWeaponAction::doExecute(int elapsed, Mission *pMission, PedInstance *
     return true;
 }
 
-EnterVehicleAction::EnterVehicleAction(Vehicle *pVehicle) : MovementAction(kActTypeUndefined, kOrigUser, true) {
+EnterVehicleAction::EnterVehicleAction(CreatOrigin origin, Vehicle *pVehicle) :
+        MovementAction(kActTypeUndefined, origin, true) {
     pVehicle_ = pVehicle;
 }
 
index 68c833fd0286c96c629e9570a288fa29069293d4..cd428179d392cea7a847766bc1e5865a9f0f8833 100644 (file)
@@ -247,6 +247,18 @@ namespace fs_actions {
         int32 range_;
     };
 
+    /*!
+     * This action is used in scripted action when a ped
+     * needs to escape the map and our agents must kill him.
+     */
+    class EscapeAction : public MovementAction {
+    public:
+        EscapeAction():
+            MovementAction(kActTypeUndefined, kOrigScript, false, true) {}
+    protected:
+        bool doExecute(int elapsed, Mission *pMission, PedInstance *pPed);
+    };
+
     /*!
      * This action is used to make a ped follow another ped.
      * Both must be walking.
@@ -313,7 +325,7 @@ namespace fs_actions {
      */
     class EnterVehicleAction : public MovementAction {
     public:
-        EnterVehicleAction(Vehicle *pVehicle);
+        EnterVehicleAction(CreatOrigin origin, Vehicle *pVehicle);
 
     protected:
         void doStart(Mission *pMission, PedInstance *pPed);
index f4ce1ac3bda6083b3e34421d2e7fc2d194661853..7514f3e6ebed0a8d8ef17f3a9323cf5c0d7518e3 100644 (file)
@@ -254,7 +254,7 @@ void SquadSelection::enterOrLeaveVehicle(Vehicle *pVehicle, bool addAction) {
         
         if (getIn && !pAgent->inVehicle()) {
             // Agent is out and everybody must get in
-            pAgent->addActionEnterVehicle(pVehicle, addAction);
+            pAgent->addActionEnterVehicle(fs_actions::kOrigUser, pVehicle, addAction);
         } else if (!getIn && pAgent->inVehicle() == pVehicle) {
             // Agent is in the given car and everybody must get out
             // first stops the vehicle if it's a car
index ab9036ec18f5bed15e14af593009b48235ccdcae..5a459a9d9d80896d374d83ac24cb41fe7334877f 100644 (file)
@@ -695,7 +695,7 @@ void MissionManager::createPeds(const LevelData::LevelDataAll &level_data, DataI
                 // TODO: set scenarios
                 
                if (p->useNewAnimation()) {
-                    createScriptedActionsForPed(p, level_data, i);
+                    createScriptedActionsForPed(pMission, di, level_data, i, p);
                 } else {
                     uint16 offset_start = READ_LE_UINT16(pedref.offset_scenario_start);
                     uint16 offset_nxt = offset_start;
@@ -810,7 +810,7 @@ void MissionManager::createPeds(const LevelData::LevelDataAll &level_data, DataI
     }
 }
 
-void MissionManager::createScriptedActionsForPed(PedInstance *pPed, const LevelData::LevelDataAll &level_data, uint16 pedIdx) {
+void MissionManager::createScriptedActionsForPed(Mission *pMission, DataIndex &di, const LevelData::LevelDataAll &level_data, uint16 pedIdx, PedInstance *pPed) {
     const LevelData::People & pedref = level_data.people[pedIdx];
     uint16 offset_start = READ_LE_UINT16(pedref.offset_scenario_start);
     uint16 offset_nxt = offset_start;
@@ -833,7 +833,7 @@ void MissionManager::createScriptedActionsForPed(PedInstance *pPed, const LevelD
         // 3?(south africa)
         // 5?(kenya)
         // 6 (kenya) - ped offset when in vehicle, and? (TODO)
-        // 7 - assasinate target escaped, mission failed (TODO properly)
+        // 7 - assasinate target escaped, mission failed
         // 8 - walking to pos, triggers on our agents in range, x,y defined
         // 9 - repeat from start, actually this might be end of script
         // 10 - train stops and waits
@@ -851,12 +851,13 @@ void MissionManager::createScriptedActionsForPed(PedInstance *pPed, const LevelD
             PathNode pn(sc.tilex >> 1, sc.tiley >> 1, sc.tilez,
                 (sc.tilex & 0x01) << 7, (sc.tiley & 0x01) << 7);
             if (sc.type == LevelData::kScenarioTypeTrigger) {
-                LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Trigger"))
+                LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Trigger at (%d, %d, %d)", pn.tileX(), pn.tileY(), pn.tileZ()))
                 pPed->addActionTrigger(6 * 256, pn);
             }
             if (v) {
-                printf("Scenario with car\n");
-                //pPed->createActQUsingCar(as, &pn, v);
+                LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Drive car to (%d, %d, %d)", pn.tileX(), pn.tileY(), pn.tileZ()))
+                VehicleInstance *pCar = dynamic_cast<VehicleInstance *>(v);
+                pPed->addActionDriveVehicle(fs_actions::kOrigScript, pCar, pn, true);
             } else {
                 LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Walk toward location (%d, %d, %d)", pn.tileX(), pn.tileY(), pn.tileZ()))
                 pPed->addActionWalkToLocUsingDirection(pn, fs_actions::kOrigScript, true);
@@ -866,7 +867,27 @@ void MissionManager::createScriptedActionsForPed(PedInstance *pPed, const LevelD
                 //pPed->createActQResetActionQueue(as);
             }
         } else if (sc.type == LevelData::kScenarioTypeUseVehicle) {
-            LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Use car"))
+            if (notInVehicle) {
+                LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Enter car"))
+                uint16 bindx = READ_LE_UINT16(sc.offset_object);
+                // TODO: test all maps for objects other then vehicle
+                assert(bindx >= 0x5C02 && bindx < 0x6682);
+                bindx -= 0x5C02;
+                bindx /= 42;
+                if (di.vindx[bindx] != 0xFFFF) {
+                    v = pMission->vehicle(di.vindx[bindx]);
+                    pPed->addActionEnterVehicle(fs_actions::kOrigScript, v, true);
+                }
+            } else {
+                PathNode pn(v->tileX(), v->tileY(), v->tileZ(),
+                    v->offX(), v->offY());
+                LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Drive to (%d, %d, %d)", pn.tileX(), pn.tileY(), pn.tileZ()))
+                VehicleInstance *pCar = dynamic_cast<VehicleInstance *>(v);
+                pPed->addActionDriveVehicle(fs_actions::kOrigScript, pCar, pn, true);
+            }
+        } else if (sc.type == LevelData::kScenarioTypeEscape) {
+            LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Escape"))
+            pPed->addMovementAction(new fs_actions::EscapeAction(), true);
         } else if (sc.type == 9) {
             LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - type 9"))
         } else if (sc.type == 10) {
index 00e7b90f8989a0ab25f3c665e0f477fd20e1f46e..bd18f764d45931438396d6b6d7f2321d755b8b1f 100644 (file)
@@ -84,7 +84,10 @@ private:
     //! Creates all peds
     void createPeds(const LevelData::LevelDataAll &level_data, 
                             DataIndex &di, Mission *pMission);
-    void createScriptedActionsForPed(PedInstance *pPed, const LevelData::LevelDataAll &level_data, uint16 pedIdx);
+    void createScriptedActionsForPed(Mission *pMission, 
+                                        DataIndex &di, 
+                                        const LevelData::LevelDataAll &level_data, 
+                                        uint16 pedIdx, PedInstance *pPed);
     //! Creates objectives
     void createObjectives(const LevelData::LevelDataAll &level_data, 
                             DataIndex &di, Mission *pMission);
index ca8095030c0aeb5f35c616732c522673e4b2bece..0191fe772949af6ff17cff5315867be3924183a1 100644 (file)
@@ -363,6 +363,8 @@ namespace LevelData {
     static const int kPeopleLocNotVisible = 0x0D;
     /*! Constant for field Scenario::type :  Use vehicle to go somewhere.*/
     static const int kScenarioTypeUseVehicle = 0x02;
+    /*! Constant for field Scenario::type :  Target has escape the map.*/
+    static const int kScenarioTypeEscape = 0x07;
     /*! Constant for field Scenario::type : this is a trigger. 
      * Agents will trigger it when they enter the circle defined by the center and a fixed radius.*/
     static const int kScenarioTypeTrigger = 0x08;
index ca2223f4c964a31d3c07622f27921ba58f95f2d5..159fd913d8cf5293a3a981d5689abb889d47da88 100644 (file)
@@ -86,21 +86,11 @@ ObjAssassinate::ObjAssassinate(MapObject * pMapObject) : TargetObjective(pMapObj
  */
 void ObjAssassinate::evaluate(Mission *pMission) {
     PedInstance *p = static_cast<PedInstance *>(p_target_);
-    if (p->isDead())
-    {
+    if (p->isDead()) {
         // Target is dead -> objective is completed
         endObjective(true);
-    } else {
-        int x = p->tileX();
-        int y = p->tileY();
-        // target might be off visible area (escaped) -> failed
-        if (p->inVehicle() && (x < (pMission->minX() >> 1)
-            || x > pMission->maxX() + ((pMission->mmax_x_ - pMission->maxX()) >> 1)
-            || y < (pMission->minY() >> 1)
-            || y > pMission->maxY() + ((pMission->mmax_y_ - pMission->maxY()) >> 1)))
-        {
-            endObjective(false);
-        }
+    } else if (p->hasEscaped()) {
+        endObjective(false);
     }
 }
 
index 668bb8cd06bc53c1b5bfae0e4854e2f1622243ac..26062634eb0cf711ce13edf378c087b74aa05a35 100644 (file)
@@ -179,6 +179,25 @@ public:
         kPedTypeCriminal = 0x10
     } ;
 
+    enum pedDescStateMasks {
+        pd_smUndefined = 0x0,
+        pd_smControlled = 0x0001,
+        pd_smArmed = 0x0002,
+        // no active action should be done, ex. persuaded ped will shoot target
+        // of persuader only if persuader shoots at it
+        pd_smSupporter = 0x0004,
+        pd_smEnemyInSight = 0x0008,
+        // only if all weapon has no ammunition, persuadatron excludes this
+        // should not be used for hostile_desc_
+        pd_smNoAmmunition = 0x0010,
+        // all non-player controllled peds should have this set
+        pd_smAutoAction = 0x0020,
+        /*! When a mission's objective is to kill a ped and this ped has
+        escaped, this value is used to indicate he's escaped.*/
+        pd_smEscaped = 0x0080,
+        pd_smAll = 0xFFFF
+    };
+
     PedInstance(Ped *ped, int m);
     ~PedInstance();
 
@@ -187,6 +206,10 @@ public:
 
     //! 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
@@ -194,6 +217,10 @@ public:
     //! Return the type of Ped
     PedType type() { return type_; }
     void setTypeFromValue(uint8 value);
+    //! Return true if ped has escaped the map
+    bool hasEscaped() { return IS_FLAG_SET(desc_state_, pd_smEscaped); }
+    //! Indicate that the ped has escaped
+    void escape() { SET_FLAG(desc_state_, pd_smEscaped); }
 
     typedef enum {
         ad_NoAnimation,
@@ -303,7 +330,8 @@ public:
     //! Adds action to pick up weapon from the ground
     void addActionPickup(WeaponInstance *pWeapon, bool appendAction);
     //! Adds action to enter a given vehicle
-    void addActionEnterVehicle(Vehicle *pVehicle, bool appendAction);
+    void addActionEnterVehicle(fs_actions::CreatOrigin origin,
+                                Vehicle *pVehicle, bool appendAction);
     //! Adds action to drive vehicle to destination
     void addActionDriveVehicle(fs_actions::CreatOrigin origin, 
            VehicleInstance *pVehicle, PathNode &destination, bool appendAction);
@@ -597,22 +625,6 @@ public:
         og_dmCriminal = 0x10
     } objGroupDefMasks;
 
-    typedef enum {
-        pd_smUndefined = 0x0,
-        pd_smControlled = 0x0001,
-        pd_smArmed = 0x0002,
-        // no active action should be done, ex. persuaded ped will shoot target
-        // of persuader only if persuader shoots at it
-        pd_smSupporter = 0x0004,
-        pd_smEnemyInSight = 0x0008,
-        // only if all weapon has no ammunition, persuadatron excludes this
-        // should not be used for hostile_desc_
-        pd_smNoAmmunition = 0x0010,
-        // all non-player controllled peds should have this set
-        pd_smAutoAction = 0x0020,
-        pd_smAll = 0xFFFF
-    } pedDescStateMasks;
-
     typedef enum {
         ai_aNone = 0x0,
         // Setup control over object where possible to lose this control
index a2426de2c3b9115d3e53b55a94968fba795fecb1..7b6d1c48d9160f95a72e37afb6be9c3547567db4 100644 (file)
@@ -132,15 +132,16 @@ void PedInstance::addActionPickup(WeaponInstance *pWeapon, bool appendAction) {
 
 /*!
  * Sets or append action to enter the given vehicle.
+ * \param origin
  * \param pVehicle
  * \param appendAction If true action is append after all existing actions.
  */
-void PedInstance::addActionEnterVehicle(Vehicle *pVehicle, bool appendAction) {
+void PedInstance::addActionEnterVehicle(fs_actions::CreatOrigin origin, Vehicle *pVehicle, bool appendAction) {
     // First go to vehicle
-    fs_actions::WalkAction *action = new fs_actions::WalkAction(fs_actions::kOrigUser, (ShootableMapObject *) pVehicle);
+    fs_actions::WalkAction *action = new fs_actions::WalkAction(origin, (ShootableMapObject *) pVehicle);
     addMovementAction(action, appendAction);
     // Then get in
-    fs_actions::EnterVehicleAction *enterAct = new fs_actions::EnterVehicleAction(pVehicle);
+    fs_actions::EnterVehicleAction *enterAct = new fs_actions::EnterVehicleAction(origin, pVehicle);
     addMovementAction(enterAct, true);
 }