diff --git a/Unity/Assets/Scripts/TH1_Data/MapData.cs b/Unity/Assets/Scripts/TH1_Data/MapData.cs index 53bf59325..3e53bbd26 100644 --- a/Unity/Assets/Scripts/TH1_Data/MapData.cs +++ b/Unity/Assets/Scripts/TH1_Data/MapData.cs @@ -386,6 +386,7 @@ namespace RuntimeData EnsurePlayerSlots(netMode); var changed = false; + System.Random random = null; var usedEmpires = new HashSet<(uint CivId, uint ForceId)>(); foreach (var slot in MultiCivs) { @@ -414,7 +415,8 @@ namespace RuntimeData continue; } - var option = GetAvailablePlayerOption(Math.Max(0, i - 1), usedEmpires, ShouldUseAllEmpiresForRandomSlot(slot, netMode)); + random ??= CreatePlayerSlotRandom(); + var option = GetRandomAvailablePlayerOption(random, usedEmpires, ShouldUseAllEmpiresForRandomSlot(slot, netMode)); slot.CivId = option.CivId; slot.ForceId = option.ForceId; slot.IsCivFixed = true; @@ -449,6 +451,35 @@ namespace RuntimeData return options[preferredIndex % options.Count]; } + private static System.Random CreatePlayerSlotRandom() + { + unchecked + { + var seed = Environment.TickCount; + seed = (seed * 397) ^ DateTime.UtcNow.Ticks.GetHashCode(); + seed = (seed * 397) ^ Guid.NewGuid().GetHashCode(); + return new System.Random(seed); + } + } + + private static (uint CivId, uint ForceId) GetRandomAvailablePlayerOption( + System.Random random, + HashSet<(uint CivId, uint ForceId)> usedEmpires, + bool useAllEmpires) + { + var options = GetAvailablePlayerOptions(useAllEmpires); + if (options.Count == 0) return (0, 0); + + var candidates = new List<(uint CivId, uint ForceId)>(); + foreach (var option in options) + { + if (!usedEmpires.Contains(option)) candidates.Add(option); + } + + if (candidates.Count == 0) candidates = options; + return candidates[random.Next(candidates.Count)]; + } + private static List<(uint CivId, uint ForceId)> GetAvailablePlayerOptions(bool useAllEmpires) { var result = new List<(uint CivId, uint ForceId)>();