Skip to content
This repository has been archived by the owner on Oct 21, 2023. It is now read-only.

mod : partial item update without items.json #1237

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11,784 changes: 6,446 additions & 5,338 deletions data/items.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/Application/Games/Commands/GetGameUserCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ internal static readonly (string id, ItemSlot slot)[][] DefaultItemSets =
("crpg_aserai_civil_e_v2_h0", ItemSlot.Body),
("crpg_southern_moccasins_v2_h0", ItemSlot.Leg),
("crpg_hoe_v1_h0", ItemSlot.Weapon0),
("crpg_throwing_stone_v1_h0", ItemSlot.Weapon1),
("crpg_throwing_stone_v2_h0", ItemSlot.Weapon1),
},
// vlandia
new[]
Expand All @@ -55,7 +55,7 @@ internal static readonly (string id, ItemSlot slot)[][] DefaultItemSets =
("crpg_leather_gloves_v2_h0", ItemSlot.Hand),
("crpg_leather_shoes_v2_h0", ItemSlot.Leg),
("crpg_iron_pitchfork_h0", ItemSlot.Weapon0),
("crpg_throwing_stone_v1_h0", ItemSlot.Weapon1),
("crpg_throwing_stone_v2_h0", ItemSlot.Weapon1),
},
// empire
new[]
Expand All @@ -64,7 +64,7 @@ internal static readonly (string id, ItemSlot slot)[][] DefaultItemSets =
("crpg_tied_cloth_tunic_v2_h0", ItemSlot.Body),
("crpg_leather_shoes_v2_h0", ItemSlot.Leg),
("crpg_iron_pitchfork_h0", ItemSlot.Weapon0),
("crpg_throwing_stone_v1_h0", ItemSlot.Weapon1),
("crpg_throwing_stone_v2_h0", ItemSlot.Weapon1),
},
// sturgia
new[]
Expand All @@ -82,7 +82,7 @@ internal static readonly (string id, ItemSlot slot)[][] DefaultItemSets =
("crpg_steppe_robe_v2_h0", ItemSlot.Body),
("crpg_leather_boots_v2_h0", ItemSlot.Leg),
("crpg_hatchet_h0", ItemSlot.Weapon0),
("crpg_throwing_stone_v1_h0", ItemSlot.Weapon1),
("crpg_throwing_stone_v2_h0", ItemSlot.Weapon1),
},
// battania
new[]
Expand All @@ -91,15 +91,15 @@ internal static readonly (string id, ItemSlot slot)[][] DefaultItemSets =
("crpg_armwraps_v2_h0", ItemSlot.Hand),
("crpg_ragged_boots_v2_h0", ItemSlot.Leg),
("crpg_makeshift_sledgehammer_h0", ItemSlot.Weapon0),
("crpg_throwing_stone_v1_h0", ItemSlot.Weapon1),
("crpg_throwing_stone_v2_h0", ItemSlot.Weapon1),
},
// looters
new[]
{
("crpg_vlandia_bandit_cape_b_v2_h0", ItemSlot.Head),
("crpg_vlandia_bandit_c_v2_h0", ItemSlot.Body),
("crpg_rough_tied_boots_v2_h0", ItemSlot.Leg),
("crpg_light_mace_h0", ItemSlot.Weapon0),
("crpg_spiked_club_h0", ItemSlot.Weapon0),
("crpg_bound_adarga_v2_h0", ItemSlot.Weapon1),
},
};
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<InvariantGlobalization>true</InvariantGlobalization>

<!-- Use Bannerlord version + cRPG version for the revision number -->
<Version>1.1.5.79</Version>
<Version>1.1.6.80</Version>
<!-- Flag to enable to add revision id to the assembly version -->
<SourceControlInformationFeatureSupported>true</SourceControlInformationFeatureSupported>
<IncludeSourceRevisionInInformationalVersion>true</IncludeSourceRevisionInInformationalVersion>
Expand Down
52 changes: 52 additions & 0 deletions src/Domain/Entities/GameServers/GameServerConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using Crpg.Domain.Common;

namespace Crpg.Domain.Entities.Servers;

public class GameServerConfig : AuditableEntity
{
// Common settings for all type of server
public string ServerName { get; set; } = string.Empty;
public Region Region { get; set; }
public int ServerInstance { get; set; }
public GameMode GameMode { get; set; }
public string? GamePassword { get; set; }
public string? WelcomeMessage { get; set; }
public List<string> Maps { get; set; } = new List<string>();
public bool? AllowPollsToKickPlayers { get; set; }
public bool? AllowPollsToChangeMaps { get; set; }
public bool? DisableCultureVoting { get; set; }
public Culture CultureTeam1 { get; set; }
public Culture CultureTeam2 { get; set; }
public int MaxNumberOfPlayers { get; set; }
public int? AutoTeamBalanceThreshold { get; set; }
public int? FriendlyFireDamageMeleeFriendPercent { get; set; }
public int? FriendlyFireDamageMeleeSelfPercent { get; set; }
public int? FriendlyFireDamageRangedFriendPercent { get; set; }
public int? FriendlyFireDamageRangedSelfPercent { get; set; }
public int NumberOfBotsTeam1 { get; set; }
public int NumberOfBotsTeam2 { get; set; }
public int? MinNumberOfPlayersForMatchStart { get; set; } // Battle, Siege, TDeathmatch
public int? RoundTotal { get; set; }
public int? MapTimeLimit { get; set; }
public int? RoundTimeLimit { get; set; }
public int? WarmupTimeLimit { get; set; }
public int? RoundPreparationTimeLimit { get; set; } // Battle, Conquest, DTV, Siege, Deathmatch
public bool? Enable_automated_battle_switching { get; set; }

// Conquest type of server settings
public int? RespawnPeriodTeam1 { get; set; }
public int? RespawnPeriodTeam2 { get; set; }
public bool? Set_automated_battle_count { get; set; }

// Duel type of server settings
public int? MinScoreToWinDuel { get; set; }
public bool? End_game_after_mission_is_over { get; set; }

// cRPG specific settings
public float? Crpg_team_balancer_clan_group_size_penalty { get; set; } // Apply a rating increase to members of the same clan that are playing in the same team
public float? Crpg_experience_multiplier { get; set; } // Sets a reward multiplier for the server.
public int? Crpg_reward_tick { get; set; } // Sets the reward tick duration in seconds for Conquest/Siege/Team Deatmatch.
public bool? Crpg_team_balance_once { get; set; } // Sets if the team balancer should balance only after warmup.
public TimeSpan? Crpg_happy_hours { get; set; } // Sets the happy hours. Format: HH:MM-HH:MM,TZ
public bool? Crpg_apply_harmony_patches { get; set; } // Apply Harmony patches
}
10 changes: 10 additions & 0 deletions src/Domain/Entities/GameServers/GameType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Crpg.Domain.Entities.Servers;
public enum GameMode

Check warning on line 2 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

File name should match first type name

Check warning on line 2 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

File name should match first type name

Check warning on line 2 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

File name should match first type name
{
cRPGBattle,

Check warning on line 4 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGBattle' should begin with an uppercase letter

Check warning on line 4 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGBattle' should begin with an uppercase letter

Check warning on line 4 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGBattle' should begin with an uppercase letter
cRPGConquest,

Check warning on line 5 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGConquest' should begin with an uppercase letter

Check warning on line 5 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGConquest' should begin with an uppercase letter

Check warning on line 5 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGConquest' should begin with an uppercase letter
cRPGDTV,

Check warning on line 6 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGDTV' should begin with an uppercase letter

Check warning on line 6 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGDTV' should begin with an uppercase letter
cRPGDuel,

Check warning on line 7 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGDuel' should begin with an uppercase letter

Check warning on line 7 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGDuel' should begin with an uppercase letter
cRPGSiege,

Check warning on line 8 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGSiege' should begin with an uppercase letter

Check warning on line 8 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGSiege' should begin with an uppercase letter
cRPGTeamDeathmatch,

Check warning on line 9 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGTeamDeathmatch' should begin with an uppercase letter

Check warning on line 9 in src/Domain/Entities/GameServers/GameType.cs

View workflow job for this annotation

GitHub Actions / build

Element 'cRPGTeamDeathmatch' should begin with an uppercase letter
}
1 change: 1 addition & 0 deletions src/Domain/Entities/Users/Role.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ public enum Role
{
User,
Moderator,
GameAdmin,
Admin,
}
44 changes: 43 additions & 1 deletion src/Module.Client/GUI/MapSpriteData.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<SpriteCategories>
<SpriteCategory>
<Name>ui_mploading</Name>
<SpriteSheetCount>123</SpriteSheetCount>
<SpriteSheetCount>126</SpriteSheetCount>
<SpriteSheetSize ID="1" Width="3840" Height="1935" />
<SpriteSheetSize ID="2" Width="3840" Height="1935" />
<SpriteSheetSize ID="3" Width="3383" Height="1902" />
Expand Down Expand Up @@ -129,6 +129,9 @@
<SpriteSheetSize ID="121" Width="1920" Height="1080" />
<SpriteSheetSize ID="122" Width="1920" Height="1080" />
<SpriteSheetSize ID="123" Width="1920" Height="1080" />
<SpriteSheetSize ID="124" Width="1920" Height="1080" />
<SpriteSheetSize ID="125" Width="1920" Height="1080" />
<SpriteSheetSize ID="126" Width="1920" Height="1080" />
<AlwaysLoad />
</SpriteCategory>
</SpriteCategories>
Expand Down Expand Up @@ -1123,6 +1126,33 @@
<SheetY>0</SheetY>
<CategoryName>ui_mploading</CategoryName>
</SpritePart>
<SpritePart>
<SheetID>124</SheetID>
<Name>crpg_battle_thearena</Name>
<Width>1920</Width>
<Height>1080</Height>
<SheetX>0</SheetX>
<SheetY>0</SheetY>
<CategoryName>ui_mploading</CategoryName>
</SpritePart>
<SpritePart>
<SheetID>125</SheetID>
<Name>crpg_battle_krakatoa</Name>
<Width>1920</Width>
<Height>1080</Height>
<SheetX>0</SheetX>
<SheetY>0</SheetY>
<CategoryName>ui_mploading</CategoryName>
</SpritePart>
<SpritePart>
<SheetID>126</SheetID>
<Name>crpg_dtv_frozenshore</Name>
<Width>1920</Width>
<Height>1080</Height>
<SheetX>0</SheetX>
<SheetY>0</SheetY>
<CategoryName>ui_mploading</CategoryName>
</SpritePart>
</SpriteParts>
<Sprites>
<GenericSprite>
Expand Down Expand Up @@ -1565,5 +1595,17 @@
<Name>crpg_dtv_encampment</Name>
<SpritePartName>crpg_dtv_encampment</SpritePartName>
</GenericSprite>
<GenericSprite>
<Name>crpg_battle_thearena</Name>
<SpritePartName>crpg_battle_thearena</SpritePartName>
</GenericSprite>
<GenericSprite>
<Name>crpg_battle_krakatoa</Name>
<SpritePartName>crpg_battle_krakatoa</SpritePartName>
</GenericSprite>
<GenericSprite>
<Name>crpg_dtv_frozenshore</Name>
<SpritePartName>crpg_dtv_frozenshore</SpritePartName>
</GenericSprite>
</Sprites>
</SpriteData>
2 changes: 1 addition & 1 deletion src/Module.Server/Balancing/GameMatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

internal class GameMatch
{
public int TotalCount => TeamA.Count + TeamB.Count + Waiting.Count;
internal List<WeightedCrpgUser> TeamA { get; set; } = new();
internal List<WeightedCrpgUser> TeamB { get; set; } = new();
internal List<WeightedCrpgUser> Waiting { get; set; } = new();
}

internal class ClanGroupsGameMatch
{
internal List<ClanGroup> TeamA { get; set; } = new();
Expand Down
85 changes: 41 additions & 44 deletions src/Module.Server/Balancing/MatchBalancer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,16 @@ public GameMatch BannerBalancingWithEdgeCases(GameMatch gameMatch, bool firstBal
{
MatchBalancingHelpers.DumpTeamsStatus(gameMatch);
Debug.Print(nameof(BannerBalancingWithEdgeCases));

GameMatch balancedBannerGameMatch;

if (gameMatch.TotalCount <= 2)
{
Debug.Print("Game has 2 or less players");
balancedBannerGameMatch = RandomlyAssignWaitingPlayersTeam(gameMatch);
MatchBalancingHelpers.DumpTeamsStatus(balancedBannerGameMatch);
return balancedBannerGameMatch;
}

// This is the path we take when team were randomly assigned.
// we do not care of completely scrambling the teams since no round was played yet
if (firstBalance)
Expand Down Expand Up @@ -93,13 +101,9 @@ public GameMatch BannerBalancingWithEdgeCases(GameMatch gameMatch, bool firstBal
{
// This are failcases in case bannerbalance was not enough
Debug.Print("ratio difference is above 10%");
// to rewrite to work with all penalty values
if (CrpgServerConfiguration.TeamBalancerClanGroupSizePenalty == 0f)
{
balancedBannerGameMatch = BalanceTeamOfSimilarSizes(balancedBannerGameMatch, bannerBalance: false, 0.10f);
}
balancedBannerGameMatch = BalanceTeamOfSimilarSizes(balancedBannerGameMatch, bannerBalance: false, 0.10f);

if (IsBalanceGoodEnough(balancedBannerGameMatch, maxSizeRatio: 0.85f, maxDifference: 10f, percentageDifference: 0.15f))
if (IsBalanceGoodEnough(balancedBannerGameMatch, maxSizeRatio: 0.75f, maxDifference: 10f, percentageDifference: 0.15f))
{
// A few swaps solved the problem. Most of the clangroups are intact
Debug.Print("Ratio Difference is below 15%, we're not nuking.");
Expand All @@ -109,6 +113,7 @@ public GameMatch BannerBalancingWithEdgeCases(GameMatch gameMatch, bool firstBal
// A few swaps were not enough. Swaps are a form of gradient descent. Sometimes there are local extremas that are not global extremas
// Here we completely abandon banner balance by completely reshuffling the card then redoing swaps
Debug.Print("Swaps were not enough. This should really not happen often (ratio difference above 15%)");
MatchBalancingHelpers.DumpTeamsStatus(balancedBannerGameMatch);
MatchBalancingHelpers.DumpTeams(balancedBannerGameMatch);
Debug.Print("NaiveCaptainBalancing + Balancing Without BannerGrouping");
balancedBannerGameMatch = NaiveCaptainBalancing(balancedBannerGameMatch);
Expand Down Expand Up @@ -304,8 +309,7 @@ private bool FindAndSwapUsers(GameMatch gameMatch, float sizeScaler)
? (gameMatch.TeamA, gameMatch.TeamB)
: (gameMatch.TeamB, gameMatch.TeamA);
int userCountDifference = weakTeam.Count - strongTeam.Count;
bool swappingFromWeakTeam = userCountDifference <= 0;
float sizeOffset = Math.Abs(userCountDifference);
bool swappingFromWeakTeam = userCountDifference < 0;

(List<WeightedCrpgUser> teamToSwapFrom, List<WeightedCrpgUser> teamToSwapTo) = swappingFromWeakTeam
? (weakTeam, strongTeam)
Expand All @@ -316,39 +320,49 @@ private bool FindAndSwapUsers(GameMatch gameMatch, float sizeScaler)
? weakTeam.OrderBy(c => c.Weight).FirstOrDefault()
: strongTeam.OrderBy(c => c.Weight).LastOrDefault();
// These calculation are made to account for both the case where we are swapping a user with a list of user , or swapping no one with a list of users.
float bestWeightedCrpgUserToSwap1Weight = bestWeightedCrpgUserToSwap1?.Weight ?? 0;
int bestWeightedCrpgUserToSwap1Count = bestWeightedCrpgUserToSwap1 != null ? 1 : 0;
float moveWeightHalfDifference = MatchBalancingHelpers.ComputeMoveWeightHalfDifference(teamToSwapFrom, teamToSwapTo, bestWeightedCrpgUserToSwap1);
double targetWeight = swappingFromWeakTeam
? bestWeightedCrpgUserToSwap1Weight + Math.Abs(teamWeightDiff) / 2f
: bestWeightedCrpgUserToSwap1Weight - Math.Abs(teamWeightDiff) / 2f;
List<WeightedCrpgUser> bestWeightedCrpgUsersToSwap2 = MatchBalancingHelpers.FindWeightedCrpgUsersToSwap((float)targetWeight, teamToSwapTo, sizeOffset / 2f, sizeScaler);
? moveWeightHalfDifference + Math.Abs(teamWeightDiff) / 2f
: moveWeightHalfDifference - Math.Abs(teamWeightDiff) / 2f;
List<WeightedCrpgUser> bestWeightedCrpgUserToSwap1List = bestWeightedCrpgUserToSwap1 == null ? new List<WeightedCrpgUser>() : new List<WeightedCrpgUser> { bestWeightedCrpgUserToSwap1 };

float teamSizeDifference = teamToSwapTo.Count - teamToSwapFrom.Count; // positive value
float targetSize = (teamSizeDifference + bestWeightedCrpgUserToSwap1List.Count) / 2f;

List<WeightedCrpgUser> bestWeightedCrpgUsersToSwap2 = MatchBalancingHelpers.FindWeightedCrpgUsersToSwap((float)targetWeight, teamToSwapTo, teamToSwapFrom, targetSize, sizeScaler);

// the pair difference (strong - weak) needs to be close to TargetVector
Vector2 targetVector = new(sizeOffset * sizeScaler, (float)teamWeightDiff / 2f);
float sizeDifferenceAfterSwap = teamSizeDifference + (bestWeightedCrpgUserToSwap1List.Count - bestWeightedCrpgUsersToSwap2.Count) * 2f;

// the pair difference (strong - weak) needs to be close to zero
Vector2 bestPairVector = new(
(bestWeightedCrpgUsersToSwap2.Count - 1) * sizeScaler,
Math.Abs(bestWeightedCrpgUserToSwap1Weight - bestWeightedCrpgUsersToSwap2.Sum(u => u.Weight)));
sizeDifferenceAfterSwap * sizeScaler,
(float)Math.Abs(MatchBalancingHelpers.ComputeTeamDiffAfterSwap(teamToSwapFrom, teamToSwapTo, bestWeightedCrpgUserToSwap1List, bestWeightedCrpgUsersToSwap2)));

foreach (var user in teamToSwapFrom)
{
targetSize = (teamSizeDifference + 1) / 2f;
List<WeightedCrpgUser> userSingleton = new() { user };
moveWeightHalfDifference = MatchBalancingHelpers.ComputeMoveWeightHalfDifference(teamToSwapFrom, teamToSwapTo, user);
targetWeight = swappingFromWeakTeam
? user.Weight + Math.Abs(teamWeightDiff) / 2f
: user.Weight - Math.Abs(teamWeightDiff) / 2f;
List<WeightedCrpgUser> potentialWeightedCrpgUsersToSwap = MatchBalancingHelpers.FindWeightedCrpgUsersToSwap((float)targetWeight, teamToSwapTo, bestWeightedCrpgUserToSwap1Count + sizeOffset / 2f, sizeScaler);
? moveWeightHalfDifference + Math.Abs(teamWeightDiff) / 2f
: moveWeightHalfDifference - Math.Abs(teamWeightDiff) / 2f;
List<WeightedCrpgUser> potentialWeightedCrpgUsersToSwap = MatchBalancingHelpers.FindWeightedCrpgUsersToSwap((float)targetWeight, teamToSwapTo, teamToSwapFrom, targetSize, sizeScaler);
sizeDifferenceAfterSwap = teamSizeDifference + (1 - potentialWeightedCrpgUsersToSwap.Count) * 2;
Vector2 potentialPairVector = new(
(potentialWeightedCrpgUsersToSwap.Count - 1) * sizeScaler,
Math.Abs(user.Weight - potentialWeightedCrpgUsersToSwap.Sum(u => u.Weight)));
if ((targetVector - potentialPairVector).Length() < (targetVector - bestPairVector).Length())
sizeDifferenceAfterSwap * sizeScaler,
(float)Math.Abs(MatchBalancingHelpers.ComputeTeamDiffAfterSwap(teamToSwapFrom, teamToSwapTo, userSingleton, potentialWeightedCrpgUsersToSwap)));
if (potentialPairVector.Length() < bestPairVector.Length())
{
bestWeightedCrpgUserToSwap1 = user;
bestWeightedCrpgUsersToSwap2 = potentialWeightedCrpgUsersToSwap;
bestPairVector = potentialPairVector;
}
}

if (!IsSwapValid(strongTeam, weakTeam, swappingFromWeakTeam, bestWeightedCrpgUserToSwap1Count,
bestWeightedCrpgUserToSwap1Weight, bestWeightedCrpgUsersToSwap2.Count,
bestWeightedCrpgUsersToSwap2.Sum(u => u.Weight), sizeScaler))
bestWeightedCrpgUserToSwap1List = bestWeightedCrpgUserToSwap1 == null ? new List<WeightedCrpgUser>() : new List<WeightedCrpgUser> { bestWeightedCrpgUserToSwap1 };

// TODO : checking only for weight difference , but what about size?
if (Math.Abs(MatchBalancingHelpers.ComputeTeamDiffAfterSwap(teamToSwapFrom, teamToSwapTo, bestWeightedCrpgUserToSwap1List, bestWeightedCrpgUsersToSwap2)) - teamWeightDiff > 0)
{
return false;
}
Expand Down Expand Up @@ -485,23 +499,6 @@ private bool IsClanGroupsSwapValid(List<ClanGroup> strongTeam, List<ClanGroup> w
return newDifferenceVector.Length() < oldDifferenceVector.Length();
}

private bool IsSwapValid(List<WeightedCrpgUser> strongTeam, List<WeightedCrpgUser> weakTeam, bool swappingFromWeakTeam,
int sourceGroupSize, float sourceGroupWeight, int destinationGroupSize, float destinationGroupWeight,
float sizeScaler)
{
float newTeamWeightDiff = swappingFromWeakTeam
? strongTeam.Sum(u => u.Weight) + 2f * sourceGroupWeight - 2f * destinationGroupWeight - weakTeam.Sum(u => u.Weight)
: strongTeam.Sum(u => u.Weight) - 2f * sourceGroupWeight + 2f * destinationGroupWeight - weakTeam.Sum(u => u.Weight);
float newTeamSizeDiff = swappingFromWeakTeam
? strongTeam.Count + 2 * sourceGroupSize - 2f * destinationGroupSize - weakTeam.Count
: strongTeam.Count - 2 * sourceGroupSize + 2f * destinationGroupSize - weakTeam.Count;

Vector2 oldDifferenceVector = new((strongTeam.Count - weakTeam.Count) * sizeScaler,
strongTeam.Sum(u => u.Weight) - weakTeam.Sum(u => u.Weight));
Vector2 newDifferenceVector = new(newTeamSizeDiff * sizeScaler, newTeamWeightDiff);
return newDifferenceVector.Length() < oldDifferenceVector.Length();
}

private bool IsWeightRatioAcceptable(GameMatch gameMatch, float percentageDifference)
{
double weightRatio = Math.Abs(
Expand Down
Loading
Loading