mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 10:21:18 +03:00
ipc super fix
This commit is contained in:
parent
9f97b146bc
commit
d7c79c414a
3 changed files with 134 additions and 49 deletions
80
Content.Client/Corvax/Ipc/IpcSystem.cs
Normal file
80
Content.Client/Corvax/Ipc/IpcSystem.cs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
using Content.Shared.Alert;
|
||||
using Content.Shared.Corvax.Ipc;
|
||||
using Content.Shared.Power.EntitySystems;
|
||||
using Content.Shared.PowerCell;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client.Corvax.Ipc;
|
||||
public sealed class IpcSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly PowerCellSystem _powerCell = default!;
|
||||
[Dependency] private readonly SharedBatterySystem _battery = default!;
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
private static readonly TimeSpan AlertUpdateDelay = TimeSpan.FromSeconds(0.5f);
|
||||
private TimeSpan _nextAlertUpdate = TimeSpan.Zero;
|
||||
private EntityQuery<IpcComponent> _ipcQuery;
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
_ipcQuery = GetEntityQuery<IpcComponent>();
|
||||
SubscribeLocalEvent<IpcComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
|
||||
SubscribeLocalEvent<IpcComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
|
||||
|
||||
SubscribeLocalEvent<IpcComponent, PowerCellChangedEvent>(OnPowerCellChanged);
|
||||
SubscribeLocalEvent<IpcComponent, PowerCellSlotEmptyEvent>(OnPowerCellEmpty);
|
||||
}
|
||||
private void OnPowerCellChanged(EntityUid uid, IpcComponent component, ref PowerCellChangedEvent args)
|
||||
{
|
||||
if (_player.LocalEntity != uid)
|
||||
return;
|
||||
UpdateBatteryAlert((uid, component));
|
||||
}
|
||||
private void OnPowerCellEmpty(EntityUid uid, IpcComponent component, ref PowerCellSlotEmptyEvent args)
|
||||
{
|
||||
if (_player.LocalEntity != uid)
|
||||
return;
|
||||
UpdateBatteryAlert((uid, component));
|
||||
}
|
||||
private void OnPlayerAttached(Entity<IpcComponent> ent, ref LocalPlayerAttachedEvent args)
|
||||
{
|
||||
UpdateBatteryAlert(ent);
|
||||
}
|
||||
private void OnPlayerDetached(Entity<IpcComponent> ent, ref LocalPlayerDetachedEvent args)
|
||||
{
|
||||
_alerts.ClearAlert(ent.Owner, ent.Comp.BatteryAlert);
|
||||
_alerts.ClearAlert(ent.Owner, ent.Comp.NoBatteryAlert);
|
||||
}
|
||||
private void UpdateBatteryAlert(Entity<IpcComponent> ent)
|
||||
{
|
||||
if (!_powerCell.TryGetBatteryFromSlot(ent.Owner, out var battery)
|
||||
|| _battery.GetCharge(battery.Value.AsNullable()) / battery.Value.Comp.MaxCharge < 0.01f)
|
||||
{
|
||||
_alerts.ClearAlert(ent.Owner, ent.Comp.BatteryAlert);
|
||||
_alerts.ShowAlert(ent.Owner, ent.Comp.NoBatteryAlert);
|
||||
return;
|
||||
}
|
||||
var chargePercent = (short)MathF.Round(
|
||||
_battery.GetCharge(battery.Value.AsNullable()) / battery.Value.Comp.MaxCharge * 10f);
|
||||
if (chargePercent == 0 && _powerCell.HasDrawCharge(ent.Owner))
|
||||
chargePercent = 1;
|
||||
_alerts.ClearAlert(ent.Owner, ent.Comp.NoBatteryAlert);
|
||||
_alerts.ShowAlert(ent.Owner, ent.Comp.BatteryAlert, chargePercent);
|
||||
}
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
if (_player.LocalEntity is not { } localPlayer)
|
||||
return;
|
||||
var curTime = _timing.CurTime;
|
||||
if (curTime < _nextAlertUpdate)
|
||||
return;
|
||||
_nextAlertUpdate = curTime + AlertUpdateDelay;
|
||||
if (!_ipcQuery.TryComp(localPlayer, out var ipc))
|
||||
return;
|
||||
UpdateBatteryAlert((localPlayer, ipc));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using Content.Shared.Actions;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Body;
|
||||
using Content.Shared.Corvax.Ipc;
|
||||
using Content.Shared.Damage;
|
||||
|
|
@ -8,34 +7,31 @@ using Content.Shared.Emp;
|
|||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Humanoid.Markings;
|
||||
using Content.Shared.Mobs;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Ninja.Components;
|
||||
using Content.Shared.Ninja.Systems;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Power;
|
||||
using Content.Shared.Power.EntitySystems;
|
||||
using Content.Shared.PowerCell;
|
||||
using Content.Shared.PowerCell.Components;
|
||||
using Content.Shared.Sound.Components;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Corvax.Ipc;
|
||||
|
||||
public sealed partial class IpcSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedActionsSystem _action = default!;
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly SharedBatteryDrainerSystem _batteryDrainer = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly PowerCellSystem _powerCell = default!;
|
||||
[Dependency] private readonly DamageableSystem _damageable = default!;
|
||||
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
|
||||
[Dependency] private readonly SharedBatterySystem _battery = default!;
|
||||
[Dependency] private readonly SharedVisualBodySystem _visualBody = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
|
@ -53,23 +49,27 @@ public sealed partial class IpcSystem : EntitySystem
|
|||
subs.Event<IpcFaceSelectMessage>(OnFaceSelected);
|
||||
});
|
||||
SubscribeLocalEvent<IpcComponent, PowerCellSlotEmptyEvent>(OnPowerCellEmpty);
|
||||
SubscribeLocalEvent<IpcComponent, BatteryStateChangedEvent>(OnBatteryStateChanged);
|
||||
SubscribeLocalEvent<IpcComponent, ChargeChangedEvent>(OnChargeChanged);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
var query = EntityQueryEnumerator<IpcComponent>();
|
||||
while (query.MoveNext(out var uid, out var comp))
|
||||
{
|
||||
if (!comp.IsSlowedByBattery)
|
||||
continue;
|
||||
if (_powerCell.TryGetBatteryFromSlot(uid, out var battery)
|
||||
&& _battery.GetCharge(battery.Value.AsNullable()) / battery.Value.Comp.MaxCharge >= 0.01f)
|
||||
{
|
||||
comp.IsSlowedByBattery = false;
|
||||
_movementSpeedModifier.RefreshMovementSpeedModifiers(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void OnPowerCellEmpty(EntityUid uid, IpcComponent component, ref PowerCellSlotEmptyEvent args)
|
||||
{
|
||||
UpdateBatteryAlert((uid, component));
|
||||
}
|
||||
private void OnBatteryStateChanged(EntityUid uid, IpcComponent component, ref BatteryStateChangedEvent args)
|
||||
{
|
||||
UpdateBatteryAlert((uid, component));
|
||||
}
|
||||
private void OnChargeChanged(EntityUid uid, IpcComponent component, ref ChargeChangedEvent args)
|
||||
{
|
||||
UpdateBatteryAlert((uid, component));
|
||||
}
|
||||
|
||||
private void OnMapInit(EntityUid uid, IpcComponent component, MapInitEvent args)
|
||||
{
|
||||
UpdateBatteryAlert((uid, component));
|
||||
|
|
@ -77,23 +77,27 @@ public sealed partial class IpcSystem : EntitySystem
|
|||
_action.AddAction(uid, ref component.ChangeFaceActionEntity, component.ChangeFaceAction);
|
||||
_movementSpeedModifier.RefreshMovementSpeedModifiers(uid);
|
||||
|
||||
if (_visualBody.TryGatherMarkingsData(uid, null, out _, out _, out var applied)
|
||||
&& applied.TryGetValue("Head", out var headMarkings)
|
||||
&& headMarkings.TryGetValue(HumanoidVisualLayers.Snout, out var snoutMarkings)
|
||||
&& snoutMarkings.Count > 0)
|
||||
{
|
||||
component.SelectedFace = snoutMarkings[0].MarkingId;
|
||||
Dirty(uid, component);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnComponentShutdown(EntityUid uid, IpcComponent component, ComponentShutdown args)
|
||||
{
|
||||
_action.RemoveAction(uid, component.ActionEntity);
|
||||
_action.RemoveAction(uid, component.ChangeFaceActionEntity);
|
||||
}
|
||||
|
||||
private void OnPowerCellChanged(EntityUid uid, IpcComponent component, PowerCellChangedEvent args)
|
||||
private void OnPowerCellChanged(EntityUid uid, IpcComponent component, ref PowerCellChangedEvent args)
|
||||
{
|
||||
if (MetaData(uid).EntityLifeStage >= EntityLifeStage.Terminating)
|
||||
return;
|
||||
|
||||
UpdateBatteryAlert((uid, component));
|
||||
|
||||
}
|
||||
|
||||
private void OnToggleAction(EntityUid uid, IpcComponent component, ToggleDrainActionEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
|
|
@ -114,34 +118,23 @@ public sealed partial class IpcSystem : EntitySystem
|
|||
var message = component.DrainActivated ? "ipc-component-ready" : "ipc-component-disabled";
|
||||
_popup.PopupEntity(Loc.GetString(message), uid, uid);
|
||||
}
|
||||
private void UpdateBatteryAlert(Entity<IpcComponent> ent, PowerCellSlotComponent? slot = null)
|
||||
private void UpdateBatteryAlert(Entity<IpcComponent> ent)
|
||||
{
|
||||
if (!_powerCell.TryGetBatteryFromSlot(ent.Owner, out var battery)
|
||||
|| _battery.GetCharge(battery.Value.AsNullable()) / battery.Value.Comp.MaxCharge < 0.01f)
|
||||
{
|
||||
_alerts.ClearAlert(ent.Owner, ent.Comp.BatteryAlert);
|
||||
_alerts.ShowAlert(ent.Owner, ent.Comp.NoBatteryAlert);
|
||||
_movementSpeedModifier.RefreshMovementSpeedModifiers(ent.Owner);
|
||||
return;
|
||||
}
|
||||
var chargePercent = (short)MathF.Round(
|
||||
_battery.GetCharge(battery.Value.AsNullable()) / battery.Value.Comp.MaxCharge * 10f);
|
||||
if (chargePercent == 0 && _powerCell.HasDrawCharge(ent.Owner))
|
||||
chargePercent = 1;
|
||||
|
||||
_alerts.ClearAlert(ent.Owner, ent.Comp.NoBatteryAlert);
|
||||
_alerts.ShowAlert(ent.Owner, ent.Comp.BatteryAlert, chargePercent);
|
||||
_movementSpeedModifier.RefreshMovementSpeedModifiers(ent.Owner);
|
||||
}
|
||||
|
||||
private void OnRefreshMovementSpeedModifiers(EntityUid uid, IpcComponent comp, RefreshMovementSpeedModifiersEvent args)
|
||||
{
|
||||
if (!_powerCell.TryGetBatteryFromSlot(uid, out var battery) || _battery.GetCharge(battery.Value.AsNullable()) / battery.Value.Comp.MaxCharge < 0.01f)
|
||||
if (!_powerCell.TryGetBatteryFromSlot(uid, out var battery)
|
||||
|| _battery.GetCharge(battery.Value.AsNullable()) / battery.Value.Comp.MaxCharge < 0.01f)
|
||||
{
|
||||
args.ModifySpeed(0.2f);
|
||||
comp.IsSlowedByBattery = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
comp.IsSlowedByBattery = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnOpenFaceAction(EntityUid uid, IpcComponent comp, OpenIpcFaceActionEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
|
|
@ -154,12 +147,13 @@ public sealed partial class IpcSystem : EntitySystem
|
|||
_ui.TryToggleUi(uid, IpcFaceUiKey.Face, actor.PlayerSession);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnFaceSelected(Entity<IpcComponent> ent, ref IpcFaceSelectMessage msg)
|
||||
{
|
||||
if (_visualBody.TryGatherMarkingsData(ent.Owner, null, out var profiles, out var markings, out var applied))
|
||||
{
|
||||
if (applied.TryGetValue("Head", out var headMarkings) && headMarkings.TryGetValue(HumanoidVisualLayers.Snout, out var snoutMarkings))
|
||||
if (applied.TryGetValue("Head", out var headMarkings)
|
||||
&& headMarkings.TryGetValue(HumanoidVisualLayers.Snout, out var snoutMarkings)
|
||||
&& snoutMarkings.Count > 0)
|
||||
{
|
||||
_visualBody.ApplyMarkings(ent.Owner, new()
|
||||
{
|
||||
|
|
@ -169,25 +163,33 @@ public sealed partial class IpcSystem : EntitySystem
|
|||
},
|
||||
});
|
||||
}
|
||||
else if (_prototype.TryIndex<MarkingPrototype>(msg.State, out var proto))
|
||||
{
|
||||
_visualBody.ApplyMarkings(ent.Owner, new()
|
||||
{
|
||||
["Head"] = new()
|
||||
{
|
||||
[HumanoidVisualLayers.Snout] = new List<Marking>() { proto.AsMarking() },
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ent.Comp.SelectedFace = msg.State;
|
||||
Dirty(ent);
|
||||
_ui.CloseUi(ent.Owner, IpcFaceUiKey.Face);
|
||||
}
|
||||
|
||||
private void OnEmpPulse(EntityUid uid, IpcComponent component, ref EmpPulseEvent args)
|
||||
{
|
||||
args.Affected = true;
|
||||
|
||||
var damage = new DamageSpecifier();
|
||||
damage.DamageDict.Add("Shock", 30);
|
||||
_damageable.TryChangeDamage(uid, damage);//ChangeDamage ?
|
||||
_damageable.TryChangeDamage(uid, damage);
|
||||
}
|
||||
|
||||
private void OnMobStateChanged(EntityUid uid, IpcComponent component, ref MobStateChangedEvent args)
|
||||
{
|
||||
if (_mobState.IsCritical(uid))
|
||||
if (args.NewMobState == MobState.Critical)
|
||||
{
|
||||
var sound = EnsureComp<SpamEmitSoundComponent>(uid);
|
||||
sound.Sound = new SoundPathSpecifier("/Audio/Machines/buzz-two.ogg");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
|
@ -36,6 +36,9 @@ public sealed partial class IpcComponent : Component
|
|||
[DataField, AutoNetworkedField]
|
||||
public ProtoId<IpcFaceProfilePrototype> FaceProfile = "DefaultIpcFaces";
|
||||
|
||||
[DataField]
|
||||
public bool IsSlowedByBattery;
|
||||
|
||||
public bool DrainActivated;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue