Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections.Generic;
- using System.Linq;
- using VoidwalkerEngine.Framework.Collections;
- using VoidwalkerEngine.Framework.DataTypes;
- using VoidwalkerEngine.Framework.Game.Systems.Enchanting;
- using VoidwalkerEngine.Framework.Game.Systems.GameItems;
- using VoidwalkerEngine.Framework.Game.Systems.GameItems.Data;
- using VoidwalkerEngine.Framework.Game.Systems.Loot;
- using VoidwalkerEngine.Framework.Logic;
- using VoidwalkerEngine.Framework.Utilities;
- namespace VoidwalkerEngine.Framework.Algorithms
- {
- public partial class LootGenerator
- {
- private VoidwalkerRandom _random;
- private List<UniqueEquipmentTemplate> _legendaries { get; set; }
- private List<Enchantment> _enchantments { get; set; }
- private GameDatabase _database;
- static LootGenerator()
- {
- InitializeRareNameSuffixes();
- }
- public LootGenerator()
- {
- _enchantments = new List<Enchantment>();
- _random = new VoidwalkerRandom();
- if (_database.Enchantments != null)
- {
- foreach (Enchantment enchantment in _database.Enchantments)
- {
- if (enchantment.IsSpawnable)
- {
- this._enchantments.Add(enchantment);
- }
- }
- this._legendaries = _database.UniqueGameItemTemplates;
- }
- }
- public List<GameItemTemplate> Process(int level, List<LootTableDrop> items)
- {
- if (items == null || items.Count == 0)
- {
- return null;
- }
- List<GameItem> results = new List<GameItem>();
- foreach (LootTableDrop drop in items)
- {
- int quantity = _random.NextRange(drop.Quantity);
- if (quantity > 0)
- {
- if (drop.Item.ItemType.IsGeneratable())
- {
- /**
- * Roll Enchantments for each item in quantity.
- * This allows for multiple items to have different
- * enchantments, and qualities.
- */
- for (int i = 0; i < quantity; i++)
- {
- GameItem item = Generate(drop.Item, drop.LootArgs, level);
- results.Add(item);
- }
- }
- else
- {
- List<GameItem> existingStacks = new List<GameItem>();
- foreach (GameItem item in results)
- {
- if (item.IsStackableWith(drop.Item))
- {
- existingStacks.Add(item);
- }
- }
- if (existingStacks.Count == 0)
- {
- GameItem copy = new GameItem();
- copy.Copy(drop.Item);
- existingStacks.Add(copy);
- }
- int currentStackIndex = 0;
- GameItem stackable = existingStacks[currentStackIndex];
- for (int i = 1; i < quantity; i++)
- {
- int totalQuantity = stackable.Quantity + 1;
- if (totalQuantity <= stackable.StackSize)
- {
- stackable.Quantity++;
- }
- else
- {
- currentStackIndex++;
- GameItem copy = new GameItem();
- copy.Copy(drop.Item);
- existingStacks.Add(copy);
- }
- }
- results.RemoveAll(p => p.Identifier.Equals(drop.Item.Identifier));
- results.AddRange(existingStacks);
- }
- }
- }
- return results;
- return null;
- }
- /// <summary>
- /// Summary
- /// </summary>
- /// <param name="template"></param>
- /// <param name="lootParams"></param>
- /// <param name="level"></param>
- /// <returns></returns>
- public GameItem Generate(GameItemTemplate template, LootDropArgs lootParams, int level)
- {
- GameItem result = new GameItem();
- result.Copy(template);
- result.Quality = GenerateItemQuality(lootParams);
- result.IsEthereal = GenerateEthereal();
- GameItemType itemConstraint = template.ItemType;
- result.Enchantments = new List<Enchantment>();
- int maximumEnchantments = result.Quality.GetMaximumEnchantmentSlots();
- if (result.Quality == QualityType.Legendary)
- {
- maximumEnchantments -= 1;
- }
- int enchantmentCount =
- result.IsEthereal ?
- maximumEnchantments :
- GenerateEnchantmentCount(result.Quality);
- // Generate enchantments based upon quality
- switch (result.Quality)
- {
- case QualityType.Uncommon:
- result.Enchantments = GenerateEnchantments(itemConstraint, level, enchantmentCount);
- break;
- case QualityType.Rare:
- result.Enchantments = GenerateEnchantments(itemConstraint, level, enchantmentCount);
- result.Header = GenerateRareName(itemConstraint);
- break;
- case QualityType.Epic:
- result.Enchantments = GenerateEnchantments(itemConstraint, level, enchantmentCount);
- result.Header = GenerateEpicName();
- break;
- case QualityType.Legendary:
- if (this._legendaries != null)
- {
- List<LegendaryItemTemplate> candidates = new List<LegendaryItemTemplate>();
- foreach (LegendaryItemTemplate candidate in this._legendaries)
- {
- if (candidate.Constraints.Contains(itemConstraint))
- {
- if (candidate.LevelBracket.Contains(level))
- {
- candidates.Add(candidate);
- }
- }
- }
- if (candidates.Count > 0)
- {
- LegendaryItemTemplate legendary = _random.Choose(candidates);
- result.LegendaryTemplate = legendary;
- result.Enchantments = GenerateEnchantments(itemConstraint, level, enchantmentCount);
- result.Header = legendary.Header;
- break;
- }
- }
- /**
- * The player rolled a legendary, however the routine failed. This may mean
- * that no legendary exists for their level bracket, or the item type has no
- * corresponding legendary. We will default to giving them a guaranteed epic.
- */
- result.Quality = QualityType.Epic;
- goto case QualityType.Epic;
- }
- result.Repair();
- return result;
- return null;
- }
- /// <summary>
- /// sdfsdf
- /// </summary>
- /// <param name="dropArgs"></param>
- /// <returns></returns>
- public QualityType GenerateItemQuality(LootDropArgs dropArgs)
- {
- /**
- * This needs to handle probabilities as doubles instead.
- */
- if (_random.NextProbability(dropArgs.LegendaryChance))
- {
- return QualityType.Unique;
- }
- if (_random.NextProbability(dropArgs.EpicChance))
- {
- return QualityType.Epic;
- }
- if (_random.NextProbability(dropArgs.RareChance))
- {
- return QualityType.Rare;
- }
- if (_random.NextProbability(dropArgs.UncommonChance))
- {
- return QualityType.Uncommon;
- }
- return QualityType.Common;
- }
- /// <summary>
- /// Attempts to generate the flag for an item being Ethereal
- /// The current odds of rolling an Ethereal item is 1 in 1024 (0.0009765625%)
- /// </summary>
- public bool GenerateEthereal()
- {
- return _random.NextProbability(new Probability(1, 1024));
- }
- /// <summary>
- /// sfsdf
- /// </summary>
- /// <param name="constraint"></param>
- /// <param name="level"></param>
- /// <returns></returns>
- public Enchantment GenerateEnchantment(GameItemType constraint, int level)
- {
- if (this._enchantments == null || this._enchantments.Count == 0)
- {
- return null;
- }
- return GenerateEnchantments(constraint, level, 1)[0];
- }
- /// <summary>
- /// fsdfsdf
- /// </summary>
- /// <param name="constraint"></param>
- /// <param name="level"></param>
- /// <param name="count"></param>
- /// <param name="allowDuplicates"></param>
- /// <returns></returns>
- private List<Enchantment> GenerateEnchantments(GameItemType constraint, int level, int count, bool allowDuplicates = false)
- {
- List<Enchantment> results = new List<Enchantment>();
- if (count == 0)
- {
- return results;
- }
- int totalFitness = 0;
- List<Enchantment> filteredEnchantments = new List<Enchantment>();
- foreach (Enchantment candidate in this._enchantments)
- {
- if (candidate.Constraints.Contains(constraint) && candidate.LevelBracket.Contains(level))
- {
- filteredEnchantments.Add(candidate);
- totalFitness += candidate.Frequency;
- }
- }
- if (filteredEnchantments.Count < count)
- {
- count = filteredEnchantments.Count;
- if (count == 0)
- {
- return results;
- }
- }
- filteredEnchantments.OrderBy(enchantment => enchantment.Frequency).Reverse().ToList();
- int enchantmentsGenerated = 0;
- bool isSearching = true;
- int attempts = 0;
- const int maximumAttempts = 32; // Prevent Infinite Loops
- while (isSearching)
- {
- Enchantment selectedEnchantment = null;
- int randomSample = _random.NextInteger(totalFitness);
- foreach (Enchantment attempt in filteredEnchantments)
- {
- if (randomSample < attempt.Frequency)
- {
- selectedEnchantment = attempt;
- break;
- }
- randomSample -= attempt.Frequency;
- }
- if (allowDuplicates ||
- !results.Any(e => e == selectedEnchantment) &&
- !results.Any(e => e.Family.Equals(selectedEnchantment.Family)))
- {
- attempts = 0;
- results.Add(selectedEnchantment);
- enchantmentsGenerated++;
- }
- attempts++;
- if (enchantmentsGenerated == count || attempts >= maximumAttempts)
- {
- isSearching = false;
- }
- }
- return results;
- }
- private int GenerateEnchantmentCount(QualityType quality)
- {
- int result = 0;
- switch (quality)
- {
- case QualityType.Uncommon:
- if (_random.NextProbability(75))
- {
- return 1;
- }
- break;
- case QualityType.Rare:
- if (_random.NextProbability(75))
- {
- result += 1;
- }
- if (_random.NextProbability(40))
- {
- result += 1;
- }
- break;
- case QualityType.Epic:
- if (_random.NextProbability(75))
- {
- result += 1;
- }
- for (int i = 0; i < 2; i++)
- {
- if (_random.NextProbability(40))
- {
- result += 1;
- }
- }
- break;
- case QualityType.Unique:
- if (_random.NextProbability(75))
- {
- result += 1;
- }
- if (_random.NextProbability(75))
- {
- result += 1;
- }
- if (_random.NextProbability(40))
- {
- result += 1;
- }
- break;
- }
- return result;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement