Beispiel #1
0
        public Vector3 XXXSteerToEvadeAllDefenders()
        {
            // sum up weighted evasion
            Vector3 evade = Vector3.Zero;

            for (int i = 0; i < Globals.CtfEnemyCount; i++)
            {
                CtfEnemy e         = Globals.CtfEnemies[i];
                Vector3  eOffset   = e.Position - Position;
                float    eDistance = eOffset.Length();

                // xxx maybe this should take into account e's heading? xxx
                float   timeEstimate = 0.5f * eDistance / e.Speed;               //xxx
                Vector3 eFuture      = e.PredictFuturePosition(timeEstimate);

                // annotation
                annotation.CircleXZ(e.Radius, eFuture, Globals.EvadeColor, 20);

                // steering to flee from eFuture (enemy's future position)
                Vector3 flee = xxxSteerForFlee(eFuture);

                float eForwardDistance = Vector3.Dot(Forward, eOffset);
                float behindThreshold  = Radius * -2;

                float distanceWeight = 4 / eDistance;
                float forwardWeight  = ((eForwardDistance > behindThreshold) ? 1.0f : 0.5f);

                Vector3 adjustedFlee = flee * distanceWeight * forwardWeight;

                evade += adjustedFlee;
            }
            return(evade);
        }
Beispiel #2
0
        public Vector3 SteerToEvadeAllDefenders()
        {
            Vector3 evade        = Vector3.Zero;
            float   goalDistance = Vector3.Distance(Globals.HomeBaseCenter, Position);

            // sum up weighted evasion
            for (int i = 0; i < Globals.CtfEnemyCount; i++)
            {
                CtfEnemy e         = Globals.CtfEnemies[i];
                Vector3  eOffset   = e.Position - Position;
                float    eDistance = eOffset.Length();

                float eForwardDistance = Vector3.Dot(Forward, eOffset);
                float behindThreshold  = Radius * 2;
                bool  behind           = eForwardDistance < behindThreshold;
                if ((!behind) || (eDistance < 5))
                {
                    if (eDistance < (goalDistance * 1.2))                     //xxx
                    {
                        // const float timeEstimate = 0.5f * eDistance / e.speed;//xxx
                        float   timeEstimate = 0.15f * eDistance / e.Speed;                      //xxx
                        Vector3 future       = e.PredictFuturePosition(timeEstimate);

                        annotation.CircleXZ(e.Radius, future, Globals.EvadeColor, 20);                         // xxx

                        Vector3 offset  = future - Position;
                        Vector3 lateral = Vector3Helpers.PerpendicularComponent(offset, Forward);
                        float   d       = lateral.Length();
                        float   weight  = -1000 / (d * d);
                        evade += (lateral / d) * weight;
                    }
                }
            }
            return(evade);
        }
Beispiel #3
0
        // is there a clear path to the goal?
        public bool IsPathToGoalClear()
        {
            float sideThreshold   = Radius * 8.0f;
            float behindThreshold = Radius * 2.0f;

            Vector3 goalOffset    = Globals.HomeBaseCenter - Position;
            float   goalDistance  = goalOffset.Length();
            Vector3 goalDirection = goalOffset / goalDistance;

            bool goalIsAside = IsAside(Globals.HomeBaseCenter, 0.5f);

            // for annotation: loop over all and save result, instead of early return
            bool xxxReturn = true;

            // loop over enemies
            for (int i = 0; i < Globals.CtfEnemyCount; i++)
            {
                // short name for this enemy
                CtfEnemy e                = Globals.CtfEnemies[i];
                float    eDistance        = Vector3.Distance(Position, e.Position);
                float    timeEstimate     = 0.3f * eDistance / e.Speed;          //xxx
                Vector3  eFuture          = e.PredictFuturePosition(timeEstimate);
                Vector3  eOffset          = eFuture - Position;
                float    alongCorridor    = Vector3.Dot(goalDirection, eOffset);
                bool     inCorridor       = ((alongCorridor > -behindThreshold) && (alongCorridor < goalDistance));
                float    eForwardDistance = Vector3.Dot(Forward, eOffset);

                // xxx temp move this up before the conditionals
                annotation.CircleXZ(e.Radius, eFuture, Globals.ClearPathColor, 20);                 //xxx

                // consider as potential blocker if within the corridor
                if (inCorridor)
                {
                    Vector3 perp           = eOffset - (goalDirection * alongCorridor);
                    float   acrossCorridor = perp.Length();
                    if (acrossCorridor < sideThreshold)
                    {
                        // not a blocker if behind us and we are perp to corridor
                        float eFront = eForwardDistance + e.Radius;

                        //annotation.annotationLine (position, forward*eFront, gGreen); // xxx
                        //annotation.annotationLine (e.position, forward*eFront, gGreen); // xxx

                        // xxx
                        // std::ostringstream message;
                        // message << "eFront = " << std::setprecision(2)
                        //         << std::setiosflags(std::ios::fixed) << eFront << std::ends;
                        // draw2dTextAt3dLocation (*message.str(), eFuture, gWhite);

                        bool eIsBehind             = eFront < -behindThreshold;
                        bool eIsWayBehind          = eFront < (-2 * behindThreshold);
                        bool safeToTurnTowardsGoal = ((eIsBehind && goalIsAside) || eIsWayBehind);

                        if (!safeToTurnTowardsGoal)
                        {
                            // this enemy blocks the path to the goal, so return false
                            annotation.Line(Position, e.Position, Globals.ClearPathColor);
                            // return false;
                            xxxReturn = false;
                        }
                    }
                }
            }

            // no enemies found along path, return true to indicate path is clear
            // clearPathAnnotation (sideThreshold, behindThreshold, goalDirection);
            // return true;
            //if (xxxReturn)
            ClearPathAnnotation(sideThreshold, behindThreshold, goalDirection);
            return(xxxReturn);
        }