Guest User

Untitled

a guest
Nov 9th, 2024
9
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.38 KB | Gaming | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using MoreSuitsMod.Model.Factories.Interfaces;
  6. using MoreSuitsMod.Model.Suit;
  7. using UnityEngine;
  8. using Debug = UnityEngine.Debug;
  9.  
  10. namespace MoreSuitsMod.Model.Factories;
  11.  
  12.  
  13. public class SuitFactory : MonoBehaviour, ISuitFactory
  14. {
  15.     public List<string> SuitFolderPaths { get; set; }
  16.     private List<string> _texturePaths = [];
  17.     private List<string> _assetPaths = [];
  18.     private Dictionary<string, Material> _customMaterialCache = [];
  19.     public UnlockableItem OriginalSuit { get; set; }
  20.    
  21.     public List<ISuit> Create()
  22.     {
  23.         List<ISuit> suits = new List<ISuit>();
  24.         SetPaths();
  25.         SortPaths();
  26.         foreach (Material material in InitMaterialsCache())
  27.         {
  28.             _customMaterialCache.Add(material.name, material);
  29.         }
  30.  
  31.         foreach (string texturePath in _texturePaths)
  32.         {
  33.             var suit = InitSuitFromPath(texturePath);
  34.             suit = HandleSuitModifications(suit, texturePath);
  35.             suits.Add(suit);
  36.  
  37.         }
  38.         return suits;
  39.     }
  40.  
  41.  
  42.     private (List<string> texturePaths, List<string> assetPaths) InitPaths()
  43.     {
  44.         List<string> texturePaths = [];
  45.         List<string> assetPaths = [];
  46.  
  47.         foreach (var suitsFolderPath in SuitFolderPaths)
  48.         {
  49.             if (suitsFolderPath == "") continue;
  50.             var pngFiles = Directory.GetFiles(suitsFolderPath, "*.png");
  51.             var bundleFiles = Directory.GetFiles(suitsFolderPath, "*.matbundle");
  52.             texturePaths.AddRange(pngFiles);
  53.             assetPaths.AddRange(bundleFiles);
  54.         }
  55.  
  56.         return (texturePaths, assetPaths);
  57.     }
  58.  
  59.     private void SetPaths()
  60.     {
  61.         var paths = InitPaths();
  62.         _texturePaths = paths.texturePaths;
  63.         _assetPaths = paths.assetPaths;
  64.     }
  65.  
  66.     private void SortPaths()
  67.     {
  68.         _texturePaths.Sort();
  69.         _assetPaths.Sort();
  70.     }
  71.  
  72.     private List<Material> InitMaterialsCache()
  73.     {
  74.         try
  75.         {
  76.             List<Material> materials = [];
  77.             foreach (var assetPath in _assetPaths)
  78.             {
  79.                 AssetBundle assetBundle = AssetBundle.LoadFromFile(assetPath);
  80.                 UnityEngine.Object[] assets = assetBundle.LoadAllAssets();
  81.                 foreach (var asset in assets)
  82.                 {
  83.                     if (asset is Material material)
  84.                     {
  85.                         materials.Add(material);
  86.                     }
  87.                 }
  88.             }
  89.  
  90.             return materials;
  91.         }
  92.         catch (Exception e)
  93.         {
  94.             //TODO add custom exception here.
  95.             throw new Exception($"Failed to load materials from {_assetPaths}", e);
  96.         }
  97.     }
  98.  
  99.     private ISuit InitSuitFromPath(string texturePath)
  100.     {
  101.         if (string.IsNullOrEmpty(texturePath))
  102.         {
  103.             Debug.LogError("Texture path is null or empty.");
  104.             return null;
  105.         }
  106.  
  107.         ISuit suit = new CustomSuit();
  108.         suit.UnlockableName = Path.GetFileNameWithoutExtension(texturePath);
  109.         Debug.Log(texturePath);
  110.         suit.SuitMaterial = InitMaterialFromPath(texturePath);
  111.         if (suit.SuitMaterial == null)
  112.         {
  113.             Debug.LogError($"Failed to initialize material from path: {texturePath}");
  114.         }
  115.  
  116.         return suit;
  117.     }
  118.  
  119.  
  120.     private Material InitMaterialFromPath(string texturePath)
  121.     {
  122.         Material material = Path
  123.             .GetFileNameWithoutExtension(texturePath)
  124.             .ToLower() == "default"
  125.             ? OriginalSuit.suitMaterial
  126.             : Instantiate(JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson(OriginalSuit)).suitMaterial);
  127.         material.mainTexture = InitSuitTextureFromPath(texturePath);
  128.         return material;
  129.     }
  130.  
  131.     private Texture2D InitSuitTextureFromPath(string texturePath)
  132.     {
  133.         byte[] fileData = File.ReadAllBytes(texturePath);
  134.         Texture2D texture = new Texture2D(2, 2);
  135.         texture.LoadImage(fileData);
  136.  
  137.         texture.Apply(true, true);
  138.         return texture;
  139.     }
  140.  
  141.     private ISuit HandleSuitModifications(ISuit suit, string texturePath)
  142.     {
  143.         {
  144.             string advancedJsonPath = Path.Combine(Path.GetDirectoryName(texturePath), "advanced",
  145.                 suit.UnlockableName + ".json");
  146.  
  147.  
  148.             if (!File.Exists(advancedJsonPath)) return suit;
  149.  
  150.  
  151.             foreach (string line in File.ReadAllLines(advancedJsonPath))
  152.             {
  153.                 string[] keyValue = line.Trim().Split(':');
  154.                 if (keyValue.Length != 2) continue;
  155.  
  156.                 string keyData = keyValue[0].Trim('"', ' ', ',');
  157.                 string valueData = keyValue[1].Trim('"', ' ', ',');
  158.  
  159.                 if (valueData.EndsWith(".png"))
  160.                 {
  161.                     LoadAdvancedTexture(texturePath, valueData, keyData, suit.SuitMaterial);
  162.                 }
  163.                 else
  164.                 {
  165.                     switch (keyData)
  166.                     {
  167.                         case "PRICE" when int.TryParse(valueData, out int price):
  168.                             suit.Price = price;
  169.                             break;
  170.  
  171.                         case "KEYWORD":
  172.                             suit.SuitMaterial.EnableKeyword(valueData);
  173.                             break;
  174.  
  175.                         case "DISABLEKEYWORD":
  176.                             suit.SuitMaterial.DisableKeyword(valueData);
  177.                             break;
  178.  
  179.                         case "SHADERPASS":
  180.                             suit.SuitMaterial.SetShaderPassEnabled(valueData, true);
  181.                             break;
  182.  
  183.                         case "DISABLESHADERPASS":
  184.                             suit.SuitMaterial.SetShaderPassEnabled(valueData, false);
  185.                             break;
  186.  
  187.                         case "SHADER":
  188.                             Shader shader = Shader.Find(valueData);
  189.                             suit.SuitMaterial.shader = shader;
  190.                             break;
  191.  
  192.                         case "MATERIAL":
  193.                             ApplyCustomMaterial(valueData, suit.SuitMaterial.mainTexture);
  194.                             break;
  195.  
  196.                         default:
  197.                             ApplyNumericOrVectorValue(keyData, valueData, suit.SuitMaterial);
  198.                             break;
  199.                     }
  200.                 }
  201.             }
  202.         }
  203.         return suit;
  204.     }
  205.  
  206.     private void LoadAdvancedTexture(string baseTexturePath, string textureFileName, string textureKey, Material material)
  207.         {
  208.             string texturePath = Path.Combine(Path.GetDirectoryName(baseTexturePath), "advanced", textureFileName);
  209.             byte[] textureData = File.ReadAllBytes(texturePath);
  210.             Texture2D advancedTexture = new Texture2D(2, 2);
  211.             advancedTexture.LoadImage(textureData);
  212.             advancedTexture.Apply(true, true);
  213.             material.SetTexture(textureKey, advancedTexture);
  214.         }
  215.     private void ApplyCustomMaterial(string materialName, Texture mainTexture)
  216.         {
  217.             Material customMaterial = Instantiate(_customMaterialCache[materialName]);
  218.             customMaterial.mainTexture = mainTexture;
  219.            
  220.         }
  221.        
  222.  
  223.         private void ApplyNumericOrVectorValue(string key, string value, Material material)
  224.         {
  225.             if (float.TryParse(value, out float floatValue))
  226.             {
  227.                 material.SetFloat(key, floatValue);
  228.             }
  229.             else if (TryParseVector4(value, out Vector4 vectorValue))
  230.             {
  231.                 material.SetVector(key, vectorValue);
  232.             }
  233.     }
  234.         public static bool TryParseVector4(string input, out Vector4 vector)
  235.         {
  236.             vector = Vector4.zero;
  237.  
  238.             string[] components = input.Split(',');
  239.  
  240.             if (components.Length == 4)
  241.             {
  242.                 if (float.TryParse(components[0], out float x) &&
  243.                     float.TryParse(components[1], out float y) &&
  244.                     float.TryParse(components[2], out float z) &&
  245.                     float.TryParse(components[3], out float w))
  246.                 {
  247.                     vector = new Vector4(x, y, z, w);
  248.                     return true;
  249.                 }
  250.             }
  251.  
  252.             return false;
  253.         }
  254.        
  255. }
  256.  
  257.  
  258.  
Advertisement
Add Comment
Please, Sign In to add comment