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