Ticket #1537: chasing.diff

File chasing.diff, 6.2 KB (added by sanderd17, 10 years ago)
  • binaries/data/mods/public/simulation/components/UnitAI.js

     
    16611661                    var attackName = "attack_" + this.order.data.attackType.toLowerCase();
    16621662                    this.SelectAnimation(attackName, false, 1.0, "attack");
    16631663                    this.SetAnimationSync(prepare, this.attackTimers.repeat);
    1664                     this.StartTimer(prepare, this.attackTimers.repeat);
     1664                    // repeat timer faster than repeat time for the attack
     1665                    // as targets out-of-range also get detected in the timer loop
     1666                    // and the unit should respond fast to it to stop the animation in time
     1667                    this.StartTimer(prepare, Math.min(250,this.attackTimers.repeat));
    16651668                    // TODO: we should probably only bother syncing projectile attacks, not melee
    16661669
    16671670                    // If using a non-default prepare time, re-sync the animation when the timer runs.
  • source/simulation2/components/CCmpUnitMotion.cpp

     
    132132    bool m_FormationController;
    133133    fixed m_WalkSpeed, m_OriginalWalkSpeed; // in metres per second
    134134    fixed m_RunSpeed, m_OriginalRunSpeed;
     135    fixed m_TurnLength;
    135136    ICmpPathfinder::pass_class_t m_PassClass;
    136137    ICmpPathfinder::cost_class_t m_CostClass;
    137138
     
    297298        m_WalkSpeed = m_OriginalWalkSpeed = paramNode.GetChild("WalkSpeed").ToFixed();
    298299        m_Speed = m_WalkSpeed;
    299300        m_CurSpeed = fixed::Zero();
     301        m_TurnLength = fixed::Zero();
    300302
    301303        if (paramNode.GetChild("Run").IsOk())
    302304            m_RunSpeed = m_OriginalRunSpeed = paramNode.GetChild("Run").GetChild("Speed").ToFixed();
     
    350352
    351353        serialize.NumberFixed_Unbounded("speed", m_Speed);
    352354
     355        serialize.NumberFixed_Unbounded("turnLength", m_TurnLength);
     356
    353357        serialize.Bool("moving", m_Moving);
    354358        serialize.Bool("facePointAfterMove", m_FacePointAfterMove);
    355359
     
    379383        {
    380384            if (m_FormationController)
    381385            {
    382                 fixed dt = static_cast<const CMessageUpdate_MotionFormation&> (msg).turnLength;
    383                 Move(dt);
     386                m_TurnLength = static_cast<const CMessageUpdate_MotionFormation&> (msg).turnLength;
     387                Move(m_TurnLength);
    384388            }
    385389            break;
    386390        }
     
    388392        {
    389393            if (!m_FormationController)
    390394            {
    391                 fixed dt = static_cast<const CMessageUpdate_MotionUnit&> (msg).turnLength;
    392                 Move(dt);
     395                m_TurnLength = static_cast<const CMessageUpdate_MotionFormation&> (msg).turnLength;
     396                Move(m_TurnLength);
    393397            }
    394398            break;
    395399        }
     
    535539
    536540    void MoveSucceeded()
    537541    {
     542        // No longer moving, so speed is 0.
     543        m_CurSpeed = fixed::Zero();
    538544        m_Moving = false;
    539545
    540546        CmpPtr<ICmpObstruction> cmpObstruction(GetEntityHandle());
     
    541547        if (cmpObstruction)
    542548            cmpObstruction->SetMovingFlag(false);
    543549
    544         // No longer moving, so speed is 0.
    545         m_CurSpeed = fixed::Zero();
    546 
    547550        CMessageMotionChanged msg(false, false);
    548551        GetSimContext().GetComponentManager().PostMessage(GetEntityId(), msg);
    549552    }
     
    995998                        }
    996999                        else
    9971000                        {
     1001                            // check if target was reached in case of a moving target
     1002                            CmpPtr<ICmpUnitMotion> cmpUnitMotion(GetSimContext(), m_TargetEntity);
     1003                            if
     1004                            (
     1005                                cmpUnitMotion &&
     1006                                cmpUnitMotion->IsMoving() &&
     1007                                MoveToTargetRange(m_TargetEntity, m_TargetMinRange, m_TargetMaxRange)
     1008                            )
     1009                                return;
     1010
    9981011                            // Not in formation, so just finish moving
    999 
    10001012                            StopMoving();
    10011013
    1002 
    10031014                            if (m_FacePointAfterMove)
    10041015                                FaceTowardsPointFromPos(pos, m_FinalGoal.x, m_FinalGoal.z);
    10051016                            // TODO: if the goal was a square building, we ought to point towards the
     
    13131324
    13141325    CFixedVector2D pos = cmpPosition->GetPosition2D();
    13151326
     1327    entity_pos_t overShoot = fixed::Zero();
     1328
     1329    // if the target is also moving, take an overshoot into account
     1330    CmpPtr<ICmpUnitMotion> cmpUnitMotion(GetSimContext(), target);
     1331    if (cmpUnitMotion && cmpUnitMotion->IsMoving())
     1332        overShoot = m_CurSpeed.Multiply(m_TurnLength);
     1333
     1334    entity_pos_t origMaxRange = maxRange;
     1335    entity_pos_t origMinRange = minRange;
     1336    maxRange -= overShoot;
     1337    minRange += overShoot;
     1338    if (maxRange < fixed::Zero() && origMaxRange >= fixed::Zero())
     1339        maxRange = fixed::Zero();
     1340    if (maxRange > fixed::Zero() && minRange > maxRange)
     1341        minRange = maxRange;   
     1342
    13161343    ICmpPathfinder::Goal goal;
    13171344
    13181345    if (minRange.IsZero() && maxRange.IsZero())
     
    13811408    m_State = STATE_INDIVIDUAL_PATH;
    13821409    m_TargetEntity = target;
    13831410    m_TargetOffset = CFixedVector2D();
    1384     m_TargetMinRange = minRange;
    1385     m_TargetMaxRange = maxRange;
     1411    m_TargetMinRange = origMinRange;
     1412    m_TargetMaxRange = origMaxRange;
    13861413    m_FinalGoal = goal;
    13871414
    13881415    BeginPathing(pos, goal);
     
    14571484bool CCmpUnitMotion::MoveToTargetRange(entity_id_t target, entity_pos_t minRange, entity_pos_t maxRange)
    14581485{
    14591486    PROFILE("MoveToTargetRange");
     1487    entity_pos_t overShoot = fixed::Zero();
    14601488
     1489    // if the target is als moving, take an overshoot into account
     1490    CmpPtr<ICmpUnitMotion> cmpUnitMotion(GetSimContext(), target);
     1491    if (cmpUnitMotion && cmpUnitMotion->IsMoving())
     1492        overShoot = m_CurSpeed.Multiply(m_TurnLength);
     1493
     1494    entity_pos_t origMaxRange = maxRange;
     1495    entity_pos_t origMinRange = minRange;
     1496    maxRange -= overShoot;
     1497    minRange += overShoot;
     1498    if (maxRange < fixed::Zero() && origMaxRange >= fixed::Zero())
     1499        maxRange = fixed::Zero();
     1500    if (maxRange > fixed::Zero() && minRange > maxRange)
     1501        minRange = maxRange;   
     1502
    14611503    CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle());
    14621504    if (!cmpPosition || !cmpPosition->IsInWorld())
    14631505        return false;
     
    15781620        m_State = STATE_INDIVIDUAL_PATH;
    15791621        m_TargetEntity = target;
    15801622        m_TargetOffset = CFixedVector2D();
    1581         m_TargetMinRange = minRange;
    1582         m_TargetMaxRange = maxRange;
     1623        m_TargetMinRange = origMinRange;
     1624        m_TargetMaxRange = origMaxRange;
    15831625        m_FinalGoal = goal;
    15841626
    15851627        BeginPathing(pos, goal);
     
    15961638
    15971639        CFixedVector2D targetPos = cmpTargetPosition->GetPosition2D();
    15981640
    1599         return MoveToPointRange(targetPos.X, targetPos.Y, minRange, maxRange, target);
     1641        return MoveToPointRange(targetPos.X, targetPos.Y, origMinRange, origMaxRange, target);
    16001642    }
    16011643}
    16021644