Esempio n. 1
0
        public static void CreateChamber(RDungeonMap map, DungeonArrayFloor arrayFloor, int chamberNum, string string1, string string2, string string3)
        {
            try {
                bool started = false;
                //Messenger.AdminMsg(chamberNum.ToString(), Text.Black);
                switch (chamberNum) {
                    case 1: {//pre-mapped
                        DungeonArrayRoom room = arrayFloor.Rooms[arrayFloor.Chamber.X, arrayFloor.Chamber.Y];
                        string[] start = string2.Split(':');
                        string[] end = string3.Split(':');
                        int sourceX = start[0].ToInt();
                        int sourceY = start[1].ToInt();
                        int xDiff = end[0].ToInt() - sourceX + 1;
                        int yDiff = end[1].ToInt() - sourceY + 1;

                        IMap sourceMap = MapManager.RetrieveMap(string1.ToInt());
                        for (int x = 0; x < xDiff; x++) {
                            for (int y = 0; y < yDiff; y++) {
                                MapCloner.CloneTile(sourceMap, sourceX + x, sourceY + y, map.Tile[room.StartX + x, room.StartY + y]);
                                arrayFloor.MapArray[room.StartX + x, room.StartY + y] = sourceMap.Tile[sourceX + x, sourceY + y].RDungeonMapValue;
                            }
                        }
                        }
                        break;
                    case 2: {//no chamber

                        }
                        break;
                    case 3: {//chamber that accepts start and end

                        }
                        break;
                    case 4: {//Ice Puzzle
                            int startX = 0;
                            int startY = 0;
                            string[] parse = string1.Split(':');
                            bool start = false;
                            bool end = false;
                            if (parse[0] == "1") {
                                start = true;
                            }
                            if (parse[1] == "1") {
                                end = true;
                            }
                            if (start && end) {
                                for (int x = 0; x < map.MaxX; x++) {
                                    for (int y = 0; y < map.MaxY; y++) {
                                        map.Tile[x, y].Type = Enums.TileType.Blocked;
                                        arrayFloor.MapArray[x, y] = 1025;
                                    }
                                }
                            }

                            DungeonArrayRoom room = arrayFloor.Rooms[arrayFloor.Chamber.X, arrayFloor.Chamber.Y];
                            parse = string3.Split(':');
                            int xDiff = room.EndX - room.StartX + 1;
                            int yDiff = room.EndY - room.StartY + 1;
                            int[,] intArray = new int[xDiff - 2, yDiff-2];

                            if (start && end) {

                                intArray = RandomIce.GenIcePuzzle(xDiff - 2, yDiff-2, parse[2].ToInt(), parse[3].ToInt(), parse[4].ToInt(), parse[5].ToInt(), parse[6].ToInt(), false, false);
                            } else if (end) {
                                intArray = RandomIce.GenIcePuzzle(xDiff - 2, yDiff-2, parse[2].ToInt(), parse[3].ToInt(), parse[4].ToInt(), parse[5].ToInt(), parse[6].ToInt(), true, false);
                            }

                            //put it on the map
                            for (int y = 0; y < yDiff; y++) {
                                for (int x = 0; x < xDiff; x++) {
                                    if (x == 0 || x == xDiff - 1 || y == 0 || y == yDiff - 1) {
                                        map.Tile[room.StartX + x, room.StartY + y].Type = Enums.TileType.Slippery;
                                        arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 2;
                                    } else if (intArray[x-1,y-1] == RandomIce.START) {

                                        map.Tile[room.StartX + x, room.StartY + y].Type = Enums.TileType.Walkable;
                                        arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 6;
                                        startX = x;
                                        startY = y;
                                        started = true;
                                    } else if (intArray[x-1,y-1] == RandomIce.END) {

                                        map.Tile[room.StartX + x, room.StartY + y].Type = Enums.TileType.RDungeonGoal;
                                        arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 7;
                                    } else if (intArray[x-1,y-1] == RandomIce.BLOCK) {
                                        map.Tile[room.StartX + x, room.StartY + y].Type = Enums.TileType.Blocked;
                                        arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 1;
                                    } else if (intArray[x-1,y-1] == RandomIce.GROUND) {
                                        map.Tile[room.StartX + x, room.StartY + y].Type = Enums.TileType.Hallway;
                                        arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 3;
                                    } else {
                                        map.Tile[room.StartX + x, room.StartY + y].Type = Enums.TileType.Slippery;
                                        arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 2;
                                    }

                                }
                            }

                            if (!start && end) {
                                if (startX == 1) {
                                    map.Tile[room.StartX + startX - 1, room.StartY + startY].Type = Enums.TileType.Walkable;
                                    arrayFloor.MapArray[room.StartX + startX - 1, room.StartY + startY] = 6;
                                } else if (startX == xDiff - 2) {
                                    map.Tile[room.StartX + startX + 1, room.StartY + startY].Type = Enums.TileType.Walkable;
                                    arrayFloor.MapArray[room.StartX + startX + 1, room.StartY + startY] = 6;
                                    }
                                if (startY == 1) {
                                    map.Tile[room.StartX + startX, room.StartY + startY - 1].Type = Enums.TileType.Walkable;
                                    arrayFloor.MapArray[room.StartX + startX, room.StartY + startY - 1] = 6;
                                } else if (startY == yDiff - 2) {
                                    map.Tile[room.StartX + startX, room.StartY + startY + 1].Type = Enums.TileType.Walkable;
                                    arrayFloor.MapArray[room.StartX + startX, room.StartY + startY + 1] = 6;
                                }
                            }

                            if (start && end) {
                                map.Tile[room.StartX, room.StartY].Type = Enums.TileType.Scripted;
                                map.Tile[room.StartX, room.StartY].Data1 = 15;
                                map.Tile[room.StartX, room.StartY].Data3 = 1;
                                arrayFloor.MapArray[room.StartX, room.StartY] = 4;
                            } else if (end) {
                                map.Tile[room.StartX, room.StartY].Type = Enums.TileType.Walkable;
                                arrayFloor.MapArray[room.StartX, room.StartY] = 3;
                                map.Tile[room.EndX, room.EndY].Type = Enums.TileType.Walkable;
                                arrayFloor.MapArray[room.EndX, room.EndY] = 3;
                            }
                            if (!started && start) {
                                Messenger.AdminMsg("Bad puzzle generated", Text.Red);
                            }
                        }
                        break;
                    case 10: {//pre-mapped locked chamber
                        DungeonArrayRoom room = arrayFloor.Rooms[arrayFloor.Chamber.X, arrayFloor.Chamber.Y];

                        //IMap sourceMap = MapManager.RetrieveMap(string1.ToInt());
                        for (int x = 0; x < 5; x++) {
                            for (int y = 0; y < 5; y++) {
                                if (x == 2 && y == 3) {
                                    map.Tile[room.StartX + x, room.StartY + y].Type = Enums.TileType.ScriptedSign;
                                    map.Tile[room.StartX + x, room.StartY + y].Mask2 = 6;
                                    map.Tile[room.StartX + x, room.StartY + y].Mask2Set = 4;
                                    map.Tile[room.StartX + x, room.StartY + y].Data1 = 10;
                                    map.Tile[room.StartX + x, room.StartY + y].String1 = "-2:-3";
                                    map.Tile[room.StartX + x, room.StartY + y].String2 = "2:1";
                                    arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 1025;
                                } else if (x == 0 || y == 0 || x == 4 || y == 4) {
                                    arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 4;
                                } else if (x == 1 || y == 1 || x == 3 || y == 3) {
                                    map.Tile[room.StartX + x, room.StartY + y].Type = Enums.TileType.Blocked;
                                    arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 1025;
                                } else if (x == 2 && y == 2) {
                                    map.Tile[room.StartX + x, room.StartY + y].Type = Enums.TileType.ScriptedSign;
                                    map.Tile[room.StartX + x, room.StartY + y].Data1 = 9;
                                    map.Tile[room.StartX + x, room.StartY + y].String1 = string1;
                                    map.Tile[room.StartX + x, room.StartY + y].String2 = string2;
                                    map.Tile[room.StartX + x, room.StartY + y].String3 = "3";
                                    arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 1025;
                                }

                            }
                        }
                        }
                        break;
                    case 11: {//3x3 kecleon shop
                        DungeonArrayRoom room = arrayFloor.Rooms[arrayFloor.Chamber.X, arrayFloor.Chamber.Y];

                        //IMap sourceMap = MapManager.RetrieveMap(string1.ToInt());
                        //Messenger.AdminMsg("Room creating", Text.Red);
                        for (int x = 0; x < 7; x++) {
                            for (int y = 0; y < 7; y++) {
                                if (x <= 1 || y <= 1 || x >= 5 || y >= 5) {
                                    //free space
                                    arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 4;
                                } else if (x == 2 || y == 2 || x == 4 || y == 4) {
                                    if (Server.Math.Rand(0,2) == 0) {
                                        //shop
                                        int itemNum = 0;
                                        int itemVal = 1;
                                        string tag = "";
                                        int price = 1;
                                        string[] itemSelection = string2.Split(';');
                                        string[] priceSelection = string3.Split(';');
                                        int chosenIndex = Server.Math.Rand(0, itemSelection.Length);
                                        string[] chosenItem = itemSelection[chosenIndex].Split(',');
                                        if (chosenItem[0].IsNumeric()) {
                                            if (chosenItem.Length == 2 && chosenItem[1].IsNumeric()) {
                                                itemNum = chosenItem[0].ToInt();
                                                itemVal = chosenItem[1].ToInt();
                                                price = priceSelection[chosenIndex].ToInt();
                                            } else if (chosenItem.Length == 3 && chosenItem[2].IsNumeric()) {
                                                itemNum = chosenItem[0].ToInt();
                                                itemVal = chosenItem[1].ToInt();
                                                tag = chosenItem[2];
                                                price = priceSelection[chosenIndex].ToInt();
                                            } else {
                                                itemNum = chosenItem[0].ToInt();
                                                price = priceSelection[chosenIndex].ToInt();
                                            }
                                        }
                                        map.Tile[room.StartX + x, room.StartY + y].Type = Enums.TileType.DropShop;
                                        map.Tile[room.StartX + x, room.StartY + y].Mask2 = 67;
                                        map.Tile[room.StartX + x, room.StartY + y].Mask2Set = 0;
                                        map.Tile[room.StartX + x, room.StartY + y].Data1 = price; //price per unit
                                        map.Tile[room.StartX + x, room.StartY + y].Data2 = itemNum; //item
                                        map.Tile[room.StartX + x, room.StartY + y].Data3 = itemVal; //amount
                                        map.Tile[room.StartX + x, room.StartY + y].String1 = "";//no tag//no charID
                                        map.Tile[room.StartX + x, room.StartY + y].String2 = "";//no tag
                                        arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 1027;
                                    } else {
                                        map.Tile[room.StartX + x, room.StartY + y].Type = Enums.TileType.DropShop;
                                        map.Tile[room.StartX + x, room.StartY + y].Mask2 = 67;
                                        map.Tile[room.StartX + x, room.StartY + y].Mask2Set = 0;
                                        map.Tile[room.StartX + x, room.StartY + y].Data1 = 0; //price per unit
                                        map.Tile[room.StartX + x, room.StartY + y].Data2 = 0; //item
                                        map.Tile[room.StartX + x, room.StartY + y].Data2 = 0; //amount
                                        map.Tile[room.StartX + x, room.StartY + y].String1 = "";//no tag//no charID
                                        map.Tile[room.StartX + x, room.StartY + y].String2 = "";//no tag
                                        arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 1027;
                                    }
                                } else if (x == 3 && y == 3) {
                                    map.Tile[room.StartX + x, room.StartY + y].Type = Enums.TileType.NPCAvoid;
                                    map.Tile[room.StartX + x, room.StartY + y].Mask2 = 67;
                                    map.Tile[room.StartX + x, room.StartY + y].Mask2Set = 0;
                                    arrayFloor.MapArray[room.StartX + x, room.StartY + y] = 1027;
                                    MapNpcPreset npc = new MapNpcPreset();
                                    npc.SpawnX = room.StartX + x;
                                    npc.SpawnY = room.StartY + y;
                                    npc.NpcNum = 32;
                                    npc.MinLevel = 100;
                                    npc.MaxLevel = 100;
                                    map.Npc.Add(npc);
                                }

                            }
                        }
                        //Messenger.AdminMsg("Room created: " + map.Name, Text.Red);
                        }
                        break;
                    default: {
                            if (arrayFloor.Start.X == arrayFloor.Chamber.X && arrayFloor.Start.Y == arrayFloor.Chamber.Y) {
                                DungeonArrayRoom room = arrayFloor.Rooms[arrayFloor.Start.X, arrayFloor.Start.Y];
                                arrayFloor.MapArray[room.StartX, room.StartY] = DungeonArrayFloor.STARTTILE;
                            }
                            if (arrayFloor.End.X == arrayFloor.Chamber.X && arrayFloor.End.Y == arrayFloor.Chamber.Y) {
                                DungeonArrayRoom room = arrayFloor.Rooms[arrayFloor.End.X, arrayFloor.End.Y];
                                arrayFloor.MapArray[room.StartX + 1, room.StartY] = DungeonArrayFloor.ENDTILE;
                            }
                        }
                        break;
                }
            } catch (Exception e) {
                Messenger.AdminMsg(e.ToString(), Text.Black);
            }
        }
        public static RDungeonMap GenerateFloor(Client client, int dungeonIndex, int floorNum, GeneratorOptions options)
        {
            RDungeon dungeon = RDungeonManager.RDungeons[dungeonIndex];
            RDungeonFloor floor = dungeon.Floors[floorNum];

            //decide on a chamber
            RDungeonChamberReq req = null;
            int chamber = -1;
            if (options.Chambers.Count > 0) {
                chamber = Math.Rand(0, options.Chambers.Count);
                req = (RDungeonChamberReq)Scripting.ScriptManager.InvokeFunction("GetChamberReq", options.Chambers[chamber].ChamberNum, options.Chambers[chamber].String1, options.Chambers[chamber].String2, options.Chambers[chamber].String3);
            }

            // Generate the ASCII map

            DungeonArrayFloor arrayFloor = new DungeonArrayFloor(options, req);
            //int[,] arrayMap = ASCIIFloorGen.GenASCIIMap(options);

            //ASCIIFloorGen.TextureDungeon(arrayMap);

            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();

            watch.Start();

            // Prepare the base map
            DataManager.Maps.RDungeonMap rDungeonMap = new DataManager.Maps.RDungeonMap(MapManager.GenerateMapID(RDungeonMap.ID_PREFIX));
            rDungeonMap.MaxX = arrayFloor.MapArray.GetUpperBound(0);
            rDungeonMap.MaxY = arrayFloor.MapArray.GetUpperBound(1);
            rDungeonMap.Tile = new DataManager.Maps.Tile[rDungeonMap.MaxX + 1, rDungeonMap.MaxY + 1];
            rDungeonMap.RDungeonIndex = dungeonIndex;
            rDungeonMap.RDungeonFloor = floorNum;

            RDungeonMap map = new RDungeonMap(rDungeonMap);

            for (int x = 0; x <= rDungeonMap.Tile.GetUpperBound(0); x++) {
                for (int y = 0; y <= rDungeonMap.Tile.GetUpperBound(1); y++) {
                    AmbiguateTile(map.Tile[x,y]);
                }
            }

            map.Name = GenerateName(dungeonIndex, floorNum);

            map.Revision = 0;
            map.OriginalDarkness = floor.Darkness;
            map.HungerEnabled = true;
            map.RecruitEnabled = dungeon.Recruitment;
            map.ExpEnabled = dungeon.Exp;
            map.TimeLimit = dungeon.WindTimer;
            map.DungeonIndex = dungeon.DungeonIndex;
            map.MinNpcs = floor.NpcMin;
            map.MaxNpcs = floor.NpcMax;
            map.NpcSpawnTime = floor.NpcSpawnTime;

            if (Globals.ServerWeather != Enums.Weather.Ambiguous) {
                map.Weather = Globals.ServerWeather;
            } else if (floor.Weather.Count > 0) {
                map.Weather = floor.Weather[Server.Math.Rand(0, floor.Weather.Count)];
            }

            map.Music = floor.Music;

            //texture chamber
            if (arrayFloor.Chamber.X != -1 && arrayFloor.Chamber.Y != -1) {
                Scripting.ScriptManager.InvokeSub("CreateChamber", map, arrayFloor, options.Chambers[chamber].ChamberNum, options.Chambers[chamber].String1, options.Chambers[chamber].String2, options.Chambers[chamber].String3);
            }

            DungeonArrayFloor.TextureDungeon(arrayFloor.MapArray);

            for (int x = 0; x <= rDungeonMap.Tile.GetUpperBound(0); x++) {
                for (int y = 0; y <= rDungeonMap.Tile.GetUpperBound(1); y++) {
                    map.Tile[x, y].RDungeonMapValue = arrayFloor.MapArray[x, y];
                }
            }

            TextureDungeonMap(map);

            //block borders
            for (int y = 0; y <= map.MaxY; y++) {
                map.Tile[0, y].Type = Enums.TileType.Blocked;
                map.Tile[map.MaxX, y].Type = Enums.TileType.Blocked;
            }
            for (int x = 0; x <= map.MaxX; x++) {
                map.Tile[x, 0].Type = Enums.TileType.Blocked;
                map.Tile[x, map.MaxY].Type = Enums.TileType.Blocked;
            }

            watch.Stop();

            foreach (MapNpcPreset npc in floor.Npcs) {
                MapNpcPreset newNpc = new MapNpcPreset();
                newNpc.NpcNum = npc.NpcNum;
                newNpc.MinLevel = npc.MinLevel;
                newNpc.MaxLevel = npc.MaxLevel;
                newNpc.SpawnX = npc.SpawnX;
                newNpc.SpawnY = npc.SpawnY;
                newNpc.AppearanceRate = npc.AppearanceRate;
                newNpc.StartStatus = npc.StartStatus;
                newNpc.StartStatusCounter = npc.StartStatusCounter;
                newNpc.StartStatusChance = npc.StartStatusChance;
                map.Npc.Add(newNpc);
            }

            map.SpawnItems();
            int n = Server.Math.Rand(options.ItemMin, options.ItemMax + 1);
            if (floor.Items.Count == 0) {
                n = 0;
            } else if (n > Constants.MAX_MAP_ITEMS) {
                n = Constants.MAX_MAP_ITEMS;
            }
            int slot = 0;
            int itemX = -1, itemY = -1;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < 100; j++) {
                    bool spawned = false;
                    if (Server.Math.Rand(0, 100) < floor.Items[slot].AppearanceRate) {
                        arrayFloor.GenItem(floor.Items[slot].OnGround, floor.Items[slot].OnWater, floor.Items[slot].OnWall, ref itemX, ref itemY);
                        if (itemX > -1) {
                            map.SpawnItem(floor.Items[slot].ItemNum, Server.Math.Rand(floor.Items[slot].MinAmount, floor.Items[slot].MaxAmount + 1),
                                          (Server.Math.Rand(0, 100) < floor.Items[slot].StickyRate), floor.Items[slot].Hidden, floor.Items[slot].Tag, itemX, itemY, null);
                            spawned = true;
                        }

                    }
                    slot++;
                    if (slot >= floor.Items.Count) slot = 0;
                    if (spawned) break;
                }
            }

            //map.SpawnNpcs();
            map.NpcSpawnWait = new TickCount(Core.GetTickCount().Tick);

            return map;
        }