diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCMap.uexml b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCMap.uexml
index bbaff359..364f7ff8 100644
--- a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCMap.uexml
+++ b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCMap.uexml
@@ -38,7 +38,7 @@
-
+
@@ -67,7 +67,7 @@
-
+
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCPalette.uexml b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCPalette.uexml
index 4faf4ac9..9c25af00 100644
--- a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCPalette.uexml
+++ b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCPalette.uexml
@@ -3,7 +3,7 @@
-
+
*.pal
@@ -16,5 +16,26 @@
+
+
+
+
+ *.pal
+
+
+
+ RIFF
+ PAL
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCPicture.uexml b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCPicture.uexml
index 95bdd0e6..04f727cc 100644
--- a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCPicture.uexml
+++ b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCPicture.uexml
@@ -47,5 +47,20 @@
+
+
+
+
+ *.pcx
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCResourceBIN.uexml b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCResourceBIN.uexml
index daba2d24..166ab075 100644
--- a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCResourceBIN.uexml
+++ b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GameDeveloper/Associations/NewWorldComputing/NWCResourceBIN.uexml
@@ -3,7 +3,7 @@
-
+
*.bin
@@ -16,5 +16,20 @@
+
+
+
+
+ *.bin
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GraphicDesigner/Associations/Palette/NewWorldComputingPAL.uexml b/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GraphicDesigner/Associations/Palette/NewWorldComputingPAL.uexml
deleted file mode 100644
index 5008a1b8..00000000
--- a/Content/UniversalEditor.Content.PlatformIndependent/Extensions/GraphicDesigner/Associations/Palette/NewWorldComputingPAL.uexml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
- *.pal
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj b/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
index bbed5fa3..0fc02b36 100644
--- a/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
+++ b/Content/UniversalEditor.Content.PlatformIndependent/UniversalEditor.Content.PlatformIndependent.csproj
@@ -608,7 +608,6 @@
-
diff --git a/Libraries/UniversalEditor.Core/DataFormatFragment.cs b/Libraries/UniversalEditor.Core/DataFormatFragment.cs
new file mode 100644
index 00000000..de273d89
--- /dev/null
+++ b/Libraries/UniversalEditor.Core/DataFormatFragment.cs
@@ -0,0 +1,41 @@
+//
+// DataFormatFragment.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+
+using System;
+using UniversalEditor.IO;
+
+namespace UniversalEditor
+{
+ public abstract class DataFormatFragment
+ {
+ protected abstract T ReadInternal(IO.Reader reader);
+ protected abstract void WriteInternal(IO.Writer writer, T value);
+
+ public T Read(IO.Reader reader)
+ {
+ return ReadInternal(reader);
+ }
+ public void Write(IO.Writer writer, T value)
+ {
+ WriteInternal(writer, value);
+ }
+ }
+}
diff --git a/Libraries/UniversalEditor.Core/UniversalEditor.Core.csproj b/Libraries/UniversalEditor.Core/UniversalEditor.Core.csproj
index 171e4194..30a0a8a1 100644
--- a/Libraries/UniversalEditor.Core/UniversalEditor.Core.csproj
+++ b/Libraries/UniversalEditor.Core/UniversalEditor.Core.csproj
@@ -91,6 +91,7 @@
+
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/Multimedia/Palette/NewWorldComputing/RIFFPaletteDataFormat.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/Multimedia/Palette/NewWorldComputing/RIFFPaletteDataFormat.cs
new file mode 100644
index 00000000..f786f12c
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/Multimedia/Palette/NewWorldComputing/RIFFPaletteDataFormat.cs
@@ -0,0 +1,81 @@
+//
+// RIFFPaletteDataFormat.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+using System.Collections.Generic;
+using UniversalEditor.DataFormats.Chunked.RIFF;
+using UniversalEditor.ObjectModels.Chunked;
+using UniversalEditor.ObjectModels.Multimedia.Palette;
+
+namespace UniversalEditor.DataFormats.Multimedia.Palette.NewWorldComputing
+{
+ public class RIFFPaletteDataFormat : RIFFDataFormat
+ {
+ private static DataFormatReference _dfr = null;
+ protected override DataFormatReference MakeReferenceInternal()
+ {
+ if (_dfr == null)
+ {
+ _dfr = new DataFormatReference(GetType());
+ _dfr.Capabilities.Add(typeof(PaletteObjectModel), DataFormatCapabilities.All);
+ }
+ return _dfr;
+ }
+
+ protected override void BeforeLoadInternal(Stack objectModels)
+ {
+ base.BeforeLoadInternal(objectModels);
+ objectModels.Push(new ChunkedObjectModel());
+ }
+ protected override void AfterLoadInternal(Stack objectModels)
+ {
+ base.AfterLoadInternal(objectModels);
+
+ ChunkedObjectModel riff = (objectModels.Pop() as ChunkedObjectModel);
+ PaletteObjectModel palette = (objectModels.Pop() as PaletteObjectModel);
+
+ RIFFGroupChunk grp = (riff.Chunks[0] as RIFFGroupChunk);
+ if (grp.ID != "PAL ")
+ throw new InvalidDataFormatException("RIFF container does not contain a group chunk with ID 'PAL '");
+
+ RIFFDataChunk data = (grp.Chunks["data"] as RIFFDataChunk);
+ if (data == null)
+ throw new InvalidDataFormatException("'PAL ' group chunk does not contain a data chunk with ID 'data'");
+
+ if (data.Data.Length % 4 != 0)
+ throw new InvalidDataFormatException("'data' data chunk length is not evenly divisible by 4");
+
+ for (int i = 4; i < data.Data.Length; i += 4)
+ {
+ MBS.Framework.Drawing.Color color = MBS.Framework.Drawing.Color.FromRGBAByte(data.Data[i], data.Data[i + 1], data.Data[i + 2]);
+ palette.Entries.Add(new PaletteEntry(color));
+ }
+ }
+ protected override void BeforeSaveInternal(Stack objectModels)
+ {
+ base.BeforeSaveInternal(objectModels);
+
+ PaletteObjectModel palette = (objectModels.Pop() as PaletteObjectModel);
+ ChunkedObjectModel riff = new ChunkedObjectModel();
+
+ objectModels.Push(riff);
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/Multimedia/Picture/NewWorldComputing/PCX/PCXDataFormat.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/Multimedia/Picture/NewWorldComputing/PCX/PCXDataFormat.cs
new file mode 100644
index 00000000..bb4cc336
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/Multimedia/Picture/NewWorldComputing/PCX/PCXDataFormat.cs
@@ -0,0 +1,109 @@
+//
+// PCXDataFormat.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+using UniversalEditor.IO;
+using UniversalEditor.ObjectModels.Multimedia.Palette;
+using UniversalEditor.ObjectModels.Multimedia.Picture;
+
+namespace UniversalEditor.DataFormats.Multimedia.Picture.NewWorldComputing.PCX
+{
+ public class PCXDataFormat : DataFormat
+ {
+ private static DataFormatReference _dfr = null;
+ protected override DataFormatReference MakeReferenceInternal()
+ {
+ if (_dfr == null)
+ {
+ _dfr = base.MakeReferenceInternal();
+ _dfr.Capabilities.Add(typeof(PictureObjectModel), DataFormatCapabilities.All);
+ _dfr.ImportOptions.Add(new CustomOptionFile("PaletteFileName", "External _palette", "Palette|*.pal"));
+ }
+ return _dfr;
+ }
+
+ public string PaletteFileName { get; set; } = null;
+ public PaletteObjectModel Palette { get; set; } = null;
+
+ protected override void LoadInternal(ref ObjectModel objectModel)
+ {
+ PictureObjectModel pic = (objectModel as PictureObjectModel);
+ if (pic == null) throw new ObjectModelNotSupportedException();
+
+ Reader reader = Accessor.Reader;
+
+ if (!String.IsNullOrEmpty(PaletteFileName) && System.IO.File.Exists(PaletteFileName))
+ {
+ Palette = Common.Reflection.GetAvailableObjectModel(PaletteFileName);
+ }
+
+ uint dataLength = reader.ReadUInt32();
+ uint width = reader.ReadUInt32();
+ uint height = reader.ReadUInt32();
+ if (dataLength != (width * height))
+ {
+ // TODO: sanity check?
+ }
+
+ pic.Width = (int)width;
+ pic.Height = (int)height;
+
+ byte[] indices = reader.ReadBytes(width * height);
+
+ if (Palette == null)
+ Palette = new PaletteObjectModel();
+
+ if (!reader.EndOfStream)
+ {
+ // byte nul = reader.ReadByte();
+ // if (nul != 0) return; //eeee?
+
+ for (int i = 0; i < 256; i++)
+ {
+ byte r = reader.ReadByte();
+ byte g = reader.ReadByte();
+ byte b = reader.ReadByte();
+ Palette.Entries.Add(new PaletteEntry(MBS.Framework.Drawing.Color.FromRGBAByte(r, g, b)));
+ }
+ }
+
+ int x = 0, y = 0;
+ for (int i = 0; i < indices.Length; i++)
+ {
+ byte index = indices[i];
+ pic.SetPixel(Palette.Entries[index].Color, x, y);
+
+ x++;
+ if (x >= pic.Width)
+ {
+ reader.Align(4);
+
+ x = 0;
+ y++;
+ }
+ }
+ }
+
+ protected override void SaveInternal(ObjectModel objectModel)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NWCSceneLayout/NewWorldComputing/BIN/BINDataFormat.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NWCSceneLayout/NewWorldComputing/BIN/BINDataFormat.cs
index 5102339b..21c8d9d8 100644
--- a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NWCSceneLayout/NewWorldComputing/BIN/BINDataFormat.cs
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NWCSceneLayout/NewWorldComputing/BIN/BINDataFormat.cs
@@ -173,6 +173,12 @@ namespace UniversalEditor.DataFormats.NWCSceneLayout.NewWorldComputing.BIN
if (designer == null)
throw new ObjectModelNotSupportedException();
+ // HACK: because there simply is no better way to differentiate between window layout BINs and animation BINs (except maybe filename ending in FRM.BIN)
+ if (Accessor.Length == 821 && Accessor.GetFileName().EndsWith("FRM.BIN"))
+ {
+ throw new InvalidDataFormatException(); // to kick it to the *other* BIN format
+ }
+
if (!designer.Libraries.Contains(NWCSceneLayoutLibrary))
designer.Libraries.Add(NWCSceneLayoutLibrary);
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/Animation/BINAnimationType.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/Animation/BINAnimationType.cs
new file mode 100644
index 00000000..43f46d38
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/Animation/BINAnimationType.cs
@@ -0,0 +1,61 @@
+//
+// BINAnimationType.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+namespace UniversalEditor.DataFormats.NewWorldComputing.Animation
+{
+ public enum BINAnimationType
+ {
+ MOVE_START, // Start of the moving sequence on 1st animation cycle: flyers will fly up
+ MOVE_TILE_START, // Supposed to be played at the beginning of 2nd+ move.
+ MOVE_MAIN, // Core animation. Most units only have this one.
+ MOVE_TILE_END, // Cavalry & wolf. Played at the end of the cycle (2nd tile to 3rd), but not at the last one
+ MOVE_STOP, // End of the moving sequence when arrived: landing for example
+ MOVE_ONE, // Used when moving 1 tile. LICH and POWER_LICH doesn't have this, use MOVE_MAIN
+ TEMPORARY, // This is an empty placeholder for combined animation built from previous parts
+ STATIC, // Frame 1
+ IDLE1,
+ IDLE2, // Idle animations: picked at random with different probablities, rarely all 5 present
+ IDLE3,
+ IDLE4,
+ IDLE5,
+ DEATH,
+ WINCE_UP,
+ WINCE_END,
+ ATTACK1, // Attacks, number represents the angle: 1 is TOP, 2 is CENTER, 3 is BOTTOM
+ ATTACK1_END,
+ DOUBLEHEX1,
+ DOUBLEHEX1_END,
+ ATTACK2,
+ ATTACK2_END,
+ DOUBLEHEX2,
+ DOUBLEHEX2_END,
+ ATTACK3,
+ ATTACK3_END,
+ DOUBLEHEX3,
+ DOUBLEHEX3_END,
+ SHOOT1,
+ SHOOT1_END,
+ SHOOT2,
+ SHOOT2_END,
+ SHOOT3,
+ SHOOT3_END
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/Animation/BINDataFormat.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/Animation/BINDataFormat.cs
new file mode 100644
index 00000000..9ad713ac
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/Animation/BINDataFormat.cs
@@ -0,0 +1,147 @@
+//
+// BINDataFormat.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+using UniversalEditor.IO;
+using UniversalEditor.ObjectModels.Multimedia.SpriteAnimationCollection;
+
+namespace UniversalEditor.DataFormats.NewWorldComputing.Animation
+{
+ public class BINDataFormat : DataFormat
+ {
+ public const byte IDLE_ANIMATION_COUNT_MAX = 5;
+ public const byte PROJECTILE_ANGLE_MAX = 12;
+ public const byte FRAME_MAX = 16;
+
+ private static DataFormatReference _dfr = null;
+ protected override DataFormatReference MakeReferenceInternal()
+ {
+ if (_dfr == null)
+ {
+ _dfr = base.MakeReferenceInternal();
+ _dfr.Capabilities.Add(typeof(SpriteAnimationCollectionObjectModel), DataFormatCapabilities.All);
+ }
+ return _dfr;
+ }
+
+ protected override void LoadInternal(ref ObjectModel objectModel)
+ {
+ SpriteAnimationCollectionObjectModel anim = (objectModel as SpriteAnimationCollectionObjectModel);
+ if (anim == null)
+ throw new ObjectModelNotSupportedException();
+
+ // HACK: because there simply is no better way to differentiate between window layout BINs and animation BINs (except maybe filename ending in FRM.BIN)
+ if (!(Accessor.Length == 821 && Accessor.GetFileName().EndsWith("FRM.BIN")))
+ {
+ throw new InvalidDataFormatException(); // to kick it to the *other* BIN format
+ }
+
+ Reader reader = Accessor.Reader;
+
+ byte one = reader.ReadByte();
+
+ short eyePositionX = reader.ReadInt16();
+ short eyePositionY = reader.ReadInt16();
+
+ // frame offsets for the future use
+ int[][] moveOffsets = new int[7][];
+ for (int i = 0; i < 7; i++)
+ {
+ int[] moveOffset = new int[16];
+ for ( int frame = 0; frame < 16; ++frame)
+ {
+ moveOffset[frame] = reader.ReadByte();
+ }
+ moveOffsets[i] = moveOffset;
+ }
+
+ // at offset 117
+ byte idleAnimationCount = reader.ReadByte();
+ float[] idleAnimationPriorities = new float[IDLE_ANIMATION_COUNT_MAX];
+ uint[] unusedIdleDelays = new uint[IDLE_ANIMATION_COUNT_MAX];
+ for (byte i = 0; i < IDLE_ANIMATION_COUNT_MAX; i++)
+ {
+ idleAnimationPriorities[i] = reader.ReadSingle();
+ }
+ for (byte i = 0; i < IDLE_ANIMATION_COUNT_MAX; i++)
+ {
+ unusedIdleDelays[i] = reader.ReadUInt32();
+ }
+
+ // at offset 158
+ uint idleAnimationDelay = reader.ReadUInt32();
+
+ uint moveSpeed = reader.ReadUInt32();
+ uint shootSpeed = reader.ReadUInt32();
+ uint flightSpeed = reader.ReadUInt32();
+
+ // projectile data
+ for (int i = 0; i < 3; i++)
+ {
+ short projectileOffsetX = reader.ReadInt16();
+ short projectileOffsetY = reader.ReadInt16();
+ }
+
+ // describes how to rotate the projectile when
+ byte projectileAngleCount = reader.ReadByte();
+ for (byte i = 0; i < PROJECTILE_ANGLE_MAX; i++)
+ {
+ // even though there are only {projectileAngleCount} items, the rest of PROJECTILE_ANGLE_MAX is filled with zeroes
+ float projectileAngle = reader.ReadSingle();
+ }
+
+ // Positional offsets for sprites & drawing
+ uint troopCountOffsetLeft = reader.ReadUInt32();
+ uint troopCountOffsetRight = reader.ReadUInt32();
+
+ // Load animation sequences themselves
+ int nMaxAnimationTypes = Enum.GetValues(typeof(BINAnimationType)).Length;
+
+ byte[] animCounts = new byte[nMaxAnimationTypes];
+ byte[][] animFrames = new byte[nMaxAnimationTypes][];
+
+ SpriteAnimation[] anims = new SpriteAnimation[nMaxAnimationTypes];
+ for (int idx = 0; idx < nMaxAnimationTypes; ++idx)
+ {
+ animCounts[idx] = reader.ReadByte();
+
+ anims[idx] = new SpriteAnimation();
+ anims[idx].Name = Enum.GetName(typeof(BINAnimationType), idx);
+ }
+ for (int idx = 0; idx < nMaxAnimationTypes; ++idx)
+ {
+ animFrames[idx] = new byte[FRAME_MAX];
+ for (byte frame = 0; frame < FRAME_MAX; frame++)
+ {
+ animFrames[idx][frame] = reader.ReadByte();
+ }
+ for (byte frame = 0; frame < animCounts[idx]; frame++)
+ {
+ anims[idx].Frames.Add(animFrames[idx][frame]);
+ }
+ anim.Animations.Add(anims[idx]);
+ }
+ }
+ protected override void SaveInternal(ObjectModel objectModel)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/CastleFragment.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/CastleFragment.cs
new file mode 100644
index 00000000..30cd1493
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/CastleFragment.cs
@@ -0,0 +1,102 @@
+//
+// CastleFragment.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+
+using UniversalEditor.IO;
+using UniversalEditor.ObjectModels.NewWorldComputing.Map;
+
+namespace UniversalEditor.DataFormats.NewWorldComputing.WorldMap2D.NewWorldComputing.Heroes2
+{
+ public class CastleFragment : DataFormatFragment
+ {
+ protected override MapCastle ReadInternal(Reader reader)
+ {
+ MapCastle castle = new MapCastle();
+ castle.Color = (MapCastleColor)reader.ReadByte();
+ castle.HasCustomBuilding = reader.ReadBoolean();
+ castle.Buildings = (MapBuildingType)reader.ReadUInt16();
+ castle.Dwellings = (MapDwellingType)reader.ReadUInt16();
+ castle.MageGuildLevel = (MapMageGuildLevel)reader.ReadByte();
+ castle.HasCustomTroops = reader.ReadBoolean();
+
+ byte[] monsterTypes = reader.ReadBytes(5);
+ ushort[] monsterCounts = reader.ReadUInt16Array(5);
+ for (int i = 0; i < monsterTypes.Length; i++)
+ {
+ if (monsterTypes[i] != 0xFF)
+ {
+ castle.Monsters[i] = new MapArmyMonster((MapMonsterType)monsterTypes[i], monsterCounts[i]);
+ }
+ }
+
+ castle.HasCaptain = reader.ReadBoolean();
+ castle.HasCustomName = reader.ReadBoolean();
+ castle.Name = reader.ReadFixedLengthString(13).TrimNull();
+ castle.Type = (MapCastleType)reader.ReadByte();
+ castle.IsCastle = reader.ReadBoolean();
+ castle.IsUpgradable = reader.ReadBoolean(); // 00 TRUE, 01 FALSE
+
+ byte[] unknown = reader.ReadBytes(29);
+
+ return castle;
+ }
+ protected override void WriteInternal(Writer writer, MapCastle value)
+ {
+ writer.WriteByte((byte)value.Color);
+ writer.WriteBoolean(value.HasCustomBuilding);
+ writer.WriteUInt16((ushort)value.Buildings);
+ writer.WriteUInt16((ushort)value.Dwellings);
+ writer.WriteByte((byte)value.MageGuildLevel);
+ writer.WriteBoolean(value.HasCustomTroops);
+
+ for (int i = 0; i < 5; i++)
+ {
+ if (i < value.Monsters.Length)
+ {
+ writer.WriteByte((byte)value.Monsters[i].MonsterType);
+ }
+ else
+ {
+ writer.WriteByte(0);
+ }
+ }
+ for (int i = 0; i < 5; i++)
+ {
+ if (i < value.Monsters.Length)
+ {
+ writer.WriteUInt16(value.Monsters[i].Amount);
+ }
+ else
+ {
+ writer.WriteUInt16(0);
+ }
+ }
+
+ writer.WriteBoolean(value.HasCaptain);
+ writer.WriteBoolean(value.HasCustomName);
+ writer.WriteFixedLengthString(value.Name, 13);
+ writer.WriteByte((byte)value.Type);
+ writer.WriteBoolean(value.IsCastle);
+ writer.WriteBoolean(value.IsUpgradable); // 00 TRUE, 01 FALSE
+
+ writer.WriteBytes(new byte[29]);// idk
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/EventFragment.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/EventFragment.cs
new file mode 100644
index 00000000..47982a5c
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/EventFragment.cs
@@ -0,0 +1,93 @@
+//
+// EventFragment.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+
+using UniversalEditor.IO;
+using UniversalEditor.ObjectModels.NewWorldComputing.Map;
+
+namespace UniversalEditor.DataFormats.NewWorldComputing.WorldMap2D.NewWorldComputing.Heroes2
+{
+ public class EventFragment : DataFormatFragment
+ {
+ protected override MapEvent ReadInternal(Reader reader)
+ {
+ MapEvent evt = new MapEvent();
+ evt.AmountWood = reader.ReadInt32();
+ evt.AmountMercury = reader.ReadInt32();
+ evt.AmountOre = reader.ReadInt32();
+ evt.AmountSulfur = reader.ReadInt32();
+ evt.AmountCrystal = reader.ReadInt32();
+ evt.AmountGems = reader.ReadInt32();
+ evt.AmountGold = reader.ReadInt32();
+
+ short nArtifact = reader.ReadInt16();
+ // evt.Artifact = (MapArtifact)nArtifact;
+
+ evt.AllowComputer = reader.ReadBoolean();
+ evt.SingleVisit = reader.ReadBoolean();
+
+ byte[] unknown = reader.ReadBytes(10);
+
+ bool colorBlue = reader.ReadBoolean();
+ if (colorBlue) evt.AllowedKingdoms |= MapKingdomColor.Blue;
+ bool colorGreen = reader.ReadBoolean();
+ if (colorGreen) evt.AllowedKingdoms |= MapKingdomColor.Green;
+ bool colorRed = reader.ReadBoolean();
+ if (colorRed) evt.AllowedKingdoms |= MapKingdomColor.Red;
+ bool colorYellow = reader.ReadBoolean();
+ if (colorYellow) evt.AllowedKingdoms |= MapKingdomColor.Yellow;
+ bool colorOrange = reader.ReadBoolean();
+ if (colorOrange) evt.AllowedKingdoms |= MapKingdomColor.Orange;
+ bool colorPurple = reader.ReadBoolean();
+ if (colorPurple) evt.AllowedKingdoms |= MapKingdomColor.Purple;
+
+ evt.Message = reader.ReadNullTerminatedString();
+ return evt;
+ }
+ protected override void WriteInternal(Writer writer, MapEvent value)
+ {
+ writer.WriteInt32(value.AmountWood);
+ writer.WriteInt32(value.AmountMercury);
+ writer.WriteInt32(value.AmountOre);
+ writer.WriteInt32(value.AmountSulfur);
+ writer.WriteInt32(value.AmountCrystal);
+ writer.WriteInt32(value.AmountGems);
+ writer.WriteInt32(value.AmountGold);
+
+ short nArtifact = 0;
+ writer.WriteInt16(nArtifact);
+ // evt.Artifact = (MapArtifact)nArtifact;
+
+ writer.WriteBoolean(value.AllowComputer);
+ writer.WriteBoolean(value.SingleVisit);
+
+ writer.WriteBytes(new byte[10]);
+
+ writer.WriteBoolean((value.AllowedKingdoms & MapKingdomColor.Blue) == MapKingdomColor.Blue);
+ writer.WriteBoolean((value.AllowedKingdoms & MapKingdomColor.Green) == MapKingdomColor.Green);
+ writer.WriteBoolean((value.AllowedKingdoms & MapKingdomColor.Red) == MapKingdomColor.Red);
+ writer.WriteBoolean((value.AllowedKingdoms & MapKingdomColor.Yellow) == MapKingdomColor.Yellow);
+ writer.WriteBoolean((value.AllowedKingdoms & MapKingdomColor.Orange) == MapKingdomColor.Orange);
+ writer.WriteBoolean((value.AllowedKingdoms & MapKingdomColor.Purple) == MapKingdomColor.Purple);
+
+ writer.WriteNullTerminatedString(value.Message);
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/HeroFragment.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/HeroFragment.cs
new file mode 100644
index 00000000..fcaf9a1d
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/HeroFragment.cs
@@ -0,0 +1,167 @@
+//
+// HeroFragment.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+using UniversalEditor.IO;
+using UniversalEditor.ObjectModels.NewWorldComputing;
+using UniversalEditor.ObjectModels.NewWorldComputing.Map;
+
+namespace UniversalEditor.DataFormats.NewWorldComputing.WorldMap2D.NewWorldComputing.Heroes2
+{
+ public class HeroFragment : DataFormatFragment
+ {
+ protected override MapHero ReadInternal(Reader reader)
+ {
+ MapHero hero = new MapHero();
+ bool unk = reader.ReadBoolean();
+ hero.HasCustomTroops = reader.ReadBoolean();
+
+ byte[] monsters = reader.ReadBytes(5);
+ ushort[] monsterCount = reader.ReadUInt16Array(5);
+ for (int i = 0; i < monsters.Length; i++)
+ {
+ if (monsters[i] != 0xFF)
+ {
+ MapMonsterType monsterType = (MapMonsterType)monsters[i];
+ hero.Monsters.Add(new MapArmyMonster(monsterType, monsterCount[i]));
+ }
+ }
+
+ hero.HasCustomPortrait = reader.ReadBoolean();
+ hero.CustomPortraitIndex = reader.ReadByte();
+
+ byte[] customArtifacts = reader.ReadBytes(3); // -1 if unset
+ for (int i = 0; i < customArtifacts.Length; i++)
+ {
+ if (customArtifacts[i] != 0xFF)
+ {
+ MapArtifact artifact = new MapArtifact((MapArtifactType)customArtifacts[i]);
+ hero.Artifacts.Add(artifact);
+ }
+ }
+
+ byte unknown2 = reader.ReadByte();
+
+ hero.Experience = reader.ReadUInt32();
+
+ hero.HasCustomSkills = reader.ReadBoolean();
+ byte[] skills = reader.ReadBytes(8); // 0xff none, pathfinding, archery, logistic, scouting, diplomacy, navigation, leadership, wisdom,
+ // mysticism, luck, ballistics, eagle, necromance, estate
+ byte[] skillLevels = reader.ReadBytes(8); // 1 = basic, 2 = advanced, 3 = expert, 0 = unset
+ for (int i = 0; i < skills.Length; i++)
+ {
+ if (skills[i] != 0xFF)
+ {
+ HeroSkillType type = (HeroSkillType)skills[i];
+ HeroSkillLevel level = (HeroSkillLevel)skillLevels[i];
+ hero.Skills.Add(new HeroSkill(type, level));
+ }
+ }
+
+ byte unknown3 = reader.ReadByte();
+ hero.HasCustomName = reader.ReadBoolean();
+ hero.Name = reader.ReadFixedLengthString(13).TrimNull();
+ hero.Patrol = reader.ReadBoolean();
+ hero.PatrolSquareCount = reader.ReadByte();
+
+ byte[] unknown4 = reader.ReadBytes(15);
+ return hero;
+ }
+
+ protected override void WriteInternal(Writer writer, MapHero value)
+ {
+ writer.WriteBoolean(false);
+ writer.WriteBoolean(value.HasCustomTroops);
+
+ for (int i = 0; i < 5; i++)
+ {
+ if (i < value.Monsters.Count)
+ {
+ writer.WriteByte((byte)value.Monsters[i].MonsterType);
+ }
+ else
+ {
+ writer.WriteByte(255);
+ }
+ }
+ for (int i = 0; i < 5; i++)
+ {
+ if (i < value.Monsters.Count)
+ {
+ writer.WriteUInt16((byte)value.Monsters[i].Amount);
+ }
+ else
+ {
+ writer.WriteUInt16(0);
+ }
+ }
+
+ writer.WriteBoolean(value.HasCustomPortrait);
+ writer.WriteByte(value.CustomPortraitIndex);
+
+ for (int i = 0; i < 3; i++)
+ {
+ if (i < value.Artifacts.Count)
+ {
+ writer.WriteByte((byte)value.Artifacts[i].Type);
+ }
+ else
+ {
+ writer.WriteByte(255);
+ }
+ }
+
+ writer.WriteByte(0);
+ writer.WriteUInt32(value.Experience);
+
+ writer.WriteBoolean(value.HasCustomSkills);
+ for (int i = 0; i < 8; i++)
+ {
+ if (i < value.Skills.Count)
+ {
+ writer.WriteByte((byte)value.Skills[i].Type);
+ }
+ else
+ {
+ writer.WriteByte(255);
+ }
+ }
+ for (int i = 0; i < 8; i++)
+ {
+ if (i < value.Skills.Count)
+ {
+ writer.WriteByte((byte)value.Skills[i].Level);
+ }
+ else
+ {
+ writer.WriteByte(0);
+ }
+ }
+
+ writer.WriteByte(0); // unknown3
+ writer.WriteBoolean(value.HasCustomName);
+ writer.WriteFixedLengthString(value.Name, 13);
+ writer.WriteBoolean(value.Patrol);
+ writer.WriteByte(value.PatrolSquareCount);
+
+ writer.WriteBytes(new byte[15]);
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/Heroes2MapDataFormat.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/Heroes2MapDataFormat.cs
index 965a6a25..7606b068 100644
--- a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/Heroes2MapDataFormat.cs
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/Heroes2MapDataFormat.cs
@@ -20,9 +20,11 @@
// along with this program. If not, see .
using System;
+using UniversalEditor.IO;
+using UniversalEditor.ObjectModels.NewWorldComputing;
using UniversalEditor.ObjectModels.NewWorldComputing.Map;
-namespace UniversalEditor.DataFormats.Gaming.WorldMap2D.NewWorldComputing.Heroes2
+namespace UniversalEditor.DataFormats.NewWorldComputing.WorldMap2D.NewWorldComputing.Heroes2
{
///
/// Pprovides a for manipulating Heroes of Might and Magic II map files.
@@ -119,138 +121,173 @@ namespace UniversalEditor.DataFormats.Gaming.WorldMap2D.NewWorldComputing.Heroes
#endregion
// kingdom count
- br.Accessor.Seek(0x1A, IO.SeekOrigin.Begin);
byte kingdomCount = br.ReadByte();
+ byte nCount1 = br.ReadByte(); // idk?
+ byte nCount2 = br.ReadByte(); // idk?
- br.Accessor.Seek(0x1D, IO.SeekOrigin.Begin);
map.WinConditions = (MapWinCondition)br.ReadByte();
+ map.ComputerAlsoWins = (MapWinCondition)br.ReadByte();
+ map.AllowNormalVictory = br.ReadBoolean();
- byte wins1 = br.ReadByte();
- byte wins2 = br.ReadByte();
ushort wins3 = br.ReadUInt16();
- br.Accessor.Seek(0x2C, IO.SeekOrigin.Begin);
- ushort wins4 = br.ReadUInt16();
- br.Accessor.Seek(0x22, IO.SeekOrigin.Begin);
map.LoseConditions = (MapLoseCondition)br.ReadByte();
-
- ushort loss1 = br.ReadUInt16();
- br.Accessor.Seek(0x2E, IO.SeekOrigin.Begin);
- ushort loss2 = br.ReadUInt16();
+ ushort u2 = br.ReadUInt16();
// starting hero
- br.Accessor.Seek(0x25, IO.SeekOrigin.Begin);
byte startingHero = br.ReadByte();
bool withHeroes = (startingHero == 0);
- byte[] races = br.ReadBytes(5);
+ byte[] races = br.ReadBytes(6);
- // name
+ ushort wins2 = br.ReadUInt16();
+ ushort loss2 = br.ReadUInt16();
+
+ // map name
br.Accessor.Seek(0x3A, IO.SeekOrigin.Begin);
- map.Name = br.ReadFixedLengthString(16);
- map.Name = map.Name.TrimNull();
- // name
+ map.Name = br.ReadFixedLengthString(16).TrimNull();
+
+ // map description
br.Accessor.Seek(0x76, IO.SeekOrigin.Begin);
- map.Description = br.ReadFixedLengthString(143);
- map.Description = map.Description.TrimNull();
+ map.Description = br.ReadFixedLengthString(143).TrimNull();
byte[] unknown = br.ReadBytes(157);
- ushort unknown2 = br.ReadUInt16();
+ ushort nObjects = br.ReadUInt16();
- // 33044 bytes between here and there - tiles (36 * 36 * 25 bytes per tile)
+ // 33044 bytes between here and there - tiles (width * height * 20 bytes per tile)
+ uint width = br.ReadUInt32();
+ uint height = br.ReadUInt32();
- long pos = br.Accessor.Position;
- br.Accessor.Position = pos;
-
- for (ushort i = 0; i < unknown2; i++)
- {
- MapTile tile = ReadTile(br);
- }
+ TileFragment fragTile = new TileFragment();
for (int y = 0; y < map.Height; y++)
{
for (int x = 0; x < map.Width; x++)
{
- MapTile tile = ReadTile(br);
+ MapTile tile = fragTile.Read(br);
map.Tiles.Add(tile);
}
}
- #region Castle
- for (byte i = 0; i < kingdomCount; i++)
+ // addons
+ uint nAddons = br.ReadUInt32();
+ for (uint i = 0; i < nAddons; i++)
{
- MapCastle castle = ReadCastle(br);
+ ushort indexAddon = br.ReadUInt16();
+ byte objectNameN1 = br.ReadByte();
+ objectNameN1 *= 2; // idk
+ byte indexNameN1 = br.ReadByte();
+ byte quantityN = br.ReadByte();
+ byte objectNameN2 = br.ReadByte();
+ byte indexNameN2 = br.ReadByte();
+ uint uniqNumberN1 = br.ReadUInt32();
+ uint uniqNumberN2 = br.ReadUInt32();
+ }
+
+ for (int i = 0; i < 72; i++)
+ {
+ // castle coordinates
+ // 72 x 3 byte (cx, cy, id)
+ byte cx = br.ReadByte();
+ byte cy = br.ReadByte();
+ byte id = br.ReadByte();
+
+ if (cx == 0xFF && cy == 0xFF)
+ continue;
+
+ bool isCastle = false;
+ if ((id & 0x80) == 0x80)
+ {
+ isCastle = true;
+ id = (byte)(id & ~0x80);
+ }
+
+ MapCastleType castleType = (MapCastleType)id;
+ // map.Castles.Add(new MapCastle(castleType, cx, cy, isCastle));
+ }
+
+ // kingdom resource coordinates
+ for (int i = 0; i < 144; i++)
+ {
+ byte cx = br.ReadByte();
+ byte cy = br.ReadByte();
+ byte id = br.ReadByte();
+
+ if (cx == 0xFF && cy == 0xFF)
+ continue;
+
+ MapResourceType resourceType = (MapResourceType)id;
+
+ }
+
+ map.ObeliskCount = br.ReadByte();
+ return;
+
+ // idk wtf this is
+ uint countBlock = 0;
+ while (!br.EndOfStream)
+ {
+ byte l = br.ReadByte();
+ byte h = br.ReadByte();
+ if (l == 0 && h == 0)
+ break;
+ countBlock = (uint)(256 * (h + l) - 1); // wtf
+ }
+
+ MonsterFragment fragMonster = new MonsterFragment();
+ CastleFragment fragCastle = new CastleFragment();
+ HeroFragment fragHero = new HeroFragment();
+ EventFragment fragEvent = new EventFragment();
+
+ for (ushort i = 0; i < countBlock; i++)
+ {
+ ushort blockSize = br.ReadUInt16();
+
+ MapTile tile = FindObject(map, i);
+ switch ((MapItemType)blockSize)
+ {
+ case MapItemType.Monster:
+ {
+ MapArmyMonster item = fragMonster.Read(br);
+ map.Items.Add(item);
+ break;
+ }
+ case MapItemType.Castle:
+ {
+ MapCastle castle = fragCastle.Read(br);
+ map.Items.Add(castle);
+ break;
+ }
+ case MapItemType.Hero:
+ {
+ MapHero hero = fragHero.Read(br);
+ map.Items.Add(hero);
+ break;
+ }
+ }
}
- #endregion
}
- private MapTile ReadTile(IO.Reader br)
+ private MapTile FindObject(MapObjectModel map, ushort i)
{
- MapTile tile = new MapTile();
- tile.GroundType = (MapGroundType)br.ReadUInt16(); // tile (ocean, grass, snow, swamp, lava, desert, dirt, wasteland, beach)
- byte objectName1 = br.ReadByte(); // level 1.0
- byte indexName1 = br.ReadByte(); // index level 1.0 or 0xFF
- byte quantity1 = br.ReadByte(); // count
- byte quantity2 = br.ReadByte(); // count
- byte objectName2 = br.ReadByte(); // level 2.0
- byte indexName2 = br.ReadByte(); // index level 2.0 or 0xFF
- byte shape = br.ReadByte(); // shape reflect % 4, 0 none, 1 vertical, 2 horizontal, 3 any
- byte generalObject = br.ReadByte(); // zero or object
- ushort indexAddon = br.ReadUInt16(); // zero or index addons_t
- uint uniqNumber1 = br.ReadUInt32(); // level 1.0
- uint uniqNumber2 = br.ReadUInt32(); // level 2.0
-
- byte[] unknown = br.ReadBytes(5);
- // 259229
- return tile;
-
- ushort indexAddonN = br.ReadUInt16(); // zero or next addons_t
- byte objectNameN1 = br.ReadByte(); // level 1.N
- byte indexNameN1 = br.ReadByte(); // level 1.N or 0xFF
- byte quantityN = br.ReadByte(); //
- byte objectNameN2 = br.ReadByte(); // level 2.N
- byte indexNameN2 = br.ReadByte(); // level 1.N or 0xFF
- uint uniqNumberN1 = br.ReadUInt32(); // level 1.N
- uint uniqNumberN2 = br.ReadUInt32(); // level 2.N
-
- return tile;
- }
-
- private MapCastle ReadCastle(IO.Reader br)
- {
- MapCastle castle = new MapCastle();
-
- ushort signal = br.ReadUInt16();
-
- castle.Color = (MapCastleColor)br.ReadByte();
- castle.HasCustomBuilding = br.ReadBoolean();
- castle.Buildings = (MapBuildingType)br.ReadUInt16();
- castle.Dwellings = (MapDwellingType)br.ReadUInt16();
- castle.MageGuildLevel = (MapMageGuildLevel)br.ReadByte();
- castle.HasCustomTroops = br.ReadBoolean();
-
- for (int i = 0; i < 5; i++)
+ int findobject = -1;
+ for (int it_index = 0; it_index < map.Tiles.Count && findobject < 0; ++it_index)
{
- castle.Monsters[i] = new MapArmyMonster();
- castle.Monsters[i].MonsterType = (MapMonsterType)br.ReadByte();
- }
- for (int i = 0; i < 5; i++)
- {
- castle.Monsters[i].Amount = br.ReadUInt16();
+ MapTile tile = map.Tiles[it_index];
+
+ // orders(quantity2, quantity1)
+ int orders = tile.Quantity2; // (tile.GetQuantity2() ? tile.GetQuantity2() : 0);
+ orders <<= 8;
+ orders |= tile.Quantity1; // tile.GetQuantity1();
+
+ if ((orders != 0) && !((orders % 0x08) != 0) && (i + 1 == orders / 0x08))
+ findobject = it_index;
}
+ if (findobject == -1)
+ return null;
- castle.HasCaptain = br.ReadBoolean();
- castle.HasCustomName = br.ReadBoolean();
- castle.Name = br.ReadFixedLengthString(13);
- castle.Name = castle.Name.TrimNull();
- castle.Type = (MapCastleType)br.ReadByte();
- castle.IsCastle = br.ReadBoolean();
- castle.IsUpgradable = br.ReadBoolean(); // 00 TRUE, 01 FALSE
-
- byte[] unknown = br.ReadBytes(29);
-
- return castle;
+ return map.Tiles[findobject];
}
protected override void SaveInternal(ObjectModel objectModel)
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/MonsterFragment.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/MonsterFragment.cs
new file mode 100644
index 00000000..abbb66f4
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/MonsterFragment.cs
@@ -0,0 +1,39 @@
+//
+// MonsterFragment.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+using UniversalEditor.IO;
+using UniversalEditor.ObjectModels.NewWorldComputing.Map;
+
+namespace UniversalEditor.DataFormats.NewWorldComputing.WorldMap2D.NewWorldComputing.Heroes2
+{
+ public class MonsterFragment : DataFormatFragment
+ {
+ protected override MapArmyMonster ReadInternal(Reader reader)
+ {
+ MapArmyMonster item = null; //new MapArmyMonster();
+ return item;
+ }
+ protected override void WriteInternal(Writer writer, MapArmyMonster value)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/TileFragment.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/TileFragment.cs
new file mode 100644
index 00000000..b5d3b4ce
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes2/TileFragment.cs
@@ -0,0 +1,62 @@
+//
+// TileFragment.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+using UniversalEditor.IO;
+using UniversalEditor.ObjectModels.NewWorldComputing.Map;
+
+namespace UniversalEditor.DataFormats.NewWorldComputing.WorldMap2D.NewWorldComputing.Heroes2
+{
+ public class TileFragment : DataFormatFragment
+ {
+ protected override MapTile ReadInternal(Reader reader)
+ {
+ MapTile tile = new MapTile();
+ tile.GroundType = (MapGroundType)reader.ReadUInt16(); // tile (ocean, grass, snow, swamp, lava, desert, dirt, wasteland, beach)
+ tile.ObjectName1 = reader.ReadByte(); // level 1.0
+ tile.IndexName1 = reader.ReadByte(); // index level 1.0 or 0xFF
+ tile.Quantity1 = reader.ReadByte(); // count
+ tile.Quantity2 = reader.ReadByte(); // count
+ tile.ObjectName2 = reader.ReadByte(); // level 2.0
+ tile.IndexName2 = reader.ReadByte(); // index level 2.0 or 0xFF
+ tile.Shape = reader.ReadByte(); // shape reflect % 4, 0 none, 1 vertical, 2 horizontal, 3 any
+ tile.GeneralObject = reader.ReadByte(); // zero or object
+ tile.IndexAddon = reader.ReadUInt16(); // zero or index addons_t
+ tile.UniqNumber1 = reader.ReadUInt32(); // level 1.0
+ tile.UniqNumber2 = reader.ReadUInt32(); // level 2.0
+ return tile;
+ }
+ protected override void WriteInternal(Writer writer, MapTile value)
+ {
+ writer.WriteUInt16((ushort)value.GroundType);
+ writer.WriteByte(value.ObjectName1);
+ writer.WriteByte(value.IndexName1);
+ writer.WriteByte(value.Quantity1);
+ writer.WriteByte(value.Quantity2);
+ writer.WriteByte(value.ObjectName2);
+ writer.WriteByte(value.IndexName2);
+ writer.WriteByte(value.Shape);
+ writer.WriteByte(value.GeneralObject);
+ writer.WriteUInt16(value.IndexAddon);
+ writer.WriteUInt32(value.UniqNumber1);
+ writer.WriteUInt32(value.UniqNumber2);
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes3/Heroes3GameType.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes3/Heroes3GameType.cs
index cf0a7ad3..0e14604b 100644
--- a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes3/Heroes3GameType.cs
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes3/Heroes3GameType.cs
@@ -19,7 +19,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-namespace UniversalEditor.DataFormats.Gaming.WorldMap2D.NewWorldComputing.Heroes3
+namespace UniversalEditor.DataFormats.NewWorldComputing.WorldMap2D.NewWorldComputing.Heroes3
{
///
/// Indicates the game campaign type supported by a Heroes of Might and Magic III game map.
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes3/Heroes3MapDataFormat.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes3/Heroes3MapDataFormat.cs
index c2b3dfa1..e25186f3 100644
--- a/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes3/Heroes3MapDataFormat.cs
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/DataFormats/NewWorldComputing/WorldMap2D/NewWorldComputing/Heroes3/Heroes3MapDataFormat.cs
@@ -22,7 +22,7 @@
using UniversalEditor.Accessors;
using UniversalEditor.ObjectModels.NewWorldComputing.Map;
-namespace UniversalEditor.DataFormats.Gaming.WorldMap2D.NewWorldComputing.Heroes3
+namespace UniversalEditor.DataFormats.NewWorldComputing.WorldMap2D.NewWorldComputing.Heroes3
{
///
/// Provides a for manipulating Heroes of Might and Magic III map files.
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/HeroSkill.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/HeroSkill.cs
new file mode 100644
index 00000000..e9f6f9f8
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/HeroSkill.cs
@@ -0,0 +1,41 @@
+//
+// HeroSkill.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+namespace UniversalEditor.ObjectModels.NewWorldComputing
+{
+ public class HeroSkill
+ {
+ public class HeroSkillCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public HeroSkillType Type { get; set; }
+ public HeroSkillLevel Level { get; set; } = HeroSkillLevel.Basic;
+
+ public HeroSkill(HeroSkillType type, HeroSkillLevel level)
+ {
+ Type = type;
+ Level = level;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/HeroSkillLevel.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/HeroSkillLevel.cs
new file mode 100644
index 00000000..63b9e211
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/HeroSkillLevel.cs
@@ -0,0 +1,30 @@
+//
+// HeroSkillLevel.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+namespace UniversalEditor.ObjectModels.NewWorldComputing
+{
+ public enum HeroSkillLevel
+ {
+ Basic = 1,
+ Advanced = 2,
+ Expert = 3
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/HeroSkillType.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/HeroSkillType.cs
new file mode 100644
index 00000000..af37d76e
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/HeroSkillType.cs
@@ -0,0 +1,28 @@
+//
+// HeroSkillType.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+namespace UniversalEditor.ObjectModels.NewWorldComputing
+{
+ public enum HeroSkillType
+ {
+ Unknown = 255
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapArmyMonster.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapArmyMonster.cs
index d7975f46..f405a900 100644
--- a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapArmyMonster.cs
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapArmyMonster.cs
@@ -24,9 +24,21 @@ namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
///
/// Represents an army monster placed on a Heroes of Might and Magic map.
///
- public class MapArmyMonster
+ public class MapArmyMonster : MapItem
{
+ public class MapArmyMonsterCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
public ushort Amount { get; set; } = 0;
public MapMonsterType MonsterType { get; set; } = MapMonsterType.Unknown;
- }
+
+ public MapArmyMonster(MapMonsterType monsterType, ushort amount)
+ {
+ MonsterType = monsterType;
+ Amount = amount;
+ }
+ }
}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapArtifact.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapArtifact.cs
new file mode 100644
index 00000000..e7242239
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapArtifact.cs
@@ -0,0 +1,39 @@
+//
+// MapArtifact.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
+{
+ public class MapArtifact : MapItem
+ {
+ public class MapArtifactCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ public MapArtifactType Type { get; set; } = MapArtifactType.Unknown;
+
+ public MapArtifact(MapArtifactType type)
+ {
+ Type = type;
+ }
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapArtifactType.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapArtifactType.cs
new file mode 100644
index 00000000..1551eb56
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapArtifactType.cs
@@ -0,0 +1,28 @@
+//
+// MapArtifactType.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
+{
+ public enum MapArtifactType : byte
+ {
+ Unknown = 255
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapCastle.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapCastle.cs
index e9c357ab..12d42b2b 100644
--- a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapCastle.cs
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapCastle.cs
@@ -26,7 +26,7 @@ namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
///
/// Defines characteristics related to a castle placed on a map.
///
- public class MapCastle
+ public class MapCastle : MapItem
{
private MapCastleColor mvarColor = MapCastleColor.Unknown;
public MapCastleColor Color { get { return mvarColor; } set { mvarColor = value; } }
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapCastleType.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapCastleType.cs
index 3d3a01eb..76e545e4 100644
--- a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapCastleType.cs
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapCastleType.cs
@@ -26,12 +26,14 @@ namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
///
public enum MapCastleType : byte
{
+ Unknown = 0xFF,
Knight = 0,
Barbarian = 1,
Sorceress = 2,
Warlock = 3,
Wizard = 4,
Necroman = 5,
- Unknown = 6
+ Multiple = 6,
+ Random = 7
}
}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapEvent.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapEvent.cs
new file mode 100644
index 00000000..5b94513a
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapEvent.cs
@@ -0,0 +1,100 @@
+//
+// MapEvent.cs - represents an event which occurs on the map
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+
+using System;
+
+namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
+{
+ public class MapEvent
+ {
+ public class MapEventCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ // resource counts
+ ///
+ /// Gets or sets the amount of Wood resource that should be given to or taken from the player.
+ ///
+ /// The amount of Wood resource that should be given to or taken from the player.
+ public int AmountWood { get; set; } = 0;
+ // resource counts
+ ///
+ /// Gets or sets the amount of Mercury resource that should be given to or taken from the player.
+ ///
+ /// The amount of Mercury resource that should be given to or taken from the player.
+ public int AmountMercury { get; set; } = 0;
+ // resource counts
+ ///
+ /// Gets or sets the amount of Ore resource that should be given to or taken from the player.
+ ///
+ /// The amount of Ore resource that should be given to or taken from the player.
+ public int AmountOre { get; set; } = 0;
+ // resource counts
+ ///
+ /// Gets or sets the amount of Sulfur resource that should be given to or taken from the player.
+ ///
+ /// The amount of Sulfur resource that should be given to or taken from the player.
+ public int AmountSulfur { get; set; } = 0;
+ // resource counts
+ ///
+ /// Gets or sets the amount of Crystal resource that should be given to or taken from the player.
+ ///
+ /// The amount of Crystal resource that should be given to or taken from the player.
+ public int AmountCrystal { get; set; } = 0;
+ // resource counts
+ ///
+ /// Gets or sets the amount of Gems resource that should be given to or taken from the player.
+ ///
+ /// The amount of Gems resource that should be given to or taken from the player.
+ public int AmountGems { get; set; } = 0;
+ // resource counts
+ ///
+ /// Gets or sets the amount of Gold resource that should be given to or taken from the player.
+ ///
+ /// The amount of Gold resource that should be given to or taken from the player.
+ public int AmountGold { get; set; } = 0;
+
+ ///
+ /// Gets or sets a value indicating whether this is available to be triggered by a non-player (i.e., computer) character.
+ ///
+ /// true if computer players are allowed to trigger the event; otherwise, false.
+ public bool AllowComputer { get; set; } = false;
+ ///
+ /// Gets or sets a value indicating whether this triggers only once.
+ ///
+ /// true if this triggers only once; otherwise, false.
+ public bool SingleVisit { get; set; } = false;
+
+ ///
+ /// Gets or sets a mask indicating the kingdom alliances which are allowed to trigger this event.
+ ///
+ /// The kingdom alliances which are allowed to trigger this event.
+ public MapKingdomColor AllowedKingdoms { get; set; } = MapKingdomColor.All;
+
+ ///
+ /// Gets or sets the message displayed to the player upon triggering this event.
+ ///
+ /// The message displayed to the player upon triggering this event.
+ public string Message { get; set; } = null;
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapHero.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapHero.cs
new file mode 100644
index 00000000..e51e115b
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapHero.cs
@@ -0,0 +1,45 @@
+//
+// MapHero.cs - represents a hero on a map
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+
+namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
+{
+ public class MapHero : MapItem
+ {
+ public bool HasCustomTroops { get; set; } = false;
+
+ public bool HasCustomName { get; set; } = false;
+ public string Name { get; set; } = null;
+
+ public MapArmyMonster.MapArmyMonsterCollection Monsters { get; } = new MapArmyMonster.MapArmyMonsterCollection();
+ public MapArtifact.MapArtifactCollection Artifacts { get; } = new MapArtifact.MapArtifactCollection();
+
+ public bool HasCustomSkills { get; set; } = false;
+ public HeroSkill.HeroSkillCollection Skills { get; } = new HeroSkill.HeroSkillCollection();
+
+ public bool HasCustomPortrait { get; set; }
+ public byte CustomPortraitIndex { get; set; }
+
+ public uint Experience { get; set; }
+
+ public bool Patrol { get; set; } = false;
+ public byte PatrolSquareCount { get; set; } = 0;
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapItem.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapItem.cs
new file mode 100644
index 00000000..81c85277
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapItem.cs
@@ -0,0 +1,33 @@
+//
+// MapItem.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
+{
+ public abstract class MapItem
+ {
+ public class MapItemCollection
+ : System.Collections.ObjectModel.Collection
+ {
+
+ }
+
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapItemType.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapItemType.cs
new file mode 100644
index 00000000..3328be5d
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapItemType.cs
@@ -0,0 +1,32 @@
+//
+// MapItemType.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
+{
+ public enum MapItemType
+ {
+ Monster = 0x16,
+ Castle = 0x46,
+ Hero = 0x4C,
+
+ Unknown1 = 0xC3
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapObjectModel.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapObjectModel.cs
index d9c573b0..8c21f29a 100644
--- a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapObjectModel.cs
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapObjectModel.cs
@@ -64,6 +64,9 @@ namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
/// The win conditions.
public MapWinCondition WinConditions { get; set; } = MapWinCondition.None;
+ public MapWinCondition ComputerAlsoWins { get; set; } = MapWinCondition.None;
+ public bool AllowNormalVictory { get; set; } = false;
+
///
/// Indicates the condition(s) required to lose a game using this map.
///
@@ -74,5 +77,8 @@ namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
public string Description { get; set; } = String.Empty;
public MapTile.MapTileCollection Tiles { get; } = new MapTile.MapTileCollection();
+ public MapItem.MapItemCollection Items { get; } = new MapItem.MapItemCollection();
+
+ public byte ObeliskCount { get; set; } = 0;
}
}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapResourceType.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapResourceType.cs
new file mode 100644
index 00000000..c08b4d77
--- /dev/null
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapResourceType.cs
@@ -0,0 +1,39 @@
+//
+// MapResourceType.cs
+//
+// Author:
+// Michael Becker
+//
+// Copyright (c) 2020 Mike Becker's Software
+//
+// 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 3 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, see .
+using System;
+namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
+{
+ public enum MapResourceType
+ {
+ Wood = 0x00,
+ Mercury,
+ Ore,
+ Sulfur,
+ Crystal,
+ Gems,
+ Gold,
+
+ Lighthouse = 0x64,
+ DragonCity = 0x65,
+
+ AbandonedMine = 0x67
+ }
+}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapTile.cs b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapTile.cs
index b8e647ce..b54f0a47 100644
--- a/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapTile.cs
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/ObjectModels/NewWorldComputing/Map/MapTile.cs
@@ -36,5 +36,16 @@ namespace UniversalEditor.ObjectModels.NewWorldComputing.Map
///
/// The type of the ground.
public MapGroundType GroundType { get; set; } = MapGroundType.Unknown;
- }
+ public byte ObjectName1 { get; set; }
+ public byte IndexName1 { get; set; }
+ public byte Quantity1 { get; set; }
+ public byte Quantity2 { get; set; }
+ public byte ObjectName2 { get; set; }
+ public byte IndexName2 { get; set; }
+ public byte Shape { get; set; }
+ public byte GeneralObject { get; set; }
+ public ushort IndexAddon { get; set; }
+ public uint UniqNumber1 { get; set; }
+ public uint UniqNumber2 { get; set; }
+ }
}
diff --git a/Plugins/UniversalEditor.Plugins.NewWorldComputing/UniversalEditor.Plugins.NewWorldComputing.csproj b/Plugins/UniversalEditor.Plugins.NewWorldComputing/UniversalEditor.Plugins.NewWorldComputing.csproj
index ad288368..ca45878d 100644
--- a/Plugins/UniversalEditor.Plugins.NewWorldComputing/UniversalEditor.Plugins.NewWorldComputing.csproj
+++ b/Plugins/UniversalEditor.Plugins.NewWorldComputing/UniversalEditor.Plugins.NewWorldComputing.csproj
@@ -85,6 +85,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -126,6 +145,8 @@
+
+