public static MapNpc Load(BinaryReader br) { var npc = new MapNpc(); npc.Id = (NpcCharacterId)br.ReadByte(); // +0 npc.Sound = br.ReadByte(); // +1 npc.EventNumber = br.ReadUInt16(); // +2 if (npc.EventNumber == 0xffff) { npc.EventNumber = null; } npc.ObjectNumber = FormatUtil.Tweak(br.ReadUInt16()) ?? 0; // +4 npc.Flags = (NpcFlags)br.ReadByte(); // +6 // Combine this & MovementType ? npc.Movement = (MovementType)br.ReadByte(); // +7 npc.Unk8 = br.ReadByte(); // +8 npc.Unk9 = br.ReadByte(); // +9 return(npc); }
public static MapData2D Load(BinaryReader br, long streamLength, string name) { var startPosition = br.BaseStream.Position; var map = new MapData2D(); map.Unk0 = br.ReadByte(); // 0 int npcCount = br.ReadByte(); // 1 if (npcCount == 0) { npcCount = 0x20; } else if (npcCount == 0x40) { npcCount = 0x60; } var mapType = br.ReadByte(); // 2 Debug.Assert(2 == mapType); // 1 = 3D, 2 = 2D map.Sound = br.ReadByte(); //3 map.Width = br.ReadByte(); //4 map.Height = br.ReadByte(); //5 map.TilesetId = FormatUtil.Tweak(br.ReadByte()) ?? throw new FormatException("Invalid tile-set id encountered"); //6 map.CombatBackgroundId = br.ReadByte(); //7 map.PaletteId = FormatUtil.Tweak(br.ReadByte()) ?? throw new FormatException("Invalid palette id encountered"); //8 map.FrameRate = br.ReadByte(); //9 for (int i = 0; i < npcCount; i++) { var npc = MapNpc.Load(br); if (npc.Id == 0) { continue; } map.Npcs.Add(npc); } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); map.Underlay = new int[map.Width * map.Height]; map.Overlay = new int[map.Width * map.Height]; for (int i = 0; i < map.Width * map.Height; i++) { byte b1 = br.ReadByte(); byte b2 = br.ReadByte(); byte b3 = br.ReadByte(); int overlay = (b1 << 4) + (b2 >> 4) - 2; int underlay = ((b2 & 0x0F) << 8) + b3 - 2; map.Overlay[i] = overlay; map.Underlay[i] = underlay; } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); int zoneCount = br.ReadUInt16(); for (int i = 0; i < zoneCount; i++) { map.Zones.Add(MapEventZone.LoadGlobalZone(br)); } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); for (int j = 0; j < map.Height; j++) { zoneCount = br.ReadUInt16(); for (int i = 0; i < zoneCount; i++) { map.Zones.Add(MapEventZone.LoadZone(br, (ushort)j)); } } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); int eventCount = br.ReadUInt16(); for (int i = 0; i < eventCount; i++) { map.Events.Add(EventNode.Load(br, i)); } foreach (var mapEvent in map.Events.OfType <EventNode>()) { if (mapEvent.NextEventId.HasValue) { mapEvent.NextEvent = map.Events[mapEvent.NextEventId.Value]; } if (mapEvent is BranchNode q && q.NextEventWhenFalseId.HasValue) { q.NextEventWhenFalse = map.Events[q.NextEventWhenFalseId.Value]; } } foreach (var zone in map.Zones) { if (zone.EventNumber != 65535) { zone.Event = map.Events[zone.EventNumber]; } } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); foreach (var npc in map.Npcs) { npc.LoadWaypoints(br); } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); map.ZoneLookup = Enumerable.Repeat(-1, map.Width * map.Height).ToArray(); for (int i = 0; i < map.Zones.Count; i++) { var z = map.Zones[i]; map.ZoneLookup[z.Y * map.Width + z.X] = i; } return(map); }
public static MapData3D Load(BinaryReader br, long streamLength, string name) { var startPosition = br.BaseStream.Position; var map = new MapData3D(); map.CeilingFlags = br.ReadByte(); // 0 int npcCount = br.ReadByte(); // 1 if (npcCount == 0) { npcCount = 0x20; } else if (npcCount == 0x40) { npcCount = 0x60; } var mapType = br.ReadByte(); // 2 Debug.Assert(1 == mapType); // 1 = 3D, 2 = 2D map.SongId = (SongId)br.ReadByte() - 1; // 3 map.Width = br.ReadByte(); // 4 map.Height = br.ReadByte(); // 5 byte labData = br.ReadByte(); // 6 map.LabDataId = (LabyrinthDataId)labData; map.Unk7 = br.ReadByte(); // 7 Possibly combat background?? map.PaletteId = (PaletteId)br.ReadByte() - 1; // 8 map.Sound = br.ReadByte() - 1; // 9 for (int i = 0; i < npcCount; i++) { var npc = MapNpc.Load(br); if (npc.Id == 0) { continue; } map.Npcs.Add(npc); } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); map.Contents = new int[map.Width * map.Height]; map.Floors = new int[map.Width * map.Height]; map.Ceilings = new int[map.Width * map.Height]; for (int i = 0; i < map.Width * map.Height; i++) { map.Contents[i] = br.ReadByte(); map.Floors[i] = br.ReadByte(); map.Ceilings[i] = br.ReadByte(); } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); int zoneCount = br.ReadUInt16(); for (int i = 0; i < zoneCount; i++) { map.Zones.Add(MapEventZone.LoadGlobalZone(br)); } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); for (int j = 0; j < map.Height; j++) { zoneCount = br.ReadUInt16(); for (int i = 0; i < zoneCount; i++) { map.Zones.Add(MapEventZone.LoadZone(br, (ushort)j)); } } if (br.BaseStream.Position == startPosition + streamLength) { Debug.Assert(map.Zones.Count == 0); return(map); } int eventCount = br.ReadUInt16(); for (int i = 0; i < eventCount; i++) { map.Events.Add(EventNode.Load(br, i)); } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); foreach (var npc in map.Npcs) { npc.LoadWaypoints(br); } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); int automapInfoCount = br.ReadUInt16(); if (automapInfoCount != 0xffff) { for (int i = 0; i < automapInfoCount; i++) { map.Automap.Add(AutomapInfo.Load(br)); } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); } map.AutomapGraphics = br.ReadBytes(0x40); for (int i = 0; i < 64; i++) { var eventId = br.ReadUInt16(); if (eventId == 0xffff) { continue; } map.ActiveMapEvents.Add(eventId); } Debug.Assert(br.BaseStream.Position <= startPosition + streamLength); return(map); }