Advertisement
Krythic

Gen

May 18th, 2025
358
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 14.34 KB | None | 0 0
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using UnityEngine;
  6. using VoidwalkerEngine.Framework.Algorithms;
  7.  
  8.  
  9. public class RarityEventArgs
  10. {
  11.     public int uncommonChance;
  12.     public int rareChance;
  13.     public int epicChance;
  14.     public int uniqueChance;
  15.  
  16.     public int superiorChance;
  17.     public int commonChance;
  18.     public int lowQualityChance;
  19.  
  20.     public RarityEventArgs(int uncommonChance, int rareChance, int epicChance, int uniqueChance)
  21.     {
  22.         this.uncommonChance = uncommonChance;
  23.         this.rareChance = rareChance;
  24.         this.epicChance = epicChance;
  25.         this.uniqueChance = uniqueChance;
  26.  
  27.     }
  28.  
  29.     public RarityEventArgs()
  30.     {
  31.  
  32.     }
  33. }
  34.  
  35. public class GameItemEnchanter
  36. {
  37.     private List<Enchantment> _enchantmentTemplates;
  38.     private GameItemNameGenerator _gameItemNameGenerator;
  39.  
  40.     public GameItemEnchanter()
  41.     {
  42.         Initialize();
  43.     }
  44.  
  45.     private void Initialize()
  46.     {
  47.         LoadEnchantmentTemplates();
  48.         _gameItemNameGenerator = new GameItemNameGenerator();
  49.     }
  50.  
  51.     public static float CalculateEffectiveMagicFind(float totalMagicFind, GameItemRarity rarity)
  52.     {
  53.         float rarityFactor = rarity.ToRarityMagicFindFactor();
  54.         return (totalMagicFind * rarityFactor) / (totalMagicFind + rarityFactor);
  55.     }
  56.  
  57.     public GameItemTemplate Enchant(GameItemTemplate baseItemTemplate, int itemLevel, int magicFind, RarityEventArgs rarityTemplate)
  58.     {
  59.         Dictionary<GameItemRarity, float> rarityChances = new Dictionary<GameItemRarity, float>
  60.         {
  61.             { GameItemRarity.Unique, rarityTemplate.uniqueChance / 100f },
  62.             { GameItemRarity.Epic, rarityTemplate.epicChance / 100f },
  63.             { GameItemRarity.Rare, rarityTemplate.rareChance / 100f },
  64.             { GameItemRarity.Uncommon, rarityTemplate.uncommonChance / 100f }
  65.         };
  66.         GameItemRarity[] rarities = new GameItemRarity[] { GameItemRarity.Unique, GameItemRarity.Epic, GameItemRarity.Rare, GameItemRarity.Uncommon };
  67.         foreach (GameItemRarity rarity in rarities)
  68.         {
  69.             float effectiveChance = Mathf.Clamp(
  70.                 rarityChances[rarity] * CalculateEffectiveMagicFind(magicFind, rarity),
  71.                 0f,
  72.                 1f
  73.             );
  74.  
  75.             if (UnityEngine.Random.Range(0f, 1f) <= effectiveChance)
  76.             {
  77.                 return Enchant(baseItemTemplate, rarity, itemLevel);
  78.             }
  79.         }
  80.  
  81.         return Enchant(baseItemTemplate, GameItemRarity.Common, itemLevel);
  82.     }
  83.  
  84.     public GameItemTemplate Enchant(GameItemTemplate baseItemTemplate, GameItemRarity rarity, int itemLevel)
  85.     {
  86.         GameItemTemplate gameItemTemplate = ScriptableObject.CreateInstance<GameItemTemplate>();
  87.         gameItemTemplate.itemType = baseItemTemplate.itemType;
  88.         gameItemTemplate.itemRarity = rarity;
  89.         gameItemTemplate.itemName = "LGI_001";
  90.         gameItemTemplate.itemIcon = baseItemTemplate.itemIcon;
  91.         gameItemTemplate.weaponDamageMin = baseItemTemplate.weaponDamageMin;
  92.         gameItemTemplate.weaponDamageMax = baseItemTemplate.weaponDamageMax;
  93.         gameItemTemplate.itemLevel = itemLevel;
  94.         gameItemTemplate.stats = GenerateStats(baseItemTemplate.itemType.ToPrimaryStatProvider());
  95.         int enchantmentCount = NextEnchantmentCount(rarity);
  96.         Debug.Log("Enchantment Count: " + enchantmentCount);
  97.         Enchantment[] generatedAffixes = GenerateRandomEnchantments(baseItemTemplate.itemType, itemLevel, enchantmentCount, out Enchantment[] generatedTemplates);
  98.         Debug.Log("Generated Affixes: " + generatedAffixes.Length);
  99.         gameItemTemplate.enchantments = generatedAffixes;
  100.         gameItemTemplate.isGenerated = true;
  101.         switch (rarity)
  102.         {
  103.             case GameItemRarity.Common:
  104.                 gameItemTemplate.itemName = "Null Common";
  105.                 break;
  106.             case GameItemRarity.Uncommon:
  107.                 gameItemTemplate.itemName = "null uncommon";
  108.                 break;
  109.             case GameItemRarity.Rare:
  110.                 gameItemTemplate.itemName = _gameItemNameGenerator.GenerateRareName(gameItemTemplate.itemType);
  111.                 break;
  112.             case GameItemRarity.Epic:
  113.                 gameItemTemplate.itemName = _gameItemNameGenerator.GenerateEpicName(gameItemTemplate.itemType);
  114.                 break;
  115.             case GameItemRarity.Unique:
  116.                 gameItemTemplate.itemName = "Null Legendary";
  117.                 break;
  118.             default:
  119.                 gameItemTemplate.itemName = "Error";
  120.                 break;
  121.         }
  122.         gameItemTemplate.isEthereal = GenerateEthereal();
  123.         return gameItemTemplate;
  124.     }
  125.  
  126.     private Enchantment[] GetValidEnchantmentTemplates(GameItemType itemType, int itemLevel)
  127.     {
  128.         List<Enchantment> validEnchantments = new List<Enchantment>();
  129.         foreach (Enchantment template in _enchantmentTemplates)
  130.         {
  131.             if (template.levelBracket.Contains(itemLevel))
  132.             {
  133.                 foreach (GameItemType constraint in template.constraints)
  134.                 {
  135.                     if (constraint == itemType)
  136.                     {
  137.                         validEnchantments.Add(template);
  138.                         break;
  139.                     }
  140.                 }
  141.             }
  142.         }
  143.         return validEnchantments.ToArray();
  144.     }
  145.  
  146.     public Enchantment[] GenerateRandomEnchantments(GameItemType itemType, int itemLevel, int affixCount, out Enchantment[] generatedEnchantmentTemplateResults)
  147.     {
  148.         Enchantment[] validTemplates = GetValidEnchantmentTemplates(itemType, itemLevel);
  149.         List<Enchantment> generatedEnchantments = new List<Enchantment>();
  150.         List<Enchantment> selectedTemplates = new List<Enchantment>();
  151.  
  152.         if (validTemplates.Length == 0)
  153.         {
  154.             generatedEnchantmentTemplateResults = null;
  155.             return generatedEnchantments.ToArray();
  156.         }
  157.  
  158.         List<Enchantment> templatesPool = new List<Enchantment>(validTemplates);
  159.         int totalWeight = templatesPool.Sum(t => t.weight);
  160.  
  161.         for (int i = 0; i < affixCount && templatesPool.Count > 0; i++)
  162.         {
  163.             int randomWeight = UnityEngine.Random.Range(0, totalWeight);
  164.             int cumulativeWeight = 0;
  165.  
  166.             foreach (Enchantment template in templatesPool)
  167.             {
  168.                 cumulativeWeight += template.weight;
  169.                 if (randomWeight < cumulativeWeight)
  170.                 {
  171.                     generatedEnchantments.Add(template);
  172.                     selectedTemplates.Add(template);
  173.                     totalWeight -= template.weight;
  174.                     templatesPool.Remove(template);
  175.                     break;
  176.                 }
  177.             }
  178.         }
  179.  
  180.         generatedEnchantmentTemplateResults = selectedTemplates.ToArray();
  181.         return generatedEnchantments.ToArray();
  182.     }
  183.  
  184.     public int NextEnchantmentCount(GameItemRarity rarity)
  185.     {
  186.         switch (rarity)
  187.         {
  188.             case GameItemRarity.Uncommon:
  189.                 return UnityEngine.Random.Range(1, 2);
  190.             case GameItemRarity.Rare:
  191.                 return UnityEngine.Random.Range(2, 3);
  192.             default:
  193.                 return 0;
  194.         }
  195.     }
  196.  
  197.     public bool GenerateEthereal()
  198.     {
  199.         return UnityEngine.Random.Range(0, 512) < 1;
  200.     }
  201.  
  202.     public void LoadEnchantmentTemplates()
  203.     {
  204.         List<Enchantment> templates = new List<Enchantment>();
  205.         string fileName = "EnchantmentTemplates";
  206.  
  207.         try
  208.         {
  209.             TextAsset textAsset = Resources.Load<TextAsset>("Prefabs/Data/" + fileName);
  210.             if (textAsset == null)
  211.             {
  212.                 Debug.LogError($"[LoadEnchantmentTemplates] File not found: Resources/Prefabs/Data/{fileName}");
  213.                 return;
  214.             }
  215.  
  216.             string[] lines = textAsset.text.Split(new[] { '\n' }, System.StringSplitOptions.RemoveEmptyEntries);
  217.             Debug.Log($"[LoadEnchantmentTemplates] Loaded {lines.Length} lines from {fileName}.");
  218.             if (lines.Length <= 1)
  219.             {
  220.                 Debug.LogWarning("[LoadEnchantmentTemplates] Enchantment template file is empty or missing data.");
  221.                 return;
  222.             }
  223.  
  224.             for (int i = 0; i < lines.Length; i++)
  225.             {
  226.                 string[] fields = lines[i].Split(new[] { '\t' }, System.StringSplitOptions.None);
  227.                 if (fields.Length < 10)
  228.                 {
  229.                     Debug.LogWarning($"[LoadEnchantmentTemplates] Skipping line {i + 1}: Not enough fields.");
  230.                     continue;
  231.                 }
  232.  
  233.                 try
  234.                 {
  235.                     Enchantment enchantment = new Enchantment();
  236.  
  237.                     if (!Enchantment.TryParseEnchantmentProperty(fields[1], out EnchantmentProperty property))
  238.                     {
  239.                         Debug.LogWarning($"[LoadEnchantmentTemplates] Line {i + 1}: Could not parse property '{fields[1]}'.");
  240.                         continue;
  241.                     }
  242.                     // Identifier   Property    Family  Name    Level   Value   Minimum Maximum Weight  Constraints Description
  243.                     enchantment.identifier = fields[0];
  244.                     enchantment.property = property;
  245.                     enchantment.family = fields[2];
  246.                     enchantment.displayName = fields[3];
  247.                     enchantment.levelBracket = Range.Parse(fields[4]);
  248.                     enchantment.value = ParseInt32Field(fields[5]);
  249.                     enchantment.minimum = ParseInt32Field(fields[6]);
  250.                     enchantment.maximum = ParseInt32Field(fields[7]);
  251.                     enchantment.weight = ParseInt32Field(fields[8]);
  252.                     enchantment.constraints = ParseGameItemConstraintsField(fields[9]);
  253.                     enchantment.displayDescription = fields[10];
  254.  
  255.                     templates.Add(enchantment);
  256.                     Debug.Log($"[LoadEnchantmentTemplates] Line {i + 1}: Loaded enchantment '{enchantment.displayName}' with property '{enchantment.property}'.");
  257.                 }
  258.                 catch (FormatException fe)
  259.                 {
  260.                     Debug.LogWarning($"[LoadEnchantmentTemplates] Line {i + 1}: Format exception - {fe.Message}");
  261.                 }
  262.                 catch (System.Exception ex)
  263.                 {
  264.                     Debug.LogWarning($"[LoadEnchantmentTemplates] Line {i + 1}: Unexpected error - {ex.Message}");
  265.                 }
  266.             }
  267.         }
  268.         catch (System.Exception ex)
  269.         {
  270.             Debug.LogError($"[LoadEnchantmentTemplates] Failed to load templates: {ex.Message}");
  271.             return;
  272.         }
  273.  
  274.         this._enchantmentTemplates = templates;
  275.         Debug.Log($"[LoadEnchantmentTemplates] Successfully loaded {templates.Count} enchantment templates.");
  276.     }
  277.  
  278.     private int ParseInt32Field(string field)
  279.     {
  280.         if (field.Equals("--"))
  281.         {
  282.             return 0;
  283.         }
  284.         else
  285.         {
  286.             return Int32.Parse(field);
  287.         }
  288.     }
  289.  
  290.     private static GameItemType[] ParseGameItemConstraintsField(string constraints)
  291.     {
  292.         if (string.IsNullOrWhiteSpace(constraints))
  293.         {
  294.             return new GameItemType[0];
  295.         }
  296.         string[] constraintParts = constraints.Split(",", System.StringSplitOptions.RemoveEmptyEntries);
  297.         List<GameItemType> results = new List<GameItemType>();
  298.         foreach (string constraint in constraintParts)
  299.         {
  300.             string trimmedConstraint = constraint.Trim();
  301.             GameItemType parsedConstraint = ParseGameItemTypeConstraint(trimmedConstraint);
  302.             if (!results.Contains(parsedConstraint))
  303.             {
  304.                 results.Add(parsedConstraint);
  305.             }
  306.         }
  307.         return results.ToArray();
  308.     }
  309.  
  310.     public static Dictionary<StatType, StatScalingType> GenerateStats(StatType[] preferredStats)
  311.     {
  312.         if (preferredStats == null || preferredStats.Length == 0)
  313.         {
  314.             return new Dictionary<StatType, StatScalingType>();
  315.         }
  316.  
  317.         if (preferredStats.Length == 1)
  318.         {
  319.             Dictionary<StatType, StatScalingType> stats = new Dictionary<StatType, StatScalingType>
  320.             {
  321.                 { StatType.Strength, StatScalingType.Lesser }
  322.             };
  323.             return stats;
  324.         }
  325.  
  326.         int firstIndex = UnityEngine.Random.Range(0, preferredStats.Length);
  327.         int secondIndex;
  328.         do
  329.         {
  330.             secondIndex = UnityEngine.Random.Range(0, preferredStats.Length);
  331.         } while (secondIndex == firstIndex);
  332.         Dictionary<StatType, StatScalingType> selectedStats = new Dictionary<StatType, StatScalingType>
  333.             {
  334.                 { preferredStats[firstIndex], StatScalingType.Lesser },
  335.                 { preferredStats[secondIndex], StatScalingType.Lesser },
  336.             };
  337.         return selectedStats;
  338.     }
  339.  
  340.     private static GameItemType ParseGameItemTypeConstraint(string constraints)
  341.     {
  342.         switch (constraints)
  343.         {
  344.             case "Dagger":
  345.                 return GameItemType.Dagger;
  346.             case "Sword":
  347.                 return GameItemType.Sword;
  348.             case "Greatsword":
  349.                 return GameItemType.GreatSword;
  350.             case "Axe":
  351.                 return GameItemType.Axe;
  352.             case "Greataxe":
  353.                 return GameItemType.GreatAxe;
  354.             case "Mace":
  355.                 return GameItemType.Mace;
  356.             case "Greatmace":
  357.                 return GameItemType.GreatMace;
  358.             case "Bow":
  359.                 return GameItemType.Bow;
  360.             case "Headwear":
  361.                 return GameItemType.Headwear;
  362.             case "Chestwear":
  363.                 return GameItemType.Chestwear;
  364.             case "Handwear":
  365.                 return GameItemType.Handwear;
  366.             case "Footwear":
  367.                 return GameItemType.Footwear;
  368.             case "Amulet":
  369.                 return GameItemType.Amulet;
  370.             case "Ring":
  371.                 return GameItemType.Ring;
  372.             case "Shield":
  373.                 return GameItemType.Shield;
  374.             case "Charm":
  375.                 return GameItemType.Charm;
  376.             default:
  377.                 throw new System.Exception("Could not parse GameItemConstraint: '" + constraints + "'!");
  378.         }
  379.     }
  380. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement