private bool HasEdge(int x, int y, Direction dir)
        {
            Room.Tile             tile    = room.GetTile(x, y);
            Room.Tile.TerrainType terrain = tile.Terrain;
            Room.SlopeDirection   slope   = (terrain == Room.Tile.TerrainType.Slope) ? room.IdentifySlope(x, y) : Room.SlopeDirection.Broken;

            if (terrain == Room.Tile.TerrainType.Solid)
            {
                return(true);
            }
            if (terrain == Room.Tile.TerrainType.Air ||
                terrain == Room.Tile.TerrainType.ShortcutEntrance ||
                terrain == Room.Tile.TerrainType.Floor)
            {
                return(false);
            }
            switch (dir)
            {
            case Direction.Up:
                return(slope == Room.SlopeDirection.DownRight || slope == Room.SlopeDirection.DownLeft);

            case Direction.Right:
                return(slope == Room.SlopeDirection.UpLeft || slope == Room.SlopeDirection.DownLeft);

            case Direction.Down:
                return(slope == Room.SlopeDirection.UpRight || slope == Room.SlopeDirection.UpLeft);

            case Direction.Left:
                return(slope == Room.SlopeDirection.DownRight || slope == Room.SlopeDirection.UpRight);
            }
            return(false);
        }
Exemple #2
0
    public bool PointInSolid(int x, int y)
    {
        Room.Tile tile = Room.realizedRoom.GetTile(new Vector2(x, y));
        int       lx   = x - tile.X * 20;
        int       ly   = y - tile.Y * 20;

        switch (tile.Terrain)
        {
        case global::Room.Tile.TerrainType.Solid:
            return(true);

        case global::Room.Tile.TerrainType.Air:
            return(false);

        case global::Room.Tile.TerrainType.Floor:
            return(ly > 10);

        case global::Room.Tile.TerrainType.ShortcutEntrance:
            return(true);

        case global::Room.Tile.TerrainType.Slope:
            switch (Room.realizedRoom.IdentifySlope(tile.X, tile.Y))
            {
            case global::Room.SlopeDirection.Broken:
                return(true);

            case global::Room.SlopeDirection.DownRight:
                return(ly > lx);

            case global::Room.SlopeDirection.UpLeft:
                return(ly < lx);

            case global::Room.SlopeDirection.UpRight:
                return(ly < 20 - lx);

            case global::Room.SlopeDirection.DownLeft:
                return(ly > 20 - lx);
            }
            break;
        }
        return(false);
    }
        public void UpdateMapper(int iterations)
        {
            Room.Tile[,] tiles = _tiles;
            for (int i = 0; i < iterations; i++)
            {
                switch (state)
                {
                case MappingState.FindingEdges:
                {
                    Room.Tile             tile    = tiles[_x, _y];
                    Room.Tile.TerrainType terrain = tile.Terrain;
                    Room.SlopeDirection   slope   = (terrain == Room.Tile.TerrainType.Slope) ? room.IdentifySlope(_x, _y) : Room.SlopeDirection.Broken;

                    if (HasEdge(_x, _y, Direction.Left) && !HasEdge(_x - 1, _y, Direction.Right))
                    {
                        AddEdge(_x, _y, Direction.Left);
                    }
                    if (HasEdge(_x, _y, Direction.Down) && !HasEdge(_x, _y - 1, Direction.Up))
                    {
                        AddEdge(_x, _y, Direction.Down);
                    }
                    if (HasEdge(_x, _y, Direction.Right) && !HasEdge(_x + 1, _y, Direction.Left))
                    {
                        AddEdge(_x, _y, Direction.Right);
                    }
                    if (HasEdge(_x, _y, Direction.Up) && !HasEdge(_x, _y + 1, Direction.Down))
                    {
                        AddEdge(_x, _y, Direction.Up);
                    }

                    if (slope != Room.SlopeDirection.Broken)
                    {
                        AddSlopeEdge(_x, _y, slope);
                    }

                    _x++;
                    if (_x >= room.TileWidth)
                    {
                        _x = 0;
                        _y++;
                        if (_y >= room.TileHeight)
                        {
                            _y    = corners.Count;
                            state = MappingState.DuplicatingPoints;
                        }
                    }
                }
                break;

                case MappingState.DuplicatingPoints:
                {
                    corners.Add(corners[_x]);
                    _x++;
                    if (_x >= _y)
                    {
                        state = MappingState.Done;
                        _x    = 0;
                        _y    = 0;
                    }
                }
                break;

                case MappingState.Done:
                    return;
                }
            }
        }
Exemple #4
0
    public void ApplyTerrain(bool finalize = true)
    {
        if (!affectTerrain)
        {
            return;
        }
        Room rroom = Room.realizedRoom;

        if (rroom == null)
        {
            return;
        }

        // No culling should happen

        int seed = Random.seed;

        Random.seed = ID.number;

        IntVector2 mins = rroom.GetTilePosition(realPos - new Vector2(rad, rad));
        IntVector2 maxs = rroom.GetTilePosition(realPos + new Vector2(rad, rad));

        // Erode terrain
        for (int tx = mins.x; tx <= maxs.x; tx++)
        {
            for (int ty = mins.y; ty <= maxs.y; ty++)
            {
                Room.Tile tile = rroom.GetTile(tx, ty);
                float     dist = Vector2.Distance(rroom.MiddleOfTile(tile.X, tile.Y), realPos);
                //bool hasNearbyShortcut = false;
                //for(int ox = -1; ox <= 1; ox++)
                //{
                //    for(int oy = -1; oy <= 1; oy++)
                //    {
                //        if(rroom.GetTile(tx + ox, ty + oy).Terrain == global::Room.Tile.TerrainType.ShortcutEntrance)
                //        {
                //            hasNearbyShortcut = true;
                //            break;
                //        }
                //    }
                //}
                //if (hasNearbyShortcut) continue;
                if (dist < rad * 0.85f - Random.value * 30f)
                {
                    if (tile.Terrain == global::Room.Tile.TerrainType.ShortcutEntrance)
                    {
                        shortcutsModified = true;
                        int ind = System.Array.IndexOf(rroom.shortcutsIndex, new IntVector2(tile.X, tile.Y));
                        rroom.shortcuts[ind].shortCutType = ShortcutData.Type.DeadEnd;
                        foreach (UpdatableAndDeletable obj in rroom.updateList)
                        {
                            if (obj is ShortcutHelper sh)
                            {
                                for (int i = sh.pushers.Count - 1; i >= 0; i--)
                                {
                                    ShortcutHelper.ShortcutPusher sp = sh.pushers[i];
                                    if (sp.shortCutPos.x == tile.X && sp.shortCutPos.y == tile.Y)
                                    {
                                        sh.pushers.RemoveAt(i);
                                    }
                                }
                            }
                        }
                    }
                    if (dist < rad * 0.7f - Random.value * 15f)
                    {
                        tile.wallbehind = false;
                    }
                    tile.Terrain        = global::Room.Tile.TerrainType.Air;
                    tile.horizontalBeam = false;
                    tile.verticalBeam   = false;
                    if (tile.shortCut != 0)
                    {
                        shortcutsModified = true;
                        tile.shortCut     = 0;
                    }
                }
            }
        }

        // Convert all slopable blocks into slopes, with some random chance
        for (int tx = mins.x - 1; tx <= maxs.x + 1; tx++)
        {
            for (int ty = mins.y - 1; ty <= maxs.y + 1; ty++)
            {
                Room.Tile tile = rroom.GetTile(tx, ty);
                float     dist = Vector2.Distance(rroom.MiddleOfTile(tile.X, tile.Y), realPos);
                //bool hasNearbyShortcut = false;
                //for(int i = 0; i < 4; i++)
                //{
                //    if(rroom.GetTile(tx + Custom.fourDirections[i].x, ty + Custom.fourDirections[i].y).Terrain == global::Room.Tile.TerrainType.ShortcutEntrance)
                //    {
                //        hasNearbyShortcut = true;
                //        break;
                //    }
                //}
                //if (hasNearbyShortcut) continue;
                if (dist < rad * 0.85f + 20f)
                {
                    if (tile.Terrain == global::Room.Tile.TerrainType.Solid)
                    {
                        if (IsSlopeValid(tx, ty) && (Random.value < 0.65f))
                        {
                            tile.Terrain = global::Room.Tile.TerrainType.Slope;
                        }
                    }
                }
            }
        }

        // One last pass to remove any broken slopes
        for (int tx = mins.x - 1; tx <= maxs.x + 1; tx++)
        {
            for (int ty = mins.y - 1; ty <= maxs.y + 1; ty++)
            {
                Room.Tile tile = rroom.GetTile(tx, ty);
                if (tile.Terrain == global::Room.Tile.TerrainType.Slope && rroom.IdentifySlope(tx, ty) == global::Room.SlopeDirection.Broken)
                {
                    tile.Terrain = global::Room.Tile.TerrainType.Air;
                }
            }
        }

        Random.seed = seed;

        if (finalize)
        {
            FinalizeTerrainDestruction(rroom);
        }
    }