private void CreatePassageInPoint(Tile center, bool makeDoor, MapRoom roomA, MapRoom roomB) { center.SetColor(Tile.ORANGE); Tile start = GetClosestTileFrom(center, WorldHolder.WALL); int dx = start.tileX - center.tileX; int dy = start.tileY - center.tileY; Tile end = GetTile(center.tileX - dx, center.tileY - dy); if (end.tileType != WorldHolder.WALL) { end = GetClosestTileFrom(end, WorldHolder.WALL); } List <Tile> line = GetLine(start, end); foreach (Tile t in line) { t.SetColor(Tile.GREEN); } start.SetColor(Tile.MAGENTA); end.SetColor(Tile.PINK); MapPassage passage = new MapPassage(line, center, start, end, roomA, roomB); passage.isDoor = makeDoor; mapHolder.AddPassage(passage); }
private void GetClosestTiles(MapRoom roomA, MapRoom roomB, out Tile bestTileA, out Tile bestTileB, out int bestDistance) { bestDistance = -1; bestTileA = null; bestTileB = null; // projedeme vsechny okrajove body roomA for (int tileIndexA = 0; tileIndexA < roomA.edgeTiles.Count; tileIndexA++) { // projedeme vsechny okrajovy body roomB for (int tileIndexB = 0; tileIndexB < roomB.edgeTiles.Count; tileIndexB++) { Tile tileA = roomA.edgeTiles[tileIndexA]; Tile tileB = roomB.edgeTiles[tileIndexB]; // vypocitame vzdalenost kazdych dvou okrajovych bodu obou mistnosti int dx = tileA.tileX - tileB.tileX; int dy = tileA.tileY - tileB.tileY; int dist = dx * dx + dy * dy; if (dist < bestDistance || bestDistance == -1) { bestDistance = dist; bestTileA = tileA; bestTileB = tileB; } } } }
private void CreatePassage(MapRoom roomA, MapRoom roomB) { Tile bestTileA; Tile bestTileB; int bestDistance; GetClosestTiles(roomA, roomB, out bestTileA, out bestTileB, out bestDistance); bestTileA.SetColor(Tile.ORANGE); bestTileB.SetColor(Tile.PURPLE); List <Tile> line = GetLine(bestTileA, bestTileB); List <Tile> passageTiles = new List <Tile>(); foreach (Tile t in line) { t.SetColor(Tile.BROWN); List <Tile> circle = DrawCircle(t, 5, WorldHolder.GROUND); foreach (Tile c in circle) { passageTiles.Add(c); } } bool makeDoor = roomA.region.isLockedRegion || roomB.region.isLockedRegion; CreatePassageInPoint(line[line.Count / 2], makeDoor, roomA, roomB); }
private void ConnectRooms(MapRoom roomA, MapRoom roomB) { roomA.connectedRooms.Add(roomB); roomB.connectedRooms.Add(roomA); if (roomA.isAccessibleFromStartRoom || roomB.isAccessibleFromStartRoom) { roomA.SetAccessibleFromStartRoom(); roomB.SetAccessibleFromStartRoom(); } CreatePassage(roomA, roomB); }
public MapPassage(List <Tile> tiles, Tile center, Tile start, Tile end, MapRoom roomA, MapRoom roomB) { this.tiles = tiles; centerTile = center; starTile = start; endTile = end; this.roomA = roomA; this.roomB = roomB; enabled = true; }
public static void ConnectRooms(MapRoom roomA, MapRoom roomB) { if (roomA.isAccessibleFromStartRoom) { roomB.SetAccessibleFromStartRoom(); } else if (roomB.isAccessibleFromStartRoom) { roomA.SetAccessibleFromStartRoom(); } roomA.connectedRooms.Add(roomB); roomB.connectedRooms.Add(roomA); }
private bool CanBeConnected(MapRoom roomA, MapRoom roomB) { if (roomA.region.Equals(roomB.region)) { return(false); } MapRegion regA = roomA.region; MapRegion regB = roomB.region; List <MapRegion> regionsA = new List <MapRegion>(); List <MapRegion> regionsB = new List <MapRegion>(); regionsA.Add(regA); regionsB.Add(regB); // najit child regiony foreach (MapRegion region in mapHolder.regions.Values) { if (region.HasParentRegion()) { if (region.parentRegion.Equals(regA)) { regionsA.Add(region); } else if (region.parentRegion.Equals(regB)) { regionsB.Add(region); } } } bool areNeighbours = false; foreach (MapRegion ra in regionsA) { foreach (MapRegion rb in regionsB) { if (mapHolder.IsNeighbour(ra, rb)) { areNeighbours = true; return(areNeighbours); } } } return(areNeighbours); }
private void AnalyzeRooms() { List <Region> wallRegions = GetRegions(WorldHolder.WALL); List <Region> groundRegions = GetRegions(WorldHolder.GROUND); rooms = new List <MapRoom>(); foreach (Region r in groundRegions) { MapRoom room = new MapRoom(r.tiles, tiles); rooms.Add(room); } UncheckAllTiles(); }
private bool AreRoomsConnected(MapRoom roomA, MapRoom roomB) { return(roomA.IsConnected(roomB)); }
private void ConnectRoomsToStart() { Queue <MapRoom> toConnect = new Queue <MapRoom>(); List <MapRoom> connectedToStart = new List <MapRoom>(); MapRoom startRoom = null; List <MapRegion> checks; foreach (MapRoom room in rooms) { if (room.region.isStartRegion) { startRoom = room; startRoom.SetAccessibleFromStartRoom(); connectedToStart.Add(startRoom); Queue <MapRegion> neighbours = new Queue <MapRegion>(); foreach (MapRegion reg in mapHolder.GetNeighbourRegions(startRoom.region)) { if (!reg.empty) { neighbours.Enqueue(reg); } } checks = new List <MapRegion>(); // vzit vsechny sousedy startovni mistnosti while (neighbours.Count > 0) { MapRegion reg = neighbours.Dequeue(); checks.Add(reg); // jen ty ktere MAJI BYT pripojene if (reg == null || !reg.isAccessibleFromStart) { continue; } // soused startovniho regionu je jeho potomek - jsou spojeny - pridat do seznamu connectedToStart if (reg.IsInFamily(startRoom.region)) { foreach (MapRoom r in GetRoomsInRegion(reg)) { connectedToStart.Add(r); } // pridat vsechny sousedy child regionu foreach (MapRegion r in mapHolder.GetNeighbourRegions(reg)) { if (r != null && r.isAccessibleFromStart && !neighbours.Contains(r) && !checks.Contains(r)) { neighbours.Enqueue(r); } } continue; } // pridat do seznamu k pripojeni foreach (MapRoom r in GetRoomsInRegion(reg)) { if (!r.isAccessibleFromStartRoom) { toConnect.Enqueue(r); } } } } } while (toConnect.Count > 0) { // 1. vzit kazdou mistnost k pripojeni a zkusit ji pripojit k jedne z mistnosti v "connected" MapRoom toConnectRoom = toConnect.Dequeue(); //Debug.Log("** connecting " + toConnectRoom.region.x + ", " + toConnectRoom.region.y); int max = connectedToStart.Count; for (int i = 0; i < max; i++) { MapRoom connectedRoom = connectedToStart[i]; // mistnosti jsou sousedi if (CanBeConnected(toConnectRoom, connectedRoom) && !AreRoomsConnected(toConnectRoom, connectedRoom)) { if (connectedRoom.isAccessibleFromStartRoom && connectedRoom.region.onlyOnePassage && connectedRoom.connectedRooms.Count > 0) { continue; } //Debug.Log("propojuji " + toConnectRoom.region.x + ", " + toConnectRoom.region.y + " s " + connectedRoom.region.x + ", " + connectedRoom.region.y); ConnectRooms(toConnectRoom, connectedRoom); connectedToStart.Add(toConnectRoom); Queue <MapRegion> neighbours = new Queue <MapRegion>(); foreach (MapRegion reg in mapHolder.GetNeighbourRegions(toConnectRoom.region)) { // pokud to neni empty region, pridat jeho sousedy do fronty if (!reg.empty) { neighbours.Enqueue(reg); } } checks = new List <MapRegion>(); // vzit vsechny sousedy startovni mistnosti while (neighbours.Count > 0) { MapRegion reg = neighbours.Dequeue(); checks.Add(reg); // jen ty ktere MAJI BYT pripojene if (reg == null || !reg.isAccessibleFromStart) // TODO check if already connected? { continue; } // soused startovniho regionu je jeho potomek - jsou spojeny - pridat do seznamu connectedToStart if (reg.IsInFamily(toConnectRoom.region)) { //Debug.Log("region " + reg.x + ", " + reg.y + " je ve family s toConnect (" + toConnectRoom.region.x + ", " + toConnectRoom.region.y + ")"); foreach (MapRoom r in GetRoomsInRegion(reg)) { if (!connectedToStart.Contains(r)) { connectedToStart.Add(r); // maybe add duplicity check } } // pridat vsechny sousedy child regionu foreach (MapRegion r in mapHolder.GetNeighbourRegions(reg)) { if (r != null && r.isAccessibleFromStart && !neighbours.Contains(r) && !checks.Contains(r)) { //Debug.Log("pridavam souseda (reg " + reg.x + ", " + reg.y + ") : " + r.x + ", " + r.y); neighbours.Enqueue(r); } } continue; } // pridat do seznamu k pripojeni foreach (MapRoom r in GetRoomsInRegion(reg.GetParentOrSelf())) { if (!r.isAccessibleFromStartRoom) { toConnect.Enqueue(r); } } } // pripojit k prvni nalezene if (toConnectRoom.region.onlyOnePassage) { break; } } } } }
public void GenerateGenericEnemyGroup(MapRoom room, AbstractLevelData level, RoomType roomType, int difficulty, MapRegion regionData, int forcedId = -1) { Player player = GameSystem.Instance.CurrentPlayer; int playerLevel = 1; if (player != null) { playerLevel = player.Level; } RegionSize size = RegionSize.SMALL; if (regionData != null) { int sInt = regionData.GetFamilyRegions().Count; if (sInt == 2 || sInt == 3) { size = RegionSize.MEDIUM; } else if (sInt >= 4) { size = RegionSize.LARGE; } } int world = WorldHolder.instance.worldLevel; int selectedId = forcedId; if (forcedId < 0) { int soucet = 0; foreach (MobGroup group in mobGroups) { if (group.minRegionSize != RegionSize.NULL && group.minRegionSize > size) { continue; } if (group.maxRegionSize != RegionSize.NULL && group.maxRegionSize < size) { continue; } if (roomType == group.roomType && group.minLevel <= playerLevel && group.maxLevel >= playerLevel && group.maxWorld >= world && group.minWorld <= world) { soucet += group.frequency; } } int[] sum = new int[soucet]; soucet = 0; foreach (MobGroup group in mobGroups) { if (group.minRegionSize != RegionSize.NULL && group.minRegionSize > size) { continue; } if (group.maxRegionSize != RegionSize.NULL && group.maxRegionSize < size) { continue; } if (roomType == group.roomType && group.minLevel <= playerLevel && group.maxLevel >= playerLevel && group.maxWorld >= world && group.minWorld <= world) { for (int i = 0; i < group.frequency; i++) { sum[soucet + i] = group.id; } soucet += group.frequency; } } if (sum.Length == 0) { return; } int rnd = Random.Range(0, sum.Length); selectedId = sum[rnd]; } if (selectedId < 0) { Debug.LogError("chyba - nenalezena spravna groupa "); return; } bool spawned = false; foreach (MobGroup group in mobGroups) { if (group.id == selectedId) //if ((roomType == group.roomType && group.minLevel <= playerLevel && group.maxLevel >= playerLevel && group.maxWorld >= world && group.minWorld <= world && forcedId < 0) || (forcedId > 0 && group.id == forcedId)) { List <MonsterSpawnInfo> infos = new List <MonsterSpawnInfo>(); int count = 0; foreach (MobData mob in group.mobs) { Tile tile; if (mob.minSize != RegionSize.NULL) { if (size < mob.minSize) { continue; } } if (mob.location == MapRoom.DIRECTION_LARGEST_ROOM) { tile = room.GetLargestSubRoom(mob.exclude); } else { tile = room.GetSubRoom(mob.roomSize, mob.location, mob.exclude); } if (tile == null) { continue; } MonsterSpawnInfo monsterInfo; if (mob.count > 1) { for (int i = 0; i < mob.count; i++) { monsterInfo = level.SpawnMonsterToRoom(room, mob.monsterTypeName, tile, true, mob.level, mob.chance); if (monsterInfo != null) { count++; monsterInfo.tempId = mob.mobId; if (mob.idParent > 0) { try { MonsterSpawnInfo parent = null; foreach (MonsterSpawnInfo inf in infos) { if (inf.tempId == mob.idParent) { parent = inf; break; } } monsterInfo.master = parent; } catch (Exception) { throw new Exception("pokousim se nastavit idparent na " + mob.idParent + " ale takovy mob neexistuje! kouka se jen na moby ktere byly nacteny drive. ID nacitaneho moba je " + mob.mobId); } } infos.Add(monsterInfo); } } } else { monsterInfo = level.SpawnMonsterToRoom(room, mob.monsterTypeName, tile, false, mob.level, mob.chance); if (monsterInfo != null) { count++; monsterInfo.tempId = mob.mobId; if (mob.idParent > 0) { try { MonsterSpawnInfo parent = null; foreach (MonsterSpawnInfo inf in infos) { if (inf.tempId == mob.idParent) { parent = inf; break; } } monsterInfo.master = parent; } catch (Exception) { throw new Exception("pokousim se nastavit idparent na " + mob.idParent + " ale takovy mob neexistuje! kouka se jen na moby ktere byly nacteny drive. ID nacitaneho moba je " + mob.mobId); } } infos.Add(monsterInfo); } } } if (group.extraGroups.Any()) { int minStack = 10000; int maxStack = 0; foreach (ExtraGroupData extraGroup in group.extraGroups) { // spawn all -1 groups if (extraGroup.stackId == -1) { if (Random.Range(0, 100) < extraGroup.chance) { GenerateGenericEnemyGroup(room, level, RoomType.EXTRA_ROOM, difficulty, regionData, extraGroup.groupId); } } else // optimize for next for loop { if (extraGroup.stackId > maxStack) { maxStack = extraGroup.stackId; } if (extraGroup.stackId < minStack) { minStack = extraGroup.stackId; } } } // are there any groups that have stackid set? if (maxStack > 0) { // shuffle System.Random rnd = new System.Random(); IOrderedEnumerable <ExtraGroupData> shuffled = group.extraGroups.OrderBy(item => rnd.Next()); for (int i = minStack; i <= maxStack; i++) { foreach (ExtraGroupData extraGroup in shuffled) { if (extraGroup.stackId == i) { if (Random.Range(0, 100) < extraGroup.chance) { GenerateGenericEnemyGroup(room, level, RoomType.EXTRA_ROOM, difficulty, regionData, extraGroup.groupId); break; // only one spawned group per stack } } } } } } spawned = true; Debug.Log("spawnuto " + count + " ze skup. " + selectedId); break; } } if (!spawned) { Debug.LogError("nenalezena spawngroup do mistnosti typu " + roomType.ToString() + " " + room.region.x + "-" + room.region.y + " in world " + level.ToString()); } if (forcedId > 0 && WorldHolder.instance.activeMap != null) { WorldHolder.instance.activeMap.ConfigureMonstersAfterSpawn(); } }
public int CompareTo(MapRoom otherRoom) { return(otherRoom.roomSize.CompareTo(roomSize)); }
public bool IsConnected(MapRoom otherRoom) { return(connectedRooms.Contains(otherRoom)); }