#region References
using System;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
#endregion
namespace Ultima
{
///
/// Represents land tile data.
///
///
///
public struct LandData
{
private string m_Name;
private short m_TexID;
private TileFlag m_Flags;
private int m_Unk1;
public LandData(string name, int TexID, TileFlag flags, int unk1)
{
m_Name = name;
m_TexID = (short)TexID;
m_Flags = flags;
m_Unk1 = unk1;
}
public unsafe LandData(NewLandTileDataMul mulstruct)
{
m_TexID = mulstruct.texID;
m_Flags = (TileFlag)mulstruct.flags;
m_Unk1 = mulstruct.unk1;
m_Name = TileData.ReadNameString(mulstruct.name);
}
public unsafe LandData(OldLandTileDataMul mulstruct)
{
m_TexID = mulstruct.texID;
m_Flags = (TileFlag)mulstruct.flags;
m_Unk1 = 0;
m_Name = TileData.ReadNameString(mulstruct.name);
}
///
/// Gets the name of this land tile.
///
public string Name { get { return m_Name; } set { m_Name = value; } }
///
/// Gets the Texture ID of this land tile.
///
public short TextureID { get { return m_TexID; } set { m_TexID = value; } }
///
/// Gets a bitfield representing the 32 individual flags of this land tile.
///
public TileFlag Flags { get { return m_Flags; } set { m_Flags = value; } }
///
/// Gets a new UOHSA Unknown Int
///
public int Unk1 { get { return m_Unk1; } set { m_Unk1 = value; } }
public void ReadData(string[] split)
{
int i = 1;
m_Name = split[i++];
m_TexID = (short)TileData.ConvertStringToInt(split[i++]);
m_Unk1 = TileData.ConvertStringToInt(split[i++]);
m_Flags = 0;
int temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Background;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Weapon;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Transparent;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Translucent;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Wall;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Damaging;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Impassable;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Wet;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Unknown1;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Surface;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Bridge;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Generic;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Window;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.NoShoot;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.ArticleA;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.ArticleAn;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Internal;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Foliage;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.PartialHue;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Unknown2;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Map;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Container;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Wearable;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.LightSource;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Animation;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.HoverOver;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Unknown3;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Armor;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Roof;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.Door;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.StairBack;
}
temp = Convert.ToByte(split[i++]);
if (temp != 0)
{
m_Flags |= TileFlag.StairRight;
}
}
}
///
/// Represents item tile data.
///
///
///
public struct ItemData
{
internal string m_Name;
internal TileFlag m_Flags;
internal int m_Unk1;
internal byte m_Weight;
internal byte m_Quality;
internal byte m_Quantity;
internal byte m_Value;
internal byte m_Height;
internal short m_Animation;
internal byte m_Hue;
internal byte m_StackOffset;
internal short m_MiscData;
internal byte m_Unk2;
internal byte m_Unk3;
public ItemData(
string name,
TileFlag flags,
int unk1,
int weight,
int quality,
int quantity,
int value,
int height,
int anim,
int hue,
int stackingoffset,
int MiscData,
int unk2,
int unk3)
{
m_Name = name;
m_Flags = flags;
m_Unk1 = unk1;
m_Weight = (byte)weight;
m_Quality = (byte)quality;
m_Quantity = (byte)quantity;
m_Value = (byte)value;
m_Height = (byte)height;
m_Animation = (short)anim;
m_Hue = (byte)hue;
m_StackOffset = (byte)stackingoffset;
m_MiscData = (short)MiscData;
m_Unk2 = (byte)unk2;
m_Unk3 = (byte)unk3;
}
public unsafe ItemData(NewItemTileDataMul mulstruct)
{
m_Name = TileData.ReadNameString(mulstruct.name);
m_Flags = (TileFlag)mulstruct.flags;
m_Unk1 = mulstruct.unk1;
m_Weight = mulstruct.weight;
m_Quality = mulstruct.quality;
m_Quantity = mulstruct.quantity;
m_Value = mulstruct.value;
m_Height = mulstruct.height;
m_Animation = mulstruct.anim;
m_Hue = mulstruct.hue;
m_StackOffset = mulstruct.stackingoffset;
m_MiscData = mulstruct.miscdata;
m_Unk2 = mulstruct.unk2;
m_Unk3 = mulstruct.unk3;
}
public unsafe ItemData(OldItemTileDataMul mulstruct)
{
m_Name = TileData.ReadNameString(mulstruct.name);
m_Flags = (TileFlag)mulstruct.flags;
m_Unk1 = 0;
m_Weight = mulstruct.weight;
m_Quality = mulstruct.quality;
m_Quantity = mulstruct.quantity;
m_Value = mulstruct.value;
m_Height = mulstruct.height;
m_Animation = mulstruct.anim;
m_Hue = mulstruct.hue;
m_StackOffset = mulstruct.stackingoffset;
m_MiscData = mulstruct.miscdata;
m_Unk2 = mulstruct.unk2;
m_Unk3 = mulstruct.unk3;
}
///
/// Gets the name of this item.
///
public string Name { get { return m_Name; } set { m_Name = value; } }
///
/// Gets the animation body index of this item.
///
///
public short Animation { get { return m_Animation; } set { m_Animation = value; } }
///
/// Gets a bitfield representing the 32 individual flags of this item.
///
///
public TileFlag Flags { get { return m_Flags; } set { m_Flags = value; } }
///
/// Gets an unknown new UOAHS int
///
public int Unk1 { get { return m_Unk1; } set { m_Unk1 = value; } }
///
/// Whether or not this item is flagged as ''.
///
///
public bool Background { get { return ((m_Flags & TileFlag.Background) != 0); } }
///
/// Whether or not this item is flagged as ''.
///
///
public bool Bridge { get { return ((m_Flags & TileFlag.Bridge) != 0); } }
///
/// Whether or not this item is flagged as ''.
///
///
public bool Impassable { get { return ((m_Flags & TileFlag.Impassable) != 0); } }
///
/// Whether or not this item is flagged as ''.
///
///
public bool Surface { get { return ((m_Flags & TileFlag.Surface) != 0); } }
///
/// Gets the weight of this item.
///
public byte Weight { get { return m_Weight; } set { m_Weight = value; } }
///
/// Gets the 'quality' of this item. For wearable items, this will be the layer.
///
public byte Quality { get { return m_Quality; } set { m_Quality = value; } }
///
/// Gets the 'quantity' of this item.
///
public byte Quantity { get { return m_Quantity; } set { m_Quantity = value; } }
///
/// Gets the 'value' of this item.
///
public byte Value { get { return m_Value; } set { m_Value = value; } }
///
/// Gets the Hue of this item.
///
public byte Hue { get { return m_Hue; } set { m_Hue = value; } }
///
/// Gets the stackingoffset of this item. (If flag Generic)
///
public byte StackingOffset { get { return m_StackOffset; } set { m_StackOffset = value; } }
///
/// Gets the height of this item.
///
public byte Height { get { return m_Height; } set { m_Height = value; } }
///
/// Gets the MiscData of this item. (old UO Demo weapontemplate definition) (Unk1)
///
public short MiscData { get { return m_MiscData; } set { m_MiscData = value; } }
///
/// Gets the unk2 of this item.
///
public byte Unk2 { get { return m_Unk2; } set { m_Unk2 = value; } }
///
/// Gets the unk3 of this item.
///
public byte Unk3 { get { return m_Unk3; } set { m_Unk3 = value; } }
///
/// Gets the 'calculated height' of this item. For bridges, this will be:
///
/// ( / 2)
///
/// .
///
public int CalcHeight
{
get
{
if ((m_Flags & TileFlag.Bridge) != 0)
{
return m_Height / 2;
}
else
{
return m_Height;
}
}
}
///
/// Whether or not this item is wearable as ''.
///
///
public bool Wearable { get { return ((m_Flags & TileFlag.Wearable) != 0); } }
public void ReadData(string[] split)
{
m_Name = split[1];
m_Weight = Convert.ToByte(split[2]);
m_Quality = Convert.ToByte(split[3]);
m_Animation = (short)TileData.ConvertStringToInt(split[4]);
m_Height = Convert.ToByte(split[5]);
m_Hue = Convert.ToByte(split[6]);
m_Quantity = Convert.ToByte(split[7]);
m_StackOffset = Convert.ToByte(split[8]);
m_MiscData = Convert.ToInt16(split[9]);
m_Unk1 = Convert.ToInt32(split[10]);
m_Unk2 = Convert.ToByte(split[11]);
m_Unk3 = Convert.ToByte(split[12]);
m_Flags = 0;
int temp = Convert.ToByte(split[13]);
if (temp != 0)
{
m_Flags |= TileFlag.Background;
}
temp = Convert.ToByte(split[14]);
if (temp != 0)
{
m_Flags |= TileFlag.Weapon;
}
temp = Convert.ToByte(split[15]);
if (temp != 0)
{
m_Flags |= TileFlag.Transparent;
}
temp = Convert.ToByte(split[16]);
if (temp != 0)
{
m_Flags |= TileFlag.Translucent;
}
temp = Convert.ToByte(split[17]);
if (temp != 0)
{
m_Flags |= TileFlag.Wall;
}
temp = Convert.ToByte(split[18]);
if (temp != 0)
{
m_Flags |= TileFlag.Damaging;
}
temp = Convert.ToByte(split[19]);
if (temp != 0)
{
m_Flags |= TileFlag.Impassable;
}
temp = Convert.ToByte(split[20]);
if (temp != 0)
{
m_Flags |= TileFlag.Wet;
}
temp = Convert.ToByte(split[21]);
if (temp != 0)
{
m_Flags |= TileFlag.Unknown1;
}
temp = Convert.ToByte(split[22]);
if (temp != 0)
{
m_Flags |= TileFlag.Surface;
}
temp = Convert.ToByte(split[23]);
if (temp != 0)
{
m_Flags |= TileFlag.Bridge;
}
temp = Convert.ToByte(split[24]);
if (temp != 0)
{
m_Flags |= TileFlag.Generic;
}
temp = Convert.ToByte(split[25]);
if (temp != 0)
{
m_Flags |= TileFlag.Window;
}
temp = Convert.ToByte(split[26]);
if (temp != 0)
{
m_Flags |= TileFlag.NoShoot;
}
temp = Convert.ToByte(split[27]);
if (temp != 0)
{
m_Flags |= TileFlag.ArticleA;
}
temp = Convert.ToByte(split[28]);
if (temp != 0)
{
m_Flags |= TileFlag.ArticleAn;
}
temp = Convert.ToByte(split[29]);
if (temp != 0)
{
m_Flags |= TileFlag.Internal;
}
temp = Convert.ToByte(split[30]);
if (temp != 0)
{
m_Flags |= TileFlag.Foliage;
}
temp = Convert.ToByte(split[31]);
if (temp != 0)
{
m_Flags |= TileFlag.PartialHue;
}
temp = Convert.ToByte(split[32]);
if (temp != 0)
{
m_Flags |= TileFlag.Unknown2;
}
temp = Convert.ToByte(split[33]);
if (temp != 0)
{
m_Flags |= TileFlag.Map;
}
temp = Convert.ToByte(split[34]);
if (temp != 0)
{
m_Flags |= TileFlag.Container;
}
temp = Convert.ToByte(split[35]);
if (temp != 0)
{
m_Flags |= TileFlag.Wearable;
}
temp = Convert.ToByte(split[36]);
if (temp != 0)
{
m_Flags |= TileFlag.LightSource;
}
temp = Convert.ToByte(split[37]);
if (temp != 0)
{
m_Flags |= TileFlag.Animation;
}
temp = Convert.ToByte(split[38]);
if (temp != 0)
{
m_Flags |= TileFlag.HoverOver;
}
temp = Convert.ToByte(split[39]);
if (temp != 0)
{
m_Flags |= TileFlag.Unknown3;
}
temp = Convert.ToByte(split[40]);
if (temp != 0)
{
m_Flags |= TileFlag.Armor;
}
temp = Convert.ToByte(split[41]);
if (temp != 0)
{
m_Flags |= TileFlag.Roof;
}
temp = Convert.ToByte(split[42]);
if (temp != 0)
{
m_Flags |= TileFlag.Door;
}
temp = Convert.ToByte(split[43]);
if (temp != 0)
{
m_Flags |= TileFlag.StairBack;
}
temp = Convert.ToByte(split[44]);
if (temp != 0)
{
m_Flags |= TileFlag.StairRight;
}
}
}
///
/// An enumeration of 32 different tile flags.
///
///
///
[Flags]
public enum TileFlag : ulong
{
///
/// Nothing is flagged.
///
None = 0x00000000,
///
/// Not yet documented.
///
Background = 0x00000001,
///
/// Not yet documented.
///
Weapon = 0x00000002,
///
/// Not yet documented.
///
Transparent = 0x00000004,
///
/// The tile is rendered with partial alpha-transparency.
///
Translucent = 0x00000008,
///
/// The tile is a wall.
///
Wall = 0x00000010,
///
/// The tile can cause damage when moved over.
///
Damaging = 0x00000020,
///
/// The tile may not be moved over or through.
///
Impassable = 0x00000040,
///
/// Not yet documented.
///
Wet = 0x00000080,
///
/// Unknown.
///
Unknown1 = 0x00000100,
///
/// The tile is a surface. It may be moved over, but not through.
///
Surface = 0x00000200,
///
/// The tile is a stair, ramp, or ladder.
///
Bridge = 0x00000400,
///
/// The tile is stackable
///
Generic = 0x00000800,
///
/// The tile is a window. Like , tiles with this flag block line of sight.
///
Window = 0x00001000,
///
/// The tile blocks line of sight.
///
NoShoot = 0x00002000,
///
/// For single-amount tiles, the string "a " should be prepended to the tile name.
///
ArticleA = 0x00004000,
///
/// For single-amount tiles, the string "an " should be prepended to the tile name.
///
ArticleAn = 0x00008000,
///
/// Not yet documented.
///
Internal = 0x00010000,
///
/// The tile becomes translucent when walked behind. Boat masts also have this flag.
///
Foliage = 0x00020000,
///
/// Only gray pixels will be hued
///
PartialHue = 0x00040000,
///
/// Unknown.
///
Unknown2 = 0x00080000,
///
/// The tile is a map--in the cartography sense. Unknown usage.
///
Map = 0x00100000,
///
/// The tile is a container.
///
Container = 0x00200000,
///
/// The tile may be equiped.
///
Wearable = 0x00400000,
///
/// The tile gives off light.
///
LightSource = 0x00800000,
///
/// The tile is animated.
///
Animation = 0x01000000,
///
/// Gargoyles can fly over
///
HoverOver = 0x02000000,
///
/// Unknown.
///
Unknown3 = 0x04000000,
///
/// Not yet documented.
///
Armor = 0x08000000,
///
/// The tile is a slanted roof.
///
Roof = 0x10000000,
///
/// The tile is a door. Tiles with this flag can be moved through by ghosts and GMs.
///
Door = 0x20000000,
///
/// Not yet documented.
///
StairBack = 0x40000000,
///
/// Not yet documented.
///
StairRight = 0x80000000
}
///
/// Contains lists of land and item tile data.
///
///
///
public static class TileData
{
private static LandData[] m_LandData;
private static ItemData[] m_ItemData;
private static int[] m_HeightTable;
///
/// Gets the list of land tile data.
///
public static LandData[] LandTable { get { return m_LandData; } set { m_LandData = value; } }
///
/// Gets the list of item tile data.
///
public static ItemData[] ItemTable { get { return m_ItemData; } set { m_ItemData = value; } }
public static int[] HeightTable { get { return m_HeightTable; } }
private static readonly byte[] m_StringBuffer = new byte[20];
private static string ReadNameString(BinaryReader bin)
{
bin.Read(m_StringBuffer, 0, 20);
int count;
for (count = 0; count < 20 && m_StringBuffer[count] != 0; ++count)
{
;
}
return Encoding.Default.GetString(m_StringBuffer, 0, count);
}
public static unsafe string ReadNameString(byte* buffer)
{
int count;
for (count = 0; count < 20 && *buffer != 0; ++count)
{
m_StringBuffer[count] = *buffer++;
}
return Encoding.Default.GetString(m_StringBuffer, 0, count);
}
private static int[] landheader;
private static int[] itemheader;
static TileData()
{
Initialize();
}
public static unsafe void Initialize()
{
string filePath = Files.GetFilePath("tiledata.mul");
if (filePath != null)
{
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
bool useNeWTileDataFormat = Art.IsUOAHS();
landheader = new int[512];
int j = 0;
m_LandData = new LandData[0x4000];
var buffer = new byte[fs.Length];
GCHandle gc = GCHandle.Alloc(buffer, GCHandleType.Pinned);
long currpos = 0;
try
{
fs.Read(buffer, 0, buffer.Length);
for (int i = 0; i < 0x4000; i += 32)
{
var ptrheader = new IntPtr((long)gc.AddrOfPinnedObject() + currpos);
currpos += 4;
landheader[j++] = (int)Marshal.PtrToStructure(ptrheader, typeof(int));
for (int count = 0; count < 32; ++count)
{
var ptr = new IntPtr((long)gc.AddrOfPinnedObject() + currpos);
if (useNeWTileDataFormat)
{
currpos += sizeof(NewLandTileDataMul);
var cur = (NewLandTileDataMul)Marshal.PtrToStructure(ptr, typeof(NewLandTileDataMul));
m_LandData[i + count] = new LandData(cur);
}
else
{
currpos += sizeof(OldLandTileDataMul);
var cur = (OldLandTileDataMul)Marshal.PtrToStructure(ptr, typeof(OldLandTileDataMul));
m_LandData[i + count] = new LandData(cur);
}
}
}
long remaining = buffer.Length - currpos;
int structsize = useNeWTileDataFormat ? sizeof(NewItemTileDataMul) : sizeof(OldItemTileDataMul);
itemheader = new int[(remaining / ((structsize * 32) + 4))];
int itemlength = itemheader.Length * 32;
m_ItemData = new ItemData[itemlength];
m_HeightTable = new int[itemlength];
j = 0;
for (int i = 0; i < itemlength; i += 32)
{
var ptrheader = new IntPtr((long)gc.AddrOfPinnedObject() + currpos);
currpos += 4;
itemheader[j++] = (int)Marshal.PtrToStructure(ptrheader, typeof(int));
for (int count = 0; count < 32; ++count)
{
var ptr = new IntPtr((long)gc.AddrOfPinnedObject() + currpos);
if (useNeWTileDataFormat)
{
currpos += sizeof(NewItemTileDataMul);
var cur = (NewItemTileDataMul)Marshal.PtrToStructure(ptr, typeof(NewItemTileDataMul));
m_ItemData[i + count] = new ItemData(cur);
m_HeightTable[i + count] = cur.height;
}
else
{
currpos += sizeof(OldItemTileDataMul);
var cur = (OldItemTileDataMul)Marshal.PtrToStructure(ptr, typeof(OldItemTileDataMul));
m_ItemData[i + count] = new ItemData(cur);
m_HeightTable[i + count] = cur.height;
}
}
}
}
finally
{
gc.Free();
}
}
}
}
///
/// Saves and to tiledata.mul
///
///
public static void SaveTileData(string FileName)
{
using (var fs = new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.Write))
{
using (var bin = new BinaryWriter(fs))
{
int j = 0;
bool useNewTileDataFormat = Art.IsUOAHS();
for (int i = 0; i < 0x4000; ++i)
{
if ((i & 0x1F) == 0)
{
bin.Write(landheader[j++]); //header
}
bin.Write((int)m_LandData[i].Flags);
if (useNewTileDataFormat)
{
bin.Write(m_LandData[i].Unk1);
}
bin.Write(m_LandData[i].TextureID);
var b = new byte[20];
if (m_LandData[i].Name != null)
{
byte[] bb = Encoding.Default.GetBytes(m_LandData[i].Name);
if (bb.Length > 20)
{
Array.Resize(ref bb, 20);
}
bb.CopyTo(b, 0);
}
bin.Write(b);
}
j = 0;
for (int i = 0; i < m_ItemData.Length; ++i)
{
if ((i & 0x1F) == 0)
{
bin.Write(itemheader[j++]); // header
}
bin.Write((int)m_ItemData[i].Flags);
if (useNewTileDataFormat)
{
bin.Write(m_ItemData[i].Unk1);
}
bin.Write(m_ItemData[i].Weight);
bin.Write(m_ItemData[i].Quality);
bin.Write(m_ItemData[i].MiscData);
bin.Write(m_ItemData[i].Unk2);
bin.Write(m_ItemData[i].Quantity);
bin.Write(m_ItemData[i].Animation);
bin.Write(m_ItemData[i].Unk3);
bin.Write(m_ItemData[i].Hue);
bin.Write(m_ItemData[i].StackingOffset); //unk4
bin.Write(m_ItemData[i].Value); //unk5
bin.Write(m_ItemData[i].Height);
var b = new byte[20];
if (m_ItemData[i].Name != null)
{
byte[] bb = Encoding.Default.GetBytes(m_ItemData[i].Name);
if (bb.Length > 20)
{
Array.Resize(ref bb, 20);
}
bb.CopyTo(b, 0);
}
bin.Write(b);
}
}
}
}
///
/// Exports to csv file
///
///
public static void ExportItemDataToCSV(string FileName)
{
using (
var Tex = new StreamWriter(
new FileStream(FileName, FileMode.Create, FileAccess.ReadWrite), Encoding.GetEncoding(1252)))
{
Tex.Write(
"ID;Name;Weight/Quantity;Layer/Quality;Gump/AnimID;Height;Hue;Class/Quantity;StackingOffset;MiscData;Unknown1;Unknown2;Unknown3");
Tex.Write(";Background;Weapon;Transparent;Translucent;Wall;Damage;Impassible;Wet;Unknow1");
Tex.Write(";Surface;Bridge;Generic;Window;NoShoot;PrefixA;PrefixAn;Internal;Foliage;PartialHue");
Tex.Write(";Unknow2;Map;Container/Height;Wearable;Lightsource;Animation;HoverOver");
Tex.WriteLine(";Unknow3;Armor;Roof;Door;StairBack;StairRight");
for (int i = 0; i < m_ItemData.Length; ++i)
{
ItemData tile = m_ItemData[i];
Tex.Write(String.Format("0x{0:X4}", i));
Tex.Write(String.Format(";{0}", tile.Name));
Tex.Write(";" + tile.Weight);
Tex.Write(";" + tile.Quality);
Tex.Write(String.Format(";0x{0:X4}", tile.Animation));
Tex.Write(";" + tile.Height);
Tex.Write(";" + tile.Hue);
Tex.Write(";" + tile.Quantity);
Tex.Write(";" + tile.StackingOffset);
Tex.Write(";" + tile.MiscData);
Tex.Write(";" + tile.Unk1);
Tex.Write(";" + tile.Unk2);
Tex.Write(";" + tile.Unk3);
Tex.Write(";" + (((tile.Flags & TileFlag.Background) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Weapon) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Transparent) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Translucent) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Wall) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Damaging) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Impassable) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Wet) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Unknown1) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Surface) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Bridge) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Generic) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Window) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.NoShoot) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.ArticleA) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.ArticleAn) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Internal) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Foliage) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.PartialHue) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Unknown2) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Map) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Container) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Wearable) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.LightSource) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Animation) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.HoverOver) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Unknown3) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Armor) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Roof) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Door) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.StairBack) != 0) ? "1" : "0"));
Tex.WriteLine(";" + (((tile.Flags & TileFlag.StairRight) != 0) ? "1" : "0"));
}
}
}
///
/// Exports to csv file
///
///
public static void ExportLandDataToCSV(string FileName)
{
using (var Tex = new StreamWriter(new FileStream(FileName, FileMode.Create, FileAccess.ReadWrite)))
{
Tex.Write("ID;Name;TextureID;HSAUnk1");
Tex.Write(";Background;Weapon;Transparent;Translucent;Wall;Damage;Impassible;Wet;Unknow1");
Tex.Write(";Surface;Bridge;Generic;Window;NoShoot;PrefixA;PrefixAn;Internal;Foliage;PartialHue");
Tex.Write(";Unknow2;Map;Container/Height;Wearable;Lightsource;Animation;HoverOver");
Tex.WriteLine(";Unknow3;Armor;Roof;Door;StairBack;StairRight");
for (int i = 0; i < m_LandData.Length; ++i)
{
LandData tile = m_LandData[i];
Tex.Write(String.Format("0x{0:X4}", i));
Tex.Write(";" + tile.Name);
Tex.Write(";" + String.Format("0x{0:X4}", tile.TextureID));
Tex.Write(";" + tile.Unk1);
Tex.Write(";" + (((tile.Flags & TileFlag.Background) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Weapon) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Transparent) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Translucent) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Wall) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Damaging) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Impassable) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Wet) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Unknown1) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Surface) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Bridge) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Generic) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Window) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.NoShoot) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.ArticleA) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.ArticleAn) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Internal) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Foliage) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.PartialHue) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Unknown2) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Map) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Container) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Wearable) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.LightSource) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Animation) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.HoverOver) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Unknown3) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Armor) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Roof) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.Door) != 0) ? "1" : "0"));
Tex.Write(";" + (((tile.Flags & TileFlag.StairBack) != 0) ? "1" : "0"));
Tex.WriteLine(";" + (((tile.Flags & TileFlag.StairRight) != 0) ? "1" : "0"));
}
}
}
public static int ConvertStringToInt(string text)
{
int result;
if (text.Contains("0x"))
{
string convert = text.Replace("0x", "");
int.TryParse(convert, NumberStyles.HexNumber, null, out result);
}
else
{
int.TryParse(text, NumberStyles.Integer, null, out result);
}
return result;
}
public static void ImportItemDataFromCSV(string FileName)
{
if (!File.Exists(FileName))
{
return;
}
using (var sr = new StreamReader(FileName))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if ((line = line.Trim()).Length == 0 || line.StartsWith("#"))
{
continue;
}
if (line.StartsWith("ID;"))
{
continue;
}
try
{
string[] split = line.Split(';');
if (split.Length < 45)
{
continue;
}
int id = ConvertStringToInt(split[0]);
m_ItemData[id].ReadData(split);
}
catch
{ }
}
}
}
public static void ImportLandDataFromCSV(string FileName)
{
if (!File.Exists(FileName))
{
return;
}
using (var sr = new StreamReader(FileName))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if ((line = line.Trim()).Length == 0 || line.StartsWith("#"))
{
continue;
}
if (line.StartsWith("ID;"))
{
continue;
}
try
{
string[] split = line.Split(';');
if (split.Length < 36)
{
continue;
}
int id = ConvertStringToInt(split[0]);
m_LandData[id].ReadData(split);
}
catch
{ }
}
}
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct OldLandTileDataMul
{
public int flags;
public short texID;
public fixed byte name [20];
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct NewLandTileDataMul
{
public int flags;
public int unk1;
public short texID;
public fixed byte name [20];
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct OldItemTileDataMul
{
public int flags;
public byte weight;
public byte quality;
public short miscdata;
public byte unk2;
public byte quantity;
public short anim;
public byte unk3;
public byte hue;
public byte stackingoffset;
public byte value;
public byte height;
public fixed byte name [20];
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct NewItemTileDataMul
{
public int flags;
public int unk1;
public byte weight;
public byte quality;
public short miscdata;
public byte unk2;
public byte quantity;
public short anim;
public byte unk3;
public byte hue;
public byte stackingoffset;
public byte value;
public byte height;
public fixed byte name [20];
}
}