Exemple #1
0
    public Cell[][] ComputeMap(Cell[][] baseMap, Enemy[] enemies, List <List <Vector2> > cellsByEnemy)
    {
        Cell[][] im = new Cell[cellsX][];

        for (int x = 0; x < cellsX; x++)
        {
            im [x] = new Cell[cellsZ];
            for (int y = 0; y < cellsZ; y++)
            {
                im [x] [y] = baseMap [x] [y].Copy();
            }
        }

        for (int i = 0; i < enemies.Length; i++)
        {
            Enemy enemy = enemies [i];
            // For every enemy, get their direction and current world position and scale into IM scale
            Vector2 dir = new Vector2(enemy.GetSimulatedForward().x, enemy.GetSimulatedForward().z);

            // Convert enemy position into Grid Coordinates
            Vector2 pos = new Vector2((enemy.GetSimulationPosition().x - minX) / tileSizeX, (enemy.GetSimulationPosition().z - minZ) / tileSizeZ);
            Vector2 p   = new Vector2();

            for (int x = -1; x <= 1; x++)
            {
                for (int y = -1; y <= 1; y++)
                {
                    // Check map boundaries
                    if (Mathf.FloorToInt(pos.x + x) >= 0 && Mathf.FloorToInt(pos.x + x) < cellsX && Mathf.FloorToInt(pos.y + y) >= 0 && Mathf.FloorToInt(pos.y + y) < cellsZ)
                    {
                        // (everything  here is in world coord, so we must transform back from grid coord to world coord)
                        // If the distance from the position of the guy to the middle of the 4 cells around him is leseer than the radius, we paint those cells
                        if (Vector2.Distance(new Vector2(enemy.GetSimulationPosition().x, enemy.GetSimulationPosition().z), new Vector2((Mathf.Floor(pos.x + x) + tileSizeX) * tileSizeX + minX, (Mathf.Floor(pos.y + y) + tileSizeZ) * tileSizeZ + minZ)) < enemy.radius)
                        {
                            im [Mathf.FloorToInt(pos.x + x)] [Mathf.FloorToInt(pos.y + y)].seen = true;
                            cellsByEnemy [i].Add(new Vector2(pos.x + x, pos.y + y));
                        }
                    }
                }
            }

            // if tileSizeX != tileSizeZ we can be in big trouble!
            float dist = enemy.fovDistance / ((tileSizeX + tileSizeZ) / 2);

            DDA dda = new DDA(tileSizeX, tileSizeZ, cellsX, cellsZ);

            for (int x = 0; x < cellsX; x++)
            {
                for (int y = 0; y < cellsZ; y++)
                {
                    // Skip cells that are staticly blocked or seen by other enemies
                    // Don't skip cells seen by other enemies or we won't have the correct seenCells computed
                    if (im [x] [y].blocked || im [x] [y].safe)
                    {
                        continue;
                    }

                    // This enemy haven't seen it yet
                    bool seen = false;

                    for (int px = 0; px <= 1; px++)
                    {
                        for (int py = 0; py <= 1; py++)
                        {
                            // Destination of the ray
                            p.Set(x + px, y + py);

                            // Direction of the ray
                            Vector2 res = (p - pos).normalized;

                            // Is the target within our FoV?
                            if (Vector2.Distance(p, pos) < dist && Vector2.Angle(res, dir) < enemy.fovAngle)
                            {
                                // Check if target is seen by this enemy
                                seen = seen || dda.HasLOS(im, p, pos, res, x, y);
                            }
                        }
                    }

                    // If this enemy has seen it
                    if (seen)
                    {
                        cellsByEnemy [i].Add(new Vector2(x, y));
                    }

                    // Now take into account other enemies before modifying the cells value
                    im [x] [y].seen = im [x] [y].seen || seen;
                }
            }
        }
        return(im);
    }