Ticket #3337: PathFixTempr.diff

File PathFixTempr.diff, 4.1 KB (added by wraitii, 9 years ago)
  • source/simulation2/components/CCmpUnitMotion.cpp

     
    733733        m_PathState = PATHSTATE_FOLLOWING;
    734734        StartSucceeded();
    735735    }
    736     else if (m_PathState == PATHSTATE_WAITING_REQUESTING_SHORT)
     736    else if (m_PathState == PATHSTATE_WAITING_REQUESTING_SHORT || m_PathState == PATHSTATE_FOLLOWING_REQUESTING_SHORT)
    737737    {
    738738        m_ShortPath = path;
    739 
    740         // If there's no waypoints then we couldn't get near the target
    741         if (m_ShortPath.m_Waypoints.empty())
    742         {
    743             // If we're globally following a long path, try to remove the next waypoint, it might be obstructed
    744             if (m_LongPath.m_Waypoints.size() > 1)
    745                 m_LongPath.m_Waypoints.pop_back();
    746             else if (!IsFormationMember())
    747             {
    748                 StartFailed();
    749                 return;
    750             }
    751             else
    752             {
    753                 m_Moving = false;
    754                 CMessageMotionChanged msg(true, true);
    755                 GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
    756             }
    757         }
    758 
     739               
    759740        CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle());
    760741        if (!cmpPosition || !cmpPosition->IsInWorld())
    761742        {
     
    762743            StartFailed();
    763744            return;
    764745        }
    765 
     746       
     747       
    766748        // Now we've got a short path that we can follow
    767         m_PathState = PATHSTATE_FOLLOWING;
     749       
     750        if (!m_ShortPath.m_Waypoints.empty())
     751        {
     752            m_PathState = PATHSTATE_FOLLOWING;
     753            StartSucceeded();
     754        }
     755        else
     756        {
     757            CMessageMotionChanged msg(false, true);
     758            GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
     759            m_ExpectedPathTicket = 0;
     760            m_ShortPath.m_Waypoints.clear();
     761           
     762            CmpPtr<ICmpObstruction> cmpObstruction(GetEntityHandle());
     763            if (cmpObstruction)
     764                cmpObstruction->SetMovingFlag(false);
    768765
    769         StartSucceeded();
     766            m_PathState = PATHSTATE_FOLLOWING_REQUESTING_SHORT;
     767           
     768            // With the new long pathfinder, the short pathfinder is used to get around units
     769            // as those are not considered. This means we can effectively get stuck because of some units
     770            // (sometimes the short pathfinder would have to go beyond its box to find a path and fails)
     771            // While we wait for a better solution, we'll do two things:
     772            // -Retry on the next turn: it might have been a moving unit so we'll be good to go
     773            // -Tell idle units to go away. Hopefully that will clear a path.
     774           
     775            CmpPtr<ICmpRangeManager> cmpRangeManager(GetSystemEntity());
     776            CmpPtr<ICmpOwnership> cmpOwnership(GetEntityHandle());
     777            if (cmpRangeManager && cmpOwnership)
     778            {
     779                std::vector<int> Owners;
     780                Owners.push_back(cmpOwnership->GetOwner());
     781                std::vector<entity_id_t> idleUnits = cmpRangeManager->ExecuteQueryAroundPos(cmpPosition->GetPosition2D(), entity_pos_t::Zero(), entity_pos_t::FromInt(10), Owners, IID_UnitMotion);
     782                for (entity_id_t ent : idleUnits)
     783                {
     784                    if (ent == GetEntityId())
     785                        continue;
     786                    CmpPtr<ICmpUnitMotion> cmpUnitMotion(GetSimContext(), ent);
     787                    if (cmpUnitMotion && !cmpUnitMotion->IsMoving())
     788                        cmpUnitMotion->MoveToPointRange(cmpPosition->GetPosition2D().X, cmpPosition->GetPosition2D().Y, entity_pos_t::FromInt(10), entity_pos_t::FromInt(16));
     789                }
     790            }
     791        }
    770792    }
    771793    else if (m_PathState == PATHSTATE_FOLLOWING_REQUESTING_LONG)
    772794    {
     
    794816        // old path while this request is active, so it'll be slightly incorrect
    795817        // by the time the request has completed)
    796818    }
    797     else if (m_PathState == PATHSTATE_FOLLOWING_REQUESTING_SHORT)
    798     {
    799         // Replace the current path with the new one
    800         m_ShortPath = path;
    801 
    802         // If there's no waypoints then we couldn't get near the target
    803         if (m_ShortPath.m_Waypoints.empty())
    804         {
    805             // We should stop moving (unless we're in a formation, in which
    806             // case we should continue following it)
    807             if (!IsFormationMember())
    808             {
    809                 MoveFailed();
    810                 return;
    811             }
    812             else
    813             {
    814                 m_Moving = false;
    815                 CMessageMotionChanged msg(false, true);
    816                 GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
    817             }
    818         }
    819 
    820         m_PathState = PATHSTATE_FOLLOWING;
    821     }
    822819    else
    823820    {
    824821        LOGWARNING("unexpected PathResult (%u %d %d)", GetEntityId(), m_State, m_PathState);