Introduce PickRandom and TryPickRandom extensions

This commit is contained in:
Stepan Goremykin 2023-01-29 14:49:27 +01:00
parent f39f26f7e2
commit c9a70d7e63
8 changed files with 111 additions and 90 deletions

View File

@ -1,13 +1,13 @@
//Blizzless Project 2022
using System;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using DiIiS_NA.Core.Helpers.Math;
namespace DiIiS_NA.Core.Extensions
namespace DiIiS_NA.Core.Extensions;
public static class EnumerableExtensions
{
public static class EnumerableExtensions
{
public static string HexDump(this IEnumerable<byte> collection)
{
var sb = new StringBuilder();
@ -44,7 +44,7 @@ namespace DiIiS_NA.Core.Extensions
}
hex.Append(value.ToString("X2"));
hex.Append(' ');
text.Append(string.Format("{0}", (char.IsWhiteSpace((char)value) && (char)value != ' ') ? '.' : (char)value)); // prettify text
text.Append($"{((char.IsWhiteSpace((char)value) && (char)value != ' ') ? '.' : (char)value)}"); // prettify text
++i;
}
var hexstring = hex.ToString();
@ -57,5 +57,14 @@ namespace DiIiS_NA.Core.Extensions
output.Append(text);
return output.ToString();
}
public static TItem PickRandom<TItem>(this IEnumerable<TItem> source)
{
return RandomHelper.RandomItem(source);
}
public static bool TryPickRandom<TItem>(this IEnumerable<TItem> source, out TItem randomItem)
{
return RandomHelper.TryGetRandomItem(source, out randomItem);
}
}

View File

@ -1,7 +1,6 @@
using System;
using System.Linq;
using System.Collections.Generic;
using DiIiS_NA.Core.Logging;
namespace DiIiS_NA.Core.Helpers.Math;
@ -46,6 +45,26 @@ public static class RandomHelper
return collection.ElementAt(randomIndex);
}
public static bool TryGetRandomItem<T>(IEnumerable<T> source, out T randomItem)
{
var collection = source as IReadOnlyCollection<T> ?? source?.ToArray();
if (collection == null)
{
throw new ArgumentException("Cannot be null", nameof(source));
}
if (collection.Count == 0)
{
randomItem = default;
return false;
}
var randomIndex = Next(collection.Count);
randomItem = collection.ElementAt(randomIndex);
return true;
}
/// <summary>
/// Picks a random item from a list
/// </summary>
@ -74,26 +93,26 @@ public static class RandomHelper
public class ItemRandomHelper
{
uint a;
uint b;
uint _a;
uint _b;
public ItemRandomHelper(int seed)
{
a = (uint)seed;
b = 666;
_a = (uint)seed;
_b = 666;
}
public void ReinitSeed()
{
b = 666;
_b = 666;
}
public uint Next()
{
ulong temp = 1791398085UL * a + b;
a = (uint)temp;
b = (uint)(temp >> 32);
ulong temp = 1791398085UL * _a + _b;
_a = (uint)temp;
_b = (uint)(temp >> 32);
return a;
return _a;
}
public float Next(float min, float max)

View File

@ -7,6 +7,7 @@ using DiIiS_NA.Core.MPQ.FileFormats.Types;
using DiIiS_NA.GameServer.Core.Types.TagMap;
using System.Linq;
using System;
using DiIiS_NA.Core.Extensions;
using DiIiS_NA.Core.Helpers.Math;
using DiIiS_NA.D3_GameServer.Core.Types.SNO;
@ -104,7 +105,7 @@ namespace DiIiS_NA.Core.MPQ.FileFormats
}
var possibleDeaths = deathTags.Select(GetAniSNO).Where(x => x != AnimationSno._NONE);
return RandomHelper.RandomItem(possibleDeaths);
return possibleDeaths.PickRandom();
}
}
public enum AnimationTags

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DiIiS_NA.Core.Extensions;
using DiIiS_NA.Core.Helpers.Math;
using DiIiS_NA.Core.MPQ;
using DiIiS_NA.D3_GameServer.Core.Types.SNO;
@ -196,12 +197,12 @@ namespace DiIiS_NA.GameServer.GSSystem.AISystem.Brains
// randomly used an implemented power
if (PresetPowers.Count > 0)
{
//int power = this.PresetPowers[RandomHelper.Next(this.PresetPowers.Count)].Key;
// int power = this.PresetPowers[RandomHelper.Next(this.PresetPowers.Count)].Key;
List<int> availablePowers = PresetPowers.Where(p => (p.Value.CooldownTimer == null || p.Value.CooldownTimer.TimedOut) && PowerLoader.HasImplementationForPowerSNO(p.Key)).Select(p => p.Key).ToList();
if (availablePowers.Any(p => p != 30592))
return availablePowers.Where(p => p != 30592).ToList()[RandomHelper.Next(availablePowers.Count(p => p != 30592))];
if (availablePowers.Where(p => p != 30592).TryPickRandom(out var randomItem))
return randomItem;
if (availablePowers.Contains(30592))
return 30592; //melee attack
return 30592; // melee attack
}
// no usable power

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DiIiS_NA.Core.Extensions;
using DiIiS_NA.Core.Helpers.Math;
using DiIiS_NA.Core.Logging;
using DiIiS_NA.Core.MPQ;
@ -435,16 +436,13 @@ namespace DiIiS_NA.GameServer.GSSystem.AISystem.Brains
//int power = this.PresetPowers[RandomHelper.Next(this.PresetPowers.Count)].Key;
var availablePowers = PresetPowers.Where(p => (p.Value.CooldownTimer == null || p.Value.CooldownTimer.TimedOut) && PowerLoader.HasImplementationForPowerSNO(p.Key)).Select(p => p.Key).ToList();
if (availablePowers.Count(p => p != 30592) > 0)
if (availablePowers.Where(p => p != 30592).TryPickRandom(out var selectedPower))
{
int SelectedPower = availablePowers.Where(p => p != 30592).ToList()[RandomHelper.Next(availablePowers.Count(p => p != 30592))];
//if(SelectedPower == 73824)
//if(SkeletonKingWhirlwind)
return SelectedPower;
return selectedPower;
}
if (availablePowers.Contains(30592))
return 30592; //melee attack
return 30592; // melee attack
// no usable power
return -1;

View File

@ -1,6 +1,7 @@
using DiIiS_NA.Core.Logging;
using System.Collections.Generic;
using System.Linq;
using DiIiS_NA.Core.Extensions;
using DiIiS_NA.GameServer.GSSystem.AISystem.Brains;
using static DiIiS_NA.Core.MPQ.FileFormats.GameBalance;
using Actor = DiIiS_NA.GameServer.GSSystem.ActorSystem.Actor;
@ -250,17 +251,13 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
public static int GeneratePrefixName()
{
var prefixes = NamesList.Where(n => n.AffixType == AffixType.Prefix);
var randomPrefix = RandomHelper.RandomItem(prefixes);
var randomPrefix = NamesList.Where(n => n.AffixType == AffixType.Prefix).PickRandom();
return randomPrefix.Hash;
}
public static int GenerateSuffixName()
{
var prefixes = NamesList.Where(n => n.AffixType == AffixType.Suffix);
var randomPrefix = RandomHelper.RandomItem(prefixes);
var randomPrefix = NamesList.Where(n => n.AffixType == AffixType.Suffix).PickRandom();
return randomPrefix.Hash;
}
}

View File

@ -302,11 +302,8 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
else
{
var entries = clusterSelected[sceneChunk.SceneSpecification.ClusterID];
SubSceneEntry subSceneEntry = null;
if (entries.Count > 0)
if (entries.TryPickRandom(out var subSceneEntry))
{
subSceneEntry = RandomHelper.RandomItem(entries);
entries.Remove(subSceneEntry);
}
else
@ -1975,7 +1972,7 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
for (int i = 0; i < count; i++)
{
//Chose a random exit to test
Vector3D chosenExitPosition = RandomHelper.RandomItem(exitTypes).Value;
Vector3D chosenExitPosition = exitTypes.PickRandom().Value;
var chosenExitDirection = (from pair in exitTypes
where pair.Value == chosenExitPosition
select pair.Key).FirstOrDefault();
@ -2087,7 +2084,7 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
return null;
}
return RandomHelper.RandomItem(tilesWithRightDirection);
return tilesWithRightDirection.PickRandom();
}
private TileInfo GetTile(Dictionary<int, TileInfo> tiles, int snoId)
@ -2105,7 +2102,7 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
private TileInfo GetTileInfo(Dictionary<int, TileInfo> tiles, TileTypes tileType)
{
var tilesWithRightType = tiles.Values.Where(tile => tile.TileType == (int)tileType);
return RandomHelper.RandomItem(tilesWithRightType);
return tilesWithRightType.PickRandom();
}
private TileInfo GetTileInfo(Dictionary<int, TileInfo> tiles, TileTypes tileType, int exitDirectionBits)

View File

@ -17,6 +17,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DiIiS_NA.Core.Extensions;
namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Implementations
{
@ -3300,10 +3301,8 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Implementations
Remove();
var newms = payload.Target.GetMonstersInRange(40f);
if (newms.Count > 0)
if (newms.TryPickRandom(out var target))
{
var target = RandomHelper.RandomItem(newms);
AddBuff(target, new Rune_B_Buff());
}
}
@ -4497,7 +4496,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Implementations
{
Founded = true;
var possibleTargets = projectile.GetMonstersInRange(25f);
var target = RandomHelper.RandomItem(possibleTargets);
var target = possibleTargets.PickRandom();
projectile.Launch(target.Position, 1f);
}
};