Predict Mind Roles (#39611)
This commit is contained in:
@@ -19,11 +19,13 @@ public sealed class ParadoxCloneRoleSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnRefreshNameModifiers(Entity<ParadoxCloneRoleComponent> ent, ref MindRelayedEvent<RefreshNameModifiersEvent> args)
|
private void OnRefreshNameModifiers(Entity<ParadoxCloneRoleComponent> ent, ref MindRelayedEvent<RefreshNameModifiersEvent> args)
|
||||||
{
|
{
|
||||||
if (!TryComp<MindRoleComponent>(ent.Owner, out var roleComp))
|
var mindId = Transform(ent).ParentUid; // the mind role entity is in a container in the mind entity
|
||||||
|
|
||||||
|
if (!TryComp<MindComponent>(mindId, out var mindComp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// only show for ghosts
|
// only show for ghosts
|
||||||
if (!HasComp<GhostComponent>(roleComp.Mind.Comp.OwnedEntity))
|
if (!HasComp<GhostComponent>(mindComp.OwnedEntity))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ent.Comp.NameModifier != null)
|
if (ent.Comp.NameModifier != null)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public sealed class RoleSystem : SharedRoleSystem
|
|||||||
|
|
||||||
// Briefing is no longer raised on the mind entity itself
|
// Briefing is no longer raised on the mind entity itself
|
||||||
// because all the components that briefings subscribe to should be on Mind Role Entities
|
// because all the components that briefings subscribe to should be on Mind Role Entities
|
||||||
foreach(var role in mindComp.MindRoles)
|
foreach (var role in mindComp.MindRoleContainer.ContainedEntities)
|
||||||
{
|
{
|
||||||
RaiseLocalEvent(role, ref ev);
|
RaiseLocalEvent(role, ref ev);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public sealed partial class JobCondition : EntityEffectCondition
|
|||||||
|| !args.EntityManager.TryGetComponent<MindComponent>(mindContainer.Mind, out var mind))
|
|| !args.EntityManager.TryGetComponent<MindComponent>(mindContainer.Mind, out var mind))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
foreach (var roleId in mind.MindRoles)
|
foreach (var roleId in mind.MindRoleContainer.ContainedEntities)
|
||||||
{
|
{
|
||||||
if (!args.EntityManager.HasComponent<JobRoleComponent>(roleId))
|
if (!args.EntityManager.HasComponent<JobRoleComponent>(roleId))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
using Content.Shared.GameTicking;
|
|
||||||
using Content.Shared.Mind.Components;
|
using Content.Shared.Mind.Components;
|
||||||
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Network;
|
using Robust.Shared.Network;
|
||||||
using Robust.Shared.Player;
|
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Shared.Mind;
|
namespace Content.Shared.Mind;
|
||||||
@@ -100,10 +99,16 @@ public sealed partial class MindComponent : Component
|
|||||||
public bool PreventSuicide { get; set; }
|
public bool PreventSuicide { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Mind Role Entities belonging to this Mind
|
/// Mind Role Entities belonging to this Mind are stored in this container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField, AutoNetworkedField]
|
[ViewVariables]
|
||||||
public List<EntityUid> MindRoles = new List<EntityUid>();
|
public Container MindRoleContainer = default!;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The id for the MindRoleContainer.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public const string MindRoleContainerId = "mind_roles";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The mind's current antagonist/special role, or lack thereof;
|
/// The mind's current antagonist/special role, or lack thereof;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public abstract partial class SharedMindSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
RaiseLocalEvent(mindId, ref ev);
|
RaiseLocalEvent(mindId, ref ev);
|
||||||
|
|
||||||
foreach (var role in mindComp.MindRoles)
|
foreach (var role in mindComp.MindRoleContainer.ContainedEntities)
|
||||||
RaiseLocalEvent(role, ref ev);
|
RaiseLocalEvent(role, ref ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,7 @@ public abstract partial class SharedMindSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
RaiseLocalEvent(mindId, ref ev);
|
RaiseLocalEvent(mindId, ref ev);
|
||||||
|
|
||||||
foreach (var role in mindComp.MindRoles)
|
foreach (var role in mindComp.MindRoleContainer.ContainedEntities)
|
||||||
RaiseLocalEvent(role, ref ev);
|
RaiseLocalEvent(role, ref ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ using Content.Shared.Mobs.Systems;
|
|||||||
using Content.Shared.Objectives.Systems;
|
using Content.Shared.Objectives.Systems;
|
||||||
using Content.Shared.Players;
|
using Content.Shared.Players;
|
||||||
using Content.Shared.Speech;
|
using Content.Shared.Speech;
|
||||||
|
|
||||||
using Content.Shared.Whitelist;
|
using Content.Shared.Whitelist;
|
||||||
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Network;
|
using Robust.Shared.Network;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
@@ -36,6 +36,7 @@ public abstract partial class SharedMindSystem : EntitySystem
|
|||||||
[Dependency] private readonly ISharedPlayerManager _playerManager = default!;
|
[Dependency] private readonly ISharedPlayerManager _playerManager = default!;
|
||||||
[Dependency] private readonly MetaDataSystem _metadata = default!;
|
[Dependency] private readonly MetaDataSystem _metadata = default!;
|
||||||
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
||||||
|
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
protected readonly Dictionary<NetUserId, EntityUid> UserMinds = new();
|
protected readonly Dictionary<NetUserId, EntityUid> UserMinds = new();
|
||||||
@@ -64,6 +65,8 @@ public abstract partial class SharedMindSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnMindStartup(EntityUid uid, MindComponent component, ComponentStartup args)
|
private void OnMindStartup(EntityUid uid, MindComponent component, ComponentStartup args)
|
||||||
{
|
{
|
||||||
|
component.MindRoleContainer = _container.EnsureContainer<Container>(uid, MindComponent.MindRoleContainerId);
|
||||||
|
|
||||||
if (component.UserId == null)
|
if (component.UserId == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -35,14 +35,6 @@ public sealed partial class MindRoleComponent : BaseMindRoleComponent
|
|||||||
[DataField]
|
[DataField]
|
||||||
public bool ExclusiveAntag;
|
public bool ExclusiveAntag;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Mind that this role belongs to.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// TODO: Make this a datafield. Also components should not store other components.
|
|
||||||
/// </remarks>
|
|
||||||
public Entity<MindComponent> Mind;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Antagonist prototype of this role.
|
/// The Antagonist prototype of this role.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ using Content.Shared.Whitelist;
|
|||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
@@ -35,7 +34,6 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
Subs.CVar(_cfg, CCVars.GameRoleTimerOverride, SetRequirementOverride, true);
|
Subs.CVar(_cfg, CCVars.GameRoleTimerOverride, SetRequirementOverride, true);
|
||||||
|
|
||||||
SubscribeLocalEvent<MindRoleComponent, ComponentShutdown>(OnComponentShutdown);
|
|
||||||
SubscribeLocalEvent<StartingMindRoleComponent, PlayerSpawnCompleteEvent>(OnSpawn);
|
SubscribeLocalEvent<StartingMindRoleComponent, PlayerSpawnCompleteEvent>(OnSpawn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,22 +150,23 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
//If that was somehow to occur, a second mindrole for that comp would be created
|
//If that was somehow to occur, a second mindrole for that comp would be created
|
||||||
//Meaning any mind role checks could return wrong results, since they just return the first match they find
|
//Meaning any mind role checks could return wrong results, since they just return the first match they find
|
||||||
|
|
||||||
var mindRoleId = Spawn(protoId, MapCoordinates.Nullspace);
|
if (!PredictedTrySpawnInContainer(protoId, mindId, MindComponent.MindRoleContainerId, out var mindRoleId))
|
||||||
EnsureComp<MindRoleComponent>(mindRoleId);
|
{
|
||||||
var mindRoleComp = Comp<MindRoleComponent>(mindRoleId);
|
Log.Error($"Failed to add role {protoId} to {ToPrettyString(mindId)} : Could not spawn the role entity inside the container");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mindRoleComp = EnsureComp<MindRoleComponent>(mindRoleId.Value);
|
||||||
|
|
||||||
mindRoleComp.Mind = (mindId,mind);
|
|
||||||
if (jobPrototype is not null)
|
if (jobPrototype is not null)
|
||||||
{
|
{
|
||||||
mindRoleComp.JobPrototype = jobPrototype;
|
mindRoleComp.JobPrototype = jobPrototype;
|
||||||
EnsureComp<JobRoleComponent>(mindRoleId);
|
EnsureComp<JobRoleComponent>(mindRoleId.Value);
|
||||||
DebugTools.AssertNull(mindRoleComp.AntagPrototype);
|
DebugTools.AssertNull(mindRoleComp.AntagPrototype);
|
||||||
DebugTools.Assert(!mindRoleComp.Antag);
|
DebugTools.Assert(!mindRoleComp.Antag);
|
||||||
DebugTools.Assert(!mindRoleComp.ExclusiveAntag);
|
DebugTools.Assert(!mindRoleComp.ExclusiveAntag);
|
||||||
}
|
}
|
||||||
|
|
||||||
mind.MindRoles.Add(mindRoleId);
|
|
||||||
|
|
||||||
var update = MindRolesUpdate((mindId, mind));
|
var update = MindRolesUpdate((mindId, mind));
|
||||||
|
|
||||||
// RoleType refresh, Role time tracking, Update Admin playerlist
|
// RoleType refresh, Role time tracking, Update Admin playerlist
|
||||||
@@ -230,7 +229,7 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
var roles = new List<Entity<MindRoleComponent>>();
|
var roles = new List<Entity<MindRoleComponent>>();
|
||||||
|
|
||||||
foreach (var role in mind.MindRoles)
|
foreach (var role in mind.MindRoleContainer.ContainedEntities)
|
||||||
{
|
{
|
||||||
var comp = Comp<MindRoleComponent>(role);
|
var comp = Comp<MindRoleComponent>(role);
|
||||||
if (comp.RoleType is not null)
|
if (comp.RoleType is not null)
|
||||||
@@ -301,7 +300,7 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
var original = "'" + typeof(T).Name + "'";
|
var original = "'" + typeof(T).Name + "'";
|
||||||
var deleteName = original;
|
var deleteName = original;
|
||||||
|
|
||||||
foreach (var role in mind.Comp.MindRoles)
|
foreach (var role in mind.Comp.MindRoleContainer.ContainedEntities)
|
||||||
{
|
{
|
||||||
if (!HasComp<MindRoleComponent>(role))
|
if (!HasComp<MindRoleComponent>(role))
|
||||||
{
|
{
|
||||||
@@ -366,7 +365,7 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
var original = "'" + protoId + "'";
|
var original = "'" + protoId + "'";
|
||||||
var deleteName = original;
|
var deleteName = original;
|
||||||
var delete = new List<EntityUid>();
|
var delete = new List<EntityUid>();
|
||||||
foreach (var role in mind.Comp.MindRoles)
|
foreach (var role in mind.Comp.MindRoleContainer.ContainedEntities)
|
||||||
{
|
{
|
||||||
if (!HasComp<MindRoleComponent>(role))
|
if (!HasComp<MindRoleComponent>(role))
|
||||||
{
|
{
|
||||||
@@ -416,17 +415,6 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removing the mind role's reference on component shutdown
|
|
||||||
// to make sure the reference gets removed even if the mind role entity was deleted by outside code
|
|
||||||
private void OnComponentShutdown(Entity<MindRoleComponent> ent, ref ComponentShutdown args)
|
|
||||||
{
|
|
||||||
//TODO: Just ensure that the tests don't spawn unassociated mind role entities
|
|
||||||
if (ent.Comp.Mind.Comp is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ent.Comp.Mind.Comp.MindRoles.Remove(ent.Owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the first mind role of a specific T type on a mind entity.
|
/// Finds the first mind role of a specific T type on a mind entity.
|
||||||
/// Outputs entity components for the mind role's MindRoleComponent and for T
|
/// Outputs entity components for the mind role's MindRoleComponent and for T
|
||||||
@@ -442,7 +430,7 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
if (!Resolve(mind.Owner, ref mind.Comp))
|
if (!Resolve(mind.Owner, ref mind.Comp))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
foreach (var roleEnt in mind.Comp.MindRoles)
|
foreach (var roleEnt in mind.Comp.MindRoleContainer.ContainedEntities)
|
||||||
{
|
{
|
||||||
if (!TryComp(roleEnt, out T? tcomp))
|
if (!TryComp(roleEnt, out T? tcomp))
|
||||||
continue;
|
continue;
|
||||||
@@ -487,7 +475,7 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
|
|
||||||
var found = false;
|
var found = false;
|
||||||
|
|
||||||
foreach (var roleEnt in mind.MindRoles)
|
foreach (var roleEnt in mind.MindRoleContainer.ContainedEntities)
|
||||||
{
|
{
|
||||||
if (!HasComp(roleEnt, type))
|
if (!HasComp(roleEnt, type))
|
||||||
continue;
|
continue;
|
||||||
@@ -511,7 +499,7 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool MindHasRole(Entity<MindComponent> mind, EntityWhitelist whitelist)
|
public bool MindHasRole(Entity<MindComponent> mind, EntityWhitelist whitelist)
|
||||||
{
|
{
|
||||||
foreach (var roleEnt in mind.Comp.MindRoles)
|
foreach (var roleEnt in mind.Comp.MindRoleContainer.ContainedEntities)
|
||||||
{
|
{
|
||||||
if (_whitelist.IsWhitelistPass(whitelist, roleEnt))
|
if (_whitelist.IsWhitelistPass(whitelist, roleEnt))
|
||||||
return true;
|
return true;
|
||||||
@@ -544,7 +532,7 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
|
|
||||||
var mind = Comp<MindComponent>(mindId);
|
var mind = Comp<MindComponent>(mindId);
|
||||||
|
|
||||||
foreach (var uid in mind.MindRoles)
|
foreach (var uid in mind.MindRoleContainer.ContainedEntities)
|
||||||
{
|
{
|
||||||
if (HasComp<T>(uid) && TryComp<MindRoleComponent>(uid, out var comp))
|
if (HasComp<T>(uid) && TryComp<MindRoleComponent>(uid, out var comp))
|
||||||
result = (uid, comp);
|
result = (uid, comp);
|
||||||
@@ -564,7 +552,7 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
if (!Resolve(mind.Owner, ref mind.Comp))
|
if (!Resolve(mind.Owner, ref mind.Comp))
|
||||||
return roleInfo;
|
return roleInfo;
|
||||||
|
|
||||||
foreach (var role in mind.Comp.MindRoles)
|
foreach (var role in mind.Comp.MindRoleContainer.ContainedEntities)
|
||||||
{
|
{
|
||||||
var valid = false;
|
var valid = false;
|
||||||
var name = "game-ticker-unknown-role";
|
var name = "game-ticker-unknown-role";
|
||||||
@@ -651,7 +639,7 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
|
|
||||||
var antagonist = false;
|
var antagonist = false;
|
||||||
var exclusiveAntag = false;
|
var exclusiveAntag = false;
|
||||||
foreach (var role in mind.Comp.MindRoles)
|
foreach (var role in mind.Comp.MindRoleContainer.ContainedEntities)
|
||||||
{
|
{
|
||||||
if (!TryComp<MindRoleComponent>(role, out var roleComp))
|
if (!TryComp<MindRoleComponent>(role, out var roleComp))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user