struct VehicleCustomTemplatePersistentData { persistent var vehicleID : TweakDBID; persistent var template : SavedVehicleVisualCustomizationTemplate; } struct vehicleVisualCustomizationPersistentData { persistent var ID : TweakDBID; persistent var visualCustomizationData : vehicleVisualModdingDefinition; } class StoreVisualCustomizationDataForIDEvent extends Event { var vehicleID : TweakDBID; var template : VehicleVisualCustomizationTemplate; } struct VehicleUniqueTemplatePersistentData { persistent var modelName : CName; persistent var templatesID : array< TweakDBID >; public static function ToTemplate( data : VehicleUniqueTemplatePersistentData, index : Int32 ) : VehicleVisualCustomizationTemplate { return VehicleVisualCustomizationTemplate.FromRecord( TweakDBInterface.GetVehicleColorTemplateRecord( data.templatesID[ index ] ), data.modelName ); } } class vehicleVisualCustomizationComponent extends GameComponent { public function OnGameAttach() { UpdateStoredLegacyTemplates(); RemoveCorruptedTemplates(); } public const function HasVisualCustomizationTemplateStored( visualCustomization : VehicleVisualCustomizationTemplate, optional modelName : CName ) : Bool { return GetMyPS().HasVisualCustomizationTemplateStored( visualCustomization, modelName ); } public const function GetNumberOfStoredVisualCustomizationTemplates( type : VehicleVisualCustomizationType, optional modelName : CName ) : Int32 { return GetMyPS().GetNumberOfStoredVisualCustomizationTemplates( type, modelName ); } public constexpr function GetMaxNumberOfVisualCustomizationTemplates( type : VehicleVisualCustomizationType ) : Int32 { return GetMyPS().GetMaxNumberOfVisualCustomizationTemplates( type ); } public const function CanStoreVisualCustomizationTemplateType( type : VehicleVisualCustomizationType, optional modelName : CName ) : Bool { return GetMyPS().CanStoreVisualCustomizationTemplateType( type, modelName ); } public const function GetStoredVisualCustomizationTemplate( type : VehicleVisualCustomizationType, index : Int32, optional modelName : CName ) : VehicleVisualCustomizationTemplate { return GetMyPS().GetStoredVisualCustomizationTemplate( type, index, modelName ); } public function StoreVisualCustomizationTemplate( template : VehicleVisualCustomizationTemplate, optional modelName : CName ) { GetMyPS().StoreVisualCustomizationTemplate( template, modelName ); } public function DeleteVisualCustomizationTemplate( template : VehicleVisualCustomizationTemplate, optional modelName : CName ) { GetMyPS().DeleteVisualCustomizationTemplate( template, modelName ); } public const function RetrieveVisualCustomizationForVehicle( vehicleID : TweakDBID ) : VehicleVisualCustomizationTemplate { var template : VehicleVisualCustomizationTemplate; GetMyPS().GetAppliedCustomizationDataForVehicle( vehicleID, template ); return template; } protected event OnStoreVisualCustomizationDataForIDEvent( evt : StoreVisualCustomizationDataForIDEvent ) { GetMyPS().StoreAppliedCustomizationDataForVehicle( evt.vehicleID, evt.template ); } private const function GetOwner() : GameObject { return ( ( GameObject )( GetEntity() ) ); } private const function GetMyPS() : vehicleVisualCustomizationComponentPS { return ( ( vehicleVisualCustomizationComponentPS )( GetPS() ) ); } private function UpdateStoredLegacyTemplates() { var legacyData : array< vehicleVisualCustomizationPersistentData >; var updatedTemplate : VehicleVisualCustomizationTemplate; var index : Int32; legacyData = GetMyPS().GetLegacyVisualCustomizationData(); for( index = 0; index < legacyData.Size(); index += 1 ) { updatedTemplate = vehicleVisualModdingDefinition.UpdateToNewFormat( legacyData[ index ].visualCustomizationData ); GetMyPS().StoreAppliedCustomizationDataForVehicle( legacyData[ index ].ID, updatedTemplate ); } GetMyPS().DeleteLegacyVisualCustomizationData(); } private function RemoveCorruptedTemplates() { GetMyPS().RemoveCorruptedTemplates(); } } class vehicleVisualCustomizationComponentPS extends GameComponentPS { private persistent var m_storedAppliedVisualCustomization : array< VehicleCustomTemplatePersistentData >; private persistent var m_storedGenericVisualCustomizationTemplates : array< GenericTemplatePersistentData >; private persistent var m_storedUniqueVisualCustomizationTemplates : array< VehicleUniqueTemplatePersistentData >; private persistent var m_storedVisualCustomizationData : array< vehicleVisualCustomizationPersistentData >; public const function GetNumberOfStoredVisualCustomizationTemplates( type : VehicleVisualCustomizationType, optional modelName : CName ) : Int32 { var uniqueTemplateIndex : Int32; if( type == VehicleVisualCustomizationType.Generic ) { return m_storedGenericVisualCustomizationTemplates.Size(); } else { uniqueTemplateIndex = GetStoredUniqueTemplatesIndexForVehicle( modelName ); if( uniqueTemplateIndex == -1 ) { return 0; } return m_storedUniqueVisualCustomizationTemplates[ uniqueTemplateIndex ].templatesID.Size(); } } public constexpr function GetMaxNumberOfVisualCustomizationTemplates( type : VehicleVisualCustomizationType ) : Int32 { return ( ( type == VehicleVisualCustomizationType.Unique ) ? ( TDB.GetInt( T"player.vehicle.maxNumberOfStoredUniquePatterns" ) ) : ( TDB.GetInt( T"player.vehicle.maxNumberOfStoredGenericPatterns" ) ) ); } public function CanStoreVisualCustomizationTemplateType( type : VehicleVisualCustomizationType, optional modelName : CName ) : Bool { return GetNumberOfStoredVisualCustomizationTemplates( type, modelName ) < GetMaxNumberOfVisualCustomizationTemplates( type ); } public function HasVisualCustomizationTemplateStored( template : VehicleVisualCustomizationTemplate, optional modelName : CName ) : Bool { var uniqueTemplateIndex : Int32; var i : Int32; if( VehicleVisualCustomizationTemplate.GetType( template ) == VehicleVisualCustomizationType.Generic ) { for( i = 0; i < m_storedGenericVisualCustomizationTemplates.Size(); i += 1 ) { if( GenericTemplatePersistentData.Equals( m_storedGenericVisualCustomizationTemplates[ i ], template.genericData ) ) { return true; } } return false; } else { uniqueTemplateIndex = GetStoredUniqueTemplatesIndexForVehicle( modelName ); if( uniqueTemplateIndex == -1 ) { return 0; } for( i = 0; i < m_storedUniqueVisualCustomizationTemplates[ uniqueTemplateIndex ].templatesID.Size(); i += 1 ) { if( VehicleVisualCustomizationTemplate.Equals( VehicleUniqueTemplatePersistentData.ToTemplate( m_storedUniqueVisualCustomizationTemplates[ uniqueTemplateIndex ], i ), template ) ) { return true; } } return false; } } public function GetStoredVisualCustomizationTemplate( type : VehicleVisualCustomizationType, index : Int32, optional modelName : CName ) : VehicleVisualCustomizationTemplate { var ret : VehicleVisualCustomizationTemplate; var uniqueTemplateIndex : Int32; if( type == VehicleVisualCustomizationType.Unique ) { uniqueTemplateIndex = GetStoredUniqueTemplatesIndexForVehicle( modelName ); if( uniqueTemplateIndex == -1 ) { return ret; } if( index < m_storedUniqueVisualCustomizationTemplates[ uniqueTemplateIndex ].templatesID.Size() ) { ret = VehicleUniqueTemplatePersistentData.ToTemplate( m_storedUniqueVisualCustomizationTemplates[ uniqueTemplateIndex ], index ); } } else if( type == VehicleVisualCustomizationType.Generic && ( index < m_storedGenericVisualCustomizationTemplates.Size() ) ) { ret.hasUniqueTemplate = false; ret.genericData = m_storedGenericVisualCustomizationTemplates[ index ]; } return ret; } public function StoreVisualCustomizationTemplate( template : VehicleVisualCustomizationTemplate, optional modelName : CName ) { var uniqueTemplateIndex : Int32; var newPersistentData : VehicleUniqueTemplatePersistentData; if( CanStoreVisualCustomizationTemplateType( VehicleVisualCustomizationTemplate.GetType( template ), modelName ) && !( HasVisualCustomizationTemplateStored( template, modelName ) ) ) { if( VehicleVisualCustomizationTemplate.GetType( template ) == VehicleVisualCustomizationType.Generic ) { m_storedGenericVisualCustomizationTemplates.PushBack( template.genericData ); } else { if( modelName == '' ) { return; } uniqueTemplateIndex = GetStoredUniqueTemplatesIndexForVehicle( modelName ); if( uniqueTemplateIndex == -1 ) { newPersistentData.modelName = modelName; m_storedUniqueVisualCustomizationTemplates.PushBack( newPersistentData ); uniqueTemplateIndex = m_storedUniqueVisualCustomizationTemplates.Size() - 1; } m_storedUniqueVisualCustomizationTemplates[ uniqueTemplateIndex ].templatesID.PushBack( template.uniqueData.recordId ); } } } public function DeleteVisualCustomizationTemplate( template : VehicleVisualCustomizationTemplate, optional modelName : CName ) { var templateIndex : Int32; var uniqueTemplateIndex : Int32; if( VehicleVisualCustomizationTemplate.GetType( template ) == VehicleVisualCustomizationType.Generic ) { templateIndex = m_storedGenericVisualCustomizationTemplates.FindFirst( template.genericData ); m_storedGenericVisualCustomizationTemplates.Erase( templateIndex ); } else { uniqueTemplateIndex = GetStoredUniqueTemplatesIndexForVehicle( modelName ); if( uniqueTemplateIndex == -1 ) { return; } templateIndex = m_storedUniqueVisualCustomizationTemplates[ uniqueTemplateIndex ].templatesID.FindFirst( template.uniqueData.recordId ); m_storedUniqueVisualCustomizationTemplates[ uniqueTemplateIndex ].templatesID.Erase( templateIndex ); } } public function StoreAppliedCustomizationDataForVehicle( vehicleID : TweakDBID, template : VehicleVisualCustomizationTemplate ) { var dataPackage : VehicleCustomTemplatePersistentData; var i : Int32; var checkedID : TweakDBID; while( i < m_storedAppliedVisualCustomization.Size() ) { checkedID = m_storedAppliedVisualCustomization[ i ].vehicleID; if( checkedID == vehicleID ) { m_storedAppliedVisualCustomization[ i ].template = SavedVehicleVisualCustomizationTemplate.FromVehicleVisualCustomizationTemplate( template ); return; } i += 1; } dataPackage.vehicleID = vehicleID; dataPackage.template = SavedVehicleVisualCustomizationTemplate.FromVehicleVisualCustomizationTemplate( template ); m_storedAppliedVisualCustomization.PushBack( dataPackage ); } public const function GetAppliedCustomizationDataForVehicle( vehicleID : TweakDBID, out template : VehicleVisualCustomizationTemplate ) : Bool { var i : Int32; var checkedID : TweakDBID; if( m_storedAppliedVisualCustomization.Size() == 0 ) { return false; } while( i < m_storedAppliedVisualCustomization.Size() ) { checkedID = m_storedAppliedVisualCustomization[ i ].vehicleID; if( checkedID == vehicleID ) { template = SavedVehicleVisualCustomizationTemplate.ToVehicleVisualCustomizationTemplate( m_storedAppliedVisualCustomization[ i ].template ); return true; } i += 1; } return false; } public const function GetLegacyVisualCustomizationData() : array< vehicleVisualCustomizationPersistentData > { return m_storedVisualCustomizationData; } public function DeleteLegacyVisualCustomizationData() { m_storedVisualCustomizationData.Clear(); } public function RemoveCorruptedTemplates() { var i, j : Int32; for( i = 0; i < m_storedUniqueVisualCustomizationTemplates.Size(); i += 1 ) { for( j = m_storedUniqueVisualCustomizationTemplates[ i ].templatesID.Size() - 1; j >= 0; j -= 1 ) { if( !( VehicleVisualCustomizationTemplate.IsValid( VehicleUniqueTemplatePersistentData.ToTemplate( m_storedUniqueVisualCustomizationTemplates[ i ], j ) ) ) ) { m_storedUniqueVisualCustomizationTemplates[ i ].templatesID.Erase( j ); } } } for( i = m_storedAppliedVisualCustomization.Size() - 1; i >= 0; i -= 1 ) { if( !( VehicleVisualCustomizationTemplate.IsValid( SavedVehicleVisualCustomizationTemplate.ToVehicleVisualCustomizationTemplate( m_storedAppliedVisualCustomization[ i ].template ) ) ) ) { m_storedAppliedVisualCustomization.Erase( i ); } } } private const function GetStoredUniqueTemplatesIndexForVehicle( modelName : CName ) : Int32 { var i : Int32; if( modelName == '' ) { return -1; } for( i = 0; i < m_storedUniqueVisualCustomizationTemplates.Size(); i += 1 ) { if( m_storedUniqueVisualCustomizationTemplates[ i ].modelName == modelName ) { return i; } } return -1; } }