diff --git a/ItemEditor.sln b/ItemEditor.sln
index 12d7033..01890ab 100644
--- a/ItemEditor.sln
+++ b/ItemEditor.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29806.167
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ItemEditor", "Source\ItemEditor.csproj", "{9A90BE1A-4A8F-4BFE-92E7-2C0EF64D850C}"
ProjectSection(ProjectDependencies) = postProject
@@ -16,6 +16,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginTwo", "Source\PluginT
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginInterface", "Source\PluginInterface\PluginInterface.csproj", "{CEF21172-258C-4D0D-B024-ED7EF99612A2}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginFour", "Source\PluginFour\PluginFour.csproj", "{8DE984FF-979E-4F90-AD69-D44AD944F70C}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -86,8 +88,23 @@ Global
{CEF21172-258C-4D0D-B024-ED7EF99612A2}.Release|x64.Build.0 = Release|x64
{CEF21172-258C-4D0D-B024-ED7EF99612A2}.Release|x86.ActiveCfg = Release|x86
{CEF21172-258C-4D0D-B024-ED7EF99612A2}.Release|x86.Build.0 = Release|x86
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}.Debug|x64.ActiveCfg = Debug|x64
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}.Debug|x64.Build.0 = Debug|x64
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}.Debug|x86.ActiveCfg = Debug|x86
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}.Debug|x86.Build.0 = Debug|x86
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}.Release|x64.ActiveCfg = Release|x64
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}.Release|x64.Build.0 = Release|x64
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}.Release|x86.ActiveCfg = Release|x86
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {727FCD4C-59DD-4C4B-85EC-FE0D0C50DE54}
+ EndGlobalSection
EndGlobal
diff --git a/Source/Dialogs/NewOtbFileForm.cs b/Source/Dialogs/NewOtbFileForm.cs
index 5c2664c..860111b 100644
--- a/Source/Dialogs/NewOtbFileForm.cs
+++ b/Source/Dialogs/NewOtbFileForm.cs
@@ -1,4 +1,4 @@
-#region Licence
+#region Licence
/**
* Copyright © 2014-2019 OTTools
*
diff --git a/Source/Host/PluginServices.cs b/Source/Host/PluginServices.cs
index 6aae97d..9438319 100644
--- a/Source/Host/PluginServices.cs
+++ b/Source/Host/PluginServices.cs
@@ -1,4 +1,4 @@
-#region Licence
+#region Licence
/**
* Copyright © 2014-2019 OTTools
*
diff --git a/Source/PluginFour/Plugin.cs b/Source/PluginFour/Plugin.cs
new file mode 100644
index 0000000..f723c9c
--- /dev/null
+++ b/Source/PluginFour/Plugin.cs
@@ -0,0 +1,396 @@
+#region Licence
+/**
+* Copyright © 2014-2019 OTTools
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program; if not, write to the Free Software Foundation, Inc.,
+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#endregion
+
+#region Using Statements
+using ItemEditor;
+using OTLib.Server.Items;
+using PluginInterface;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+#endregion
+
+namespace PluginFour
+{
+ internal enum ItemFlag : byte
+ {
+ Ground = 0x00,
+ GroundBorder = 0x01,
+ OnBottom = 0x02,
+ OnTop = 0x03,
+ Container = 0x04,
+ Stackable = 0x05,
+ ForceUse = 0x06,
+ MultiUse = 0x07,
+ Writable = 0x08,
+ Readable = 0x09,
+ FluidContainer = 0x0A,
+ Fluid = 0x0B,
+ IsUnpassable = 0x0C,
+ IsUnmoveable = 0x0D,
+ BlockMissiles = 0x0E,
+ BlockPathfinder = 0x0F,
+ Pickupable = 0x10,
+ Hangable = 0x11,
+ IsVertical = 0x12,
+ IsHorizontal = 0x13,
+ Rotatable = 0x14,
+ HasLight = 0x15,
+ DontHide = 0x16,
+ Translucent = 0x17,
+ HasOffset = 0x18,
+ HasElevation = 0x19,
+ Lying = 0x1A,
+ AnimateAlways = 0x1B,
+ Minimap = 0x1C,
+ Actions = 0x1D,
+ FullGround = 0x1E,
+
+ LastFlag = 0xFF
+ }
+
+ public class Plugin : IPlugin
+ {
+ #region Private Properties
+
+ private Dictionary sprites;
+ private ushort itemCount;
+
+ #endregion
+
+ #region Constructor
+
+ public Plugin()
+ {
+ this.Settings = new Settings();
+ this.sprites = new Dictionary();
+ this.Items = new ClientItems();
+ this.SupportedClients = new List();
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ // internal implementation
+ public Settings Settings { get; private set;}
+
+ // IPlugin implementation
+ public IPluginHost Host { get; set; }
+
+ public List SupportedClients { get; private set; }
+
+ public ClientItems Items { get; set; }
+
+ public ushort MinItemId { get { return 100; } }
+
+ public ushort MaxItemId { get { return this.itemCount; } }
+
+ public bool Loaded { get; private set; }
+
+ #endregion
+
+ #region Public Methods
+
+ public bool LoadClient(SupportedClient client, bool extended, bool frameDurations, bool transparency, string datFullPath, string sprFullPath)
+ {
+ if (this.Loaded)
+ {
+ this.Dispose();
+ }
+
+ if (!LoadDat(datFullPath, client, extended, frameDurations))
+ {
+ Trace.WriteLine("Failed to load dat.");
+ return false;
+ }
+
+ if (!LoadSprites(sprFullPath, client, extended, transparency))
+ {
+ Trace.WriteLine("Failed to load spr.");
+ return false;
+ }
+
+ this.Loaded = true;
+ return true;
+ }
+
+ public void Initialize()
+ {
+ this.Settings.Load("PluginFour.xml");
+ this.SupportedClients = Settings.GetSupportedClientList();
+ }
+
+ public SupportedClient GetClientBySignatures(uint datSignature, uint sprSignature)
+ {
+ foreach (SupportedClient client in this.SupportedClients)
+ {
+ if (client.DatSignature == datSignature && client.SprSignature == sprSignature)
+ {
+ return client;
+ }
+ }
+
+ return null;
+ }
+
+ public ClientItem GetClientItem(ushort id)
+ {
+ if (this.Loaded && id >= 100 && id <= this.itemCount)
+ {
+ return this.Items[id];
+ }
+
+ return null;
+ }
+
+ public void Dispose()
+ {
+ if (this.Loaded)
+ {
+ this.sprites.Clear();
+ this.Items.Clear();
+ this.itemCount = 0;
+ this.Loaded = false;
+ }
+ }
+
+ public bool LoadSprites(string filename, SupportedClient client, bool extended, bool transparency)
+ {
+ return Sprite.LoadSprites(filename, ref sprites, client, extended, transparency);
+ }
+
+ public bool LoadDat(string filename, SupportedClient client, bool extended, bool frameDurations)
+ {
+ using (FileStream fileStream = new FileStream(filename, FileMode.Open))
+ {
+ BinaryReader reader = new BinaryReader(fileStream);
+
+ uint datSignature = reader.ReadUInt32();
+ if (client.DatSignature != datSignature)
+ {
+ string message = "PluginFour: Bad dat signature. Expected signature is {0:X} and loaded signature is {1:X}.";
+ Trace.WriteLine(string.Format(message, client.DatSignature, datSignature));
+ return false;
+ }
+
+ // get max id
+ this.itemCount = reader.ReadUInt16();
+ reader.ReadUInt16(); // skipping outfits count
+ reader.ReadUInt16(); // skipping effects count
+ reader.ReadUInt16(); // skipping missiles count
+
+ ushort id = 100;
+ while (id <= this.itemCount)
+ {
+ ClientItem item = new ClientItem();
+ item.ID = id;
+ this.Items[id] = item;
+
+ // read the options until we find 0xff
+ ItemFlag flag;
+ do
+ {
+ flag = (ItemFlag)reader.ReadByte();
+
+ switch (flag)
+ {
+ case ItemFlag.Ground:
+ item.Type = ServerItemType.Ground;
+ item.GroundSpeed = reader.ReadUInt16();
+ break;
+
+ case ItemFlag.GroundBorder:
+ item.HasStackOrder = true;
+ item.StackOrder = TileStackOrder.Border;
+ break;
+
+ case ItemFlag.OnBottom:
+ item.HasStackOrder = true;
+ item.StackOrder = TileStackOrder.Bottom;
+ break;
+
+ case ItemFlag.OnTop:
+ item.HasStackOrder = true;
+ item.StackOrder = TileStackOrder.Top;
+ break;
+
+ case ItemFlag.Container:
+ item.Type = ServerItemType.Container;
+ break;
+
+ case ItemFlag.Stackable:
+ item.Stackable = true;
+ break;
+
+ case ItemFlag.ForceUse:
+ item.ForceUse = true;
+ break;
+
+ case ItemFlag.MultiUse:
+ item.MultiUse = true;
+ break;
+
+ case ItemFlag.Writable:
+ item.Readable = true;
+ item.MaxReadWriteChars = reader.ReadUInt16();
+ break;
+
+ case ItemFlag.Readable:
+ item.Readable = true;
+ item.MaxReadChars = reader.ReadUInt16();
+ break;
+
+ case ItemFlag.FluidContainer:
+ item.Type = ServerItemType.Fluid;
+ break;
+
+ case ItemFlag.Fluid:
+ item.Type = ServerItemType.Splash;
+ break;
+
+ case ItemFlag.IsUnpassable:
+ item.Unpassable = true;
+ break;
+
+ case ItemFlag.IsUnmoveable:
+ item.Movable = false;
+ break;
+
+ case ItemFlag.BlockMissiles:
+ item.BlockMissiles = true;
+ break;
+
+ case ItemFlag.BlockPathfinder:
+ item.BlockPathfinder = true;
+ break;
+
+ case ItemFlag.Pickupable:
+ item.Pickupable = true;
+ break;
+
+ case ItemFlag.Hangable:
+ item.Hangable = true;
+ break;
+
+ case ItemFlag.IsHorizontal:
+ item.HookEast = true;
+ break;
+
+ case ItemFlag.IsVertical:
+ item.HookSouth = true;
+ break;
+
+ case ItemFlag.Rotatable:
+ item.Rotatable = true;
+ break;
+
+ case ItemFlag.HasLight:
+ item.LightLevel = reader.ReadUInt16();
+ item.LightColor = reader.ReadUInt16();
+ break;
+
+ case ItemFlag.DontHide:
+ break;
+
+ case ItemFlag.Translucent:
+ break;
+
+ case ItemFlag.HasOffset:
+ reader.ReadUInt16(); // OffsetX
+ reader.ReadUInt16(); // OffsetY
+ break;
+
+ case ItemFlag.HasElevation:
+ item.HasElevation = true;
+ reader.ReadUInt16(); // Height
+ break;
+
+ case ItemFlag.Lying:
+ break;
+
+ case ItemFlag.AnimateAlways:
+ break;
+
+ case ItemFlag.Minimap:
+ item.MinimapColor = reader.ReadUInt16();
+ break;
+
+ case ItemFlag.Actions: // actions
+ reader.ReadUInt16();
+ break;
+
+ case ItemFlag.FullGround:
+ item.FullGround = true;
+ break;
+
+ case ItemFlag.LastFlag:
+ break;
+
+ default:
+ Trace.WriteLine(string.Format("PluginFour: Error while parsing, unknown flag 0x{0:X} at id {1}.", flag, id));
+ return false;
+ }
+
+ } while (flag != ItemFlag.LastFlag);
+
+ item.Width = reader.ReadByte();
+ item.Height = reader.ReadByte();
+
+ if (item.Width > 1 || item.Height > 1)
+ {
+ // Skipping exact size.
+ reader.ReadByte();
+ }
+
+ item.Layers = reader.ReadByte();
+ item.PatternX = reader.ReadByte();
+ item.PatternY = reader.ReadByte();
+ item.PatternZ = reader.ReadByte();
+ item.Frames = reader.ReadByte();
+
+ item.NumSprites = (uint)(item.Width * item.Height * item.Layers * item.PatternX * item.PatternY * item.PatternZ * item.Frames);
+ // Read the sprite ids
+ for (uint i = 0; i < item.NumSprites; ++i)
+ {
+ uint spriteId = reader.ReadUInt16();
+ Sprite sprite;
+ if (!sprites.TryGetValue(spriteId, out sprite))
+ {
+ sprite = new Sprite();
+ sprite.ID = spriteId;
+ sprites[spriteId] = sprite;
+ }
+
+ item.SpriteList.Add(sprite);
+ }
+
+ ++id;
+ }
+ }
+
+ return true;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/PluginFour/PluginFour.csproj b/Source/PluginFour/PluginFour.csproj
new file mode 100644
index 0000000..be1deab
--- /dev/null
+++ b/Source/PluginFour/PluginFour.csproj
@@ -0,0 +1,95 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {8DE984FF-979E-4F90-AD69-D44AD944F70C}
+ Library
+ Properties
+ PluginFour
+ PluginFour
+ v4.5.2
+ 512
+
+
+
+ true
+ full
+ false
+ ..\bin\Debug\Plugins\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+
+
+ pdbonly
+ true
+ ..\bin\Release\Plugins\
+ TRACE
+ prompt
+ 4
+ AnyCPU
+ false
+
+
+ x86
+ ..\bin\x86\Debug\Plugins\
+ TRACE;DEBUG
+ false
+
+
+ x86
+ ..\bin\x86\Release\Plugins\
+ true
+ TRACE
+ false
+
+
+ true
+ ..\bin\x64\Debug\Plugins\
+ x64
+ MinimumRecommendedRules.ruleset
+ DEBUG;TRACE
+ false
+
+
+ ..\bin\x64\Release\Plugins\
+ true
+ x64
+ MinimumRecommendedRules.ruleset
+ TRACE
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {cef21172-258c-4d0d-b024-ed7ef99612a2}
+ PluginInterface
+ False
+
+
+
+
+ PreserveNewest
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/PluginFour/PluginFour.sln b/Source/PluginFour/PluginFour.sln
new file mode 100644
index 0000000..20d5580
--- /dev/null
+++ b/Source/PluginFour/PluginFour.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.902
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginFour", "PluginFour.vcxproj", "{B3949100-6235-43D4-BBE6-C759D186A6E4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B3949100-6235-43D4-BBE6-C759D186A6E4}.Debug|x64.ActiveCfg = Debug|x64
+ {B3949100-6235-43D4-BBE6-C759D186A6E4}.Debug|x64.Build.0 = Debug|x64
+ {B3949100-6235-43D4-BBE6-C759D186A6E4}.Debug|x86.ActiveCfg = Debug|Win32
+ {B3949100-6235-43D4-BBE6-C759D186A6E4}.Debug|x86.Build.0 = Debug|Win32
+ {B3949100-6235-43D4-BBE6-C759D186A6E4}.Release|x64.ActiveCfg = Release|x64
+ {B3949100-6235-43D4-BBE6-C759D186A6E4}.Release|x64.Build.0 = Release|x64
+ {B3949100-6235-43D4-BBE6-C759D186A6E4}.Release|x86.ActiveCfg = Release|Win32
+ {B3949100-6235-43D4-BBE6-C759D186A6E4}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {18F83782-7DD9-4291-8A17-A60753BA55A3}
+ EndGlobalSection
+EndGlobal
diff --git a/Source/PluginFour/PluginFour.vcxproj b/Source/PluginFour/PluginFour.vcxproj
new file mode 100644
index 0000000..0fc7796
--- /dev/null
+++ b/Source/PluginFour/PluginFour.vcxproj
@@ -0,0 +1,105 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 15.0
+ {B3949100-6235-43D4-BBE6-C759D186A6E4}
+ Win32Proj
+
+
+
+ Application
+ true
+ v141
+
+
+ Application
+ false
+ v141
+
+
+ Application
+ true
+ v141
+
+
+ Application
+ false
+ v141
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+
+ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreadedDebugDLL
+ Level3
+ ProgramDatabase
+ Disabled
+
+
+ MachineX86
+ true
+ Windows
+
+
+
+
+ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+ Level3
+ ProgramDatabase
+
+
+ MachineX86
+ true
+ Windows
+ true
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/PluginFour/PluginFour.xml b/Source/PluginFour/PluginFour.xml
new file mode 100644
index 0000000..4362afb
--- /dev/null
+++ b/Source/PluginFour/PluginFour.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Source/PluginFour/Properties/AssemblyInfo.cs b/Source/PluginFour/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..554b629
--- /dev/null
+++ b/Source/PluginFour/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ItemEditor Plugin Four")]
+[assembly: AssemblyDescription("ItemEditor Plugin.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Plugin Four")]
+[assembly: AssemblyCopyright("Copyright © 2014-2019 OTTools")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("26026a2e-35f1-4373-8fd3-557f971ba43b")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("0.4.3.0")]
+[assembly: AssemblyFileVersion("0.4.3.0")]
diff --git a/Source/PluginFour/Settings.StyleCop b/Source/PluginFour/Settings.StyleCop
new file mode 100644
index 0000000..dcc44e5
--- /dev/null
+++ b/Source/PluginFour/Settings.StyleCop
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+ False
+
+
+
+
+
+
+
\ No newline at end of file