Ticket #3790: remove_planning.patch

File remove_planning.patch, 10.6 KB (added by Itms, 8 years ago)
  • source/simulation2/components/CCmpUnitMotion.cpp

     
    1 /* Copyright (C) 2015 Wildfire Games.
     1/* Copyright (C) 2016 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
     
    109109static const CColor OVERLAY_COLOR_LONG_PATH(1, 1, 1, 1);
    110110static const CColor OVERLAY_COLOR_SHORT_PATH(1, 0, 0, 1);
    111111
    112 struct SUnitMotionPlanning
    113 {
    114     WaypointPath nextStepShortPath; // if !nextStepClean, store a short path for the next step here
    115     u32 expectedPathTicket;
    116     bool nextStepClean; // is there any obstruction between the next two long waypoints?
    117 
    118     SUnitMotionPlanning() : expectedPathTicket(0), nextStepClean(true) {}
    119 };
    120 
    121 /**
    122  * Serialization helper template for SUnitMotionPlanning
    123  */
    124 struct SerializeUnitMotionPlanning
    125 {
    126     template<typename S>
    127     void operator()(S& serialize, const char* UNUSED(name), SUnitMotionPlanning& value)
    128     {
    129         SerializeVector<SerializeWaypoint>()(serialize, "next step short path", value.nextStepShortPath.m_Waypoints);
    130         serialize.NumberU32_Unbounded("expected path ticket", value.expectedPathTicket);
    131         serialize.Bool("next step clean", value.nextStepClean);
    132     }
    133 };
    134 
    135112class CCmpUnitMotion : public ICmpUnitMotion
    136113{
    137114public:
     
    264241
    265242    // Motion planning
    266243    u8 m_Tries; // how many tries we've done to get to our current Final Goal.
    267     SUnitMotionPlanning m_Planning;
    268244
    269245    PathGoal m_FinalGoal;
    270246
     
    336312        m_ExpectedPathTicket = 0;
    337313
    338314        m_Tries = 0;
    339         m_Planning = SUnitMotionPlanning();
    340        
     315
    341316        m_TargetEntity = INVALID_ENTITY;
    342317
    343318        m_FinalGoal.type = PathGoal::POINT;
     
    377352        SerializeVector<SerializeWaypoint>()(serialize, "long path", m_LongPath.m_Waypoints);
    378353        SerializeVector<SerializeWaypoint>()(serialize, "short path", m_ShortPath.m_Waypoints);
    379354
    380         SerializeUnitMotionPlanning()(serialize, "planning", m_Planning);
    381 
    382355        SerializeGoal()(serialize, "goal", m_FinalGoal);
    383356    }
    384357
     
    599572        CmpPtr<ICmpObstruction> cmpObstruction(GetEntityHandle());
    600573        if (cmpObstruction)
    601574            cmpObstruction->SetMovingFlag(true);
    602        
     575
    603576        m_Moving = true;
    604        
     577
    605578        CMessageMotionChanged msg(true, false);
    606579        GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
    607580    }
     
    634607    void Move(fixed dt);
    635608
    636609    /**
    637      * Analyze our current path, and check if we expect to be obstructed soon
    638      * If yes, try to anticipate.
    639      * TODO: remove this and use a more general "pushing" manager.
    640      */
    641     void PlanNextStep(const CFixedVector2D& pos, const CFixedVector2D& currentOffset);
    642 
    643     /**
    644610     * Decide whether to approximate the given range from a square target as a circle,
    645611     * rather than as a square.
    646612     */
     
    697663     * noTarget is true only when used inside tryGoingStraightToTargetEntity,
    698664     * in which case we do not want the target obstruction otherwise it would always fail
    699665     */
    700     ControlGroupMovementObstructionFilter GetObstructionFilter(bool forceAvoidMovingUnits = false, bool noTarget = false) const;
     666    ControlGroupMovementObstructionFilter GetObstructionFilter(bool noTarget = false) const;
    701667
    702668    /**
    703669     * Start moving to the given goal, from our current position 'from'.
     
    735701
    736702    m_Moving = false;
    737703
    738     if (ticket == m_Planning.expectedPathTicket)
    739     {
    740         // If no path was found, better cancel the planning
    741         if (path.m_Waypoints.empty())
    742             m_Planning = SUnitMotionPlanning();
    743 
    744         m_Planning.nextStepShortPath = path;
    745         return;
    746     }
    747 
    748704    // Ignore obsolete path requests
    749705    if (ticket != m_ExpectedPathTicket)
    750706        return;
     
    785741
    786742        if (cmpObstruction)
    787743            cmpObstruction->SetMovingFlag(true);
    788        
     744
    789745        m_Moving = true;
    790746    }
    791747    else if (m_PathState == PATHSTATE_WAITING_REQUESTING_SHORT || m_PathState == PATHSTATE_FOLLOWING_REQUESTING_SHORT)
     
    808764                GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
    809765                return;
    810766            }
    811            
     767
    812768            CMessageMotionChanged msg(false, false);
    813769            GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
    814770
     
    815771            CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle());
    816772            if (!cmpPosition || !cmpPosition->IsInWorld())
    817773                return;
    818            
     774
    819775            CFixedVector2D pos = cmpPosition->GetPosition2D();
    820776
    821777            if (ShouldConsiderOurselvesAtDestination(pos))
     
    829785
    830786        // else we could, so reset our number of tries.
    831787        m_Tries = 0;
    832        
     788
    833789        // Now we've got a short path that we can follow
    834790        if (!HasValidPath())
    835791            StartSucceeded();
     
    842798        m_Moving = true;
    843799    }
    844800    else
    845     {
    846801        LOGWARNING("unexpected PathResult (%u %d %d)", GetEntityId(), m_State, m_PathState);
    847     }
    848802}
    849803
    850804void CCmpUnitMotion::Move(fixed dt)
     
    926880
    927881        fixed timeLeft = dt;
    928882        fixed zero = fixed::Zero();
    929        
     883
    930884        while (timeLeft > zero)
    931885        {
    932886            // If we ran out of path, we have to stop
     
    976930                target = pos + offset;
    977931
    978932                if (cmpPathfinder->CheckMovement(GetObstructionFilter(), pos.X, pos.Y, target.X, target.Y, m_Clearance, m_PassClass))
    979                 {
    980                     PlanNextStep(pos, offset);
    981933                    pos = target;
    982                     break;
    983                 }
    984934                else
    985                 {
    986                     // Error - path was obstructed
    987                     wasObstructed = true;
    988                     break;
    989                 }
     935                    wasObstructed = true; // Error - path was obstructed
     936
     937                break;
    990938            }
    991939        }
    992940
     
    994942        if (pos != initialPos)
    995943        {
    996944            CFixedVector2D offset = pos - initialPos;
    997            
     945
    998946            // Face towards the target
    999947            entity_angle_t angle = atan2_approx(offset.X, offset.Y);
    1000948            cmpPosition->MoveAndTurnTo(pos.X,pos.Y, angle);
     
    1002950            // Calculate the mean speed over this past turn.
    1003951            m_CurSpeed = cmpPosition->GetDistanceTravelled() / dt;
    1004952        }
    1005        
     953
    1006954        if (wasObstructed)
    1007955        {
    1008956            // Oops, we hit something (very likely another unit).
    1009957            // This is when we might easily get stuck wrongly.
    1010            
     958
    1011959            // check if we've arrived.
    1012960            if (ShouldConsiderOurselvesAtDestination(pos))
    1013961                return;
    1014            
     962
    1015963            // If we still have long waypoints, try and compute a short path
    1016964            // This will get us around units, amongst others.
    1017965            // However in some cases a long waypoint will be in located in the obstruction of
     
    1032980                    square.z = m_LongPath.m_Waypoints.back().z;
    1033981                    std::vector<entity_id_t> unitOnGoal;
    1034982                    // don't ignore moving units as those might be units like us, ie not really moving.
    1035                     cmpObstructionManager->GetUnitsOnObstruction(square, unitOnGoal, GetObstructionFilter(false, false), true);
     983                    cmpObstructionManager->GetUnitsOnObstruction(square, unitOnGoal, GetObstructionFilter(), true);
    1036984                    if (!unitOnGoal.empty())
    1037985                        m_LongPath.m_Waypoints.pop_back();
    1038986                }
     
    11191067    }
    11201068}
    11211069
    1122 void CCmpUnitMotion::PlanNextStep(const CFixedVector2D& pos, const CFixedVector2D& currentOffset)
    1123 {
    1124     if (m_LongPath.m_Waypoints.empty())
    1125         return;
    1126    
    1127     CmpPtr<ICmpPathfinder> cmpPathfinder(GetSystemEntity());
    1128     CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSystemEntity());
    1129     if (!cmpPathfinder || !cmpObstructionManager)
    1130         return;
    1131    
    1132     m_Planning = SUnitMotionPlanning();
    1133    
    1134     // see 2 turns in advance, otherwise this would start to lag in MP
    1135     CFixedVector2D futurePos = pos + currentOffset*2;
    1136    
    1137     // Don't actually use CheckMovement since we want to check against units only, we assume the rest is taken care of.
    1138     if (!cmpObstructionManager->TestLine(GetObstructionFilter(true, false), pos.X, pos.Y, futurePos.X, futurePos.Y, m_Clearance, true))
    1139         return;
    1140    
    1141     // we will run into a static unit obstruction. Try to shortpath around it.
    1142     PathGoal goal;
    1143     if (m_LongPath.m_Waypoints.size() > 1 || m_FinalGoal.DistanceToPoint(pos) > LONG_PATH_MIN_DIST)
    1144         goal = { PathGoal::POINT, m_LongPath.m_Waypoints.back().x, m_LongPath.m_Waypoints.back().z };
    1145     else
    1146     {
    1147         UpdateFinalGoal();
    1148         goal = m_FinalGoal;
    1149         m_LongPath.m_Waypoints.clear();
    1150         CFixedVector2D target = goal.NearestPointOnGoal(pos);
    1151         m_LongPath.m_Waypoints.emplace_back(Waypoint{ target.X, target.Y });
    1152     }
    1153     RequestShortPath(pos, goal, false);
    1154     m_PathState = PATHSTATE_FOLLOWING_REQUESTING_SHORT;
    1155 }
    1156 
    11571070bool CCmpUnitMotion::ComputeTargetPosition(CFixedVector2D& out)
    11581071{
    11591072    if (m_TargetEntity == INVALID_ENTITY)
     
    12301143    CFixedVector2D goalPos = goal.NearestPointOnGoal(from);
    12311144
    12321145    // Check if there's any collisions on that route
    1233     if (!cmpPathfinder->CheckMovement(GetObstructionFilter(false, true), from.X, from.Y, goalPos.X, goalPos.Y, m_Clearance, m_PassClass))
     1146    if (!cmpPathfinder->CheckMovement(GetObstructionFilter(true), from.X, from.Y, goalPos.X, goalPos.Y, m_Clearance, m_PassClass))
    12341147        return false;
    12351148
    12361149    // That route is okay, so update our path
     
    13091222{
    13101223    if (m_TargetEntity != INVALID_ENTITY || m_FinalGoal.DistanceToPoint(from) > SHORT_PATH_GOAL_RADIUS)
    13111224        return false;
    1312    
     1225
    13131226    StopMoving();
    13141227    MoveSucceeded();
    1315        
     1228
    13161229    if (m_FacePointAfterMove)
    13171230        FaceTowardsPointFromPos(from, m_FinalGoal.x, m_FinalGoal.z);
    13181231    return true;
     
    13651278    }
    13661279}
    13671280
    1368 ControlGroupMovementObstructionFilter CCmpUnitMotion::GetObstructionFilter(bool forceAvoidMovingUnits, bool noTarget) const
     1281ControlGroupMovementObstructionFilter CCmpUnitMotion::GetObstructionFilter(bool noTarget) const
    13691282{
    13701283    entity_id_t group = noTarget ? m_TargetEntity : GetGroup();
    1371     return ControlGroupMovementObstructionFilter(forceAvoidMovingUnits || ShouldAvoidMovingUnits(), group);
     1284    return ControlGroupMovementObstructionFilter(ShouldAvoidMovingUnits(), group);
    13721285}
    13731286
    13741287
     
    13771290{
    13781291    // reset our state for sanity.
    13791292    m_ExpectedPathTicket = 0;
    1380    
     1293
    13811294    CmpPtr<ICmpObstruction> cmpObstruction(GetEntityHandle());
    13821295    if (cmpObstruction)
    13831296        cmpObstruction->SetMovingFlag(false);
    1384    
     1297
    13851298    m_Moving = false;
    13861299
    13871300    m_PathState = PATHSTATE_NONE;
     
    14701383        searchRange = std::min(goal.hw, SHORT_PATH_MIN_SEARCH_RANGE * 2);
    14711384    if (searchRange > SHORT_PATH_MAX_SEARCH_RANGE)
    14721385        searchRange = SHORT_PATH_MAX_SEARCH_RANGE;
    1473    
     1386
    14741387    m_ExpectedPathTicket = cmpPathfinder->ComputeShortPathAsync(from.X, from.Y, m_Clearance, searchRange, goal, m_PassClass, avoidMovingUnits, GetGroup(), GetEntityId());
    14751388}
    14761389
     
    15591472    CmpPtr<ICmpObstructionManager> cmpObstructionManager(GetSystemEntity());
    15601473    ICmpObstructionManager::ObstructionSquare obstruction;
    15611474//TODO  if (cmpObstructionManager)
    1562 //      hasObstruction = cmpObstructionManager->FindMostImportantObstruction(GetObstructionFilter(true), x, z, m_Radius, obstruction);
     1475//      hasObstruction = cmpObstructionManager->FindMostImportantObstruction(GetObstructionFilter(), x, z, m_Radius, obstruction);
    15631476
    15641477    if (minRange.IsZero() && maxRange.IsZero() && hasObstruction)
    15651478    {