Ejemplo n.º 1
0
        private bool considerPoint(InvestigatedPoint point)
        {
            if (point.Time < _timeOfReset)
            {
                return(false);
            }

            if (_hasPoint && areCloseEnough(point, _point))
            {
                _hasPoint = false;
                markInvestigated(point);
                return(true);
            }

            if (considerPoint(_block, point))
            {
                return(true);
            }

            for (int i = 0; i < _blocks.Count; i++)
            {
                if (considerPoint(_blocks[i], point))
                {
                    if (_blocks[i].Empty)
                    {
                        _investigatedBlocks.Add(_blocks[i]);
                        _blocks.RemoveAt(i);
                    }

                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 2
0
        private bool areCloseEnough(InvestigatedPoint a, SearchPoint b)
        {
            if (Vector3.Distance(a.Position, b.Position) < 0.5f)
            {
                return(true);
            }

            return(false);
        }
Ejemplo n.º 3
0
        private void finishInvestigatingThePoint()
        {
            var point = new InvestigatedPoint(_point.Position);

            _hasPoint = false;

            markInvestigated(point);

            for (int i = 0; i < _friends.Count; i++)
            {
                _friends[i].considerPoint(point);
            }
        }
Ejemplo n.º 4
0
        private bool considerPoint(SearchBlock block, InvestigatedPoint point)
        {
            for (int i = 0; i < block.Count; i++)
            {
                if (areCloseEnough(point, block.Get(i)))
                {
                    block.Investigate(i);
                    markInvestigated(point);
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Told by the brains to force mark a position as investigated.
        /// </summary>
        public void ToMarkPointInspected(Vector3 position)
        {
            if (!isActiveAndEnabled)
            {
                return;
            }

            var point = new InvestigatedPoint(position);

            if (!considerPoint(point))
            {
                markInvestigated(point);
            }

            foreach (var friend in _friends)
            {
                friend.considerPoint(point);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Told by the brains to force mark a position as investigated.
        /// </summary>
        public void ToMarkPointInspected(Vector3 position)
        {
            if (!isActiveAndEnabled)
            {
                return;
            }

            var point = new InvestigatedPoint(position);

            if (!considerPoint(point))
            {
                markInvestigated(point);
            }

            for (int i = 0; i < _friends.Count; i++)
            {
                _friends[i].considerPoint(point);
            }
        }
Ejemplo n.º 7
0
        private void glimpse(SearchBlock block)
        {
            for (int i = block.Count - 1; i >= 0; i--)
            {
                var p = block.Get(i);

                if (canBeInvestigated(p))
                {
                    var point = new InvestigatedPoint(p.Position);
                    markInvestigated(point);

                    foreach (var friend in _friends)
                    {
                        friend.considerPoint(point);
                    }

                    block.Investigate(i);
                }
            }
        }
Ejemplo n.º 8
0
 private void markInvestigated(InvestigatedPoint point)
 {
     _investigated.Add(point);
     Message("OnPointInvestigated", point.Position);
 }
Ejemplo n.º 9
0
        private void Update()
        {
            for (int i = _investigated.Count - 1; i >= 0; i--)
            {
                if (_investigated[i].Time < Time.timeSinceLevelLoad - MaxInvestigationAge)
                {
                    _investigated.RemoveAt(i);
                }
            }

            if (!_isSearching)
            {
                return;
            }

            if (_blocks.Count == 0 && !_hasPoint)
            {
                ToClearSearchHistory();

                _hasPreviousPoint = false;
                _points.Clear();

                foreach (var block in _investigatedBlocks)
                {
                    _blockCache.Give(block);
                }

                _investigatedBlocks.Clear();
                _usedCovers.Clear();
                _coverCache.Reset(transform.position, MaxDistance, false);

                foreach (var item in _coverCache.Items)
                {
                    if (_usedCovers.Contains(item.Cover))
                    {
                        continue;
                    }

                    var cover = item.Cover;

                    while (cover.LeftAdjacent != null && !_usedCovers.Contains(cover.LeftAdjacent))
                    {
                        cover = cover.LeftAdjacent;
                    }

                    var index = -1;

                    while (cover != null)
                    {
                        _usedCovers.Add(cover);

                        var left   = cover.LeftCorner(cover.Bottom) - cover.Forward * 0.25f;
                        var right  = cover.RightCorner(cover.Bottom) - cover.Forward * 0.25f;
                        var vector = right - left;
                        var length = vector.magnitude;

                        var leftApproach  = left;
                        var rightApproach = right;

                        {
                            NavMeshHit hit;
                            var        position = left + cover.Left * CoverOffset;

                            if (NavMesh.Raycast(left, position, out hit, 1))
                            {
                                leftApproach = left;
                            }
                            else
                            {
                                leftApproach = position;
                            }
                        }

                        {
                            NavMeshHit hit;
                            var        position = right + cover.Right * CoverOffset;

                            if (NavMesh.Raycast(right, position, out hit, 1))
                            {
                                rightApproach = right;
                            }
                            else
                            {
                                rightApproach = position;
                            }
                        }

                        if (cover.LeftAdjacent != null && cover.RightAdjacent != null)
                        {
                            leftApproach  = left;
                            rightApproach = right;
                        }
                        else if (cover.LeftAdjacent != null)
                        {
                            leftApproach = rightApproach;
                        }
                        else if (cover.RightAdjacent != null)
                        {
                            rightApproach = leftApproach;
                        }

                        possiblyAddRightPoint(ref index, new SearchPoint(left, leftApproach, -cover.Forward, false));

                        if (length > Advanced.BlockThreshold * 2)
                        {
                            possiblyAddRightPoint(ref index, new SearchPoint(left + vector * 0.2f, leftApproach, -cover.Forward, false));
                            possiblyAddRightPoint(ref index, new SearchPoint(left + vector * 0.4f, leftApproach, -cover.Forward, false));
                            possiblyAddRightPoint(ref index, new SearchPoint(left + vector * 0.6f, rightApproach, -cover.Forward, false));
                            possiblyAddRightPoint(ref index, new SearchPoint(left + vector * 0.8f, rightApproach, -cover.Forward, false));
                        }
                        else if (length > Advanced.BlockThreshold)
                        {
                            possiblyAddRightPoint(ref index, new SearchPoint(left + vector * 0.33f, leftApproach, -cover.Forward, false));
                            possiblyAddRightPoint(ref index, new SearchPoint(left + vector * 0.66f, rightApproach, -cover.Forward, false));
                        }

                        possiblyAddRightPoint(ref index, new SearchPoint(right, rightApproach, -cover.Forward, false));

                        if (cover.RightAdjacent != null && !_usedCovers.Contains(cover.RightAdjacent))
                        {
                            cover = cover.RightAdjacent;
                        }
                        else
                        {
                            cover = null;
                        }
                    }
                }

                _zoneCache.Reset(transform.position, MaxDistance);

                foreach (var block in _zoneCache.Items)
                {
                    foreach (var position in block.Points(Advanced.BlockThreshold))
                    {
                        addPoint(new SearchPoint(position, false));
                    }
                }

                mergeBlocks();
            }

            if (DebugPoints)
            {
                foreach (var block in _blocks)
                {
                    debugBlock(block);
                }

                foreach (var block in _investigatedBlocks)
                {
                    debugBlock(block);
                }
            }

            if (_blocks.Count == 0 && !_hasPoint)
            {
                return;
            }

            if (_block.Empty && !_hasPoint)
            {
                var pickedIndex   = -1;
                var previousValue = 0f;

                for (int i = 0; i < _blocks.Count; i++)
                {
                    var vector    = _searchPosition - _blocks[i].Center;
                    var distance  = vector.magnitude;
                    var direction = vector / distance;

                    var value = distance;

                    if (_hasBlockDirection)
                    {
                        value *= -Vector3.Dot(direction, _blockDirection) * 0.5f + 1.5f;
                    }
                    else
                    {
                        value *= -Vector3.Dot(direction, _actor.HeadDirection) * 0.5f + 1.5f;
                    }

                    if (pickedIndex < 0 || value < previousValue)
                    {
                        pickedIndex   = i;
                        previousValue = value;
                    }
                }


                if (pickedIndex != -1)
                {
                    _block = _blocks[pickedIndex];

                    _blocks.RemoveAt(pickedIndex);
                    _investigatedBlocks.Add(_block);

                    _hasBlockDirection = true;
                    _blockDirection    = (_block.Center - _searchPosition).normalized;
                }
            }

            if (!_hasPoint)
            {
                int   index;
                float value;
                findBestPoint(_block, out index, out value);

                setPoint(_block.Indices[index]);
                _block.Investigate(index);
            }

            if (!_hasApproached && !shouldApproach(_point))
            {
                _hasApproached = true;

                if (_wasRunning)
                {
                    run();
                }
                else
                {
                    walk();
                }
            }

            if (_wasRunning && !shouldRunTo(_point.Position))
            {
                walk();
            }

            _checkWait -= Time.deltaTime;

            if (_checkWait <= float.Epsilon)
            {
                glimpse(_block);

                for (int b = _blocks.Count - 1; b >= 0; b--)
                {
                    glimpse(_blocks[b]);

                    if (_blocks[b].Empty)
                    {
                        _investigatedBlocks.Add(_blocks[b]);
                        _blocks.RemoveAt(b);
                    }
                }

                _checkWait = 0.25f;
            }

            if (DebugTarget)
            {
                Debug.DrawLine(transform.position, _point.Position, Color.yellow);
            }

            if (canBeInvestigated(_point))
            {
                var point = new InvestigatedPoint(_point.Position);
                _hasPoint = false;

                markInvestigated(point);

                foreach (var friend in _friends)
                {
                    friend.considerPoint(point);
                }
            }
        }