Advertisement
Krythic

wfsfsdf

Aug 27th, 2021
1,206
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.87 KB | None | 0 0
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using VoidwalkerEngine.Framework.Collections;
  4. using VoidwalkerEngine.Framework.DataTypes;
  5. using VoidwalkerEngine.Framework.Game.Systems.Enchanting;
  6. using VoidwalkerEngine.Framework.Game.Systems.GameItems;
  7. using VoidwalkerEngine.Framework.Game.Systems.GameItems.Data;
  8. using VoidwalkerEngine.Framework.Game.Systems.Loot;
  9. using VoidwalkerEngine.Framework.Logic;
  10. using VoidwalkerEngine.Framework.Utilities;
  11.  
  12. namespace VoidwalkerEngine.Framework.Algorithms
  13. {
  14.     public partial class LootGenerator
  15.     {
  16.         private VoidwalkerRandom _random;
  17.         private List<UniqueEquipmentTemplate> _legendaries { get; set; }
  18.         private List<Enchantment> _enchantments { get; set; }
  19.         private GameDatabase _database;
  20.  
  21.         static LootGenerator()
  22.         {
  23.             InitializeRareNameSuffixes();
  24.         }
  25.  
  26.         public LootGenerator()
  27.         {
  28.             _enchantments = new List<Enchantment>();
  29.             _random = new VoidwalkerRandom();
  30.             if (_database.Enchantments != null)
  31.             {
  32.                 foreach (Enchantment enchantment in _database.Enchantments)
  33.                 {
  34.                     if (enchantment.IsSpawnable)
  35.                     {
  36.                         this._enchantments.Add(enchantment);
  37.                     }
  38.                 }
  39.                 this._legendaries = _database.UniqueGameItemTemplates;
  40.             }
  41.         }
  42.  
  43.         public List<GameItemTemplate> Process(int level, List<LootTableDrop> items)
  44.         {
  45.             if (items == null || items.Count == 0)
  46.             {
  47.                 return null;
  48.             }
  49.             List<GameItem> results = new List<GameItem>();
  50.  
  51.             foreach (LootTableDrop drop in items)
  52.             {
  53.                 int quantity = _random.NextRange(drop.Quantity);
  54.                 if (quantity > 0)
  55.                 {
  56.                     if (drop.Item.ItemType.IsGeneratable())
  57.                     {
  58.                         /**
  59.                          * Roll Enchantments for each item in quantity.
  60.                          * This allows for multiple items to have different
  61.                          * enchantments, and qualities.
  62.                          */
  63.                         for (int i = 0; i < quantity; i++)
  64.                         {
  65.                             GameItem item = Generate(drop.Item, drop.LootArgs, level);
  66.                             results.Add(item);
  67.                         }
  68.                     }
  69.                     else
  70.                     {
  71.                         List<GameItem> existingStacks = new List<GameItem>();
  72.                         foreach (GameItem item in results)
  73.                         {
  74.                             if (item.IsStackableWith(drop.Item))
  75.                             {
  76.                                 existingStacks.Add(item);
  77.                             }
  78.                         }
  79.                         if (existingStacks.Count == 0)
  80.                         {
  81.                             GameItem copy = new GameItem();
  82.                             copy.Copy(drop.Item);
  83.                             existingStacks.Add(copy);
  84.                         }
  85.                         int currentStackIndex = 0;
  86.                         GameItem stackable = existingStacks[currentStackIndex];
  87.                         for (int i = 1; i < quantity; i++)
  88.                         {
  89.                             int totalQuantity = stackable.Quantity + 1;
  90.                             if (totalQuantity <= stackable.StackSize)
  91.                             {
  92.                                 stackable.Quantity++;
  93.                             }
  94.                             else
  95.                             {
  96.                                 currentStackIndex++;
  97.                                 GameItem copy = new GameItem();
  98.                                 copy.Copy(drop.Item);
  99.                                 existingStacks.Add(copy);
  100.                             }
  101.                         }
  102.                         results.RemoveAll(p => p.Identifier.Equals(drop.Item.Identifier));
  103.                         results.AddRange(existingStacks);
  104.                     }
  105.                 }
  106.             }
  107.             return results;
  108.             return null;
  109.         }
  110.  
  111.         /// <summary>
  112.         ///  Summary
  113.         /// </summary>
  114.         /// <param name="template"></param>
  115.         /// <param name="lootParams"></param>
  116.         /// <param name="level"></param>
  117.         /// <returns></returns>
  118.         public GameItem Generate(GameItemTemplate template, LootDropArgs lootParams, int level)
  119.         {
  120.             GameItem result = new GameItem();
  121.             result.Copy(template);
  122.             result.Quality = GenerateItemQuality(lootParams);
  123.             result.IsEthereal = GenerateEthereal();
  124.             GameItemType itemConstraint = template.ItemType;
  125.             result.Enchantments = new List<Enchantment>();
  126.  
  127.             int maximumEnchantments = result.Quality.GetMaximumEnchantmentSlots();
  128.             if (result.Quality == QualityType.Legendary)
  129.             {
  130.                 maximumEnchantments -= 1;
  131.             }
  132.             int enchantmentCount =
  133.                 result.IsEthereal ?
  134.                 maximumEnchantments :
  135.                 GenerateEnchantmentCount(result.Quality);
  136.             // Generate enchantments based upon quality
  137.             switch (result.Quality)
  138.             {
  139.                 case QualityType.Uncommon:
  140.                     result.Enchantments = GenerateEnchantments(itemConstraint, level, enchantmentCount);
  141.                     break;
  142.  
  143.                 case QualityType.Rare:
  144.                     result.Enchantments = GenerateEnchantments(itemConstraint, level, enchantmentCount);
  145.                     result.Header = GenerateRareName(itemConstraint);
  146.                     break;
  147.  
  148.                 case QualityType.Epic:
  149.                     result.Enchantments = GenerateEnchantments(itemConstraint, level, enchantmentCount);
  150.                     result.Header = GenerateEpicName();
  151.                     break;
  152.  
  153.                 case QualityType.Legendary:
  154.                     if (this._legendaries != null)
  155.                     {
  156.                         List<LegendaryItemTemplate> candidates = new List<LegendaryItemTemplate>();
  157.                         foreach (LegendaryItemTemplate candidate in this._legendaries)
  158.                         {
  159.                             if (candidate.Constraints.Contains(itemConstraint))
  160.                             {
  161.                                 if (candidate.LevelBracket.Contains(level))
  162.                                 {
  163.                                     candidates.Add(candidate);
  164.                                 }
  165.                             }
  166.                         }
  167.                         if (candidates.Count > 0)
  168.                         {
  169.                             LegendaryItemTemplate legendary = _random.Choose(candidates);
  170.                             result.LegendaryTemplate = legendary;
  171.                             result.Enchantments = GenerateEnchantments(itemConstraint, level, enchantmentCount);
  172.                             result.Header = legendary.Header;
  173.                             break;
  174.                         }
  175.                     }
  176.                     /**
  177.                      * The player rolled a legendary, however the routine failed. This may mean
  178.                      * that no legendary exists for their level bracket, or the item type has no
  179.                      * corresponding legendary. We will default to giving them a guaranteed epic.
  180.                      */
  181.                     result.Quality = QualityType.Epic;
  182.                     goto case QualityType.Epic;
  183.             }
  184.             result.Repair();
  185.             return result;
  186.             return null;
  187.         }
  188.  
  189.         /// <summary>
  190.         /// sdfsdf
  191.         /// </summary>
  192.         /// <param name="dropArgs"></param>
  193.         /// <returns></returns>
  194.         public QualityType GenerateItemQuality(LootDropArgs dropArgs)
  195.         {
  196.             /**
  197.              * This needs to handle probabilities as doubles instead.
  198.              */
  199.             if (_random.NextProbability(dropArgs.LegendaryChance))
  200.             {
  201.                 return QualityType.Unique;
  202.             }
  203.             if (_random.NextProbability(dropArgs.EpicChance))
  204.             {
  205.                 return QualityType.Epic;
  206.             }
  207.             if (_random.NextProbability(dropArgs.RareChance))
  208.             {
  209.                 return QualityType.Rare;
  210.             }
  211.             if (_random.NextProbability(dropArgs.UncommonChance))
  212.             {
  213.                 return QualityType.Uncommon;
  214.             }
  215.             return QualityType.Common;
  216.         }
  217.  
  218.         /// <summary>
  219.         /// Attempts to generate the flag for an item being Ethereal
  220.         /// The current odds of rolling an Ethereal item is 1 in 1024 (‭‭0.0009765625‬%)
  221.         /// </summary>
  222.         public bool GenerateEthereal()
  223.         {
  224.             return _random.NextProbability(new Probability(1, 1024));
  225.         }
  226.  
  227.         /// <summary>
  228.         /// sfsdf
  229.         /// </summary>
  230.         /// <param name="constraint"></param>
  231.         /// <param name="level"></param>
  232.         /// <returns></returns>
  233.         public Enchantment GenerateEnchantment(GameItemType constraint, int level)
  234.         {
  235.             if (this._enchantments == null || this._enchantments.Count == 0)
  236.             {
  237.                 return null;
  238.             }
  239.             return GenerateEnchantments(constraint, level, 1)[0];
  240.         }
  241.  
  242.         /// <summary>
  243.         /// fsdfsdf
  244.         /// </summary>
  245.         /// <param name="constraint"></param>
  246.         /// <param name="level"></param>
  247.         /// <param name="count"></param>
  248.         /// <param name="allowDuplicates"></param>
  249.         /// <returns></returns>
  250.         private List<Enchantment> GenerateEnchantments(GameItemType constraint, int level, int count, bool allowDuplicates = false)
  251.         {
  252.             List<Enchantment> results = new List<Enchantment>();
  253.             if (count == 0)
  254.             {
  255.                 return results;
  256.             }
  257.             int totalFitness = 0;
  258.             List<Enchantment> filteredEnchantments = new List<Enchantment>();
  259.             foreach (Enchantment candidate in this._enchantments)
  260.             {
  261.                 if (candidate.Constraints.Contains(constraint) && candidate.LevelBracket.Contains(level))
  262.                 {
  263.                     filteredEnchantments.Add(candidate);
  264.                     totalFitness += candidate.Frequency;
  265.                 }
  266.             }
  267.             if (filteredEnchantments.Count < count)
  268.             {
  269.                 count = filteredEnchantments.Count;
  270.                 if (count == 0)
  271.                 {
  272.                     return results;
  273.                 }
  274.             }
  275.             filteredEnchantments.OrderBy(enchantment => enchantment.Frequency).Reverse().ToList();
  276.             int enchantmentsGenerated = 0;
  277.             bool isSearching = true;
  278.             int attempts = 0;
  279.             const int maximumAttempts = 32; // Prevent Infinite Loops
  280.             while (isSearching)
  281.             {
  282.                 Enchantment selectedEnchantment = null;
  283.                 int randomSample = _random.NextInteger(totalFitness);
  284.                 foreach (Enchantment attempt in filteredEnchantments)
  285.                 {
  286.                     if (randomSample < attempt.Frequency)
  287.                     {
  288.                         selectedEnchantment = attempt;
  289.                         break;
  290.                     }
  291.                     randomSample -= attempt.Frequency;
  292.                 }
  293.                 if (allowDuplicates ||
  294.                     !results.Any(e => e == selectedEnchantment) &&
  295.                     !results.Any(e => e.Family.Equals(selectedEnchantment.Family)))
  296.                 {
  297.                     attempts = 0;
  298.                     results.Add(selectedEnchantment);
  299.                     enchantmentsGenerated++;
  300.                 }
  301.                 attempts++;
  302.                 if (enchantmentsGenerated == count || attempts >= maximumAttempts)
  303.                 {
  304.                     isSearching = false;
  305.                 }
  306.             }
  307.             return results;
  308.         }
  309.  
  310.         private int GenerateEnchantmentCount(QualityType quality)
  311.         {
  312.             int result = 0;
  313.             switch (quality)
  314.             {
  315.                 case QualityType.Uncommon:
  316.                     if (_random.NextProbability(75))
  317.                     {
  318.                         return 1;
  319.                     }
  320.                     break;
  321.  
  322.                 case QualityType.Rare:
  323.                     if (_random.NextProbability(75))
  324.                     {
  325.                         result += 1;
  326.                     }
  327.                     if (_random.NextProbability(40))
  328.                     {
  329.                         result += 1;
  330.                     }
  331.                     break;
  332.  
  333.                 case QualityType.Epic:
  334.                     if (_random.NextProbability(75))
  335.                     {
  336.                         result += 1;
  337.                     }
  338.                     for (int i = 0; i < 2; i++)
  339.                     {
  340.                         if (_random.NextProbability(40))
  341.                         {
  342.                             result += 1;
  343.                         }
  344.                     }
  345.                     break;
  346.  
  347.                 case QualityType.Unique:
  348.                     if (_random.NextProbability(75))
  349.                     {
  350.                         result += 1;
  351.                     }
  352.                     if (_random.NextProbability(75))
  353.                     {
  354.                         result += 1;
  355.                     }
  356.                     if (_random.NextProbability(40))
  357.                     {
  358.                         result += 1;
  359.                     }
  360.                     break;
  361.             }
  362.             return result;
  363.         }
  364.     }
  365. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement