Ticket #1537: chasing.6.diff

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

     
    17061706                    // Check the target is still alive and attackable
    17071707                    if (this.TargetIsAlive(target) && this.CanAttack(target, this.order.data.forceResponse || null))
    17081708                    {
    1709                         // Check we can still reach the target
    1710                         if (this.CheckTargetAttackRange(target, IID_Attack, this.order.data.attackType))
     1709                        // If we are hunting, first update the target position of the gather order so we know where will be the killed animal
     1710                        if (this.order.data.hunting && this.orderQueue[1] && this.orderQueue[1].data.lastPos)
    17111711                        {
    1712                             // If we are hunting, first update the target position of the gather order so we know where will be the killed animal
    1713                             if (this.order.data.hunting && this.orderQueue[1] && this.orderQueue[1].data.lastPos)
     1712                            var cmpPosition = Engine.QueryInterface(this.order.data.target, IID_Position);
     1713                            if (cmpPosition && cmpPosition.IsInWorld())
    17141714                            {
    1715                                 var cmpPosition = Engine.QueryInterface(this.order.data.target, IID_Position);
    1716                                 if (cmpPosition && cmpPosition.IsInWorld())
    1717                                 {
    1718                                     // Store the initial position, so that we can find the rest of the herd later
    1719                                     if (!this.orderQueue[1].data.initPos)
    1720                                         this.orderQueue[1].data.initPos = this.orderQueue[1].data.lastPos;
    1721                                     this.orderQueue[1].data.lastPos = cmpPosition.GetPosition();
    1722                                     // We still know where the animal is, so we shouldn't give up before going there
    1723                                     this.orderQueue[1].data.secondTry = undefined;
    1724                                 }
     1715                                // Store the initial position, so that we can find the rest of the herd later
     1716                                if (!this.orderQueue[1].data.initPos)
     1717                                    this.orderQueue[1].data.initPos = this.orderQueue[1].data.lastPos;
     1718                                this.orderQueue[1].data.lastPos = cmpPosition.GetPosition();
     1719                                // We still know where the animal is, so we shouldn't give up before going there
     1720                                this.orderQueue[1].data.secondTry = undefined;
    17251721                            }
     1722                        }
    17261723
    1727                             var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
    1728                             this.lastAttacked = cmpTimer.GetTime() - msg.lateness;
     1724                        var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
     1725                        this.lastAttacked = cmpTimer.GetTime() - msg.lateness;
    17291726
    1730                             this.FaceTowardsTarget(target);
    1731                             var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
    1732                             cmpAttack.PerformAttack(this.order.data.attackType, target);
     1727                        this.FaceTowardsTarget(target);
     1728                        var cmpAttack = Engine.QueryInterface(this.entity, IID_Attack);
     1729                        cmpAttack.PerformAttack(this.order.data.attackType, target);
    17331730
     1731                       
     1732                        // Check we can still reach the target for the next attack
     1733                        if (this.CheckTargetAttackRange(target, IID_Attack, this.order.data.attackType))
     1734                        {
    17341735                            if (this.resyncAnimation)
    17351736                            {
    17361737                                this.SetAnimationSync(this.attackTimers.repeat, this.attackTimers.repeat);
  • binaries/data/mods/public/simulation/templates/template_unit_cavalry_ranged.xml

     
    1111      <Pierce>10.0</Pierce>
    1212      <Crush>0.0</Crush>
    1313      <MaxRange>16.0</MaxRange>
    14       <MinRange>0.0</MinRange>
     14      <MinRange>20.0</MinRange>
    1515      <ProjectileSpeed>25.0</ProjectileSpeed>
    1616      <PrepareTime>900</PrepareTime>
    1717      <RepeatTime>1500</RepeatTime>
  • binaries/data/mods/public/simulation/templates/template_unit_cavalry_ranged_archer.xml

     
    66      <Pierce>20.0</Pierce>
    77      <Crush>0.0</Crush>
    88      <MaxRange>56.0</MaxRange>
    9       <MinRange>0.0</MinRange>
    109      <ProjectileSpeed>75.0</ProjectileSpeed>
    1110      <PrepareTime>1200</PrepareTime>
    1211      <RepeatTime>2000</RepeatTime>
  • binaries/data/mods/public/simulation/templates/template_unit_cavalry_ranged_javelinist.xml

     
    66      <Pierce>25.0</Pierce>
    77      <Crush>0.0</Crush>
    88      <MaxRange>44</MaxRange>
    9       <MinRange>0.0</MinRange>
    109      <ProjectileSpeed>50.0</ProjectileSpeed>
    1110      <PrepareTime>1200</PrepareTime>
    1211      <RepeatTime>2000</RepeatTime>
  • source/simulation2/components/CCmpObstruction.cpp

     
    442442        return m_Tag;
    443443    }
    444444
     445    virtual bool GetPreviousObstructionSquare(ICmpObstructionManager::ObstructionSquare& out)
     446    {
     447        return GetObstructionSquare(out, true);
     448    }
     449
    445450    virtual bool GetObstructionSquare(ICmpObstructionManager::ObstructionSquare& out)
    446451    {
     452        return GetObstructionSquare(out, false);
     453    }
     454
     455    virtual bool GetObstructionSquare(ICmpObstructionManager::ObstructionSquare& out, bool previousPosition)
     456    {
    447457        CmpPtr<ICmpPosition> cmpPosition(GetEntityHandle());
    448458        if (!cmpPosition)
    449459            return false; // error
     
    455465        if (!cmpPosition->IsInWorld())
    456466            return false; // no obstruction square
    457467
    458         CFixedVector2D pos = cmpPosition->GetPosition2D();
     468        CFixedVector2D pos;
     469        if (previousPosition)
     470            pos = cmpPosition->GetPreviousPosition2D();
     471        else
     472            pos = cmpPosition->GetPosition2D();
    459473        if (m_Type == STATIC)
    460474            out = cmpObstructionManager->GetStaticShapeObstruction(pos.X, pos.Y, cmpPosition->GetRotation().Y, m_Size0, m_Size1);
    461475        else if (m_Type == UNIT)
  • source/simulation2/components/CCmpUnitMotion.cpp

     
    107107static const CColor OVERLAY_COLOUR_LONG_PATH(1, 1, 1, 1);
    108108static const CColor OVERLAY_COLOUR_SHORT_PATH(1, 0, 0, 1);
    109109
    110 static const entity_pos_t g_GoalDelta = entity_pos_t::FromInt(TERRAIN_TILE_SIZE)/4; // for extending the goal outwards/inwards a little bit
     110static const entity_pos_t g_GoalDelta = entity_pos_t::FromInt(TERRAIN_TILE_SIZE)/2; // for extending the goal outwards/inwards a little bit
    111111
    112112class CCmpUnitMotion : public ICmpUnitMotion
    113113{
     
    995995                        }
    996996                        else
    997997                        {
     998                            // check if target was reached in case of a moving target
     999                            CmpPtr<ICmpUnitMotion> cmpUnitMotion(GetSimContext(), m_TargetEntity);
     1000                            if
     1001                            (
     1002                                cmpUnitMotion &&
     1003                                cmpUnitMotion->IsMoving() &&
     1004                                MoveToTargetRange(m_TargetEntity, m_TargetMinRange, m_TargetMaxRange)
     1005                            )
     1006                                return;
     1007
    9981008                            // Not in formation, so just finish moving
    999 
    10001009                            StopMoving();
     1010                            m_State = STATE_IDLE;
     1011                            MoveSucceeded();
    10011012
    1002 
    10031013                            if (m_FacePointAfterMove)
    10041014                                FaceTowardsPointFromPos(pos, m_FinalGoal.x, m_FinalGoal.z);
    10051015                            // TODO: if the goal was a square building, we ought to point towards the
     
    15081518
    15091519        entity_pos_t distance = Geometry::DistanceToSquare(pos - CFixedVector2D(obstruction.x, obstruction.z), obstruction.u, obstruction.v, halfSize);
    15101520
    1511         if (distance < minRange)
     1521        // compare with previous obstruction
     1522        ICmpObstructionManager::ObstructionSquare previousObstruction;
     1523        cmpObstruction->GetPreviousObstructionSquare(previousObstruction);
     1524        entity_pos_t previousDistance = Geometry::DistanceToSquare(pos - CFixedVector2D(previousObstruction.x, previousObstruction.z), obstruction.u, obstruction.v, halfSize);
     1525
     1526        if (distance < minRange && previousDistance < minRange)
    15121527        {
    15131528            // Too close to the square - need to move away
    15141529
     
    15231538            goal.hw = obstruction.hw + delta;
    15241539            goal.hh = obstruction.hh + delta;
    15251540        }
    1526         else if (maxRange < entity_pos_t::Zero() || distance < maxRange)
     1541        else if (maxRange < entity_pos_t::Zero() || distance < maxRange || previousDistance < maxRange)
    15271542        {
    15281543            // We're already in range - no need to move anywhere
    15291544            if (m_FacePointAfterMove)
     
    15541569                    return false;
    15551570                }
    15561571
     1572                entity_pos_t previousCircleDistance = (pos - CFixedVector2D(previousObstruction.x, previousObstruction.z)).Length() - circleRadius;
     1573
     1574                if (previousCircleDistance < maxRange)
     1575                {
     1576                    // We're already in range - no need to move anywhere
     1577                    if (m_FacePointAfterMove)
     1578                        FaceTowardsPointFromPos(pos, goal.x, goal.z);
     1579                    return false;
     1580                }
     1581
     1582
    15571583                entity_pos_t goalDistance = maxRange - g_GoalDelta;
    15581584
    15591585                goal.type = ICmpPathfinder::Goal::CIRCLE;
     
    16261652        CFixedVector2D halfSize(obstruction.hw, obstruction.hh);
    16271653        entity_pos_t distance = Geometry::DistanceToSquare(pos - CFixedVector2D(obstruction.x, obstruction.z), obstruction.u, obstruction.v, halfSize);
    16281654
     1655        // compare with previous obstruction
     1656        ICmpObstructionManager::ObstructionSquare previousObstruction;
     1657        cmpObstruction->GetPreviousObstructionSquare(previousObstruction);
     1658        entity_pos_t previousDistance = Geometry::DistanceToSquare(pos - CFixedVector2D(previousObstruction.x, previousObstruction.z), obstruction.u, obstruction.v, halfSize);
     1659       
    16291660        // See if we're too close to the target square
    1630         if (distance < minRange)
     1661        if (distance < minRange && previousDistance < minRange)
    16311662            return false;
    16321663
    16331664        // See if we're close enough to the target square
    1634         if (maxRange < entity_pos_t::Zero() || distance <= maxRange)
     1665        if (maxRange < entity_pos_t::Zero() || distance <= maxRange || previousDistance <= maxRange)
    16351666            return true;
    16361667
    16371668        entity_pos_t circleRadius = halfSize.Length();
     
    16451676
    16461677            if (circleDistance <= maxRange)
    16471678                return true;
     1679            // also check circle around previous position
     1680            circleDistance = (pos - CFixedVector2D(previousObstruction.x, previousObstruction.z)).Length() - circleRadius;
     1681
     1682            if (circleDistance <= maxRange)
     1683                return true;
    16481684        }
    16491685
    16501686        return false;
     
    16551691        if (!cmpTargetPosition || !cmpTargetPosition->IsInWorld())
    16561692            return false;
    16571693
    1658         CFixedVector2D targetPos = cmpTargetPosition->GetPosition2D();
     1694        CFixedVector2D targetPos = cmpTargetPosition->GetPreviousPosition2D();
    16591695
    16601696        entity_pos_t distance = (pos - targetPos).Length();
    16611697
    1662         if (minRange <= distance && (maxRange < entity_pos_t::Zero() || distance <= maxRange))
    1663             return true;
    1664 
    1665         return false;
     1698        return minRange <= distance &&
     1699            (maxRange < entity_pos_t::Zero() || distance <= maxRange);
    16661700    }
    16671701}
    16681702
  • source/simulation2/components/ICmpObstruction.h

     
    4747     */
    4848    virtual bool GetObstructionSquare(ICmpObstructionManager::ObstructionSquare& out) = 0;
    4949
     50    /**
     51     * Same as the method above, but returns an obstruction shape for the previous turn
     52     */
     53    virtual bool GetPreviousObstructionSquare(ICmpObstructionManager::ObstructionSquare& out) = 0;
     54
    5055    virtual entity_pos_t GetUnitRadius() = 0;
    5156
    5257    virtual bool IsControlPersistent() = 0;