public override bool Compile(Uri baseUri, BinaryAsset asset, XmlNode node, GameDefinition game, string trace, ref int position, out string ErrorDescription)
        {
            if (IsVoid)
            {
                int count = 4 - (position & 3);
                if (count != 0)
                {
                    if (Default != null)
                    {
                        for (int idx = 0; idx < count; ++idx)
                        {
                            asset.Content[position++ + idx] = byte.Parse(Default);
                        }
                    }
                    else
                    {
                        position += count;
                    }
                }
                ErrorDescription = string.Empty;
                return(true);
            }
            bool isFound = false;

            if (IsAttribute)
            {
                string value = null;
                foreach (XmlAttribute attribute in node.Attributes)
                {
                    if (attribute.Name == id)
                    {
                        isFound = true;
                        value   = attribute.Value;
                        break;
                    }
                }
                if (value == null && Default != null)
                {
                    value = Default;
                }
                switch (AssetType)
                {
                case String:
                    if (value == null)
                    {
                        position += 8;
                    }
                    else
                    {
                        int stringLength = value.Length;
                        FileHelper.SetInt(stringLength, position, asset.Content);
                        position     += 4;
                        stringLength += 4 - (stringLength & 3);
                        BinaryAsset stringAsset = new BinaryAsset(stringLength);
                        FileHelper.SetString(value, 0, stringAsset.Content);
                        asset.SubAssets.Add(position, stringAsset);
                        position += 4;
                    }
                    break;

                case Byte:
                    if (value != null)
                    {
                        FileHelper.SetByte(byte.Parse(value), position, asset.Content);
                    }
                    ++position;
                    break;

                case Angle:
                    if (value != null)
                    {
                        Types.Angle angle = new Types.Angle(value);
                        FileHelper.SetFloat(angle.Value, position, asset.Content);
                    }
                    position += 4;
                    break;

                case Percentage:
                    if (value != null)
                    {
                        Types.Percentage percentage = new Types.Percentage(value);
                        FileHelper.SetFloat(percentage.Value, position, asset.Content);
                    }
                    position += 4;
                    break;

                case SageBool:
                    if (value != null)
                    {
                        Types.SageBool sageBool = new Types.SageBool(value);
                        FileHelper.SetBool(sageBool.Value, position, asset.Content);
                    }
                    ++position;
                    break;

                case SageInt:
                    if (value != null)
                    {
                        Types.SageInt sageInt = new Types.SageInt(value);
                        FileHelper.SetInt(sageInt.Value, position, asset.Content);
                    }
                    position += 4;
                    break;

                case SageReal:
                    if (value != null)
                    {
                        Types.SageReal sageReal = new Types.SageReal(value);
                        FileHelper.SetFloat(sageReal.Value, position, asset.Content);
                    }
                    position += 4;
                    break;

                case SageUnsignedInt:
                    if (value != null)
                    {
                        Types.SageUnsignedInt sageUInt = new Types.SageUnsignedInt(value);
                        FileHelper.SetUInt(sageUInt.Value, position, asset.Content);
                    }
                    position += 4;
                    break;

                case SageUnsignedShort:
                    if (value != null)
                    {
                        Types.SageUnsignedShort sageUShort = new Types.SageUnsignedShort(value);
                        FileHelper.SetUShort(sageUShort.Value, position, asset.Content);
                    }
                    position += 2;
                    break;

                case Time:
                    if (value != null)
                    {
                        Types.Time time = new Types.Time(value);
                        FileHelper.SetFloat(time.Value, position, asset.Content);
                    }
                    position += 4;
                    break;

                case Velocity:
                    if (value != null)
                    {
                        Types.Velocity velocity = new Types.Velocity(value);
                        FileHelper.SetFloat(velocity.Value, position, asset.Content);
                    }
                    position += 4;
                    break;

                default:
                    bool isImplemented = false;
                    foreach (BaseAssetType baseAssetType in game.Assets.AssetTypes)
                    {
                        if (baseAssetType.id == AssetType)
                        {
                            isImplemented = true;
                            Type assetTypeType = baseAssetType.GetType();
                            if (assetTypeType == typeof(EnumAssetType))
                            {
                                if (value != null)
                                {
                                    EnumAssetType enumAsset = baseAssetType as EnumAssetType;
                                    FileHelper.SetUInt(enumAsset.GetValue(value), position, asset.Content);
                                }
                                position += 4;
                                break;
                            }
                            if (assetTypeType == typeof(FlagsAssetType))
                            {
                                FlagsAssetType flagsAsset = baseAssetType as FlagsAssetType;
                                int            numSpans   = flagsAsset.NumSpans(game);
                                if (value != null)
                                {
                                    string[] flags = value.Split(' ');
                                    if (flagsAsset.GetUsingAll(game) && flags[0] == "ALL")
                                    {
                                        for (int idx = 0; idx < numSpans; ++idx)
                                        {
                                            FileHelper.SetUInt(0xFFFFFFFF, position + (idx << 2), asset.Content);
                                        }
                                    }
                                    else
                                    {
                                        foreach (string flag in flags)
                                        {
                                            uint[] spanAndBit = flagsAsset.GetValue(flag, game);
                                            if (spanAndBit != null)
                                            {
                                                FileHelper.SetUInt(FileHelper.GetUInt((int)(position + (spanAndBit[0] << 2)), asset.Content) | spanAndBit[1],
                                                                   (int)(position + (spanAndBit[0] << 2)), asset.Content);
                                            }
                                        }
                                    }
                                }
                                position += numSpans << 2;
                                break;
                            }
                            else
                            {
                                ErrorDescription = string.Format(NotSupportedAssetTypeAttribute, typeof(EntryType).Name, AssetType);
                                return(false);
                            }
                        }
                    }
                    if (!isImplemented)
                    {
                        ErrorDescription = string.Format(NotImplementedAssetTypeAttribute, typeof(EntryType).Name, AssetType);
                        return(false);
                    }
                    break;
                }
            }
            else
            {
                foreach (XmlNode childNode in node.ChildNodes)
                {
                    if (childNode.Name == id)
                    {
                        isFound = true;
                        if (AssetType != String &&
                            AssetType != Byte &&
                            AssetType != Angle &&
                            AssetType != Percentage &&
                            AssetType != SageBool &&
                            AssetType != SageInt &&
                            AssetType != SageReal &&
                            AssetType != SageUnsignedInt &&
                            AssetType != SageUnsignedShort &&
                            AssetType != Time &&
                            AssetType != Velocity)
                        {
                            foreach (BaseAssetType baseAssetType in game.Assets.AssetTypes)
                            {
                                if (baseAssetType.id == AssetType)
                                {
                                    AssetType baseAsset = baseAssetType as AssetType;
                                    if (baseAsset.Entries != null)
                                    {
                                        trace += '.' + id;
                                        foreach (BaseEntryType baseEntryType in baseAsset.Entries)
                                        {
                                            if (!baseEntryType.Compile(baseUri, asset, childNode, game, trace, ref position, out ErrorDescription))
                                            {
                                                return(false);
                                            }
                                        }
                                    }
                                    ErrorDescription = string.Empty;
                                    return(true);
                                }
                            }
                            ErrorDescription = string.Format(NotImplementedAssetTypeElement, typeof(EntryType).Name, AssetType);
                            return(false);
                        }
                        string value = childNode.InnerXml;
                        if (value == string.Empty && Default != null)
                        {
                            value = Default;
                        }
                        switch (AssetType)
                        {
                        case String:
                            int stringLength = value.Length;
                            FileHelper.SetInt(stringLength, position, asset.Content);
                            position     += 4;
                            stringLength += 4 - (stringLength & 3);
                            BinaryAsset stringAsset = new BinaryAsset(stringLength);
                            FileHelper.SetString(value, 0, stringAsset.Content);
                            asset.SubAssets.Add(position, stringAsset);
                            position += 4;
                            break;

                        case Byte:
                            if (value != string.Empty)
                            {
                                FileHelper.SetByte(byte.Parse(value), position, asset.Content);
                            }
                            ++position;
                            break;

                        case Angle:
                            if (value != string.Empty)
                            {
                                Types.Angle angle = new Types.Angle(value);
                                FileHelper.SetFloat(angle.Value, position, asset.Content);
                            }
                            position += 4;
                            break;

                        case Percentage:
                            if (value != string.Empty)
                            {
                                Types.Percentage percentage = new Types.Percentage(value);
                                FileHelper.SetFloat(percentage.Value, position, asset.Content);
                            }
                            position += 4;
                            break;

                        case SageBool:
                            if (value != string.Empty)
                            {
                                Types.SageBool sageBool = new Types.SageBool(value);
                                FileHelper.SetBool(sageBool.Value, position, asset.Content);
                            }
                            ++position;
                            break;

                        case SageInt:
                            if (value != string.Empty)
                            {
                                Types.SageInt sageInt = new Types.SageInt(value);
                                FileHelper.SetInt(sageInt.Value, position, asset.Content);
                            }
                            position += 4;
                            break;

                        case SageReal:
                            if (value != string.Empty)
                            {
                                Types.SageReal sageReal = new Types.SageReal(value);
                                FileHelper.SetFloat(sageReal.Value, position, asset.Content);
                            }
                            position += 4;
                            break;

                        case SageUnsignedInt:
                            if (value != string.Empty)
                            {
                                Types.SageUnsignedInt sageUInt = new Types.SageUnsignedInt(value);
                                FileHelper.SetUInt(sageUInt.Value, position, asset.Content);
                            }
                            position += 4;
                            break;

                        case SageUnsignedShort:
                            if (value != string.Empty)
                            {
                                Types.SageUnsignedShort sageUShort = new Types.SageUnsignedShort(value);
                                FileHelper.SetUShort(sageUShort.Value, position, asset.Content);
                            }
                            position += 2;
                            break;

                        case Time:
                            if (value != string.Empty)
                            {
                                Types.Time time = new Types.Time(value);
                                FileHelper.SetFloat(time.Value, position, asset.Content);
                            }
                            position += 4;
                            break;

                        case Velocity:
                            if (value != string.Empty)
                            {
                                Types.Velocity velocity = new Types.Velocity(value);
                                FileHelper.SetFloat(velocity.Value, position, asset.Content);
                            }
                            position += 4;
                            break;
                        }
                        break;
                    }
                }
                if (!isFound)
                {
                    if (AssetType != String &&
                        AssetType != Byte &&
                        AssetType != Angle &&
                        AssetType != Percentage &&
                        AssetType != SageBool &&
                        AssetType != SageInt &&
                        AssetType != SageReal &&
                        AssetType != SageUnsignedInt &&
                        AssetType != SageUnsignedShort &&
                        AssetType != Time &&
                        AssetType != Velocity)
                    {
                        foreach (BaseAssetType baseAssetType in game.Assets.AssetTypes)
                        {
                            if (baseAssetType.id == AssetType)
                            {
                                AssetType baseAsset = baseAssetType as AssetType;
                                if (Default != null && baseAsset.Entries != null)
                                {
                                    XmlDocument fakeDocument = new XmlDocument();
                                    XmlNode     fakeNode     = fakeDocument.CreateElement(id);
                                    trace += '.' + id;
                                    string[] defaults = Default.Split(',');
                                    int      idx      = 0;
                                    if (baseAsset.Entries[idx].GetType() == typeof(EntryInheritanceType))
                                    {
                                        string inheritanceAssetType = (baseAsset.Entries[idx] as EntryInheritanceType).AssetType;
                                        foreach (BaseAssetType baseInheritedAssetType in game.Assets.AssetTypes)
                                        {
                                            if (baseInheritedAssetType.id == inheritanceAssetType)
                                            {
                                                AssetType inheritedBaseAsset = baseInheritedAssetType as AssetType;
                                                while (idx < defaults.Length)
                                                {
                                                    XmlAttribute fakeAttribute = fakeDocument.CreateAttribute(inheritedBaseAsset.Entries[idx].id);
                                                    fakeAttribute.Value = defaults[idx];
                                                    fakeNode.Attributes.Append(fakeAttribute);
                                                    ++idx;
                                                }
                                                break;
                                            }
                                        }
                                        int idy = 1;
                                        while (idx < defaults.Length)
                                        {
                                            XmlAttribute fakeAttribute = fakeDocument.CreateAttribute(baseAsset.Entries[idy].id);
                                            fakeAttribute.Value = defaults[idx];
                                            fakeNode.Attributes.Append(fakeAttribute);
                                            ++idx;
                                            ++idy;
                                        }
                                    }
                                    else
                                    {
                                        while (idx < defaults.Length)
                                        {
                                            XmlAttribute fakeAttribute = fakeDocument.CreateAttribute(baseAsset.Entries[idx].id);
                                            fakeAttribute.Value = defaults[idx];
                                            fakeNode.Attributes.Append(fakeAttribute);
                                            ++idx;
                                        }
                                    }
                                    foreach (BaseEntryType baseEntryType in baseAsset.Entries)
                                    {
                                        if (!baseEntryType.Compile(baseUri, asset, fakeNode, game, trace, ref position, out ErrorDescription))
                                        {
                                            return(false);
                                        }
                                    }
                                }
                                else
                                {
                                    position += baseAsset.GetLength(game);
                                }
                                break;
                            }
                        }
                    }
                    else
                    {
                        switch (AssetType)
                        {
                        case String:
                            position += 8;
                            break;

                        case Angle:
                        case Percentage:
                        case SageInt:
                        case SageReal:
                        case SageUnsignedInt:
                        case Time:
                        case Velocity:
                            position += 4;
                            break;

                        case SageUnsignedShort:
                            position += 2;
                            break;

                        case Byte:
                        case SageBool:
                            ++position;
                            break;
                        }
                    }
                    //ErrorDescription = string.Format(NotRequiredNotFoundElement, id, trace);
                    //return false;
                }
            }
            if (!isFound && IsRequired)
            {
                if (IsAttribute)
                {
                    ErrorDescription = string.Format(RequiredNotFoundAttribute, id, trace);
                }
                else
                {
                    ErrorDescription = string.Format(RequiredNotFoundElement, id, trace);
                }
                return(false);
            }
            ErrorDescription = string.Empty;
            return(true);
        }
        public override bool Compile(Uri baseUri, BinaryAsset asset, XmlNode node, GameDefinition game, string trace, ref int position, out string ErrorDescription)
        {
            bool isFound = false;

            if (IsAttribute)
            {
                foreach (XmlAttribute attribute in node.Attributes)
                {
                    if (attribute.Name == id)
                    {
                        isFound = true;
                        string value;
                        switch (AssetType)
                        {
                        case String:
                            value = attribute.Value;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(8);
                                asset.SubAssets.Add(position, assetRelocation);
                                int stringLength = value.Length;
                                FileHelper.SetInt(stringLength, 0, assetRelocation.Content);
                                stringLength += 4 - (stringLength & 3);
                                BinaryAsset stringAsset = new BinaryAsset(stringLength);
                                FileHelper.SetString(value, 0, stringAsset.Content);
                                assetRelocation.SubAssets.Add(4, stringAsset);
                            }
                            break;

                        case Byte:
                            value = attribute.Value;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                FileHelper.SetByte(byte.Parse(value), 0, assetRelocation.Content);
                            }
                            break;

                        case Angle:
                            value = attribute.Value;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.Angle angle = new Types.Angle(value);
                                FileHelper.SetFloat(angle.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case Percentage:
                            value = attribute.Value;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.Percentage percentage = new Types.Percentage(value);
                                FileHelper.SetFloat(percentage.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case SageBool:
                            value = attribute.Value;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.SageBool sageBool = new Types.SageBool(value);
                                FileHelper.SetBool(sageBool.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case SageInt:
                            value = attribute.Value;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.SageInt sageInt = new Types.SageInt(value);
                                FileHelper.SetInt(sageInt.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case SageReal:
                            value = attribute.Value;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.SageReal sageReal = new Types.SageReal(value);
                                FileHelper.SetFloat(sageReal.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case SageUnsignedInt:
                            value = attribute.Value;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.SageUnsignedInt sageUInt = new Types.SageUnsignedInt(value);
                                FileHelper.SetUInt(sageUInt.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case SageUnsignedShort:
                            value = attribute.Value;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.SageUnsignedShort sageUShort = new Types.SageUnsignedShort(value);
                                FileHelper.SetUShort(sageUShort.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case Time:
                            value = attribute.Value;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.Time time = new Types.Time(value);
                                FileHelper.SetFloat(time.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case Velocity:
                            value = attribute.Value;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.Velocity velocity = new Types.Velocity(value);
                                FileHelper.SetFloat(velocity.Value, 0, assetRelocation.Content);
                            }
                            break;
                        }
                        foreach (BaseAssetType relocationBaseAsset in game.Assets.AssetTypes)
                        {
                            if (relocationBaseAsset.id == AssetType)
                            {
                                int         length          = relocationBaseAsset.GetLength(game);
                                BinaryAsset assetRelocation = new BinaryAsset(length);
                                asset.SubAssets.Add(position, assetRelocation);
                                trace += '.' + id;
                                Type assetTypeType = relocationBaseAsset.GetType();
                                int  subPosition   = 0;
                                if (assetTypeType == typeof(EnumAssetType))
                                {
                                    EnumAssetType enumAsset = relocationBaseAsset as EnumAssetType;
                                    FileHelper.SetUInt(enumAsset.GetValue(attribute.Value.Trim()), subPosition, assetRelocation.Content);
                                    subPosition += 4;
                                }
                                else if (assetTypeType == typeof(FlagsAssetType))
                                {
                                    FlagsAssetType flagsAsset = relocationBaseAsset as FlagsAssetType;
                                    int            numSpans   = flagsAsset.NumSpans(game);
                                    value = attribute.Value.Trim();
                                    if (value.Length > 0)
                                    {
                                        string[] flags = value.Split(new char[] { ' ', '\n', '\r', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                                        foreach (string flag in flags)
                                        {
                                            uint[] spanAndBit = flagsAsset.GetValue(flag, game);
                                            if (spanAndBit != null)
                                            {
                                                FileHelper.SetUInt(FileHelper.GetUInt((int)(subPosition + (spanAndBit[0] << 2)), assetRelocation.Content) | spanAndBit[1],
                                                                   (int)(subPosition + (spanAndBit[0] << 2)), assetRelocation.Content);
                                            }
                                        }
                                    }
                                    subPosition += numSpans << 2;
                                    break;
                                }
                                else
                                {
                                    AssetType relocationAsset = relocationBaseAsset as AssetType;
                                    foreach (BaseEntryType relocationBaseEntry in relocationAsset.Entries)
                                    {
                                        if (!relocationBaseEntry.Compile(baseUri, assetRelocation, attribute, game, trace, ref subPosition, out ErrorDescription))
                                        {
                                            return(false);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                foreach (XmlNode childNode in node.ChildNodes)
                {
                    if (childNode.Name == id)
                    {
                        isFound = true;
                        string value;
                        switch (AssetType)
                        {
                        case String:
                            value = childNode.InnerText;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(8);
                                asset.SubAssets.Add(position, assetRelocation);
                                int stringLength = value.Length;
                                FileHelper.SetInt(stringLength, 0, assetRelocation.Content);
                                stringLength += 4 - (stringLength & 3);
                                BinaryAsset stringAsset = new BinaryAsset(stringLength);
                                FileHelper.SetString(value, 0, stringAsset.Content);
                                assetRelocation.SubAssets.Add(4, stringAsset);
                            }
                            break;

                        case Byte:
                            value = childNode.InnerText;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                FileHelper.SetByte(byte.Parse(value), 0, assetRelocation.Content);
                            }
                            break;

                        case Angle:
                            value = childNode.InnerText;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.Angle angle = new Types.Angle(value);
                                FileHelper.SetFloat(angle.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case Percentage:
                            value = childNode.InnerText;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.Percentage percentage = new Types.Percentage(value);
                                FileHelper.SetFloat(percentage.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case SageBool:
                            value = childNode.InnerText;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.SageBool sageBool = new Types.SageBool(value);
                                FileHelper.SetBool(sageBool.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case SageInt:
                            value = childNode.InnerText;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.SageInt sageInt = new Types.SageInt(value);
                                FileHelper.SetInt(sageInt.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case SageReal:
                            value = childNode.InnerText;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.SageReal sageReal = new Types.SageReal(value);
                                FileHelper.SetFloat(sageReal.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case SageUnsignedInt:
                            value = childNode.InnerText;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.SageUnsignedInt sageUInt = new Types.SageUnsignedInt(value);
                                FileHelper.SetUInt(sageUInt.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case SageUnsignedShort:
                            value = childNode.InnerText;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.SageUnsignedShort sageUShort = new Types.SageUnsignedShort(value);
                                FileHelper.SetUShort(sageUShort.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case Time:
                            value = childNode.InnerText;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.Time time = new Types.Time(value);
                                FileHelper.SetFloat(time.Value, 0, assetRelocation.Content);
                            }
                            break;

                        case Velocity:
                            value = childNode.InnerText;
                            if (value != string.Empty)
                            {
                                BinaryAsset assetRelocation = new BinaryAsset(4);
                                asset.SubAssets.Add(position, assetRelocation);
                                Types.Velocity velocity = new Types.Velocity(value);
                                FileHelper.SetFloat(velocity.Value, 0, assetRelocation.Content);
                            }
                            break;
                        }
                        foreach (BaseAssetType relocationBaseAsset in game.Assets.AssetTypes)
                        {
                            if (relocationBaseAsset.id == AssetType)
                            {
                                int         length          = relocationBaseAsset.GetLength(game);
                                BinaryAsset assetRelocation = new BinaryAsset(length);
                                asset.SubAssets.Add(position, assetRelocation);
                                trace += '.' + id;
                                Type assetTypeType = relocationBaseAsset.GetType();
                                int  subPosition   = 0;
                                if (assetTypeType == typeof(EnumAssetType))
                                {
                                    EnumAssetType enumAsset = relocationBaseAsset as EnumAssetType;
                                    FileHelper.SetUInt(enumAsset.GetValue(childNode.InnerText.Trim()), subPosition, assetRelocation.Content);
                                    subPosition += 4;
                                }
                                else if (assetTypeType == typeof(FlagsAssetType))
                                {
                                    FlagsAssetType flagsAsset = relocationBaseAsset as FlagsAssetType;
                                    int            numSpans   = flagsAsset.NumSpans(game);
                                    value = childNode.InnerText.Trim();
                                    if (value.Length > 0)
                                    {
                                        string[] flags = value.Split(new char[] { ' ', '\n', '\r', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                                        foreach (string flag in flags)
                                        {
                                            uint[] spanAndBit = flagsAsset.GetValue(flag, game);
                                            if (spanAndBit != null)
                                            {
                                                FileHelper.SetUInt(FileHelper.GetUInt((int)(subPosition + (spanAndBit[0] << 2)), assetRelocation.Content) | spanAndBit[1],
                                                                   (int)(subPosition + (spanAndBit[0] << 2)), assetRelocation.Content);
                                            }
                                        }
                                    }
                                    subPosition += numSpans << 2;
                                    break;
                                }
                                else
                                {
                                    AssetType relocationAsset = relocationBaseAsset as AssetType;
                                    foreach (BaseEntryType relocationBaseEntry in relocationAsset.Entries)
                                    {
                                        if (!relocationBaseEntry.Compile(baseUri, assetRelocation, childNode, game, trace, ref subPosition, out ErrorDescription))
                                        {
                                            return(false);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (!isFound && IsRequired)
            {
                if (IsAttribute)
                {
                    ErrorDescription = string.Format(RequiredNotFoundAttribute, id, trace);
                }
                else
                {
                    ErrorDescription = string.Format(RequiredNotFoundElement, id, trace);
                }
                return(false);
            }
            if (!isFound)
            {
                //ErrorDescription = string.Format("Critical Error: {0}.:{1} not found, handling not yet implemented!", typeof(EntryListType).Name, AssetType);
                //return false;
            }
            position        += 4;
            ErrorDescription = string.Empty;
            return(true);
        }
Exemple #3
0
        public override bool Compile(Uri baseUri, BinaryAsset asset, XmlNode node, GameDefinition game, string trace, ref int position, out string ErrorDescription)
        {
            if (IsAttribute)
            {
                bool     isFound = false;
                string[] values  = null;
                foreach (XmlAttribute attribute in node.Attributes)
                {
                    if (attribute.Name == id)
                    {
                        isFound = true;
                        values  = attribute.Value.Split(' ');
                        break;
                    }
                }
                if (isFound)
                {
                    if (values.Length < MinLength)
                    {
                        ErrorDescription = string.Format(LessThenMinElements, trace, MinLength, id);
                        return(false);
                    }
                    if (MaxLength != 0 && values.Length > MaxLength)
                    {
                        ErrorDescription = string.Format(MoreThenMaxElements, trace, MaxLength, id);
                        return(false);
                    }
                    if (values.Length != 0)
                    {
                        FileHelper.SetInt(values.Length, position, asset.Content);
                        position += 4;
                        trace    += '.' + id;
                        BinaryAsset assetList   = null;
                        int         subPosition = 0;
                        switch (AssetType)
                        {
                        case String:
                            assetList = new BinaryAsset(values.Length * 8);
                            asset.SubAssets.Add(position, assetList);
                            foreach (string value in values)
                            {
                                int stringLength = value.Length;
                                FileHelper.SetInt(stringLength, subPosition, assetList.Content);
                                subPosition  += 4;
                                stringLength += 4 - (stringLength & 3);
                                BinaryAsset stringAsset = new BinaryAsset(stringLength);
                                FileHelper.SetString(value, 0, stringAsset.Content);
                                assetList.SubAssets.Add(subPosition, stringAsset);
                                subPosition += 4;
                            }
                            break;

                        case Byte:
                            int byteCount = 4 - (values.Length & 3);
                            if (byteCount == 4)
                            {
                                assetList = new BinaryAsset(values.Length);
                            }
                            else
                            {
                                assetList = new BinaryAsset(values.Length + byteCount);
                            }
                            asset.SubAssets.Add(position, assetList);
                            foreach (string value in values)
                            {
                                FileHelper.SetByte(byte.Parse(value), subPosition, assetList.Content);
                                ++subPosition;
                            }
                            break;

                        case Angle:
                            assetList = new BinaryAsset(values.Length * 4);
                            asset.SubAssets.Add(position, assetList);
                            foreach (string value in values)
                            {
                                Types.Angle angle = new Types.Angle(value);
                                FileHelper.SetFloat(angle.Value, subPosition, assetList.Content);
                                subPosition += 4;
                            }
                            break;

                        case Percentage:
                            assetList = new BinaryAsset(values.Length * 4);
                            asset.SubAssets.Add(position, assetList);
                            foreach (string value in values)
                            {
                                Types.Percentage percentage = new Types.Percentage(value);
                                FileHelper.SetFloat(percentage.Value, subPosition, assetList.Content);
                                subPosition += 4;
                            }
                            break;

                        case SageBool:
                            int sageBoolCount = 4 - (values.Length & 3);
                            if (sageBoolCount == 4)
                            {
                                assetList = new BinaryAsset(values.Length);
                            }
                            else
                            {
                                assetList = new BinaryAsset(values.Length + sageBoolCount);
                            }
                            asset.SubAssets.Add(position, assetList);
                            foreach (string value in values)
                            {
                                Types.SageBool sageBool = new Types.SageBool(value);
                                FileHelper.SetBool(sageBool.Value, subPosition, assetList.Content);
                                ++subPosition;
                            }
                            break;

                        case SageInt:
                            assetList = new BinaryAsset(values.Length * 4);
                            asset.SubAssets.Add(position, assetList);
                            foreach (string value in values)
                            {
                                Types.SageInt sageInt = new Types.SageInt(value);
                                FileHelper.SetInt(sageInt.Value, subPosition, assetList.Content);
                                subPosition += 4;
                            }
                            break;

                        case SageReal:
                            assetList = new BinaryAsset(values.Length * 4);
                            asset.SubAssets.Add(position, assetList);
                            foreach (string value in values)
                            {
                                Types.SageReal sageReal = new Types.SageReal(value);
                                FileHelper.SetFloat(sageReal.Value, subPosition, assetList.Content);
                                subPosition += 4;
                            }
                            break;

                        case SageUnsignedInt:
                            assetList = new BinaryAsset(values.Length * 4);
                            asset.SubAssets.Add(position, assetList);
                            foreach (string value in values)
                            {
                                Types.SageUnsignedInt sageUnsignedInt = new Types.SageUnsignedInt(value);
                                FileHelper.SetUInt(sageUnsignedInt.Value, subPosition, assetList.Content);
                                subPosition += 4;
                            }
                            break;

                        case SageUnsignedShort:
                            int sageUnsignedShortCount = 2 - (values.Length & 1);
                            if (sageUnsignedShortCount == 2)
                            {
                                assetList = new BinaryAsset(values.Length * 2);
                            }
                            else
                            {
                                assetList = new BinaryAsset((values.Length + sageUnsignedShortCount) * 2);
                            }
                            asset.SubAssets.Add(position, assetList);
                            foreach (string value in values)
                            {
                                Types.SageUnsignedShort sageUnsignedShort = new Types.SageUnsignedShort(value);
                                FileHelper.SetUShort(sageUnsignedShort.Value, subPosition, assetList.Content);
                                subPosition += 2;
                            }
                            break;

                        case Time:
                            assetList = new BinaryAsset(values.Length * 4);
                            asset.SubAssets.Add(position, assetList);
                            foreach (string value in values)
                            {
                                Types.Time time = new Types.Time(value);
                                FileHelper.SetFloat(time.Value, subPosition, assetList.Content);
                                subPosition += 4;
                            }
                            break;

                        case Velocity:
                            assetList = new BinaryAsset(values.Length * 4);
                            asset.SubAssets.Add(position, assetList);
                            foreach (string value in values)
                            {
                                Types.Velocity velocity = new Types.Velocity(value);
                                FileHelper.SetFloat(velocity.Value, subPosition, assetList.Content);
                                subPosition += 4;
                            }
                            break;

                        default:
                            foreach (BaseAssetType listBaseAsset in game.Assets.AssetTypes)
                            {
                                if (listBaseAsset.id == AssetType)
                                {
                                    AssetType listAsset = listBaseAsset as AssetType;
                                    assetList = new BinaryAsset(values.Length * listAsset.GetLength(game));
                                    asset.SubAssets.Add(position, assetList);
                                    for (int idx = 0; idx < values.Length; ++idx)
                                    {
                                        XmlDocument fakeDocument  = new XmlDocument();
                                        XmlNode     fakeAttribute = fakeDocument.CreateAttribute(id);
                                        fakeAttribute.Value = values[idx];
                                        foreach (BaseEntryType listBaseEntry in listAsset.Entries)
                                        {
                                            if (!listBaseEntry.Compile(baseUri, assetList, fakeAttribute, game, trace, ref subPosition, out ErrorDescription))
                                            {
                                                return(false);
                                            }
                                        }
                                    }
                                    break;
                                }
                            }
                            break;
                        }
                        position += 4;
                    }
                    else
                    {
                        position += 8;
                    }
                }
                else
                {
                    if (IsRequired)
                    {
                        ErrorDescription = string.Format(RequiredNotFoundAttribute, id, trace);
                        return(false);
                    }
                    position += 8;
                }
            }
            else
            {
                List <XmlNode> nodes = new List <XmlNode>();
                foreach (XmlNode childNode in node.ChildNodes)
                {
                    if (childNode.Name == id)
                    {
                        nodes.Add(childNode);
                    }
                }
                if (nodes.Count < MinLength)
                {
                    ErrorDescription = string.Format(LessThenMinElements, trace, MinLength, id);
                    return(false);
                }
                if (MaxLength != 0 && nodes.Count > MaxLength)
                {
                    ErrorDescription = string.Format(MoreThenMaxElements, trace, MaxLength, id);
                    return(false);
                }
                if (nodes.Count != 0)
                {
                    FileHelper.SetInt(nodes.Count, position, asset.Content);
                    position += 4;
                    trace    += '.' + id;
                    BinaryAsset assetList   = null;
                    int         subPosition = 0;
                    switch (AssetType)
                    {
                    case String:
                        assetList = new BinaryAsset(nodes.Count * 8);
                        asset.SubAssets.Add(position, assetList);
                        for (int idx = 0; idx < nodes.Count; ++idx)
                        {
                            string value        = nodes[idx].InnerText;
                            int    stringLength = value.Length;
                            FileHelper.SetInt(stringLength, subPosition, assetList.Content);
                            subPosition  += 4;
                            stringLength += 4 - (stringLength & 3);
                            BinaryAsset stringAsset = new BinaryAsset(stringLength);
                            FileHelper.SetString(value, 0, stringAsset.Content);
                            assetList.SubAssets.Add(subPosition, stringAsset);
                            subPosition += 4;
                        }
                        break;

                    case Byte:
                        int byteCount = 4 - (nodes.Count & 3);
                        if (byteCount == 4)
                        {
                            assetList = new BinaryAsset(nodes.Count);
                        }
                        else
                        {
                            assetList = new BinaryAsset(nodes.Count + byteCount);
                        }
                        asset.SubAssets.Add(position, assetList);
                        for (int idx = 0; idx < nodes.Count; ++idx)
                        {
                            string value = nodes[idx].InnerText;
                            FileHelper.SetByte(byte.Parse(value), subPosition, assetList.Content);
                            ++subPosition;
                        }
                        break;

                    case Angle:
                        assetList = new BinaryAsset(nodes.Count * 4);
                        asset.SubAssets.Add(position, assetList);
                        for (int idx = 0; idx < nodes.Count; ++idx)
                        {
                            string      value = nodes[idx].InnerText;
                            Types.Angle angle = new Types.Angle(value);
                            FileHelper.SetFloat(angle.Value, subPosition, assetList.Content);
                            subPosition += 4;
                        }
                        break;

                    case Percentage:
                        assetList = new BinaryAsset(nodes.Count * 4);
                        asset.SubAssets.Add(position, assetList);
                        for (int idx = 0; idx < nodes.Count; ++idx)
                        {
                            string           value      = nodes[idx].InnerText;
                            Types.Percentage percentage = new Types.Percentage(value);
                            FileHelper.SetFloat(percentage.Value, subPosition, assetList.Content);
                            subPosition += 4;
                        }
                        break;

                    case SageBool:
                        int sageBoolCount = 4 - (nodes.Count & 3);
                        if (sageBoolCount == 4)
                        {
                            assetList = new BinaryAsset(nodes.Count);
                        }
                        else
                        {
                            assetList = new BinaryAsset(nodes.Count + sageBoolCount);
                        }
                        asset.SubAssets.Add(position, assetList);
                        for (int idx = 0; idx < nodes.Count; ++idx)
                        {
                            string         value    = nodes[idx].InnerText;
                            Types.SageBool sageBool = new Types.SageBool(value);
                            FileHelper.SetBool(sageBool.Value, subPosition, assetList.Content);
                            ++subPosition;
                        }
                        break;

                    case SageInt:
                        assetList = new BinaryAsset(nodes.Count * 4);
                        asset.SubAssets.Add(position, assetList);
                        for (int idx = 0; idx < nodes.Count; ++idx)
                        {
                            string        value   = nodes[idx].InnerText;
                            Types.SageInt sageInt = new Types.SageInt(value);
                            FileHelper.SetInt(sageInt.Value, subPosition, assetList.Content);
                            subPosition += 4;
                        }
                        break;

                    case SageReal:
                        assetList = new BinaryAsset(nodes.Count * 4);
                        asset.SubAssets.Add(position, assetList);
                        for (int idx = 0; idx < nodes.Count; ++idx)
                        {
                            string         value    = nodes[idx].InnerText;
                            Types.SageReal sageReal = new Types.SageReal(value);
                            FileHelper.SetFloat(sageReal.Value, subPosition, assetList.Content);
                            subPosition += 4;
                        }
                        break;

                    case SageUnsignedInt:
                        assetList = new BinaryAsset(nodes.Count * 4);
                        asset.SubAssets.Add(position, assetList);
                        for (int idx = 0; idx < nodes.Count; ++idx)
                        {
                            string value = nodes[idx].InnerText;
                            Types.SageUnsignedInt sageUnsignedInt = new Types.SageUnsignedInt(value);
                            FileHelper.SetUInt(sageUnsignedInt.Value, subPosition, assetList.Content);
                            subPosition += 4;
                        }
                        break;

                    case SageUnsignedShort:
                        int sageUnsignedShortCount = 2 - (nodes.Count & 1);
                        if (sageUnsignedShortCount == 2)
                        {
                            assetList = new BinaryAsset(nodes.Count * 2);
                        }
                        else
                        {
                            assetList = new BinaryAsset((nodes.Count + sageUnsignedShortCount) * 2);
                        }
                        asset.SubAssets.Add(position, assetList);
                        for (int idx = 0; idx < nodes.Count; ++idx)
                        {
                            string value = nodes[idx].InnerText;
                            Types.SageUnsignedShort sageUnsignedShort = new Types.SageUnsignedShort(value);
                            FileHelper.SetUShort(sageUnsignedShort.Value, subPosition, assetList.Content);
                            subPosition += 2;
                        }
                        break;

                    case Time:
                        assetList = new BinaryAsset(nodes.Count * 4);
                        asset.SubAssets.Add(position, assetList);
                        for (int idx = 0; idx < nodes.Count; ++idx)
                        {
                            string     value = nodes[idx].InnerText;
                            Types.Time time  = new Types.Time(value);
                            FileHelper.SetFloat(time.Value, subPosition, assetList.Content);
                            subPosition += 4;
                        }
                        break;

                    case Velocity:
                        assetList = new BinaryAsset(nodes.Count * 4);
                        asset.SubAssets.Add(position, assetList);
                        for (int idx = 0; idx < nodes.Count; ++idx)
                        {
                            string         value    = nodes[idx].InnerText;
                            Types.Velocity velocity = new Types.Velocity(value);
                            FileHelper.SetFloat(velocity.Value, subPosition, assetList.Content);
                            subPosition += 4;
                        }
                        break;

                    default:
                        foreach (BaseAssetType listBaseAsset in game.Assets.AssetTypes)
                        {
                            if (listBaseAsset.id == AssetType)
                            {
                                AssetType listAsset = listBaseAsset as AssetType;
                                assetList = new BinaryAsset(nodes.Count * listAsset.GetLength(game));
                                asset.SubAssets.Add(position, assetList);
                                for (int idx = 0; idx < nodes.Count; ++idx)
                                {
                                    foreach (BaseEntryType listBaseEntry in listAsset.Entries)
                                    {
                                        if (!listBaseEntry.Compile(baseUri, assetList, nodes[idx], game, trace, ref subPosition, out ErrorDescription))
                                        {
                                            return(false);
                                        }
                                    }
                                }
                                break;
                            }
                        }
                        break;
                    }
                    position += 4;
                }
                else
                {
                    position += 8;
                }
            }
            ErrorDescription = string.Empty;
            return(true);
        }