/// <summary>
        /// To complete the step, all the elements inside the step must be completed.
        /// For all the elements except for paths (LineString geometries) the elements are one,
        /// so the step is completed in one element completition.
        /// </summary>
        /// <param name="currentStep"></param>
        private bool CompleteStep(NavigationStep currentStep)
        {
            bool completed = false;

            var elems = GetElementsFor(currentStep);

            if (elems == 1)
            {
                completed = true;
            }
            else
            {
                // If this is the first time we deal with this step, lets say we are in the 0
                if (!completedElementsForStep.ContainsKey(currentStep))
                {
                    completedElementsForStep.Add(currentStep, 0);
                }

                // Add one
                completedElementsForStep[currentStep]++;
                // Is completed if it matches in number
                if (completedElementsForStep[currentStep] == elems)
                {
                    completed = true;
                }
            }

            // Only complete
            completed &= !currentStep.LockNavigation;

            stepCompleted[currentStep] = completed;

            SaveNavigation(Game.Instance.GameState.GetMemory("geo_extension"));
            return(completed);
        }
        public void SomethingReached(GameObject gb)
        {
            if (navigating && currentStep != null && currentStep.Reference == gb.name)
            {
                var mb = GetReference(gb.name);
                if (mb != null)
                {
                    // Check if reached
                    bool reached = IsReached(mb);
                    UpdateArrow(reached);

                    // Go next
                    if (reached && !currentStep.LockNavigation && CompleteStep(currentStep))
                    {
                        // If the step is completed successfully we set the current step to null
                        currentStep = null;

                        if (stepCompleted.All(kv => kv.Value))
                        {
                            // Navigation finished
                            navigating = false;
                            SaveNavigation(Game.Instance.GameState.GetMemory("geo_extension"));
                            DestroyImmediate(this.gameObject);
                        }
                    }
                }
            }
        }
        // -------------------------
        // Public methods
        // -------------------------

        public void Navigate()
        {
            Init();

            navigating = true;
            if (Steps.Count > 0)
            {
                currentStep = Steps[0];
            }

            SaveNavigation(Game.Instance.GameState.GetMemory("geo_extension"));
        }
        // -------------------------
        // Public methods
        // -------------------------

        public void Navigate()
        {
            Init();

            navigating = true;
            if (Steps.Count > 0)
            {
                currentStep = Steps[0];
            }

            SaveNavigation();
        }
        private bool IsReached(NavigationStep currentStep)
        {
            if (!character)
            {
                character = FindObjectOfType <GeoPositionedCharacter>();
            }

            var mb = GetReference(currentStep.Reference);

            if (mb == null)
            {
                return(false); // If the element is not there, just try to skip it
            }
            return(IsReached(mb));
        }
        private int GetElementsFor(NavigationStep currentStep)
        {
            var mb = GetReference(currentStep.Reference);

            if (mb is GeoElementMB && (mb as GeoElementMB).Element.Geometry.Type == GMLGeometry.GeometryType.LineString)
            {
                // If it is a path, all the points are elements
                return((mb as GeoElementMB).Element.Geometry.Points.Count);
            }
            else
            {
                // Just itself is the element
                return(1);
            }
        }
        private int GetElementsFor(NavigationStep currentStep)
        {
            var mb           = GetReference(currentStep.Reference);
            var geoElementMb = mb as GeoElementMB;

            if (geoElementMb != null && geoElementMb.Geometry.Type == GMLGeometry.GeometryType.LineString)
            {
                // If it is a path, all the points are elements
                return(geoElementMb.Geometry.Points.Length);
            }
            else
            {
                // Just itself is the element
                return(1);
            }
        }
        private bool IsReached(NavigationStep currentStep)
        {
            if (!character)
            {
                character = FindObjectOfType <GeoPositionedCharacter>();
            }

            var mb = GetReference(currentStep.Reference);

            if (mb == null)
            {
                return(false); // If the element is not there, just try to skip it
            }
            else if (mb is GeoWrapper)
            {
                var wrap             = mb as GeoWrapper;
                var position         = (Vector2d)wrap.Reference.TransformManagerParameters["Position"];
                var interactionRange = (float)wrap.Reference.TransformManagerParameters["InteractionRange"];

                var distance     = GM.SeparationInMeters(position, character.LatLon);
                var realDistance = GM.SeparationInMeters(position, Input.location.lastData.LatLonD());

                // Is inside if the character is in range but also the real coords are saying so
                // Otherwise, if there is no character or gps, only one of the checks is valid

                return((!character || distance < interactionRange) &&
                       (!GPSController.Instance.IsStarted() || realDistance < interactionRange) &&
                       (GPSController.Instance.IsStarted() || character));
            }
            else if (mb is GeoElementMB)
            {
                var geomb = mb as GeoElementMB;

                // Is inside if the character is inside the influence but also the real coords are saying so
                // Otherwise, if there is no character or gps, only one of the checks is valid

                // TODO check if the line element is reached
                return((!character || geomb.Element.Geometry.InsideInfluence(character.LatLon)) &&
                       (!GPSController.Instance.IsStarted() || geomb.Element.Geometry.InsideInfluence(Input.location.lastData.LatLonD())) &&
                       (GPSController.Instance.IsStarted() || character));
            }
            else
            {
                return(false);
            }
        }
        public void Update()
        {
            if (navigating)
            {
                if (NavigationStrategy == NavigationType.Closeness)
                {
                    currentStep = FindClosestStep(Steps);
                }
                else if (currentStep == null)
                {
                    currentStep = FindNextStep(Steps);
                }

                if (currentStep != null)
                {
                    // Check if reached
                    bool reached = IsReached(currentStep);
                    UpdateArrow(reached);

                    // Go next
                    if (reached && !currentStep.LockNavigation)
                    {
                        // If the step is completed successfully we set the current step to null
                        if (CompleteStep(currentStep))
                        {
                            currentStep = null;

                            if (stepCompleted.All(kv => kv.Value == true))
                            {
                                // Navigation finished
                                navigating = false;
                                SaveNavigation();
                                DestroyImmediate(this.gameObject);
                            }
                        }
                    }
                }
            }
        }
示例#10
0
        private bool IsReached(NavigationStep currentStep)
        {
            if (!character)
            {
                character = FindObjectOfType <GeoPositionedCharacter>();
            }

            var mb = GetReference(currentStep.Reference);

            if (mb == null)
            {
                return(false); // If the element is not there, just try to skip it
            }
            else if (mb is GeoPositioner)
            {
                var wrap             = mb as GeoPositioner;
                var position         = (Vector2d)wrap.Context.TransformManagerParameters["Position"];
                var interactionRange = (float)wrap.Context.TransformManagerParameters["InteractionRange"];

                var distance     = GM.SeparationInMeters(position, character.LatLon);
                var realDistance = GM.SeparationInMeters(position, GeoExtension.Instance.Location);

                // Is inside if the character is in range but also the real coords are saying so
                // Otherwise, if there is no character or gps, only one of the checks is valid

                return((!character || distance < interactionRange) &&
                       (!GeoExtension.Instance.IsStarted() || realDistance < interactionRange) &&
                       (GeoExtension.Instance.IsStarted() || character));
            }
            else if (mb is GeoElementMB)
            {
                var geomb = mb as GeoElementMB;

                // Is inside if the character is inside the influence but also the real coords are saying so
                // Otherwise, if there is no character or gps, only one of the checks is valid

                var location = character ? character.LatLon : GeoExtension.Instance.Location;
                if (geomb.Geometry.InsideInfluence(location))
                {
                    if (geomb.Geometry.Type == GMLGeometry.GeometryType.LineString)
                    {
                        var step = 0;
                        completedElementsForStep.TryGetValue(currentStep, out step);
                        var position = geomb.Geometry.Points[step];
                        var distance = GM.SeparationInMeters(position, location);
                        return(distance < geomb.Geometry.Influence);
                    }
                    else
                    {
                        return(true);
                    }
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }