Exemple #1
0
        private int GetIndex(Seeker seeker)
        {
            int   index              = -1;
            float verticalMidpoint   = Bounds.xMin + (Bounds.width / 2f);
            float horizontalMidpoint = Bounds.yMin + (Bounds.height / 2f);

            var position = seeker.transform.position;
            // Seeker is inside the top half

            bool topQuadrant = _pathfinder.worldStart.z - position.z < horizontalMidpoint;
            // Seeker is inside the bottom half
            bool bottomQuadrant = _pathfinder.worldStart.z - position.z >= horizontalMidpoint;

            // Seeker is inside the left half
            if (seeker.transform.position.x - _pathfinder.worldStart.x < verticalMidpoint)
            {
                if (topQuadrant)
                {
                    index = 1;
                }
                else if (bottomQuadrant)
                {
                    index = 2;
                }
            }

            // Seeker is inside the right half
            else if (seeker.transform.position.x - _pathfinder.worldStart.x >= verticalMidpoint)
            {
                if (topQuadrant)
                {
                    index = 0;
                }
                else if (bottomQuadrant)
                {
                    index = 3;
                }
            }

            return(index);
        }
Exemple #2
0
        public void insert(Seeker seeker)
        {
            if (nodesInUse)
            {
                int index = getIndex(seeker);

                if (index != -1)
                {
                    nodes[index].insert(seeker);

                    return;
                }
            }

            objects.Add(seeker);

            if (objects.Count > maxObjectsPerQuad && level < maxDepthLevel)
            {
                nodesInUse = true;

                int i = 0;
                while (i < objects.Count)
                {
                    Seeker obj = objects[i];

                    int index = getIndex(obj);
                    if (index != -1)
                    {
                        nodes[index].insert(obj);
                        objects.Remove(obj);
                    }
                    else
                    {
                        i++;
                    }
                }
            }
        }
Exemple #3
0
        public void Insert(Seeker seeker)
        {
            if (NodesInUse)
            {
                int index = GetIndex(seeker);

                if (index != -1)
                {
                    Nodes[index].Insert(seeker);

                    return;
                }
            }

            Objects.Add(seeker);

            if (Objects.Count > MaxObjectsPerQuad && _level < MaxDepthLevel)
            {
                NodesInUse = true;

                int i = 0;
                while (i < Objects.Count)
                {
                    Seeker obj = Objects[i];

                    int index = GetIndex(obj);
                    if (index != -1)
                    {
                        Nodes[index].Insert(obj);
                        Objects.Remove(obj);
                    }
                    else
                    {
                        i++;
                    }
                }
            }
        }
Exemple #4
0
 // Add seeker to already calculated flowPath, for example, there is 1 flowfield path for all characters in a tower defence game
 // and you want to add characters over time.
 public void AddSeekerToExistingFlowField(int flowFieldPathKey, Seeker seeker)
 {
     charactersInFlowPath[flowFieldPathKey].Add(seeker);
     seeker.SetFlowField(worldData.flowFieldManager.flowFieldPaths[flowFieldPathKey], false);
 }
Exemple #5
0
        private int getIndex(Seeker seeker)
        {
            int index = -1;

            // Seeker is inside the top half // 2dview
            bool topQuadrant = seeker.transform.position.z > bounds[1];
            // Seeker is inside the bottom half // 2dview
            bool bottomQuadrant = seeker.transform.position.z <= bounds[1];
            // Seeker is inside the top height half
            bool topWorldY_Quadrant = seeker.transform.position.y >= bounds[2];

            // Seeker is inside the left half
            if (seeker.transform.position.x < bounds[0])
            {
                if (topWorldY_Quadrant)
                {
                    if (topQuadrant)
                    {
                        index = 5;
                    }
                    else if (bottomQuadrant)
                    {
                        index = 6;
                    }
                }
                else
                {
                    if (topQuadrant)
                    {
                        index = 1;
                    }
                    else if (bottomQuadrant)
                    {
                        index = 2;
                    }
                }
            }

            // Seeker is inside the right half
            else if (seeker.transform.position.x >= bounds[0])
            {
                if (topWorldY_Quadrant)
                {
                    if (topQuadrant)
                    {
                        index = 4;
                    }
                    else if (bottomQuadrant)
                    {
                        index = 7;
                    }
                }
                else
                {
                    if (topQuadrant)
                    {
                        index = 0;
                    }
                    else if (bottomQuadrant)
                    {
                        index = 3;
                    }
                }
            }

            return(index);
        }
Exemple #6
0
        public void CheckIfMovementLegit(Seeker seeker)
        {
            if (seeker.currentTile != null && seeker.currentWorldArea != null)
            {
                int xDir = 0;
                int yDir = 0;

                bool capXMovement  = false;
                bool capZMovement  = false;
                int  areaXMovement = -1;
                int  areaZMovement = -1;

                if (seeker.movement.x != 0)
                {
                    if (seeker.movement.x > 0)
                    {
                        xDir = 1;
                    }
                    else
                    {
                        xDir = -1;
                    }
                }

                if (seeker.movement.z != 0)
                {
                    if (seeker.movement.z > 0)
                    {
                        yDir = -1;
                    }
                    else
                    {
                        yDir = 1;
                    }
                }

                if (yDir == 0 && xDir == 0)
                {
                    // nothing changed
                }
                else
                {
                    Tile destination;
                    if (seeker.currentTile.GridPos.X + xDir > -1 &&
                        seeker.currentTile.GridPos.X + xDir < seeker.currentWorldArea.GridWidth)
                    {
                        // inside world area
                        destination =
                            seeker.currentWorldArea.TileGrid[seeker.currentTile.GridPos.X + xDir][
                                seeker.currentTile.GridPos.Y];
                        if (destination == null) // null, can we travel to another world area, or is there nothing?
                        {
                            areaXMovement = CheckIfMovingToOtherArea(seeker, xDir, 0);
                            capXMovement  = true;
                        }
                        else if (destination.Blocked)
                        {
                            capXMovement = true;
                        }
                    }
                    else
                    {
                        areaXMovement = CheckIfMovingToOtherArea(seeker, xDir, 0);
                        capXMovement  = true;
                    }

                    if (seeker.currentTile.GridPos.Y + yDir > -1 &&
                        seeker.currentTile.GridPos.Y + yDir < seeker.currentWorldArea.GridLength)
                    {
                        // inside world area
                        destination =
                            seeker.currentWorldArea.TileGrid[seeker.currentTile.GridPos.X][
                                seeker.currentTile.GridPos.Y + yDir];
                        if (destination == null) // null, can we travel to another world area, or is there nothing?
                        {
                            areaZMovement = CheckIfMovingToOtherArea(seeker, 0, yDir);
                            capZMovement  = true;
                        }
                        else if (destination.Blocked)
                        {
                            capZMovement = true;
                        }
                    }
                    else
                    {
                        // outside
                        areaZMovement = CheckIfMovingToOtherArea(seeker, 0, yDir);
                        capZMovement  = true;
                    }

                    if (!capXMovement && !capZMovement) // diagonal check
                    {
                        destination =
                            seeker.currentWorldArea.TileGrid[seeker.currentTile.GridPos.X + xDir][
                                seeker.currentTile.GridPos.Y + yDir];
                        if (destination == null || destination.Blocked)
                        {
                            if (seeker.desiredFlowValue == Vector2.zero)
                            {
                                seeker.movement = Vector3.zero;
                            }
                            else
                            {
                                if (seeker.desiredFlowValue.x == 0 ||
                                    (seeker.desiredFlowValue.x > 0 && seeker.movement.x < 0) ||
                                    (seeker.desiredFlowValue.x < 0 && seeker.movement.x > 0))
                                {
                                    float futureXPos = seeker.transform.position.x + seeker.movement.x;
                                    float border     =
                                        _worldData.TileManager
                                        .GetTileWorldPosition(seeker.currentTile, seeker.currentWorldArea).x +
                                        (_worldData.Pathfinder.tileSize * 0.49f * xDir);
                                    if (xDir == 1 && futureXPos > border)
                                    {
                                        seeker.movement.x -= (futureXPos - border);
                                    }
                                    else if (xDir == -1 && futureXPos < border)
                                    {
                                        seeker.movement.x -= (futureXPos - border);
                                    }
                                }

                                if (seeker.desiredFlowValue.y == 0 ||
                                    (seeker.movement.z > 0 && seeker.desiredFlowValue.y < 0) ||
                                    (seeker.movement.z < 0 && seeker.desiredFlowValue.y > 0))
                                {
                                    float futureZPos = seeker.transform.position.z + seeker.movement.z;
                                    float border     =
                                        _worldData.TileManager
                                        .GetTileWorldPosition(seeker.currentTile, seeker.currentWorldArea).z +
                                        (_worldData.Pathfinder.tileSize * 0.49f * -yDir);
                                    if (yDir == -1 && futureZPos > border)
                                    {
                                        seeker.movement.z -= (futureZPos - border);
                                    }
                                    else if (yDir == 1 && futureZPos < border)
                                    {
                                        seeker.movement.z -= (futureZPos - border);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (areaXMovement != -1 && areaZMovement != -1)
                        {
                            if (seeker.desiredFlowValue.x == 0 ||
                                (seeker.desiredFlowValue.x > 0 && seeker.movement.x < 0) ||
                                (seeker.desiredFlowValue.x < 0 && seeker.movement.x > 0))
                            {
                                areaXMovement = -1;
                            }
                            else
                            {
                                areaZMovement = -1;
                            }
                        }
                    }

                    if (capXMovement)
                    {
                        if (areaXMovement == -1)
                        {
                            float futureXPos = seeker.transform.position.x + seeker.movement.x;
                            float border     =
                                _worldData.TileManager.GetTileWorldPosition(seeker.currentTile, seeker.currentWorldArea)
                                .x + (_worldData.Pathfinder.tileSize * 0.49f * xDir);
                            if (xDir == 1 && futureXPos > border)
                            {
                                seeker.movement.x -= (futureXPos - border);
                            }
                            else if (xDir == -1 && futureXPos < border)
                            {
                                seeker.movement.x -= (futureXPos - border);
                            }
                        }
                        else
                        {
                            if (yDir != 0)
                            {
                                bool capZ = false;
                                int  destinationAreaGridX =
                                    (seeker.currentTile.GridPos.X + xDir + seeker.currentWorldArea.LeftOffset) -
                                    _worldData.WorldAreas[areaXMovement].LeftOffset;
                                int destinationAreaGridY =
                                    (seeker.currentTile.GridPos.Y + yDir + seeker.currentWorldArea.TopOffset) -
                                    _worldData.WorldAreas[areaXMovement].TopOffset;

                                if (destinationAreaGridY < _worldData.WorldAreas[areaXMovement].GridLength &&
                                    destinationAreaGridY > -1)
                                {
                                    destination =
                                        _worldData.WorldAreas[areaXMovement].TileGrid[destinationAreaGridX][
                                            destinationAreaGridY];
                                    if (destination == null || destination.Blocked)
                                    {
                                        capZ = true;
                                    }
                                }
                                else
                                {
                                    capZ = true;
                                }

                                if (capZ)
                                {
                                    float futureZPos = seeker.transform.position.z + seeker.movement.z;
                                    float border     =
                                        _worldData.TileManager
                                        .GetTileWorldPosition(seeker.currentTile, seeker.currentWorldArea).z +
                                        (_worldData.Pathfinder.tileSize * 0.49f * -yDir);
                                    if (yDir == -1 && futureZPos > border)
                                    {
                                        seeker.movement.z -= (futureZPos - border);
                                    }
                                    else if (yDir == 1 && futureZPos < border)
                                    {
                                        seeker.movement.z -= (futureZPos - border);
                                    }
                                }
                            }
                        }
                    }

                    if (capZMovement)
                    {
                        if (areaZMovement == -1)
                        {
                            float futureZPos = seeker.transform.position.z + seeker.movement.z;
                            float border     =
                                _worldData.TileManager.GetTileWorldPosition(seeker.currentTile, seeker.currentWorldArea)
                                .z + (_worldData.Pathfinder.tileSize * 0.49f * -yDir);
                            if (yDir == -1 && futureZPos > border)
                            {
                                seeker.movement.z -= (futureZPos - border);
                            }
                            else if (yDir == 1 && futureZPos < border)
                            {
                                seeker.movement.z -= (futureZPos - border);
                            }
                        }
                        else
                        {
                            if (yDir != 0)
                            {
                                bool capX = false;
                                int  destinationAreaGridX =
                                    (seeker.currentTile.GridPos.X + xDir + seeker.currentWorldArea.LeftOffset) -
                                    _worldData.WorldAreas[areaZMovement].LeftOffset;
                                int destinationAreaGridY =
                                    (seeker.currentTile.GridPos.Y + yDir + seeker.currentWorldArea.TopOffset) -
                                    _worldData.WorldAreas[areaZMovement].TopOffset;

                                if (destinationAreaGridX < _worldData.WorldAreas[areaZMovement].GridWidth &&
                                    destinationAreaGridX > -1)
                                {
                                    destination =
                                        _worldData.WorldAreas[areaZMovement].TileGrid[destinationAreaGridX][
                                            destinationAreaGridY];
                                    if (destination == null || destination.Blocked)
                                    {
                                        capX = true;
                                    }
                                }
                                else
                                {
                                    capX = true;
                                }

                                if (capX)
                                {
                                    float futureXPos = seeker.transform.position.x + seeker.movement.x;
                                    float border     =
                                        _worldData.TileManager
                                        .GetTileWorldPosition(seeker.currentTile, seeker.currentWorldArea).x +
                                        (_worldData.Pathfinder.tileSize * 0.49f * xDir);
                                    if (xDir == 1 && futureXPos > border)
                                    {
                                        seeker.movement.x -= (futureXPos - border);
                                    }
                                    else if (xDir == -1 && futureXPos < border)
                                    {
                                        seeker.movement.x -= (futureXPos - border);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Exemple #7
0
 // remove a seeker when you do not want him to move / or is dead/removed
 public void RemoveSeeker(Seeker seeker)
 {
     _allSeekers.Remove(seeker);
 }
Exemple #8
0
        public Vector2 FindFlowValueFromPosition(Vector3 worldPosition, FlowField flowField, Seeker seeker)
        {
            seeker.currentWorldArea = null;
            seeker.currentTile      = null;

            Vector2   vec  = Vector2.zero;
            WorldArea area = _worldData.TileManager.GetWorldAreaAtPosition(worldPosition);

            if (area != null)
            {
                int worldX = _worldData.TileManager.LocationToWorldGridX(worldPosition);
                int worldY = _worldData.TileManager.LocationToWorldGridY(worldPosition);

                //Debug.Log("Area Index: " + area.Index);
                //Debug.Log("WorldX: " + (worldX - area.LeftOffset));

                Tile tile = area.TileGrid[worldX - area.LeftOffset][worldY - area.TopOffset];
                if (tile != null)
                {
                    seeker.currentWorldArea = area;
                    seeker.currentTile      = tile;

                    _key.X = area.Index;
                    _key.Y = tile.SectorIndex;

                    if (flowField.Field.ContainsKey(_key))
                    {
                        vec = _worldData.FlowFieldManager.DirToVector(flowField.Field[_key][tile.IndexWithinSector]);
                    }
                }
            }

            return(vec);
        }
Exemple #9
0
 // add seeker to manager, now the seeker's tick() will be called,  thus making him move
 public void AddSeeker(Seeker seeker)
 {
     _allSeekers.Add(seeker);
 }
Exemple #10
0
 public void SetNeighboursQuad(Seeker seeker, float neighbourRadiusSquared)
 {
     SetSearchBoxQuad(seeker);
     RetrieveSeekerNeighboursQuad(seeker, neighbourRadiusSquared);
 }
Exemple #11
0
        private int CheckIfMovingToOtherArea(Seeker seeker, int xDir, int yDir)
        {
            //if (_worldData.Pathfinder.worldIsMultiLayered)
            //{
            IntVector2 key = seeker.currentTile.GridPos;

            if (seeker.currentWorldArea.WorldAreaTileConnections.ContainsKey(key)
                ) // if our current tile connects to tile in another world area, outside of our own tile grid
            {
                List <IntVector3> values = seeker.currentWorldArea.WorldAreaTileConnections[key];

                for (int i = 0; i < values.Count; i++)
                {
                    if (!_worldData.WorldAreas[values[i].Z].TileGrid[values[i].X][values[i].Y].Blocked)
                    {
                        if (xDir != 0)
                        {
                            if (_worldData.WorldAreas[values[i].Z].TopOffset + values[i].Y ==
                                seeker.currentWorldArea.TopOffset + key.Y
                                ) // align on Z. its straight ahead or behind
                            {
                                if (xDir == 1 && (_worldData.WorldAreas[values[i].Z].LeftOffset + values[i].X >
                                                  seeker.currentWorldArea.LeftOffset + key.X))     // right
                                {
                                    return(values[i].Z);
                                }
                                if (xDir == -1 &&
                                    (_worldData.WorldAreas[values[i].Z].LeftOffset + values[i].X <
                                     seeker.currentWorldArea.LeftOffset + key.X))     // left
                                {
                                    return(values[i].Z);
                                }
                            }
                        }
                        else
                        {
                            if (_worldData.WorldAreas[values[i].Z].LeftOffset + values[i].X ==
                                seeker.currentWorldArea.LeftOffset + key.X &&
                                !_worldData.WorldAreas[values[i].Z].TileGrid[values[i].X][values[i].Y].Blocked
                                ) // align on X. its straight ahead or behind
                            {
                                if (yDir == -1 && (_worldData.WorldAreas[values[i].Z].TopOffset + values[i].Y <
                                                   seeker.currentWorldArea.TopOffset + key.Y))     // forward
                                {
                                    return(values[i].Z);
                                }
                                if (yDir == 1 &&
                                    (_worldData.WorldAreas[values[i].Z].TopOffset + values[i].Y >
                                     seeker.currentWorldArea.TopOffset + key.Y))     // back
                                {
                                    return(values[i].Z);
                                }
                            }
                        }
                    }
                }
            }
            //}

            return(-1);
        }
 private void SetSearchBoxQuad(Seeker seeker)
 {
     searchQuad.xMin  = seeker.transform.position.x - pathfinder.worldStart.x - seeker.neighbourRadius;
     searchQuad.yMin  = pathfinder.worldStart.z - seeker.transform.position.z - seeker.neighbourRadius;
     searchQuad.width = searchQuad.height = seeker.neighbourRadius * 2f;
 }
        public Vector2 FindflowValueFromPosition(Vector3 worldPosition, FlowField flowField, Seeker seeker)
        {
            seeker.currentWorldArea = null;
            seeker.currentTile      = null;

            Vector2   vec  = Vector2.zero;
            WorldArea area = worldData.tileManager.GetWorldAreaAtPosition(worldPosition);

            if (area != null)
            {
                int worldX = worldData.tileManager.locationToWorldGridX(worldPosition);
                int worldY = worldData.tileManager.locationToWorldGridY(worldPosition);

                Tile tile = area.tileGrid[worldX - area.leftOffset][worldY - area.topOffset];
                if (tile != null)
                {
                    seeker.currentWorldArea = area;
                    seeker.currentTile      = tile;

                    key.x = area.index;
                    key.y = tile.sectorIndex;

                    if (flowField.field.ContainsKey(key))
                    {
                        vec = worldData.flowFieldManager.DirToVector(flowField.field[key][tile.indexWithinSector]);
                    }
                }
            }

            return(vec);
        }