Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
 public PlusPropertyList?ShowForm(ref PlusPropertyList current)
 {
     propertyGrid1.SelectedObject = new PlusPropertyList(current);
     ShowDialog();
     return(result);
 }