namespace Content.Server.Antag;
-public sealed class AntagSelectionPlayerPool(params List<ICommonSession>[] sessions)
+public sealed class AntagSelectionPlayerPool (List<List<ICommonSession>> orderedPools)
{
- private readonly List<List<ICommonSession>> _orderedPools = sessions.ToList();
-
public bool TryPickAndTake(IRobustRandom random, [NotNullWhen(true)] out ICommonSession? session)
{
session = null;
- foreach (var pool in _orderedPools)
+ foreach (var pool in orderedPools)
{
if (pool.Count == 0)
continue;
return session != null;
}
- public int Count => _orderedPools.Sum(p => p.Count);
+ public int Count => orderedPools.Sum(p => p.Count);
}
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly GhostRoleSystem _ghostRole = default!;
[Dependency] private readonly JobSystem _jobs = default!;
- [Dependency] private readonly MapSystem _map = default!;
[Dependency] private readonly MindSystem _mind = default!;
[Dependency] private readonly RoleSystem _role = default!;
[Dependency] private readonly StationSpawningSystem _stationSpawning = default!;
if (!TryGetNextAvailableDefinition((uid, antag), out var def))
continue;
- MakeAntag((uid, antag), args.Player, def.Value);
+ if (TryMakeAntag((uid, antag), args.Player, def.Value))
+ break;
}
}
}
}
+ /// <summary>
+ /// Tries to makes a given player into the specified antagonist.
+ /// </summary>
+ public bool TryMakeAntag(Entity<AntagSelectionComponent> ent, ICommonSession? session, AntagSelectionDefinition def, bool ignoreSpawner = false)
+ {
+ if (!IsSessionValid(ent, session, def) ||
+ !IsEntityValid(session?.AttachedEntity, def))
+ {
+ return false;
+ }
+
+ MakeAntag(ent, session, def, ignoreSpawner);
+ return true;
+ }
+
/// <summary>
/// Makes a given player into the specified antagonist.
/// </summary>
{
var playerXform = Transform(player);
var pos = RobustRandom.Pick(getPosEv.Coordinates);
- var mapEnt = _map.GetMap(pos.MapId);
_transform.SetMapCoordinates((player, playerXform), pos);
}
_mind.SetUserId(curMind.Value, session.UserId);
}
- EntityManager.AddComponents(curMind.Value, def.MindComponents);
_mind.TransferTo(curMind.Value, antagEnt, ghostCheckOverride: true);
+ _role.MindAddRoles(curMind.Value, def.MindComponents);
ent.Comp.SelectedMinds.Add((curMind.Value, Name(player)));
}
/// </summary>
public AntagSelectionPlayerPool GetPlayerPool(Entity<AntagSelectionComponent> ent, List<ICommonSession> sessions, AntagSelectionDefinition def)
{
- var primaryList = new List<ICommonSession>();
- var secondaryList = new List<ICommonSession>();
- var fallbackList = new List<ICommonSession>();
- var rawList = new List<ICommonSession>();
+ var preferredList = new List<ICommonSession>();
+ var secondBestList = new List<ICommonSession>();
+ var unwantedList = new List<ICommonSession>();
+ var invalidList = new List<ICommonSession>();
foreach (var session in sessions)
{
if (!IsSessionValid(ent, session, def) ||
!IsEntityValid(session.AttachedEntity, def))
{
- rawList.Add(session);
+ invalidList.Add(session);
continue;
}
var pref = (HumanoidCharacterProfile) _pref.GetPreferences(session.UserId).SelectedCharacter;
- if (def.PrefRoles.Count == 0 || pref.AntagPreferences.Any(p => def.PrefRoles.Contains(p)))
+ if (def.PrefRoles.Count != 0 && pref.AntagPreferences.Any(p => def.PrefRoles.Contains(p)))
{
- primaryList.Add(session);
+ preferredList.Add(session);
}
- else if (def.PrefRoles.Count == 0 || pref.AntagPreferences.Any(p => def.FallbackRoles.Contains(p)))
+ else if (def.FallbackRoles.Count != 0 && pref.AntagPreferences.Any(p => def.FallbackRoles.Contains(p)))
{
- secondaryList.Add(session);
+ secondBestList.Add(session);
}
else
{
- fallbackList.Add(session);
+ unwantedList.Add(session);
}
}
- return new AntagSelectionPlayerPool(primaryList, secondaryList, fallbackList, rawList);
+ return new AntagSelectionPlayerPool(new() { preferredList, secondBestList, unwantedList, invalidList });
}
/// <summary>
/// Checks if a given session is valid for an antagonist.
/// </summary>
- public bool IsSessionValid(Entity<AntagSelectionComponent> ent, ICommonSession session, AntagSelectionDefinition def, EntityUid? mind = null)
+ public bool IsSessionValid(Entity<AntagSelectionComponent> ent, ICommonSession? session, AntagSelectionDefinition def, EntityUid? mind = null)
{
+ if (session == null)
+ return true;
+
mind ??= session.GetMind();
if (session.Status is SessionStatus.Disconnected or SessionStatus.Zombie)
public int StartingBalance = 20;
[DataField]
- public int MaxDifficulty = 20;
+ public int MaxDifficulty = 5;
}
return EntityQueryEnumerator<ActiveGameRuleComponent, T, GameRuleComponent>();
}
+ /// <summary>
+ /// Queries all gamerules, regardless of if they're active or not.
+ /// </summary>
+ protected EntityQueryEnumerator<T, GameRuleComponent> QueryAllRules()
+ {
+ return EntityQueryEnumerator<T, GameRuleComponent>();
+ }
+
/// <summary>
/// Utility function for finding a random event-eligible station entity
/// </summary>
if (args.Forced || args.Cancelled)
return;
- var query = QueryActiveRules();
- while (query.MoveNext(out var uid, out _, out _, out var gameRule))
+ var query = QueryAllRules();
+ while (query.MoveNext(out var uid, out _, out var gameRule))
{
var minPlayers = gameRule.MinPlayers;
if (args.Players.Length >= minPlayers)
var timeRemain = nukeops.WarNukieArriveDelay + Timing.CurTime;
ev.DeclaratorEntity.Comp.ShuttleDisabledTime = timeRemain;
- DistributeExtraTc(nukeops);
+ DistributeExtraTc((uid, nukeops));
}
}
}
return WarConditionStatus.YesWar;
}
- private void DistributeExtraTc(NukeopsRuleComponent nukieRule)
+ private void DistributeExtraTc(Entity<NukeopsRuleComponent> nukieRule)
{
var enumerator = EntityQueryEnumerator<StoreComponent>();
while (enumerator.MoveNext(out var uid, out var component))
if (!_tag.HasTag(uid, NukeOpsUplinkTagPrototype))
continue;
- if (GetOutpost(uid) is not {} outpost)
+ if (GetOutpost(nukieRule.Owner) is not { } outpost)
continue;
if (Transform(uid).MapID != Transform(outpost).MapID) // Will receive bonus TC only on their start outpost
continue;
- _store.TryAddCurrency(new () { { TelecrystalCurrencyPrototype, nukieRule.WarTcAmountPerNukie } }, uid, component);
+ _store.TryAddCurrency(new () { { TelecrystalCurrencyPrototype, nukieRule.Comp.WarTcAmountPerNukie } }, uid, component);
var msg = Loc.GetString("store-currency-war-boost-given", ("target", uid));
_popupSystem.PopupEntity(msg, uid);
if (!Resolve(ent, ref ent.Comp, false))
return null;
- return ent.Comp.MapGrids.FirstOrNull();
+ return ent.Comp.MapGrids.Where(e => HasComp<StationMemberComponent>(e) && !HasComp<NukeOpsShuttleComponent>(e)).FirstOrNull();
}
/// <remarks>
//Generate objectives
GenerateObjectives(mindId, mind, ent);
+ _antag.SendBriefing(args.EntityUid, MakeBriefing(args.EntityUid), null, null);
}
private void GenerateObjectives(EntityUid mindId, MindComponent mind, ThiefRuleComponent thiefRule)
+using System.Linq;
using Content.Shared.Administration.Logs;
using Content.Shared.Database;
using Content.Shared.Mind;
_antagTypes.Add(typeof(T));
}
+ public void MindAddRoles(EntityUid mindId, ComponentRegistry components, MindComponent? mind = null, bool silent = false)
+ {
+ if (!Resolve(mindId, ref mind))
+ return;
+
+ EntityManager.AddComponents(mindId, components);
+ var antagonist = false;
+ foreach (var compReg in components.Values)
+ {
+ var compType = compReg.Component.GetType();
+
+ var comp = EntityManager.ComponentFactory.GetComponent(compType);
+ if (IsAntagonistRole(comp.GetType()))
+ {
+ antagonist = true;
+ break;
+ }
+ }
+
+ var mindEv = new MindRoleAddedEvent(silent);
+ RaiseLocalEvent(mindId, ref mindEv);
+
+ var message = new RoleAddedEvent(mindId, mind, antagonist, silent);
+ if (mind.OwnedEntity != null)
+ {
+ RaiseLocalEvent(mind.OwnedEntity.Value, message, true);
+ }
+
+ _adminLogger.Add(LogType.Mind, LogImpact.Low,
+ $"Role components {string.Join(components.Keys.ToString(), ", ")} added to mind of {_minds.MindOwnerLoggingString(mind)}");
+ }
+
public void MindAddRole(EntityUid mindId, Component component, MindComponent? mind = null, bool silent = false)
{
if (!Resolve(mindId, ref mind))