mirror of
https://github.com/DeltaV-Station/Delta-v.git
synced 2026-09-29 23:57:29 +00:00
* Fix the sensor monitoring console forcing a GC every 3 seconds (#38146) * Optimize sensor monitoring window graph drawing * Add shared static Vector2 pool for all GraphView instances * Address requested changes * remove lock * Update submodule to 264.0.0 (#38629) * Toy/Plushie Inhands and Wearables (#38514) * Fixed dependency injection and some other issues in a few places. * More issue fixes * patchfor broken NetworkConfiguratorLinkMenu (#38632) fix * Fix solutions flickering when transferring contents (#34838) * Use Solution clones when applying SolutionComponent states * Revert "Use Solution clones when applying SolutionComponent states" This reverts commit 013fd111cf92b22562e00f98a7aaa49bc4b4ed62. * Make Solution implement ICloneable and rename Clone method. * Copy CanReact value when cloning a Solution * Convert to IRobustCloneable * Fix typos in guidebook: Buisness → Business (#38636) * Fix typo in `MinorAntagonists.xml` Buisness → Business * Fix typo in `YourFirstCharacter.xml` Buisness → Business * Various Headphones Fixes and Tweaks (#38479) * sprites, wearables * neck * icon-on sprite * Cleanup prototype instantiation in `DamageTest` (#38639) Cleanup prototype instantiation in DamageTest * Cleanup prototype instantiation in `ExplosionSystem` (#38642) Cleanup prototype instantiation in ExplosionSystem * AddBodyPartCommand localization. (#38612) commit * fix ItemSlotsSystem debug assert (#38655) * Allow the Command & Super door remotes to use the access of their user. (Re-creation of PR due to changes to game balance) (#35536) * Added directional beacons (#38284) * Added directional beacons Signed-off-by: Nox38 <nebulousnox38@gmail.com> * Fixed names Signed-off-by: Nox38 <nebulousnox38@gmail.com> --------- Signed-off-by: Nox38 <nebulousnox38@gmail.com> * Power stat and nuke codes commands get some LEC love. (#38585) * commit * requested changes. * Dsay Dirty and Follow commands converted to LEC and localized. (#38666) * commit * whoopwhoopwhoop * Retro laser sprite fix (#38676) * Fixed everything except the icon Signed-off-by: Nox38 <nebulousnox38@gmail.com> * fixed icon Signed-off-by: Nox38 <nebulousnox38@gmail.com> --------- Signed-off-by: Nox38 <nebulousnox38@gmail.com> * fix water coolers (#38681) * Monochromacy typo fix (#38686) * fixes the typo * Fixed cloning looking for the trait, not the component, RE https://github.com/space-wizards/space-station-14/pull/38686#issuecomment-3025093504 * Apply suggestions from code review --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Validate `CloningSettingsPrototype`s (#38688) * Validate CloningSettingsPrototypes * Update Content.IntegrationTests/Tests/Cloning/CloningSettingsPrototypeTest.cs Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Check EventComponents too --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Add test of objective-related console commands (#36400) * Add test of objective add/list/remove commands * Not sure why we're validating test prototypes, but sure * We don't need a map * Improvements and fixups for New Status Effect API (#38660) * Predict healing and bloodstream (#38690) * initial commit * reapply 38126 * fix rootable * someone missed an important minus sign here * try this * fix * fix * reenable crit hits * cleanup * fix status time dirtying * fix * camelCase * Healing and bloodstream prediction fixes. * Resolving Wizard casting recall on nuke disk making it impossible to disarm (#38661) * Resolving Wizard Recall on Nuke disk making it impossible to disarm - Adding a DisarmBomb case to nuke status update loop - Changing a few methods and parameters to properly follow formatting standards - Updating some names to follow camelCase * Updating missed tag * Reverting DataField change Should prevent this preventative bugfix being a breaking change. * Switch HSV to the default colorspace for character customization (#38434) * Made HSV default for character editor * Adds/fixes comments to HSV defaulting * Added dropbox fix, potentially cursed * Revert "Added dropbox fix, potentially cursed" This reverts commit a709883366fbee813e839742125e70844672af29. --------- Co-authored-by: TrixxedHeart <46364955+TrixxedBit@users.noreply.github.com> * Fix: Don't deploy foldables when clicking on items inside containers (#38709) * Fix * Apply suggestions from code review --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Pressure Relief Valve (#36708) * initial system (this math is probably WRONG) * General code cleanup and OnExamined support (holy moly this code sucks) * UICode and related events foundation TODO: - Actually write the XAML UI and the underlying system - Un-shitcode the entire thing - Actually test everything... * Working UI code TODO: Make predicted, as this certainly isn't predicted. Even though I said it was. It isn't. * Remove one TODO for unshitcoding the examine code * Add reminder yea * Make predicted (defenitely isn't) (also defenitely isn't a copypaste from pressure pump code) * It's predicted! TODO: - Give it snazzy predicted visuals! - Have a different field for pressure entry, lest it gets bulldozed every UI update. * Improve gas pressure relief valve UI TODO: Reminder to reduce amount of dirties using deltafields * Implement DirtyField prediction * Entity<T> cleanup A lot of Entity<T> conversions and lukewarm cleanup. Also got caught copy pasting code in 4K UHD but it's not like you couldn't tell. * More cleanup and comments * Remove TODO comment on bulldozing window title * """refactoring""" - Move appearance out of shared and finally fix it. Pointless to predict appearance in this instance. - More Entity<T> conversions because I like them. - Move UI creation handling over entirely to the ActivatableUI system. - Fix a hardcoded locale string (why????). * Add visuals * Revert debugging variable replacememt yea * Revert skissue * Remove unused using directives and remove TODO * Localize, cleanup, document * Fix adminlogging discrepancy * Add ability to construct, add guidebook entry * Clear up comment * Add guidebook tooltip to valve * Convert GasPressureReliefValveBoundUserInterface declaration into primary constructor * Adds more input handling and adds autofill on open * Un-deepfry input validator shitcode Genuinely what was I smoking * improve visuals logic * Refactor again - Update math to the correct implementation - Moved code that could be re-used in the future into a helper method under AtmosphereSystem.Gases.cs * I'm sorry but I hate warnings * Remove unused using directive in AtmosphereSystem.Gases.cs * Review and cleanup * Lukewarm UI glossup * Maintainer for the upstream project btw * Remove redundant state sets and messy logic * Unduplicate valve updater code * Redo UI (im sorry Slarti) * run tests * Test refactored UI messaging * Second round of UI improvements - God please find a way to improve this system. Feels bad. * Update loop implementation * Further predict UI * Clear up SetToCurrentThreshold * cleanup * Update to master + pipe layers and bug fixes want to run tests * fixes * Deploy rename pipebomb * Documentation and requested changes * Rename the method that wiggled away * Undo rounding changes * Fix comment * Rename and cleanup * Apply suggestions from code review --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Fix TextLinkTag (#32203) * Adjust uplink buy button to be under item icon (#38596) * Adjusted uplink buy button to be under item icon * Put the discount subtext under the icon * Indent fixes, added margin --------- Co-authored-by: TrixxedHeart <46364955+TrixxedBit@users.noreply.github.com> * Scurrets - Audio Improvements (#38482) * Scurret audio tuning * Add new sfx * Update sneezing sfx * YAML support * Rename a folder * make telesci wreck easier (#37569) rel * Validate `ShaderPrototype` IDs (#38728) * Convert all shader prototype string literals to protoids in overlays * Convert more shader prototype literal strings to protoids * Convert ValidatePrototypeId to ProtoId * Later * [BUGFIX] Fixed revenant malfunction ability not working properly only MediBots and Stasis bed (#38664) * fixed * clean up * orks fix smart * review fix 1 * more requested changes * less cursed * more descriptive description * better wording * Tiny Tiny Cleanup of the EyeClosingSystem. (#38734) Update EyeClosingSystem.cs * Fix human skin tone distribution (#38701) * fix: Use PredictedQueueDel for gib spell (#38729) * fix: don't default to uncharged sprite state for cells (#38730) * Fix Hristov description - remove inaccurate technical specs (#38746) - Removes inaccurate 'armor piercing 14.5mm shells' reference - Replaces it with a more funny description, matching the style of the other snipers and guns - Keeps ammunition type '.60 anti-materiel ammo' specification - Fixes issue #38590 Co-authored-by: Arthur Fiorese de Andrade <aandrade@cmcxs.gov.br> * feat: allow mopping evaporating puddles (#38743) * Validate remaining `ProtoId` strings (#38747) Validate remaining ProtoId strings * Validate `ProtoId`s in tests (#38745) * Convert string literals to protoids in Content.Tests * Convert string literals to protoids or consts in Content.IntegrationTests * Fix linter failures Tricksy static using misled me * Cleanup warning in StomachSystem (#38748) you did not see this * Vox scars (#38592) * Added vox scars n'stuff, renamed vox_tattoos.ftl to just vox.ftl * Revert "Added vox scars n'stuff, renamed vox_tattoos.ftl to just vox.ftl" This reverts commit c73da55ba3b39ddf93b493aecd85604c54dd8a15. * locale key fix * Changed top surgery scar names to be more generalized * Adjusted face scars * Formatting fixes --------- Co-authored-by: TrixxedHeart <46364955+TrixxedBit@users.noreply.github.com> * UnlockNode command to LEC. (#38751) * commit * Update UnlockNodeCommand.cs * commit * move command locale to its own file. * Update Content.Server/Xenoarchaeology/Artifact/UnlockNodeCommand.cs --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Typofixes for figurine dialogue (#38737) * Typofixes for figurine dialogue * Forgot two * Janitor Tool: Wire Brush (#38667) * Wow! It's -brush- * spacing. * Update Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * fixed changes --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Minor escape menu UX improvements (#38650) * fix: spellbooks can have infinite charges (#38376) * fix: spellbooks can have infinite charges * refactor: indicate infinite spellbook charges with null Not sure if I like this much better...
360 lines
12 KiB
C#
360 lines
12 KiB
C#
using System.Collections.Frozen;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using Robust.Shared.Player;
|
|
using Robust.Shared.Prototypes;
|
|
using Robust.Shared.Timing;
|
|
|
|
namespace Content.Shared.Alert;
|
|
|
|
public abstract class AlertsSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly IGameTiming _timing = default!;
|
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
|
|
|
private FrozenDictionary<ProtoId<AlertPrototype>, AlertPrototype> _typeToAlert = default!;
|
|
|
|
public IReadOnlyDictionary<AlertKey, AlertState>? GetActiveAlerts(EntityUid euid)
|
|
{
|
|
return TryComp(euid, out AlertsComponent? comp)
|
|
? comp.Alerts
|
|
: null;
|
|
}
|
|
|
|
public short GetSeverityRange(ProtoId<AlertPrototype> alertType)
|
|
{
|
|
var minSeverity = _typeToAlert[alertType].MinSeverity;
|
|
return (short)MathF.Max(minSeverity,_typeToAlert[alertType].MaxSeverity - minSeverity);
|
|
}
|
|
|
|
public short GetMaxSeverity(ProtoId<AlertPrototype> alertType)
|
|
{
|
|
return _typeToAlert[alertType].MaxSeverity;
|
|
}
|
|
|
|
public short GetMinSeverity(ProtoId<AlertPrototype> alertType)
|
|
{
|
|
return _typeToAlert[alertType].MinSeverity;
|
|
}
|
|
|
|
public bool IsShowingAlert(EntityUid euid, ProtoId<AlertPrototype> alertType)
|
|
{
|
|
if (!TryComp(euid, out AlertsComponent? alertsComponent))
|
|
return false;
|
|
|
|
if (TryGet(alertType, out var alert))
|
|
{
|
|
return alertsComponent.Alerts.ContainsKey(alert.AlertKey);
|
|
}
|
|
|
|
Log.Debug("Unknown alert type {0}", alertType);
|
|
return false;
|
|
}
|
|
|
|
/// <returns>true iff an alert of the indicated alert category is currently showing</returns>
|
|
public bool IsShowingAlertCategory(EntityUid euid, ProtoId<AlertCategoryPrototype> alertCategory)
|
|
{
|
|
return TryComp(euid, out AlertsComponent? alertsComponent)
|
|
&& alertsComponent.Alerts.ContainsKey(AlertKey.ForCategory(alertCategory));
|
|
}
|
|
|
|
public bool TryGetAlertState(EntityUid euid, AlertKey key, out AlertState alertState)
|
|
{
|
|
if (TryComp(euid, out AlertsComponent? alertsComponent))
|
|
return alertsComponent.Alerts.TryGetValue(key, out alertState);
|
|
|
|
alertState = default;
|
|
return false;
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Shows the alert. If the alert or another alert of the same category is already showing,
|
|
/// it will be updated / replaced with the specified values.
|
|
/// </summary>
|
|
/// <param name="euid"></param>
|
|
/// <param name="alertType">type of the alert to set</param>
|
|
/// <param name="severity">severity, if supported by the alert</param>
|
|
/// <param name="cooldown">cooldown start and end, if null there will be no cooldown (and it will
|
|
/// be erased if there is currently a cooldown for the alert)</param>
|
|
/// <param name="autoRemove">if true, the alert will be removed at the end of the cooldown</param>
|
|
/// <param name="showCooldown">if true, the cooldown will be visibly shown over the alert icon</param>
|
|
public void ShowAlert(EntityUid euid, ProtoId<AlertPrototype> alertType, short? severity = null, (TimeSpan, TimeSpan)? cooldown = null, bool autoRemove = false, bool showCooldown = true )
|
|
{
|
|
// This should be handled as part of networking.
|
|
if (_timing.ApplyingState)
|
|
return;
|
|
|
|
if (!TryComp(euid, out AlertsComponent? alertsComponent))
|
|
return;
|
|
|
|
if (TryGet(alertType, out var alert))
|
|
{
|
|
// Check whether the alert category we want to show is already being displayed, with the same type,
|
|
// severity, and cooldown.
|
|
if (alertsComponent.Alerts.TryGetValue(alert.AlertKey, out var alertStateCallback) &&
|
|
alertStateCallback.Type == alertType &&
|
|
alertStateCallback.Severity == severity &&
|
|
alertStateCallback.Cooldown == cooldown &&
|
|
alertStateCallback.AutoRemove == autoRemove &&
|
|
alertStateCallback.ShowCooldown == showCooldown)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// In the case we're changing the alert type but not the category, we need to remove it first.
|
|
alertsComponent.Alerts.Remove(alert.AlertKey);
|
|
|
|
var state = new AlertState
|
|
{ Cooldown = cooldown, Severity = severity, Type = alertType, AutoRemove = autoRemove, ShowCooldown = showCooldown};
|
|
alertsComponent.Alerts[alert.AlertKey] = state;
|
|
|
|
// Keeping a list of AutoRemove alerts, so Update() doesn't need to check every alert
|
|
if (autoRemove)
|
|
{
|
|
var autoComp = EnsureComp<AlertAutoRemoveComponent>(euid);
|
|
if (!autoComp.AlertKeys.Contains(alert.AlertKey))
|
|
autoComp.AlertKeys.Add(alert.AlertKey);
|
|
}
|
|
|
|
AfterShowAlert((euid, alertsComponent));
|
|
|
|
Dirty(euid, alertsComponent);
|
|
}
|
|
else
|
|
{
|
|
Log.Error("Unable to show alert {0}, please ensure this alertType has" +
|
|
" a corresponding YML alert prototype",
|
|
alertType);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clear the alert with the given category, if one is currently showing.
|
|
/// </summary>
|
|
public void ClearAlertCategory(EntityUid euid, ProtoId<AlertCategoryPrototype> category)
|
|
{
|
|
if(!TryComp(euid, out AlertsComponent? alertsComponent))
|
|
return;
|
|
|
|
var key = AlertKey.ForCategory(category);
|
|
if (!alertsComponent.Alerts.Remove(key))
|
|
{
|
|
return;
|
|
}
|
|
|
|
AfterClearAlert((euid, alertsComponent));
|
|
|
|
Dirty(euid, alertsComponent);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clear the alert of the given type if it is currently showing.
|
|
/// </summary>
|
|
public void ClearAlert(EntityUid euid, ProtoId<AlertPrototype> alertType)
|
|
{
|
|
if (_timing.ApplyingState)
|
|
return;
|
|
|
|
if (!TryComp(euid, out AlertsComponent? alertsComponent))
|
|
return;
|
|
|
|
if (TryGet(alertType, out var alert))
|
|
{
|
|
if (!alertsComponent.Alerts.Remove(alert.AlertKey))
|
|
{
|
|
return;
|
|
}
|
|
|
|
AfterClearAlert((euid, alertsComponent));
|
|
|
|
Dirty(euid, alertsComponent);
|
|
}
|
|
else
|
|
{
|
|
Log.Error("Unable to clear alert, unknown alertType {0}", alertType);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invoked after showing an alert prior to dirtying the component
|
|
/// </summary>
|
|
protected virtual void AfterShowAlert(Entity<AlertsComponent> alerts) { }
|
|
|
|
/// <summary>
|
|
/// Invoked after clearing an alert prior to dirtying the component
|
|
/// </summary>
|
|
protected virtual void AfterClearAlert(Entity<AlertsComponent> alerts) { }
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<AlertsComponent, ComponentStartup>(HandleComponentStartup);
|
|
SubscribeLocalEvent<AlertsComponent, ComponentShutdown>(HandleComponentShutdown);
|
|
SubscribeLocalEvent<AlertsComponent, PlayerAttachedEvent>(OnPlayerAttached);
|
|
|
|
SubscribeLocalEvent<AlertAutoRemoveComponent, EntityUnpausedEvent>(OnAutoRemoveUnPaused);
|
|
|
|
SubscribeAllEvent<ClickAlertEvent>(HandleClickAlert);
|
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(HandlePrototypesReloaded);
|
|
LoadPrototypes();
|
|
}
|
|
|
|
private void OnAutoRemoveUnPaused(EntityUid uid, AlertAutoRemoveComponent comp, EntityUnpausedEvent args)
|
|
{
|
|
if (!TryComp<AlertsComponent>(uid, out var alertComp))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var dirty = false;
|
|
|
|
foreach (var alert in alertComp.Alerts)
|
|
{
|
|
if (alert.Value.Cooldown is null)
|
|
continue;
|
|
|
|
var cooldown = (alert.Value.Cooldown.Value.Item1, alert.Value.Cooldown.Value.Item2 + args.PausedTime);
|
|
|
|
var state = new AlertState
|
|
{
|
|
Severity = alert.Value.Severity,
|
|
Cooldown = cooldown,
|
|
ShowCooldown = alert.Value.ShowCooldown,
|
|
AutoRemove = alert.Value.AutoRemove,
|
|
Type = alert.Value.Type
|
|
};
|
|
alertComp.Alerts[alert.Key] = state;
|
|
dirty = true;
|
|
}
|
|
|
|
if (dirty)
|
|
Dirty(uid, comp);
|
|
}
|
|
|
|
public override void Update(float frameTime)
|
|
{
|
|
base.Update(frameTime);
|
|
|
|
var query = EntityQueryEnumerator<AlertAutoRemoveComponent>();
|
|
while (query.MoveNext(out var uid, out var autoComp))
|
|
{
|
|
var dirtyComp = false;
|
|
if (autoComp.AlertKeys.Count <= 0 || !TryComp<AlertsComponent>(uid, out var alertComp))
|
|
{
|
|
RemCompDeferred(uid, autoComp);
|
|
continue;
|
|
}
|
|
|
|
var removeList = new List<AlertKey>();
|
|
foreach (var alertKey in autoComp.AlertKeys)
|
|
{
|
|
alertComp.Alerts.TryGetValue(alertKey, out var alertState);
|
|
|
|
if (alertState.Cooldown is null || alertState.Cooldown.Value.Item2 >= _timing.CurTime)
|
|
continue;
|
|
removeList.Add(alertKey);
|
|
alertComp.Alerts.Remove(alertKey);
|
|
dirtyComp = true;
|
|
}
|
|
|
|
foreach (var alertKey in removeList)
|
|
{
|
|
autoComp.AlertKeys.Remove(alertKey);
|
|
}
|
|
|
|
if (dirtyComp)
|
|
Dirty(uid, alertComp);
|
|
}
|
|
}
|
|
|
|
protected virtual void HandleComponentShutdown(EntityUid uid, AlertsComponent component, ComponentShutdown args)
|
|
{
|
|
RaiseLocalEvent(uid, new AlertSyncEvent(uid), true);
|
|
}
|
|
|
|
private void HandleComponentStartup(EntityUid uid, AlertsComponent component, ComponentStartup args)
|
|
{
|
|
RaiseLocalEvent(uid, new AlertSyncEvent(uid), true);
|
|
}
|
|
|
|
private void HandlePrototypesReloaded(PrototypesReloadedEventArgs obj)
|
|
{
|
|
if (obj.WasModified<AlertPrototype>())
|
|
LoadPrototypes();
|
|
}
|
|
|
|
protected virtual void LoadPrototypes()
|
|
{
|
|
var dict = new Dictionary<ProtoId<AlertPrototype>, AlertPrototype>();
|
|
foreach (var alert in _prototypeManager.EnumeratePrototypes<AlertPrototype>())
|
|
{
|
|
if (!dict.TryAdd(alert.ID, alert))
|
|
{
|
|
Log.Error("Found alert with duplicate alertType {0} - all alerts must have" +
|
|
" a unique alertType, this one will be skipped", alert.ID);
|
|
}
|
|
}
|
|
|
|
_typeToAlert = dict.ToFrozenDictionary();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to get the alert of the indicated type
|
|
/// </summary>
|
|
/// <returns>true if found</returns>
|
|
public bool TryGet(ProtoId<AlertPrototype> alertType, [NotNullWhen(true)] out AlertPrototype? alert)
|
|
{
|
|
return _typeToAlert.TryGetValue(alertType, out alert);
|
|
}
|
|
|
|
private void HandleClickAlert(ClickAlertEvent msg, EntitySessionEventArgs args)
|
|
{
|
|
var player = args.SenderSession.AttachedEntity;
|
|
if (player is null || !HasComp<AlertsComponent>(player))
|
|
return;
|
|
|
|
if (!IsShowingAlert(player.Value, msg.Type))
|
|
{
|
|
Log.Debug("User {0} attempted to" +
|
|
" click alert {1} which is not currently showing for them",
|
|
Comp<MetaDataComponent>(player.Value).EntityName, msg.Type);
|
|
return;
|
|
}
|
|
|
|
if (!TryGet(msg.Type, out var alert))
|
|
{
|
|
Log.Warning("Unrecognized encoded alert {0}", msg.Type);
|
|
return;
|
|
}
|
|
|
|
if (ActivateAlert(player.Value, alert) && _timing.IsFirstTimePredicted)
|
|
{
|
|
HandledAlert();
|
|
}
|
|
}
|
|
|
|
protected virtual void HandledAlert()
|
|
{
|
|
|
|
}
|
|
|
|
public bool ActivateAlert(EntityUid user, AlertPrototype alert)
|
|
{
|
|
if (alert.ClickEvent is not { } clickEvent)
|
|
return false;
|
|
|
|
clickEvent.Handled = false;
|
|
clickEvent.User = user;
|
|
clickEvent.AlertId = alert.ID;
|
|
|
|
RaiseLocalEvent(user, (object) clickEvent, true);
|
|
return clickEvent.Handled;
|
|
}
|
|
|
|
private void OnPlayerAttached(EntityUid uid, AlertsComponent component, PlayerAttachedEvent args)
|
|
{
|
|
Dirty(uid, component);
|
|
}
|
|
}
|