예제 #1
0
        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);
        }
예제 #2
0
        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;
                    }
                }
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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;
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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();
        }
예제 #9
0
 private bool AreRoomsConnected(MapRoom roomA, MapRoom roomB)
 {
     return(roomA.IsConnected(roomB));
 }
예제 #10
0
        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;
                        }
                    }
                }
            }
        }
예제 #11
0
        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();
            }
        }
예제 #12
0
 public int CompareTo(MapRoom otherRoom)
 {
     return(otherRoom.roomSize.CompareTo(roomSize));
 }
예제 #13
0
 public bool IsConnected(MapRoom otherRoom)
 {
     return(connectedRooms.Contains(otherRoom));
 }