Пример #1
0
        public virtual IDictionary BuildNonGenericMapInstance(MapObjectInfo mapObjectInfo, Type t)
        {
            System.Collections.Generic.IDictionary <AbstractObjectInfo, AbstractObjectInfo> map = mapObjectInfo.GetMap();
            IDictionary newMap;

            try
            {
                newMap = (IDictionary)System.Activator.CreateInstance(t);
            }
            catch (System.Exception e)
            {
                throw new ODBRuntimeException(NeoDatisError.MapInstanciationError.AddParameter(map.GetType().FullName), e);
            }
            int i = 0;

            System.Collections.Generic.IEnumerator <AbstractObjectInfo> iterator = map.Keys.GetEnumerator();
            AbstractObjectInfo key = null;

            while (iterator.MoveNext())
            {
                key = iterator.Current;
                object realKey   = BuildOneInstance(key);
                object realValue = BuildOneInstance(map[key]);
                newMap[realKey] = realValue;
            }
            return(newMap);
        }
Пример #2
0
        public virtual object BuildGenericMapInstance(MapObjectInfo mapObjectInfo, Type t)
        {
            System.Collections.Generic.IDictionary <AbstractObjectInfo, AbstractObjectInfo> map = mapObjectInfo.GetMap();
            Type   genericType = t.GetGenericTypeDefinition();
            object newMap      = null;

            try
            {
                newMap = System.Activator.CreateInstance(t);
            }
            catch (System.Exception e)
            {
                Console.WriteLine(e);
                throw new ODBRuntimeException(NeoDatisError.MapInstanciationError.AddParameter(map.GetType().FullName), e);
            }

            int i = 0;

            System.Collections.Generic.IEnumerator <AbstractObjectInfo> iterator = map.Keys.GetEnumerator();
            AbstractObjectInfo key    = null;
            MethodInfo         method = t.GetMethod("Add", t.GetGenericArguments());

            while (iterator.MoveNext())
            {
                key = iterator.Current;
                object realKey   = BuildOneInstance(key);
                object realValue = BuildOneInstance(map[key]);
                method.Invoke(newMap, new object[] { realKey, realValue });
            }
            return(newMap);
        }
        /// <summary>Checks if something in the Map has changed, if yes, stores the change</summary>
        /// <param name="nnoi1">
        /// The first Object meta representation (nnoi =
        /// NonNativeObjectInfo)
        /// </param>
        /// <param name="nnoi2">The second object meta representation</param>
        /// <param name="fieldIndex">The field index that this map represents</param>
        /// <param name="moi1">The Meta representation of the map 1 (moi = MapObjectInfo)</param>
        /// <param name="moi2">The Meta representation of the map 2</param>
        /// <param name="objectRecursionLevel"></param>
        /// <returns>true if the 2 map representations are different</returns>
        private bool ManageMapChanges(NonNativeObjectInfo
                                      nnoi1, NonNativeObjectInfo nnoi2, int fieldId
                                      , MapObjectInfo moi1, MapObjectInfo
                                      moi2, int objectRecursionLevel)
        {
            if (true)
            {
                return(true);
            }
            IDictionary <AbstractObjectInfo
                         , AbstractObjectInfo> map1 = moi1.GetMap();
            IDictionary <AbstractObjectInfo
                         , AbstractObjectInfo> map2 = moi2.GetMap();

            if (map1.Count != map2.Count)
            {
                System.Text.StringBuilder buffer = new System.Text.StringBuilder();
                buffer.Append("Map size has changed oldsize=").Append(map1.Count).Append("/newsize="
                                                                                         ).Append(map2.Count);
                StoreChangedObject(nnoi1, nnoi2, fieldId, moi1, moi2, buffer.ToString(), objectRecursionLevel
                                   );
                return(true);
            }
            IEnumerator <AbstractObjectInfo
                         > keys1 = map1.Keys.GetEnumerator();
            IEnumerator <AbstractObjectInfo
                         >     keys2  = map2.Keys.GetEnumerator();
            AbstractObjectInfo key1   = null;
            AbstractObjectInfo key2   = null;
            AbstractObjectInfo value1 = null;
            AbstractObjectInfo value2 = null;
            int index = 0;

            while (keys1.MoveNext())
            {
                keys2.MoveNext();
                key1 = keys1.Current;
                key2 = keys2.Current;
                bool keysHaveChanged = this.HasChanged(key1, key2, objectRecursionLevel);
                if (keysHaveChanged)
                {
                    StoreChangedObject(nnoi1, nnoi2, fieldId, key1, key2, "Map key index " + index +
                                       " has changed", objectRecursionLevel);
                    return(true);
                }
                value1 = map1[key1];
                value2 = map2[key2];
                bool valuesHaveChanged = this.HasChanged(value1, value2, objectRecursionLevel);
                if (valuesHaveChanged)
                {
                    StoreChangedObject(nnoi1, nnoi2, fieldId, value1, value2, "Map value index " + index
                                       + " has changed", objectRecursionLevel);
                    return(true);
                }
                index++;
            }
            return(false);
        }
Пример #4
0
 /// <summary>
 /// 0 = touch
 /// 1 = stay near
 /// 2 = neutral, basically ignore it (this is 0 to 1)
 /// 3 =  avoid
 /// 4 = attack
 /// </summary>
 /// <remarks>
 /// This default implementation is very simplistic.  It is meant to be overridden with ItemOptions.CameraHardCoded_ClassifyObject
 /// </remarks>
 public static double[] ClassifyObject(MapObjectInfo mapObject)
 {
     return(new[]
     {
         0d,
         0d,
         mapObject == null ? 0d : 1d,
         0d,
         0d,
     });
 }
Пример #5
0
        public virtual object BuildMapInstance(MapObjectInfo moi)
        {
            Type t = classPool.GetClass(moi.GetRealMapClassName());

            if (t.IsGenericType)
            {
                return(BuildGenericMapInstance(moi, t));
            }
            else
            {
                return(BuildNonGenericMapInstance(moi, t));
            }
        }
Пример #6
0
    /// <summary>
    /// Place an object on a grid tile
    /// </summary>
    /// <param name="objectTrans"></param>
    /// <param name="xCoord"></param>
    /// <param name="zCoord"></param>
    public static void PlaceObject(Transform objectTrans, int xCoord, int zCoord)
    {
        MapObjectInfo movedObject = objectTrans.GetComponent <MapObjectInfo>();

        if (movedObject.currentOccupyingTile != null)
        {
            movedObject.currentOccupyingTile.containingObject = null; // Erase it from the previous tile
        }

        sMapManager.currentMap[xCoord, zCoord].containingObject = objectTrans.gameObject;                                 // Assign the object to tile
        movedObject.currentOccupyingTile = sMapManager.currentMap[xCoord, zCoord];                                        // Update the tile this moved object is occuping
        objectTrans.position             = sMapManager.currentMap[xCoord, zCoord].transform.position + Vector3.up * 0.5f; // Move the object
    }
Пример #7
0
        private static double BuildField_NodeSprtAncestorMass(MapOctree[] ancestors, Point3D minRange, Point3D maxRange)
        {
            if (ancestors == null)
            {
                return(0d);
            }

            double retVal = 0d;

            for (int ancestorCntr = 0; ancestorCntr < ancestors.Length; ancestorCntr++)
            {
                if (ancestors[ancestorCntr].Items == null)
                {
                    continue;
                }

                for (int itemCntr = 0; itemCntr < ancestors[ancestorCntr].Items.Length; itemCntr++)
                {
                    MapObjectInfo item = ancestors[ancestorCntr].Items[itemCntr];

                    // Make sure the item is inside this cell
                    if (!Math3D.IsIntersecting_AABB_AABB(item.AABBMin, item.AABBMax, minRange, maxRange))
                    {
                        continue;
                    }

                    // Get the amount of the ancestor's shape that is inside this cell
                    double fromX = minRange.X < item.AABBMin.X ? item.AABBMin.X : minRange.X;
                    double toX   = maxRange.X > item.AABBMax.X ? item.AABBMax.X : maxRange.X;

                    double fromY = minRange.Y < item.AABBMin.Y ? item.AABBMin.Y : minRange.Y;
                    double toY   = maxRange.Y > item.AABBMax.Y ? item.AABBMax.Y : maxRange.Y;

                    double fromZ = minRange.Z < item.AABBMin.Z ? item.AABBMin.Z : minRange.Z;
                    double toZ   = maxRange.Z > item.AABBMax.Z ? item.AABBMax.Z : maxRange.Z;

                    // Get the percent that's inside compared to the whoe shape
                    double subVolume   = (toX - fromX) * (toY - fromY) * (toZ - fromZ);
                    double wholeVolume = (item.AABBMax.X - item.AABBMin.X) * (item.AABBMax.Y - item.AABBMin.Y) * (item.AABBMax.Z - item.AABBMin.Z);

                    double percent = subVolume / wholeVolume;

                    // Take that percent of the shape's mass
                    retVal += item.Mass * percent;
                }
            }

            return(retVal);
        }
Пример #8
0
        private static Vector3D GetMatchVelocityForce(MapObjectInfo mapObject, Vector3D velocity)
        {
            //Vector3D dif = mapObject.Velocity - velocity;     // this just causes the whole blob to have an average of zero
            Vector3D dif = mapObject.Velocity;

            //TODO: Have a gradient of velocity match based on distance.  So if this is really far away from the item, then the item
            //should have no influence

            return dif;
        }
Пример #9
0
        //private Tuple<Vector3D?, Vector3D?> GetSeekForce_1()
        //{
        //    #region velocity

        //    double maxSpeed = this.MaxSpeed;
        //    double maxAngSpeed = this.MaxAngularSpeed;

        //    Vector3D velocity = this.VelocityWorld;
        //    Vector3D angVelocity = this.PhysicsBody.AngularVelocity;

        //    Vector3D desiredVelocity = velocity + Math3D.GetRandomVector_Spherical(maxSpeed / 10);
        //    Vector3D desiredAngVelocity = angVelocity + Math3D.GetRandomVector_Spherical(maxAngSpeed / 10);

        //    desiredVelocity = CapVector(desiredVelocity, maxSpeed);
        //    desiredAngVelocity = CapVector(desiredAngVelocity, maxAngSpeed);

        //    #endregion

        //    #region acceleration

        //    double maxAccel = this.MaxAccel;
        //    double maxAngAccel = this.MaxAngularAccel;

        //    //TODO: Come up with better units for converting velocity to acceleration
        //    Vector3D accel = desiredAngVelocity - velocity;
        //    Vector3D angAccel = desiredAngVelocity - angVelocity;

        //    accel = CapVector(accel, maxAccel);
        //    angAccel = CapVector(angAccel, maxAngAccel);

        //    #endregion

        //    #region force

        //    // Multiply by mass to turn accel into force
        //    accel *= this.PhysicsBody.Mass;

        //    MassMatrix inertia = this.PhysicsBody.MassMatrix;
        //    double dot = Math.Abs(Vector3D.DotProduct(angAccel.ToUnit(), inertia.Inertia.ToUnit()));

        //    //TODO: Make sure this is right
        //    angAccel *= dot * inertia.Inertia.Length;

        //    #endregion

        //    return new Tuple<Vector3D?, Vector3D?>(accel, angAccel);
        //}

        //private Vector3D? GetStrokeForce_FIRST(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity)
        //{
        //    if (objectiveStroke == null)
        //    {
        //        return null;
        //    }

        //    // For now, just aim straight for the first point
        //    return (objectiveStroke.Points[0].Item1 - position).ToUnit(false) * this.MaxAccel;
        //}
        //private Vector3D? GetStrokeForce_HASREPULSE(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity)
        //{
        //    //const double CLOSEENOUGHRADIUSMULT = 2;
        //    //const double VELOCITYINFLUENCERADIUSMULT = 5;
        //    const double CLOSEENOUGHRADIUSMULT = 8;
        //    const double VELOCITYINFLUENCERADIUSMULT = 15;

        //    // Null stroke
        //    if (objectiveStroke == null)
        //    {
        //        lock (_currentStrokeLock) _currentlyChasingStroke = null;
        //        return null;
        //    }

        //    #region current stroke

        //    // Get currently chasing stroke

        //    CurrentChasingStroke currentStroke = null;
        //    lock (_currentStrokeLock)
        //    {
        //        currentStroke = _currentlyChasingStroke;
        //        if (currentStroke == null || currentStroke.Stroke.Token != objectiveStroke.Token)
        //        {
        //            currentStroke = new CurrentChasingStroke(objectiveStroke, ACCEL * 3);
        //            _currentlyChasingStroke = currentStroke;
        //        }
        //    }

        //    #endregion
        //    #region current index of stroke

        //    int currentIndex = currentStroke.CurrentIndex;
        //    Vector3D towardCurrentPoint;
        //    double towardCurrentPointLenSqr;

        //    while (true)
        //    {
        //        if (currentIndex >= currentStroke.Stroke.Points.Length)
        //        {
        //            // Already went through all the points
        //            return null;
        //        }

        //        // If too close to the current point, then advance to the next
        //        towardCurrentPoint = currentStroke.Stroke.Points[currentIndex].Item1 - position;
        //        towardCurrentPointLenSqr = towardCurrentPoint.LengthSquared;
        //        double closeEnoughDist = this.Radius * CLOSEENOUGHRADIUSMULT;

        //        if (towardCurrentPointLenSqr < closeEnoughDist * closeEnoughDist)
        //        {
        //            currentIndex++;
        //            currentStroke.CurrentIndex = currentIndex;
        //        }
        //        else
        //        {
        //            break;
        //        }
        //    }

        //    #endregion

        //    // Start with attraction to the current point
        //    Vector3D retVal = towardCurrentPoint.ToUnit(false) * this.MaxAccel;

        //    #region influence velocity

        //    // Add the desired velocity

        //    double velocityInfluenceDist = this.Radius * VELOCITYINFLUENCERADIUSMULT;

        //    if (towardCurrentPointLenSqr < velocityInfluenceDist * velocityInfluenceDist)
        //    {
        //        double percent = UtilityCore.GetScaledValue(1d, 0d, 0d, velocityInfluenceDist, Math.Sqrt(towardCurrentPointLenSqr));

        //        retVal += currentStroke.Stroke.Points[currentIndex].Item2 * percent;
        //    }

        //    #endregion
        //    #region repulse

        //    foreach (var repulse in currentStroke.UpcomingPoints[currentIndex])
        //    {
        //        Vector3D dirToPoint = position - repulse.Position;
        //        double lenSqr = dirToPoint.LengthSquared;

        //        if (lenSqr > repulse.EffectRadius * repulse.EffectRadius)
        //        {
        //            // Too far away to be influenced by this point
        //            continue;
        //        }

        //        if (lenSqr.IsNearZero())
        //        {
        //            retVal += Math3D.GetRandomVector_Spherical_Shell(repulse.Strength);
        //        }
        //        else
        //        {
        //            retVal += dirToPoint.ToUnit(false) * repulse.Strength;
        //        }
        //    }

        //    #endregion

        //    return retVal;
        //}
        //private Vector3D? GetStrokeForce_LATEST(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity)
        //{
        //    //const double CLOSEENOUGHRADIUSMULT = 2;
        //    //const double VELOCITYINFLUENCERADIUSMULT = 5;
        //    const double CLOSEENOUGHRADIUSMULT = 4;
        //    const double VELOCITYINFLUENCERADIUSMULT = 15;

        //    // Null stroke
        //    if (objectiveStroke == null)
        //    {
        //        lock (_currentStrokeLock) _currentlyChasingStroke = null;
        //        return null;
        //    }

        //    #region current stroke

        //    // Get currently chasing stroke

        //    CurrentChasingStroke currentStroke = null;
        //    lock (_currentStrokeLock)
        //    {
        //        currentStroke = _currentlyChasingStroke;
        //        if (currentStroke == null || currentStroke.Stroke.Token != objectiveStroke.Token)
        //        {
        //            currentStroke = new CurrentChasingStroke(objectiveStroke, ACCEL * 3);
        //            _currentlyChasingStroke = currentStroke;
        //        }
        //    }

        //    #endregion
        //    #region current index of stroke

        //    int currentIndex = currentStroke.CurrentIndex;
        //    Vector3D towardCurrentPoint;
        //    double towardCurrentPointLenSqr;

        //    while (true)
        //    {
        //        //if (currentIndex > 0)
        //        //{
        //        //    return null;
        //        //}

        //        if (currentIndex >= currentStroke.Stroke.Points.Length)
        //        {
        //            // Already went through all the points
        //            return null;
        //        }

        //        // If too close to the current point, then advance to the next
        //        towardCurrentPoint = currentStroke.Stroke.Points[currentIndex].Item1 - position;
        //        towardCurrentPointLenSqr = towardCurrentPoint.LengthSquared;
        //        double closeEnoughDist = this.Radius * CLOSEENOUGHRADIUSMULT;

        //        if (towardCurrentPointLenSqr < closeEnoughDist * closeEnoughDist)
        //        {
        //            currentIndex++;
        //            currentStroke.CurrentIndex = currentIndex;
        //        }
        //        else
        //        {
        //            break;
        //        }
        //    }

        //    #endregion

        //    // Start with attraction to the current point
        //    Vector3D retVal = towardCurrentPoint.ToUnit(false) * this.MaxAccel;

        //    #region influence velocity

        //    // Add the desired velocity

        //    //double velocityInfluenceDist = this.Radius * VELOCITYINFLUENCERADIUSMULT;

        //    //if (towardCurrentPointLenSqr < velocityInfluenceDist * velocityInfluenceDist)
        //    //{
        //    //    double percent = UtilityCore.GetScaledValue(1d, 0d, 0d, velocityInfluenceDist, Math.Sqrt(towardCurrentPointLenSqr));

        //    //    retVal += currentStroke.Stroke.Points[currentIndex].Item2 * percent;
        //    //}

        //    #endregion
        //    #region repulse

        //    //foreach (var repulse in currentStroke.UpcomingPoints[currentIndex])
        //    //{
        //    //    Vector3D dirToPoint = position - repulse.Position;
        //    //    double lenSqr = dirToPoint.LengthSquared;

        //    //    if (lenSqr > repulse.EffectRadius * repulse.EffectRadius)
        //    //    {
        //    //        // Too far away to be influenced by this point
        //    //        continue;
        //    //    }

        //    //    if (lenSqr.IsNearZero())
        //    //    {
        //    //        retVal += Math3D.GetRandomVector_Spherical_Shell(repulse.Strength);
        //    //    }
        //    //    else
        //    //    {
        //    //        retVal += dirToPoint.ToUnit(false) * repulse.Strength;
        //    //    }
        //    //}

        //    #endregion

        //    return retVal;
        //}
        //private Vector3D? GetStrokeForce_MULTINOVELOCITY(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity)
        //{
        //    const double CLOSEENOUGHRADIUSMULT = 3;

        //    if (objectiveStroke == null)
        //    {
        //        return null;
        //    }

        //    Tuple<long, int> stroke_index = _stroke_index;
        //    if (stroke_index == null || stroke_index.Item1 != objectiveStroke.Token)
        //    {
        //        stroke_index = Tuple.Create(objectiveStroke.Token, 0);
        //        _stroke_index = stroke_index;
        //    }

        //    Vector3D toObjective;
        //    while (true)
        //    {
        //        if (stroke_index.Item2 >= objectiveStroke.Points.Length)
        //        {
        //            return null;
        //        }

        //        toObjective = objectiveStroke.Points[stroke_index.Item2].Item1 - position;
        //        if (toObjective.LengthSquared > (this.Radius * CLOSEENOUGHRADIUSMULT) * (this.Radius * CLOSEENOUGHRADIUSMULT))
        //        {
        //            break;
        //        }

        //        stroke_index = Tuple.Create(stroke_index.Item1, stroke_index.Item2 + 1);
        //        _stroke_index = stroke_index;
        //    }

        //    // For now, just aim straight for the first point
        //    return (toObjective).ToUnit(false) * this.MaxAccel;
        //}
        //private Vector3D? GetStrokeForce_MULTIWITHVELOCITY(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity)
        //{
        //    const double CLOSEENOUGHRADIUSMULT = 3;
        //    const double VELOCITYINFLUENCERADIUSMULT = 7;

        //    // This fails when they are on or very near the stroke and try to swim up stream.  The point they are trying to
        //    // go to is pushing them along.
        //    //
        //    // So need to just move on to the next point (or maybe just closest point).  Need to take dot product of direction
        //    // and point's velocity into account

        //    if (objectiveStroke == null)
        //    {
        //        return null;
        //    }

        //    Tuple<long, int> stroke_index = _stroke_index;
        //    if (stroke_index == null || stroke_index.Item1 != objectiveStroke.Token)
        //    {
        //        stroke_index = Tuple.Create(objectiveStroke.Token, 0);
        //        _stroke_index = stroke_index;
        //    }

        //    #region get the next point

        //    Vector3D toObjective;
        //    while (true)
        //    {
        //        if (stroke_index.Item2 >= objectiveStroke.Points.Length)
        //        {
        //            return null;
        //        }

        //        toObjective = objectiveStroke.Points[stroke_index.Item2].Item1 - position;
        //        if (toObjective.LengthSquared > (this.Radius * CLOSEENOUGHRADIUSMULT) * (this.Radius * CLOSEENOUGHRADIUSMULT))
        //        {
        //            break;
        //        }

        //        stroke_index = Tuple.Create(stroke_index.Item1, stroke_index.Item2 + 1);
        //        _stroke_index = stroke_index;
        //    }

        //    #endregion

        //    // For now, just aim straight for the first point
        //    Vector3D retVal = (toObjective).ToUnit(false) * this.MaxAccel;

        //    #region influence velocity

        //    // Add the desired velocity

        //    double velocityInfluenceDist = this.Radius * VELOCITYINFLUENCERADIUSMULT;

        //    if (toObjective.LengthSquared < velocityInfluenceDist * velocityInfluenceDist)
        //    {
        //        double percent = UtilityCore.GetScaledValue(2d, 0d, 0d, velocityInfluenceDist, toObjective.Length);

        //        retVal += objectiveStroke.Points[stroke_index.Item2].Item2 * percent;
        //    }

        //    #endregion

        //    return retVal;
        //}
        //private Vector3D? GetStrokeForce_BETTER(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity)
        //{
        //    if (objectiveStroke == null)
        //    {
        //        return null;
        //    }

        //    double maxAccel = this.MaxAccel;
        //    double radius = this.Radius;

        //    //TODO: Don't just use the return length, have the function also return a weighted distance to the point (based on dot)
        //    //TODO: Remember which points are objectives, and never choose any index less than that (once null, ignore the stroke)

        //    int startIndex = 0;
        //    var strokeIndex = _stroke_index;
        //    if (strokeIndex != null && strokeIndex.Item1 == objectiveStroke.Token)
        //    {
        //        startIndex = strokeIndex.Item2;
        //    }

        //    if (startIndex >= objectiveStroke.Points.Length)
        //    {
        //        return null;
        //    }

        //    var candidates = Enumerable.Range(startIndex, objectiveStroke.Points.Length - startIndex).
        //        Select(o => new { Index = o, Item = objectiveStroke.Points[o], Force = GetStrokePointForce_BETTER(objectiveStroke.Points[o], position, velocity, maxAccel, radius) }).
        //        Where(o => o.Force != null).
        //        OrderBy(o => o.Force.Value.LengthSquared).
        //        FirstOrDefault();

        //    if (candidates == null)
        //    {
        //        _stroke_index = Tuple.Create(objectiveStroke.Token, objectiveStroke.Points.Length);
        //        return null;
        //    }

        //    _stroke_index = Tuple.Create(objectiveStroke.Token, candidates.Index);
        //    return candidates.Force;
        //}
        //private static Vector3D? GetStrokePointForce_BETTER(Tuple<Point3D, Vector3D> strokePoint, Point3D position, Vector3D velocity, double maxAccel, double radius)
        //{
        //    const double VELOCITYINFLUENCERADIUSMULT = 7;
        //    const double MINDOT = -.7;

        //    Vector3D toPoint = strokePoint.Item1 - position;
        //    double toPointLength = toPoint.Length;

        //    if (toPointLength.IsNearZero())
        //    {
        //        // Sitting on top of the point.  The only force felt is the point's velocity
        //        return strokePoint.Item2;
        //    }

        //    Vector3D toPointUnit = toPoint / toPointLength;

        //    double dot = Vector3D.DotProduct(toPointUnit, strokePoint.Item2.ToUnit());

        //    if (dot < MINDOT)
        //    {
        //        // It would have to fly too directly up stream to get to the point
        //        return null;
        //    }

        //    // Toward Point
        //    Vector3D retVal = toPointUnit * maxAccel;
        //    //if (dot < 0)     // The larger the dot, the larger the force (because when the dot is small, this point is in the wrong direction)
        //    //{
        //    //    double percent = UtilityCore.GetScaledValue(0d, 1d, MINDOT, 0d, dot);
        //    //    retVal *= percent;
        //    //}

        //    // Influence velocity
        //    double velocityInfluenceDist = radius * VELOCITYINFLUENCERADIUSMULT;

        //    if (toPointLength < velocityInfluenceDist)
        //    {
        //        double percent = UtilityCore.GetScaledValue(2d, 0d, 0d, velocityInfluenceDist, toPointLength);
        //        retVal += strokePoint.Item2 * percent;
        //    }

        //    //TODO: Compare a dot with the return force and location/velocity of point to see if it's even possible
        //    //to get to that point

        //    return retVal;
        //}

        #endregion

        #endregion
        #region Private Methods - initial forces

        private ForceSettings_Initial GetForceSetting_Initial(ref int chaseBotCount, MapObjectInfo item, int maxBotCount)
        {
            // Convert into a lookup vector, then do a fuzzy lookup (this will allow the bot to learn about objects instead
            // of a hardcoded switch statement)

            if (item.MapObject is Asteroid)
            {
                return _settings_Asteroid;
            }
            else if (item.MapObject is SwarmBot1a)
            {
                chaseBotCount++;
                if (chaseBotCount <= maxBotCount)
                {
                    return _settings_OtherBot_Chase;
                }
                else
                {
                    return _settings_OtherBot_Passive;
                }
            }
            else
            {
                return null;
            }
        }
 protected virtual NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo GetNativeObjectInfoInternal
     (NeoDatis.Odb.Core.Layers.Layer2.Meta.ODBType type, object o, bool recursive
     , System.Collections.Generic.IDictionary <object, NeoDatis.Odb.Core.Layers.Layer2.Meta.NonNativeObjectInfo
                                               > alreadyReadObjects, NeoDatis.Odb.Core.Layers.Layer1.Introspector.IIntrospectionCallback
     callback)
 {
     NeoDatis.Odb.Core.Layers.Layer2.Meta.AbstractObjectInfo aoi = null;
     if (type.IsAtomicNative())
     {
         if (o == null)
         {
             aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type.GetId());
         }
         else
         {
             aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.AtomicNativeObjectInfo(o, type
                                                                                   .GetId());
         }
     }
     else
     {
         if (type.IsCollection())
         {
             aoi = IntrospectCollection((System.Collections.ICollection)o, recursive, alreadyReadObjects
                                        , type, callback);
         }
         else
         {
             if (type.IsArray())
             {
                 if (o == null)
                 {
                     aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo(null);
                 }
                 else
                 {
                     // Gets the type of the elements of the array
                     string realArrayClassName = OdbClassUtil.GetFullName(o.GetType().GetElementType());
                     NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo aroi = null;
                     if (recursive)
                     {
                         aroi = IntrospectArray(o, recursive, alreadyReadObjects, type, callback);
                     }
                     else
                     {
                         aroi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.ArrayObjectInfo((object[])o
                                                                                         );
                     }
                     aroi.SetRealArrayComponentClassName(realArrayClassName);
                     aoi = aroi;
                 }
             }
             else
             {
                 if (type.IsMap())
                 {
                     if (o == null)
                     {
                         aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.MapObjectInfo(null, type, type.GetDefaultInstanciationClass
                                                                                          ().FullName);
                     }
                     else
                     {
                         MapObjectInfo moi = null;
                         string        realMapClassName = OdbClassUtil.GetFullName(o.GetType());
                         bool          isGeneric        = o.GetType().IsGenericType;
                         if (isGeneric)
                         {
                             moi = new MapObjectInfo(IntrospectGenericMap((System.Collections.Generic.IDictionary <object, object>)o, recursive, alreadyReadObjects, callback), type, realMapClassName);
                         }
                         else
                         {
                             moi = new MapObjectInfo(IntrospectNonGenericMap((System.Collections.IDictionary)o, recursive, alreadyReadObjects, callback), type, realMapClassName);
                         }
                         if (realMapClassName.IndexOf("$") != -1)
                         {
                             moi.SetRealMapClassName(OdbClassUtil.GetFullName(type.GetDefaultInstanciationClass()));
                         }
                         aoi = moi;
                     }
                 }
                 else
                 {
                     if (type.IsEnum())
                     {
                         System.Enum enumObject = (System.Enum)o;
                         if (enumObject == null)
                         {
                             aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.NullNativeObjectInfo(type.GetSize(
                                                                                                     ));
                         }
                         else
                         {
                             Type   t             = enumObject.GetType();
                             string enumClassName = enumObject == null ? null : OdbClassUtil.GetFullName(enumObject.GetType());
                             // Here we must check if the enum is already in the meta model. Enum must be stored in the meta
                             // model to optimize its storing as we need to keep track of the enum class
                             // for each enum stored. So instead of storing the enum class name, we can store enum class id, a long
                             // instead of the full enum class name string
                             NeoDatis.Odb.Core.Layers.Layer2.Meta.ClassInfo ci = GetClassInfo(enumClassName);
                             string enumValue = enumObject == null ? null : enumObject.ToString();
                             aoi = new NeoDatis.Odb.Core.Layers.Layer2.Meta.EnumNativeObjectInfo(ci, enumValue
                                                                                                 );
                         }
                     }
                 }
             }
         }
     }
     return(aoi);
 }
Пример #11
0
        private static Vector3D GetMatchVelocityForce(MapObjectInfo mapObject, Vector3D velocity, double minSpeed)
        {
            //Vector3D dif = mapObject.Velocity - velocity;     // this just causes the whole blob to have an average of zero
            Vector3D dif = mapObject.Velocity;

            if (minSpeed > 0 && dif.LengthSquared < minSpeed * minSpeed)
            {
                dif = dif.ToUnit(false);
                if (dif.LengthSquared.IsNearZero())
                {
                    dif = Math3D.GetRandomVector_Spherical(minSpeed);
                }
                else
                {
                    dif *= minSpeed;
                }
            }

            //TODO: Have a gradient of velocity match based on distance.  So if this is really far away from the item, then the item
            //should have no influence

            return dif;
        }
Пример #12
0
        private Tuple<MapObjectInfo, double, ForceSettings_Initial>[] GetNeighbors(MapOctree snapshot, Point3D position)
        {
            // Get nearby items, sort by distance
            double searchRadius = this.SearchRadius;

            var initial = snapshot.GetItems(position, searchRadius).
                Where(o => o.Token != this.Token).
                Select(o => Tuple.Create(o, (o.Position - position).LengthSquared)).
                OrderBy(o => o.Item2).
                ToArray();

            // Get chase settings for each item
            //NOTE: This needs to be done after sorting on distance, because bots will have different settings if too many are actively chased
            var retVal = new List<Tuple<MapObjectInfo, double, ForceSettings_Initial>>();

            bool sawParent = false;
            int chaseNeighborCount = this.ChaseNeighborCount;
            int currentNeighborCount = 0;

            foreach (var item in initial)
            {
                ForceSettings_Initial chaseProps = GetForceSetting_Initial(ref currentNeighborCount, ref sawParent, item.Item1, chaseNeighborCount);
                if (chaseProps != null)
                {
                    retVal.Add(Tuple.Create(item.Item1, item.Item2, chaseProps));
                }
            }

            if (!sawParent && _parent != null && !_parent.IsDisposed)
            {
                MapObjectInfo parent = new MapObjectInfo(_parent, _parentType);
                retVal.Add(Tuple.Create(parent, (parent.Position - position).LengthSquared, _settings_Parent));
            }

            return retVal.ToArray();
        }
Пример #13
0
        //private Tuple<Vector3D?, Vector3D?> GetSeekForce_1()
        //{
        //    #region velocity

        //    double maxSpeed = this.MaxSpeed;
        //    double maxAngSpeed = this.MaxAngularSpeed;

        //    Vector3D velocity = this.VelocityWorld;
        //    Vector3D angVelocity = this.PhysicsBody.AngularVelocity;

        //    Vector3D desiredVelocity = velocity + Math3D.GetRandomVector_Spherical(maxSpeed / 10);
        //    Vector3D desiredAngVelocity = angVelocity + Math3D.GetRandomVector_Spherical(maxAngSpeed / 10);

        //    desiredVelocity = CapVector(desiredVelocity, maxSpeed);
        //    desiredAngVelocity = CapVector(desiredAngVelocity, maxAngSpeed);

        //    #endregion

        //    #region acceleration

        //    double maxAccel = this.MaxAccel;
        //    double maxAngAccel = this.MaxAngularAccel;

        //    //TODO: Come up with better units for converting velocity to acceleration
        //    Vector3D accel = desiredAngVelocity - velocity;
        //    Vector3D angAccel = desiredAngVelocity - angVelocity;

        //    accel = CapVector(accel, maxAccel);
        //    angAccel = CapVector(angAccel, maxAngAccel);

        //    #endregion

        //    #region force

        //    // Multiply by mass to turn accel into force
        //    accel *= this.PhysicsBody.Mass;

        //    MassMatrix inertia = this.PhysicsBody.MassMatrix;
        //    double dot = Math.Abs(Vector3D.DotProduct(angAccel.ToUnit(), inertia.Inertia.ToUnit()));

        //    //TODO: Make sure this is right
        //    angAccel *= dot * inertia.Inertia.Length;

        //    #endregion

        //    return new Tuple<Vector3D?, Vector3D?>(accel, angAccel);
        //}

        //private Vector3D? GetStrokeForce_FIRST(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity)
        //{
        //    if (objectiveStroke == null)
        //    {
        //        return null;
        //    }

        //    // For now, just aim straight for the first point
        //    return (objectiveStroke.Points[0].Item1 - position).ToUnit(false) * this.MaxAccel;
        //}
        //private Vector3D? GetStrokeForce_HASREPULSE(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity)
        //{
        //    //const double CLOSEENOUGHRADIUSMULT = 2;
        //    //const double VELOCITYINFLUENCERADIUSMULT = 5;
        //    const double CLOSEENOUGHRADIUSMULT = 8;
        //    const double VELOCITYINFLUENCERADIUSMULT = 15;

        //    // Null stroke
        //    if (objectiveStroke == null)
        //    {
        //        lock (_currentStrokeLock) _currentlyChasingStroke = null;
        //        return null;
        //    }

        //    #region current stroke

        //    // Get currently chasing stroke

        //    CurrentChasingStroke currentStroke = null;
        //    lock (_currentStrokeLock)
        //    {
        //        currentStroke = _currentlyChasingStroke;
        //        if (currentStroke == null || currentStroke.Stroke.Token != objectiveStroke.Token)
        //        {
        //            currentStroke = new CurrentChasingStroke(objectiveStroke, ACCEL * 3);
        //            _currentlyChasingStroke = currentStroke;
        //        }
        //    }

        //    #endregion
        //    #region current index of stroke

        //    int currentIndex = currentStroke.CurrentIndex;
        //    Vector3D towardCurrentPoint;
        //    double towardCurrentPointLenSqr;

        //    while (true)
        //    {
        //        if (currentIndex >= currentStroke.Stroke.Points.Length)
        //        {
        //            // Already went through all the points
        //            return null;
        //        }

        //        // If too close to the current point, then advance to the next
        //        towardCurrentPoint = currentStroke.Stroke.Points[currentIndex].Item1 - position;
        //        towardCurrentPointLenSqr = towardCurrentPoint.LengthSquared;
        //        double closeEnoughDist = this.Radius * CLOSEENOUGHRADIUSMULT;

        //        if (towardCurrentPointLenSqr < closeEnoughDist * closeEnoughDist)
        //        {
        //            currentIndex++;
        //            currentStroke.CurrentIndex = currentIndex;
        //        }
        //        else
        //        {
        //            break;
        //        }
        //    }

        //    #endregion

        //    // Start with attraction to the current point
        //    Vector3D retVal = towardCurrentPoint.ToUnit(false) * this.MaxAccel;

        //    #region influence velocity

        //    // Add the desired velocity

        //    double velocityInfluenceDist = this.Radius * VELOCITYINFLUENCERADIUSMULT;

        //    if (towardCurrentPointLenSqr < velocityInfluenceDist * velocityInfluenceDist)
        //    {
        //        double percent = UtilityCore.GetScaledValue(1d, 0d, 0d, velocityInfluenceDist, Math.Sqrt(towardCurrentPointLenSqr));

        //        retVal += currentStroke.Stroke.Points[currentIndex].Item2 * percent;
        //    }

        //    #endregion
        //    #region repulse

        //    foreach (var repulse in currentStroke.UpcomingPoints[currentIndex])
        //    {
        //        Vector3D dirToPoint = position - repulse.Position;
        //        double lenSqr = dirToPoint.LengthSquared;

        //        if (lenSqr > repulse.EffectRadius * repulse.EffectRadius)
        //        {
        //            // Too far away to be influenced by this point
        //            continue;
        //        }

        //        if (lenSqr.IsNearZero())
        //        {
        //            retVal += Math3D.GetRandomVector_Spherical_Shell(repulse.Strength);
        //        }
        //        else
        //        {
        //            retVal += dirToPoint.ToUnit(false) * repulse.Strength;
        //        }
        //    }

        //    #endregion

        //    return retVal;
        //}
        //private Vector3D? GetStrokeForce_LATEST(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity)
        //{
        //    //const double CLOSEENOUGHRADIUSMULT = 2;
        //    //const double VELOCITYINFLUENCERADIUSMULT = 5;
        //    const double CLOSEENOUGHRADIUSMULT = 4;
        //    const double VELOCITYINFLUENCERADIUSMULT = 15;

        //    // Null stroke
        //    if (objectiveStroke == null)
        //    {
        //        lock (_currentStrokeLock) _currentlyChasingStroke = null;
        //        return null;
        //    }

        //    #region current stroke

        //    // Get currently chasing stroke

        //    CurrentChasingStroke currentStroke = null;
        //    lock (_currentStrokeLock)
        //    {
        //        currentStroke = _currentlyChasingStroke;
        //        if (currentStroke == null || currentStroke.Stroke.Token != objectiveStroke.Token)
        //        {
        //            currentStroke = new CurrentChasingStroke(objectiveStroke, ACCEL * 3);
        //            _currentlyChasingStroke = currentStroke;
        //        }
        //    }

        //    #endregion
        //    #region current index of stroke

        //    int currentIndex = currentStroke.CurrentIndex;
        //    Vector3D towardCurrentPoint;
        //    double towardCurrentPointLenSqr;

        //    while (true)
        //    {
        //        //if (currentIndex > 0)
        //        //{
        //        //    return null;
        //        //}

        //        if (currentIndex >= currentStroke.Stroke.Points.Length)
        //        {
        //            // Already went through all the points
        //            return null;
        //        }

        //        // If too close to the current point, then advance to the next
        //        towardCurrentPoint = currentStroke.Stroke.Points[currentIndex].Item1 - position;
        //        towardCurrentPointLenSqr = towardCurrentPoint.LengthSquared;
        //        double closeEnoughDist = this.Radius * CLOSEENOUGHRADIUSMULT;

        //        if (towardCurrentPointLenSqr < closeEnoughDist * closeEnoughDist)
        //        {
        //            currentIndex++;
        //            currentStroke.CurrentIndex = currentIndex;
        //        }
        //        else
        //        {
        //            break;
        //        }
        //    }

        //    #endregion

        //    // Start with attraction to the current point
        //    Vector3D retVal = towardCurrentPoint.ToUnit(false) * this.MaxAccel;

        //    #region influence velocity

        //    // Add the desired velocity

        //    //double velocityInfluenceDist = this.Radius * VELOCITYINFLUENCERADIUSMULT;

        //    //if (towardCurrentPointLenSqr < velocityInfluenceDist * velocityInfluenceDist)
        //    //{
        //    //    double percent = UtilityCore.GetScaledValue(1d, 0d, 0d, velocityInfluenceDist, Math.Sqrt(towardCurrentPointLenSqr));

        //    //    retVal += currentStroke.Stroke.Points[currentIndex].Item2 * percent;
        //    //}

        //    #endregion
        //    #region repulse

        //    //foreach (var repulse in currentStroke.UpcomingPoints[currentIndex])
        //    //{
        //    //    Vector3D dirToPoint = position - repulse.Position;
        //    //    double lenSqr = dirToPoint.LengthSquared;

        //    //    if (lenSqr > repulse.EffectRadius * repulse.EffectRadius)
        //    //    {
        //    //        // Too far away to be influenced by this point
        //    //        continue;
        //    //    }

        //    //    if (lenSqr.IsNearZero())
        //    //    {
        //    //        retVal += Math3D.GetRandomVector_Spherical_Shell(repulse.Strength);
        //    //    }
        //    //    else
        //    //    {
        //    //        retVal += dirToPoint.ToUnit(false) * repulse.Strength;
        //    //    }
        //    //}

        //    #endregion

        //    return retVal;
        //}
        //private Vector3D? GetStrokeForce_MULTINOVELOCITY(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity)
        //{
        //    const double CLOSEENOUGHRADIUSMULT = 3;

        //    if (objectiveStroke == null)
        //    {
        //        return null;
        //    }

        //    Tuple<long, int> stroke_index = _stroke_index;
        //    if (stroke_index == null || stroke_index.Item1 != objectiveStroke.Token)
        //    {
        //        stroke_index = Tuple.Create(objectiveStroke.Token, 0);
        //        _stroke_index = stroke_index;
        //    }

        //    Vector3D toObjective;
        //    while (true)
        //    {
        //        if (stroke_index.Item2 >= objectiveStroke.Points.Length)
        //        {
        //            return null;
        //        }

        //        toObjective = objectiveStroke.Points[stroke_index.Item2].Item1 - position;
        //        if (toObjective.LengthSquared > (this.Radius * CLOSEENOUGHRADIUSMULT) * (this.Radius * CLOSEENOUGHRADIUSMULT))
        //        {
        //            break;
        //        }

        //        stroke_index = Tuple.Create(stroke_index.Item1, stroke_index.Item2 + 1);
        //        _stroke_index = stroke_index;
        //    }

        //    // For now, just aim straight for the first point
        //    return (toObjective).ToUnit(false) * this.MaxAccel;
        //}
        //private Vector3D? GetStrokeForce_MULTIWITHVELOCITY(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity)
        //{
        //    const double CLOSEENOUGHRADIUSMULT = 3;
        //    const double VELOCITYINFLUENCERADIUSMULT = 7;

        //    // This fails when they are on or very near the stroke and try to swim up stream.  The point they are trying to
        //    // go to is pushing them along.
        //    //
        //    // So need to just move on to the next point (or maybe just closest point).  Need to take dot product of direction
        //    // and point's velocity into account

        //    if (objectiveStroke == null)
        //    {
        //        return null;
        //    }

        //    Tuple<long, int> stroke_index = _stroke_index;
        //    if (stroke_index == null || stroke_index.Item1 != objectiveStroke.Token)
        //    {
        //        stroke_index = Tuple.Create(objectiveStroke.Token, 0);
        //        _stroke_index = stroke_index;
        //    }

        //    #region get the next point

        //    Vector3D toObjective;
        //    while (true)
        //    {
        //        if (stroke_index.Item2 >= objectiveStroke.Points.Length)
        //        {
        //            return null;
        //        }

        //        toObjective = objectiveStroke.Points[stroke_index.Item2].Item1 - position;
        //        if (toObjective.LengthSquared > (this.Radius * CLOSEENOUGHRADIUSMULT) * (this.Radius * CLOSEENOUGHRADIUSMULT))
        //        {
        //            break;
        //        }

        //        stroke_index = Tuple.Create(stroke_index.Item1, stroke_index.Item2 + 1);
        //        _stroke_index = stroke_index;
        //    }

        //    #endregion

        //    // For now, just aim straight for the first point
        //    Vector3D retVal = (toObjective).ToUnit(false) * this.MaxAccel;

        //    #region influence velocity

        //    // Add the desired velocity

        //    double velocityInfluenceDist = this.Radius * VELOCITYINFLUENCERADIUSMULT;

        //    if (toObjective.LengthSquared < velocityInfluenceDist * velocityInfluenceDist)
        //    {
        //        double percent = UtilityCore.GetScaledValue(2d, 0d, 0d, velocityInfluenceDist, toObjective.Length);

        //        retVal += objectiveStroke.Points[stroke_index.Item2].Item2 * percent;
        //    }

        //    #endregion

        //    return retVal;
        //}
        //private Vector3D? GetStrokeForce_BETTER(SwarmObjectiveStrokes.Stroke objectiveStroke, Point3D position, Vector3D velocity)
        //{
        //    if (objectiveStroke == null)
        //    {
        //        return null;
        //    }

        //    double maxAccel = this.MaxAccel;
        //    double radius = this.Radius;

        //    //TODO: Don't just use the return length, have the function also return a weighted distance to the point (based on dot)
        //    //TODO: Remember which points are objectives, and never choose any index less than that (once null, ignore the stroke)

        //    int startIndex = 0;
        //    var strokeIndex = _stroke_index;
        //    if (strokeIndex != null && strokeIndex.Item1 == objectiveStroke.Token)
        //    {
        //        startIndex = strokeIndex.Item2;
        //    }

        //    if (startIndex >= objectiveStroke.Points.Length)
        //    {
        //        return null;
        //    }

        //    var candidates = Enumerable.Range(startIndex, objectiveStroke.Points.Length - startIndex).
        //        Select(o => new { Index = o, Item = objectiveStroke.Points[o], Force = GetStrokePointForce_BETTER(objectiveStroke.Points[o], position, velocity, maxAccel, radius) }).
        //        Where(o => o.Force != null).
        //        OrderBy(o => o.Force.Value.LengthSquared).
        //        FirstOrDefault();

        //    if (candidates == null)
        //    {
        //        _stroke_index = Tuple.Create(objectiveStroke.Token, objectiveStroke.Points.Length);
        //        return null;
        //    }

        //    _stroke_index = Tuple.Create(objectiveStroke.Token, candidates.Index);
        //    return candidates.Force;
        //}
        //private static Vector3D? GetStrokePointForce_BETTER(Tuple<Point3D, Vector3D> strokePoint, Point3D position, Vector3D velocity, double maxAccel, double radius)
        //{
        //    const double VELOCITYINFLUENCERADIUSMULT = 7;
        //    const double MINDOT = -.7;

        //    Vector3D toPoint = strokePoint.Item1 - position;
        //    double toPointLength = toPoint.Length;

        //    if (toPointLength.IsNearZero())
        //    {
        //        // Sitting on top of the point.  The only force felt is the point's velocity
        //        return strokePoint.Item2;
        //    }

        //    Vector3D toPointUnit = toPoint / toPointLength;

        //    double dot = Vector3D.DotProduct(toPointUnit, strokePoint.Item2.ToUnit());

        //    if (dot < MINDOT)
        //    {
        //        // It would have to fly too directly up stream to get to the point
        //        return null;
        //    }

        //    // Toward Point
        //    Vector3D retVal = toPointUnit * maxAccel;
        //    //if (dot < 0)     // The larger the dot, the larger the force (because when the dot is small, this point is in the wrong direction)
        //    //{
        //    //    double percent = UtilityCore.GetScaledValue(0d, 1d, MINDOT, 0d, dot);
        //    //    retVal *= percent;
        //    //}

        //    // Influence velocity
        //    double velocityInfluenceDist = radius * VELOCITYINFLUENCERADIUSMULT;

        //    if (toPointLength < velocityInfluenceDist)
        //    {
        //        double percent = UtilityCore.GetScaledValue(2d, 0d, 0d, velocityInfluenceDist, toPointLength);
        //        retVal += strokePoint.Item2 * percent;
        //    }

        //    //TODO: Compare a dot with the return force and location/velocity of point to see if it's even possible
        //    //to get to that point

        //    return retVal;
        //}

        #endregion

        #endregion
        #region Private Methods - initial forces

        private ForceSettings_Initial GetForceSetting_Initial(ref int chaseBotCount, ref bool sawParent, MapObjectInfo item, int maxBotCount)
        {
            //TODO: Convert into a lookup vector, then do a fuzzy lookup (this will allow the bot to learn about objects instead
            //of a hardcoded switch statement)

            if (_parent != null && !_parent.IsDisposed && item.Token == _parent.Token)
            {
                sawParent = true;
                return _settings_Parent;
            }
            else if (item.MapObject is Asteroid)
            {
                return _settings_Asteroid;
            }
            else if (item.MapObject is SwarmBot1b)
            {
                chaseBotCount++;
                if (chaseBotCount <= maxBotCount)
                {
                    return _settings_OtherBot_Chase;
                }
                else
                {
                    return _settings_OtherBot_Passive;
                }
            }
            else
            {
                return null;
            }
        }
 private static ChangeInstruction[] ExamineMinerals_Remove1(MapObjectInfo[] minerals, int count)
 {
     return minerals.
         Select(o => (Mineral)o.MapObject).
         OrderBy(o => o.Credits).
         Take(count).
         Select(o => new ChangeInstruction(new[] { o })).
         ToArray();
 }
        private bool HasChanged(NonNativeObjectInfo nnoi1, NonNativeObjectInfo nnoi2, int objectRecursionLevel)
        {
            AbstractObjectInfo value1 = null;
            AbstractObjectInfo value2 = null;
            bool hasChanged           = false;
            // If the object is already being checked, return false, this second
            // check will not affect the check
            int n = 0;

            alreadyCheckingObjects.TryGetValue(nnoi2, out n);
            if (n != 0)
            {
                return(false);
            }
            // Put the object in the temporary cache
            alreadyCheckingObjects[nnoi1] = 1;
            alreadyCheckingObjects[nnoi2] = 1;
            // Warning ID Start with 1 and not 0
            for (int id = 1; id <= nnoi1.GetMaxNbattributes(); id++)
            {
                value1 = nnoi1.GetAttributeValueFromId(id);
                // Gets the value by the attribute id to be sure
                // Problem because a new object info may not have the right ids ?
                // Check if
                // the new oiD is ok.
                value2 = nnoi2.GetAttributeValueFromId(id);
                if (value2 == null)
                {
                    // this means the object to have attribute id
                    StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel);
                    hasChanged = true;
                    continue;
                }
                if (value1 == null)
                {
                    //throw new ODBRuntimeException("ObjectInfoComparator.hasChanged:attribute with id "+id+" does not exist on "+nnoi2);
                    // This happens when this object was created with an version of ClassInfo (which has been refactored).
                    // In this case,we simply tell that in place update is not supported so that the object will be rewritten with
                    // new metamodel
                    supportInPlaceUpdate = false;
                    continue;
                }
                // If both are null, no effect
                if (value1.IsNull() && value2.IsNull())
                {
                    continue;
                }
                if (value1.IsNull() || value2.IsNull())
                {
                    supportInPlaceUpdate = false;
                    hasChanged           = true;
                    StoreActionSetAttributetoNull(nnoi1, id, objectRecursionLevel);
                    continue;
                }
                if (!ClassAreCompatible(value1, value2))
                {
                    if (value2 is NativeObjectInfo)
                    {
                        StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel);
                        StoreChangedAttributeAction(new ChangedNativeAttributeAction
                                                        (nnoi1, nnoi2, nnoi1.GetHeader().GetAttributeIdentificationFromId(id), (NativeObjectInfo
                                                                                                                                )value2, objectRecursionLevel, false, nnoi1.GetClassInfo().GetAttributeInfoFromId
                                                            (id).GetName()));
                    }
                    if (value2 is ObjectReference)
                    {
                        NonNativeObjectInfo nnoi = (NonNativeObjectInfo
                                                    )value1;
                        ObjectReference oref = (ObjectReference
                                                )value2;
                        if (!nnoi.GetOid().Equals(oref.GetOid()))
                        {
                            StoreChangedObject(nnoi1, nnoi2, id, objectRecursionLevel);
                            int attributeIdThatHasChanged = id;
                            // this is the exact position where the object reference
                            // definition is stored
                            long attributeDefinitionPosition = nnoi2.GetAttributeDefinitionPosition(attributeIdThatHasChanged
                                                                                                    );
                            StoreChangedAttributeAction(new ChangedObjectReferenceAttributeAction
                                                            (attributeDefinitionPosition, (ObjectReference
                                                                                           )value2, objectRecursionLevel));
                        }
                        else
                        {
                            continue;
                        }
                    }
                    hasChanged = true;
                    continue;
                }
                if (value1.IsAtomicNativeObject())
                {
                    if (!value1.Equals(value2))
                    {
                        // storeChangedObject(nnoi1, nnoi2, id,
                        // objectRecursionLevel);
                        StoreChangedAttributeAction(new ChangedNativeAttributeAction
                                                        (nnoi1, nnoi2, nnoi1.GetHeader().GetAttributeIdentificationFromId(id), (NativeObjectInfo
                                                                                                                                )value2, objectRecursionLevel, false, nnoi1.GetClassInfo().GetAttributeInfoFromId
                                                            (id).GetName()));
                        hasChanged = true;
                        continue;
                    }
                    continue;
                }
                if (value1.IsCollectionObject())
                {
                    CollectionObjectInfo coi1 = (CollectionObjectInfo)value1;
                    CollectionObjectInfo coi2 = (CollectionObjectInfo)value2;
                    bool collectionHasChanged = ManageCollectionChanges(nnoi1, nnoi2, id, coi1, coi2, objectRecursionLevel);
                    hasChanged = hasChanged || collectionHasChanged;
                    continue;
                }
                if (value1.IsArrayObject())
                {
                    ArrayObjectInfo aoi1            = (ArrayObjectInfo)value1;
                    ArrayObjectInfo aoi2            = (ArrayObjectInfo)value2;
                    bool            arrayHasChanged = ManageArrayChanges(nnoi1, nnoi2, id, aoi1, aoi2, objectRecursionLevel
                                                                         );
                    hasChanged = hasChanged || arrayHasChanged;
                    continue;
                }
                if (value1.IsMapObject())
                {
                    MapObjectInfo moi1          = (MapObjectInfo)value1;
                    MapObjectInfo moi2          = (MapObjectInfo)value2;
                    bool          mapHasChanged = ManageMapChanges(nnoi1, nnoi2, id, moi1, moi2, objectRecursionLevel
                                                                   );
                    hasChanged = hasChanged || mapHasChanged;
                    continue;
                }
                if (value1.IsEnumObject())
                {
                    EnumNativeObjectInfo enoi1 = (EnumNativeObjectInfo)value1;
                    EnumNativeObjectInfo enoi2 = (EnumNativeObjectInfo)value2;
                    bool enumHasChanged        = !enoi1.GetEnumClassInfo().GetId().Equals(enoi2.GetEnumClassInfo
                                                                                              ().GetId()) || !enoi1.GetEnumName().Equals(enoi2.GetEnumName());
                    hasChanged = hasChanged || enumHasChanged;
                    continue;
                }
                if (value1.IsNonNativeObject())
                {
                    NonNativeObjectInfo oi1 = (NonNativeObjectInfo)value1;
                    NonNativeObjectInfo oi2 = (NonNativeObjectInfo)value2;
                    // If oids are equal, they are the same objects
                    if (oi1.GetOid() != null && oi1.GetOid().Equals(oi2.GetOid()))
                    {
                        hasChanged = HasChanged(value1, value2, objectRecursionLevel + 1) || hasChanged;
                    }
                    else
                    {
                        // This means that an object reference has changed.
                        hasChanged = true;
                        // keep track of the position where the reference must be
                        // updated
                        long positionToUpdateReference = nnoi1.GetAttributeDefinitionPosition(id);
                        StoreNewObjectReference(positionToUpdateReference, oi2, objectRecursionLevel, nnoi1
                                                .GetClassInfo().GetAttributeInfoFromId(id).GetName());
                        objectRecursionLevel++;
                        // Value2 may have change too
                        AddPendingVerification(value2);
                    }
                    continue;
                }
            }
            int i1 = (int)alreadyCheckingObjects[nnoi1];
            int i2 = (int)alreadyCheckingObjects[nnoi2];

            if (i1 != null)
            {
                i1 = i1 - 1;
            }
            if (i2 != null)
            {
                i2 = i2 - 1;
            }
            if (i1 == 0)
            {
                alreadyCheckingObjects.Remove(nnoi1);
            }
            else
            {
                alreadyCheckingObjects.Add(nnoi1, i1);
            }
            if (i2 == 0)
            {
                alreadyCheckingObjects.Remove(nnoi2);
            }
            else
            {
                alreadyCheckingObjects.Add(nnoi2, i2);
            }
            return(hasChanged);
        }