Merge remote-tracking branch 'upstream/master' into ed-04-06-2024-upstream
# Conflicts: # Resources/Prototypes/Accents/word_replacements.yml
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
using Content.Shared.StatusIcon;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Access.Components
|
||||
{
|
||||
@@ -9,7 +9,7 @@ namespace Content.Server.Access.Components
|
||||
/// <summary>
|
||||
/// Set of job icons that the agent ID card can show.
|
||||
/// </summary>
|
||||
[DataField("icons", customTypeSerializer: typeof(PrototypeIdHashSetSerializer<StatusIconPrototype>))]
|
||||
public HashSet<string> Icons = new();
|
||||
[DataField]
|
||||
public HashSet<ProtoId<StatusIconPrototype>> Icons;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,14 +90,10 @@ namespace Content.Server.Access.Systems
|
||||
private void OnJobIconChanged(EntityUid uid, AgentIDCardComponent comp, AgentIDCardJobIconChangedMessage args)
|
||||
{
|
||||
if (!TryComp<IdCardComponent>(uid, out var idCard))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_prototypeManager.TryIndex<StatusIconPrototype>(args.JobIconId, out var jobIcon))
|
||||
{
|
||||
if (!_prototypeManager.TryIndex(args.JobIconId, out var jobIcon))
|
||||
return;
|
||||
}
|
||||
|
||||
_cardSystem.TryChangeJobIcon(uid, jobIcon, idCard);
|
||||
|
||||
@@ -109,7 +105,7 @@ namespace Content.Server.Access.Systems
|
||||
{
|
||||
foreach (var jobPrototype in _prototypeManager.EnumeratePrototypes<JobPrototype>())
|
||||
{
|
||||
if(jobPrototype.Icon == jobIcon.ID)
|
||||
if (jobPrototype.Icon == jobIcon.ID)
|
||||
{
|
||||
job = jobPrototype;
|
||||
return true;
|
||||
|
||||
@@ -129,7 +129,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
|
||||
_idCard.TryChangeJobTitle(targetId, newJobTitle, player: player);
|
||||
|
||||
if (_prototype.TryIndex<JobPrototype>(newJobProto, out var job)
|
||||
&& _prototype.TryIndex<StatusIconPrototype>(job.Icon, out var jobIcon))
|
||||
&& _prototype.TryIndex(job.Icon, out var jobIcon))
|
||||
{
|
||||
_idCard.TryChangeJobIcon(targetId, jobIcon, player: player);
|
||||
_idCard.TryChangeJobDepartment(targetId, job);
|
||||
|
||||
@@ -82,9 +82,7 @@ public sealed class PresetIdCardSystem : EntitySystem
|
||||
_cardSystem.TryChangeJobTitle(uid, job.LocalizedName);
|
||||
_cardSystem.TryChangeJobDepartment(uid, job);
|
||||
|
||||
if (_prototypeManager.TryIndex<StatusIconPrototype>(job.Icon, out var jobIcon))
|
||||
{
|
||||
if (_prototypeManager.TryIndex(job.Icon, out var jobIcon))
|
||||
_cardSystem.TryChangeJobIcon(uid, jobIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ using System.Text.Json.Nodes;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.Administration.Systems;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Presets;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Maps;
|
||||
using Content.Server.RoundEnd;
|
||||
using Content.Shared.Administration.Managers;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Prototypes;
|
||||
using Robust.Server.ServerStatus;
|
||||
using Robust.Shared.Asynchronous;
|
||||
|
||||
@@ -2,7 +2,6 @@ using System.Linq;
|
||||
using Content.Server.Antag.Components;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.Ghost.Roles;
|
||||
using Content.Server.Ghost.Roles.Components;
|
||||
@@ -15,6 +14,7 @@ using Content.Server.Shuttles.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.Antag;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Players;
|
||||
@@ -182,20 +182,20 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
|
||||
.Where(x => GameTicker.PlayerGameStatuses[x.UserId] == PlayerGameStatus.JoinedGame)
|
||||
.ToList();
|
||||
|
||||
ChooseAntags((uid, component), players);
|
||||
ChooseAntags((uid, component), players, midround: true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chooses antagonists from the given selection of players
|
||||
/// </summary>
|
||||
public void ChooseAntags(Entity<AntagSelectionComponent> ent, IList<ICommonSession> pool)
|
||||
public void ChooseAntags(Entity<AntagSelectionComponent> ent, IList<ICommonSession> pool, bool midround = false)
|
||||
{
|
||||
if (ent.Comp.SelectionsComplete)
|
||||
return;
|
||||
|
||||
foreach (var def in ent.Comp.Definitions)
|
||||
{
|
||||
ChooseAntags(ent, pool, def);
|
||||
ChooseAntags(ent, pool, def, midround: midround);
|
||||
}
|
||||
|
||||
ent.Comp.SelectionsComplete = true;
|
||||
@@ -204,17 +204,28 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem<AntagSelection
|
||||
/// <summary>
|
||||
/// Chooses antagonists from the given selection of players for the given antag definition.
|
||||
/// </summary>
|
||||
public void ChooseAntags(Entity<AntagSelectionComponent> ent, IList<ICommonSession> pool, AntagSelectionDefinition def)
|
||||
/// <param name="midround">Disable picking players for pre-spawn antags in the middle of a round</param>
|
||||
public void ChooseAntags(Entity<AntagSelectionComponent> ent, IList<ICommonSession> pool, AntagSelectionDefinition def, bool midround = false)
|
||||
{
|
||||
var playerPool = GetPlayerPool(ent, pool, def);
|
||||
var count = GetTargetAntagCount(ent, GetTotalPlayerCount(pool), def);
|
||||
|
||||
// if there is both a spawner and players getting picked, let it fall back to a spawner.
|
||||
var noSpawner = def.SpawnerPrototype == null;
|
||||
var picking = def.PickPlayer;
|
||||
if (midround && ent.Comp.SelectionTime == AntagSelectionTime.PrePlayerSpawn)
|
||||
{
|
||||
// prevent antag selection from happening if the round is on-going, requiring a spawner if used midround.
|
||||
// this is so rules like nukies, if added by an admin midround, dont make random living people nukies
|
||||
Log.Info($"Antags for rule {ent:?} get picked pre-spawn so only spawners will be made.");
|
||||
DebugTools.Assert(def.SpawnerPrototype != null, $"Rule {ent:?} had no spawner for pre-spawn rule added mid-round!");
|
||||
picking = false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
var session = (ICommonSession?) null;
|
||||
if (def.PickPlayer)
|
||||
if (picking)
|
||||
{
|
||||
if (!playerPool.TryPickAndTake(RobustRandom, out session) && noSpawner)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Server.Administration.Systems;
|
||||
using Content.Server.Destructible.Thresholds;
|
||||
using Content.Shared.Antag;
|
||||
using Content.Shared.Destructible.Thresholds;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Whitelist;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Content.Server.Antag.Mimic;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.VendingMachines;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
@@ -300,6 +300,21 @@ public sealed partial class CargoSystem
|
||||
return IsBountyComplete(GetBountyEntities(container), entries, out bountyEntities);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the <paramref name="entity"/> meets the criteria for the bounty <paramref name="entry"/>.
|
||||
/// </summary>
|
||||
/// <returns>true if <paramref name="entity"/> is a valid item for the bounty entry, otherwise false</returns>
|
||||
public bool IsValidBountyEntry(EntityUid entity, CargoBountyItemEntry entry)
|
||||
{
|
||||
if (!_whitelistSys.IsValid(entry.Whitelist, entity))
|
||||
return false;
|
||||
|
||||
if (entry.Blacklist != null && _whitelistSys.IsValid(entry.Blacklist, entity))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsBountyComplete(HashSet<EntityUid> entities, IEnumerable<CargoBountyItemEntry> entries, out HashSet<EntityUid> bountyEntities)
|
||||
{
|
||||
bountyEntities = new();
|
||||
@@ -313,7 +328,7 @@ public sealed partial class CargoSystem
|
||||
var temp = new HashSet<EntityUid>();
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
if (!_whitelistSys.IsValid(entry.Whitelist, entity) || (entry.Blacklist != null && _whitelistSys.IsValid(entry.Blacklist, entity)))
|
||||
if (!IsValidBountyEntry(entity, entry))
|
||||
continue;
|
||||
|
||||
count += _stackQuery.CompOrNull(entity)?.Count ?? 1;
|
||||
|
||||
@@ -49,18 +49,20 @@ public partial class ChatSystem
|
||||
/// <param name="hideLog">Whether or not this message should appear in the adminlog window</param>
|
||||
/// <param name="range">Conceptual range of transmission, if it shows in the chat window, if it shows to far-away ghosts or ghosts at all...</param>
|
||||
/// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
|
||||
/// <param name="forceEmote">Bypasses whitelist/blacklist/availibility checks for if the entity can use this emote</param>
|
||||
public void TryEmoteWithChat(
|
||||
EntityUid source,
|
||||
string emoteId,
|
||||
ChatTransmitRange range = ChatTransmitRange.Normal,
|
||||
bool hideLog = false,
|
||||
string? nameOverride = null,
|
||||
bool ignoreActionBlocker = false
|
||||
bool ignoreActionBlocker = false,
|
||||
bool forceEmote = false
|
||||
)
|
||||
{
|
||||
if (!_prototypeManager.TryIndex<EmotePrototype>(emoteId, out var proto))
|
||||
return;
|
||||
TryEmoteWithChat(source, proto, range, hideLog: hideLog, nameOverride, ignoreActionBlocker: ignoreActionBlocker);
|
||||
TryEmoteWithChat(source, proto, range, hideLog: hideLog, nameOverride, ignoreActionBlocker: ignoreActionBlocker, forceEmote: forceEmote);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -72,21 +74,18 @@ public partial class ChatSystem
|
||||
/// <param name="hideChat">Whether or not this message should appear in the chat window</param>
|
||||
/// <param name="range">Conceptual range of transmission, if it shows in the chat window, if it shows to far-away ghosts or ghosts at all...</param>
|
||||
/// <param name="nameOverride">The name to use for the speaking entity. Usually this should just be modified via <see cref="TransformSpeakerNameEvent"/>. If this is set, the event will not get raised.</param>
|
||||
/// <param name="forceEmote">Bypasses whitelist/blacklist/availibility checks for if the entity can use this emote</param>
|
||||
public void TryEmoteWithChat(
|
||||
EntityUid source,
|
||||
EmotePrototype emote,
|
||||
ChatTransmitRange range = ChatTransmitRange.Normal,
|
||||
bool hideLog = false,
|
||||
string? nameOverride = null,
|
||||
bool ignoreActionBlocker = false
|
||||
bool ignoreActionBlocker = false,
|
||||
bool forceEmote = false
|
||||
)
|
||||
{
|
||||
if (_whitelistSystem.IsWhitelistFailOrNull(emote.Whitelist, source) || _whitelistSystem.IsBlacklistPass(emote.Blacklist, source))
|
||||
return;
|
||||
|
||||
if (!emote.Available &&
|
||||
TryComp<SpeechComponent>(source, out var speech) &&
|
||||
!speech.AllowedEmotes.Contains(emote.ID))
|
||||
if (!forceEmote && !AllowedToUseEmote(source, emote))
|
||||
return;
|
||||
|
||||
// check if proto has valid message for chat
|
||||
@@ -155,15 +154,40 @@ public partial class ChatSystem
|
||||
_audio.PlayPvs(sound, uid, param);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a valid emote was typed, to play sounds and etc and invokes an event.
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="textInput"></param>
|
||||
private void TryEmoteChatInput(EntityUid uid, string textInput)
|
||||
{
|
||||
var actionLower = textInput.ToLower();
|
||||
if (!_wordEmoteDict.TryGetValue(actionLower, out var emote))
|
||||
return;
|
||||
|
||||
if (!AllowedToUseEmote(uid, emote))
|
||||
return;
|
||||
|
||||
InvokeEmoteEvent(uid, emote);
|
||||
}
|
||||
/// <summary>
|
||||
/// Checks if we can use this emote based on the emotes whitelist, blacklist, and availibility to the entity.
|
||||
/// </summary>
|
||||
/// <param name="source">The entity that is speaking</param>
|
||||
/// <param name="emote">The emote being used</param>
|
||||
/// <returns></returns>
|
||||
private bool AllowedToUseEmote(EntityUid source, EmotePrototype emote)
|
||||
{
|
||||
if ((_whitelistSystem.IsWhitelistFail(emote.Whitelist, source) || _whitelistSystem.IsBlacklistPass(emote.Blacklist, source)))
|
||||
return false;
|
||||
|
||||
if (!emote.Available &&
|
||||
TryComp<SpeechComponent>(source, out var speech) &&
|
||||
!speech.AllowedEmotes.Contains(emote.ID))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void InvokeEmoteEvent(EntityUid uid, EmotePrototype proto)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototy
|
||||
namespace Content.Server.Chemistry.ReagentEffects;
|
||||
|
||||
/// <summary>
|
||||
/// Tries to force someone to emote (scream, laugh, etc).
|
||||
/// Tries to force someone to emote (scream, laugh, etc). Still respects whitelists/blacklists and other limits of the specified emote unless forced.
|
||||
/// </summary>
|
||||
[UsedImplicitly]
|
||||
public sealed partial class Emote : ReagentEffect
|
||||
@@ -19,6 +19,9 @@ public sealed partial class Emote : ReagentEffect
|
||||
[DataField]
|
||||
public bool ShowInChat;
|
||||
|
||||
[DataField]
|
||||
public bool Force = false;
|
||||
|
||||
// JUSTIFICATION: Emoting is flavor, so same reason popup messages are not in here.
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
|
||||
=> null;
|
||||
@@ -30,7 +33,7 @@ public sealed partial class Emote : ReagentEffect
|
||||
|
||||
var chatSys = args.EntityManager.System<ChatSystem>();
|
||||
if (ShowInChat)
|
||||
chatSys.TryEmoteWithChat(args.SolutionEntity, EmoteId, ChatTransmitRange.GhostRangeLimit);
|
||||
chatSys.TryEmoteWithChat(args.SolutionEntity, EmoteId, ChatTransmitRange.GhostRangeLimit, forceEmote: Force);
|
||||
else
|
||||
chatSys.TryEmoteWithoutChat(args.SolutionEntity, EmoteId);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Shared.Chemistry.Reaction;
|
||||
using Content.Shared.Chemistry.Reaction;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Maps;
|
||||
@@ -47,7 +47,8 @@ public sealed partial class CreateEntityTileReaction : ITileReaction
|
||||
int acc = 0;
|
||||
foreach (var ent in tile.GetEntitiesInTile())
|
||||
{
|
||||
if (Whitelist.IsValid(ent))
|
||||
var whitelistSystem = entityManager.System<EntityWhitelistSystem>();
|
||||
if (whitelistSystem.IsWhitelistPass(Whitelist, ent))
|
||||
acc += 1;
|
||||
|
||||
if (acc >= MaxOnTile)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Shared.Configurable;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Tools.Components;
|
||||
using Content.Shared.Tools.Systems;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Player;
|
||||
@@ -11,6 +12,7 @@ namespace Content.Server.Configurable;
|
||||
public sealed class ConfigurationSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -28,7 +30,7 @@ public sealed class ConfigurationSystem : EntitySystem
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (!TryComp(args.Used, out ToolComponent? tool) || !tool.Qualities.Contains(component.QualityNeeded))
|
||||
if (!_toolSystem.HasQuality(args.Used, component.QualityNeeded))
|
||||
return;
|
||||
|
||||
args.Handled = _uiSystem.TryOpenUi(uid, ConfigurationUiKey.Key, args.User);
|
||||
@@ -68,7 +70,7 @@ public sealed class ConfigurationSystem : EntitySystem
|
||||
|
||||
private void OnInsert(EntityUid uid, ConfigurationComponent component, ContainerIsInsertingAttemptEvent args)
|
||||
{
|
||||
if (!TryComp(args.EntityUid, out ToolComponent? tool) || !tool.Qualities.Contains(component.QualityNeeded))
|
||||
if (!_toolSystem.HasQuality(args.EntityUid, component.QualityNeeded))
|
||||
return;
|
||||
|
||||
args.Cancel();
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Tools;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Construction.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Used for something that can be refined by welder.
|
||||
/// For example, glass shard can be refined to glass sheet.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(RefiningSystem))]
|
||||
public sealed partial class WelderRefinableComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The items created when the item is refined.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public List<EntitySpawnEntry> RefineResult = new();
|
||||
|
||||
/// <summary>
|
||||
/// The amount of time it takes to refine a given item.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float RefineTime = 2f;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of fuel it takes to refine a given item.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float RefineFuel;
|
||||
|
||||
/// <summary>
|
||||
/// The tool type needed in order to refine this item.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<ToolQualityPrototype> QualityNeeded = "Welding";
|
||||
}
|
||||
@@ -14,6 +14,7 @@ using Content.Shared.Hands.EntitySystems;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Player;
|
||||
@@ -30,6 +31,7 @@ namespace Content.Server.Construction
|
||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookupSystem = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
|
||||
// --- WARNING! LEGACY CODE AHEAD! ---
|
||||
// This entire file contains the legacy code for initial construction.
|
||||
@@ -337,7 +339,7 @@ namespace Content.Server.Construction
|
||||
return false;
|
||||
}
|
||||
|
||||
if (constructionPrototype.EntityWhitelist != null && !constructionPrototype.EntityWhitelist.IsValid(user))
|
||||
if (_whitelistSystem.IsWhitelistFail(constructionPrototype.EntityWhitelist, user))
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("construction-system-cannot-start"), user, user);
|
||||
return false;
|
||||
@@ -422,7 +424,7 @@ namespace Content.Server.Construction
|
||||
return;
|
||||
}
|
||||
|
||||
if (constructionPrototype.EntityWhitelist != null && !constructionPrototype.EntityWhitelist.IsValid(user))
|
||||
if (_whitelistSystem.IsWhitelistFail(constructionPrototype.EntityWhitelist, user))
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("construction-system-cannot-start"), user, user);
|
||||
return;
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
using Content.Server.Construction.Components;
|
||||
using Content.Shared.Construction;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Tools.Systems;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Construction;
|
||||
|
||||
public sealed class RefiningSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<WelderRefinableComponent, InteractUsingEvent>(OnInteractUsing);
|
||||
SubscribeLocalEvent<WelderRefinableComponent, WelderRefineDoAfterEvent>(OnDoAfter);
|
||||
}
|
||||
|
||||
private void OnInteractUsing(EntityUid uid, WelderRefinableComponent component, InteractUsingEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
args.Handled = _toolSystem.UseTool(
|
||||
args.Used,
|
||||
args.User,
|
||||
uid,
|
||||
component.RefineTime,
|
||||
component.QualityNeeded,
|
||||
new WelderRefineDoAfterEvent(),
|
||||
fuel: component.RefineFuel);
|
||||
}
|
||||
|
||||
private void OnDoAfter(EntityUid uid, WelderRefinableComponent component, WelderRefineDoAfterEvent args)
|
||||
{
|
||||
if (args.Cancelled)
|
||||
return;
|
||||
|
||||
var xform = Transform(uid);
|
||||
var spawns = EntitySpawnCollection.GetSpawns(component.RefineResult, _random);
|
||||
foreach (var spawn in spawns)
|
||||
{
|
||||
SpawnNextToOrDrop(spawn, uid, xform);
|
||||
}
|
||||
|
||||
Del(uid);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,19 @@
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Tools;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Damage.Components
|
||||
namespace Content.Server.Damage.Components;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class DamageOnToolInteractComponent : Component
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed partial class DamageOnToolInteractComponent : Component
|
||||
{
|
||||
[DataField("tools")]
|
||||
public PrototypeFlags<ToolQualityPrototype> Tools { get; private set; } = new ();
|
||||
[DataField]
|
||||
public ProtoId<ToolQualityPrototype> Tools { get; private set; }
|
||||
|
||||
// TODO: Remove this snowflake stuff, make damage per-tool quality perhaps?
|
||||
[DataField("weldingDamage")]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public DamageSpecifier? WeldingDamage { get; private set; }
|
||||
// TODO: Remove this snowflake stuff, make damage per-tool quality perhaps?
|
||||
[DataField]
|
||||
public DamageSpecifier? WeldingDamage { get; private set; }
|
||||
|
||||
[DataField("defaultDamage")]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public DamageSpecifier? DefaultDamage { get; private set; }
|
||||
}
|
||||
[DataField]
|
||||
public DamageSpecifier? DefaultDamage { get; private set; }
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using Content.Shared.Damage;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Tools.Components;
|
||||
using Content.Shared.Tools.Systems;
|
||||
using ItemToggleComponent = Content.Shared.Item.ItemToggle.Components.ItemToggleComponent;
|
||||
|
||||
namespace Content.Server.Damage.Systems
|
||||
@@ -12,6 +13,7 @@ namespace Content.Server.Damage.Systems
|
||||
{
|
||||
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -42,8 +44,7 @@ namespace Content.Server.Damage.Systems
|
||||
args.Handled = true;
|
||||
}
|
||||
else if (component.DefaultDamage is {} damage
|
||||
&& EntityManager.TryGetComponent(args.Used, out ToolComponent? tool)
|
||||
&& tool.Qualities.ContainsAny(component.Tools))
|
||||
&& _toolSystem.HasQuality(args.Used, component.Tools))
|
||||
{
|
||||
var dmg = _damageableSystem.TryChangeDamage(args.Target, damage, origin: args.User);
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using System.Numerics;
|
||||
using Content.Server.Forensics;
|
||||
using Content.Server.Stack;
|
||||
using Content.Shared.Destructible.Thresholds;
|
||||
using Content.Shared.Prototypes;
|
||||
using Content.Shared.Stacks;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
|
||||
|
||||
namespace Content.Server.Destructible.Thresholds.Behaviors
|
||||
{
|
||||
@@ -17,8 +17,8 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
|
||||
/// <summary>
|
||||
/// Entities spawned on reaching this threshold, from a min to a max.
|
||||
/// </summary>
|
||||
[DataField("spawn", customTypeSerializer:typeof(PrototypeIdDictionarySerializer<MinMax, EntityPrototype>))]
|
||||
public Dictionary<string, MinMax> Spawn { get; set; } = new();
|
||||
[DataField]
|
||||
public Dictionary<EntProtoId, MinMax> Spawn = new();
|
||||
|
||||
[DataField("offset")]
|
||||
public float Offset { get; set; } = 0.5f;
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Destructible.Thresholds
|
||||
{
|
||||
[Serializable]
|
||||
[DataDefinition]
|
||||
public partial struct MinMax
|
||||
{
|
||||
[DataField("min")]
|
||||
public int Min;
|
||||
|
||||
[DataField("max")]
|
||||
public int Max;
|
||||
|
||||
public MinMax(int min, int max)
|
||||
{
|
||||
Min = min;
|
||||
Max = max;
|
||||
}
|
||||
|
||||
public int Next(IRobustRandom random)
|
||||
{
|
||||
return random.Next(Min, Max + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Content.Server.GameTicking.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Added to game rules before <see cref="GameRuleStartedEvent"/> and removed before <see cref="GameRuleEndedEvent"/>.
|
||||
/// Mutually exclusive with <seealso cref="EndedGameRuleComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class ActiveGameRuleComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Server.GameTicking.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Generic component used to track a gamerule that's start has been delayed.
|
||||
/// </summary>
|
||||
[RegisterComponent, AutoGenerateComponentPause]
|
||||
public sealed partial class DelayedStartRuleComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The time at which the rule will start properly.
|
||||
/// </summary>
|
||||
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
|
||||
public TimeSpan RuleStartTime;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Content.Server.GameTicking.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Added to game rules before <see cref="GameRuleEndedEvent"/>.
|
||||
/// Mutually exclusive with <seealso cref="ActiveGameRuleComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class EndedGameRuleComponent : Component
|
||||
{
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
using Content.Server.Destructible.Thresholds;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Server.GameTicking.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Component attached to all gamerule entities.
|
||||
/// Used to both track the entity as well as store basic data
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class GameRuleComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Game time when game rule was activated
|
||||
/// </summary>
|
||||
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
|
||||
public TimeSpan ActivatedAt;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum amount of players needed for this game rule.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int MinPlayers;
|
||||
|
||||
/// <summary>
|
||||
/// A delay for when the rule the is started and when the starting logic actually runs.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public MinMax? Delay;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when a rule is added but hasn't formally begun yet.
|
||||
/// Good for announcing station events and other such things.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public readonly record struct GameRuleAddedEvent(EntityUid RuleEntity, string RuleId);
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the rule actually begins.
|
||||
/// Player-facing logic should begin here.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public readonly record struct GameRuleStartedEvent(EntityUid RuleEntity, string RuleId);
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the rule ends.
|
||||
/// Do cleanup and other such things here.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public readonly record struct GameRuleEndedEvent(EntityUid RuleEntity, string RuleId);
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Administration;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Prototypes;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Console;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.Maps;
|
||||
using Content.Shared.GridPreloader.Prototypes;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -10,25 +8,27 @@ namespace Content.Server.GameTicking.Rules.Components;
|
||||
|
||||
/// <summary>
|
||||
/// This is used for a game rule that loads a map when activated.
|
||||
/// Works with <see cref="RuleGridsComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
[RegisterComponent, Access(typeof(LoadMapRuleSystem))]
|
||||
public sealed partial class LoadMapRuleComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public MapId? Map;
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="GameMapPrototype"/> to load on a new map.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<GameMapPrototype>? GameMap;
|
||||
|
||||
/// <summary>
|
||||
/// A map path to load on a new map.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ResPath? MapPath;
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="PreloadedGridPrototype"/> to move to a new map.
|
||||
/// If there are no instances left nothing is done.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public ProtoId<PreloadedGridPrototype>? PreloadedGrid;
|
||||
|
||||
[DataField]
|
||||
public List<EntityUid> MapGrids = new();
|
||||
|
||||
[DataField]
|
||||
public EntityWhitelist? SpawnerWhitelist;
|
||||
}
|
||||
|
||||
@@ -6,4 +6,9 @@
|
||||
[RegisterComponent, Access(typeof(RespawnRuleSystem))]
|
||||
public sealed partial class RespawnDeadRuleComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether or not we want to add everyone who dies to the respawn tracker
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool AlwaysRespawnDead;
|
||||
}
|
||||
|
||||
@@ -13,18 +13,24 @@ public sealed partial class RespawnTrackerComponent : Component
|
||||
/// A list of the people that should be respawned.
|
||||
/// Used to make sure that we don't respawn aghosts or observers.
|
||||
/// </summary>
|
||||
[DataField("players")]
|
||||
[DataField]
|
||||
public HashSet<NetUserId> Players = new();
|
||||
|
||||
/// <summary>
|
||||
/// The delay between dying and respawning.
|
||||
/// </summary>
|
||||
[DataField("respawnDelay")]
|
||||
[DataField]
|
||||
public TimeSpan RespawnDelay = TimeSpan.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary of player netuserids and when they will respawn.
|
||||
/// </summary>
|
||||
[DataField("respawnQueue")]
|
||||
[DataField]
|
||||
public Dictionary<NetUserId, TimeSpan> RespawnQueue = new();
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not to delete the original body when respawning
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool DeleteBody = true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
/// <summary>
|
||||
/// Stores grids created by another gamerule component.
|
||||
/// With <c>AntagSelection</c>, spawners on these grids can be used for its antags.
|
||||
/// </summary>
|
||||
[RegisterComponent, Access(typeof(RuleGridsSystem))]
|
||||
public sealed partial class RuleGridsComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// The map that was loaded.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public MapId? Map;
|
||||
|
||||
/// <summary>
|
||||
/// The grid entities that have been loaded.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public List<EntityUid> MapGrids = new();
|
||||
|
||||
/// <summary>
|
||||
/// Whitelist for a spawner to be considered for an antag.
|
||||
/// All spawners must have <c>SpawnPointComponent</c> regardless to be found.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntityWhitelist? SpawnerWhitelist;
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Administration.Commands;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.KillTracking;
|
||||
using Content.Server.Mind;
|
||||
using Content.Server.Points;
|
||||
using Content.Server.RoundEnd;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Points;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Server.GameObjects;
|
||||
@@ -56,7 +56,7 @@ public sealed class DeathMatchRuleSystem : GameRuleSystem<DeathMatchRuleComponen
|
||||
_mind.TransferTo(newMind, mob);
|
||||
SetOutfitCommand.SetOutfit(mob, dm.Gear, EntityManager);
|
||||
EnsureComp<KillTrackerComponent>(mob);
|
||||
_respawn.AddToTracker(ev.Player.UserId, uid, tracker);
|
||||
_respawn.AddToTracker(ev.Player.UserId, (uid, tracker));
|
||||
|
||||
_point.EnsurePlayer(ev.Player.UserId, uid, point);
|
||||
|
||||
@@ -73,7 +73,7 @@ public sealed class DeathMatchRuleSystem : GameRuleSystem<DeathMatchRuleComponen
|
||||
{
|
||||
if (!GameTicker.IsGameRuleActive(uid, rule))
|
||||
continue;
|
||||
_respawn.AddToTracker(ev.Mob, uid, tracker);
|
||||
_respawn.AddToTracker((ev.Mob, null), (uid, tracker));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
|
||||
namespace Content.Server.GameTicking.Rules;
|
||||
|
||||
/*
|
||||
[Prototype("gameRule")]
|
||||
public sealed partial class GameRulePrototype : IPrototype
|
||||
{
|
||||
[IdDataField]
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
[DataField("config", required: true)]
|
||||
public GameRuleConfiguration Configuration { get; private set; } = default!;
|
||||
}
|
||||
*/
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Random.Helpers;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Collections;
|
||||
@@ -126,4 +126,8 @@ public abstract partial class GameRuleSystem<T> where T: IComponent
|
||||
return found;
|
||||
}
|
||||
|
||||
protected void ForceEndSelf(EntityUid uid, GameRuleComponent? component = null)
|
||||
{
|
||||
GameTicker.EndGameRule(uid, component);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Threading;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Player;
|
||||
using Timer = Robust.Shared.Timing.Timer;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.KillTracking;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using Content.Server.Antag;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.GridPreloader;
|
||||
using Content.Server.Spawners.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Maps;
|
||||
using Robust.Shared.Map;
|
||||
@@ -13,96 +11,70 @@ namespace Content.Server.GameTicking.Rules;
|
||||
public sealed class LoadMapRuleSystem : GameRuleSystem<LoadMapRuleComponent>
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly MapSystem _map = default!;
|
||||
[Dependency] private readonly MapLoaderSystem _mapLoader = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
[Dependency] private readonly TransformSystem _transform = default!;
|
||||
[Dependency] private readonly GridPreloaderSystem _gridPreloader = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<LoadMapRuleComponent, AntagSelectLocationEvent>(OnSelectLocation);
|
||||
SubscribeLocalEvent<GridSplitEvent>(OnGridSplit);
|
||||
}
|
||||
|
||||
private void OnGridSplit(ref GridSplitEvent args)
|
||||
{
|
||||
var rule = QueryActiveRules();
|
||||
while (rule.MoveNext(out _, out var mapComp, out _))
|
||||
{
|
||||
if (!mapComp.MapGrids.Contains(args.Grid))
|
||||
continue;
|
||||
|
||||
mapComp.MapGrids.AddRange(args.NewGrids);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Added(EntityUid uid, LoadMapRuleComponent comp, GameRuleComponent rule, GameRuleAddedEvent args)
|
||||
{
|
||||
if (comp.Map != null)
|
||||
if (comp.PreloadedGrid != null && !_gridPreloader.PreloadingEnabled)
|
||||
{
|
||||
// Preloading will never work if it's disabled, duh
|
||||
Log.Debug($"Immediately ending {ToPrettyString(uid):rule} as preloading grids is disabled by cvar.");
|
||||
ForceEndSelf(uid, rule);
|
||||
return;
|
||||
}
|
||||
|
||||
// grid preloading needs map to init after moving it
|
||||
var mapUid = comp.PreloadedGrid != null ? _map.CreateMap(out var mapId, false) : _map.CreateMap(out mapId);
|
||||
_metaData.SetEntityName(mapUid, $"LoadMapRule destination for rule {ToPrettyString(uid)}");
|
||||
comp.Map = mapId;
|
||||
var mapUid = _map.CreateMap(out var mapId, runMapInit: comp.PreloadedGrid == null);
|
||||
|
||||
Log.Info($"Created map {mapId} for {ToPrettyString(uid):rule}");
|
||||
|
||||
IReadOnlyList<EntityUid> grids;
|
||||
if (comp.GameMap != null)
|
||||
{
|
||||
var gameMap = _prototypeManager.Index(comp.GameMap.Value);
|
||||
comp.MapGrids.AddRange(GameTicker.LoadGameMap(gameMap, comp.Map.Value, new MapLoadOptions()));
|
||||
grids = GameTicker.LoadGameMap(gameMap, mapId, new MapLoadOptions());
|
||||
}
|
||||
else if (comp.MapPath != null)
|
||||
else if (comp.MapPath is {} path)
|
||||
{
|
||||
if (!_mapLoader.TryLoad(comp.Map.Value,
|
||||
comp.MapPath.Value.ToString(),
|
||||
out var roots,
|
||||
new MapLoadOptions { LoadMap = true }))
|
||||
var options = new MapLoadOptions { LoadMap = true };
|
||||
if (!_mapLoader.TryLoad(mapId, path.ToString(), out var roots, options))
|
||||
{
|
||||
_mapManager.DeleteMap(mapId);
|
||||
Log.Error($"Failed to load map from {path}!");
|
||||
Del(mapUid);
|
||||
ForceEndSelf(uid, rule);
|
||||
return;
|
||||
}
|
||||
|
||||
comp.MapGrids.AddRange(roots);
|
||||
grids = roots;
|
||||
}
|
||||
else if (comp.PreloadedGrid != null)
|
||||
else if (comp.PreloadedGrid is {} preloaded)
|
||||
{
|
||||
// TODO: If there are no preloaded grids left, any rule announcements will still go off!
|
||||
if (!_gridPreloader.TryGetPreloadedGrid(comp.PreloadedGrid.Value, out var loadedShuttle))
|
||||
if (!_gridPreloader.TryGetPreloadedGrid(preloaded, out var loadedShuttle))
|
||||
{
|
||||
_mapManager.DeleteMap(mapId);
|
||||
Log.Error($"Failed to get a preloaded grid with {preloaded}!");
|
||||
Del(mapUid);
|
||||
ForceEndSelf(uid, rule);
|
||||
return;
|
||||
}
|
||||
|
||||
_transform.SetParent(loadedShuttle.Value, mapUid);
|
||||
comp.MapGrids.Add(loadedShuttle.Value);
|
||||
_map.InitializeMap(mapId);
|
||||
grids = new List<EntityUid>() { loadedShuttle.Value };
|
||||
_map.InitializeMap(mapUid);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error($"No valid map prototype or map path associated with the rule {ToPrettyString(uid)}");
|
||||
Del(mapUid);
|
||||
ForceEndSelf(uid, rule);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectLocation(Entity<LoadMapRuleComponent> ent, ref AntagSelectLocationEvent args)
|
||||
{
|
||||
var query = EntityQueryEnumerator<SpawnPointComponent, TransformComponent>();
|
||||
while (query.MoveNext(out var uid, out _, out var xform))
|
||||
{
|
||||
if (xform.MapID != ent.Comp.Map)
|
||||
continue;
|
||||
|
||||
if (xform.GridUid == null || !ent.Comp.MapGrids.Contains(xform.GridUid.Value))
|
||||
continue;
|
||||
|
||||
if (ent.Comp.SpawnerWhitelist != null && !ent.Comp.SpawnerWhitelist.IsValid(uid, EntityManager))
|
||||
continue;
|
||||
|
||||
args.Coordinates.Add(_transform.GetMapCoordinates(xform));
|
||||
}
|
||||
var ev = new RuleLoadedGridsEvent(mapId, grids);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Threading;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Timer = Robust.Shared.Timing.Timer;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules;
|
||||
|
||||
@@ -11,6 +11,7 @@ using Content.Server.Shuttles.Systems;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Store.Components;
|
||||
using Content.Server.Store.Systems;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.NPC.Components;
|
||||
@@ -24,7 +25,6 @@ using Robust.Shared.Map;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Shared.Store.Components;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules;
|
||||
@@ -260,10 +260,10 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
{
|
||||
var map = Transform(ent).MapID;
|
||||
|
||||
var rules = EntityQueryEnumerator<NukeopsRuleComponent, LoadMapRuleComponent>();
|
||||
while (rules.MoveNext(out var uid, out _, out var mapRule))
|
||||
var rules = EntityQueryEnumerator<NukeopsRuleComponent, RuleGridsComponent>();
|
||||
while (rules.MoveNext(out var uid, out _, out var grids))
|
||||
{
|
||||
if (map != mapRule.Map)
|
||||
if (map != grids.Map)
|
||||
continue;
|
||||
ent.Comp.AssociatedRule = uid;
|
||||
break;
|
||||
@@ -324,7 +324,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
if (nukeops.WarDeclaredTime != null)
|
||||
continue;
|
||||
|
||||
if (TryComp<LoadMapRuleComponent>(uid, out var mapComp) && Transform(ev.DeclaratorEntity).MapID != mapComp.Map)
|
||||
if (TryComp<RuleGridsComponent>(uid, out var grids) && Transform(ev.DeclaratorEntity).MapID != grids.Map)
|
||||
continue;
|
||||
|
||||
var newStatus = GetWarCondition(nukeops, ev.Status);
|
||||
@@ -445,7 +445,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
|
||||
// Check that there are spawns available and that they can access the shuttle.
|
||||
var spawnsAvailable = EntityQuery<NukeOperativeSpawnerComponent>(true).Any();
|
||||
if (spawnsAvailable && CompOrNull<LoadMapRuleComponent>(ent)?.Map == shuttleMapId)
|
||||
if (spawnsAvailable && CompOrNull<RuleGridsComponent>(ent)?.Map == shuttleMapId)
|
||||
return; // Ghost spawns can still access the shuttle. Continue the round.
|
||||
|
||||
// The shuttle is inaccessible to both living nuke operatives and yet to spawn nuke operatives,
|
||||
@@ -478,7 +478,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
|
||||
/// Is this method the shitty glue holding together the last of my sanity? yes.
|
||||
/// Do i have a better solution? not presently.
|
||||
/// </remarks>
|
||||
private EntityUid? GetOutpost(Entity<LoadMapRuleComponent?> ent)
|
||||
private EntityUid? GetOutpost(Entity<RuleGridsComponent?> ent)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp, false))
|
||||
return null;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.Database.Migrations.Postgres;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Mobs;
|
||||
@@ -34,38 +35,6 @@ public sealed class RespawnRuleSystem : GameRuleSystem<RespawnDeadRuleComponent>
|
||||
SubscribeLocalEvent<MobStateChangedEvent>(OnMobStateChanged);
|
||||
}
|
||||
|
||||
private void OnSuicide(SuicideEvent ev)
|
||||
{
|
||||
if (!TryComp<ActorComponent>(ev.Victim, out var actor))
|
||||
return;
|
||||
|
||||
var query = EntityQueryEnumerator<RespawnTrackerComponent>();
|
||||
while (query.MoveNext(out _, out var respawn))
|
||||
{
|
||||
if (respawn.Players.Remove(actor.PlayerSession.UserId))
|
||||
QueueDel(ev.Victim);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMobStateChanged(MobStateChangedEvent args)
|
||||
{
|
||||
if (args.NewMobState == MobState.Alive)
|
||||
return;
|
||||
|
||||
if (!TryComp<ActorComponent>(args.Target, out var actor))
|
||||
return;
|
||||
|
||||
var query = EntityQueryEnumerator<RespawnDeadRuleComponent, GameRuleComponent>();
|
||||
while (query.MoveNext(out var uid, out _, out var rule))
|
||||
{
|
||||
if (!GameTicker.IsGameRuleActive(uid, rule))
|
||||
continue;
|
||||
|
||||
if (RespawnPlayer(args.Target, uid, actor: actor))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
@@ -75,8 +44,7 @@ public sealed class RespawnRuleSystem : GameRuleSystem<RespawnDeadRuleComponent>
|
||||
|
||||
foreach (var tracker in EntityQuery<RespawnTrackerComponent>())
|
||||
{
|
||||
var queue = new Dictionary<NetUserId, TimeSpan>(tracker.RespawnQueue);
|
||||
foreach (var (player, time) in queue)
|
||||
foreach (var (player, time) in tracker.RespawnQueue)
|
||||
{
|
||||
if (_timing.CurTime < time)
|
||||
continue;
|
||||
@@ -92,53 +60,84 @@ public sealed class RespawnRuleSystem : GameRuleSystem<RespawnDeadRuleComponent>
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a given player to the respawn tracker, ensuring that they are respawned if they die.
|
||||
/// </summary>
|
||||
public void AddToTracker(EntityUid player, EntityUid tracker, RespawnTrackerComponent? component = null, ActorComponent? actor = null)
|
||||
private void OnSuicide(SuicideEvent ev)
|
||||
{
|
||||
if (!Resolve(tracker, ref component) || !Resolve(player, ref actor, false))
|
||||
return;
|
||||
if (!TryComp<ActorComponent>(ev.Victim, out var actor))
|
||||
return;
|
||||
|
||||
AddToTracker(actor.PlayerSession.UserId, tracker, component);
|
||||
var query = EntityQueryEnumerator<RespawnTrackerComponent>();
|
||||
while (query.MoveNext(out _, out var respawn))
|
||||
{
|
||||
if (respawn.Players.Remove(actor.PlayerSession.UserId))
|
||||
QueueDel(ev.Victim);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a given player to the respawn tracker, ensuring that they are respawned if they die.
|
||||
/// </summary>
|
||||
public void AddToTracker(NetUserId id, EntityUid tracker, RespawnTrackerComponent? component = null)
|
||||
private void OnMobStateChanged(MobStateChangedEvent args)
|
||||
{
|
||||
if (!Resolve(tracker, ref component))
|
||||
if (args.NewMobState != MobState.Dead)
|
||||
return;
|
||||
|
||||
component.Players.Add(id);
|
||||
if (!TryComp<ActorComponent>(args.Target, out var actor))
|
||||
return;
|
||||
|
||||
var query = EntityQueryEnumerator<RespawnDeadRuleComponent, RespawnTrackerComponent, GameRuleComponent>();
|
||||
while (query.MoveNext(out var uid, out var respawnRule, out var tracker, out var rule))
|
||||
{
|
||||
if (!GameTicker.IsGameRuleActive(uid, rule))
|
||||
continue;
|
||||
|
||||
if (respawnRule.AlwaysRespawnDead)
|
||||
AddToTracker(actor.PlayerSession.UserId, (uid, tracker));
|
||||
if (RespawnPlayer((args.Target, actor), (uid, tracker)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to directly respawn a player, skipping the lobby screen.
|
||||
/// </summary>
|
||||
public bool RespawnPlayer(EntityUid player, EntityUid respawnTracker, RespawnTrackerComponent? component = null, ActorComponent? actor = null)
|
||||
public bool RespawnPlayer(Entity<ActorComponent> player, Entity<RespawnTrackerComponent> respawnTracker)
|
||||
{
|
||||
if (!Resolve(respawnTracker, ref component) || !Resolve(player, ref actor, false))
|
||||
if (!respawnTracker.Comp.Players.Contains(player.Comp.PlayerSession.UserId) || respawnTracker.Comp.RespawnQueue.ContainsKey(player.Comp.PlayerSession.UserId))
|
||||
return false;
|
||||
|
||||
if (!component.Players.Contains(actor.PlayerSession.UserId) || component.RespawnQueue.ContainsKey(actor.PlayerSession.UserId))
|
||||
return false;
|
||||
|
||||
if (component.RespawnDelay == TimeSpan.Zero)
|
||||
if (respawnTracker.Comp.RespawnDelay == TimeSpan.Zero)
|
||||
{
|
||||
if (_station.GetStations().FirstOrNull() is not { } station)
|
||||
return false;
|
||||
|
||||
QueueDel(player);
|
||||
GameTicker.MakeJoinGame(actor.PlayerSession, station, silent: true);
|
||||
if (respawnTracker.Comp.DeleteBody)
|
||||
QueueDel(player);
|
||||
GameTicker.MakeJoinGame(player.Comp.PlayerSession, station, silent: true);
|
||||
return false;
|
||||
}
|
||||
|
||||
var msg = Loc.GetString("rule-respawn-in-seconds", ("second", component.RespawnDelay.TotalSeconds));
|
||||
var msg = Loc.GetString("rule-respawn-in-seconds", ("second", respawnTracker.Comp.RespawnDelay.TotalSeconds));
|
||||
var wrappedMsg = Loc.GetString("chat-manager-server-wrap-message", ("message", msg));
|
||||
_chatManager.ChatMessageToOne(ChatChannel.Server, msg, wrappedMsg, respawnTracker, false, actor.PlayerSession.Channel, Color.LimeGreen);
|
||||
component.RespawnQueue[actor.PlayerSession.UserId] = _timing.CurTime + component.RespawnDelay;
|
||||
_chatManager.ChatMessageToOne(ChatChannel.Server, msg, wrappedMsg, respawnTracker, false, player.Comp.PlayerSession.Channel, Color.LimeGreen);
|
||||
|
||||
respawnTracker.Comp.RespawnQueue[player.Comp.PlayerSession.UserId] = _timing.CurTime + respawnTracker.Comp.RespawnDelay;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a given player to the respawn tracker, ensuring that they are respawned if they die.
|
||||
/// </summary>
|
||||
public void AddToTracker(Entity<ActorComponent?> player, Entity<RespawnTrackerComponent?> respawnTracker)
|
||||
{
|
||||
if (!Resolve(respawnTracker, ref respawnTracker.Comp) || !Resolve(player, ref player.Comp, false))
|
||||
return;
|
||||
|
||||
AddToTracker(player.Comp.PlayerSession.UserId, (respawnTracker, respawnTracker.Comp));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a given player to the respawn tracker, ensuring that they are respawned if they die.
|
||||
/// </summary>
|
||||
public void AddToTracker(NetUserId id, Entity<RespawnTrackerComponent> tracker)
|
||||
{
|
||||
tracker.Comp.Players.Add(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ using Content.Server.RoundEnd;
|
||||
using Content.Server.Shuttles.Systems;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.IdentityManagement;
|
||||
using Content.Shared.Mind;
|
||||
@@ -27,7 +28,6 @@ using Content.Shared.Stunnable;
|
||||
using Content.Shared.Zombies;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Shared.Cuffs.Components;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Linq;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Shuttles.Systems;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Station.Events;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
78
Content.Server/GameTicking/Rules/RuleGridsSystem.cs
Normal file
78
Content.Server/GameTicking/Rules/RuleGridsSystem.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using Content.Server.Antag;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Spawners.Components;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Server.Physics;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules;
|
||||
|
||||
/// <summary>
|
||||
/// Handles storing grids from <see cref="RuleLoadedGridsEvent"/> and antags spawning on their spawners.
|
||||
/// </summary>
|
||||
public sealed class RuleGridsSystem : GameRuleSystem<RuleGridsComponent>
|
||||
{
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<GridSplitEvent>(OnGridSplit);
|
||||
|
||||
SubscribeLocalEvent<RuleGridsComponent, RuleLoadedGridsEvent>(OnLoadedGrids);
|
||||
SubscribeLocalEvent<RuleGridsComponent, AntagSelectLocationEvent>(OnSelectLocation);
|
||||
}
|
||||
|
||||
private void OnGridSplit(ref GridSplitEvent args)
|
||||
{
|
||||
var rule = QueryActiveRules();
|
||||
while (rule.MoveNext(out _, out var comp, out _))
|
||||
{
|
||||
if (!comp.MapGrids.Contains(args.Grid))
|
||||
continue;
|
||||
|
||||
comp.MapGrids.AddRange(args.NewGrids);
|
||||
break; // only 1 rule can own a grid, not multiple
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLoadedGrids(Entity<RuleGridsComponent> ent, ref RuleLoadedGridsEvent args)
|
||||
{
|
||||
var (uid, comp) = ent;
|
||||
if (comp.Map != null && args.Map != comp.Map)
|
||||
{
|
||||
Log.Warning($"{ToPrettyString(uid):rule} loaded grids on multiple maps {comp.Map} and {args.Map}, the second will be ignored.");
|
||||
return;
|
||||
}
|
||||
|
||||
comp.Map = args.Map;
|
||||
comp.MapGrids.AddRange(args.Grids);
|
||||
}
|
||||
|
||||
private void OnSelectLocation(Entity<RuleGridsComponent> ent, ref AntagSelectLocationEvent args)
|
||||
{
|
||||
var query = EntityQueryEnumerator<SpawnPointComponent, TransformComponent>();
|
||||
while (query.MoveNext(out var uid, out _, out var xform))
|
||||
{
|
||||
if (xform.MapID != ent.Comp.Map)
|
||||
continue;
|
||||
|
||||
if (xform.GridUid is not {} grid || !ent.Comp.MapGrids.Contains(grid))
|
||||
continue;
|
||||
|
||||
if (_whitelist.IsWhitelistFail(ent.Comp.SpawnerWhitelist, uid))
|
||||
continue;
|
||||
|
||||
args.Coordinates.Add(_transform.GetMapCoordinates(xform));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised by another gamerule system to store loaded grids, and have other systems work with it.
|
||||
/// A single rule can only load grids for a single map, attempts to load more are ignored.
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public record struct RuleLoadedGridsEvent(MapId Map, IReadOnlyList<EntityUid> Grids);
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Sandbox;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules;
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.Chat.Managers;
|
||||
using Content.Server.GameTicking.Presets;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Random;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Database;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Storage;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules;
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Server.Objectives;
|
||||
using Content.Server.PDA.Ringer;
|
||||
using Content.Server.Roles;
|
||||
using Content.Server.Traitor.Uplink;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.NPC.Systems;
|
||||
using Content.Shared.Objectives.Components;
|
||||
@@ -15,7 +16,6 @@ using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Content.Server.GameTicking.Components;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server.GameTicking.Rules.VariationPass.Components;
|
||||
using Content.Server.Wires;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules.VariationPass;
|
||||
@@ -11,6 +12,8 @@ namespace Content.Server.GameTicking.Rules.VariationPass;
|
||||
/// </summary>
|
||||
public sealed class CutWireVariationPassSystem : VariationPassSystem<CutWireVariationPassComponent>
|
||||
{
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
|
||||
protected override void ApplyVariation(Entity<CutWireVariationPassComponent> ent, ref StationVariationPassEvent args)
|
||||
{
|
||||
var wiresCut = 0;
|
||||
@@ -22,7 +25,7 @@ public sealed class CutWireVariationPassSystem : VariationPassSystem<CutWireVari
|
||||
continue;
|
||||
|
||||
// Check against blacklist
|
||||
if (ent.Comp.Blacklist.IsValid(uid))
|
||||
if (_whitelistSystem.IsBlacklistPass(ent.Comp.Blacklist, uid))
|
||||
continue;
|
||||
|
||||
if (Random.Prob(ent.Comp.WireCutChance))
|
||||
|
||||
@@ -6,6 +6,7 @@ using Content.Server.RoundEnd;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.Zombies;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Mobs;
|
||||
@@ -15,7 +16,6 @@ using Content.Shared.Zombies;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Timing;
|
||||
using System.Globalization;
|
||||
using Content.Server.GameTicking.Components;
|
||||
|
||||
namespace Content.Server.GameTicking.Rules;
|
||||
|
||||
|
||||
@@ -24,12 +24,19 @@ public sealed class GridPreloaderSystem : SharedGridPreloaderSystem
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the preloading CVar is set or not.
|
||||
/// </summary>
|
||||
public bool PreloadingEnabled;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
|
||||
SubscribeLocalEvent<PostGameMapLoad>(OnPostGameMapLoad);
|
||||
|
||||
Subs.CVar(_cfg, CCVars.PreloadGrids, value => PreloadingEnabled = value, true);
|
||||
}
|
||||
|
||||
private void OnRoundRestart(RoundRestartCleanupEvent ev)
|
||||
@@ -52,7 +59,7 @@ public sealed class GridPreloaderSystem : SharedGridPreloaderSystem
|
||||
if (GetPreloaderEntity() != null)
|
||||
return;
|
||||
|
||||
if (!_cfg.GetCVar(CCVars.PreloadGrids))
|
||||
if (!PreloadingEnabled)
|
||||
return;
|
||||
|
||||
var mapUid = _map.CreateMap(out var mapId, false);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Hands.Systems;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Item;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Server.Audio;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Map.Components;
|
||||
@@ -24,6 +25,7 @@ public sealed class RandomGiftSystem : EntitySystem
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
|
||||
private readonly List<string> _possibleGiftsSafe = new();
|
||||
private readonly List<string> _possibleGiftsUnsafe = new();
|
||||
@@ -40,7 +42,7 @@ public sealed class RandomGiftSystem : EntitySystem
|
||||
|
||||
private void OnExamined(EntityUid uid, RandomGiftComponent component, ExaminedEvent args)
|
||||
{
|
||||
if (!component.ContentsViewers.IsValid(args.Examiner, EntityManager) || component.SelectedEntity is null)
|
||||
if (_whitelistSystem.IsWhitelistFail(component.ContentsViewers, args.Examiner) || component.SelectedEntity is null)
|
||||
return;
|
||||
|
||||
var name = _prototype.Index<EntityPrototype>(component.SelectedEntity).Name;
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Server.NPC.HTN;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Server.KillTracking;
|
||||
@@ -14,7 +15,8 @@ public sealed class KillTrackingSystem : EntitySystem
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<KillTrackerComponent, DamageChangedEvent>(OnDamageChanged);
|
||||
// Add damage to LifetimeDamage before MobStateChangedEvent gets raised
|
||||
SubscribeLocalEvent<KillTrackerComponent, DamageChangedEvent>(OnDamageChanged, before: [ typeof(MobThresholdSystem) ]);
|
||||
SubscribeLocalEvent<KillTrackerComponent, MobStateChangedEvent>(OnMobStateChanged);
|
||||
}
|
||||
|
||||
@@ -50,7 +52,7 @@ public sealed class KillTrackingSystem : EntitySystem
|
||||
var largestSource = GetLargestSource(component.LifetimeDamage);
|
||||
largestSource ??= killImpulse;
|
||||
|
||||
KillSource? killSource;
|
||||
KillSource killSource;
|
||||
KillSource? assistSource = null;
|
||||
|
||||
if (killImpulse is KillEnvironmentSource)
|
||||
@@ -69,13 +71,13 @@ public sealed class KillTrackingSystem : EntitySystem
|
||||
killSource = killImpulse;
|
||||
|
||||
// no assist is given to environmental kills
|
||||
if (largestSource is not KillEnvironmentSource)
|
||||
if (largestSource is not KillEnvironmentSource
|
||||
&& component.LifetimeDamage.TryGetValue(largestSource, out var largestDamage))
|
||||
{
|
||||
// you have to do at least 50% of largest source's damage to get the assist.
|
||||
if (component.LifetimeDamage[largestSource] >= component.LifetimeDamage[killSource] / 2)
|
||||
{
|
||||
var killDamage = component.LifetimeDamage.GetValueOrDefault(killSource);
|
||||
// you have to do at least twice as much damage as the killing source to get the assist.
|
||||
if (largestDamage >= killDamage / 2)
|
||||
assistSource = largestSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Tools.Components;
|
||||
using Content.Shared.Tools.Systems;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Shared.Containers;
|
||||
|
||||
@@ -15,6 +16,7 @@ public sealed class MechAssemblySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ContainerSystem _container = default!;
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
@@ -30,7 +32,7 @@ public sealed class MechAssemblySystem : EntitySystem
|
||||
|
||||
private void OnInteractUsing(EntityUid uid, MechAssemblyComponent component, InteractUsingEvent args)
|
||||
{
|
||||
if (TryComp<ToolComponent>(args.Used, out var toolComp) && toolComp.Qualities.Contains(component.QualityNeeded))
|
||||
if (_toolSystem.HasQuality(args.Used, component.QualityNeeded))
|
||||
{
|
||||
foreach (var tag in component.RequiredParts.Keys)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using Content.Shared.DoAfter;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Mech.Components;
|
||||
using Content.Shared.Mech.Equipment.Components;
|
||||
using Content.Shared.Whitelist;
|
||||
|
||||
namespace Content.Server.Mech.Systems;
|
||||
|
||||
@@ -14,6 +15,7 @@ public sealed class MechEquipmentSystem : EntitySystem
|
||||
[Dependency] private readonly MechSystem _mech = default!;
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
@@ -40,7 +42,7 @@ public sealed class MechEquipmentSystem : EntitySystem
|
||||
if (mechComp.EquipmentContainer.ContainedEntities.Count >= mechComp.MaxEquipmentAmount)
|
||||
return;
|
||||
|
||||
if (mechComp.EquipmentWhitelist != null && !mechComp.EquipmentWhitelist.IsValid(args.Used))
|
||||
if (_whitelistSystem.IsWhitelistFail(mechComp.EquipmentWhitelist, args.Used))
|
||||
return;
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("mech-equipment-begin-install", ("item", uid)), mech);
|
||||
|
||||
@@ -17,10 +17,12 @@ using Content.Shared.Tools.Components;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Shared.Wires;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Shared.Tools.Systems;
|
||||
using Robust.Server.Containers;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Player;
|
||||
using Content.Shared.Whitelist;
|
||||
|
||||
namespace Content.Server.Mech.Systems;
|
||||
|
||||
@@ -35,6 +37,8 @@ public sealed partial class MechSystem : SharedMechSystem
|
||||
[Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
@@ -87,7 +91,7 @@ public sealed partial class MechSystem : SharedMechSystem
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryComp<ToolComponent>(args.Used, out var tool) && tool.Qualities.Contains("Prying") && component.BatterySlot.ContainedEntity != null)
|
||||
if (_toolSystem.HasQuality(args.Used, "Prying") && component.BatterySlot.ContainedEntity != null)
|
||||
{
|
||||
var doAfterEventArgs = new DoAfterArgs(EntityManager, args.User, component.BatteryRemovalDelay,
|
||||
new RemoveBatteryEvent(), uid, target: uid, used: args.Target)
|
||||
@@ -222,7 +226,7 @@ public sealed partial class MechSystem : SharedMechSystem
|
||||
if (args.Cancelled || args.Handled)
|
||||
return;
|
||||
|
||||
if (component.PilotWhitelist != null && !component.PilotWhitelist.IsValid(args.User))
|
||||
if (_whitelistSystem.IsWhitelistFail(component.PilotWhitelist, args.User))
|
||||
{
|
||||
_popup.PopupEntity(Loc.GetString("mech-no-enter", ("item", uid)), args.User);
|
||||
return;
|
||||
|
||||
@@ -15,6 +15,7 @@ using Content.Shared.DoAfter;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Jittering;
|
||||
using Content.Shared.Medical;
|
||||
using Content.Shared.Mind;
|
||||
@@ -36,6 +37,7 @@ namespace Content.Server.Medical.BiomassReclaimer
|
||||
public sealed class BiomassReclaimerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly SharedJitteringSystem _jitteringSystem = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _sharedAudioSystem = default!;
|
||||
@@ -49,6 +51,7 @@ namespace Content.Server.Medical.BiomassReclaimer
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly MaterialStorageSystem _material = default!;
|
||||
[Dependency] private readonly SharedMindSystem _minds = default!;
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
|
||||
[ValidatePrototypeId<MaterialPrototype>]
|
||||
public const string BiomassPrototype = "Biomass";
|
||||
@@ -221,6 +224,12 @@ namespace Content.Server.Medical.BiomassReclaimer
|
||||
|
||||
component.ProcessingTimer = physics.FixturesMass * component.ProcessingTimePerUnitMass;
|
||||
|
||||
var inventory = _inventory.GetHandOrInventoryEntities(toProcess);
|
||||
foreach (var item in inventory)
|
||||
{
|
||||
_transform.DropNextTo(item, ent.Owner);
|
||||
}
|
||||
|
||||
QueueDel(toProcess);
|
||||
}
|
||||
|
||||
|
||||
5
Content.Server/Movement/Systems/WaddleAnimationSystem.cs
Normal file
5
Content.Server/Movement/Systems/WaddleAnimationSystem.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
using Content.Shared.Movement.Systems;
|
||||
|
||||
namespace Content.Server.Movement.Systems;
|
||||
|
||||
public sealed class WaddleAnimationSystem : SharedWaddleAnimationSystem;
|
||||
@@ -9,6 +9,7 @@ using Content.Shared.Stunnable;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Shared.Whitelist;
|
||||
|
||||
namespace Content.Server.Ninja.Systems;
|
||||
|
||||
@@ -24,6 +25,7 @@ public sealed class StunProviderSystem : SharedStunProviderSystem
|
||||
[Dependency] private readonly SharedNinjaGlovesSystem _gloves = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedStunSystem _stun = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -42,7 +44,7 @@ public sealed class StunProviderSystem : SharedStunProviderSystem
|
||||
if (args.Handled || comp.BatteryUid == null || !_gloves.AbilityCheck(uid, args, out var target))
|
||||
return;
|
||||
|
||||
if (target == uid || !comp.Whitelist.IsValid(target, EntityManager))
|
||||
if (target == uid || _whitelistSystem.IsWhitelistFail(comp.Whitelist, target))
|
||||
return;
|
||||
|
||||
if (_timing.CurTime < comp.NextStun)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Popups;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.IdentityManagement;
|
||||
@@ -9,6 +9,7 @@ using Content.Shared.Nutrition.AnimalHusbandry;
|
||||
using Content.Shared.Nutrition.Components;
|
||||
using Content.Shared.Nutrition.EntitySystems;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
@@ -33,6 +34,7 @@ public sealed class AnimalHusbandrySystem : EntitySystem
|
||||
[Dependency] private readonly PopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
|
||||
private readonly HashSet<EntityUid> _failedAttempts = new();
|
||||
private readonly HashSet<EntityUid> _birthQueue = new();
|
||||
@@ -174,7 +176,7 @@ public sealed class AnimalHusbandrySystem : EntitySystem
|
||||
if (!CanReproduce(partner))
|
||||
return false;
|
||||
|
||||
return component.PartnerWhitelist.IsValid(partner);
|
||||
return _whitelistSystem.IsWhitelistPass(component.PartnerWhitelist, partner);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -32,6 +32,7 @@ using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using Robust.Server.GameObjects;
|
||||
using Content.Shared.Whitelist;
|
||||
|
||||
namespace Content.Server.Nutrition.EntitySystems;
|
||||
|
||||
@@ -57,6 +58,7 @@ public sealed class FoodSystem : EntitySystem
|
||||
[Dependency] private readonly StackSystem _stack = default!;
|
||||
[Dependency] private readonly StomachSystem _stomach = default!;
|
||||
[Dependency] private readonly UtensilSystem _utensil = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
|
||||
public const float MaxFeedDistance = 1.0f;
|
||||
|
||||
@@ -408,7 +410,7 @@ public sealed class FoodSystem : EntitySystem
|
||||
if (comp.SpecialDigestible == null)
|
||||
continue;
|
||||
// Check if the food is in the whitelist
|
||||
if (comp.SpecialDigestible.IsValid(food, EntityManager))
|
||||
if (_whitelistSystem.IsWhitelistPass(comp.SpecialDigestible, food))
|
||||
return true;
|
||||
// They can only eat whitelist food and the food isn't in the whitelist. It's not edible.
|
||||
return false;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Shuttles.Systems;
|
||||
using Content.Shared.Cuffs.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Objectives.Components;
|
||||
using Content.Shared.Objectives.Systems;
|
||||
@@ -9,7 +10,6 @@ using Content.Shared.Random.Helpers;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using System.Linq;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using System.Text;
|
||||
using Robust.Server.Player;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server.Objectives.Components;
|
||||
using Content.Shared.Objectives.Components;
|
||||
using Content.Shared.Whitelist;
|
||||
|
||||
namespace Content.Server.Objectives.Systems;
|
||||
|
||||
@@ -8,6 +9,8 @@ namespace Content.Server.Objectives.Systems;
|
||||
/// </summary>
|
||||
public sealed class ObjectiveBlacklistRequirementSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -22,7 +25,7 @@ public sealed class ObjectiveBlacklistRequirementSystem : EntitySystem
|
||||
|
||||
foreach (var objective in args.Mind.AllObjectives)
|
||||
{
|
||||
if (comp.Blacklist.IsValid(objective, EntityManager))
|
||||
if (_whitelistSystem.IsBlacklistPass(comp.Blacklist, objective))
|
||||
{
|
||||
args.Cancelled = true;
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server.Objectives.Components;
|
||||
using Content.Shared.Objectives.Components;
|
||||
using Content.Shared.Whitelist;
|
||||
|
||||
namespace Content.Server.Objectives.Systems;
|
||||
|
||||
@@ -8,6 +9,7 @@ namespace Content.Server.Objectives.Systems;
|
||||
/// </summary>
|
||||
public sealed class RoleRequirementSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -22,7 +24,7 @@ public sealed class RoleRequirementSystem : EntitySystem
|
||||
|
||||
// this whitelist trick only works because roles are components on the mind and not entities
|
||||
// if that gets reworked then this will need changing
|
||||
if (!comp.Roles.IsValid(args.MindId, EntityManager))
|
||||
if (_whitelistSystem.IsWhitelistFail(comp.Roles, args.MindId))
|
||||
args.Cancelled = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,6 +237,16 @@ public sealed partial class NavMapSystem : SharedNavMapSystem
|
||||
component.Chunks.Clear();
|
||||
component.Beacons.Clear();
|
||||
|
||||
// Refresh beacons
|
||||
var query = EntityQueryEnumerator<NavMapBeaconComponent, TransformComponent>();
|
||||
while (query.MoveNext(out var qUid, out var qNavComp, out var qTransComp))
|
||||
{
|
||||
if (qTransComp.ParentUid != uid)
|
||||
continue;
|
||||
|
||||
UpdateNavMapBeaconData(qUid, qNavComp);
|
||||
}
|
||||
|
||||
// Loop over all tiles
|
||||
var tileRefs = _mapSystem.GetAllTiles(uid, mapGrid);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.PneumaticCannon;
|
||||
using Content.Shared.StatusEffect;
|
||||
using Content.Shared.Tools.Components;
|
||||
using Content.Shared.Tools.Systems;
|
||||
using Content.Shared.Weapons.Ranged.Components;
|
||||
using Content.Shared.Weapons.Ranged.Events;
|
||||
using Content.Shared.Weapons.Ranged.Systems;
|
||||
@@ -22,6 +22,7 @@ public sealed class PneumaticCannonSystem : SharedPneumaticCannonSystem
|
||||
[Dependency] private readonly GunSystem _gun = default!;
|
||||
[Dependency] private readonly StunSystem _stun = default!;
|
||||
[Dependency] private readonly ItemSlotsSystem _slots = default!;
|
||||
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -38,10 +39,7 @@ public sealed class PneumaticCannonSystem : SharedPneumaticCannonSystem
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (!TryComp<ToolComponent>(args.Used, out var tool))
|
||||
return;
|
||||
|
||||
if (!tool.Qualities.Contains(component.ToolModifyPower))
|
||||
if (!_toolSystem.HasQuality(args.Used, component.ToolModifyPower))
|
||||
return;
|
||||
|
||||
var val = (int) component.Power;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Server.Polymorph.Components;
|
||||
using Content.Shared.Polymorph;
|
||||
using Content.Shared.Projectiles;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Physics.Events;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -9,6 +10,8 @@ namespace Content.Server.Polymorph.Systems;
|
||||
|
||||
public partial class PolymorphSystem
|
||||
{
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Need to do this so we don't get a collection enumeration error in physics by polymorphing
|
||||
/// an entity we're colliding with
|
||||
@@ -39,8 +42,8 @@ public partial class PolymorphSystem
|
||||
return;
|
||||
|
||||
var other = args.OtherEntity;
|
||||
if (!component.Whitelist.IsValid(other, EntityManager)
|
||||
|| component.Blacklist != null && component.Blacklist.IsValid(other, EntityManager))
|
||||
if (_whitelistSystem.IsWhitelistFail(component.Whitelist, other) ||
|
||||
_whitelistSystem.IsBlacklistPass(component.Blacklist, other))
|
||||
return;
|
||||
|
||||
_queuedPolymorphUpdates.Enqueue(new (other, component.Sound, component.Polymorph));
|
||||
|
||||
@@ -6,6 +6,7 @@ using Content.Server.Power.Nodes;
|
||||
using Content.Server.Power.NodeGroups;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Pinpointer;
|
||||
using Content.Shared.Power;
|
||||
using JetBrains.Annotations;
|
||||
@@ -13,7 +14,6 @@ using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using Content.Server.GameTicking.Components;
|
||||
|
||||
namespace Content.Server.Power.EntitySystems;
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@ using Content.Server.NodeContainer.EntitySystems;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Power.NodeGroups;
|
||||
using Content.Server.Power.Pow3r;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Power;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Threading;
|
||||
|
||||
namespace Content.Server.Power.EntitySystems
|
||||
@@ -18,6 +20,7 @@ namespace Content.Server.Power.EntitySystems
|
||||
{
|
||||
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly PowerNetConnectorSystem _powerNetConnector = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly IParallelManager _parMan = default!;
|
||||
[Dependency] private readonly PowerReceiverSystem _powerReceiver = default!;
|
||||
|
||||
@@ -25,13 +28,14 @@ namespace Content.Server.Power.EntitySystems
|
||||
private readonly HashSet<PowerNet> _powerNetReconnectQueue = new();
|
||||
private readonly HashSet<ApcNet> _apcNetReconnectQueue = new();
|
||||
|
||||
private readonly BatteryRampPegSolver _solver = new();
|
||||
private BatteryRampPegSolver _solver = new();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
UpdatesAfter.Add(typeof(NodeGroupSystem));
|
||||
_solver = new(_cfg.GetCVar(CCVars.DebugPow3rDisableParallel));
|
||||
|
||||
SubscribeLocalEvent<ApcPowerReceiverComponent, ComponentInit>(ApcPowerReceiverInit);
|
||||
SubscribeLocalEvent<ApcPowerReceiverComponent, ComponentShutdown>(ApcPowerReceiverShutdown);
|
||||
@@ -53,6 +57,13 @@ namespace Content.Server.Power.EntitySystems
|
||||
SubscribeLocalEvent<PowerSupplierComponent, ComponentShutdown>(PowerSupplierShutdown);
|
||||
SubscribeLocalEvent<PowerSupplierComponent, EntityPausedEvent>(PowerSupplierPaused);
|
||||
SubscribeLocalEvent<PowerSupplierComponent, EntityUnpausedEvent>(PowerSupplierUnpaused);
|
||||
|
||||
Subs.CVar(_cfg, CCVars.DebugPow3rDisableParallel, DebugPow3rDisableParallelChanged);
|
||||
}
|
||||
|
||||
private void DebugPow3rDisableParallelChanged(bool val)
|
||||
{
|
||||
_solver = new(val);
|
||||
}
|
||||
|
||||
private void ApcPowerReceiverInit(EntityUid uid, ApcPowerReceiverComponent component, ComponentInit args)
|
||||
|
||||
@@ -9,9 +9,11 @@ namespace Content.Server.Power.Pow3r
|
||||
public sealed class BatteryRampPegSolver : IPowerSolver
|
||||
{
|
||||
private UpdateNetworkJob _networkJob;
|
||||
private bool _disableParallel;
|
||||
|
||||
public BatteryRampPegSolver()
|
||||
public BatteryRampPegSolver(bool disableParallel = false)
|
||||
{
|
||||
_disableParallel = disableParallel;
|
||||
_networkJob = new()
|
||||
{
|
||||
Solver = this,
|
||||
@@ -56,7 +58,10 @@ namespace Content.Server.Power.Pow3r
|
||||
// suppliers + discharger) Then decide based on total layer size whether its worth parallelizing that
|
||||
// layer?
|
||||
_networkJob.Networks = group;
|
||||
parallel.ProcessNow(_networkJob, group.Count);
|
||||
if (_disableParallel)
|
||||
parallel.ProcessSerialNow(_networkJob, group.Count);
|
||||
else
|
||||
parallel.ProcessNow(_networkJob, group.Count);
|
||||
}
|
||||
|
||||
ClearBatteries(state);
|
||||
|
||||
@@ -54,7 +54,7 @@ public sealed class PrayerSystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
_quickDialog.OpenDialog(actor.PlayerSession, Loc.GetString(comp.Verb), "Message", (string message) =>
|
||||
_quickDialog.OpenDialog(actor.PlayerSession, Loc.GetString(comp.Verb), Loc.GetString("prayer-popup-notify-pray-ui-message"), (string message) =>
|
||||
{
|
||||
Pray(actor.PlayerSession, comp, message);
|
||||
});
|
||||
|
||||
5
Content.Server/Revolutionary/RevolutionarySystem.cs
Normal file
5
Content.Server/Revolutionary/RevolutionarySystem.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
using Content.Shared.Revolutionary;
|
||||
|
||||
namespace Content.Server.Revolutionary;
|
||||
|
||||
public sealed class RevolutionarySystem : SharedRevolutionarySystem;
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Numerics;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Spawners.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
|
||||
@@ -5,9 +5,12 @@ namespace Content.Server.Speech.EntitySystems;
|
||||
|
||||
public sealed class SouthernAccentSystem : EntitySystem
|
||||
{
|
||||
private static readonly Regex RegexIng = new(@"ing\b");
|
||||
private static readonly Regex RegexAnd = new(@"\band\b");
|
||||
private static readonly Regex RegexDve = new("d've");
|
||||
private static readonly Regex RegexLowerIng = new(@"ing\b");
|
||||
private static readonly Regex RegexUpperIng = new(@"ING\b");
|
||||
private static readonly Regex RegexLowerAnd = new(@"\band\b");
|
||||
private static readonly Regex RegexUpperAnd = new(@"\bAND\b");
|
||||
private static readonly Regex RegexLowerDve = new(@"d've\b");
|
||||
private static readonly Regex RegexUpperDve = new(@"D'VE\b");
|
||||
|
||||
[Dependency] private readonly ReplacementAccentSystem _replacement = default!;
|
||||
|
||||
@@ -24,9 +27,12 @@ public sealed class SouthernAccentSystem : EntitySystem
|
||||
message = _replacement.ApplyReplacements(message, "southern");
|
||||
|
||||
//They shoulda started runnin' an' hidin' from me!
|
||||
message = RegexIng.Replace(message, "in'");
|
||||
message = RegexAnd.Replace(message, "an'");
|
||||
message = RegexDve.Replace(message, "da");
|
||||
message = RegexLowerIng.Replace(message, "in'");
|
||||
message = RegexUpperIng.Replace(message, "IN'");
|
||||
message = RegexLowerAnd.Replace(message, "an'");
|
||||
message = RegexUpperAnd.Replace(message, "AN'");
|
||||
message = RegexLowerDve.Replace(message, "da");
|
||||
message = RegexUpperDve.Replace(message, "DA");
|
||||
args.Message = message;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -179,13 +179,6 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem
|
||||
profile = HumanoidCharacterProfile.RandomWithSpecies(speciesId);
|
||||
}
|
||||
|
||||
if (prototype?.StartingGear != null)
|
||||
{
|
||||
var startingGear = _prototypeManager.Index<StartingGearPrototype>(prototype.StartingGear);
|
||||
EquipStartingGear(entity.Value, startingGear, raiseEvent: false);
|
||||
}
|
||||
|
||||
// Run loadouts after so stuff like storage loadouts can get
|
||||
var jobLoadout = LoadoutSystem.GetJobPrototype(prototype?.ID);
|
||||
|
||||
if (_prototypeManager.TryIndex(jobLoadout, out RoleLoadoutPrototype? roleProto))
|
||||
@@ -203,6 +196,12 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem
|
||||
EquipRoleLoadout(entity.Value, loadout, roleProto);
|
||||
}
|
||||
|
||||
if (prototype?.StartingGear != null)
|
||||
{
|
||||
var startingGear = _prototypeManager.Index<StartingGearPrototype>(prototype.StartingGear);
|
||||
EquipStartingGear(entity.Value, startingGear, raiseEvent: false);
|
||||
}
|
||||
|
||||
var gearEquippedEv = new StartingGearEquippedEvent(entity.Value);
|
||||
RaiseLocalEvent(entity.Value, ref gearEquippedEv);
|
||||
|
||||
@@ -257,10 +256,8 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem
|
||||
_cardSystem.TryChangeFullName(cardId, characterName, card);
|
||||
_cardSystem.TryChangeJobTitle(cardId, jobPrototype.LocalizedName, card);
|
||||
|
||||
if (_prototypeManager.TryIndex<StatusIconPrototype>(jobPrototype.Icon, out var jobIcon))
|
||||
{
|
||||
if (_prototypeManager.TryIndex(jobPrototype.Icon, out var jobIcon))
|
||||
_cardSystem.TryChangeJobIcon(cardId, jobIcon, card);
|
||||
}
|
||||
|
||||
var extendedAccess = false;
|
||||
if (station != null)
|
||||
@@ -311,4 +308,4 @@ public sealed class PlayerSpawningEvent : EntityEventArgs
|
||||
HumanoidCharacterProfile = humanoidCharacterProfile;
|
||||
Station = station;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Administration;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Toolshed;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Server.AlertLevel;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
@@ -20,4 +20,4 @@ public sealed class AlertLevelInterceptionRule : StationEventSystem<AlertLevelIn
|
||||
|
||||
_alertLevelSystem.SetLevel(chosenStation.Value, component.AlertLevel, true, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Content.Server.Anomaly;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Resist;
|
||||
using Content.Server.Station.Components;
|
||||
@@ -6,6 +5,7 @@ using Content.Server.StationEvents.Components;
|
||||
using Content.Server.Storage.Components;
|
||||
using Content.Server.Storage.EntitySystems;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Coordinates;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Linq;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ using System.Linq;
|
||||
using Content.Server.Cargo.Components;
|
||||
using Content.Server.Cargo.Systems;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Server.StationRecords;
|
||||
using Content.Server.StationRecords.Systems;
|
||||
using Content.Shared.StationRecords;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Linq;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Numerics;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.ImmovableRod;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Server.Weapons.Ranged.Systems;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using System.Linq;
|
||||
using Content.Server.Silicons.Laws;
|
||||
using Content.Server.Station.Components;
|
||||
@@ -7,6 +6,7 @@ using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Dataset;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Random;
|
||||
using Content.Shared.Random.Helpers;
|
||||
using Content.Shared.Silicons.Laws;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Server.Traits.Assorted;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Mind.Components;
|
||||
using Content.Shared.Traits.Assorted;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Numerics;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics.Components;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Ninja.Systems;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using System.Threading;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Server.Power.EntitySystems;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Server.Storage.Components;
|
||||
using Content.Server.Storage.EntitySystems;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Linq;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Ghost.Roles.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Radio;
|
||||
using Robust.Shared.Random;
|
||||
@@ -8,6 +7,7 @@ using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.Radio.Components;
|
||||
using Content.Shared.Doors.Components;
|
||||
using Content.Shared.Doors.Systems;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.Station.Systems;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -98,19 +98,14 @@ public abstract class StationEventSystem<T> : GameRuleSystem<T> where T : ICompo
|
||||
if (!GameTicker.IsGameRuleAdded(uid, ruleData))
|
||||
continue;
|
||||
|
||||
if (stationEvent.EndTime != null && Timing.CurTime >= stationEvent.EndTime && GameTicker.IsGameRuleActive(uid, ruleData))
|
||||
if (!GameTicker.IsGameRuleActive(uid, ruleData) && !HasComp<DelayedStartRuleComponent>(uid))
|
||||
{
|
||||
GameTicker.StartGameRule(uid, ruleData);
|
||||
}
|
||||
else if (stationEvent.EndTime != null && Timing.CurTime >= stationEvent.EndTime && GameTicker.IsGameRuleActive(uid, ruleData))
|
||||
{
|
||||
GameTicker.EndGameRule(uid, ruleData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Helper Functions
|
||||
|
||||
protected void ForceEndSelf(EntityUid uid, GameRuleComponent? component = null)
|
||||
{
|
||||
GameTicker.EndGameRule(uid, component);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ using JetBrains.Annotations;
|
||||
using Robust.Shared.Random;
|
||||
using System.Linq;
|
||||
using Content.Server.Fluids.EntitySystems;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
|
||||
namespace Content.Server.StationEvents.Events;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.Station.Components;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Content.Shared.Storage;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.GameTicking.Components;
|
||||
using Content.Server.GameTicking.Rules;
|
||||
using Content.Server.GameTicking.Rules.Components;
|
||||
using Content.Server.StationEvents.Components;
|
||||
using Content.Server.StationEvents.Events;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.GameTicking.Components;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ using Content.Shared.Interaction;
|
||||
using Content.Shared.Sticky;
|
||||
using Content.Shared.Sticky.Components;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -20,6 +21,7 @@ public sealed class StickySystem : EntitySystem
|
||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
||||
|
||||
private const string StickerSlotId = "stickers_container";
|
||||
|
||||
@@ -67,9 +69,8 @@ public sealed class StickySystem : EntitySystem
|
||||
return false;
|
||||
|
||||
// check whitelist and blacklist
|
||||
if (component.Whitelist != null && !component.Whitelist.IsValid(target))
|
||||
return false;
|
||||
if (component.Blacklist != null && component.Blacklist.IsValid(target))
|
||||
if (_whitelistSystem.IsWhitelistFail(component.Whitelist, target) ||
|
||||
_whitelistSystem.IsBlacklistPass(component.Blacklist, target))
|
||||
return false;
|
||||
|
||||
var attemptEv = new AttemptEntityStickEvent(target, user);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user