Skip to content

Commit

Permalink
fix: Cleans up code with feeding pets and adds batch coin flips rando…
Browse files Browse the repository at this point in the history
…m check (#1717)
  • Loading branch information
kamronbatman committed Apr 4, 2024
1 parent 183f6fa commit 29ea813
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 125 deletions.
3 changes: 3 additions & 0 deletions Projects/Server/Random/BuiltInRng.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public static class BuiltInRng
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long Next(long minValue, long count) => minValue + Generator.NextInt64(count);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long NextLong() => Generator.NextInt64();

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double NextDouble() => Generator.NextDouble();

Expand Down
70 changes: 61 additions & 9 deletions Projects/Server/Utilities/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,13 @@
using System.Xml;
using Server.Buffers;
using Server.Collections;
using Server.Logging;
using Server.Random;
using Server.Text;

namespace Server;

public static class Utility
{
private static readonly ILogger logger = LogFactory.GetLogger(typeof(Utility));

private static Dictionary<IPAddress, IPAddress> _ipAddressTable;

private static SkillName[] _allSkills =
Expand Down Expand Up @@ -679,18 +676,70 @@ public static TimeSpan GetXMLTimeSpan(string timeSpanString, TimeSpan defaultVal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool InUpdateRange(Point3D p1, Point3D p2) => InRange(p1, p2, 18);

// Optimized method for handling 50% random chances in succession up to a maximum
public static int CoinFlips(int amount, int maximum)
{
var heads = 0;
while (amount > 0)
{
// Range is 2^amount exclusively, maximum of 62 bits can be used
ulong num = amount >= 62
? (ulong)BuiltInRng.NextLong()
: (ulong)BuiltInRng.Next(1L << amount);

heads += BitOperations.PopCount(num);

if (heads >= maximum)
{
return maximum;
}

// 64 bits minus sign bit and exclusive maximum leaves 62 bits
amount -= 62;
}

return heads;
}

public static int CoinFlips(int amount)
{
var heads = 0;
while (amount > 0)
{
// Range is 2^amount exclusively, maximum of 62 bits can be used
ulong num = amount >= 62
? (ulong)BuiltInRng.NextLong()
: (ulong)BuiltInRng.Next(1L << amount);

heads += BitOperations.PopCount(num);

// 64 bits minus sign bit and exclusive maximum leaves 62 bits
amount -= 62;
}

return heads;
}

public static int Dice(int amount, int sides, int bonus)
{
if (amount <= 0 || sides <= 0)
{
return 0;
}

var total = 0;
int total;

for (var i = 0; i < amount; ++i)
if (sides == 2)
{
total = CoinFlips(amount);
}
else
{
total += BuiltInRng.Next(1, sides);
total = 0;
for (var i = 0; i < amount; ++i)
{
total += BuiltInRng.Next(1, sides);
}
}

return total + bonus;
Expand Down Expand Up @@ -730,8 +779,9 @@ public static T[] RandomSample<T>(this T[] source, int count)
do
{
var rand = Random(length);
if (!(list[rand] && (list[rand] = true)))
if (!list[rand])
{
list[rand] = true;
sampleList[i++] = source[rand];
}
} while (i < count);
Expand All @@ -756,8 +806,9 @@ public static List<T> RandomSample<T>(this List<T> source, int count)
do
{
var rand = Random(length);
if (!(list[rand] && (list[rand] = true)))
if (!list[rand])
{
list[rand] = true;
sampleList[i++] = source[rand];
}
} while (i < count);
Expand All @@ -780,8 +831,9 @@ public static void RandomSample<T>(this T[] source, int count, List<T> dest)
do
{
var rand = Random(length);
if (!(list[rand] && (list[rand] = true)))
if (!list[rand])
{
list[rand] = true;
dest.Add(source[rand]);
}
} while (++i < count);
Expand Down
75 changes: 37 additions & 38 deletions Projects/UOContent/Engines/Quests/Collector/Items/ImageTypeInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,41 +30,47 @@ public enum ImageType

public class ImageTypeInfo
{
private static readonly ImageTypeInfo[] m_Table =
{
new(9734, typeof(Betrayer), 75, 45),
new(9735, typeof(Bogling), 75, 45),
new(9736, typeof(BogThing), 60, 47),
new(9615, typeof(Gazer), 75, 45),
new(9743, typeof(Beetle), 60, 55),
new(9667, typeof(GiantBlackWidow), 55, 52),
new(9657, typeof(Scorpion), 65, 47),
new(9758, typeof(JukaMage), 75, 45),
new(9759, typeof(JukaWarrior), 75, 45),
new(9636, typeof(Lich), 75, 45),
new(9756, typeof(MeerMage), 75, 45),
new(9757, typeof(MeerWarrior), 75, 45),
new(9638, typeof(Mongbat), 70, 50),
new(9639, typeof(Mummy), 75, 45),
new(9654, typeof(Pixie), 75, 45),
new(9747, typeof(PlagueBeast), 60, 45),
new(9750, typeof(SandVortex), 60, 43),
new(9614, typeof(StoneGargoyle), 75, 45),
new(9753, typeof(SwampDragon), 50, 55),
new(8448, typeof(Wisp), 75, 45),
new(9746, typeof(Juggernaut), 55, 38)
};
private static readonly ImageTypeInfo[] _table =
[
new ImageTypeInfo(9734, typeof(Betrayer), ImageType.Betrayer, 75, 45),
new ImageTypeInfo(9735, typeof(Bogling), ImageType.Bogling, 75, 45),
new ImageTypeInfo(9736, typeof(BogThing), ImageType.BogThing, 60, 47),
new ImageTypeInfo(9615, typeof(Gazer), ImageType.Gazer, 75, 45),
new ImageTypeInfo(9743, typeof(Beetle), ImageType.Beetle, 60, 55),
new ImageTypeInfo(9667, typeof(GiantBlackWidow), ImageType.GiantBlackWidow, 55, 52),
new ImageTypeInfo(9657, typeof(Scorpion), ImageType.Scorpion, 65, 47),
new ImageTypeInfo(9758, typeof(JukaMage), ImageType.JukaMage, 75, 45),
new ImageTypeInfo(9759, typeof(JukaWarrior), ImageType.JukaWarrior, 75, 45),
new ImageTypeInfo(9636, typeof(Lich), ImageType.Lich, 75, 45),
new ImageTypeInfo(9756, typeof(MeerMage), ImageType.MeerMage, 75, 45),
new ImageTypeInfo(9757, typeof(MeerWarrior), ImageType.MeerWarrior, 75, 45),
new ImageTypeInfo(9638, typeof(Mongbat), ImageType.Mongbat, 70, 50),
new ImageTypeInfo(9639, typeof(Mummy), ImageType.Mummy, 75, 45),
new ImageTypeInfo(9654, typeof(Pixie), ImageType.Pixie, 75, 45),
new ImageTypeInfo(9747, typeof(PlagueBeast), ImageType.PlagueBeast, 60, 45),
new ImageTypeInfo(9750, typeof(SandVortex), ImageType.SandVortex, 60, 43),
new ImageTypeInfo(9614, typeof(StoneGargoyle), ImageType.StoneGargoyle, 75, 45),
new ImageTypeInfo(9753, typeof(SwampDragon), ImageType.SwampDragon, 50, 55),
new ImageTypeInfo(8448, typeof(Wisp), ImageType.Wisp, 75, 45),
new ImageTypeInfo(9746, typeof(Juggernaut), ImageType.Juggernaut, 55, 38)
];

// Used for sampling
private static readonly ImageTypeInfo[] _shuffleTable = (ImageTypeInfo[])_table.Clone();

public ImageTypeInfo(int figurine, Type type, int x, int y)
public ImageTypeInfo(int figurine, Type type, ImageType image, int x, int y)
{
Figurine = figurine;
Image = image;
Type = type;
X = x;
Y = y;
}

public int Figurine { get; }

public ImageType Image { get; }

public Type Type { get; }

public int Name => Figurine < 0x4000 ? 1020000 + Figurine : 1078872 + Figurine;
Expand All @@ -74,7 +80,7 @@ public ImageTypeInfo(int figurine, Type type, int x, int y)
public static ImageTypeInfo Get(ImageType image)
{
var index = (int)image;
return m_Table[index >= 0 && index < m_Table.Length ? index : 0];
return _table[index >= 0 && index < _table.Length ? index : 0];
}

public static ImageType[] RandomList(int count)
Expand All @@ -84,21 +90,14 @@ public static ImageType[] RandomList(int count)
return Array.Empty<ImageType>();
}

var length = m_Table.Length;
Span<bool> list = stackalloc bool[length];
list.Clear();

_shuffleTable.Shuffle();
var imageTypes = new ImageType[count];

var i = 0;
do
var minCount = Math.Min(count, _shuffleTable.Length);
for (var i = 0; i < minCount; i++)
{
var rand = Utility.Random(length);
if (!(list[rand] && (list[rand] = true)))
{
imageTypes[i++] = (ImageType)rand;
}
} while (i < count);
imageTypes[i] = _shuffleTable[i].Image;
}

return imageTypes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public partial class DawnsMusicBox : Item, ISecurable
{ MusicName.ValoriaShips, new DawnsMusicInfo(1075140, DawnsMusicRarity.Rare) }
};

public static readonly MusicName[] _commonTracks =
private static readonly MusicName[] _commonTracks =
{
MusicName.Samlethe, MusicName.Sailing, MusicName.Britain2, MusicName.Britain1,
MusicName.Bucsden, MusicName.Forest_a, MusicName.Cove, MusicName.Death,
Expand All @@ -86,15 +86,15 @@ public partial class DawnsMusicBox : Item, ISecurable
MusicName.Mountn_a, MusicName.Wind, MusicName.Yew, MusicName.Zento
};

public static readonly MusicName[] _uncommonTracks =
private static readonly MusicName[] _uncommonTracks =
{
MusicName.GwennoConversation, MusicName.DreadHornArea, MusicName.ElfCity,
MusicName.GoodEndGame, MusicName.GoodVsEvil, MusicName.GreatEarthSerpents,
MusicName.GrizzleDungeon, MusicName.Humanoids_U9, MusicName.MelisandesLair,
MusicName.MinocNegative, MusicName.ParoxysmusLair, MusicName.Paws
};

public static readonly MusicName[] _rareTracks =
private static readonly MusicName[] _rareTracks =
{
MusicName.SelimsBar, MusicName.SerpentIsleCombat_U7, MusicName.ValoriaShips
};
Expand All @@ -117,9 +117,16 @@ public DawnsMusicBox() : base(0x2AF9)
{
Weight = 1.0;

_tracks = new List<MusicName>();
var shuffledTracks = GetTracks(DawnsMusicRarity.Common);
shuffledTracks.Shuffle();

GetTracks(DawnsMusicRarity.Common).RandomSample(4, _tracks);
_tracks =
[
shuffledTracks[0],
shuffledTracks[1],
shuffledTracks[2],
shuffledTracks[3]
];
}

public override int LabelNumber => 1075198; // Dawn's Music Box
Expand All @@ -131,8 +138,7 @@ public override void OnAfterDuped(Item newItem)
return;
}

box.Tracks = new List<MusicName>();
box.Tracks.AddRange(Tracks);
box.Tracks = [..Tracks];
}

public override void GetProperties(IPropertyList list)
Expand Down Expand Up @@ -257,7 +263,7 @@ private void Animate()
private void Deserialize(IGenericReader reader, int version)
{
var count = reader.ReadInt();
_tracks = new List<MusicName>();
_tracks = [];

for (var i = 0; i < count; i++)
{
Expand Down

0 comments on commit 29ea813

Please sign in to comment.