Пример #1
0
        private bool Goto(SimPosition globalEnd, double distance)
        {
            bool OnlyStart = true;
            bool MadeIt    = true;

            int maxTryAgains            = 0;
            IList <Vector3d> route      = null;
            CollisionPlane   MoverPlane = MoverPlaneZ;
            bool             faked;
            bool             changePlanes = false;

            while (OnlyStart && MadeIt)
            {
                float    InitZ = Mover.SimPosition.Z;
                Vector3d v3d   = GetWorldPosition();
                if (Mover.Distance(FinalPosition) < distance)
                {
                    return(true);
                }
                float G = MoverPlane.GlobalBumpConstraint;
                if (G < 1f)
                {
                    Orig = G;
                }
                SimMoverState prev = STATE;
                STATE = SimMoverState.THINKING;
                route = SimPathStore.GetPath(MoverPlane, v3d, globalEnd.UsePosition.GlobalPosition, distance, out OnlyStart, out faked);
                // todo need to look at OnlyStart?
                PreXp = route.Count < 3 && G < MaxBigZ;
                while (route.Count < 3 && G < MaxBigZ && faked)
                {
                    if (G < 0.5)
                    {
                        G += 0.1f;
                    }
                    else
                    {
                        G += 0.5f;
                        if (Works > G)
                        {
                            G = Works;
                        }
                    }

                    MoverPlane.GlobalBumpConstraint = G;
                    route = SimPathStore.GetPath(MoverPlane, v3d, globalEnd.UsePosition.GlobalPosition, distance, out OnlyStart, out faked);
                }
                if (PreXp)
                {
                    Works = G;
                    UsedBigZ++;
                    Debug("BigG used {0} instead of {1} !!", G, Orig);
                    OnlyStart = true;
                }
                else
                {  // not PreXP
                    if (UsedBigZ > 0)
                    {
                        if (Works > 0.7f)
                        {
                            Works -= 0.5f;                // todo not as liberal the next time?
                        }
                        UsedBigZ = 0;
                        Debug("BigG RESTORE {0} instead of {1} !!", Orig, MoverPlane.GlobalBumpConstraint);
                        MoverPlane.GlobalBumpConstraint = Orig;
                    }
                }
                STATE = prev;
                STATE = FollowPathTo(route, globalEnd.UsePosition.GlobalPosition, distance);
                Vector3 newPos = GetSimPosition();
                switch (STATE)
                {
                case SimMoverState.TRYAGAIN:
                {
                    if (maxTryAgains-- > 0)
                    {
                        OnlyStart = true;
                        continue;
                    }
                    MadeIt = false;
                    continue;
                }

                case SimMoverState.COMPLETE:
                {
                    MadeIt = true;
                    continue;
                }

                case SimMoverState.BLOCKED:
                {
                    float globalEndUsePositionGlobalPositionZ = (float)globalEnd.UsePosition.GlobalPosition.Z;
                    if (faked)
                    {
                        if (Math.Abs(Mover.SimPosition.Z - InitZ) > 1)
                        {
                            MoverPlane = MoverPlanes[Mover] = PathStore.GetCollisionPlane(Mover.SimPosition.Z);
                        }
                        else
                        {
                            MoverPlane = MoverPlanes[Mover] = PathStore.GetCollisionPlane(globalEndUsePositionGlobalPositionZ);
                        }
                    }
                    OnlyStart = true;
                    MadeIt    = false;
                    continue;
                }

                case SimMoverState.PAUSED:
                case SimMoverState.MOVING:
                case SimMoverState.THINKING:
                default:
                {
                    //MadeIt = true;
                    OnlyStart = true;
                    continue;
                }
                }
            }
            if (!MadeIt && route != null)
            {
                SimMoverState prev = STATE;
                STATE = SimMoverState.THINKING;
                CollisionPlane CP = MoverPlane;
                if (CP.HeightMapNeedsUpdate)
                {
                    CP.MatrixNeedsUpdate = true;
                }
                if (!CP.MatrixNeedsUpdate || !CP.HeightMapNeedsUpdate)
                {
                    if (false)
                    {
                        CP.MatrixNeedsUpdate    = true;
                        CP.HeightMapNeedsUpdate = true;
                        Debug("Faking matrix needs update?");
                    }
                }
                else
                {
                    Debug("Matrix really needed update");
                }
                Vector3d v3d = GetWorldPosition();
                double   fd  = DistanceNoZ(v3d, globalEnd.GlobalPosition);
                if (fd < distance)
                {
                    STATE = SimMoverState.COMPLETE;
                    return(true);
                }
                CP.EnsureUpdated();
                int index = ClosetPointOnRoute(route, v3d);
                if (index > 0)
                {
                    var blockMe = new List <Vector3d>();
                    if (index + 2 < route.Count)
                    {
                        Vector3d firstBad = route[index + 1];
                        var      np       = v3d + ((firstBad - v3d) / 2);
                        blockMe.Add(np);
                        blockMe.Add(firstBad);
                        DepricateRoute(blockMe, fd);
                        STATE = prev;
                        return(MadeIt);
                    }
                }

                if (fd > distance && fd > 2)
                {
                    if (false)
                    {
                        DepricateRoute(route, fd);
                    }
                }
                Debug("Too far away " + fd + " wanted " + distance);
                STATE = prev;
            }
            return(MadeIt);
        }
 private CollisionPlane CollisionPlaneAt(float z)
 {
     return(PathStore.GetCollisionPlane(z));
 }