- Added ResetAction but no fully implemented
authorbenblan <benblan@3ce38193-f967-438d-acd5-fc4e68e0da95>
Fri, 25 Jul 2014 16:41:27 +0000 (16:41 +0000)
committerbenblan <benblan@3ce38193-f967-438d-acd5-fc4e68e0da95>
Fri, 25 Jul 2014 16:41:27 +0000 (16:41 +0000)
- Peds with no scenarios now walk randomly

freesynd/branches/rework-actions/src/ia/action.cpp
freesynd/branches/rework-actions/src/ia/actions.h
freesynd/branches/rework-actions/src/missionmanager.cpp
freesynd/branches/rework-actions/src/model/leveldata.h
freesynd/branches/rework-actions/src/pedmanager.cpp

index e7b7bfdc6371bce5f814c5a5e39b40a8ae051071..56ac88b33662cac54c788e0c16d8be384f739c31 100644 (file)
@@ -173,6 +173,15 @@ MovementAction(kActTypeWalk, origin) {
     targetState_ = PedInstance::pa_smWalking;
 }
 
+WalkToDirectionAction::WalkToDirectionAction(CreatOrigin origin) :
+MovementAction(kActTypeWalk, origin) {
+    maxDistanceToWalk_ = 0;
+    dest_.x = -1;
+    dest_.y = -1;
+    dest_.z = -1;
+    targetState_ = PedInstance::pa_smWalking;
+}
+
 void WalkToDirectionAction::doStart(Mission *pMission, PedInstance *pPed) {
     moveDirdesc_.clear();
     moveDirdesc_.bounce = true;
@@ -187,28 +196,45 @@ void WalkToDirectionAction::doStart(Mission *pMission, PedInstance *pPed) {
  */
 bool WalkToDirectionAction::doExecute(int elapsed, Mission *pMission, PedInstance *pPed) {
     bool endAction = false;
-    int diffx = dest_.x - pPed->tileX() * 256 - pPed->offX();
-    int diffy = dest_.y - pPed->tileY() * 256 - pPed->offY();
-
-    // In this case, max distance is the distance between ped and destination location
-    int maxDistanceToWalk = (int)sqrt((double)(diffx * diffx + diffy * diffy));
-
-    if (maxDistanceToWalk > 0) {
-        uint8 res = pPed->moveToDir(pMission, 
+    int distanceToWalk = 0;
+    if (dest_.x != -1) {
+        int diffx = dest_.x - pPed->tileX() * 256 - pPed->offX();
+        int diffy = dest_.y - pPed->tileY() * 256 - pPed->offY();
+
+        // In this case, distance is the distance between ped and destination location
+        distanceToWalk = (int)sqrt((double)(diffx * diffx + diffy * diffy));
+
+        if (distanceToWalk > 0) {
+            uint8 res = pPed->moveToDir(pMission, 
+                            elapsed,
+                            moveDirdesc_,
+                            -1,
+                            dest_.x, dest_.y,
+                            &distanceToWalk);
+
+            if (pPed->tileX() * 256 - pPed->offX() == dest_.x
+                && pPed->tileY() * 256 - pPed->offY() == dest_.y)
+                // TODO: add correct z or ignore it?
+            {
+                endAction = true;
+            }
+        } else {
+            endAction = true;
+        }
+    } else {
+        distanceToWalk = maxDistanceToWalk_ != 0 ? 
+                                maxDistanceToWalk_ - distWalked_ : 0;
+        pPed->moveToDir(pMission,
                         elapsed,
                         moveDirdesc_,
                         -1,
-                        dest_.x, dest_.y,
-                        &maxDistanceToWalk);
+                        -1, -1,
+                        &distanceToWalk, true);
 
-        if (pPed->tileX() * 256 - pPed->offX() == dest_.x
-            && pPed->tileY() * 256 - pPed->offY() == dest_.y)
-            // TODO: add correct z or ignore it?
-        {
-            endAction = true;
+        if (maxDistanceToWalk_ != 0) {
+            distWalked_ += distanceToWalk;
+            endAction = distWalked_ >= maxDistanceToWalk_;
         }
-    } else {
-        endAction = true;
     }
 
     if (endAction) {
@@ -254,10 +280,23 @@ bool TriggerAction::doExecute(int elapsed, Mission *pMission, PedInstance *pPed)
  * \param pPed The ped executing the action.
  */
 bool EscapeAction::doExecute(int elapsed, Mission *pMission, PedInstance *pPed) {
+    setSucceeded();
     pPed->escape();
     return true;
 }
 
+/*!
+ * 
+ * \param elapsed Time elapsed since last frame
+ * \param pMission Mission data
+ * \param pPed The ped executing the action.
+ */
+bool ResetScriptedAction::doExecute(int elapsed, Mission *pMission, PedInstance *pPed) {
+    setSucceeded();
+    printf("ResetScriptedAction : Not implemented\n");
+    return true;
+}
+
 /*!
  * Class constructor.
  * \param pTarget The ped to follow.
index cd428179d392cea7a847766bc1e5865a9f0f8833..9bd8b7e3359c5daa982a3fa943363e0288c2850d 100644 (file)
@@ -207,17 +207,19 @@ namespace fs_actions {
     };
 
     /*!
-     * This action is used to move a ped towards a given direction.
-     * Direction is either given directly or using a location.
-     * When direction is given directly, it is possible to specify a distance
+     * This action is used to move a ped towards a direction.
+     * Direction is either the one he's already pointing to or using a target location.
+     * When direction is given by ped's direction, it is possible to specify a distance
      * so that movement stops when ped travels that distance. 
      * When direction is given by a location, movement stops when
      * ped reaches that location.
      */
     class WalkToDirectionAction : public MovementAction {
     public:
-        //! Walt to direction given by point
+        //! Walk to direction given by point
         WalkToDirectionAction(CreatOrigin origin, const PathNode &pn);
+        //! Walk following ped's direction
+        WalkToDirectionAction(CreatOrigin origin);
 
         void setmaxDistanceToWalk(int distance) { maxDistanceToWalk_ = distance; }
     protected:
@@ -228,6 +230,8 @@ namespace fs_actions {
         toDefineXYZ dest_;
         /*! Structure to hold information while walking.*/
         DirMoveType moveDirdesc_;
+        /*! Count the distance the ped has walked since starting the action.*/
+        int distWalked_;
         int maxDistanceToWalk_;
     };
 
@@ -259,6 +263,17 @@ namespace fs_actions {
         bool doExecute(int elapsed, Mission *pMission, PedInstance *pPed);
     };
 
+    /*!
+     * This action is used in scripted action to reset all actions.
+     */
+    class ResetScriptedAction : public MovementAction {
+    public:
+        ResetScriptedAction():
+            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.
index 4e182745463dc121f36a49ea3cdec06a7536a30f..80742bde39e58f84630874b9c335dd43e4dbe904 100644 (file)
@@ -811,14 +811,14 @@ void MissionManager::createPeds(const LevelData::LevelDataAll &level_data, DataI
 }
 
 void MissionManager::createScriptedActionsForPed(Mission *pMission, DataIndex &di, const LevelData::LevelDataAll &level_data, PedInstance *pPed) {
-    const LevelData::People & pedref = level_data.people[pPed->id()];
-    uint16 offset_start = READ_LE_UINT16(pedref.offset_scenario_start);
+    const LevelData::People & peopleData = level_data.people[pPed->id()];
+    uint16 offset_start = READ_LE_UINT16(peopleData.offset_scenario_start);
     uint16 offset_nxt = offset_start;
     Vehicle *v = pPed->inVehicle();
-    bool notInVehicle = v == NULL;
+    bool isInVehicle = v != NULL;
 
-    // this field will hold the index of a potential trigger
-    int32 has_trigger = -1;
+    // This flag is used to add default actions if ped has no scenario
+    bool hasScenario = false;
 
 #ifdef _DEBUG
     if (offset_nxt) {
@@ -827,18 +827,9 @@ void MissionManager::createScriptedActionsForPed(Mission *pMission, DataIndex &d
 #endif
 
     while (offset_nxt) {
-        // sc.type
-        // 1 - walking/driving to pos, x,y defined
-        // 2 - vehicle to use and goto
-        // 3?(south africa)
-        // 5?(kenya)
-        // 6 (kenya) - ped offset when in vehicle, and? (TODO)
-        // 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
-        // 11 - protected target reached destination(kenya) (TODO properly)
+        
         LevelData::Scenarios sc = level_data.scenarios[offset_nxt / 8];
+        hasScenario = true;
         LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", ("At offset %d, type : %d", offset_nxt, sc.type))
 
         offset_nxt = READ_LE_UINT16(sc.next);
@@ -862,12 +853,12 @@ void MissionManager::createScriptedActionsForPed(Mission *pMission, DataIndex &d
                 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);
             }
-            if ((!notInVehicle) && offset_nxt == 0) {
-                printf("Scenario reset action\n");
-                //pPed->createActQResetActionQueue(as);
+            if (isInVehicle && offset_nxt == 0) {
+                LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Repeat driving scenario"))
+                pPed->addMovementAction(new fs_actions::ResetScriptedAction(), true);
             }
         } else if (sc.type == LevelData::kScenarioTypeUseVehicle) {
-            if (notInVehicle) {
+            if (!isInVehicle) {
                 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
@@ -888,14 +879,24 @@ void MissionManager::createScriptedActionsForPed(Mission *pMission, DataIndex &d
         } 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 == LevelData::kScenarioTypeReset) {
+            LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Reset actions"))
+            pPed->addMovementAction(new fs_actions::ResetScriptedAction(), true);
         } else if (sc.type == 10) {
             printf("Scenario type 10\n");
         } else {
             LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - unknown type %d", sc.type))
         }
-
+    } // end while
+
+    if (!hasScenario) {
+        // When ped has no scenario, check its state : if ped is walking then
+        // add a walking action so that ped can walk the map indefinitly
+        if (peopleData.state == LevelData::kPeopleStateWalking) {
+            pPed->addMovementAction(
+                new fs_actions::WalkToDirectionAction(fs_actions::kOrigDefault), 
+                true);
+        }
     }
 }
 
index 0191fe772949af6ff17cff5315867be3924183a1..0ebb2e313a681ff9c764aa41e8a845d9d2872b61 100644 (file)
@@ -84,7 +84,12 @@ namespace LevelData {
          * 0x0D and 0x0C are excluded from being loaded
          */
         uint8 location;
-        // 0x0 - standing, 0x10 - walking, 0x11 - dead
+        /*!
+         * This field gives information on the ped's state. Values are:
+         * 0x0 - standing
+         * 0x10 - walking
+         * 0x11 - dead
+         */
         uint8 state;
         uint8 unkn3[2];         // nothing changes when this changes
         uint8 index_base_anim[2];  //index in (HSTA-0.ANI)
@@ -273,11 +278,20 @@ namespace LevelData {
         uint8 tiley;
         // tile_z_ = tilez
         uint8 tilez;
-        /* 0x00 - unset scenario type, is found at start of array and end;
-        * 0x01 - has location, no object offset; 0x02 - has object offset, no
-        * location; 0x07 - data is not present (end marker?); 0x08 - has
-        * location, no object offset; 0x09 - data is not present (end marker?);
-        */
+        /*!
+         * Gives the type of scenario. Values are:
+         * 0x00 - unset scenario type, is found at start of array and end;
+         * 0x01 - walking/driving to pos, x,y defined, no object offset;
+         * 0x02 - vehicle to use and goto 
+         * 0x03 - ?(south africa)
+         * 0x05 - ?(kenya)
+         * 0x06 - (kenya) - ped offset when in vehicle, and? (TODO)
+         * 0x07 - assasinate target escaped, mission failed
+         * 0x08 - walking to pos, triggers on our agents in range, x,y defined
+         * 0x09 - repeat from start, actually this might be end of script
+         * 0x0A - train stops and waits
+         * 0x0B - protected target reached destination(kenya) (TODO properly)
+         */
         uint8 type;
     };
 
@@ -361,6 +375,12 @@ namespace LevelData {
     static const int kPeopleLocAboveWalkSurf = 0x0C;
     /*! Constant for field People::location : they are not visible/present on original map(on water located), purpose?*/
     static const int kPeopleLocNotVisible = 0x0D;
+
+    /*! Constant for field People::state : ped is walking.*/
+    static const int kPeopleStateWalking = 0x10;
+    /*! Constant for field People::state : ped is dead.*/
+    static const int kPeopleStateDead = 0x11;
+
     /*! 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.*/
@@ -368,6 +388,8 @@ namespace LevelData {
     /*! 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;
+    /*! Constant for field Scenario::type : Reset all scripted action.*/
+    static const int kScenarioTypeReset = 0x09;
 }
 
 #endif  // MODEL_LEVELDATA_H_
index 81486a594f7a1b40733b62dd9dcc5728e6295b6d..b251e5bd2b190dcf597737b0e1d16b9b354630c5 100644 (file)
@@ -169,7 +169,7 @@ PedInstance *PedManager::loadInstance(const LevelData::People & gamdata, uint16
     newped->setStartHealth(hp);
 
     newped->setDirection(gamdata.orientation);
-    if (gamdata.state == 0x11) {
+    if (gamdata.state == LevelData::kPeopleStateDead) {
         newped->setDrawnAnim(PedInstance::ad_DeadAnim);
         newped->setHealth(-1);
         newped->setStateMasks(PedInstance::pa_smDead);