예제 #1
0
        private void PlaceDoors(Room r)
        {
            foreach (var n in r.Connected.Keys.ToList())
            {
                var door = r.Connected[n];
                if (door != null)
                {
                    continue;
                }

                var i = r.Intersect(n);
                if (i.Width() == 0)
                {
                    door = new Room.Door(i.Left, Random.Int(i.Top + 1, i.Bottom));
                }
                else
                {
                    door = new Room.Door(Random.Int(i.Left + 1, i.Right), i.Top);
                }

                if (r.Connected.ContainsKey(n))
                {
                    r.Connected[n] = door;
                }
                else
                {
                    r.Connected.Add(n, door);
                }
                n.Connected[r] = door;
            }
        }
예제 #2
0
        private static void PaintBurned(Level level, Room room)
        {
            for (var i = room.Top + 1; i < room.Bottom; i++)
            {
                for (var j = room.Left + 1; j < room.Right; j++)
                {
                    var t = Terrain.EMBERS;
                    switch (Random.Int(5))
                    {
                    case 0:
                        t = Terrain.EMPTY;
                        break;

                    case 1:
                        t = Terrain.FIRE_TRAP;
                        break;

                    case 2:
                        t = Terrain.SECRET_FIRE_TRAP;
                        break;

                    case 3:
                        t = Terrain.INACTIVE_TRAP;
                        break;
                    }

                    level.map[i * Level.Width + j] = t;
                }
            }
        }
예제 #3
0
        protected internal virtual void PaintDoors(Room r)
        {
            foreach (var n in r.Connected.Keys)
            {
                if (JoinRooms(r, n))
                {
                    continue;
                }

                var d    = r.Connected[n];
                var door = d.X + d.Y * Width;

                switch (d.Type)
                {
                case levels.Room.Door.DoorType.EMPTY:
                    map[door] = Terrain.EMPTY;
                    break;

                case levels.Room.Door.DoorType.TUNNEL:
                    map[door] = TunnelTile();
                    break;

                case levels.Room.Door.DoorType.REGULAR:
                    if (Dungeon.Depth <= 1)
                    {
                        map[door] = Terrain.DOOR;
                    }
                    else
                    {
                        var localSecret = (Dungeon.Depth < 6 ? Random.Int(12 - Dungeon.Depth) : Random.Int(6)) == 0;
                        map[door] = localSecret ? Terrain.SECRET_DOOR : Terrain.DOOR;
                        if (localSecret)
                        {
                            SecretDoors++;
                        }
                    }
                    break;

                case levels.Room.Door.DoorType.UNLOCKED:
                    map[door] = Terrain.DOOR;
                    break;

                case levels.Room.Door.DoorType.HIDDEN:
                    map[door] = Terrain.SECRET_DOOR;
                    break;

                case levels.Room.Door.DoorType.BARRICADE:
                    map[door] = Random.Int(3) == 0 ? Terrain.BOOKSHELF : Terrain.BARRICADE;
                    break;

                case levels.Room.Door.DoorType.LOCKED:
                    map[door] = Terrain.LOCKED_DOOR;
                    break;
                }
            }
        }
예제 #4
0
        protected internal override void CreateItems()
        {
#if DEBUG
            return;
#endif
            var nItems = 3;
            while (Random.Float() < 0.3f)
            {
                nItems++;
            }

            for (var i = 0; i < nItems; i++)
            {
                Heap.Type type;
                switch (Random.Int(20))
                {
                case 0:
                    type = Heap.Type.Skeleton;
                    break;

                case 1:
                case 2:
                case 3:
                case 4:
                    type = Heap.Type.Chest;
                    break;

                default:
                    type = Heap.Type.Heap;
                    break;
                }
                Drop(Generator.Random(), RandomDropCell()).HeapType = type;
            }

            foreach (var itemToSpawn in itemsToSpawn)
            {
                var cell = RandomDropCell();
                if (itemToSpawn is ScrollOfUpgrade)
                {
                    while (map[cell] == Terrain.FIRE_TRAP || map[cell] == Terrain.SECRET_FIRE_TRAP)
                    {
                        cell = RandomDropCell();
                    }
                }

                Drop(itemToSpawn, cell).HeapType = Heap.Type.Heap;
            }

            var item = Bones.Get();
            if (item != null)
            {
                Drop(item, RandomDropCell()).HeapType = Heap.Type.Skeleton;
            }
        }
예제 #5
0
        protected internal virtual void PlaceTraps()
        {
            var numberOfTraps = NumberOfTraps();
            var trapChances   = TrapChances();

            for (var i = 0; i < numberOfTraps; i++)
            {
                var trapPos = Random.Int(Length);

                if (map[trapPos] != Terrain.EMPTY)
                {
                    continue;
                }

                switch (Random.Chances(trapChances))
                {
                case 0:
                    map[trapPos] = Terrain.SECRET_TOXIC_TRAP;
                    break;

                case 1:
                    map[trapPos] = Terrain.SECRET_FIRE_TRAP;
                    break;

                case 2:
                    map[trapPos] = Terrain.SECRET_PARALYTIC_TRAP;
                    break;

                case 3:
                    map[trapPos] = Terrain.SECRET_POISON_TRAP;
                    break;

                case 4:
                    map[trapPos] = Terrain.SECRET_ALARM_TRAP;
                    break;

                case 5:
                    map[trapPos] = Terrain.SECRET_LIGHTNING_TRAP;
                    break;

                case 6:
                    map[trapPos] = Terrain.SECRET_GRIPPING_TRAP;
                    break;

                case 7:
                    map[trapPos] = Terrain.SECRET_SUMMONING_TRAP;
                    break;
                }
            }
        }
예제 #6
0
        public virtual void Damage(int dmg, object src)
        {
            if (HP <= 0)
            {
                return;
            }

            buffs.Buff.Detach <Frost>(this);

            var srcClass = src.GetType();

            if (Immunities().Contains(srcClass))
            {
                dmg = 0;
            }
            else
            if (Resistances().Contains(srcClass))
            {
                dmg = Random.IntRange(0, dmg);
            }

            if (Buff <Paralysis>() != null)
            {
                if (Random.Int(dmg) >= Random.Int(HP))
                {
                    buffs.Buff.Detach <Paralysis>(this);
                    if (Dungeon.Visible[pos])
                    {
                        GLog.Information(TxtOutOfParalysis, Name);
                    }
                }
            }

            HP -= dmg;

            if (dmg > 0 || src is Character)
            {
                Sprite.ShowStatus(HP > HT / 2 ? CharSprite.Warning : CharSprite.Negative, dmg.ToString());
            }

            if (HP <= 0)
            {
                Die(src);
            }
        }
예제 #7
0
        private static void PaintFissure(Level level, Room room)
        {
            Fill(level, room.Left + 1, room.Top + 1, room.Width() - 1, room.Height() - 1, Terrain.EMPTY);

            for (var i = room.Top + 2; i < room.Bottom - 1; i++)
            {
                for (var j = room.Left + 2; j < room.Right - 1; j++)
                {
                    var v = Math.Min(i - room.Top, room.Bottom - i);
                    var h = Math.Min(j - room.Left, room.Right - j);

                    if (Math.Min(v, h) > 2 || Random.Int(2) == 0)
                    {
                        Set(level, j, i, Terrain.CHASM);
                    }
                }
            }
        }
예제 #8
0
        private static void PaintGraveyard(Level level, Room room)
        {
            Fill(level, room.Left + 1, room.Top + 1, room.Width() - 1, room.Height() - 1, Terrain.GRASS);

            var w       = room.Width() - 1;
            var h       = room.Height() - 1;
            var nGraves = Math.Max(w, h) / 2;

            var index = Random.Int(nGraves);

            var shift = Random.Int(2);

            for (var i = 0; i < nGraves; i++)
            {
                var pos = w > h ? room.Left + 1 + shift + i * 2 + (room.Top + 2 + Random.Int(h - 2)) * Level.Width : (room.Left + 2 + Random.Int(w - 2)) + (room.Top + 1 + shift + i * 2) * Level.Width;
                level.Drop(i == index ? Generator.Random() : new Gold(), pos).HeapType = Heap.Type.Tomb;
            }
        }
예제 #9
0
        protected internal virtual void Split(Rect rect)
        {
            var w = rect.Width();
            var h = rect.Height();

            if (w > MaxRoomSize && h < MinRoomSize)
            {
                var vw = Random.Int(rect.Left + 3, rect.Right - 3);
                Split(new Rect(rect.Left, rect.Top, vw, rect.Bottom));
                Split(new Rect(vw, rect.Top, rect.Right, rect.Bottom));
            }
            else
            if (h > MaxRoomSize && w < MinRoomSize)
            {
                var vh = Random.Int(rect.Top + 3, rect.Bottom - 3);
                Split(new Rect(rect.Left, rect.Top, rect.Right, vh));
                Split(new Rect(rect.Left, vh, rect.Right, rect.Bottom));
            }
            else if ((new System.Random(1).NextDouble() <= (MinRoomSize * MinRoomSize / rect.Square()) && w <= MaxRoomSize && h <= MaxRoomSize) || w < MinRoomSize || h < MinRoomSize)
            {
                Rooms.Add((Room) new Room().Set(rect));
            }
            else
            {
                if (Random.Float() < (float)(w - 2) / (w + h - 4))
                {
                    var vw = Random.Int(rect.Left + 3, rect.Right - 3);
                    Split(new Rect(rect.Left, rect.Top, vw, rect.Bottom));
                    Split(new Rect(vw, rect.Top, rect.Right, rect.Bottom));
                }
                else
                {
                    var vh = Random.Int(rect.Top + 3, rect.Bottom - 3);
                    Split(new Rect(rect.Left, rect.Top, rect.Right, vh));
                    Split(new Rect(rect.Left, vh, rect.Right, rect.Bottom));
                }
            }
        }
예제 #10
0
        protected internal virtual void Paint()
        {
            foreach (var r in Rooms)
            {
                if (r.type != RoomType.NULL)
                {
                    PlaceDoors(r);
                    r.Paint(this, r);
                }
                else
                {
                    if (feeling == Feeling.CHASM && Random.Int(2) == 0)
                    {
                        Painter.Fill(this, r, Terrain.WALL);
                    }
                }
            }

            foreach (var r in Rooms)
            {
                PaintDoors(r);
            }
        }
예제 #11
0
        public virtual void Wither()
        {
            Dungeon.Level.Uproot(Pos);

            Sprite.Kill();
            if (Dungeon.Visible[Pos])
            {
                CellEmitter.Get(Pos).Burst(LeafParticle.Factory, 6);
            }

            if (Dungeon.Hero.subClass != HeroSubClass.WARDEN)
            {
                return;
            }

            if (Random.Int(5) == 0)
            {
                Dungeon.Level.Drop(Generator.Random(Generator.Category.SEED), Pos).Sprite.Drop();
            }
            if (Random.Int(5) == 0)
            {
                Dungeon.Level.Drop(new Dewdrop(), Pos).Sprite.Drop();
            }
        }
예제 #12
0
        private static void PaintBridge(Level level, Room room)
        {
            Fill(level, room.Left + 1, room.Top + 1, room.Width() - 1, room.Height() - 1, !Dungeon.BossLevel() && !Dungeon.BossLevel(Dungeon.Depth + 1) && Random.Int(3) == 0 ? Terrain.CHASM : Terrain.WATER);

            Point door1 = null;
            Point door2 = null;

            foreach (var p in room.Connected.Values)
            {
                if (door1 == null)
                {
                    door1 = p;
                }
                else
                {
                    door2 = p;
                }
            }

            if ((door1.X == room.Left && door2.X == room.Right) || (door1.X == room.Right && door2.X == room.Left))
            {
                var s = room.Width() / 2;

                DrawInside(level, room, door1, s, Terrain.EMPTY_SP);
                DrawInside(level, room, door2, s, Terrain.EMPTY_SP);
                Fill(level, room.Center().X, Math.Min(door1.Y, door2.Y), 1, Math.Abs(door1.Y - door2.Y) + 1, Terrain.EMPTY_SP);
            }
            else
            if ((door1.Y == room.Top && door2.Y == room.Bottom) || (door1.Y == room.Bottom && door2.Y == room.Top))
            {
                int s = room.Height() / 2;

                DrawInside(level, room, door1, s, Terrain.EMPTY_SP);
                DrawInside(level, room, door2, s, Terrain.EMPTY_SP);
                Fill(level, Math.Min(door1.X, door2.X), room.Center().Y, Math.Abs(door1.X - door2.X) + 1, 1, Terrain.EMPTY_SP);
            }
            else
            if (door1.X == door2.X)
            {
                Fill(level, door1.X == room.Left ? room.Left + 1 : room.Right - 1, Math.Min(door1.Y, door2.Y), 1, Math.Abs(door1.Y - door2.Y) + 1, Terrain.EMPTY_SP);
            }
            else
            if (door1.Y == door2.Y)
            {
                Fill(level, Math.Min(door1.X, door2.X), door1.Y == room.Top ? room.Top + 1 : room.Bottom - 1, Math.Abs(door1.X - door2.X) + 1, 1, Terrain.EMPTY_SP);
            }
            else
            if (door1.Y == room.Top || door1.Y == room.Bottom)
            {
                DrawInside(level, room, door1, Math.Abs(door1.Y - door2.Y), Terrain.EMPTY_SP);
                DrawInside(level, room, door2, Math.Abs(door1.X - door2.X), Terrain.EMPTY_SP);
            }
            else
            if (door1.X == room.Left || door1.X == room.Right)
            {
                DrawInside(level, room, door1, Math.Abs(door1.X - door2.X), Terrain.EMPTY_SP);
                DrawInside(level, room, door2, Math.Abs(door1.Y - door2.Y), Terrain.EMPTY_SP);
            }
        }
예제 #13
0
 public static bool AsNeeded()
 {
     return(Random.Int(12 * (1 + ArcaneStyli)) < Depth);
 }
예제 #14
0
 public override int NMobs()
 {
     return(2 + Dungeon.Depth % 5 + Random.Int(3));
 }
예제 #15
0
 protected internal virtual int NumberOfTraps()
 {
     return(Dungeon.Depth <= 1 ? 0 : Random.Int(1, Rooms.Count + Dungeon.Depth));
 }
예제 #16
0
        public override void Paint(Level level, Room room)
        {
            Fill(level, room, Terrain.WALL);
            foreach (var door in room.Connected.Values)
            {
                door.Set(Room.Door.DoorType.REGULAR);
            }

            if (!Dungeon.BossLevel() && Random.Int(5) == 0)
            {
                switch (Random.Int(6))
                {
                case 0:
                    if (level.feeling != Level.Feeling.GRASS)
                    {
                        if (Math.Min(room.Width(), room.Height()) >= 4 && Math.Max(room.Width(), room.Height()) >= 6)
                        {
                            PaintGraveyard(level, room);
                            return;
                        }
                    }

                    break;

                case 1:
                    if (Dungeon.Depth > 1)
                    {
                        PaintBurned(level, room);
                        return;
                    }
                    break;

                case 2:
                    if (Math.Max(room.Width(), room.Height()) >= 4)
                    {
                        PaintStriped(level, room);
                        return;
                    }
                    break;

                case 3:
                    if (room.Width() >= 6 && room.Height() >= 6)
                    {
                        PaintStudy(level, room);
                        return;
                    }
                    break;

                case 4:
                    if (level.feeling != Level.Feeling.WATER)
                    {
                        if (room.Connected.Count == 2 && room.Width() >= 4 && room.Height() >= 4)
                        {
                            PaintBridge(level, room);
                            return;
                        }
                    }
                    break;

                case 5:
                    if (!Dungeon.BossLevel() && !Dungeon.BossLevel(Dungeon.Depth + 1) && Math.Min(room.Width(), room.Height()) >= 5)
                    {
                        PaintFissure(level, room);
                        return;
                    }
                    break;
                }
            }

            Fill(level, room, 1, Terrain.EMPTY);
        }
예제 #17
0
        protected internal virtual void AssignRoomType()
        {
            var specialRooms = 0;

            foreach (var r in Rooms.Where(r => r.type == RoomType.NULL && r.Connected.Count == 1))
            {
                if (Specials.Count > 0 && r.Width() > 3 && r.Height() > 3 && Random.Int(specialRooms * specialRooms + 2) == 0)
                {
                    if (pitRoomNeeded)
                    {
                        r.type        = RoomType.PIT;
                        pitRoomNeeded = false;

                        Specials.Remove(RoomType.ARMORY);
                        Specials.Remove(RoomType.CRYPT);
                        Specials.Remove(RoomType.LABORATORY);
                        Specials.Remove(RoomType.LIBRARY);
                        Specials.Remove(RoomType.STATUE);
                        Specials.Remove(RoomType.TREASURY);
                        Specials.Remove(RoomType.VAULT);
                        Specials.Remove(RoomType.WEAK_FLOOR);
                    }
                    else if (Dungeon.Depth % 5 == 2 && Specials.Contains(RoomType.LABORATORY))
                    {
                        r.type = RoomType.LABORATORY;
                    }
                    else if (Dungeon.Depth >= Dungeon.Transmutation && Specials.Contains(RoomType.MAGIC_WELL))
                    {
                        r.type = RoomType.MAGIC_WELL;
                    }
                    else
                    {
                        var n = Specials.Count;
                        r.type = Specials[Math.Min(Random.Int(n), Random.Int(n))];

                        if (r.type == RoomType.WEAK_FLOOR)
                        {
                            weakFloorCreated = true;
                        }
                    }

                    levels.Room.UseType(r.type);
                    Specials.Remove(r.type);
                    specialRooms++;
                }
                else if (Random.Int(2) == 0)
                {
                    var neigbours = r.Neigbours.Where(n => !r.Connected.ContainsKey(n) && !levels.Room.SPECIALS.Contains(n.type) && n.type != RoomType.PIT).ToList();

                    if (neigbours.Count > 1)
                    {
                        r.Connect(Random.Element(neigbours));
                    }
                }
            }

            var count = 0;

            foreach (var r in Rooms)
            {
                if (r.type != RoomType.NULL)
                {
                    continue;
                }

                var connections = r.Connected.Count;
                switch (connections)
                {
                case 0:
                    break;

                default:
                    if (Random.Int(connections * connections) == 0)
                    {
                        r.type = RoomType.STANDARD;
                        count++;
                    }
                    else
                    {
                        r.type = RoomType.TUNNEL;
                    }

                    break;
                }
            }

            while (count < 4)
            {
                var r = RandomRoom(RoomType.TUNNEL, 1);

                if (r == null)
                {
                    continue;
                }

                r.type = RoomType.STANDARD;
                count++;
            }
        }