Skip to content
Draft
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
4 changes: 3 additions & 1 deletion Nuclei/Events/ServerEvents.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Nuclei.Features;

namespace Nuclei.Events;

Expand All @@ -15,6 +16,7 @@ public static class ServerEvents
internal static void OnServerStarted()
{
ServerStarted?.Invoke();
TimeService.Initialize();
}

/// <summary>
Expand All @@ -26,4 +28,4 @@ internal static void OnServerStopped()
{
ServerStopped?.Invoke();
}
}
}
2 changes: 2 additions & 0 deletions Nuclei/Events/TimeEvents.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Nuclei.Features;

namespace Nuclei.Events;

Expand Down Expand Up @@ -57,6 +58,7 @@ internal static void OnEveryMinute()
internal static void OnEvery10Minutes()
{
Every10Minutes?.Invoke();
AutoBalanceService.BalanceTeams();
}

internal static void OnEvery30Minutes()
Expand Down
83 changes: 83 additions & 0 deletions Nuclei/Features/AutoBalanceService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NuclearOption.Networking;

namespace Nuclei.Features;

// Used with a timer service, it will check and balance team player count
public static class AutoBalanceService
{
public static bool BalanceTeams()
{
var HQs = FactionRegistry.GetAllHQs().ToList();

// new List<> required due to bug in GetPlayers() code if called multiple times
var faction1Players = new List<Player>(HQs[0].GetPlayers(false));
var faction2Players = new List<Player>(HQs[1].GetPlayers(false));

double faction1PlayersCount = faction1Players.Count;
double faction2PlayersCount = faction2Players.Count;

double totalPlayers = faction1PlayersCount + faction2PlayersCount;

if (HQs[0].preventJoin || HQs[1].preventJoin) return false; // If co-op, don't balance

//get % of players of total for each faction
double faction1Ratio = faction1PlayersCount / totalPlayers;
double faction2Ratio = faction2PlayersCount / totalPlayers;

// if the difference btwn the %'s is greater than the ratioMinimum, commence auto-balance
// TODO: Make this configurable via Nuclei.Config
double ratioMinimum = .10;
double factionRatioDifference = Math.Abs(faction1Ratio - faction2Ratio);

if (factionRatioDifference > ratioMinimum)
{
// dont balance if ratio reaches threshold but team is only diff by 1 players
if (faction1PlayersCount - faction2PlayersCount == 1) return false;


// Formula meaning: Get the % of players, where % is the ratio difference. This number
// is max players needed to move, except you need to div by 2 because each player moved
// moves the ratio diff 2x.
var numPlayersToMove = (int)(factionRatioDifference * totalPlayers / 2);

// Autobalance players from faction 1 to faction 2
if (faction1PlayersCount > faction2PlayersCount)
{
MovePlayers(numPlayersToMove, faction1Players, HQs[1]);
return true;
}
// Autobalance players from faction 2 to faction 1
else
{

MovePlayers(numPlayersToMove, faction2Players, HQs[0]);
return true;
}
}
else return false;
}

private static void MovePlayers(int numPlayersToMove, List<Player> factionPlayers, FactionHQ factionToSet)
{
int factionPlayerCount = factionPlayers.Count;
ChatService.SendChatMessage($"movePlayers factionPlayerCount: {factionPlayerCount}");
HashSet<int> indices = [];
Random rnd = new();
for (int i = 0; i < numPlayersToMove; i++)
{
if (!indices.Add(rnd.Next(0, factionPlayerCount)))
i--; // redo if random num generated is already in hashset
}

foreach (var x in indices)
{

// TODO: FIND WAY TO CHANGE FACTION MID GAME. functions below do not work
//factionPlayers[x].SetFaction(factionToSet);
//factionToSet.AddPlayer(factionPlayers[x]);
}
}
}
2 changes: 1 addition & 1 deletion Nuclei/Features/MissionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static class MissionService
/// <summary>
/// The current mission time.
/// </summary>
public static float CurrentMissionTime => Globals.MissionManagerInstance.missionTime;
public static float CurrentMissionTime => Globals.MissionManagerInstance.MissionTime;

/// <summary>
/// Gets all Mission Keys as an IEnumerable.
Expand Down
11 changes: 10 additions & 1 deletion Nuclei/Features/TimeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ private void FixedUpdate()
_lastTime = currentTime;

TimeEvents.OnEverySecond();


// MoTD
var motdFreq = NucleiConfig.MotDFrequency!.Value;
if (currentTime % motdFreq == 0)
{
ChatService.SendMotD();
}

if (currentTime % 3600 == 0)
{
TimeEvents.OnEveryHour();
Expand Down Expand Up @@ -85,4 +94,4 @@ private void FixedUpdate()
TimeEvents.OnEvery30Seconds();
}
}
}
}