/// <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); }
/// <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)); }
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); } }
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)); } }