/// <summary>
        /// Cast web
        /// </summary>
        /// <param name="resultSet">Result set</param>
        /// <param name="caster">Caster</param>
        /// <param name="targetPos">Target position</param>
        /// <returns>True if successful</returns>
        public static bool CastWeb(ResultSet resultSet, EntityID caster, Vector2i targetPos)
        {
            var game = (RetroDungeoneerGame)RB.Game;

            if (!CheckTargetPosValid(resultSet, targetPos, caster))
            {
                return(false);
            }

            var entities = EntityFunctions.GetEntitiesAtPos(targetPos);
            var hasWeb   = false;

            for (int i = 0; i < entities.Count; i++)
            {
                if (entities[i].e.groundTrigger != null && entities[i].e.groundTrigger.type == GroundTrigger.GroundTriggerType.Web)
                {
                    hasWeb = true;
                }
            }

            if (!hasWeb)
            {
                EntityFunctions.CreateInteractable(InteractableType.Web, targetPos);
                EffectManager.Instance.AddEffect(new EffectThrow(caster, EntityID.empty, targetPos, S.WEB, new Color32(255, 255, 255, 100), game.assets.soundWeb, game.assets.soundWeb));

                return(true);
            }

            return(false);
        }
Beispiel #2
0
        /// <summary>
        /// Spawn the exit portal
        /// </summary>
        /// <param name="pos">Location for the portal</param>
        public void SpawnExitPortal(Vector2i pos)
        {
            int      attempts  = 1000;
            Vector2i randomPos = Vector2i.zero;

            while (attempts > 0)
            {
                randomPos = new Vector2i(pos.x + Random.Range(-4, 5), pos.y + Random.Range(-4, 5));

                if (IsInFOV(randomPos) && !IsBlocked(randomPos) && pos != randomPos)
                {
                    break;
                }

                attempts--;
            }

            if (attempts == 0)
            {
                Debug.Log("Could not find a place to spawn exit portal!!");
                return;
            }

            var portal = EntityFunctions.CreateInteractable(InteractableType.Portal, randomPos);

            portal.e.stairs      = new Stairs(dungeonLevel + 1);
            portal.e.stairs.type = Stairs.StairType.PORTAL;

            EffectManager.Instance.AddEffect(new EffectPortal(portal));
        }
Beispiel #3
0
        private void MakeForestMap(int mapWidth, int mapHeight, EntityID player)
        {
            backgroundColor = new Color32(0x25, 0x8f, 0x4a, 255);
            mMusic          = C.MUSIC_FOREST;

            var playerEntity = EntityStore.Get(player);

            if (playerEntity == null)
            {
                return;
            }

            int width  = Random.Range(14, 18);
            int height = Random.Range(14, 18);

            int x = (mapWidth / 2) - (width / 2);
            int y = (mapHeight / 2) - (height / 2);

            var newRoom = new Rect2i(x, y, width, height);

            CreateRoom(newRoom, RoomShape.EllipseFuzzy);

            var roomCenter = newRoom.center;

            int randExit = Random.Range(0, 4);

            Vector2i blockadePos = Vector2i.zero;
            Vector2i thugPos     = Vector2i.zero;
            Vector2i gameExitPos = Vector2i.zero;
            Vector2i gameExitDir = Vector2i.zero;

            if (randExit == 0)
            {
                CreateHTunnel(roomCenter.x, 0, roomCenter.y);
                blockadePos    = new Vector2i(roomCenter.x - (newRoom.width / 2) - 2, roomCenter.y);
                gameExitPos    = blockadePos;
                gameExitPos.x -= 3;
                gameExitDir    = new Vector2i(-1, 0);
                thugPos        = blockadePos;
                thugPos.x     += 4;
            }
            else if (randExit == 1)
            {
                CreateHTunnel(roomCenter.x, mapWidth - 1, roomCenter.y);
                blockadePos    = new Vector2i(roomCenter.x + (newRoom.width / 2) + 2, roomCenter.y);
                gameExitPos    = blockadePos;
                gameExitPos.x += 3;
                gameExitDir    = new Vector2i(1, 0);
                thugPos        = blockadePos;
                thugPos.x     -= 4;
            }
            else if (randExit == 2)
            {
                CreateVTunnel(0, roomCenter.y, roomCenter.x);
                blockadePos    = new Vector2i(roomCenter.x, roomCenter.y - (newRoom.height / 2) - 2);
                gameExitPos    = blockadePos;
                gameExitPos.y -= 3;
                gameExitDir    = new Vector2i(0, -1);
                thugPos        = blockadePos;
                thugPos.y     += 4;
            }
            else if (randExit == 3)
            {
                CreateVTunnel(mapHeight - 1, roomCenter.y, roomCenter.x);
                blockadePos    = new Vector2i(roomCenter.x, roomCenter.y + (newRoom.height / 2) + 2);
                gameExitPos    = blockadePos;
                gameExitPos.y += 3;
                gameExitDir    = new Vector2i(0, 1);
                thugPos        = blockadePos;
                thugPos.y     -= 4;
            }

            // This is the first room, put the player in the center of it
            playerEntity.pos = RandomUtils.RandomRectPerimeterPos(new Rect2i(roomCenter.x - 1, roomCenter.y - 1, 3, 3));

            EntityID thug = EntityID.empty;

            if (dungeonLevel == 0)
            {
                thug = EntityFunctions.CreateMonster(MonsterType.InvincibleThug, thugPos);
                EntityFunctions.CreateMonster(MonsterType.InvincibleBlockade, blockadePos);
            }
            else
            {
                thug = EntityFunctions.CreateMonster(MonsterType.Thug, thugPos);
                EntityFunctions.CreateMonster(MonsterType.Blockade, blockadePos);

                while (gameExitPos.x > 0 && gameExitPos.y > 0 && gameExitPos.x < size.width && gameExitPos.y < size.height)
                {
                    EntityFunctions.CreateInteractable(InteractableType.GameExit, gameExitPos);
                    gameExitPos += gameExitDir;
                }
            }

            // Give thug a dagger and armor
            var dagger = EntityFunctions.CreateItem(ItemType.Dagger, new Vector2i(-1, -1));

            thug.e.inventory = new Inventory(1);
            thug.e.equipment = new Equipment();
            thug.e.equipment.equipment[(int)dagger.e.equippable.slot] = dagger;

            var armor = EntityFunctions.CreateItem(ItemType.LeatherArmor, new Vector2i(-1, -1));

            thug.e.equipment.equipment[(int)armor.e.equippable.slot] = armor;

            var well = EntityFunctions.CreateInteractable(InteractableType.Well, new Vector2i(roomCenter.x, roomCenter.y + 2));

            well.e.stairs = new Stairs(dungeonLevel + 1);
            if (dungeonLevel == 0)
            {
                well.e.stairs.type = Stairs.StairType.WELL;
            }
            else
            {
                well.e.stairs.type = Stairs.StairType.WELL_CLOSED;
            }

            UpdateAllEntityMapPositions();

            BeautifyForestMap();

            RecomputeFov(player, C.FOV_RADIUS);

            var game    = (RetroDungeoneerGame)RB.Game;
            var options = new List <SceneMessage.MessageBoxOption>();

            options.Add(new SceneMessage.MessageBoxOption(C.FSTR.Set("Continue"), CloseMessageBox));

            if (dungeonLevel == 0)
            {
                C.FSTR.Set(C.STR_COLOR_DIALOG);
                C.FSTR.Append("You've been travelling through the forest for hours and decide to rest at a nearby clearing.");
                C.FSTR.Append("\n\n");
                C.FSTR.Append("As you settle down a man appears behind you. He swings his sword at a rope tied to a tree beside him. Branches and debris fall onto the path blocking your only exit. It appears you've been ambushed.");
                C.FSTR.Append("\n\n");
                C.FSTR.Append(C.STR_COLOR_NAME);
                C.FSTR.Append("\"I'll take what you're carrying, once I'm done carving you up!\"").Append(C.STR_COLOR_DIALOG).Append(" the brigand says with a grimace.");
                C.FSTR.Append("\n\n");
                C.FSTR.Append("Your eyes dart to an old well in the middle of the clearing. Your options seem clear... jump down the well, or die here.");

                game.ShowMessageBox(
                    C.FSTR2.Set("Trapped"),
                    C.FSTR,
                    options);
            }
            else
            {
                C.FSTR.Set(C.STR_COLOR_DIALOG);
                C.FSTR.Append("You open your eyes, the swirling portal closes behind you. You find yourself back where it all started, in the forest clearing.");
                C.FSTR.Append("\n\n");
                C.FSTR.Append("The brigand who ambushed you is still here, preparing his trap for the next victim.");
                C.FSTR.Append("\n\n");
                C.FSTR.Append(C.STR_COLOR_NAME);
                C.FSTR.Append("\"How did you... nevermind, lets finish what we started!\"").Append(C.STR_COLOR_DIALOG).Append(" he says, startled by your sudden appearance.");
                C.FSTR.Append("\n\n");
                C.FSTR.Append("You tighten your grip on your weapon, you won't be jumping into the well this time...");

                game.ShowMessageBox(
                    C.FSTR2.Set("A Sudden Return"),
                    C.FSTR,
                    options);
            }
        }
Beispiel #4
0
        private void MakeDungeonMap(int maxRooms, int roomMinSize, int roomMaxSize, int mapWidth, int mapHeight, EntityID player)
        {
            backgroundColor = new Color32(0x47, 0x2d, 0x3c, 255);
            mMusic          = C.MUSIC_GAME;

            var playerEntity = EntityStore.Get(player);

            if (playerEntity == null)
            {
                return;
            }

            List <Rect2i> rooms = new List <Rect2i>();

            for (int r = 0; r < maxRooms; r++)
            {
                // Random width and height
                int width  = 0;
                int height = 0;

                if (dungeonLevel < 5 || rooms.Count > 0)
                {
                    width  = Random.Range(roomMinSize, roomMaxSize + 1);
                    height = Random.Range(roomMinSize, roomMaxSize + 1);
                }
                else
                {
                    width  = Random.Range(roomMinSize * 2, (roomMaxSize * 2) + 1);
                    height = Random.Range(roomMinSize * 2, (roomMaxSize * 2) + 1);
                }

                // Random position
                int x = Random.Range(0, mapWidth - width);
                int y = Random.Range(0, mapHeight - height);

                var newRoom = new Rect2i(x, y, width, height);

                // Check if the room intersects with other rooms
                bool intersects = false;
                for (int i = 0; i < rooms.Count; i++)
                {
                    if (newRoom.Intersects(rooms[i]))
                    {
                        intersects = true;
                        break;
                    }
                }

                // No intersections, it's safe to create this room
                if (!intersects)
                {
                    CreateRoom(newRoom, RoomShape.Rectangle);

                    var roomCenter = newRoom.center;

                    if (rooms.Count > 0)
                    {
                        // All rooms after the first one should be connected with a tunnel to the previous room
                        var prevRoomCenter = rooms[rooms.Count - 1].center;

                        if (Random.Range(0, 2) == 1)
                        {
                            CreateHTunnel(prevRoomCenter.x, roomCenter.x, prevRoomCenter.y);
                            CreateVTunnel(prevRoomCenter.y, roomCenter.y, roomCenter.x);
                        }
                        else
                        {
                            CreateVTunnel(prevRoomCenter.y, roomCenter.y, prevRoomCenter.x);
                            CreateHTunnel(prevRoomCenter.x, roomCenter.x, roomCenter.y);
                        }
                    }

                    // Add the new room to list of rooms
                    rooms.Add(newRoom);
                }
            }

            // Populate all rooms except for first and last
            for (int i = 1; i < rooms.Count - 1; i++)
            {
                if (i != 0 && i != rooms.Count - 1)
                {
                    var numOfMonsters = RandomUtils.FromDungeonLevel(
                        new RandomUtils.Tuple <int, int>[]
                    {
                        new RandomUtils.Tuple <int, int>(2, 1),
                        new RandomUtils.Tuple <int, int>(3, 3),
                        new RandomUtils.Tuple <int, int>(5, 5)
                    },
                        dungeonLevel);

                    var numOfItems = RandomUtils.FromDungeonLevel(
                        new RandomUtils.Tuple <int, int>[]
                    {
                        new RandomUtils.Tuple <int, int>(1, 1),
                        new RandomUtils.Tuple <int, int>(2, 4)
                    },
                        dungeonLevel);

                    PlaceEntities(rooms[i], numOfItems, numOfMonsters);
                }
            }

            var firstRoom = rooms[0];
            var lastRoom  = rooms[rooms.Count - 1];

            if (dungeonLevel < 5)
            {
                MakeStartRoom(player, firstRoom);
                var stairsDown = EntityFunctions.CreateInteractable(InteractableType.Stairs, lastRoom.center);
                stairsDown.e.stairs = new Stairs(dungeonLevel + 1);
            }
            else
            {
                // For final level make the player start room the last room, and boss room the first room
                // This makes it easier to ensure we can fit a nice big boss room before creating other rooms
                MakeBossRoom(firstRoom);
                MakeStartRoom(player, lastRoom);
            }

            UpdateAllEntityMapPositions();

            BeautifyDungeonMap();

            RecomputeFov(player, C.FOV_RADIUS);

            if (dungeonLevel == 1)
            {
                EffectManager.Instance.AddEffect(new EffectPlayerEntrance(player));
            }
        }