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,11 +1,11 @@
//Blizzless Project 2022 using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Linq; 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) public static string HexDump(this IEnumerable<byte> collection)
@ -44,7 +44,7 @@ namespace DiIiS_NA.Core.Extensions
} }
hex.Append(value.ToString("X2")); hex.Append(value.ToString("X2"));
hex.Append(' '); 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; ++i;
} }
var hexstring = hex.ToString(); var hexstring = hex.ToString();
@ -57,5 +57,14 @@ namespace DiIiS_NA.Core.Extensions
output.Append(text); output.Append(text);
return output.ToString(); 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;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using DiIiS_NA.Core.Logging;
namespace DiIiS_NA.Core.Helpers.Math; namespace DiIiS_NA.Core.Helpers.Math;
@ -46,6 +45,26 @@ public static class RandomHelper
return collection.ElementAt(randomIndex); 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> /// <summary>
/// Picks a random item from a list /// Picks a random item from a list
/// </summary> /// </summary>
@ -74,26 +93,26 @@ public static class RandomHelper
public class ItemRandomHelper public class ItemRandomHelper
{ {
uint a; uint _a;
uint b; uint _b;
public ItemRandomHelper(int seed) public ItemRandomHelper(int seed)
{ {
a = (uint)seed; _a = (uint)seed;
b = 666; _b = 666;
} }
public void ReinitSeed() public void ReinitSeed()
{ {
b = 666; _b = 666;
} }
public uint Next() public uint Next()
{ {
ulong temp = 1791398085UL * a + b; ulong temp = 1791398085UL * _a + _b;
a = (uint)temp; _a = (uint)temp;
b = (uint)(temp >> 32); _b = (uint)(temp >> 32);
return a; return _a;
} }
public float Next(float min, float max) 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 DiIiS_NA.GameServer.Core.Types.TagMap;
using System.Linq; using System.Linq;
using System; using System;
using DiIiS_NA.Core.Extensions;
using DiIiS_NA.Core.Helpers.Math; using DiIiS_NA.Core.Helpers.Math;
using DiIiS_NA.D3_GameServer.Core.Types.SNO; 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); var possibleDeaths = deathTags.Select(GetAniSNO).Where(x => x != AnimationSno._NONE);
return RandomHelper.RandomItem(possibleDeaths); return possibleDeaths.PickRandom();
} }
} }
public enum AnimationTags public enum AnimationTags

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using DiIiS_NA.Core.Extensions;
using DiIiS_NA.Core.Helpers.Math; using DiIiS_NA.Core.Helpers.Math;
using DiIiS_NA.Core.MPQ; using DiIiS_NA.Core.MPQ;
using DiIiS_NA.D3_GameServer.Core.Types.SNO; using DiIiS_NA.D3_GameServer.Core.Types.SNO;
@ -198,8 +199,8 @@ namespace DiIiS_NA.GameServer.GSSystem.AISystem.Brains
{ {
// 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(); 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)) if (availablePowers.Where(p => p != 30592).TryPickRandom(out var randomItem))
return availablePowers.Where(p => p != 30592).ToList()[RandomHelper.Next(availablePowers.Count(p => p != 30592))]; return randomItem;
if (availablePowers.Contains(30592)) if (availablePowers.Contains(30592))
return 30592; // melee attack return 30592; // melee attack
} }

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using DiIiS_NA.Core.Extensions;
using DiIiS_NA.Core.Helpers.Math; using DiIiS_NA.Core.Helpers.Math;
using DiIiS_NA.Core.Logging; using DiIiS_NA.Core.Logging;
using DiIiS_NA.Core.MPQ; using DiIiS_NA.Core.MPQ;
@ -435,12 +436,9 @@ namespace DiIiS_NA.GameServer.GSSystem.AISystem.Brains
//int power = this.PresetPowers[RandomHelper.Next(this.PresetPowers.Count)].Key; //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(); 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))]; return selectedPower;
//if(SelectedPower == 73824)
//if(SkeletonKingWhirlwind)
return SelectedPower;
} }
if (availablePowers.Contains(30592)) if (availablePowers.Contains(30592))

View File

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

View File

@ -302,11 +302,8 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
else else
{ {
var entries = clusterSelected[sceneChunk.SceneSpecification.ClusterID]; var entries = clusterSelected[sceneChunk.SceneSpecification.ClusterID];
SubSceneEntry subSceneEntry = null; if (entries.TryPickRandom(out var subSceneEntry))
if (entries.Count > 0)
{ {
subSceneEntry = RandomHelper.RandomItem(entries);
entries.Remove(subSceneEntry); entries.Remove(subSceneEntry);
} }
else else
@ -1975,7 +1972,7 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
//Chose a random exit to test //Chose a random exit to test
Vector3D chosenExitPosition = RandomHelper.RandomItem(exitTypes).Value; Vector3D chosenExitPosition = exitTypes.PickRandom().Value;
var chosenExitDirection = (from pair in exitTypes var chosenExitDirection = (from pair in exitTypes
where pair.Value == chosenExitPosition where pair.Value == chosenExitPosition
select pair.Key).FirstOrDefault(); select pair.Key).FirstOrDefault();
@ -2087,7 +2084,7 @@ namespace DiIiS_NA.GameServer.GSSystem.GeneratorsSystem
return null; return null;
} }
return RandomHelper.RandomItem(tilesWithRightDirection); return tilesWithRightDirection.PickRandom();
} }
private TileInfo GetTile(Dictionary<int, TileInfo> tiles, int snoId) 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) private TileInfo GetTileInfo(Dictionary<int, TileInfo> tiles, TileTypes tileType)
{ {
var tilesWithRightType = tiles.Values.Where(tile => tile.TileType == (int)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) 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.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using DiIiS_NA.Core.Extensions;
namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Implementations namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Implementations
{ {
@ -3300,10 +3301,8 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Implementations
Remove(); Remove();
var newms = payload.Target.GetMonstersInRange(40f); var newms = payload.Target.GetMonstersInRange(40f);
if (newms.TryPickRandom(out var target))
if (newms.Count > 0)
{ {
var target = RandomHelper.RandomItem(newms);
AddBuff(target, new Rune_B_Buff()); AddBuff(target, new Rune_B_Buff());
} }
} }
@ -4497,7 +4496,7 @@ namespace DiIiS_NA.GameServer.GSSystem.PowerSystem.Implementations
{ {
Founded = true; Founded = true;
var possibleTargets = projectile.GetMonstersInRange(25f); var possibleTargets = projectile.GetMonstersInRange(25f);
var target = RandomHelper.RandomItem(possibleTargets); var target = possibleTargets.PickRandom();
projectile.Launch(target.Position, 1f); projectile.Launch(target.Position, 1f);
} }
}; };