public static VLTBaseType CloneValue(Database database, VLTBaseType originalValue, VltClass vltClass, VltClassField vltClassField, VltCollection vltCollection) { var newValue = (originalValue is VLTArrayType) ? TypeRegistry.CreateInstance(database.Options.GameId, vltClass, vltClassField, vltCollection) : TypeRegistry.ConstructInstance(TypeRegistry.ResolveType(database.Options.GameId, vltClassField.TypeName), vltClass, vltClassField, vltCollection); if (originalValue is VLTArrayType array) { var newArray = (VLTArrayType)newValue; newArray.Capacity = array.Capacity; newArray.ItemAlignment = vltClassField.Alignment; newArray.FieldSize = vltClassField.Size; newArray.Items = array.Items.Select(i => CloneValue(database, i, vltClass, vltClassField, vltCollection)).ToList(); return(newArray); } switch (originalValue) { case PrimitiveTypeBase primitiveTypeBase: var convertible = primitiveTypeBase.GetValue(); if (convertible != null) { ((PrimitiveTypeBase)newValue).SetValue(convertible); } return(newValue); default: return(CloneObjectWithReflection(originalValue, newValue, vltClass, vltClassField, vltCollection)); } }
public override void ReadPointerData(Vault vault, BinaryReader br) { if (_layoutPointer != 0) { br.BaseStream.Position = _layoutPointer; foreach (var baseField in Collection.Class.BaseFields) { br.AlignReader(baseField.Alignment); VLTBaseType data = TypeRegistry.CreateInstance(vault.Database.Options.GameId, Collection.Class, baseField, Collection); long startPos = br.BaseStream.Position; data.Read(vault, br); long endPos = br.BaseStream.Position; if (!(data is VLTArrayType)) { Debug.Assert(endPos - startPos == baseField.Size); } //Collection.Data[baseField.Name] = data; Collection.SetRawValue(baseField.Name, data); } } foreach (var entry in _entries) { var optionalField = Collection.Class[entry.Key]; if ((optionalField.Flags & DefinitionFlags.IsStatic) != 0) { throw new Exception("Congratulations. You have successfully broken this library. Please consult with your doctor for further instructions."); } if (entry.InlineData is VLTAttribType attribType) { attribType.ReadPointerData(vault, br); Collection.SetRawValue(optionalField.Name, attribType.Data); //Collection.Data[optionalField.Name] = attribType.Data; } else { Collection.SetRawValue(optionalField.Name, entry.InlineData); //Collection.Data[optionalField.Name] = entry.InlineData; } } foreach (var dataEntry in Collection.GetData()) { if (dataEntry.Value is IPointerObject pointerObject) { pointerObject.ReadPointerData(vault, br); } } }
public void ReadPointerData(Vault vault, BinaryReader br) { Data = TypeRegistry.CreateInstance(vault.Database.Options.GameId, Class, Field, Collection); Debug.Assert(Offset != 0); br.BaseStream.Position = Offset; Data.Read(vault, br); if (!(Data is VLTArrayType)) { Debug.Assert(br.BaseStream.Position - Offset == Field.Size, "br.BaseStream.Position - Offset == Field.Size"); } }
public void Read(Vault vault, BinaryReader br) { Key = br.ReadUInt32(); InlineDataPointer = br.BaseStream.Position; if (IsInline()) { InlineData = TypeRegistry.CreateInstance(vault.Database.Options.GameId, Collection.Class, Collection.Class[Key], Collection); } else { InlineData = new VLTAttribType(Collection.Class, Collection.Class[Key], Collection); } InlineData.Read(vault, br); br.AlignReader(4); TypeIndex = br.ReadUInt16(); NodeFlags = (NodeFlagsEnum)br.ReadUInt16(); Debug.Assert((ushort)NodeFlags <= 0x20); }
public override void Execute(ModScriptDatabaseHelper database) { VltCollection collection = GetCollection(database, ClassName, CollectionName); VltClassField field = collection.Class[FieldName]; if (field.IsInLayout) { throw new InvalidDataException($"add_field failed because field '{field.Name}' is a base field"); } if (collection.HasEntry(field.Name)) { throw new InvalidDataException($"add_field failed because collection '{collection.ShortPath}' already has field '{field.Name}'"); } var vltBaseType = TypeRegistry.CreateInstance(database.Database.Options.GameId, collection.Class, field, collection); if (vltBaseType is VLTArrayType array) { if (ArrayCapacity > field.MaxCount) { throw new ModScriptCommandExecutionException( $"Cannot add field {ClassName}[{FieldName}] with capacity beyond maximum (requested {ArrayCapacity} but limit is {field.MaxCount})"); } array.Capacity = ArrayCapacity; array.ItemAlignment = field.Alignment; array.FieldSize = field.Size; array.Items = new List <VLTBaseType>(); for (var i = 0; i < ArrayCapacity; i++) { array.Items.Add(TypeRegistry.ConstructInstance(array.ItemType, collection.Class, field, collection)); } } collection.SetRawValue(field.Name, vltBaseType); }