fix antag bugs (#27319)
* fix antag bugs * Update NukeopsRuleComponent.cs
This commit is contained in:
@@ -5,15 +5,13 @@ using Robust.Shared.Random;
|
||||
|
||||
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;
|
||||
@@ -25,5 +23,5 @@ public sealed class AntagSelectionPlayerPool(params List<ICommonSession>[] sessi
|
||||
return session != null;
|
||||
}
|
||||
|
||||
public int Count => _orderedPools.Sum(p => p.Count);
|
||||
public int Count => orderedPools.Sum(p => p.Count);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
|
||||
[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!;
|
||||
@@ -133,7 +132,8 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
|
||||
if (!TryGetNextAvailableDefinition((uid, antag), out var def))
|
||||
continue;
|
||||
|
||||
MakeAntag((uid, antag), args.Player, def.Value);
|
||||
if (TryMakeAntag((uid, antag), args.Player, def.Value))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,6 +218,21 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
|
||||
}
|
||||
}
|
||||
|
||||
/// <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>
|
||||
@@ -262,7 +277,6 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
|
||||
{
|
||||
var playerXform = Transform(player);
|
||||
var pos = RobustRandom.Pick(getPosEv.Coordinates);
|
||||
var mapEnt = _map.GetMap(pos.MapId);
|
||||
_transform.SetMapCoordinates((player, playerXform), pos);
|
||||
}
|
||||
|
||||
@@ -291,8 +305,8 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
|
||||
_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)));
|
||||
}
|
||||
|
||||
@@ -310,42 +324,45 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
|
||||
/// </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)
|
||||
|
||||
@@ -71,5 +71,5 @@ public sealed partial class TraitorRuleComponent : Component
|
||||
public int StartingBalance = 20;
|
||||
|
||||
[DataField]
|
||||
public int MaxDifficulty = 20;
|
||||
public int MaxDifficulty = 5;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,14 @@ public abstract partial class GameRuleSystem<T> where T: IComponent
|
||||
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>
|
||||
|
||||
@@ -34,8 +34,8 @@ public abstract partial class GameRuleSystem<T> : EntitySystem where T : ICompon
|
||||
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)
|
||||
|
||||
@@ -344,7 +344,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
var timeRemain = nukeops.WarNukieArriveDelay + Timing.CurTime;
|
||||
ev.DeclaratorEntity.Comp.ShuttleDisabledTime = timeRemain;
|
||||
|
||||
DistributeExtraTc(nukeops);
|
||||
DistributeExtraTc((uid, nukeops));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -371,7 +371,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
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))
|
||||
@@ -379,13 +379,13 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
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);
|
||||
@@ -510,7 +510,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
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>
|
||||
|
||||
@@ -34,6 +34,7 @@ public sealed class ThiefRuleSystem : GameRuleSystem<ThiefRuleComponent>
|
||||
|
||||
//Generate objectives
|
||||
GenerateObjectives(mindId, mind, ent);
|
||||
_antag.SendBriefing(args.EntityUid, MakeBriefing(args.EntityUid), null, null);
|
||||
}
|
||||
|
||||
private void GenerateObjectives(EntityUid mindId, MindComponent mind, ThiefRuleComponent thiefRule)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Mind;
|
||||
@@ -62,6 +63,38 @@ public abstract class SharedRoleSystem : EntitySystem
|
||||
_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))
|
||||
|
||||
Reference in New Issue
Block a user