byte Unk1; // Display text in the bottom of the main menu, or 0xff display message with a OK button and the blue backgroun (?) #endregion Fields #region Constructors /// <summary> /// /// </summary> /// <param name="script"></param> public MessageToken(Script script, Maze maze) : base(script) { MsgId = script.ReadByte(); Unk0 = script.ReadByte(); Color = script.ReadByte(); Unk1 = script.ReadByte(); Message = maze.GetString(MsgId); }
/// <summary> /// /// </summary> /// <param name="script"></param> public TextMenuToken(Script script, Maze maze) : base(script) { Type = script.ReadByte(); switch (Type) { // Display a picture from a CPS file case 0xd3: { PictureName = script.ReadString(13); // Name of the cps file X = script.ReadShort(); Y = script.ReadShort(); unk0 = script.ReadByte(); unk1 = script.ReadByte(); // Something to do with palette ?? unk2 = script.ReadByte(); } break; // Close Dialog case 0xd4: { } break; //Display background ? case 0xd5: { } break; // Fade in case 0xd6: { } break; // Button texts ? case 0xd8: { TextID = script.ReadAddr(); D8_Text = Assets.Text[TextID]; D8_Buttons[0] = script.ReadAddr(); D8_Buttons[1] = script.ReadAddr(); D8_Buttons[2] = script.ReadAddr(); D8_Strings[0] = maze.GetString(D8_Buttons[0]); D8_Strings[1] = maze.GetString(D8_Buttons[1]); D8_Strings[2] = maze.GetString(D8_Buttons[2]); } break; case 0xf8: { TextID = script.ReadAddr(); Y = script.ReadAddr(); //F8_Text = maze.GetString(TextID); //if (F8_Text == null) F8_Text= Assets.Text[TextID - 1]; F8_Button = maze.GetString(Y); } break; default: { } break; } }
/// <summary> /// /// </summary> /// <param name="filename"></param> public static Maze FromFile(byte id, string filename) { Maze maze = new Maze(id); byte b; ushort s; #region Loading INF file using (BinaryReader reader = new BinaryReader(File.Open(filename + ".inf", FileMode.Open))) { // Hunk1 offset maze.Hunks[1] = reader.ReadUInt16(); #region Sub level data for (byte sub = 0; sub < 2; sub++) { if (reader.BaseStream.Position < maze.Hunks[1]) { MazeHeader header = new MazeHeader(); // Chunk offsets header.NextHunk = reader.ReadUInt16(); b = reader.ReadByte(); if (b == 0xEC) { #region General informations header.MazeName = ReadString(reader, 13); header.VmpVcnName = ReadString(reader, 13); if (reader.ReadByte() != 0xFF) header.paletteName = ReadString(reader, 13); header.SoundName = ReadString(reader, 13); #endregion #region Door name & Positions + offset for (byte i = 0; i < 2; i++) { b = reader.ReadByte(); if (b == 0xEC || b == 0xEA) { DoorInfo door = new DoorInfo(); door.GfxName = ReadString(reader, 13); door.Id = reader.ReadByte(); door.Type = reader.ReadByte(); door.knob = reader.ReadByte(); for (byte t = 0; t < 3; t++) door.DoorRectangle[t] = new Rectangle(reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16()); for (byte t = 0; t < 2; t++) door.ButtonRectangles[t] = new Rectangle(reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16()); for (byte t = 0; t < 2; t++) door.ButtonPositions[t] = new Point(reader.ReadInt16(), reader.ReadInt16()); header.Doors[i] = door; } } #endregion // Max nomber of monster ?? s = reader.ReadUInt16(); #region Monsters graphics informations for (byte i = 0; i < 2; i++) { b = reader.ReadByte(); if (b == 0xEC) { MonsterGFX gfx = new MonsterGFX(); gfx.LoadProg = reader.ReadByte(); gfx.unk0 = reader.ReadByte(); gfx.Label = ReadString(reader, 13); gfx.unk1 = reader.ReadByte(); header.MonsterGFX[i] = gfx; } } #endregion #region Monster definitions while ((b = reader.ReadByte()) != 0xFF) { MonsterType m = new MonsterType(); m.index = b; m.unk0 = reader.ReadByte(); m.THAC0 = reader.ReadByte(); m.unk1 = reader.ReadByte(); m.HPDice.Rolls = reader.ReadByte(); m.HPDice.Sides = reader.ReadByte(); m.HPDice.Base = reader.ReadByte(); m.numberOfAttacks = reader.ReadByte(); for (byte i = 0; i < 3; i++) { m.AttackDice[i] = new Dice(reader); } m.specialAttackFlag = reader.ReadUInt16(); m.AbilitiesFlag = reader.ReadUInt16(); m.unk2 = reader.ReadUInt16(); m.EXPGain = reader.ReadUInt16(); m.size = reader.ReadByte(); m.attackSound = reader.ReadByte(); m.moveSound = reader.ReadByte(); m.unk3 = reader.ReadByte(); b = (byte)reader.ReadByte(); if (b != 0xff) { m.isAttack2 = true; m.distantAttack = reader.ReadByte(); m.maxAttackCount = reader.ReadByte(); for (byte i = 0; i < m.maxAttackCount; i++) { m.attackList[i] = reader.ReadByte(); reader.ReadByte(); // Pad ??? } } m.turnUndeadValue = reader.ReadByte(); m.unk4 = reader.ReadByte(); m.unk5[0] = reader.ReadByte(); m.unk5[1] = reader.ReadByte(); m.unk5[2] = reader.ReadByte(); header.MonsterTypes.Add(m); } #endregion #region Wall decoration data b = reader.ReadByte(); if (b != 0xFF) { ushort decorateblocks = reader.ReadUInt16(); for (ushort i = 0; i < decorateblocks; i++) { DecorationInfo deco = new DecorationInfo(); b = reader.ReadByte(); if (b == 0xEC) { deco.Files = new DecorationFileName(); deco.Files.GFXName = ReadString(reader, 13); deco.Files.DECName = ReadString(reader, 13); } else if (b == 0xFB) { deco.WallMappings = new WallMapping(); deco.WallMappings.index = reader.ReadByte(); deco.WallMappings.WallType = reader.ReadByte(); deco.WallMappings.DecorationID = reader.ReadByte(); deco.WallMappings.EventMask = reader.ReadByte(); deco.WallMappings.Flags = reader.ReadByte(); } header.Decorations.Add(deco); } } #endregion while (reader.ReadUInt32() != 0xFFFFFFFF) { } } maze.Headers[sub] = header; } } #endregion // Hunk2 offset maze.Hunks[2] = reader.ReadUInt16(); #region Monsters b = reader.ReadByte(); if (b != 0xff) { #region Monster timers while ((b = reader.ReadByte()) != 0xff) { maze.Timer.Add(reader.ReadByte()); } #endregion #region Monster descriptions for (byte i = 0; i < 30; i++) { Monster m = new Monster(); m.Index = reader.ReadByte(); m.TimerID = reader.ReadByte(); s = reader.ReadUInt16(); m.Location = Location.FromValue(s); // new Point(s >> 5, s & 0x1F); m.SubPosition = (BlockSubPosition)reader.ReadByte(); m.Direction = (Compass)reader.ReadByte(); m.Type = reader.ReadByte(); m.PictureIndex = reader.ReadByte(); m.Phase = reader.ReadByte(); m.Pause = reader.ReadByte(); m.Weapon = reader.ReadUInt16(); m.PocketItem = reader.ReadUInt16(); maze.Monsters.Add(m); } #endregion } #endregion #region Scripts s = reader.ReadUInt16(); // Script length maze.Script = new Script(maze, reader.ReadBytes(s - 2)); #endregion #region Messages while (reader.BaseStream.Position < maze.Hunks[2]) { string str = SearchString(reader); maze.Messages.Add(str); } #endregion #region Triggers ushort triggercount = reader.ReadUInt16(); for (ushort i = 0; i < triggercount; i++) { Trigger t = new Trigger(); s = reader.ReadUInt16(); t.Location = Location.FromValue(s); // new Point((byte)(s & 0x1f), (byte)((s >> 5) & 0x1f)); //t.Position = new Point((byte)((s >> 5) & 0x1f), (byte)(s & 0x1f)); //t.Position = new Point(s >> 5, s & 0x1F); t.Flags = (TriggerFlag)reader.ReadUInt16(); t.Offset = reader.ReadUInt16(); maze.Triggers.Add(t); } #endregion } #endregion #region Load .MAZ file if (File.Exists(filename + ".maz")) { using (BinaryReader reader = new BinaryReader(File.Open(filename + ".maz", FileMode.Open))) { maze.Size = new Size(reader.ReadUInt16(), reader.ReadUInt16()); maze.WallFaces = reader.ReadUInt16(); maze.Blocks = new MazeBlock[maze.Size.Width, maze.Size.Height]; for (byte y = 0; y < maze.Size.Height; y++) { for (byte x = 0; x < maze.Size.Width; x++) { maze.Blocks[x, y] = MazeBlock.FromFile(reader); } } } } #endregion return maze; }
/// <summary> /// /// </summary> public Script(Maze maze, byte[] bytecode) { Maze = maze; ByteCode = bytecode; Tokens = new List<ScriptToken>(); }