Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using VoidwalkerEngine.Framework.Algorithms;
- public class RarityEventArgs
- {
- public int uncommonChance;
- public int rareChance;
- public int epicChance;
- public int uniqueChance;
- public int superiorChance;
- public int commonChance;
- public int lowQualityChance;
- public RarityEventArgs(int uncommonChance, int rareChance, int epicChance, int uniqueChance)
- {
- this.uncommonChance = uncommonChance;
- this.rareChance = rareChance;
- this.epicChance = epicChance;
- this.uniqueChance = uniqueChance;
- }
- public RarityEventArgs()
- {
- }
- }
- public class GameItemEnchanter
- {
- private List<EnchantmentTemplate> _enchantmentTemplates;
- private GameItemNameGenerator _gameItemNameGenerator;
- private static readonly List<EnchantmentTemplate> _superiorTemplate = new List<EnchantmentTemplate>() {
- new EnchantmentTemplate(EnchantmentProperty.ItemMod_EnhancedDamage, new Range(10, 15)),
- new EnchantmentTemplate(EnchantmentProperty.ItemMod_EnhancedDurability, new Range(10, 15)),
- new EnchantmentTemplate(EnchantmentProperty.ItemMod_EnhancedArmorRating, new Range(10, 15)),
- };
- public GameItemEnchanter()
- {
- Initialize();
- }
- private void Initialize()
- {
- LoadEnchantmentTemplates();
- _gameItemNameGenerator = new GameItemNameGenerator();
- }
- public static float CalculateEffectiveMagicFind(float totalMagicFind, GameItemRarity rarity)
- {
- float rarityFactor = rarity.ToRarityMagicFindFactor();
- return (totalMagicFind * rarityFactor) / (totalMagicFind + rarityFactor);
- }
- public GameItemTemplate Enchant(GameItemTemplate baseItemTemplate, int itemLevel, int magicFind, RarityEventArgs rarityTemplate)
- {
- Dictionary<GameItemRarity, float> rarityChances = new Dictionary<GameItemRarity, float>
- {
- { GameItemRarity.Unique, rarityTemplate.uniqueChance / 100f },
- { GameItemRarity.Epic, rarityTemplate.epicChance / 100f },
- { GameItemRarity.Rare, rarityTemplate.rareChance / 100f },
- { GameItemRarity.Uncommon, rarityTemplate.uncommonChance / 100f }
- };
- GameItemRarity[] rarities = new GameItemRarity[] { GameItemRarity.Unique, GameItemRarity.Epic, GameItemRarity.Rare, GameItemRarity.Uncommon };
- foreach (GameItemRarity rarity in rarities)
- {
- float effectiveChance = Mathf.Clamp(
- rarityChances[rarity] * CalculateEffectiveMagicFind(magicFind, rarity),
- 0f,
- 1f
- );
- if (UnityEngine.Random.Range(0f, 1f) <= effectiveChance)
- {
- return Enchant(baseItemTemplate, rarity, itemLevel);
- }
- }
- return Enchant(baseItemTemplate, GameItemRarity.Common, itemLevel);
- }
- public GameItemTemplate Enchant(GameItemTemplate baseItemTemplate, GameItemRarity rarity, int itemLevel)
- {
- GameItemTemplate gameItemTemplate = ScriptableObject.CreateInstance<GameItemTemplate>();
- gameItemTemplate.itemType = baseItemTemplate.itemType;
- gameItemTemplate.itemRarity = rarity;
- gameItemTemplate.itemName = "LGI_001";
- gameItemTemplate.itemIcon = baseItemTemplate.itemIcon;
- gameItemTemplate.weaponDamageMin = baseItemTemplate.weaponDamageMin;
- gameItemTemplate.weaponDamageMax = baseItemTemplate.weaponDamageMax;
- gameItemTemplate.itemLevel = itemLevel;
- int enchantmentCount = NextEnchantmentCount(rarity);
- Debug.Log("Enchantment Count: " + enchantmentCount);
- Enchantment[] generatedAffixes = GenerateRandomEnchantments(baseItemTemplate.itemType, itemLevel, enchantmentCount, out EnchantmentTemplate[] generatedTemplates);
- Debug.Log("Generated Affixes: " + generatedAffixes.Length);
- gameItemTemplate.enchantments = generatedAffixes;
- gameItemTemplate.isGenerated = true;
- switch (rarity)
- {
- case GameItemRarity.Common:
- gameItemTemplate.itemName = "Null Common";
- break;
- case GameItemRarity.Uncommon:
- gameItemTemplate.itemName = _gameItemNameGenerator.GenerateUncommonName(gameItemTemplate.itemType, gameItemTemplate.itemLevel, generatedTemplates);
- break;
- case GameItemRarity.Rare:
- gameItemTemplate.itemName = _gameItemNameGenerator.GenerateRareName(gameItemTemplate.itemType);
- break;
- case GameItemRarity.Epic:
- gameItemTemplate.itemName = _gameItemNameGenerator.GenerateEpicName(gameItemTemplate.itemType);
- break;
- case GameItemRarity.Unique:
- gameItemTemplate.itemName = "Null Legendary";
- break;
- default:
- gameItemTemplate.itemName = "Error";
- break;
- }
- gameItemTemplate.isEthereal = GenerateEthereal();
- return gameItemTemplate;
- }
- private EnchantmentTemplate[] GetValidEnchantmentTemplates(GameItemType itemType, int itemLevel)
- {
- List<EnchantmentTemplate> validEnchantments = new List<EnchantmentTemplate>();
- foreach (EnchantmentTemplate template in _enchantmentTemplates)
- {
- if (template.levelBracketRange.Contains(itemLevel))
- {
- foreach (GameItemType constraint in template.itemConstraints)
- {
- if (constraint == itemType)
- {
- validEnchantments.Add(template);
- break;
- }
- }
- }
- }
- return validEnchantments.ToArray();
- }
- public Enchantment[] GenerateRandomEnchantments(GameItemType itemType, int itemLevel, int affixCount, out EnchantmentTemplate[] generatedEnchantmentTemplateResults)
- {
- EnchantmentTemplate[] validTemplates = GetValidEnchantmentTemplates(itemType, itemLevel);
- List<Enchantment> generatedEnchantments = new List<Enchantment>();
- List<EnchantmentTemplate> selectedTemplates = new List<EnchantmentTemplate>();
- if (validTemplates.Length == 0)
- {
- generatedEnchantmentTemplateResults = null;
- return generatedEnchantments.ToArray();
- }
- List<EnchantmentTemplate> templatesPool = new List<EnchantmentTemplate>(validTemplates);
- int totalWeight = templatesPool.Sum(t => t.weight);
- for (int i = 0; i < affixCount && templatesPool.Count > 0; i++)
- {
- int randomWeight = UnityEngine.Random.Range(0, totalWeight);
- int cumulativeWeight = 0;
- foreach (EnchantmentTemplate template in templatesPool)
- {
- cumulativeWeight += template.weight;
- if (randomWeight < cumulativeWeight)
- {
- Enchantment newMagicAffix = new Enchantment
- {
- property = template.property,
- parameter = UnityEngine.Random.Range(template.staticParamRange.min, template.staticParamRange.max),
- minParam = UnityEngine.Random.Range(template.minDynamicParamRange.min, template.minDynamicParamRange.max),
- maxParam = UnityEngine.Random.Range(template.maxDynamicParamRange.min, template.maxDynamicParamRange.max),
- priceModifier = template.priceModifier,
- };
- generatedEnchantments.Add(newMagicAffix);
- selectedTemplates.Add(template);
- totalWeight -= template.weight;
- templatesPool.Remove(template);
- break;
- }
- }
- }
- generatedEnchantmentTemplateResults = selectedTemplates.ToArray();
- return generatedEnchantments.ToArray();
- }
- public int NextEnchantmentCount(GameItemRarity rarity)
- {
- switch (rarity)
- {
- case GameItemRarity.Uncommon:
- return UnityEngine.Random.Range(1, 2);
- case GameItemRarity.Rare:
- return UnityEngine.Random.Range(2, 6);
- default:
- return 0;
- }
- }
- public static Enchantment[] CombineDuplicateEnchantments(Enchantment[] enchantments)
- {
- if (enchantments == null || enchantments.Length == 0)
- {
- return Array.Empty<Enchantment>();
- }
- // Preallocate with capacity if input is large to avoid resizing
- Dictionary<EnchantmentProperty, Enchantment> combined = new Dictionary<EnchantmentProperty, Enchantment>(enchantments.Length);
- for (int i = 0; i < enchantments.Length; i++)
- {
- Enchantment enchantment = enchantments[i];
- if (combined.TryGetValue(enchantment.property, out var existing))
- {
- // Accumulate into existing
- existing.parameter += enchantment.parameter;
- existing.minParam += enchantment.minParam;
- existing.maxParam += enchantment.maxParam;
- existing.priceModifier = enchantment.priceModifier;
- }
- else
- {
- // Clone only when needed to avoid unnecessary allocations
- combined[enchantment.property] = new Enchantment
- {
- property = enchantment.property,
- parameter = enchantment.parameter,
- minParam = enchantment.minParam,
- maxParam = enchantment.maxParam,
- priceModifier = enchantment.priceModifier
- };
- }
- }
- // Use collection copy to minimize LINQ overhead
- Enchantment[] result = new Enchantment[combined.Count];
- combined.Values.CopyTo(result, 0);
- return result;
- }
- public bool GenerateEthereal()
- {
- return UnityEngine.Random.Range(0, 10) < 5;
- }
- public void LoadEnchantmentTemplates()
- {
- List<EnchantmentTemplate> templates = new List<EnchantmentTemplate>();
- string fileName = "EnchantmentTemplates";
- try
- {
- TextAsset textAsset = Resources.Load<TextAsset>("Prefabs/Data/" + fileName);
- if (textAsset == null)
- {
- Debug.LogError($"[LoadEnchantmentTemplates] File not found: Resources/Prefabs/Data/{fileName}");
- return;
- }
- string[] lines = textAsset.text.Split(new[] { '\n' }, System.StringSplitOptions.RemoveEmptyEntries);
- Debug.Log($"[LoadEnchantmentTemplates] Loaded {lines.Length} lines from {fileName}.");
- if (lines.Length <= 1)
- {
- Debug.LogWarning("[LoadEnchantmentTemplates] Enchantment template file is empty or missing data.");
- return;
- }
- for (int i = 0; i < lines.Length; i++)
- {
- string[] fields = lines[i].Split(new[] { '\t' }, System.StringSplitOptions.None);
- if (fields.Length < 8)
- {
- Debug.LogWarning($"[LoadEnchantmentTemplates] Skipping line {i + 1}: Not enough fields.");
- continue;
- }
- try
- {
- EnchantmentTemplate enchantmentTemplate = new EnchantmentTemplate();
- if (!Enchantment.TryParseEnchantmentProperty(fields[0], out EnchantmentProperty property))
- {
- Debug.LogWarning($"[LoadEnchantmentTemplates] Line {i + 1}: Could not parse property '{fields[0]}'.");
- continue;
- }
- enchantmentTemplate.property = property;
- enchantmentTemplate.prefix = fields[1];
- enchantmentTemplate.suffix = fields[2];
- enchantmentTemplate.levelBracketRange = Range.Parse(fields[3]);
- enchantmentTemplate.staticParamRange = Range.Parse(fields[4]);
- enchantmentTemplate.minDynamicParamRange = Range.Parse(fields[5]);
- enchantmentTemplate.maxDynamicParamRange = Range.Parse(fields[6]);
- enchantmentTemplate.weight = int.Parse(fields[7]);
- enchantmentTemplate.itemConstraints = ParseGameItemConstraintsField(fields[8]);
- templates.Add(enchantmentTemplate);
- }
- catch (FormatException fe)
- {
- Debug.LogWarning($"[LoadEnchantmentTemplates] Line {i + 1}: Format exception - {fe.Message}");
- }
- catch (System.Exception ex)
- {
- Debug.LogWarning($"[LoadEnchantmentTemplates] Line {i + 1}: Unexpected error - {ex.Message}");
- }
- }
- }
- catch (System.Exception ex)
- {
- Debug.LogError($"[LoadEnchantmentTemplates] Failed to load templates: {ex.Message}");
- return;
- }
- this._enchantmentTemplates = templates;
- Debug.Log($"[LoadEnchantmentTemplates] Successfully loaded {templates.Count} enchantment templates.");
- }
- private static GameItemType[] ParseGameItemConstraintsField(string constraints)
- {
- if (string.IsNullOrWhiteSpace(constraints))
- {
- return new GameItemType[0];
- }
- string[] constraintParts = constraints.Split(",", System.StringSplitOptions.RemoveEmptyEntries);
- List<GameItemType> results = new List<GameItemType>();
- foreach (string constraint in constraintParts)
- {
- string trimmedConstraint = constraint.Trim();
- GameItemType parsedConstraint = ParseGameItemTypeConstraint(trimmedConstraint);
- if (!results.Contains(parsedConstraint))
- {
- results.Add(parsedConstraint);
- }
- }
- return results.ToArray();
- }
- private static GameItemType ParseGameItemTypeConstraint(string constraints)
- {
- switch (constraints)
- {
- case "Dagger":
- return GameItemType.Dagger;
- case "Sword":
- return GameItemType.Sword;
- case "Greatsword":
- return GameItemType.GreatSword;
- case "Axe":
- return GameItemType.Axe;
- case "Greataxe":
- return GameItemType.GreatAxe;
- case "Mace":
- return GameItemType.Mace;
- case "Greatmace":
- return GameItemType.GreatMace;
- case "Bow":
- return GameItemType.Bow;
- case "Head":
- return GameItemType.Headwear;
- case "Chest":
- return GameItemType.Chestwear;
- case "Hand":
- return GameItemType.Handwear;
- case "Foot":
- return GameItemType.Footwear;
- case "Amulet":
- return GameItemType.Amulet;
- case "Ring":
- return GameItemType.Ring;
- case "Shield":
- return GameItemType.Shield;
- case "Charm":
- return GameItemType.Charm;
- default:
- throw new System.Exception("Could not parse GameItemConstraint: '" + constraints + "'!");
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement