Пример #1
0
        // TODO: DI magic please
        public MPQDS1(Stream stream, LevelPreset level, LevelDetail levelDetail, LevelType levelType, IEngineDataManager engineDataManager, IResourceManager resourceManager)
        {
            log.Debug($"Loading {level.Name} (Act {levelDetail.Act})...");
            var br = new BinaryReader(stream);

            Version = br.ReadInt32();
            Width   = br.ReadInt32() + 1;
            Height  = br.ReadInt32() + 1;
            Act     = br.ReadInt32() + 1;

            if (Version >= 10)
            {
                TagType = br.ReadInt32();
                if (TagType == 1 || TagType == 2)
                {
                    NumberOfTags = 1;
                }
            }

            FileCount = 0;
            if (Version >= 3)
            {
                FileCount = br.ReadInt32();
                for (int i = 0; i < FileCount; i++)
                {
                    var fn = "";
                    while (true)
                    {
                        var b = br.ReadByte();
                        if (b == 0)
                        {
                            break;
                        }
                        fn += (char)b;
                    }
                    if (fn.StartsWith("\\d2\\"))
                    {
                        fn = fn.Substring(4);
                    }
                    FileNames.Add(fn);
                }
            }

            if (Version >= 9 && Version <= 13)
            {
                br.ReadBytes(8);
            }

            if (Version >= 4)
            {
                NumberOfWalls = br.ReadInt32();

                if (Version >= 16)
                {
                    NumberOfFloors = br.ReadInt32();
                }
                else
                {
                    NumberOfFloors = 1;
                }
            }
            else
            {
                NumberOfFloors = 1;
                NumberOfWalls  = 1;
                NumberOfTags   = 1;
            }



            var layoutStream = new List <int>();

            if (Version < 4)
            {
                layoutStream.AddRange(new int[] { 1, 9, 5, 12, 11 });
            }
            else
            {
                for (var x = 0; x < NumberOfWalls; x++)
                {
                    layoutStream.Add(1 + x);
                    layoutStream.Add(5 + x);
                }
                for (var x = 0; x < NumberOfFloors; x++)
                {
                    layoutStream.Add(9 + x);
                }

                layoutStream.Add(11);

                if (NumberOfTags > 0)
                {
                    layoutStream.Add(12);
                }
            }

            WallLayers = new MPQDS1WallLayer[NumberOfWalls];
            for (var l = 0; l < NumberOfWalls; l++)
            {
                WallLayers[l] = new MPQDS1WallLayer
                {
                    Orientations = new MPQDS1WallOrientationTileProps[Width * Height],
                    Props        = new MPQDS1TileProps[Width * Height]
                };
            }

            FloorLayers = new MPQDS1FloorLayer[NumberOfFloors];
            for (var l = 0; l < NumberOfFloors; l++)
            {
                FloorLayers[l] = new MPQDS1FloorLayer
                {
                    Props = new MPQDS1TileProps[Width * Height]
                };
            }

            ShadowLayers = new MPQDS1ShadowLayer[1];
            for (var l = 0; l < 1; l++)
            {
                ShadowLayers[l] = new MPQDS1ShadowLayer
                {
                    Props = new MPQDS1TileProps[Width * Height]
                };
            }


            for (int n = 0; n < layoutStream.Count(); n++)
            {
                for (var y = 0; y < Height; y++)
                {
                    for (var x = 0; x < Width; x++)
                    {
                        switch (layoutStream[n])
                        {
                        // Walls
                        case 1:
                        case 2:
                        case 3:
                        case 4:
                            WallLayers[layoutStream[n] - 1].Props[x + (y * Width)] = new MPQDS1TileProps
                            {
                                Prop1 = br.ReadByte(),
                                Prop2 = br.ReadByte(),
                                Prop3 = br.ReadByte(),
                                Prop4 = br.ReadByte()
                            };
                            break;

                        // Orientations
                        case 5:
                        case 6:
                        case 7:
                        case 8:
                            // TODO: Orientations
                            if (Version < 7)
                            {
                                br.ReadBytes(4);
                            }
                            else
                            {
                                WallLayers[layoutStream[n] - 5].Orientations[x + (y * Width)] = new MPQDS1WallOrientationTileProps
                                {
                                    Orientation1 = br.ReadByte(),
                                    Orientation2 = br.ReadByte(),
                                    Orientation3 = br.ReadByte(),
                                    Orientation4 = br.ReadByte(),
                                };
                            }
                            break;

                        // Floors
                        case 9:
                        case 10:
                            FloorLayers[layoutStream[n] - 9].Props[x + (y * Width)] = new MPQDS1TileProps
                            {
                                Prop1 = br.ReadByte(),
                                Prop2 = br.ReadByte(),
                                Prop3 = br.ReadByte(),
                                Prop4 = br.ReadByte()
                            };
                            break;

                        // Shadow
                        case 11:
                            ShadowLayers[layoutStream[n] - 11].Props[x + (y * Width)] = new MPQDS1TileProps
                            {
                                Prop1 = br.ReadByte(),
                                Prop2 = br.ReadByte(),
                                Prop3 = br.ReadByte(),
                                Prop4 = br.ReadByte()
                            };
                            break;

                        // Tags
                        case 12:
                            // TODO: Tags
                            br.ReadBytes(4);
                            break;
                        }
                    }
                }
            }



            var dt1Mask = level.Dt1Mask;

            for (int i = 0; i < 32; i++)
            {
                var tilePath = levelType.File[i];
                var isMasked = ((dt1Mask >> i) & 1) == 1;
                if (!isMasked)
                {
                    continue;
                }

                log.Debug($"Loading DT resource {levelType.File[i]}");

                DT1s[i] = resourceManager.GetMPQDT1("data\\global\\tiles\\" + levelType.File[i].Replace("/", "\\"));
            }

            LookupTable = new List <DS1LookupTable>();
            foreach (var dt1 in DT1s.Where(x => x != null))
            {
                foreach (var tile in dt1.Tiles)
                {
                    LookupTable.Add(new DS1LookupTable
                    {
                        MainIndex   = tile.MainIndex,
                        Orientation = tile.Orientation,
                        SubIndex    = tile.SubIndex,
                        Frame       = tile.RarityOrFrameIndex,
                        TileRef     = tile
                    });
                }
            }
        }
Пример #2
0
        public static LevelDetail ToLevelDetail(this string[] v)
        {
            var result = new LevelDetail();
            int i      = 0;

            result.Name         = v[i++];
            result.Id           = Convert.ToInt32(v[i++]);
            result.Pal          = Convert.ToInt32(v[i++]);
            result.Act          = Convert.ToInt32(v[i++]);
            result.Layer        = Convert.ToInt32(v[i++]);
            result.SizeX        = Convert.ToInt32(v[i++]);
            result.SizeY        = Convert.ToInt32(v[i++]);
            result.OffsetX      = Convert.ToInt32(v[i++]);
            result.OffsetY      = Convert.ToInt32(v[i++]);
            result.Depend       = Convert.ToInt32(v[i++]);
            result.Rain         = Convert.ToInt32(v[i++]);
            result.Mud          = Convert.ToInt32(v[i++]);
            result.NoPer        = Convert.ToInt32(v[i++]);
            result.LOSDraw      = Convert.ToInt32(v[i++]);
            result.FloorFilter  = Convert.ToInt32(v[i++]);
            result.BlankScreen  = Convert.ToInt32(v[i++]);
            result.DrawEdges    = Convert.ToInt32(v[i++]);
            result.IsInside     = Convert.ToInt32(v[i++]);
            result.DrlgType     = Convert.ToInt32(v[i++]);
            result.LevelType    = Convert.ToInt32(v[i++]);
            result.SubType      = Convert.ToInt32(v[i++]);
            result.SubTheme     = Convert.ToInt32(v[i++]);
            result.SubWaypoint  = Convert.ToInt32(v[i++]);
            result.SubShrine    = Convert.ToInt32(v[i++]);
            result.Vis0         = Convert.ToInt32(v[i++]);
            result.Vis1         = Convert.ToInt32(v[i++]);
            result.Vis2         = Convert.ToInt32(v[i++]);
            result.Vis3         = Convert.ToInt32(v[i++]);
            result.Vis4         = Convert.ToInt32(v[i++]);
            result.Vis5         = Convert.ToInt32(v[i++]);
            result.Vis6         = Convert.ToInt32(v[i++]);
            result.Vis7         = Convert.ToInt32(v[i++]);
            result.Warp0        = Convert.ToInt32(v[i++]);
            result.Warp1        = Convert.ToInt32(v[i++]);
            result.Warp2        = Convert.ToInt32(v[i++]);
            result.Warp3        = Convert.ToInt32(v[i++]);
            result.Warp4        = Convert.ToInt32(v[i++]);
            result.Warp5        = Convert.ToInt32(v[i++]);
            result.Warp6        = Convert.ToInt32(v[i++]);
            result.Warp7        = Convert.ToInt32(v[i++]);
            result.Intensity    = Convert.ToInt32(v[i++]);
            result.Red          = Convert.ToInt32(v[i++]);
            result.Green        = Convert.ToInt32(v[i++]);
            result.Blue         = Convert.ToInt32(v[i++]);
            result.Portal       = Convert.ToInt32(v[i++]);
            result.Position     = Convert.ToInt32(v[i++]);
            result.SaveMonsters = Convert.ToInt32(v[i++]);
            result.Quest        = Convert.ToInt32(v[i++]);
            result.WarpDist     = Convert.ToInt32(v[i++]);
            result.MonLvl1      = Convert.ToInt32(v[i++]);
            result.MonLvl2      = Convert.ToInt32(v[i++]);
            result.MonLvl3      = Convert.ToInt32(v[i++]);
            result.MonDen       = Convert.ToInt32(v[i++]);
            result.MonUMin      = Convert.ToInt32(v[i++]);
            result.MonUMax      = Convert.ToInt32(v[i++]);
            result.MonWndr      = Convert.ToInt32(v[i++]);
            result.MonSpcWalk   = Convert.ToInt32(v[i++]);
            result.Mtot         = Convert.ToInt32(v[i++]);
            result.M1_25        = new int[25];
            for (int j = 0; j < 25; j++)
            {
                result.M1_25[j] = Convert.ToInt32(v[i++]);
            }
            result.S1_25 = new int[25];
            for (int j = 0; j < 25; j++)
            {
                result.S1_25[j] = Convert.ToInt32(v[i++]);
            }
            result.Utot  = Convert.ToInt32(v[i++]);
            result.U1_25 = new int[25];
            for (int j = 0; j < 25; j++)
            {
                result.U1_25[j] = Convert.ToInt32(v[i++]);
            }
            result.C1_5 = new int[5];
            for (int j = 0; j < 5; j++)
            {
                result.C1_5[j] = Convert.ToInt32(v[i++]);
            }
            result.CA1_5 = new int[5];
            for (int j = 0; j < 5; j++)
            {
                result.CA1_5[j] = Convert.ToInt32(v[i++]);
            }
            result.CD1_5 = new int[5];
            for (int j = 0; j < 5; j++)
            {
                result.CD1_5[j] = Convert.ToInt32(v[i++]);
            }
            result.Themes    = Convert.ToInt32(v[i++]);
            result.SoundEnv  = Convert.ToInt32(v[i++]);
            result.Waypoint  = Convert.ToInt32(v[i++]);
            result.LevelName = v[i++];
            result.LevelWarp = v[i++];
            result.EntryFile = v[i++];
            result.ObjGrp0_7 = new int[8];
            for (int j = 0; j < 5; j++)
            {
                result.ObjGrp0_7[j] = Convert.ToInt32(v[i++]);
            }
            result.ObjPrb0_7 = new int[8];
            for (int j = 0; j < 5; j++)
            {
                result.ObjPrb0_7[j] = Convert.ToInt32(v[i++]);
            }
            result.Beta = Convert.ToInt32(v[i++]) == 1;


            return(result);
        }
Пример #3
0
        public static LevelDetail ToLevelDetail(this string[] v, IEnumerable <LevelPreset> levelPresets, IEnumerable <LevelType> levelTypes)
        {
            var result = new LevelDetail();

            result.Difficulties.Add(eDifficulty.NORMAL, new LevelDetailDifficulty());
            result.Difficulties.Add(eDifficulty.NIGHTMARE, new LevelDetailDifficulty());
            result.Difficulties.Add(eDifficulty.HELL, new LevelDetailDifficulty());
            int i = 0;

            result.Name        = v[i++];
            result.Id          = Convert.ToInt32(v[i++]);
            result.Pal         = Convert.ToInt32(v[i++]);
            result.Act         = Convert.ToInt32(v[i++]);
            result.QuestFlag   = IntOrEmpty(v[i++]);
            result.QuestFlagEx = IntOrEmpty(v[i++]);
            result.Layer       = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.NORMAL].SizeX    = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.NORMAL].SizeY    = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.NIGHTMARE].SizeX = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.NIGHTMARE].SizeY = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.HELL].SizeX      = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.HELL].SizeY      = Convert.ToInt32(v[i++]);
            result.OffsetX  = Convert.ToInt32(v[i++]);
            result.OffsetY  = Convert.ToInt32(v[i++]);
            result.Depend   = Convert.ToInt32(v[i++]);
            result.Teleport = (v[i] == "1" || v[i] == "2");
            result.CantTeleportThroughWallsObjects = (v[i] == "0" || v[i] == "2");
            i++;
            result.Rain        = (v[i++] == "1");
            result.Mud         = (v[i++] == "1");
            result.NoPer       = (v[i++] == "1");
            result.LOSDraw     = (v[i++] == "1");
            result.FloorFilter = (v[i++] == "1");
            result.BlankScreen = (v[i++] == "1");
            result.DrawEdges   = (v[i++] == "1");
            result.IsInside    = (v[i++] == "1");
            result.DrlgType    = Convert.ToInt32(v[i++]);
            result.LevelTypeId = Convert.ToInt32(v[i++]);
            result.SubType     = Convert.ToInt32(v[i++]);
            result.SubTheme    = Convert.ToInt32(v[i++]);
            result.SubWaypoint = Convert.ToInt32(v[i++]);
            result.SubShrine   = Convert.ToInt32(v[i++]);
            result.Vis0_7      = new int[8];
            for (int j = 0; j < 8; j++)
            {
                result.Vis0_7[j] = Convert.ToInt32(v[i++]);
            }
            result.Warp0_7 = new int[8];
            for (int j = 0; j < 8; j++)
            {
                result.Warp0_7[j] = Convert.ToInt32(v[i++]);
            }
            result.Intensity    = Convert.ToInt32(v[i++]);
            result.Red          = Convert.ToInt32(v[i++]);
            result.Green        = Convert.ToInt32(v[i++]);
            result.Blue         = Convert.ToInt32(v[i++]);
            result.Portal       = (v[i++] == "1");
            result.Position     = (v[i++] == "1");
            result.SaveMonsters = (v[i++] == "1");
            result.Quest        = Convert.ToInt32(v[i++]);
            result.WarpDist     = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.NORMAL].MonLevel      = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.NIGHTMARE].MonLevel   = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.HELL].MonLevel        = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.NORMAL].MonLevelEx    = IntOrEmpty(v[i++]);
            result.Difficulties[eDifficulty.NIGHTMARE].MonLevelEx = IntOrEmpty(v[i++]);
            result.Difficulties[eDifficulty.HELL].MonLevelEx      = IntOrEmpty(v[i++]);
            result.Difficulties[eDifficulty.NORMAL].MonDen        = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.NIGHTMARE].MonDen     = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.HELL].MonDen          = Convert.ToInt32(v[i++]);
            result.Difficulties[eDifficulty.NORMAL].MonUMin       = IntOrZero(v[i++]);
            result.Difficulties[eDifficulty.NORMAL].MonUMax       = IntOrZero(v[i++]);
            result.Difficulties[eDifficulty.NIGHTMARE].MonUMin    = IntOrZero(v[i++]);
            result.Difficulties[eDifficulty.NIGHTMARE].MonUMax    = IntOrZero(v[i++]);
            result.Difficulties[eDifficulty.HELL].MonUMin         = IntOrZero(v[i++]);
            result.Difficulties[eDifficulty.HELL].MonUMax         = IntOrZero(v[i++]);
            result.MonWndr    = Convert.ToInt32(v[i++]);
            result.MonSpcWalk = Convert.ToInt32(v[i++]);
            result.Mtot       = IntOrZero(v[i++]);
            result.Difficulties[eDifficulty.NORMAL].M1_25 = new string[25]; // NOTE: the game will accept up to 25,
            // but only the first 10 are present in the mpq provided table
            // TODO: add check to see if the other 11-25 are present instead of only taking the first 10
            for (int j = 0; j < 10; j++)
            {
                result.Difficulties[eDifficulty.NORMAL].M1_25[j] = v[i++];
            }

            result.RangedSpawnPreference = (v[i++] == "1");
            result.Difficulties[eDifficulty.NIGHTMARE].M1_25 = new string[25];
            result.Difficulties[eDifficulty.HELL].M1_25      = new string[25];
            // See above TODO
            for (int j = 0; j < 10; j++)
            {
                result.Difficulties[eDifficulty.NIGHTMARE].M1_25[j] = v[i]; // note: currently these are the same
                result.Difficulties[eDifficulty.HELL].M1_25[j]      = v[i++];
            }
            result.U1_25 = new string[25];
            // See above TODO
            for (int j = 0; j < 10; j++)
            {
                result.U1_25[j] = v[i++];
            }
            result.C1_4 = new string[4];
            for (int j = 0; j < 4; j++)
            {
                result.C1_4[j] = v[i++];
            }
            result.CA1_4 = new int[4];
            for (int j = 0; j < 4; j++)
            {
                result.CA1_4[j] = IntOrZero(v[i++]);
            }
            result.CD1_4 = new int[4];
            for (int j = 0; j < 4; j++)
            {
                result.CD1_4[j] = IntOrZero(v[i++]);
            }
            result.Themes    = Convert.ToInt32(v[i++]);
            result.SoundEnv  = Convert.ToInt32(v[i++]);
            result.Waypoint  = Convert.ToInt32(v[i++]);
            result.LevelName = v[i++];
            result.LevelWarp = v[i++];
            result.EntryFile = v[i++];
            result.ObjGrp0_7 = new int[8];
            for (int j = 0; j < 5; j++)
            {
                result.ObjGrp0_7[j] = Convert.ToInt32(v[i++]);
            }
            result.ObjPrb0_7 = new int[8];
            for (int j = 0; j < 5; j++)
            {
                result.ObjPrb0_7[j] = Convert.ToInt32(v[i++]);
            }
            result.Beta        = Convert.ToInt32(v[i]) == 1;
            result.LevelPreset = levelPresets.FirstOrDefault(x => x.LevelId == result.Id);
            result.LevelType   = levelTypes.FirstOrDefault(x => x.Id == result.LevelTypeId);
            return(result);
        }