Example #1
0
        public override cVector3 force(cCritter pcritter)
        {
            cVector3 evadedirection, evadeforcevector;
            cCritter pclosestcritter = pcritter.OwnerBiota.pickClosestCritter <DataType>(pcritter,
                                                                                         _includechildclasses);

            //Case (1) No enemies to evade ----------------------------------------------
            if (pclosestcritter == null)               //NULL if there aren't any of these guys around
            {
                pcritter.restoreMaxspeed();            //Go back to my normal non-darting speed and bail.
                return(new cVector3(0.0f, 0.0f, 0.0f));
            }
            evadedirection = pclosestcritter.directionTo(pcritter);               /* Start with a unit vector that
                                                                                   * points	from my enemy towards me. */
            float cosangle = evadedirection * (pclosestcritter.Tangent);          /* Dot product of two
                                                                                   * unit vectors is the cosine of the angle between them.  I can use the cosine to figure
                                                                                   * out if the enemy is headed away from me (cosangle < 0) , generally towards me
                                                                                   * (cosangle > 0),	or directly towards me (cosangle near 1.0). */

            //Case (2) Closest enemy is moving away from me. ------------------------------
            if (cosangle < cForceClassEvade <DataType> .COSINEIGNOREANGLE) // If nearest enemy is moving away, relax.
            {
                pcritter.restoreMaxspeed();                                //Go back to my normal non-darting speed and bail.
                return(new cVector3(0.0f, 0.0f, 0.0f));
            }
            //Case (3a) Closest enemy is directly towards  me. ------------------------------
            if (cosangle > cForceClassEvade <DataType> .COSINESMALLANGLE)             /* If the nearest enemy is heading close
                                                                                       * to straight towards me, I shouldn't run straight away like a rabbit down a railorad
                                                                                       * track.  So in this case I'll head off at a 90 degree angle.  I'll use a	bit of the
                                                                                       * pointer as a "personality trait" to consistently act like a "righty" or a "lefty" in
                                                                                       * terms of which side of the railroad track I jump off of. */
            {
                evadedirection.turn(
                    ((cForceClassEvade <DataType> .TURNPERSONALITYBIT & pcritter.Personality) != 0)?
                    (float)Math.PI / 2
                        : (float)-Math.PI / 2);
            }
            //Case (3a and 3b) Closest enemy is moving towards me, directly or otherwise.
            pcritter.TempMaxSpeed = _dartspeedup * pcritter.MaxSpeedStandard;
            //Go faster while I'm darting away.
            evadeforcevector           = evadedirection * pcritter.MaxSpeed - pcritter.Velocity;
            evadeforcevector.Magnitude = _intensity;
            evadeforcevector          *= pcritter.Mass;
            return(evadeforcevector * _intensity);
        }