internal bool LevelIsReadable(byte[] Data5, List <J2TFile> Tilesets, List <Layer> Layers, string Filepath) { if (Data5 == null || Data5.Length < 20) //level stops at the end of data4, as is good and proper { this = new PlusPropertyList(null); return(true); } using (BinaryReader data5reader = new BinaryReader(new MemoryStream(Data5), J2LFile.FileEncoding)) { if (new string(data5reader.ReadChars(4)) != MLLEData5MagicString) { return(false); } uint data5Version = data5reader.ReadUInt32(); if (data5Version > CurrentMLLEData5Version) { return(false); } //should be okay to read at this point this = new PlusPropertyList(null); uint csize = data5reader.ReadUInt32(); uint usize = data5reader.ReadUInt32(); using (BinaryReader data5bodyreader = new BinaryReader(new MemoryStream(ZlibStream.UncompressBuffer(data5reader.ReadBytes((int)csize))))) { IsSnowing = data5bodyreader.ReadBoolean(); IsSnowingOutdoorsOnly = data5bodyreader.ReadBoolean(); SnowingIntensity = data5bodyreader.ReadByte(); SnowingType = (SnowTypeEnum)data5bodyreader.ReadByte(); WarpsTransmuteCoins = data5bodyreader.ReadBoolean(); DelayGeneratedCrateOrigins = data5bodyreader.ReadBoolean(); Echo = data5bodyreader.ReadInt32(); DarknessColor = Color.FromArgb(data5bodyreader.ReadInt32()); WaterChangeSpeed = data5bodyreader.ReadSingle(); WaterInteraction = (WaterInteractionEnum)data5bodyreader.ReadByte(); WaterLayer = data5bodyreader.ReadInt32(); WaterLighting = (WaterLightingEnum)data5bodyreader.ReadByte(); WaterLevel = data5bodyreader.ReadSingle(); WaterGradientStart = Color.FromArgb(data5bodyreader.ReadInt32()); WaterGradientStop = Color.FromArgb(data5bodyreader.ReadInt32()); if (data5bodyreader.ReadBoolean()) { Palette = new Palette(data5bodyreader, true); } for (int i = 0; i < Mainframe.RecolorableSpriteNames.Length; ++i) { if ((i < 11 || data5Version >= 0x105) && data5bodyreader.ReadBoolean()) //the recolorable sprite list was expanded in MLLE-Include-1.5 { ColorRemappings[i] = new byte[Palette.PaletteSize]; for (uint j = 0; j < Palette.PaletteSize; ++j) { ColorRemappings[i][j] = data5bodyreader.ReadByte(); } } else { ColorRemappings[i] = null; } } var extraTilesetCount = data5bodyreader.ReadByte(); for (uint tilesetID = 0; tilesetID < extraTilesetCount; ++tilesetID) { var tilesetFilepath = Path.Combine(Path.GetDirectoryName(Filepath), data5bodyreader.ReadString()); if (File.Exists(tilesetFilepath)) { var tileset = new J2TFile(tilesetFilepath); tileset.FirstTile = data5bodyreader.ReadUInt16(); tileset.TileCount = data5bodyreader.ReadUInt16(); if (data5bodyreader.ReadBoolean()) { tileset.ColorRemapping = new byte[Palette.PaletteSize]; for (uint i = 0; i < Palette.PaletteSize; ++i) { tileset.ColorRemapping[i] = data5bodyreader.ReadByte(); } } Tilesets.Add(tileset); } else { this = new PlusPropertyList(null); MessageBox.Show("Additional tileset \"" + tilesetFilepath + "\" not found; MLLE will stop trying to read this Data5 section.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); return(false); } } if (data5Version >= 0x102) //layers were added in MLLE-Include-1.2 { var defaultLayers = Layers.ToArray(); Layers.Clear(); int layerCount = (int)data5bodyreader.ReadUInt32(); List <Layer> nonDefaultLayers = new List <Layer>(); for (int i = 8; i < layerCount; i += 8) { J2LFile extraLevel = new J2LFile(); string levelFilePath = GetExtraDataLevelFilepath(Filepath, i / 8 - 1); if (File.Exists(levelFilePath)) { extraLevel.OpenLevel(levelFilePath, ref Data5, SecurityStringOverride: J2LFile.SecurityStringExtraDataNotForDirectEditing); nonDefaultLayers.AddRange(extraLevel.DefaultLayers); } else { this = new PlusPropertyList(null); MessageBox.Show("Additional file \"" + levelFilePath + "\" not found; MLLE will stop trying to read this Data5 section.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); return(false); } } int nextNonDefaultLayerID = 0; for (uint i = 0; i < layerCount; ++i) { sbyte layerID = data5bodyreader.ReadSByte(); Layer layer; if (layerID >= 0) { layer = defaultLayers[layerID]; } else { layer = nonDefaultLayers[nextNonDefaultLayerID++]; layer.id = -1; } layer.Name = data5bodyreader.ReadString(); layer.Hidden = data5bodyreader.ReadBoolean(); layer.SpriteMode = data5bodyreader.ReadByte(); layer.SpriteParam = data5bodyreader.ReadByte(); layer.RotationAngle = data5bodyreader.ReadInt32(); layer.RotationRadiusMultiplier = data5bodyreader.ReadInt32(); Layers.Add(layer); } if (data5Version >= 0x103) //edited tiles were added in MLLE-Include-1.3 { int levelTileCount = Tilesets.Sum(ts => (int)ts.TileCount); foreach (byte[][] images in new byte[][][] { TileImages, TileMasks }) { int numberOfImages = data5bodyreader.ReadUInt16(); for (int i = 0; i < numberOfImages; ++i) { int tileID = data5bodyreader.ReadUInt16(); images[tileID] = data5bodyreader.ReadBytes(32 * 32); } } if (data5Version >= 0x105) //weapons were added in MLLE-Include-1.5(w) { for (int weaponID = 0; weaponID < 9; ++weaponID) { bool customWeapon = data5bodyreader.ReadBoolean(); Weapon weapon = Weapons[weaponID]; weapon.Options[0] = data5bodyreader.ReadInt32(); //maximum for (int optionID = 1; optionID < Weapon.NumberOfCommonOptions; ++optionID) { weapon.Options[optionID] = data5bodyreader.ReadByte(); //birds and crates and gems and replenishment } if (weaponID == 6) { Gun7Crate = data5bodyreader.ReadByte(); } else if (weaponID == 7) { Gun8Crate = data5bodyreader.ReadByte(); } else if (weaponID == 8) { Gun9Crate = data5bodyreader.ReadByte(); } if (customWeapon) { string name = data5bodyreader.ReadString(); var extendedWeapon = WeaponsForm.GetAllAvailableWeapons().Find(w => w.Name == name); if (extendedWeapon == null) { MessageBox.Show(String.Format("Sorry, the MLLE \"Weapons\" folder did not include any .ini file defining a weapon with the name \"{0}.\"", name), "Weapon not found", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } Weapons[weaponID].Name = name; Array.Resize(ref Weapons[weaponID].Options, extendedWeapon.Options.Length); data5bodyreader.ReadInt32(); //length of jjSTREAM for (int optionID = Weapon.NumberOfCommonOptions; optionID < weapon.Options.Length; ++optionID) { switch (extendedWeapon.OptionTypes[optionID]) { case WeaponsForm.ExtendedWeapon.oTypes.Bool: case WeaponsForm.ExtendedWeapon.oTypes.Dropdown: weapon.Options[optionID] = data5bodyreader.ReadByte(); break; case WeaponsForm.ExtendedWeapon.oTypes.Int: weapon.Options[optionID] = data5bodyreader.ReadInt32(); break; } } } else if (weaponID == 7) { weapon.Options[Weapon.NumberOfCommonOptions] = data5bodyreader.ReadByte(); //Gun8 style } } } } } } } return(true); }
private bool ApplyChanges() { newrectangle = null; lock (DataSource) { if (DataSource.Width != WidthBox.Value || DataSource.Height != HeightBox.Value) { newrectangle = LayerAlign.Show(CurrentLayer, (int)WidthBox.Value - (int)DataSource.Width, (int)HeightBox.Value - (int)DataSource.Height); if (newrectangle == null) { return(false); } SourceForm.Undoable = new Stack <MLLE.Mainframe.LayerAndSpecificTiles>(SourceForm.Undoable.Where(action => action.Layer != DataSource)); SourceForm.Redoable = new Stack <MLLE.Mainframe.LayerAndSpecificTiles>(SourceForm.Redoable.Where(action => action.Layer != DataSource)); } DataSource.Width = (uint)WidthBox.Value; DataSource.Height = (uint)HeightBox.Value; if (TileWidth.Checked) { switch (DataSource.Width % 4) { case 0: DataSource.RealWidth = DataSource.Width; break; case 2: DataSource.RealWidth = DataSource.Width * 2; break; default: DataSource.RealWidth = DataSource.Width * 4; break; } } else { DataSource.RealWidth = DataSource.Width; } if (newrectangle != null) { ArrayMap <ushort> newTileMap = new ArrayMap <ushort>(DataSource.Width, DataSource.Height); for (ushort x = 0; x < DataSource.Width; x++) { for (ushort y = 0; y < DataSource.Height; y++) { newTileMap[x, y] = ( x >= -newrectangle[2] && newrectangle[2] + x < DataSource.TileMap.GetLength(0) && y >= -newrectangle[0] && newrectangle[0] + y < DataSource.TileMap.GetLength(1) ) ? DataSource.TileMap[newrectangle[2] + x, newrectangle[0] + y] : (ushort)0; } } if (DataSource.id == J2LFile.SpriteLayerID) //sprite layer, i.e. events are associated with this one { if (SourceForm.J2L.VersionType == Version.AGA) { AGAEvent[,] newAGAMap = new AGAEvent[DataSource.Width, DataSource.Height]; for (ushort x = 0; x < DataSource.Width; x++) { for (ushort y = 0; y < DataSource.Height; y++) { newAGAMap[x, y] = ( x >= -newrectangle[2] && newrectangle[2] + x < DataSource.TileMap.GetLength(0) && y >= -newrectangle[0] && newrectangle[0] + y < DataSource.TileMap.GetLength(1) ) ? SourceForm.J2L.AGA_EventMap[newrectangle[2] + x, newrectangle[0] + y] : new AGAEvent(); } } SourceForm.J2L.AGA_EventMap = newAGAMap; } else { var oldEventMap = SourceForm.J2L.EventMap; uint[,] newEventMap = new uint[DataSource.Width, DataSource.Height]; PlusPropertyList rememberPlusEventBasedSettings = new PlusPropertyList(null); rememberPlusEventBasedSettings.ReadFromEventMap(oldEventMap); rememberPlusEventBasedSettings.WriteToEventMap(newEventMap); int oldEventMapRightColumn = oldEventMap.GetLength(0) - 1; int oldEventMapBottomRow = oldEventMap.GetLength(1) - 1; for (ushort x = 0; x < DataSource.Width; x++) { for (ushort y = 0; y < DataSource.Height - 1; y++) //-1 because events in the bottom row don't work, except for a few events parsed by JJ2+ that were handled above { newEventMap[x, y] = ( x >= -newrectangle[2] && newrectangle[2] + x <= oldEventMapRightColumn && y >= -newrectangle[0] && newrectangle[0] + y < oldEventMapBottomRow ) ? oldEventMap[newrectangle[2] + x, newrectangle[0] + y] : (ushort)0; } } SourceForm.J2L.EventMap = newEventMap; } } DataSource.TileMap = newTileMap; } DataSource.TileWidth = TileWidth.Checked; DataSource.TileHeight = TileHeight.Checked; Single.TryParse(XSpeed.Text, out DataSource.XSpeed); Single.TryParse(YSpeed.Text, out DataSource.YSpeed); Single.TryParse(AutoXSpeed.Text, out DataSource.AutoXSpeed); Single.TryParse(AutoYSpeed.Text, out DataSource.AutoYSpeed); Single.TryParse(XOffset.Text, out DataSource.WaveX); Single.TryParse(YOffset.Text, out DataSource.WaveY); DataSource.LimitVisibleRegion = LimitVisibleRegion.Checked; DataSource.IsTextured = TextureMode.Checked; DataSource.HasStars = Stars.Checked; DataSource.TexturParam1 = (byte)Param1.Value; DataSource.TexturParam2 = (byte)Param2.Value; DataSource.TexturParam3 = (byte)Param3.Value; DataSource.TextureMode = (byte)TextureModeSelect.SelectedIndex; DataSource.Name = NameBox.Text; DataSource.Hidden = Hidden.Checked; DataSource.SpriteMode = (byte)SpriteMode.SelectedIndex; DataSource.SpriteParam = (byte)SpriteParam.Value; DataSource.RotationAngle = (int)RotationAngle.Value; DataSource.RotationRadiusMultiplier = (int)RotationRadiusMultiplier.Value; SourceForm.LevelHasBeenModified = true; } return(true); }
public PlusPropertyList?ShowForm(ref PlusPropertyList current) { propertyGrid1.SelectedObject = new PlusPropertyList(current); ShowDialog(); return(result); }