server-master/srcs/_plugins/WingsEmu.Plugins.BasicImplementation/Algorithms/ShellGenerationAlgorithm.cs
2026-02-10 18:21:30 +01:00

98 lines
No EOL
3.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using WingsAPI.Packets.Enums.Shells;
using WingsEmu.DTOs.Items;
using WingsEmu.Game;
using WingsEmu.Game.Algorithm;
using WingsEmu.Plugins.BasicImplementations.Algorithms.Shells;
namespace WingsEmu.Plugins.BasicImplementations.Algorithms;
public class ShellGenerationAlgorithm : IShellGenerationAlgorithm
{
private readonly IRandomGenerator _randomGenerator;
private readonly ShellCategoryConfiguration _shellCategoryConfiguration;
private readonly IShellLevelEffectConfiguration _shellLevelEffect;
private readonly IShellOptionTypeConfiguration _shellOptionType;
public ShellGenerationAlgorithm(IRandomGenerator randomGenerator, IShellOptionTypeConfiguration shellOptionType, IShellLevelEffectConfiguration shellLevelEffect,
ShellCategoryConfiguration shellCategoryConfiguration)
{
_randomGenerator = randomGenerator;
_shellOptionType = shellOptionType;
_shellLevelEffect = shellLevelEffect;
_shellCategoryConfiguration = shellCategoryConfiguration;
}
public IEnumerable<EquipmentOptionDTO> GenerateShell(byte shellType, int shellRarity, int shellLevel)
{
var shellOptions = new List<EquipmentOptionDTO>();
var optionsAlreadyOn = new List<byte>();
IReadOnlyCollection<ShellPossibleCategory> possibleCategories = _shellLevelEffect.GetEffects(shellType, (byte)shellRarity);
if (possibleCategories == null)
{
return shellOptions;
}
foreach (ShellPossibleCategory possibleCategory in possibleCategories)
{
IReadOnlyCollection<ShellEffectType> possibleEffects = _shellCategoryConfiguration.FirstOrDefault(s => s.EffectCategory == possibleCategory.EffectCategory)?.PossibleEffects;
if (possibleEffects == null)
{
continue;
}
var possibleOptions = possibleEffects.Where(s => !optionsAlreadyOn.Contains((byte)s)).ToList();
if (!possibleOptions.Any())
{
continue;
}
if (possibleCategory.IsRandom && _randomGenerator.RandomNumber(2) != 0)
{
continue;
}
byte generatedOption = (byte)possibleOptions[_randomGenerator.RandomNumber(possibleOptions.Count)];
int? optionValue = GenerateOptionValue(generatedOption, (byte)possibleCategory.EffectCategory, shellLevel);
if (optionValue == null)
{
continue;
}
optionsAlreadyOn.Add(generatedOption);
shellOptions.Add(new EquipmentOptionDTO
{
EquipmentOptionType = generatedOption > 50 ? EquipmentOptionType.ARMOR_SHELL : EquipmentOptionType.WEAPON_SHELL, // TODO: seperate it after closed-beta gameplay
Level = (byte)possibleCategory.EffectCategory,
Type = generatedOption,
Value = (int)optionValue
});
}
return shellOptions;
}
private int? GenerateOptionValue(byte randomShellEffectType, byte shellEffectCategory, int shellLevel)
{
try
{
int[] shellOptionValues = _shellOptionType.GetByTypeAndEffect(randomShellEffectType, shellEffectCategory);
if (shellOptionValues == null)
{
return null;
}
int m = _randomGenerator.RandomNumber(shellOptionValues[0] * shellLevel, shellOptionValues[1] * shellLevel);
int value = (int)Math.Floor((double)m / 100);
return value == 0 ? 1 : value;
}
catch (Exception e)
{
return null;
}
}
}