fix antag bugs (#27319)

* fix antag bugs

* Update NukeopsRuleComponent.cs
This commit is contained in:
Nemanja
2024-04-25 20:25:57 -04:00
committed by GitHub
parent 281e5fa448
commit a0b3a6b679
8 changed files with 86 additions and 29 deletions

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -71,5 +71,5 @@ public sealed partial class TraitorRuleComponent : Component
public int StartingBalance = 20;
[DataField]
public int MaxDifficulty = 20;
public int MaxDifficulty = 5;
}

View File

@@ -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>

View File

@@ -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)

View File

@@ -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>

View File

@@ -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)

View File

@@ -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))