Merge branch 'master' into tabletop-ops
This commit is contained in:
commit
30fe529007
|
|
@ -19,7 +19,7 @@
|
|||
/Content.IntegrationTests/Tests/PostMapInitTest.cs @DeltaV-Station/maptainers
|
||||
|
||||
# Server rules
|
||||
/Resources/ServerInfo/Guidebook/DeltaV/Rules/ @DeltaV-Station/head-administrators
|
||||
/Resources/ServerInfo/Guidebook/_DV/Rules/ @DeltaV-Station/head-administrators
|
||||
|
||||
# Wiki
|
||||
/.wiki/ @DeltaV-Station/direction
|
||||
|
|
|
|||
|
|
@ -289,4 +289,33 @@ Emergency alert status. ''Central Command has ordered the Epsilon security level
|
|||
| style="border: 1px solid #000000;" | Martial Law is in effect. Do not engage with Central Command Personnel. Await orders from Central Command Personnel.
|
||||
|}
|
||||
|
||||
== <span style="color:#ff8119;>Orange Alert</span> ==
|
||||
Emergency alert status. ''There is a critical station-wide structural or atmospheric threat and recovery is unlikely. Engineering staff are advised to minimize hazards and secure the Evacuation Dock. Crewmembers are advised to stay away from hazardous areas, and prepare for Evacuation.''
|
||||
|
||||
{| class="wikitable" style="width: 80%; border: 1px solid #000000;"
|
||||
!style="text-align:left; width:25%; padding:5px; padding-left:10px; background-color:#FF8119BF; border: 1px solid #000000;" | '''Condition'''
|
||||
!style="text-align:left; width:75%; padding:5px; padding-left:10px; background-color:#FF8119BF; border: 1px solid #000000;" | '''Description'''
|
||||
|-
|
||||
| style="border: 1px solid #000000;" | Chain of Command
|
||||
| style="border: 1px solid #000000;" | [[Standard_Operating_Procedure#Captain’s_Authority|CO]] > [[Chief Engineer]] > Engineering Personnel > Department Heads > Supervisory Roles
|
||||
|-
|
||||
| style="border: 1px solid #000000;" | Armoury Policy
|
||||
| style="border: 1px solid #000000;" | Issuing of lethal weapons disadvised. EVA protection heavily advised for all personnel.
|
||||
|-
|
||||
| style="border: 1px solid #000000;" | Discipline
|
||||
| style="border: 1px solid #000000;" | Report to supervisor for orders. Non-engineering personnel advised to evacuate affected areas. Security should seek to aid engineering staff where possible.
|
||||
|-
|
||||
| style="border: 1px solid #000000;" | Secure Areas
|
||||
| style="border: 1px solid #000000;" | Secure areas unbolted. [[Standard_Operating_Procedure#High_Security_Areas|HSAs]] and areas with an expectation of privacy, such as bedrooms, dorms, or medical treatment facilities, may be bolted as needed.
|
||||
|-
|
||||
| style="border: 1px solid #000000;" | Medical
|
||||
| style="border: 1px solid #000000;" | Full suit sensors heavily advised. EVA suits and functioning internals recommended for emergency responders.
|
||||
|-
|
||||
| style="border: 1px solid #000000;" | Engineering
|
||||
| style="border: 1px solid #000000;" | EVA suits heavily advised for engineers. Distribute emergency internals to crew. Ensure evacuation as soon as possible.
|
||||
|-
|
||||
| style="border: 1px solid #000000;" | Rules of Engagement
|
||||
| style="border: 1px solid #000000;" | Engage with minimal force required; prioritize de-escalation whenever possible.
|
||||
|}
|
||||
|
||||
{{Guides Menu}}
|
||||
|
|
|
|||
|
|
@ -269,7 +269,6 @@ Prisoners have certain rights that must be upheld by law enforcement and Station
|
|||
* Standard prisoner clothing must always be available for prisoners.
|
||||
* Confiscated clothing should be returned upon request, except in the case of Extended Confinement or if the clothing in question poses a clear risk to prisoner or crew safety.
|
||||
* Food and water for organic prisoners must be available and given on request.
|
||||
* Power for silicon prisoners such as IPCs and cyborgs, at minimum a cyborg recharging station must be provided.
|
||||
* Should the holding cells or Permabrig become uninhabitable, prisoners must be securely and safely relocated to another area for confinement, until the holding cells or Permabrig are returned to a serviceable state.
|
||||
* Prisoners should be granted freedom of movement within their holding area unless there is an undue risk to life and limb.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,12 +8,14 @@ using Content.Shared.CCVar;
|
|||
using Content.Shared.Ghost;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.SSDIndicator; // DeltaV - SSD time indicator
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing; // DeltaV - SSD time indicator
|
||||
|
||||
namespace Content.Client.Administration;
|
||||
|
||||
|
|
@ -26,6 +28,7 @@ internal sealed class AdminNameOverlay : Overlay
|
|||
private readonly IUserInterfaceManager _userInterfaceManager;
|
||||
private readonly SharedRoleSystem _roles;
|
||||
private readonly IPrototypeManager _prototypeManager;
|
||||
private readonly IGameTiming _timing; // DeltaV - Add timing
|
||||
private readonly Font _font;
|
||||
private readonly Font _fontBold;
|
||||
private AdminOverlayAntagFormat _overlayFormat;
|
||||
|
|
@ -53,7 +56,8 @@ internal sealed class AdminNameOverlay : Overlay
|
|||
IUserInterfaceManager userInterfaceManager,
|
||||
IConfigurationManager config,
|
||||
SharedRoleSystem roles,
|
||||
IPrototypeManager prototypeManager)
|
||||
IPrototypeManager prototypeManager,
|
||||
IGameTiming timing) // DeltaV - Add timing
|
||||
{
|
||||
_system = system;
|
||||
_entityManager = entityManager;
|
||||
|
|
@ -62,6 +66,7 @@ internal sealed class AdminNameOverlay : Overlay
|
|||
_userInterfaceManager = userInterfaceManager;
|
||||
_roles = roles;
|
||||
_prototypeManager = prototypeManager;
|
||||
_timing = timing; // DeltaV - Add timing
|
||||
ZIndex = 200;
|
||||
// Setting these to a specific ttf would break the antag symbols
|
||||
_font = resourceCache.NotoStack();
|
||||
|
|
@ -231,6 +236,17 @@ internal sealed class AdminNameOverlay : Overlay
|
|||
currentOffset += lineoffset;
|
||||
}
|
||||
|
||||
// DeltaV - SSD Time START
|
||||
if (_entityManager.TryGetComponent<SSDIndicatorComponent>(entity, out var ssdIndicator) && ssdIndicator.IsSSD)
|
||||
{
|
||||
color = Color.MediumPurple;
|
||||
color.A = alpha;
|
||||
var ssdText = Loc.GetString("admin-overlay-ssd-time", ("time", (_timing.CurTime - ssdIndicator.SsdSince).ToString("%hh':'mm':'ss")));
|
||||
args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, ssdText, uiScale, color);
|
||||
currentOffset += lineoffset;
|
||||
}
|
||||
// DeltaV END
|
||||
|
||||
// Determine antag symbol
|
||||
string? symbol;
|
||||
switch (_overlaySymbolStyle)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using Robust.Client.ResourceManagement;
|
|||
using Robust.Client.UserInterface;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing; // DeltaV - SSD time indicator
|
||||
|
||||
namespace Content.Client.Administration.Systems
|
||||
{
|
||||
|
|
@ -19,6 +20,7 @@ namespace Content.Client.Administration.Systems
|
|||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||
[Dependency] private readonly SharedRoleSystem _roles = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!; // DeltaV - added for SSD time indicator
|
||||
|
||||
private AdminNameOverlay _adminNameOverlay = default!;
|
||||
|
||||
|
|
@ -36,7 +38,8 @@ namespace Content.Client.Administration.Systems
|
|||
_userInterfaceManager,
|
||||
_configurationManager,
|
||||
_roles,
|
||||
_proto);
|
||||
_proto,
|
||||
_timing); // DeltaV - Add timing
|
||||
_adminManager.AdminStatusUpdated += OnAdminStatusUpdated;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,76 +1,7 @@
|
|||
using Content.Shared.Body.Systems;
|
||||
// Shitmed Change Start
|
||||
using Content.Shared._Shitmed.Body.Part;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Humanoid.Markings;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Utility;
|
||||
using Content.Shared.Body.Components;
|
||||
// Shitmed Change End
|
||||
|
||||
namespace Content.Client.Body.Systems;
|
||||
|
||||
public sealed class BodySystem : SharedBodySystem
|
||||
{
|
||||
// Shitmed Change Start
|
||||
[Dependency] private readonly MarkingManager _markingManager = default!;
|
||||
|
||||
private void ApplyMarkingToPart(MarkingPrototype markingPrototype,
|
||||
IReadOnlyList<Color>? colors,
|
||||
bool visible,
|
||||
SpriteComponent sprite)
|
||||
{
|
||||
for (var j = 0; j < markingPrototype.Sprites.Count; j++)
|
||||
{
|
||||
var markingSprite = markingPrototype.Sprites[j];
|
||||
|
||||
if (markingSprite is not SpriteSpecifier.Rsi rsi)
|
||||
continue;
|
||||
|
||||
var layerId = $"{markingPrototype.ID}-{rsi.RsiState}";
|
||||
|
||||
if (!sprite.LayerMapTryGet(layerId, out _))
|
||||
{
|
||||
var layer = sprite.AddLayer(markingSprite, j + 1);
|
||||
sprite.LayerMapSet(layerId, layer);
|
||||
sprite.LayerSetSprite(layerId, rsi);
|
||||
}
|
||||
|
||||
sprite.LayerSetVisible(layerId, visible);
|
||||
|
||||
if (!visible)
|
||||
continue;
|
||||
|
||||
// Okay so if the marking prototype is modified but we load old marking data this may no longer be valid
|
||||
// and we need to check the index is correct. So if that happens just default to white?
|
||||
if (colors != null && j < colors.Count)
|
||||
sprite.LayerSetColor(layerId, colors[j]);
|
||||
else
|
||||
sprite.LayerSetColor(layerId, Color.White);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ApplyPartMarkings(EntityUid target, BodyPartAppearanceComponent component)
|
||||
{
|
||||
if (!TryComp(target, out SpriteComponent? sprite))
|
||||
return;
|
||||
|
||||
if (component.Color != null)
|
||||
sprite.Color = component.Color.Value;
|
||||
|
||||
foreach (var (visualLayer, markingList) in component.Markings)
|
||||
foreach (var marking in markingList)
|
||||
{
|
||||
if (!_markingManager.TryGetMarking(marking, out var markingPrototype))
|
||||
continue;
|
||||
|
||||
ApplyMarkingToPart(markingPrototype, marking.MarkingColors, marking.Visible, sprite);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RemoveBodyMarkings(EntityUid target, BodyPartAppearanceComponent partAppearance, HumanoidAppearanceComponent bodyAppearance)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Shitmed Change End
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Linq;
|
||||
using Content.Client.DisplacementMap;
|
||||
using Content.Client.Inventory;
|
||||
using Content.Shared._DV.Silicon.IPC; // DeltaV - IPC Snouts
|
||||
using Content.Shared.Clothing;
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared.Clothing.EntitySystems;
|
||||
|
|
@ -103,12 +102,8 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
|
||||
List<PrototypeLayerData>? layers = null;
|
||||
|
||||
// Begin DeltaV Additions - IPC snouts
|
||||
var speciesId = inventory.SpeciesId;
|
||||
|
||||
if (TryComp(args.Equipee, out SnoutHelmetComponent? helmetComponent) && helmetComponent.EnableAlternateHelmet)
|
||||
speciesId = helmetComponent.ReplacementRace;
|
||||
|
||||
// first attempt to get species specific data.
|
||||
if (speciesId != null)
|
||||
item.ClothingVisuals.TryGetValue($"{args.Slot}-{speciesId}", out layers);
|
||||
|
|
@ -120,7 +115,6 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||
if (!TryGetDefaultVisuals(uid, item, args.Slot, speciesId, out layers))
|
||||
return;
|
||||
}
|
||||
// End DeltaV Additions
|
||||
|
||||
// add each layer to the visuals
|
||||
var i = 0;
|
||||
|
|
|
|||
|
|
@ -18,8 +18,36 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<DoorComponent, AppearanceChangeEvent>(OnAppearanceChange);
|
||||
// ES START
|
||||
// handle open/close state change on client after animation end, not when server says door is open
|
||||
SubscribeLocalEvent<DoorComponent, AnimationCompletedEvent>(OnAnimationCompleted);
|
||||
}
|
||||
|
||||
private void OnAnimationCompleted(Entity<DoorComponent> entity, ref AnimationCompletedEvent args)
|
||||
{
|
||||
if (!TryComp<SpriteComponent>(entity, out var sprite) || args.Key != DoorComponent.OpenCloseKey)
|
||||
return;
|
||||
|
||||
switch (entity.Comp.State)
|
||||
{
|
||||
case DoorState.Open:
|
||||
foreach (var (layer, layerState) in entity.Comp.OpenSpriteStates)
|
||||
{
|
||||
_sprite.LayerSetRsiState((entity.Owner, sprite), layer, layerState);
|
||||
}
|
||||
|
||||
break;
|
||||
case DoorState.Closed:
|
||||
foreach (var (layer, layerState) in entity.Comp.ClosedSpriteStates)
|
||||
{
|
||||
_sprite.LayerSetRsiState((entity.Owner, sprite), layer, layerState);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ES END
|
||||
|
||||
protected override void OnComponentInit(Entity<DoorComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
var comp = ent.Comp;
|
||||
|
|
@ -87,10 +115,13 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||
state = DoorState.Closed;
|
||||
|
||||
if (AppearanceSystem.TryGetData<string>(entity, PaintableVisuals.Prototype, out var prototype, args.Component))
|
||||
UpdateSpriteLayers((entity.Owner, args.Sprite), prototype);
|
||||
UpdateSpriteLayers((entity.Owner, args.Sprite), prototype);
|
||||
|
||||
if (_animationSystem.HasRunningAnimation(entity, DoorComponent.AnimationKey))
|
||||
_animationSystem.Stop(entity.Owner, DoorComponent.AnimationKey);
|
||||
// ES START
|
||||
// dont stop all animations for no reason
|
||||
//if (_animationSystem.HasRunningAnimation(entity, DoorComponent.AnimationKey))
|
||||
// _animationSystem.Stop(entity.Owner, DoorComponent.AnimationKey);
|
||||
// ES END
|
||||
|
||||
// We are checking beforehand since some doors may not have an emagging visual layer, and we don't want LayerSetVisible to throw an error.
|
||||
if (_sprite.TryGetLayer(entity.Owner, DoorVisualLayers.BaseEmagging, out var _, false))
|
||||
|
|
@ -106,6 +137,12 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||
switch (state)
|
||||
{
|
||||
case DoorState.Open:
|
||||
// ES START
|
||||
// If we are already animating the close just let that do its job
|
||||
if (_animationSystem.HasRunningAnimation(entity, DoorComponent.OpenCloseKey))
|
||||
return;
|
||||
// ES END
|
||||
|
||||
foreach (var (layer, layerState) in entity.Comp.OpenSpriteStates)
|
||||
{
|
||||
_sprite.LayerSetRsiState((entity.Owner, sprite), layer, layerState);
|
||||
|
|
@ -113,6 +150,12 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||
|
||||
return;
|
||||
case DoorState.Closed:
|
||||
// ES START
|
||||
// If we are already animating the close just let that do its job
|
||||
if (_animationSystem.HasRunningAnimation(entity, DoorComponent.OpenCloseKey))
|
||||
return;
|
||||
// ES END
|
||||
|
||||
foreach (var (layer, layerState) in entity.Comp.ClosedSpriteStates)
|
||||
{
|
||||
_sprite.LayerSetRsiState((entity.Owner, sprite), layer, layerState);
|
||||
|
|
@ -123,24 +166,47 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||
if (entity.Comp.OpeningAnimationTime == TimeSpan.Zero)
|
||||
return;
|
||||
|
||||
_animationSystem.Play(entity, (Animation)entity.Comp.OpeningAnimation, DoorComponent.AnimationKey);
|
||||
// ES START
|
||||
// since we dont stop them earlier we check here
|
||||
if (_animationSystem.HasRunningAnimation(entity, DoorComponent.OpenCloseKey))
|
||||
return;
|
||||
// ES END
|
||||
|
||||
_animationSystem.Play(entity, (Animation)entity.Comp.OpeningAnimation, DoorComponent.OpenCloseKey);
|
||||
|
||||
return;
|
||||
case DoorState.Closing:
|
||||
if (entity.Comp.ClosingAnimationTime == TimeSpan.Zero || entity.Comp.CurrentlyCrushing.Count != 0)
|
||||
return;
|
||||
|
||||
_animationSystem.Play(entity, (Animation)entity.Comp.ClosingAnimation, DoorComponent.AnimationKey);
|
||||
// ES START
|
||||
// since we dont stop them earlier we check here
|
||||
if (_animationSystem.HasRunningAnimation(entity, DoorComponent.OpenCloseKey))
|
||||
return;
|
||||
// ES END
|
||||
|
||||
_animationSystem.Play(entity, (Animation)entity.Comp.ClosingAnimation, DoorComponent.OpenCloseKey);
|
||||
|
||||
return;
|
||||
case DoorState.Denying:
|
||||
_animationSystem.Play(entity, (Animation)entity.Comp.DenyingAnimation, DoorComponent.AnimationKey);
|
||||
// ES START
|
||||
// AnimationKey -> DenyKey
|
||||
if (_animationSystem.HasRunningAnimation(entity, DoorComponent.DenyKey))
|
||||
return;
|
||||
|
||||
_animationSystem.Play(entity, (Animation)entity.Comp.DenyingAnimation, DoorComponent.DenyKey);
|
||||
// ES END
|
||||
|
||||
return;
|
||||
case DoorState.Emagging:
|
||||
// We are checking beforehand since some doors may not have an emagging visual layer.
|
||||
// ES START
|
||||
// AnimationKey -> DenyKey
|
||||
if (_animationSystem.HasRunningAnimation(entity, DoorComponent.EmagKey))
|
||||
return;
|
||||
|
||||
if (_sprite.TryGetLayer(entity.Owner, DoorVisualLayers.BaseEmagging, out var _, false))
|
||||
_animationSystem.Play(entity, (Animation)entity.Comp.EmaggingAnimation, DoorComponent.AnimationKey);
|
||||
_animationSystem.Play(entity, (Animation)entity.Comp.EmaggingAnimation, DoorComponent.EmagKey);
|
||||
// ES END
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ public sealed class EyeLerpingSystem : EntitySystem
|
|||
UpdatesAfter.Add(typeof(TransformSystem));
|
||||
UpdatesAfter.Add(typeof(Robust.Client.Physics.PhysicsSystem));
|
||||
UpdatesBefore.Add(typeof(SharedEyeSystem));
|
||||
// ES START
|
||||
UpdatesBefore.Add(typeof(EyeSystem));
|
||||
// ES END
|
||||
UpdatesOutsidePrediction = true;
|
||||
}
|
||||
|
||||
|
|
@ -68,6 +71,11 @@ public sealed class EyeLerpingSystem : EntitySystem
|
|||
{
|
||||
_eye.SetRotation(uid, lerpInfo.TargetRotation, component);
|
||||
_eye.SetZoom(uid, lerpInfo.TargetZoom, component);
|
||||
|
||||
// Starlight begin - fix ES Screenshake triggering on spawn
|
||||
if (TryComp<ContentEyeComponent>(uid, out var contentEye))
|
||||
contentEye.BaseRotation = lerpInfo.TargetRotation;
|
||||
// Starlight end
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -175,9 +183,15 @@ public sealed class EyeLerpingSystem : EntitySystem
|
|||
{
|
||||
var tickFraction = (float) _gameTiming.TickFraction / ushort.MaxValue;
|
||||
const double lerpMinimum = 0.00001;
|
||||
var query = AllEntityQuery<LerpingEyeComponent, EyeComponent, TransformComponent>();
|
||||
// ES START
|
||||
// add contenteye bc we only want to modify the fuckin base rotation
|
||||
var query = AllEntityQuery<LerpingEyeComponent, EyeComponent, ContentEyeComponent, TransformComponent>();
|
||||
// ES END
|
||||
|
||||
while (query.MoveNext(out var entity, out var lerpInfo, out var eye, out var xform))
|
||||
// ES START
|
||||
// contenteye
|
||||
while (query.MoveNext(out var entity, out var lerpInfo, out var eye, out var contentEye, out var xform))
|
||||
// ES END
|
||||
{
|
||||
// Handle zoom
|
||||
var zoomDiff = Vector2.Lerp(lerpInfo.LastZoom, lerpInfo.TargetZoom, tickFraction);
|
||||
|
|
@ -191,6 +205,14 @@ public sealed class EyeLerpingSystem : EntitySystem
|
|||
_eye.SetZoom(entity, zoomDiff, eye);
|
||||
}
|
||||
|
||||
// ES START
|
||||
// UHHHHHHHHHHHh
|
||||
// shit is fucked idk
|
||||
// we need to alter baserotation not regular eye rotation and also i added baserotation because uhh
|
||||
// there was no good way to separate 'how the eye should be oriented because of the grid/turning/etc' and 'the eye rotating on top of that'
|
||||
// had to add it
|
||||
// ES END
|
||||
|
||||
// Handle Rotation
|
||||
TryComp<InputMoverComponent>(entity, out var mover);
|
||||
|
||||
|
|
@ -199,7 +221,10 @@ public sealed class EyeLerpingSystem : EntitySystem
|
|||
|
||||
if (!NeedsLerp(mover))
|
||||
{
|
||||
_eye.SetRotation(entity, lerpInfo.TargetRotation, eye);
|
||||
// ES START
|
||||
// contenteye
|
||||
contentEye.BaseRotation = lerpInfo.TargetRotation;
|
||||
// ES END
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -207,11 +232,17 @@ public sealed class EyeLerpingSystem : EntitySystem
|
|||
|
||||
if (Math.Abs(shortest.Theta) < lerpMinimum)
|
||||
{
|
||||
_eye.SetRotation(entity, lerpInfo.TargetRotation, eye);
|
||||
// ES START
|
||||
// contenteye
|
||||
contentEye.BaseRotation = lerpInfo.TargetRotation;
|
||||
// ES END
|
||||
continue;
|
||||
}
|
||||
|
||||
_eye.SetRotation(entity, shortest * tickFraction + lerpInfo.LastRotation, eye);
|
||||
// ES START
|
||||
// contenteye
|
||||
contentEye.BaseRotation = shortest * tickFraction + lerpInfo.LastRotation;
|
||||
// ES END
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared._Shitmed.Body.Events; // Shitmed Change
|
||||
using Content.Client.DisplacementMap;
|
||||
using Content.Client.Examine;
|
||||
using Content.Client.Strip;
|
||||
using Content.Client.Verbs.UI;
|
||||
using Content.Shared.Body.Part; // Shitmed Change
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Hands.EntitySystems;
|
||||
|
|
@ -51,8 +49,6 @@ namespace Content.Client.Hands.Systems
|
|||
SubscribeLocalEvent<HandsComponent, ComponentShutdown>(OnHandsShutdown);
|
||||
SubscribeLocalEvent<HandsComponent, ComponentHandleState>(HandleComponentState);
|
||||
SubscribeLocalEvent<HandsComponent, VisualsChangedEvent>(OnVisualsChanged);
|
||||
SubscribeLocalEvent<HandsComponent, BodyPartRemovedEvent>(HandleBodyPartRemoved); // Shitmed Change
|
||||
SubscribeLocalEvent<HandsComponent, BodyPartDisabledEvent>(HandleBodyPartDisabled); // Shitmed Change
|
||||
|
||||
OnHandSetActive += OnHandActivated;
|
||||
}
|
||||
|
|
@ -206,35 +202,6 @@ namespace Content.Client.Hands.Systems
|
|||
|
||||
#region visuals
|
||||
|
||||
// Shitmed Change Start
|
||||
private void HideLayers(EntityUid uid, HandsComponent component, Entity<BodyPartComponent> part, SpriteComponent? sprite = null)
|
||||
{
|
||||
if (part.Comp.PartType != BodyPartType.Hand || !Resolve(uid, ref sprite, logMissing: false))
|
||||
return;
|
||||
|
||||
var location = part.Comp.Symmetry switch
|
||||
{
|
||||
BodyPartSymmetry.None => HandLocation.Middle,
|
||||
BodyPartSymmetry.Left => HandLocation.Left,
|
||||
BodyPartSymmetry.Right => HandLocation.Right,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(part.Comp.Symmetry))
|
||||
};
|
||||
|
||||
if (component.RevealedLayers.TryGetValue(location, out var revealedLayers))
|
||||
{
|
||||
foreach (var key in revealedLayers)
|
||||
sprite.RemoveLayer(key);
|
||||
|
||||
revealedLayers.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleBodyPartRemoved(EntityUid uid, HandsComponent component, ref BodyPartRemovedEvent args) => HideLayers(uid, component, args.Part);
|
||||
|
||||
private void HandleBodyPartDisabled(EntityUid uid, HandsComponent component, ref BodyPartDisabledEvent args) => HideLayers(uid, component, args.Part);
|
||||
|
||||
// Shitmed Change End
|
||||
|
||||
protected override void HandleEntityInserted(EntityUid uid, HandsComponent hands, EntInsertedIntoContainerMessage args)
|
||||
{
|
||||
base.HandleEntityInserted(uid, hands, args);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using Content.Shared.MedicalScanner;
|
||||
using Content.Shared._Shitmed.Targeting; // Shitmed Change
|
||||
using Content.Shared._DV.MedicalRecords; // DeltaV - Medical Records
|
||||
using JetBrains.Annotations;
|
||||
using Content.Shared._DV.MedicalRecords;
|
||||
using JetBrains.Annotations; // DeltaV - Medical Records
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client.HealthAnalyzer.UI
|
||||
|
|
@ -21,13 +20,11 @@ namespace Content.Client.HealthAnalyzer.UI
|
|||
base.Open();
|
||||
|
||||
_window = this.CreateWindow<HealthAnalyzerWindow>();
|
||||
_window.HealthAnalyzer.OnBodyPartSelected += SendBodyPartMessage; // Shitmed Change
|
||||
_window.HealthAnalyzer.OnTriageStatusChanged += SendTriageStatusMessage; // DeltaV - Medical Records
|
||||
_window.HealthAnalyzer.OnClaimPatient += SendTriageClaimMessage; // DeltaV - Medical Records
|
||||
_window.Title = EntMan.GetComponent<MetaDataComponent>(Owner).EntityName;
|
||||
}
|
||||
|
||||
|
||||
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
|
||||
{
|
||||
if (_window == null)
|
||||
|
|
@ -39,22 +36,6 @@ namespace Content.Client.HealthAnalyzer.UI
|
|||
_window.Populate(cast);
|
||||
}
|
||||
|
||||
// Shitmed Change Start
|
||||
private void SendBodyPartMessage(TargetBodyPart? part, EntityUid target) => SendMessage(new HealthAnalyzerPartMessage(EntMan.GetNetEntity(target), part ?? null));
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (!disposing)
|
||||
return;
|
||||
|
||||
if (_window != null)
|
||||
_window.HealthAnalyzer.OnBodyPartSelected -= SendBodyPartMessage;
|
||||
|
||||
_window?.Dispose();
|
||||
}
|
||||
|
||||
// Shitmed Change End
|
||||
|
||||
// Begin DeltaV - Medical Records
|
||||
private void SendTriageStatusMessage(TriageStatus status)
|
||||
=> SendMessage(new HealthAnalyzerTriageStatusMessage(status));
|
||||
|
|
|
|||
|
|
@ -6,160 +6,12 @@
|
|||
Name="NoPatientDataText"
|
||||
Text="{Loc health-analyzer-window-no-patient-data-text}" />
|
||||
|
||||
<!-- Shitmed Change Start -->
|
||||
<Button Name="ReturnButton"
|
||||
Text="{Loc 'health-analyzer-window-return-button-text'}"
|
||||
Margin="0 0 0 10"
|
||||
HorizontalExpand="False"/>
|
||||
<!-- Shitmed Change End -->
|
||||
|
||||
<BoxContainer
|
||||
Name="PatientDataContainer"
|
||||
Margin="0 0 0 5"
|
||||
Orientation="Vertical">
|
||||
<BoxContainer Orientation="Horizontal" Margin="0 0 0 5">
|
||||
<PanelContainer>
|
||||
<!-- Shitmed Change Start -->
|
||||
<SpriteView OverrideDirection="South" Name="SpriteView" Access="Public" SetSize="96 96" />
|
||||
<PanelContainer
|
||||
Name="PartView"
|
||||
SetSize="57 96"
|
||||
Margin="18 0 0 0"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Left">
|
||||
<PanelContainer
|
||||
SetSize="15 33"
|
||||
Margin="4 0 0 0"
|
||||
HorizontalAlignment="Left">
|
||||
<TextureButton
|
||||
Name="RightArmButton"
|
||||
MinSize="15 25"
|
||||
StyleClasses="TargetDollButtonRightArm"
|
||||
VerticalAlignment="Top">
|
||||
</TextureButton>
|
||||
<TextureButton
|
||||
Name="RightHandButton"
|
||||
MinSize="15 15"
|
||||
VerticalAlignment="Bottom"
|
||||
StyleClasses="TargetDollButtonRightHand">
|
||||
</TextureButton>
|
||||
</PanelContainer>
|
||||
<PanelContainer
|
||||
SetSize="43 75"
|
||||
Margin="0 0 0 0"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<TextureButton
|
||||
Name="HeadButton"
|
||||
MinSize="28 23"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center"
|
||||
StyleClasses="TargetDollButtonHead">
|
||||
<!--<PanelContainer
|
||||
SetSize="14 15"
|
||||
Margin="-1 9 0 0"
|
||||
HorizontalAlignment="Center">
|
||||
<TextureButton
|
||||
Name="EyesButton"
|
||||
MinSize="14 9"
|
||||
VerticalAlignment="Top"
|
||||
StyleClasses="TargetDollButtonEyes">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/Interface/Targeting/Doll/eyes.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="14 9"/>
|
||||
</TextureButton>
|
||||
<TextureButton
|
||||
Name="MouthButton"
|
||||
SetSize="8 6"
|
||||
VerticalAlignment="Bottom"
|
||||
StyleClasses="TargetDollButtonMouth">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/Interface/Targeting/Doll/mouth.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="8 6"/>
|
||||
</TextureButton>
|
||||
</PanelContainer>-->
|
||||
</TextureButton>
|
||||
<TextureButton
|
||||
Name="ChestButton"
|
||||
SetSize="28 30"
|
||||
Margin="0 18 0 0"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center"
|
||||
StyleClasses="TargetDollButtonChest">
|
||||
</TextureButton>
|
||||
<PanelContainer
|
||||
MinSize="38 35"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Center">
|
||||
<TextureButton
|
||||
Name="GroinButton"
|
||||
MinSize="28 15"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center"
|
||||
StyleClasses="TargetDollButtonGroin">
|
||||
</TextureButton>
|
||||
<PanelContainer
|
||||
MinSize="20 30"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Right">
|
||||
<TextureButton
|
||||
Name="LeftLegButton"
|
||||
MinSize="15 28"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Left"
|
||||
StyleClasses="TargetDollButtonLeftLeg">
|
||||
</TextureButton>
|
||||
<TextureButton
|
||||
Name="LeftFootButton"
|
||||
MinSize="20 10"
|
||||
VerticalAlignment="Bottom"
|
||||
StyleClasses="TargetDollButtonLeftFoot">
|
||||
</TextureButton>
|
||||
</PanelContainer>
|
||||
<PanelContainer
|
||||
MinSize="20 30"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Left">
|
||||
<TextureButton
|
||||
Name="RightLegButton"
|
||||
MinSize="15 28"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Right"
|
||||
StyleClasses="TargetDollButtonRightLeg">
|
||||
</TextureButton>
|
||||
<TextureButton
|
||||
Name="RightFootButton"
|
||||
MinSize="20 10"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Center"
|
||||
StyleClasses="TargetDollButtonRightFoot">
|
||||
</TextureButton>
|
||||
</PanelContainer>
|
||||
</PanelContainer>
|
||||
</PanelContainer>
|
||||
<PanelContainer
|
||||
SetSize="15 33"
|
||||
Margin="0 0 4 0"
|
||||
HorizontalAlignment="Right">
|
||||
<TextureButton
|
||||
Name="LeftArmButton"
|
||||
MinSize="15 25"
|
||||
StyleClasses="TargetDollButtonLeftArm"
|
||||
VerticalAlignment="Top">
|
||||
</TextureButton>
|
||||
<TextureButton
|
||||
Name="LeftHandButton"
|
||||
MinSize="15 15"
|
||||
VerticalAlignment="Bottom"
|
||||
StyleClasses="TargetDollButtonLeftHand">
|
||||
</TextureButton>
|
||||
</PanelContainer>
|
||||
</PanelContainer>
|
||||
</PanelContainer>
|
||||
<!-- Shitmed Change Start -->
|
||||
<TextureRect Name="NoDataTex" Access="Public" SetSize="96 96" Visible="false" Stretch="KeepAspectCentered" TexturePath="/Textures/Interface/Misc/health_analyzer_out_of_range.png"/> <!-- DeltaV - Size changed to 96 96 to be consistent with shitmed -->
|
||||
<TextureRect Name="NoDataTex" Access="Public" SetSize="96 96" Visible="false" Stretch="KeepAspectCentered" TexturePath="/Textures/Interface/Misc/health_analyzer_out_of_range.png"/> <!-- DeltaV - Size changed to 96-->
|
||||
<BoxContainer Margin="5 0 0 0" Orientation="Vertical" VerticalAlignment="Top">
|
||||
<RichTextLabel Name="NameLabel" SetWidth="150" />
|
||||
<Label Name="SpeciesLabel" VerticalAlignment="Top" StyleClasses="LabelSubText" />
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ using Content.Client._DV.Traits.Assorted; // DeltaV
|
|||
using Content.Shared._DV.Traits.Assorted; // DeltaV
|
||||
using Content.Shared._DV.Medical; // DeltaV - Uncloneable
|
||||
using Content.Shared._DV.MedicalRecords; // DeltaV - Medical Records
|
||||
using Content.Shared._Shitmed.Targeting; // Shitmed
|
||||
|
||||
// Health analyzer UI is split from its window because it's used by both the
|
||||
// health analyzer item and the cryo pod UI.
|
||||
|
|
@ -41,16 +40,6 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
|||
private readonly RedshirtSystem _redshirt; // DeltaV
|
||||
private readonly UncloneableSystem _uncloneable; // DeltaV
|
||||
|
||||
// Shitmed Change Start
|
||||
public event Action<TargetBodyPart?, EntityUid>? OnBodyPartSelected;
|
||||
private EntityUid _spriteViewEntity;
|
||||
|
||||
private readonly EntProtoId _bodyView = "AlertSpriteView";
|
||||
|
||||
private readonly Dictionary<TargetBodyPart, TextureButton> _bodyPartControls;
|
||||
private EntityUid? _target;
|
||||
// Shitmed Change End
|
||||
|
||||
// Begin DeltaV - Medical Records
|
||||
private readonly ButtonGroup _triageStatusGroup = new();
|
||||
private readonly Dictionary<TriageStatus, Button> _triageControls = new();
|
||||
|
|
@ -72,29 +61,6 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
|||
_unborgable = _entityManager.System<UnborgableSystem>(); // DeltaV
|
||||
_redshirt = _entityManager.System<RedshirtSystem>(); // DeltaV
|
||||
_uncloneable = _entityManager.System<UncloneableSystem>(); // DeltaV
|
||||
// Shitmed Change Start
|
||||
_bodyPartControls = new Dictionary<TargetBodyPart, TextureButton>
|
||||
{
|
||||
{ TargetBodyPart.Head, HeadButton },
|
||||
{ TargetBodyPart.Torso, ChestButton },
|
||||
{ TargetBodyPart.Groin, GroinButton },
|
||||
{ TargetBodyPart.LeftArm, LeftArmButton },
|
||||
{ TargetBodyPart.LeftHand, LeftHandButton },
|
||||
{ TargetBodyPart.RightArm, RightArmButton },
|
||||
{ TargetBodyPart.RightHand, RightHandButton },
|
||||
{ TargetBodyPart.LeftLeg, LeftLegButton },
|
||||
{ TargetBodyPart.LeftFoot, LeftFootButton },
|
||||
{ TargetBodyPart.RightLeg, RightLegButton },
|
||||
{ TargetBodyPart.RightFoot, RightFootButton },
|
||||
};
|
||||
|
||||
foreach (var bodyPartButton in _bodyPartControls)
|
||||
{
|
||||
bodyPartButton.Value.MouseFilter = MouseFilterMode.Stop;
|
||||
bodyPartButton.Value.OnPressed += _ => SetActiveBodyPart(bodyPartButton.Key, bodyPartButton.Value);
|
||||
}
|
||||
ReturnButton.OnPressed += _ => ResetBodyPart();
|
||||
// Shitmed Change End
|
||||
|
||||
// Begin DeltaV - Medical Records
|
||||
foreach (var item in Enum.GetValues<TriageStatus>())
|
||||
|
|
@ -120,29 +86,14 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
|||
public void Populate(HealthAnalyzerUiState state)
|
||||
{
|
||||
var target = _entityManager.GetEntity(state.TargetEntity);
|
||||
// Begin Shitmed
|
||||
_target = target;
|
||||
EntityUid? part = state.Part != null ? _entityManager.GetEntity(state.Part.Value) : null;
|
||||
var isPart = part != null;
|
||||
// End Shitmed
|
||||
|
||||
if (target == null
|
||||
|| !_entityManager.TryGetComponent<DamageableComponent>(isPart ? part : target, out var damageable)) // Shitmed
|
||||
|| !_entityManager.TryGetComponent<DamageableComponent>(target, out var damageable))
|
||||
{
|
||||
NoPatientDataText.Visible = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Begin Shitmed
|
||||
ReturnButton.Visible = isPart;
|
||||
PartNameLabel.Visible = isPart;
|
||||
|
||||
if (part != null)
|
||||
PartNameLabel.Text = _entityManager.HasComponent<MetaDataComponent>(part)
|
||||
? Identity.Name(part.Value, _entityManager)
|
||||
: Loc.GetString("health-analyzer-window-entity-unknown-value-text");
|
||||
// End Shitmed
|
||||
|
||||
NoPatientDataText.Visible = false;
|
||||
|
||||
// Scan Mode
|
||||
|
|
@ -157,11 +108,6 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
|||
|
||||
// Patient Information
|
||||
|
||||
SpriteView.SetEntity(SetupIcon(state.Body) ?? target.Value); // Shitmed Change
|
||||
SpriteView.Visible = state.ScanMode.HasValue && state.ScanMode.Value;
|
||||
PartView.Visible = SpriteView.Visible; // Shitmed Change
|
||||
NoDataTex.Visible = !SpriteView.Visible;
|
||||
|
||||
var name = new FormattedMessage();
|
||||
name.PushColor(Color.White);
|
||||
name.AddText(_entityManager.HasComponent<MetaDataComponent>(target.Value)
|
||||
|
|
@ -338,65 +284,6 @@ public sealed partial class HealthAnalyzerControl : BoxContainer
|
|||
}
|
||||
}
|
||||
|
||||
// Shitmed Change Start
|
||||
public void SetActiveBodyPart(TargetBodyPart part, TextureButton button)
|
||||
{
|
||||
if (_target == null)
|
||||
return;
|
||||
|
||||
// Bit of the ole shitcode until we have Groins in the prototypes.
|
||||
OnBodyPartSelected?.Invoke(part == TargetBodyPart.Groin ? TargetBodyPart.Torso : part, _target.Value);
|
||||
}
|
||||
|
||||
public void ResetBodyPart()
|
||||
{
|
||||
if (_target == null)
|
||||
return;
|
||||
|
||||
OnBodyPartSelected?.Invoke(null, _target.Value);
|
||||
}
|
||||
|
||||
public void SetActiveButtons(bool isHumanoid)
|
||||
{
|
||||
foreach (var button in _bodyPartControls)
|
||||
button.Value.Visible = isHumanoid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the Body Doll using Alert Entity to use in Health Analyzer.
|
||||
/// </summary>
|
||||
private EntityUid? SetupIcon(Dictionary<TargetBodyPart, TargetIntegrity>? body)
|
||||
{
|
||||
if (body is null)
|
||||
return null;
|
||||
|
||||
if (!_entityManager.Deleted(_spriteViewEntity))
|
||||
_entityManager.QueueDeleteEntity(_spriteViewEntity);
|
||||
|
||||
_spriteViewEntity = _entityManager.Spawn(_bodyView);
|
||||
|
||||
if (!_entityManager.TryGetComponent<SpriteComponent>(_spriteViewEntity, out var sprite))
|
||||
return null;
|
||||
|
||||
int layer = 0;
|
||||
foreach (var (bodyPart, integrity) in body)
|
||||
{
|
||||
// TODO: PartStatusUIController and make it use layers instead of TextureRects when EE refactors alerts.
|
||||
string enumName = Enum.GetName(typeof(TargetBodyPart), bodyPart) ?? "Unknown";
|
||||
int enumValue = (int) integrity;
|
||||
var rsi = new SpriteSpecifier.Rsi(new ResPath($"/Textures/_Shitmed/Interface/Targeting/Status/{enumName.ToLowerInvariant()}.rsi"), $"{enumName.ToLowerInvariant()}_{enumValue}");
|
||||
// Shitcode with love from Russia :)
|
||||
if (!_spriteSystem.TryGetLayer(_spriteViewEntity, layer, out _, false))
|
||||
_spriteSystem.AddTextureLayer(_spriteViewEntity, _spriteSystem.Frame0(rsi));
|
||||
else
|
||||
_spriteSystem.LayerSetTexture(_spriteViewEntity, layer, _spriteSystem.Frame0(rsi));
|
||||
_spriteSystem.LayerSetScale(_spriteViewEntity, layer, new Vector2(3f, 3f));
|
||||
layer++;
|
||||
}
|
||||
return _spriteViewEntity;
|
||||
}
|
||||
// Shitmed Change End
|
||||
|
||||
private Texture GetTexture(string texture)
|
||||
{
|
||||
var rsiPath = new ResPath("/Textures/Objects/Devices/health_analyzer.rsi");
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:ui="clr-namespace:Content.Client.HealthAnalyzer.UI"
|
||||
MaxHeight="525"
|
||||
MinWidth="350"> <!-- Shitmed Change -->
|
||||
MinWidth="300">
|
||||
<ScrollContainer
|
||||
Margin="5 5 5 5"
|
||||
ReturnMeasure="True"
|
||||
|
|
@ -11,6 +11,6 @@
|
|||
|
||||
<ui:HealthAnalyzerControl
|
||||
Name="HealthAnalyzer"
|
||||
Access="Public" /> <!-- DeltaV / Shitmed Change - Make Public-->
|
||||
Access="Public" /> <!-- DeltaV -->
|
||||
</ScrollContainer>
|
||||
</controls:FancyWindow>
|
||||
|
|
|
|||
|
|
@ -88,8 +88,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
|||
foreach (var (key, info) in component.CustomBaseLayers)
|
||||
{
|
||||
oldLayers.Remove(key);
|
||||
// Shitmed Change: For whatever reason these weren't actually ignoring the skin color as advertised.
|
||||
SetLayerData(entity, key, info.Id, sexMorph: false, color: info.Color, overrideSkin: true);
|
||||
SetLayerData(entity, key, info.Id, sexMorph: false, color: info.Color);
|
||||
}
|
||||
|
||||
// hide old layers
|
||||
|
|
@ -106,8 +105,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
|||
HumanoidVisualLayers key,
|
||||
string? protoId,
|
||||
bool sexMorph = false,
|
||||
Color? color = null,
|
||||
bool overrideSkin = false) // Shitmed Change
|
||||
Color? color = null)
|
||||
{
|
||||
var component = entity.Comp1;
|
||||
var sprite = entity.Comp2;
|
||||
|
|
@ -128,7 +126,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
|
|||
var proto = _prototypeManager.Index<HumanoidSpeciesSpriteLayer>(protoId);
|
||||
component.BaseLayers[key] = proto;
|
||||
|
||||
if (proto.MatchSkin && !overrideSkin) // Shitmed Change
|
||||
if (proto.MatchSkin)
|
||||
layer.Color = component.SkinColor.WithAlpha(proto.LayerAlpha);
|
||||
|
||||
if (proto.BaseSprite != null)
|
||||
|
|
|
|||
|
|
@ -98,18 +98,6 @@ namespace Content.Client.Input
|
|||
human.AddFunction(ContentKeyFunctions.Arcade1);
|
||||
human.AddFunction(ContentKeyFunctions.Arcade2);
|
||||
human.AddFunction(ContentKeyFunctions.Arcade3);
|
||||
// Shitmed Change Start - TODO: Add hands, feet and groin targeting.
|
||||
human.AddFunction(ContentKeyFunctions.TargetHead);
|
||||
human.AddFunction(ContentKeyFunctions.TargetTorso);
|
||||
human.AddFunction(ContentKeyFunctions.TargetLeftArm);
|
||||
human.AddFunction(ContentKeyFunctions.TargetLeftHand);
|
||||
human.AddFunction(ContentKeyFunctions.TargetRightArm);
|
||||
human.AddFunction(ContentKeyFunctions.TargetRightHand);
|
||||
human.AddFunction(ContentKeyFunctions.TargetLeftLeg);
|
||||
human.AddFunction(ContentKeyFunctions.TargetLeftFoot);
|
||||
human.AddFunction(ContentKeyFunctions.TargetRightLeg);
|
||||
human.AddFunction(ContentKeyFunctions.TargetRightFoot);
|
||||
// Shitmed Change End
|
||||
|
||||
// actions should be common (for ghosts, mobs, etc)
|
||||
common.AddFunction(ContentKeyFunctions.OpenActionsMenu);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ using Content.Shared.Interaction;
|
|||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Inventory.Events;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared._Shitmed.Targeting.Events; // Shitmed
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ public sealed class ContentEyeSystem : SharedContentEyeSystem
|
|||
while (eyeEntities.MoveNext(out var entity, out ContentEyeComponent? contentComponent, out EyeComponent? eyeComponent))
|
||||
{
|
||||
UpdateEyeOffset((entity, eyeComponent));
|
||||
// ES START
|
||||
UpdateEyeRotation((entity, eyeComponent));
|
||||
// ES END
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +74,9 @@ public sealed class ContentEyeSystem : SharedContentEyeSystem
|
|||
while (eyeEntities.MoveNext(out var entity, out ContentEyeComponent? contentComponent, out EyeComponent? eyeComponent))
|
||||
{
|
||||
UpdateEyeOffset((entity, eyeComponent));
|
||||
// ES START
|
||||
UpdateEyeRotation((entity, eyeComponent));
|
||||
// ES END
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
<Label Text="{Loc 'ui-options-accessability-header-visuals'}"
|
||||
StyleClasses="LabelKeyText"/>
|
||||
<CheckBox Name="ReducedMotionCheckBox" Text="{Loc 'ui-options-reduced-motion'}" />
|
||||
<CheckBox Name="DisableScreenshakeCheckBox" Text="{Loc 'ui-options-es-screen-shake-toggle'}" /> <!-- DeltaV - ES Screenshake Port -->
|
||||
<CheckBox Name="EnableColorNameCheckBox" Text="{Loc 'ui-options-enable-color-name'}" />
|
||||
<CheckBox Name="ColorblindFriendlyCheckBox" Text="{Loc 'ui-options-colorblind-friendly'}" />
|
||||
<ui:OptionSlider Name="ScreenShakeIntensitySlider" Title="{Loc 'ui-options-screen-shake-intensity'}" />
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using Content.Shared._DV.CCVars; // DeltaV - ES Screenshake Port
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface;
|
||||
|
|
@ -15,6 +16,7 @@ public sealed partial class AccessibilityTab : Control
|
|||
Control.AddOptionCheckBox(CCVars.ChatEnableColorName, EnableColorNameCheckBox);
|
||||
Control.AddOptionCheckBox(CCVars.AccessibilityColorblindFriendly, ColorblindFriendlyCheckBox);
|
||||
Control.AddOptionCheckBox(CCVars.ReducedMotion, ReducedMotionCheckBox);
|
||||
Control.AddOptionCheckBox(DCCVars.EsScreenshakeDisabled, DisableScreenshakeCheckBox); // DeltaV - ES Screenshake Port
|
||||
Control.AddOptionPercentSlider(CCVars.ScreenShakeIntensity, ScreenShakeIntensitySlider);
|
||||
Control.AddOptionPercentSlider(CCVars.ChatWindowOpacity, ChatWindowOpacitySlider);
|
||||
Control.AddOptionPercentSlider(CCVars.SpeechBubbleTextOpacity, SpeechBubbleTextOpacitySlider);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using System.Numerics;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Shared._Goobstation.CCVar; // GoobStation
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.Input;
|
||||
using Robust.Client.AutoGenerated;
|
||||
|
|
@ -244,20 +243,6 @@ namespace Content.Client.Options.UI.Tabs
|
|||
AddButton(ContentKeyFunctions.NanoChatNavigateDownUnread);
|
||||
// DeltaV - End NanoChat keybinds
|
||||
|
||||
// Shitmed Change Start - TODO: Add hands, feet and groin targeting.
|
||||
AddHeader("ui-options-header-targeting");
|
||||
AddButton(ContentKeyFunctions.TargetHead);
|
||||
AddButton(ContentKeyFunctions.TargetTorso);
|
||||
AddButton(ContentKeyFunctions.TargetLeftArm);
|
||||
AddButton(ContentKeyFunctions.TargetLeftHand);
|
||||
AddButton(ContentKeyFunctions.TargetRightArm);
|
||||
AddButton(ContentKeyFunctions.TargetRightHand);
|
||||
AddButton(ContentKeyFunctions.TargetLeftLeg);
|
||||
AddButton(ContentKeyFunctions.TargetLeftFoot);
|
||||
AddButton(ContentKeyFunctions.TargetRightLeg);
|
||||
AddButton(ContentKeyFunctions.TargetRightFoot);
|
||||
// Shitmed Change End
|
||||
|
||||
AddHeader("ui-options-header-misc");
|
||||
AddButton(ContentKeyFunctions.TakeScreenshot);
|
||||
AddButton(ContentKeyFunctions.TakeScreenshotNoUI);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Content.Client.CartridgeLoader;
|
||||
using Content.Shared._DV.Pager; // DeltaV - pagers
|
||||
using Content.Shared.CartridgeLoader;
|
||||
using Content.Shared.Containers.ItemSlots;
|
||||
using Content.Shared.PDA;
|
||||
|
|
@ -72,6 +73,13 @@ namespace Content.Client.PDA
|
|||
SendMessage(new PdaLockUplinkMessage());
|
||||
};
|
||||
|
||||
// Begin DeltaV - pagers
|
||||
_menu.OnUnlinkDevicePressed += address =>
|
||||
{
|
||||
SendMessage(new PagerRemoveAddressMessage(address));
|
||||
};
|
||||
// End DeltaV - pagers
|
||||
|
||||
_menu.OnProgramItemPressed += ActivateCartridge;
|
||||
_menu.OnInstallButtonPressed += InstallCartridge;
|
||||
_menu.OnUninstallButtonPressed += UninstallCartridge;
|
||||
|
|
@ -100,6 +108,7 @@ namespace Content.Client.PDA
|
|||
}
|
||||
|
||||
_menu.UpdateState(updateState);
|
||||
UpdateLinkedDevices(); // DeltaV - pagers
|
||||
}
|
||||
|
||||
protected override void AttachCartridgeUI(Control cartridgeUIFragment, string? title)
|
||||
|
|
@ -127,5 +136,13 @@ namespace Content.Client.PDA
|
|||
{
|
||||
return EntMan.GetComponentOrNull<PdaBorderColorComponent>(Owner);
|
||||
}
|
||||
|
||||
// Begin DeltaV - pagers
|
||||
public void UpdateLinkedDevices()
|
||||
{
|
||||
if (EntMan.TryGetComponent<PagerComponent>(Owner, out var receiver))
|
||||
_menu?.UpdateLinkedDevices(receiver.Devices);
|
||||
}
|
||||
// End DeltaV - pagers
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,6 +70,12 @@
|
|||
Access="Public"
|
||||
Text="{Loc 'comp-pda-ui-ringtone-button'}"
|
||||
Description="{Loc 'comp-pda-ui-ringtone-button-description'}"/>
|
||||
<!-- Begin DeltaV Additions: Pagers -->
|
||||
<pda:PdaSettingsButton Name="LinkedDevicesButton"
|
||||
Access="Public"
|
||||
Text="{Loc 'comp-pda-ui-linked-devices-button'}"
|
||||
Description="{Loc 'comp-pda-ui-linked-devices-description'}"/>
|
||||
<!-- End DeltaV Additions: Pagers -->
|
||||
<pda:PdaSettingsButton Name="ActivateMusicButton"
|
||||
Access="Public"
|
||||
Visible="False"
|
||||
|
|
@ -92,6 +98,13 @@
|
|||
HorizontalExpand="True"
|
||||
Name="ProgramView"
|
||||
Access="Public">
|
||||
<!-- Begin DeltaV Additions: Pagers -->
|
||||
<BoxContainer Orientation="Vertical"
|
||||
VerticalExpand="True"
|
||||
HorizontalExpand="True"
|
||||
Name="LinkedDeviceList"
|
||||
Visible="False"/>
|
||||
<!-- End DeltaV Additions: Pagers -->
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
<BoxContainer Name="ContentFooter" HorizontalExpand="True" SetHeight="28" Margin="1 0 2 1">
|
||||
|
|
|
|||
|
|
@ -131,6 +131,12 @@ namespace Content.Client.PDA
|
|||
{
|
||||
_clipboard.SetText(_currentDate);
|
||||
};
|
||||
|
||||
LinkedDevicesButton.OnPressed += _ =>
|
||||
{
|
||||
LinkedDeviceList.Visible = true;
|
||||
ToProgramView(Loc.GetString("comp-pda-ui-linked-devices-title"));
|
||||
};
|
||||
// End DeltaV additions
|
||||
|
||||
|
||||
|
|
@ -300,6 +306,7 @@ namespace Content.Client.PDA
|
|||
ProgramCloseButton.Visible = false;
|
||||
ProgramListButton.Visible = true;
|
||||
SettingsButton.Visible = true;
|
||||
LinkedDeviceList.Visible = false; // DeltaV - pagers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ public sealed class SSDIndicatorSystem : EntitySystem
|
|||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly Shared.SSDIndicator.SSDIndicatorSystem _shared = default!; // DeltaV - SSD Recency, don't want to rename the upstream class
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
|
@ -35,13 +36,26 @@ public sealed class SSDIndicatorSystem : EntitySystem
|
|||
!HasComp<ActiveNPCComponent>(uid) &&
|
||||
HasComp<MindExaminableComponent>(uid))
|
||||
{
|
||||
// Begin DeltaV Addition
|
||||
// Begin DeltaV Additions
|
||||
var ev = new ShowSSDIndicatorEvent();
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
if (ev.Hidden)
|
||||
return;
|
||||
// End DeltaV Addition
|
||||
args.StatusIcons.Add(_prototype.Index(component.Icon));
|
||||
|
||||
// SSD Recency Indicator
|
||||
var stage = _shared.GetStage(new Entity<SSDIndicatorComponent>(uid, component));
|
||||
var icon = stage switch
|
||||
{
|
||||
SsdStage.VeryRecent => component.VeryRecentIcon,
|
||||
SsdStage.Recent => component.RecentIcon,
|
||||
SsdStage.Cryoable => component.Icon,
|
||||
_ => throw new InvalidOperationException($"{ToPrettyString(uid)} has an invalid SSD stage {stage}."),
|
||||
};
|
||||
|
||||
args.StatusIcons.Add(_prototype.Index(icon));
|
||||
// End DeltaV Additions
|
||||
|
||||
// args.StatusIcons.Add(_prototype.Index(component.Icon)); // DeltaV - commented out. status icon now added above
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using Content.Shared.Movement.Components;
|
||||
using Content.Client.PDA; // DeltaV
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Silicons.Borgs;
|
||||
using Content.Shared.Silicons.Borgs.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
|
|
@ -66,6 +67,15 @@ public sealed partial class BorgSwitchableTypeSystem : SharedBorgSwitchableTypeS
|
|||
}
|
||||
}
|
||||
|
||||
// DeltaV - borg pdas
|
||||
if (TryComp<PdaBorderColorComponent>(entity, out var pdaBorders))
|
||||
{
|
||||
pdaBorders.BorderColor = prototype.PdaBorderColor ?? pdaBorders.BorderColor;
|
||||
pdaBorders.AccentHColor = prototype.PdaAccentHorizontalColor ?? pdaBorders.AccentHColor;
|
||||
pdaBorders.AccentVColor = prototype.PdaAccentVerticalColor ?? pdaBorders.AccentVColor;
|
||||
}
|
||||
// DeltaV - borg pdas
|
||||
|
||||
base.UpdateEntityAppearance(entity, prototype);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
using System.Numerics;
|
||||
using Content.Shared._DV.CCVars; // DeltaV - Enable Stars via CVar.
|
||||
using Content.Shared.CombatMode;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Stunnable;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.Configuration; // DeltaV - Enable Stars via CVar.
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.Random;
|
||||
|
|
@ -13,6 +15,7 @@ namespace Content.Client.Stunnable;
|
|||
|
||||
public sealed class StunSystem : SharedStunSystem
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _cfg = default!; // DeltaV - Enable Stars via CVar.
|
||||
[Dependency] private readonly SharedCombatModeSystem _combat = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SpriteSystem _spriteSystem = default!;
|
||||
|
|
@ -78,6 +81,9 @@ public sealed class StunSystem : SharedStunSystem
|
|||
|
||||
var visible = Appearance.TryGetData<bool>(entity, StunVisuals.SeeingStars, out var stars) && stars;
|
||||
|
||||
if (visible && !_cfg.GetCVar(DCCVars.ShowStunVisuals)) // DeltaV - Enable Stars via CVar.
|
||||
visible = false;
|
||||
|
||||
_spriteSystem.LayerSetVisible((entity, entity.Comp), index, visible);
|
||||
_spriteSystem.LayerSetRsiState((entity, entity.Comp), index, state);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1759,60 +1759,6 @@ namespace Content.Client.Stylesheets
|
|||
.Prop(Control.StylePropertyModulateSelf, JusticeColorHovered),
|
||||
// End DeltaV
|
||||
|
||||
// Shitmed Change Start
|
||||
Element<TextureButton>().Class("TargetDollButtonHead")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/head_hover.png")),
|
||||
|
||||
Element<TextureButton>().Class("TargetDollButtonChest")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/torso_hover.png")),
|
||||
|
||||
Element<TextureButton>().Class("TargetDollButtonGroin")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/groin_hover.png")),
|
||||
|
||||
Element<TextureButton>().Class("TargetDollButtonLeftArm")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/leftarm_hover.png")),
|
||||
|
||||
Element<TextureButton>().Class("TargetDollButtonLeftHand")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/lefthand_hover.png")),
|
||||
|
||||
Element<TextureButton>().Class("TargetDollButtonRightArm")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/rightarm_hover.png")),
|
||||
|
||||
Element<TextureButton>().Class("TargetDollButtonRightHand")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/righthand_hover.png")),
|
||||
|
||||
Element<TextureButton>().Class("TargetDollButtonLeftLeg")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/leftleg_hover.png")),
|
||||
|
||||
Element<TextureButton>().Class("TargetDollButtonLeftFoot")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/leftfoot_hover.png")),
|
||||
|
||||
Element<TextureButton>().Class("TargetDollButtonRightLeg")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/rightleg_hover.png")),
|
||||
|
||||
Element<TextureButton>().Class("TargetDollButtonRightFoot")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/rightfoot_hover.png")),
|
||||
|
||||
Element<TextureButton>().Class("TargetDollButtonEyes")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/eyes_hover.png")),
|
||||
|
||||
Element<TextureButton>().Class("TargetDollButtonMouth")
|
||||
.Pseudo(TextureButton.StylePseudoClassHover)
|
||||
.Prop(TextureButton.StylePropertyTexture, resCache.GetTexture("/Textures/_Shitmed/Interface/Targeting/Doll/mouth_hover.png")),
|
||||
// Shitmed Change End
|
||||
|
||||
// Silicon law edit ui
|
||||
Element<Label>().Class(SiliconLawContainer.StyleClassSiliconLawPositionLabel)
|
||||
.Prop(Label.StylePropertyFontColor, NanoGold),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
xmlns:hotbar="clr-namespace:Content.Client.UserInterface.Systems.Hotbar.Widgets"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:inventory="clr-namespace:Content.Client.UserInterface.Systems.Inventory.Widgets"
|
||||
xmlns:targeting="clr-namespace:Content.Client._Shitmed.UserInterface.Systems.Targeting.Widgets"
|
||||
Name="DefaultHud"
|
||||
VerticalExpand="False"
|
||||
VerticalAlignment="Bottom"
|
||||
|
|
@ -29,7 +28,6 @@
|
|||
<widgets:GhostGui Name="Ghost" Access="Protected" />
|
||||
<inventory:InventoryGui Name="Inventory" Access="Protected" />
|
||||
<hotbar:HotbarGui Name="Hotbar" Access="Protected" />
|
||||
<targeting:TargetingControl Name="Targeting" Access="Protected"/> <!-- Shitmed Change -->
|
||||
<chat:ResizableChatBox Name="Chat" Access="Protected" />
|
||||
<alerts:AlertsUI Name="Alerts" Access="Protected" />
|
||||
</screens:DefaultGameScreen>
|
||||
|
|
|
|||
|
|
@ -22,12 +22,11 @@ public sealed partial class DefaultGameScreen : InGameScreen
|
|||
SetAnchorAndMarginPreset(Hotbar, LayoutPreset.BottomWide, margin: 5);
|
||||
SetAnchorAndMarginPreset(Chat, LayoutPreset.TopRight, margin: 10);
|
||||
SetAnchorAndMarginPreset(Alerts, LayoutPreset.TopRight, margin: 10);
|
||||
SetAnchorAndMarginPreset(Targeting, LayoutPreset.BottomRight, margin: 5); // Shitmed Change
|
||||
|
||||
Chat.OnResized += ChatOnResized;
|
||||
Chat.OnChatResizeFinish += ChatOnResizeFinish;
|
||||
|
||||
MainViewport.OnResized += ResizeActionContainer;
|
||||
MainViewport.OnResized += ResizeAlertsContainer;
|
||||
Inventory.OnResized += ResizeActionContainer;
|
||||
}
|
||||
|
||||
|
|
@ -37,12 +36,6 @@ public sealed partial class DefaultGameScreen : InGameScreen
|
|||
Actions.ActionsContainer.MaxGridHeight = MainViewport.Size.Y - indent;
|
||||
}
|
||||
|
||||
private void ResizeAlertsContainer()
|
||||
{
|
||||
float indent = Chat.Size.Y + Targeting.Size.Y + 120;
|
||||
Alerts.AlertContainer.MaxGridHeight = Math.Max(MainViewport.Size.Y - indent, 1);
|
||||
}
|
||||
|
||||
private void ChatOnResizeFinish(Vector2 _)
|
||||
{
|
||||
var marginBottom = Chat.GetValue<float>(MarginBottomProperty);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
xmlns:inventory="clr-namespace:Content.Client.UserInterface.Systems.Inventory.Widgets"
|
||||
xmlns:targeting="clr-namespace:Content.Client._Shitmed.UserInterface.Systems.Targeting.Widgets"
|
||||
Name="SeparatedChatHud"
|
||||
VerticalExpand="False"
|
||||
VerticalAlignment="Bottom"
|
||||
|
|
@ -21,9 +20,8 @@
|
|||
<widgets:GhostGui Name="Ghost" Access="Protected" />
|
||||
<inventory:InventoryGui Name="Inventory" Access="Protected"/>
|
||||
<hotbar:HotbarGui Name="Hotbar" Access="Protected"/>
|
||||
<targeting:TargetingControl Name="Targeting" Access="Protected"/> <!-- Shitmed Change -->
|
||||
<BoxContainer Name="TopLeftContainer" Orientation="Horizontal"> <!--goobstation-->
|
||||
<actions:ActionsBar Name="Actions" Access="Protected" />
|
||||
<BoxContainer Name="TopLeftContainer" Orientation="Vertical">
|
||||
<actions:ActionsBar Name="Actions" Access="Protected" />
|
||||
<BoxContainer Name="VoteMenu" Access="Public" Orientation="Vertical"/>
|
||||
</BoxContainer>
|
||||
<alerts:AlertsUI Name="Alerts" Access="Protected" />
|
||||
|
|
|
|||
|
|
@ -27,8 +27,7 @@ public sealed partial class SeparatedChatGameScreen : InGameScreen
|
|||
SetAnchorAndMarginPreset(Ghost, LayoutPreset.BottomWide, margin: 80);
|
||||
SetAnchorAndMarginPreset(Hotbar, LayoutPreset.BottomWide, margin: 5);
|
||||
SetAnchorAndMarginPreset(Alerts, LayoutPreset.CenterRight, margin: 10);
|
||||
SetAnchorAndMarginPreset(Targeting, LayoutPreset.BottomRight, margin: 5);
|
||||
|
||||
|
||||
ScreenContainer.OnSplitResizeFinished += () =>
|
||||
OnChatResized?.Invoke(new Vector2(ScreenContainer.SplitFraction, 0));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,7 @@
|
|||
<widgets:AlertsUI xmlns="https://spacestation14.io"
|
||||
xmlns:widgets="clr-namespace:Content.Client.UserInterface.Systems.Alerts.Widgets"
|
||||
xmlns:partStatus="clr-namespace:Content.Client._Shitmed.UserInterface.Systems.PartStatus.Widgets"
|
||||
MinSize="64 64">
|
||||
<!-- Shitmed Change Start - TODO: Refactor this godforsaken abomination -->
|
||||
<GridContainer Columns="1" HorizontalAlignment="Right" VerticalAlignment="Top">
|
||||
<PanelContainer >
|
||||
<GridContainer Name="AlertContainer" Columns="1" HorizontalAlignment="Right" VerticalAlignment="Center" Access="Public" />
|
||||
</PanelContainer>
|
||||
<partStatus:PartStatusControl Name="PartStatus" Access="Protected"/>
|
||||
</GridContainer>
|
||||
<!-- Shitmed Change End -->
|
||||
<PanelContainer HorizontalAlignment="Right" VerticalAlignment="Top">
|
||||
<BoxContainer Name="AlertContainer" Access="Public" Orientation="Vertical" />
|
||||
</PanelContainer>
|
||||
</widgets:AlertsUI>
|
||||
|
|
|
|||
|
|
@ -280,7 +280,10 @@ public sealed partial class GunSystem : SharedGunSystem
|
|||
if (!Timing.IsFirstTimePredicted || user == null || recoil == Vector2.Zero || recoilScalar == 0)
|
||||
return;
|
||||
|
||||
_recoil.KickCamera(user.Value, recoil.Normalized() * 0.5f * recoilScalar);
|
||||
// ES START
|
||||
// reduce recoil even further
|
||||
_recoil.KickCamera(user.Value, recoil.Normalized() * 0.13f * recoilScalar);
|
||||
// ES END
|
||||
}
|
||||
|
||||
protected override void Popup(string message, EntityUid? uid, EntityUid? user)
|
||||
|
|
|
|||
|
|
@ -23,16 +23,20 @@ public sealed class AACBoundUserInterface : BoundUserInterface
|
|||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
_window?.Close();
|
||||
|
||||
if (_window is { Disposed: false })
|
||||
_window.Close();
|
||||
|
||||
_window = this.CreateWindow<AACWindow>();
|
||||
_window.OnClose += Close;
|
||||
_window.PhraseButtonPressed += OnPhraseButtonPressed;
|
||||
_window.Typing += OnTyping;
|
||||
_window.SubmitPressed += OnSubmit;
|
||||
}
|
||||
|
||||
private void OnPhraseButtonPressed(List<ProtoId<QuickPhrasePrototype>> phraseId)
|
||||
private void OnPhraseButtonPressed(List<ProtoId<QuickPhrasePrototype>> phraseId, string prefix)
|
||||
{
|
||||
SendMessage(new AACTabletSendPhraseMessage(phraseId));
|
||||
SendMessage(new AACTabletSendPhraseMessage(phraseId, prefix));
|
||||
}
|
||||
|
||||
private void OnTyping()
|
||||
|
|
@ -46,4 +50,14 @@ public sealed class AACBoundUserInterface : BoundUserInterface
|
|||
_typing ??= EntMan.System<TypingIndicatorSystem>();
|
||||
_typing?.ClientSubmittedChatText();
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (state is not AACTabletBuiState msg)
|
||||
return;
|
||||
|
||||
_window?.Update(msg);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,14 @@
|
|||
StyleClasses="AacCheckbox"
|
||||
Margin="0 0 8 0"/>
|
||||
<Control HorizontalExpand="True"/>
|
||||
</BoxContainer>
|
||||
|
||||
<Control SetWidth="170" Margin="8 0 0 0"/>
|
||||
|
||||
<OptionButton Name="RadioChannels"
|
||||
StyleClasses="OpenBoth"
|
||||
SetWidth="120"
|
||||
Margin="8 0 0 0"/>
|
||||
</BoxContainer>
|
||||
|
||||
<!-- Buffer Display and Controls -->
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
|
|
@ -29,7 +36,6 @@
|
|||
StyleClasses="AacBufferText"
|
||||
Margin="8 4"/>
|
||||
</PanelContainer>
|
||||
|
||||
<Button Name="ClearButton"
|
||||
Text="{Loc 'aac-tablet-backspace'}"
|
||||
TextAlign="Center"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ using System.Linq;
|
|||
using System.Numerics;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared._DV.QuickPhrase;
|
||||
using Content.Shared._DV.AACTablet;
|
||||
using Content.Shared.Chat;
|
||||
using Content.Shared.Radio;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
|
|
@ -16,7 +19,7 @@ public sealed partial class AACWindow : FancyWindow
|
|||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
private readonly List<QuickPhrasePrototype> _phrases;
|
||||
private readonly Dictionary<string, List<QuickPhrasePrototype>> _filteredPhrases = new();
|
||||
public event Action<List<ProtoId<QuickPhrasePrototype>>>? PhraseButtonPressed;
|
||||
public event Action<List<ProtoId<QuickPhrasePrototype>>, string>? PhraseButtonPressed;
|
||||
public event Action? Typing;
|
||||
public event Action? SubmitPressed;
|
||||
|
||||
|
|
@ -42,10 +45,16 @@ public sealed partial class AACWindow : FancyWindow
|
|||
SearchBar.OnTextChanged += FilterSearch;
|
||||
SendButton.OnPressed += SendBuffer;
|
||||
ClearButton.OnPressed += BackspaceBuffer;
|
||||
RadioChannels.OnItemSelected += OnChannelSelected;
|
||||
PopulateGui();
|
||||
FilterSearch(null);
|
||||
}
|
||||
|
||||
private void OnChannelSelected(OptionButton.ItemSelectedEventArgs args)
|
||||
{
|
||||
RadioChannels.SelectId(args.Id);
|
||||
}
|
||||
|
||||
private void BackspaceBuffer(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
if (_phraseBuffer.Count == 0)
|
||||
|
|
@ -68,12 +77,14 @@ public sealed partial class AACWindow : FancyWindow
|
|||
|
||||
private void SendBuffer(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
PhraseButtonPressed?.Invoke(_phraseBuffer);
|
||||
PhraseButtonPressed?.Invoke(_phraseBuffer, Prefix);
|
||||
_phraseBuffer.Clear();
|
||||
BufferedString.Text = string.Empty;
|
||||
SubmitPressed?.Invoke();
|
||||
}
|
||||
|
||||
private string Prefix => (string?)RadioChannels.SelectedMetadata ?? SharedChatSystem.LocalPrefix.ToString();
|
||||
|
||||
private void FilterSearch(LineEdit.LineEditEventArgs? obj)
|
||||
{
|
||||
SearchResults.RemoveAllChildren();
|
||||
|
|
@ -82,7 +93,8 @@ public sealed partial class AACWindow : FancyWindow
|
|||
var emptySearch = string.IsNullOrEmpty(SearchBar.Text);
|
||||
foreach (var phrase in _phrases)
|
||||
{
|
||||
if (!emptySearch && !Loc.GetString(phrase.Text).Contains(SearchBar.Text, StringComparison.CurrentCultureIgnoreCase))
|
||||
if (!emptySearch && !Loc.GetString(phrase.Text)
|
||||
.Contains(SearchBar.Text, StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
@ -236,8 +248,24 @@ public sealed partial class AACWindow : FancyWindow
|
|||
{
|
||||
_phraseSingle.Clear();
|
||||
_phraseSingle.Add(phraseId);
|
||||
PhraseButtonPressed?.Invoke(_phraseSingle);
|
||||
PhraseButtonPressed?.Invoke(_phraseSingle, Prefix);
|
||||
SubmitPressed?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
internal void Update(AACTabletBuiState msg)
|
||||
{
|
||||
RadioChannels.Clear();
|
||||
|
||||
var id = 0;
|
||||
RadioChannels.AddItem("Local", id);
|
||||
RadioChannels.SetItemMetadata(RadioChannels.GetIdx(id), SharedChatSystem.LocalPrefix.ToString());
|
||||
|
||||
foreach (var channel in msg.RadioChannels)
|
||||
{
|
||||
var channelProto = _prototype.Index<RadioChannelPrototype>(channel);
|
||||
RadioChannels.AddItem(channelProto.LocalizedName, ++id);
|
||||
RadioChannels.SetItemMetadata(RadioChannels.GetIdx(id), string.Concat(SharedChatSystem.RadioChannelPrefix, channelProto.KeyCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
using Content.Shared._DV.Access.Systems;
|
||||
|
||||
namespace Content.Client._DV.Access.Systems;
|
||||
|
||||
/// <summary>
|
||||
/// Client side handling of the subdermal ID system.
|
||||
/// </summary>
|
||||
public sealed class SubdermalIdCardSystem : SharedSubdermalIdCardSystem;
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<ui:RadialMenu xmlns="https://spacestation14.io"
|
||||
xmlns:ui="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
BackButtonStyleClass="RadialMenuBackButton"
|
||||
CloseButtonStyleClass="RadialMenuCloseButton"
|
||||
VerticalExpand="True"
|
||||
HorizontalExpand="True"
|
||||
MinSize="450 450">
|
||||
|
||||
<ui:RadialContainer Name="Main" VerticalExpand="True" HorizontalExpand="True" InitialRadius="100" ReserveSpaceForHiddenChildren="False"/>
|
||||
</ui:RadialMenu>
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
using Content.Client.UserInterface.Controls;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Client.UserInterface;
|
||||
using Content.Shared.Storage;
|
||||
using System.Numerics;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Client._DV.Augments;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class AugmentToolPanelMenu : RadialMenu
|
||||
{
|
||||
[Dependency] private readonly EntityManager _entManager = default!;
|
||||
|
||||
public event Action<EntityUid?>? SendAugmentToolPanelSystemMessageAction;
|
||||
|
||||
private EntityUid _owner;
|
||||
|
||||
public AugmentToolPanelMenu()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public void SetEntity(EntityUid uid)
|
||||
{
|
||||
_owner = uid;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
if (!_entManager.TryGetComponent<StorageComponent>(_owner, out var storage))
|
||||
return;
|
||||
|
||||
foreach (var (entity, _) in storage.StoredItems)
|
||||
{
|
||||
var button = new RadialMenuButtonWithSector()
|
||||
{
|
||||
SetSize = new Vector2(64f, 64f),
|
||||
};
|
||||
|
||||
button.AddChild(new SpriteView(entity, _entManager)
|
||||
{
|
||||
Scale = new Vector2(3f, 3f),
|
||||
});
|
||||
Main.AddChild(button);
|
||||
|
||||
button.OnButtonUp += _ =>
|
||||
{
|
||||
SendAugmentToolPanelSystemMessageAction?.Invoke(entity);
|
||||
Close();
|
||||
};
|
||||
}
|
||||
|
||||
var nilButton = new RadialMenuButtonWithSector()
|
||||
{
|
||||
SetSize = new Vector2(64f, 64f),
|
||||
};
|
||||
|
||||
Main.AddChild(nilButton);
|
||||
|
||||
nilButton.OnButtonUp += _ =>
|
||||
{
|
||||
SendAugmentToolPanelSystemMessageAction?.Invoke(null);
|
||||
Close();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Shared._DV.Augments;
|
||||
|
||||
namespace Content.Client._DV.Augments;
|
||||
|
||||
public sealed class AugmentToolPanelMenuBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[Dependency] private readonly IClyde _displayManager = default!;
|
||||
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
|
||||
private AugmentToolPanelMenu? _menu;
|
||||
|
||||
public AugmentToolPanelMenuBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_menu = this.CreateWindow<AugmentToolPanelMenu>();
|
||||
_menu.SetEntity(Owner);
|
||||
_menu.SendAugmentToolPanelSystemMessageAction += SendAugmentToolPanelSystemMessage;
|
||||
|
||||
// Open the menu, centered on the mouse
|
||||
var vpSize = _displayManager.ScreenSize;
|
||||
_menu.OpenCenteredAt(_inputManager.MouseScreenPosition.Position / vpSize);
|
||||
}
|
||||
|
||||
public void SendAugmentToolPanelSystemMessage(EntityUid? desiredTool)
|
||||
{
|
||||
SendMessage(new AugmentToolPanelSystemMessage(_entMan.GetNetEntity(desiredTool)));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
using Content.Shared._DV.Body.Components;
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared.Clothing.EntitySystems;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client._DV.Body;
|
||||
|
||||
/// <summary>
|
||||
/// Colors feathers.
|
||||
/// </summary>
|
||||
public sealed class FeatherVisualizer : VisualizerSystem<FeatherComponent>
|
||||
{
|
||||
[Dependency] private readonly ClothingSystem _clothing = default!;
|
||||
|
||||
protected override void OnAppearanceChange(EntityUid uid, FeatherComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
if (!AppearanceSystem.TryGetData<Color>(uid, FeatherVisuals.FeatherColor, out var featherColor, args.Component))
|
||||
return;
|
||||
|
||||
SpriteSystem.LayerSetColor(uid, FeatherVisualLayers.Feather, featherColor);
|
||||
|
||||
if (TryComp<ClothingComponent>(uid, out var clothing))
|
||||
{
|
||||
foreach (var slotPair in clothing.ClothingVisuals)
|
||||
{
|
||||
_clothing.SetLayerColor(clothing, slotPair.Key, "feather", featherColor);
|
||||
}
|
||||
}
|
||||
|
||||
if (!AppearanceSystem.TryGetData<Color>(uid, FeatherVisuals.BloodColor, out var bloodColor, args.Component))
|
||||
return;
|
||||
|
||||
SpriteSystem.LayerSetColor(uid, FeatherVisualLayers.Blood, bloodColor);
|
||||
}
|
||||
}
|
||||
|
||||
public enum FeatherVisualLayers : byte
|
||||
{
|
||||
Feather,
|
||||
Blood,
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
StyleClasses="LabelKeyText"/>
|
||||
<CheckBox Name="DisableFiltersCheckBox" Text="{Loc 'ui-options-no-filters'}" />
|
||||
<CheckBox Name="DisableGlimmerEffectCheckBox" Text="{Loc 'ui-options-disable-glimmer-effect'}" />
|
||||
<CheckBox Name="EnableStunVisualsCheckBox" Text="{Loc 'ui-options-enable-stun-visuals'}" />
|
||||
<Label Text="{Loc 'ui-options-delta-tips'}"
|
||||
StyleClasses="LabelKeyText"/>
|
||||
<CheckBox Name="DisableTipsCheckBox" Text="{Loc 'ui-options-delta-disable-tips'}" />
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public sealed partial class DeltaTab : Control
|
|||
|
||||
Control.AddOptionCheckBox(DCCVars.NoVisionFilters, DisableFiltersCheckBox);
|
||||
Control.AddOptionCheckBox(DCCVars.DisableGlimmerShader, DisableGlimmerEffectCheckBox);
|
||||
Control.AddOptionCheckBox(DCCVars.ShowStunVisuals, EnableStunVisualsCheckBox);
|
||||
Control.AddOptionCheckBox(DCCVars.DisableTips, DisableTipsCheckBox);
|
||||
|
||||
ResetTipsButton.OnPressed += _ => OnResetTipsPressed();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
using Content.Client.PDA;
|
||||
using Content.Shared._DV.Pager;
|
||||
using Content.Shared.PDA;
|
||||
|
||||
namespace Content.Client._DV.PDA;
|
||||
|
||||
public sealed class ClientEventNotificationReceiverSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _userInterface = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<PagerComponent, AfterAutoHandleStateEvent>(OnAfterAutoHandleState);
|
||||
}
|
||||
|
||||
private void OnAfterAutoHandleState(Entity<PagerComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
if (!_userInterface.TryGetOpenUi<PdaBoundUserInterface>(ent.Owner, PdaUiKey.Key, out var bui))
|
||||
return;
|
||||
|
||||
bui.UpdateLinkedDevices();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<PanelContainer HorizontalExpand="True" xmlns="https://spacestation14.io">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="4">
|
||||
<Label Name="DeviceName" Access="Public" HorizontalExpand="True" />
|
||||
<Button Name="Unlink" Access="Public" StyleClasses="ButtonSmall" Text="{Loc 'comp-pda-ui-linked-devices-unlink'}"/>
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._DV.PDA;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class LinkedDeviceItem : PanelContainer
|
||||
{
|
||||
public LinkedDeviceItem()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
using Content.Client._DV.PDA;
|
||||
using Content.Client.Stylesheets;
|
||||
using System.Linq;
|
||||
|
||||
namespace Content.Client.PDA;
|
||||
|
||||
public sealed partial class PdaMenu
|
||||
{
|
||||
public event Action<string>? OnUnlinkDevicePressed;
|
||||
|
||||
public void UpdateLinkedDevices(Dictionary<string, string> devices)
|
||||
{
|
||||
LinkedDeviceList.RemoveAllChildren();
|
||||
|
||||
var even = false;
|
||||
foreach (var (address, name) in devices.OrderBy(kvp => kvp.Value))
|
||||
{
|
||||
var item = new LinkedDeviceItem()
|
||||
{
|
||||
DeviceName = { Text = name },
|
||||
};
|
||||
item.Unlink.OnPressed += _ => OnUnlinkDevicePressed?.Invoke(address);
|
||||
LinkedDeviceList.AddChild(item);
|
||||
LinkedDeviceList.StyleClasses.Add(even ? StyleClass.PanelDark : StyleClass.PanelLight);
|
||||
even = !even;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
using Content.Shared._DV.Pager;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
|
||||
namespace Content.Client._DV.Pager;
|
||||
|
||||
public sealed class PagerButtonSystem : SharedPagerButtonSystem
|
||||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
|
||||
|
||||
private const string AnimateKey = "pager-press";
|
||||
|
||||
protected override void AfterActivated(Entity<PagerButtonComponent> ent)
|
||||
{
|
||||
if (!_animationPlayer.HasRunningAnimation(ent.Owner, AnimateKey))
|
||||
_animationPlayer.Play(ent.Owner, GetAnimation(ent), AnimateKey);
|
||||
}
|
||||
|
||||
private Animation GetAnimation(Entity<PagerButtonComponent> ent)
|
||||
{
|
||||
const float flickDuration = 20f / 60f;
|
||||
|
||||
return new Animation()
|
||||
{
|
||||
Length = TimeSpan.FromSeconds(flickDuration),
|
||||
|
||||
AnimationTracks =
|
||||
{
|
||||
new AnimationTrackSpriteFlick()
|
||||
{
|
||||
LayerKey = PagerButtonVisualLayers.Base,
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackSpriteFlick.KeyFrame(ent.Comp.PressState, 0f),
|
||||
new AnimationTrackSpriteFlick.KeyFrame(ent.Comp.UnpressedState, flickDuration),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
using Content.Shared._DV.Silicon.IPC;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Humanoid.Markings;
|
||||
|
||||
namespace Content.Client._DV.Silicon.IPC;
|
||||
|
||||
public sealed class SnoutHelmetSystem : EntitySystem
|
||||
{
|
||||
private const MarkingCategories MarkingToQuery = MarkingCategories.Snout;
|
||||
private const int MaximumMarkingCount = 0;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SnoutHelmetComponent, ComponentStartup>(OnComponentStartup);
|
||||
}
|
||||
|
||||
private void OnComponentStartup(EntityUid uid, SnoutHelmetComponent component, ComponentStartup args)
|
||||
{
|
||||
if (TryComp(uid, out HumanoidAppearanceComponent? humanoidAppearanceComponent) &&
|
||||
humanoidAppearanceComponent.ClientOldMarkings.Markings.TryGetValue(MarkingToQuery, out var markings) &&
|
||||
markings.Count > MaximumMarkingCount)
|
||||
{
|
||||
component.EnableAlternateHelmet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
using Content.Client.Alerts;
|
||||
using Content.Shared._EE.Silicon.Components;
|
||||
using Content.Shared._EE.Silicon.Systems;
|
||||
|
||||
namespace Content.Client._DV.Silicon.Charge;
|
||||
|
||||
public sealed class SiliconChargeSystem : SharedSiliconChargeSystem
|
||||
{
|
||||
[Dependency] private readonly ClientAlertsSystem _alerts = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SiliconComponent, ComponentInit>(OnSiliconInit);
|
||||
SubscribeLocalEvent<SiliconComponent, SiliconChargeStateUpdateEvent>(OnSiliconChargeStateUpdate);
|
||||
}
|
||||
|
||||
private void OnSiliconInit(EntityUid uid, SiliconComponent component, ComponentInit args)
|
||||
{
|
||||
if (!component.BatteryPowered)
|
||||
return;
|
||||
|
||||
_alerts.ShowAlert(uid, component.BatteryAlert, component.ChargeState);
|
||||
}
|
||||
|
||||
private void OnSiliconChargeStateUpdate(EntityUid uid, SiliconComponent component, SiliconChargeStateUpdateEvent ev)
|
||||
{
|
||||
_alerts.ShowAlert(uid, component.BatteryAlert, ev.ChargePercent);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
using Content.Client.Alerts;
|
||||
using Content.Shared._EE.Silicon.Components;
|
||||
using Content.Shared._DV.Silicons.Charge;
|
||||
|
||||
namespace Content.Client._DV.Silicon.Charge;
|
||||
|
||||
public sealed class SiliconDrainSystem : SharedSiliconDrainSystem
|
||||
{
|
||||
[Dependency] private readonly ClientAlertsSystem _alerts = default!;
|
||||
|
||||
protected override void UpdateChargeIcon(Entity<SiliconComponent> ent, short chargePercent)
|
||||
{
|
||||
// If you can't find a battery, set the indicator and skip it.
|
||||
if (!TryGetSiliconBattery(ent, out _))
|
||||
{
|
||||
if (_alerts.IsShowingAlert(ent.Owner, ent.Comp.BatteryAlert))
|
||||
{
|
||||
_alerts.ClearAlert(ent.Owner, ent.Comp.BatteryAlert);
|
||||
_alerts.ShowAlert(ent.Owner, ent.Comp.NoBatteryAlert);
|
||||
}
|
||||
}
|
||||
// If the battery was replaced and the no battery indicator is showing, replace the indicator
|
||||
else if (_alerts.IsShowingAlert(ent.Owner, ent.Comp.NoBatteryAlert))
|
||||
{
|
||||
_alerts.ClearAlert(ent.Owner, ent.Comp.NoBatteryAlert);
|
||||
_alerts.ShowAlert(ent.Owner, ent.Comp.BatteryAlert, chargePercent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
using Content.Client.Items;
|
||||
using Content.Shared._DV.Surgery;
|
||||
using Content.Shared.Inventory;
|
||||
using Robust.Shared.Containers;
|
||||
|
||||
namespace Content.Client._DV.Surgery;
|
||||
|
||||
/// <summary>
|
||||
/// This shows the item status for dirty surgery tools.
|
||||
/// </summary>
|
||||
public sealed class SurgeryCleanStatusSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
Subs.ItemStatus<SurgeryDirtinessComponent>(ent => new SurgeryDirtinessItemStatus(ent, EntityManager, _inventory, _container));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
using System.Numerics;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared._DV.Surgery;
|
||||
using Content.Shared._Shitmed.Medical.Surgery.Tools;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Inventory;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client._DV.Surgery;
|
||||
|
||||
public sealed class SurgeryDirtinessItemStatus : SplitBar
|
||||
{
|
||||
private readonly IEntityManager _entMan;
|
||||
private readonly EntityUid _uid;
|
||||
private readonly InventorySystem _inventory;
|
||||
private readonly SharedContainerSystem _container;
|
||||
private FixedPoint2? _dirtiness = null;
|
||||
private FixedPoint2? _gloveDirtiness = null;
|
||||
|
||||
private static readonly Color SelfCleanColor = new Color(0xD1, 0xD5, 0xD9);
|
||||
private static readonly Color SelfDirtyColor = new Color(0xE9, 0x3D, 0x58);
|
||||
private static readonly Color GloveCleanColor = new Color(0xAB, 0xE9, 0xFB);
|
||||
private static readonly Color GloveDirtyColor = new Color(0xE9, 0x64, 0x3A);
|
||||
|
||||
public SurgeryDirtinessItemStatus(EntityUid uid, IEntityManager entMan, InventorySystem inventory, SharedContainerSystem container)
|
||||
{
|
||||
_uid = uid;
|
||||
_entMan = entMan;
|
||||
_inventory = inventory;
|
||||
_container = container;
|
||||
MinBarSize = new Vector2(10, 0);
|
||||
Margin = new Thickness(4);
|
||||
MinHeight = 16;
|
||||
MaxHeight = 16;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
|
||||
if (!_entMan.TryGetComponent<SurgeryDirtinessComponent>(_uid, out var comp))
|
||||
return;
|
||||
|
||||
var isTool = _entMan.HasComponent<SurgeryToolComponent>(_uid);
|
||||
|
||||
if (_dirtiness == comp.Dirtiness && !isTool)
|
||||
return;
|
||||
_dirtiness = comp.Dirtiness;
|
||||
|
||||
if (isTool && _container.TryGetContainingContainer((_uid, null, null), out var container))
|
||||
{
|
||||
var user = container.Owner;
|
||||
|
||||
FixedPoint2? glovesDirtiness =
|
||||
_inventory.TryGetSlotEntity(user, "gloves", out var gloves)
|
||||
? _entMan.TryGetComponent<SurgeryDirtinessComponent>(_uid, out var glovesComp)
|
||||
? glovesComp.Dirtiness
|
||||
: FixedPoint2.Zero
|
||||
: null;
|
||||
|
||||
if (glovesDirtiness is not null && _gloveDirtiness == glovesDirtiness)
|
||||
return;
|
||||
_gloveDirtiness = glovesDirtiness;
|
||||
|
||||
Clear();
|
||||
|
||||
var toolAmount = FixedPoint2.Min(_dirtiness.Value / 100, 1);
|
||||
var gloveAmount = FixedPoint2.Min((_gloveDirtiness ?? 0) / 100, 1);
|
||||
var remaining = 1 - toolAmount - gloveAmount;
|
||||
|
||||
var clean = (_dirtiness + (_gloveDirtiness ?? 0)) < 50;
|
||||
var maskOn = _inventory.TryGetSlotEntity(user, "mask", out var _);
|
||||
var isFine = clean && maskOn && _gloveDirtiness is not null;
|
||||
|
||||
if (toolAmount != FixedPoint2.Zero)
|
||||
AddEntry(toolAmount.Float() * 100, isFine ? SelfCleanColor : SelfDirtyColor);
|
||||
|
||||
if (gloveAmount != FixedPoint2.Zero)
|
||||
AddEntry(gloveAmount.Float() * 100, isFine ? GloveCleanColor : GloveDirtyColor);
|
||||
|
||||
if (remaining > FixedPoint2.Zero)
|
||||
AddEntry(remaining.Float() * 100, Color.SlateGray);
|
||||
}
|
||||
else
|
||||
{
|
||||
Clear();
|
||||
|
||||
var amount = FixedPoint2.Min(_dirtiness.Value / 100, 1);
|
||||
var remaining = 1 - amount;
|
||||
|
||||
if (amount != FixedPoint2.Zero)
|
||||
AddEntry(amount.Float(), amount < 0.5 ? SelfCleanColor : SelfDirtyColor);
|
||||
|
||||
if (remaining != FixedPoint2.Zero)
|
||||
AddEntry(remaining.Float(), Color.SlateGray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
using System.Numerics;
|
||||
using Content.Shared._DV.CCVars;
|
||||
using Content.Shared._ES.Camera;
|
||||
using Content.Shared.Camera;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Noise;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client._ES;
|
||||
|
||||
// DeltaV - Anything not marked DeltaV is Ephemeral Space code moved from SharedESScreenshakeSystem
|
||||
public sealed class ESScreenshakeSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IConfigurationManager _config = default!; // DeltaV
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly SharedESScreenshakeSystem _shared = default!;
|
||||
|
||||
private bool _disabled; // DeltaV
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<ESScreenshakeComponent, GetEyeOffsetEvent>(OnGetEyeOffset);
|
||||
SubscribeLocalEvent<ESScreenshakeComponent, ESGetEyeRotationEvent>(OnGetEyeRotation);
|
||||
|
||||
_config.OnValueChanged(DCCVars.EsScreenshakeDisabled, OnDisabledChanged, true); // DeltaV
|
||||
}
|
||||
private void OnDisabledChanged(bool obj)
|
||||
{
|
||||
_disabled = obj;
|
||||
}
|
||||
|
||||
private void OnGetEyeOffset(Entity<ESScreenshakeComponent> ent, ref GetEyeOffsetEvent args)
|
||||
{
|
||||
if (!TryComp<EyeComponent>(ent, out var eye) || _disabled) // DeltaV - check if disabled
|
||||
return;
|
||||
|
||||
var noise = new FastNoiseLite(67);
|
||||
noise.SetNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
|
||||
var accumulatedOffset = Vector2.Zero;
|
||||
var maxOffset = new Vector2(0.15f, 0.15f);
|
||||
foreach (var command in ent.Comp.Commands)
|
||||
{
|
||||
if (command.Translational == null)
|
||||
continue;
|
||||
|
||||
var trauma =
|
||||
_shared.CalculateTraumaValueForCurrentTime(command.Translational, command.Start);
|
||||
if (trauma <= 0)
|
||||
continue;
|
||||
|
||||
noise.SetFrequency(command.Translational.Frequency);
|
||||
|
||||
// using the starst c ommand for y pos kinda doesnt work in the case where multiple shakes get sent at the same time
|
||||
// and the shakes are identical otherwise. but like dont do that or something idk
|
||||
var offsetX = (maxOffset.X * trauma) * noise.GetNoise((float)_timing.RealTime.TotalMilliseconds,
|
||||
(float)command.Start.TotalMilliseconds);
|
||||
noise.SetSeed(68);
|
||||
var offsetY = (maxOffset.Y * trauma) * noise.GetNoise((float)_timing.RealTime.TotalMilliseconds,
|
||||
(float)command.Start.TotalMilliseconds);
|
||||
noise.SetSeed(67);
|
||||
accumulatedOffset += new Vector2(offsetX, offsetY);
|
||||
}
|
||||
|
||||
args.Offset += accumulatedOffset;
|
||||
}
|
||||
|
||||
private void OnGetEyeRotation(Entity<ESScreenshakeComponent> ent, ref ESGetEyeRotationEvent args)
|
||||
{
|
||||
if (!TryComp<EyeComponent>(ent, out var eye) || _disabled) // DeltaV - check if disabled
|
||||
return;
|
||||
|
||||
var noise = new FastNoiseLite(67 + 420); // Epic bacon
|
||||
noise.SetNoiseType(FastNoiseLite.NoiseType.OpenSimplex2);
|
||||
|
||||
// 20deg max
|
||||
var accumulatedAngle = Angle.Zero;
|
||||
var maxAngleDegrees = 20f;
|
||||
foreach (var command in ent.Comp.Commands)
|
||||
{
|
||||
if (command.Rotational == null)
|
||||
continue;
|
||||
|
||||
var trauma =
|
||||
_shared.CalculateTraumaValueForCurrentTime(command.Rotational, command.Start);
|
||||
if (trauma <= 0)
|
||||
continue;
|
||||
|
||||
noise.SetFrequency(command.Rotational.Frequency);
|
||||
|
||||
var angle = (maxAngleDegrees * trauma) * noise.GetNoise((float)_timing.RealTime.TotalMilliseconds, (float)command.Start.TotalMilliseconds);
|
||||
accumulatedAngle += Angle.FromDegrees(angle);
|
||||
}
|
||||
|
||||
// TODO ughhh this shit breaks with something idk
|
||||
args.Rotation += accumulatedAngle;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using Content.Shared._ES.Core.Timer.Components;
|
||||
|
||||
namespace Content.Client._ES.Lighting.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Handles a point light that fades out while synced to a <see cref="ESTimedDespawnComponent"/>
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
[Access(typeof(ESTimedDespawnLightFadeSystem))]
|
||||
public sealed partial class ESTimedDespawnLightFadeComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public TimeSpan FadeTime = TimeSpan.FromSeconds(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
using Content.Client._ES.Lighting.Components;
|
||||
using Content.Shared._ES.Core.Timer.Components;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client._ES.Lighting;
|
||||
|
||||
public sealed class ESTimedDespawnLightFadeSystem : VisualizerSystem<ESTimedDespawnLightFadeComponent>
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
|
||||
|
||||
private const string FadeTrack = "light-fade";
|
||||
|
||||
protected override void OnAppearanceChange(EntityUid uid, ESTimedDespawnLightFadeComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
base.OnAppearanceChange(uid, component, ref args);
|
||||
|
||||
if (_animationPlayer.HasRunningAnimation(uid, FadeTrack))
|
||||
return;
|
||||
|
||||
if (!AppearanceSystem.TryGetData<TimeSpan>(uid, ESTimedDespawnVisuals.DespawnTime, out var time, args.Component) ||
|
||||
!TryComp<PointLightComponent>(uid, out var light))
|
||||
return;
|
||||
|
||||
var duration = time - _timing.CurTime;
|
||||
|
||||
var animation = new Animation
|
||||
{
|
||||
Length = duration,
|
||||
AnimationTracks =
|
||||
{
|
||||
new AnimationTrackComponentProperty
|
||||
{
|
||||
Property = nameof(PointLightComponent.Energy),
|
||||
ComponentType = typeof(PointLightComponent),
|
||||
InterpolationMode = AnimationInterpolationMode.Linear,
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackProperty.KeyFrame(light.Energy, 0f),
|
||||
new AnimationTrackProperty.KeyFrame(light.Energy, (float) (duration - component.FadeTime).TotalSeconds),
|
||||
new AnimationTrackProperty.KeyFrame(0f, (float) component.FadeTime.TotalSeconds, Easings.OutSine),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_animationPlayer.Play(uid, animation, FadeTrack);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using Content.Shared._ES.Core.Timer.Components;
|
||||
|
||||
namespace Content.Client._ES.Sprite.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Handles a sprite that fades out while synced to a <see cref="ESTimedDespawnComponent"/>
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
[Access(typeof(ESTimedDespawnSpriteFadeSystem))]
|
||||
public sealed partial class ESTimedDespawnSpriteFadeComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public TimeSpan FadeTime = TimeSpan.FromSeconds(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
using Content.Client._ES.Sprite.Components;
|
||||
using Content.Shared._ES.Core.Timer.Components;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Animations;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client._ES.Sprite;
|
||||
|
||||
/// <summary>
|
||||
/// This handles <see cref="ESTimedDespawnSpriteFadeComponent"/>
|
||||
/// </summary>
|
||||
public sealed class ESTimedDespawnSpriteFadeSystem : VisualizerSystem<ESTimedDespawnSpriteFadeComponent>
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
|
||||
|
||||
private const string FadeTrack = "es-sprite-fade";
|
||||
|
||||
protected override void OnAppearanceChange(EntityUid uid, ESTimedDespawnSpriteFadeComponent component, ref AppearanceChangeEvent args)
|
||||
{
|
||||
base.OnAppearanceChange(uid, component, ref args);
|
||||
|
||||
if (args.Sprite is not { } sprite)
|
||||
return;
|
||||
|
||||
if (_animationPlayer.HasRunningAnimation(uid, FadeTrack))
|
||||
return;
|
||||
|
||||
if (!AppearanceSystem.TryGetData<TimeSpan>(uid, ESTimedDespawnVisuals.DespawnTime, out var time, args.Component))
|
||||
return;
|
||||
|
||||
var duration = time - _timing.CurTime;
|
||||
|
||||
var animation = new Animation
|
||||
{
|
||||
Length = duration,
|
||||
AnimationTracks =
|
||||
{
|
||||
new AnimationTrackComponentProperty
|
||||
{
|
||||
Property = nameof(SpriteComponent.Color),
|
||||
ComponentType = typeof(SpriteComponent),
|
||||
InterpolationMode = AnimationInterpolationMode.Linear,
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackProperty.KeyFrame(sprite.Color, 0f),
|
||||
new AnimationTrackProperty.KeyFrame(sprite.Color, MathF.Max((float) (duration - component.FadeTime).TotalSeconds, 0f)),
|
||||
new AnimationTrackProperty.KeyFrame(sprite.Color.WithAlpha(0f), (float) component.FadeTime.TotalSeconds, Easings.OutSine),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
_animationPlayer.Play(uid, animation, FadeTrack);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
// SPDX-FileCopyrightText: 2026 Janet Blackquill <uhhadd@gmail.com>
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using System.Numerics;
|
||||
using Content.Shared._ST.Interaction;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Client._ST.Interaction;
|
||||
|
||||
public sealed class StellarInteractionParticleSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SpriteSystem _sprite = default!;
|
||||
[Dependency] private readonly AnimationPlayerSystem _animation = default!;
|
||||
|
||||
private const string AnimateKey = "particle-animation";
|
||||
|
||||
private static readonly EntProtoId InteractionParticleId = "StellarInteractionParticle";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeAllEvent<StellarInteractionParticleEvent>(OnInteractionParticle);
|
||||
}
|
||||
|
||||
private void OnInteractionParticle(StellarInteractionParticleEvent ev)
|
||||
{
|
||||
var performer = GetEntity(ev.Performer);
|
||||
var used = GetEntity(ev.Used);
|
||||
var target = GetEntity(ev.Target);
|
||||
|
||||
if (!Exists(performer) || !Exists(target))
|
||||
return;
|
||||
|
||||
var performerXform = Transform(performer);
|
||||
var targetXform = Transform(target);
|
||||
if (performerXform.MapID == MapId.Nullspace || targetXform.MapID == MapId.Nullspace)
|
||||
return;
|
||||
|
||||
if (performerXform.ParentUid != targetXform.ParentUid)
|
||||
return;
|
||||
|
||||
var performerTargetDelta = targetXform.LocalPosition - performerXform.LocalPosition;
|
||||
var particle = Spawn(InteractionParticleId, performerXform.Coordinates);
|
||||
|
||||
if (used is { } usedEntity && Exists(usedEntity) && TryComp<SpriteComponent>(usedEntity, out var usedSprite))
|
||||
{
|
||||
_sprite.CopySprite((usedEntity, usedSprite), particle);
|
||||
// ES START
|
||||
_sprite.SetDrawDepth(particle, (int) Shared.DrawDepth.DrawDepth.Effects);
|
||||
// ES END
|
||||
}
|
||||
|
||||
var spriteColor = Comp<SpriteComponent>(particle).Color;
|
||||
_animation.Play(particle, GetAnimation(performerTargetDelta, spriteColor), AnimateKey);
|
||||
}
|
||||
|
||||
private Animation GetAnimation(Vector2 endOffset, Color color)
|
||||
{
|
||||
var startRotation = _random.NextAngle(Angle.FromDegrees(-40), Angle.FromDegrees(40));
|
||||
var endRotation = Angle.Zero;
|
||||
var startScale = new Vector2(0.3f, 0.3f);
|
||||
var endScale = new Vector2(1f, 1f);
|
||||
var rotationLength = TimeSpan.FromMilliseconds(600);
|
||||
|
||||
var startOffset = new Vector2();
|
||||
var offsetLength = TimeSpan.FromMilliseconds(250);
|
||||
|
||||
var startColor = color.WithAlpha(color.A * 0.7f);
|
||||
var endColor = color.WithAlpha(0f);
|
||||
var colorLength = rotationLength + offsetLength;
|
||||
|
||||
return new Animation()
|
||||
{
|
||||
Length = colorLength,
|
||||
|
||||
AnimationTracks =
|
||||
{
|
||||
new AnimationTrackComponentProperty()
|
||||
{
|
||||
ComponentType = typeof(SpriteComponent),
|
||||
Property = nameof(SpriteComponent.Rotation),
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackProperty.KeyFrame(startRotation, 0f),
|
||||
new AnimationTrackProperty.KeyFrame(endRotation, (float)rotationLength.TotalSeconds, Easings.OutBack),
|
||||
},
|
||||
},
|
||||
new AnimationTrackComponentProperty()
|
||||
{
|
||||
ComponentType = typeof(SpriteComponent),
|
||||
Property = nameof(SpriteComponent.Scale),
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackProperty.KeyFrame(startScale, 0f),
|
||||
new AnimationTrackProperty.KeyFrame(endScale, (float)rotationLength.TotalSeconds, Easings.OutBack),
|
||||
},
|
||||
},
|
||||
new AnimationTrackComponentProperty()
|
||||
{
|
||||
ComponentType = typeof(SpriteComponent),
|
||||
Property = nameof(SpriteComponent.Offset),
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackProperty.KeyFrame(startOffset, 0f),
|
||||
new AnimationTrackProperty.KeyFrame(endOffset, (float)offsetLength.TotalSeconds, Easings.OutBack),
|
||||
},
|
||||
},
|
||||
new AnimationTrackComponentProperty()
|
||||
{
|
||||
ComponentType = typeof(SpriteComponent),
|
||||
Property = nameof(SpriteComponent.Color),
|
||||
KeyFrames =
|
||||
{
|
||||
new AnimationTrackProperty.KeyFrame(startColor, 0f),
|
||||
new AnimationTrackProperty.KeyFrame(startColor, (float)rotationLength.TotalSeconds),
|
||||
new AnimationTrackProperty.KeyFrame(endColor, (float)offsetLength.TotalSeconds, Easings.InOutCirc),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<controls:FancyWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="{Loc 'autodoc-add-step'}">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<Button Name="SurgeryButton" Text="{Loc 'autodoc-add-step-surgery'}"/>
|
||||
<Button Name="GrabItemButton" Text="{Loc 'autodoc-add-step-grab-item'}"/>
|
||||
<Button Name="GrabOrganButton" Text="{Loc 'autodoc-add-step-grab-organ'}"/>
|
||||
<Button Name="GrabPartButton" Text="{Loc 'autodoc-add-step-grab-part'}"/>
|
||||
<Button Name="StoreItemButton" Text="{Loc 'autodoc-add-step-store-item'}"/>
|
||||
<Button Name="SetLabelButton" Text="{Loc 'autodoc-add-step-set-label'}"/>
|
||||
<Button Name="WaitButton" Text="{Loc 'autodoc-add-step-wait'}"/>
|
||||
</BoxContainer>
|
||||
</controls:FancyWindow>
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared._Shitmed.Autodoc;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._Shitmed.Autodoc;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class AddStepWindow : FancyWindow
|
||||
{
|
||||
public event Action<IAutodocStep>? OnAddStep;
|
||||
|
||||
private PickSurgeryWindow? _surgery;
|
||||
private DialogWindow? _grab;
|
||||
private DialogWindow? _label;
|
||||
private DialogWindow? _wait;
|
||||
|
||||
public AddStepWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
// close the window once any step is added
|
||||
OnAddStep += _ => Close();
|
||||
|
||||
OnClose += () =>
|
||||
{
|
||||
_surgery?.Close();
|
||||
_grab?.Close();
|
||||
_label?.Close();
|
||||
_wait?.Close();
|
||||
};
|
||||
|
||||
// dedicated ui to pick the enum values and surgery type
|
||||
SurgeryButton.OnPressed += _ =>
|
||||
{
|
||||
if (_surgery is {} window)
|
||||
{
|
||||
window.MoveToFront();
|
||||
return;
|
||||
}
|
||||
|
||||
_surgery = new PickSurgeryWindow();
|
||||
_surgery.OnAddStep += step => OnAddStep?.Invoke(step);
|
||||
_surgery.OnClose += () => _surgery = null;
|
||||
_surgery.OpenCentered();
|
||||
};
|
||||
|
||||
// just picking a string, use a dialog
|
||||
GrabItemButton.OnPressed += _ =>
|
||||
{
|
||||
if (_grab is {} dialog)
|
||||
{
|
||||
dialog.MoveToFront();
|
||||
return;
|
||||
}
|
||||
|
||||
var field = "name";
|
||||
var prompt = Loc.GetString("autodoc-add-step-grab-item-prompt");
|
||||
var placeholder = Loc.GetString("autodoc-add-step-grab-item-placeholder");
|
||||
var entry = new QuickDialogEntry(field, QuickDialogEntryType.ShortText, prompt, placeholder);
|
||||
var entries = new List<QuickDialogEntry> { entry };
|
||||
_grab = new DialogWindow(GrabItemButton.Text!, entries);
|
||||
_grab.OnConfirmed += responses =>
|
||||
{
|
||||
var name = responses[field].Trim();
|
||||
if (name.Length < 1 || name.Length > 100)
|
||||
return;
|
||||
|
||||
OnAddStep?.Invoke(new GrabItemAutodocStep()
|
||||
{
|
||||
Name = name
|
||||
});
|
||||
};
|
||||
_grab.OnClose += () => _grab = null;
|
||||
};
|
||||
|
||||
// no arguments so these are trivial
|
||||
GrabOrganButton.OnPressed += _ => OnAddStep?.Invoke(new GrabAnyOrganAutodocStep());
|
||||
GrabPartButton.OnPressed += _ => OnAddStep?.Invoke(new GrabAnyBodyPartAutodocStep());
|
||||
StoreItemButton.OnPressed += _ => OnAddStep?.Invoke(new StoreItemAutodocStep());
|
||||
|
||||
SetLabelButton.OnPressed += _ =>
|
||||
{
|
||||
if (_label is {} dialog)
|
||||
{
|
||||
dialog.MoveToFront();
|
||||
return;
|
||||
}
|
||||
|
||||
var field = "label";
|
||||
var prompt = Loc.GetString("autodoc-add-step-set-label-prompt");
|
||||
var entry = new QuickDialogEntry(field, QuickDialogEntryType.ShortText, prompt);
|
||||
var entries = new List<QuickDialogEntry> { entry };
|
||||
_label = new DialogWindow(SetLabelButton.Text!, entries);
|
||||
_label.OnConfirmed += responses =>
|
||||
{
|
||||
var label = responses[field].Trim();
|
||||
if (label.Length < 1 || label.Length > 20)
|
||||
return;
|
||||
|
||||
OnAddStep?.Invoke(new SetLabelAutodocStep()
|
||||
{
|
||||
Label = label
|
||||
});
|
||||
};
|
||||
_label.OnClose += () => _label = null;
|
||||
};
|
||||
|
||||
WaitButton.OnPressed += _ =>
|
||||
{
|
||||
if (_wait is {} dialog)
|
||||
{
|
||||
dialog.MoveToFront();
|
||||
return;
|
||||
}
|
||||
|
||||
var field = "length";
|
||||
var prompt = Loc.GetString("autodoc-add-step-wait-prompt");
|
||||
var entry = new QuickDialogEntry(field, QuickDialogEntryType.Integer, prompt);
|
||||
var entries = new List<QuickDialogEntry> { entry };
|
||||
_wait = new DialogWindow(WaitButton.Text!, entries);
|
||||
_wait.OnConfirmed += responses =>
|
||||
{
|
||||
var length = int.Parse(responses[field].Trim());
|
||||
if (length < 1 || length > 30)
|
||||
return;
|
||||
|
||||
OnAddStep?.Invoke(new WaitAutodocStep()
|
||||
{
|
||||
Length = length
|
||||
});
|
||||
};
|
||||
_wait.OnClose += () => _wait = null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
using Content.Shared._Shitmed.Autodoc;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Player;
|
||||
|
||||
namespace Content.Client._Shitmed.Autodoc;
|
||||
|
||||
public sealed class AutodocBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
|
||||
[ViewVariables]
|
||||
private AutodocWindow? _window;
|
||||
|
||||
public AutodocBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
_window = new AutodocWindow(owner, _entMan, _player);
|
||||
|
||||
_window.OnCreateProgram += title => SendMessage(new AutodocCreateProgramMessage(title));
|
||||
_window.OnToggleProgramSafety += program => SendMessage(new AutodocToggleProgramSafetyMessage(program));
|
||||
_window.OnRemoveProgram += program => SendMessage(new AutodocRemoveProgramMessage(program));
|
||||
|
||||
_window.OnAddStep += (program, step, index) => SendMessage(new AutodocAddStepMessage(program, step, index));
|
||||
_window.OnRemoveStep += (program, stepIndex) => SendMessage(new AutodocRemoveStepMessage(program, stepIndex));
|
||||
|
||||
_window.OnImportProgram += (program) => SendMessage(new AutodocImportProgramMessage(program));
|
||||
|
||||
_window.OnStart += program => SendMessage(new AutodocStartMessage(program));
|
||||
_window.OnStop += () => SendMessage(new AutodocStopMessage());
|
||||
|
||||
_window.OnClose += () => Close();
|
||||
|
||||
_window.OpenCentered();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (disposing)
|
||||
_window?.Dispose();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<controls:FancyWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="{Loc 'autodoc-view-program-title'}"
|
||||
SetSize="600 500">
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<BoxContainer Orientation="Vertical" Margin="5 5 5 5">
|
||||
<Label Name="ProgramTitle"/> <!-- Set to Program.Title -->
|
||||
<Button Name="SafetyButton" Text="{Loc 'autodoc-safety-enabled'}"/>
|
||||
<Button Name="RemoveButton" StyleClasses="Caution" Text="{Loc 'autodoc-remove-program'}"/>
|
||||
<Button Name="AddStepButton" Text="{Loc 'autodoc-add-step'}"/>
|
||||
<Button Name="RemoveStepButton" StyleClasses="Caution" Text="{Loc 'autodoc-remove-step'}" Disabled="True"/>
|
||||
<Button Name="StartButton" StyleClasses="Caution" Text="{Loc 'autodoc-start-program'}"/>
|
||||
<Button Name="ExportProgramButton" Text="{Loc 'autodoc-export-program'}"/>
|
||||
</BoxContainer>
|
||||
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
|
||||
<ItemList Name="Steps"/> <!-- Set to Program.Steps -->
|
||||
</ScrollContainer>
|
||||
</BoxContainer>
|
||||
</controls:FancyWindow>
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared._Shitmed.Autodoc;
|
||||
using Content.Shared._Shitmed.Autodoc.Components;
|
||||
using Content.Shared._Shitmed.Autodoc.Systems;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Timing;
|
||||
using System.IO;
|
||||
|
||||
namespace Content.Client._Shitmed.Autodoc;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class AutodocProgramWindow : FancyWindow
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
[Dependency] private readonly IFileDialogManager _dialogManager = default!;
|
||||
[Dependency] private readonly ILogManager _logMan = default!;
|
||||
[Dependency] private readonly ISerializationManager _serMan = default!;
|
||||
private SharedAutodocSystem _autodoc = default!;
|
||||
|
||||
public event Action? OnToggleSafety;
|
||||
public event Action? OnRemoveProgram;
|
||||
public event Action<IAutodocStep, int>? OnAddStep;
|
||||
public event Action<int>? OnRemoveStep;
|
||||
public event Action? OnStart;
|
||||
|
||||
private EntityUid _owner;
|
||||
private AutodocProgram _program;
|
||||
private int _steps;
|
||||
private bool _safety = true;
|
||||
private ISawmill _sawmill;
|
||||
|
||||
private int? _selected;
|
||||
private AddStepWindow? _addStep;
|
||||
|
||||
public AutodocProgramWindow(EntityUid owner, AutodocProgram program)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_autodoc = _entMan.System<SharedAutodocSystem>();
|
||||
|
||||
_owner = owner;
|
||||
_program = program;
|
||||
_sawmill = _logMan.GetSawmill("autodoc-ui");
|
||||
|
||||
OnClose += () => _addStep?.Close();
|
||||
|
||||
SafetyButton.OnPressed += _ =>
|
||||
{
|
||||
OnToggleSafety?.Invoke();
|
||||
program.SkipFailed ^= true;
|
||||
UpdateSafety();
|
||||
};
|
||||
UpdateSafety();
|
||||
|
||||
RemoveButton.OnPressed += _ =>
|
||||
{
|
||||
OnRemoveProgram?.Invoke();
|
||||
Close();
|
||||
};
|
||||
|
||||
AddStepButton.OnPressed += _ =>
|
||||
{
|
||||
if (_addStep is {} window)
|
||||
{
|
||||
window.MoveToFront();
|
||||
return;
|
||||
}
|
||||
|
||||
_addStep = new AddStepWindow();
|
||||
_addStep.OnAddStep += step =>
|
||||
{
|
||||
// if nothing is selected add it to the end
|
||||
// if something is selected, insert just before it
|
||||
var index = _selected ?? program.Steps.Count;
|
||||
OnAddStep?.Invoke(step, index);
|
||||
_selected = null;
|
||||
RemoveButton.Disabled = true;
|
||||
program.Steps.Insert(index, step);
|
||||
UpdateSteps();
|
||||
};
|
||||
_addStep.OnClose += () => _addStep = null;
|
||||
_addStep.OpenCentered();
|
||||
};
|
||||
|
||||
RemoveStepButton.OnPressed += _ =>
|
||||
{
|
||||
if (_selected is not {} index)
|
||||
return;
|
||||
|
||||
_selected = null;
|
||||
RemoveStepButton.Disabled = true;
|
||||
OnRemoveStep?.Invoke(index);
|
||||
|
||||
// Steps.RemoveChild throws for no fucking reason so rebuild it
|
||||
program.Steps.RemoveAt(index);
|
||||
UpdateSteps();
|
||||
};
|
||||
|
||||
StartButton.OnPressed += _ =>
|
||||
{
|
||||
OnStart?.Invoke();
|
||||
Close();
|
||||
};
|
||||
|
||||
ExportProgramButton.OnPressed += _ =>
|
||||
{
|
||||
ExportProgram();
|
||||
};
|
||||
|
||||
Steps.OnItemSelected += args =>
|
||||
{
|
||||
_selected = args.ItemIndex;
|
||||
RemoveStepButton.Disabled = false;
|
||||
};
|
||||
Steps.OnItemDeselected += _ =>
|
||||
{
|
||||
_selected = null;
|
||||
RemoveStepButton.Disabled = true;
|
||||
};
|
||||
|
||||
UpdateSteps();
|
||||
UpdateSafety();
|
||||
}
|
||||
|
||||
private async void ExportProgram()
|
||||
{
|
||||
if (await _dialogManager.SaveFile(new FileDialogFilters(new FileDialogFilters.Group("yml"))) is not {} file)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var node = _serMan.WriteValue(_program.GetType(), _program);
|
||||
await using var writer = new StreamWriter(file.fileStream);
|
||||
node.Write(writer);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_sawmill.Error($"Error when exporting program: {e}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
await file.fileStream.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSafety()
|
||||
{
|
||||
var safety = !_program.SkipFailed;
|
||||
if (safety == _safety)
|
||||
return;
|
||||
|
||||
_safety = safety;
|
||||
|
||||
SafetyButton.Text = Loc.GetString("autodoc-safety-" + (safety ? "enabled" : "disabled"));
|
||||
if (safety)
|
||||
SafetyButton.RemoveStyleClass("Caution");
|
||||
else
|
||||
SafetyButton.AddStyleClass("Caution");
|
||||
}
|
||||
|
||||
private void UpdateSteps()
|
||||
{
|
||||
var count = _program.Steps.Count;
|
||||
if (_steps == count)
|
||||
return;
|
||||
|
||||
_steps = count;
|
||||
|
||||
Steps.Clear();
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Steps.AddItem(_program.Steps[i].Title);
|
||||
}
|
||||
|
||||
if (!_entMan.TryGetComponent<AutodocComponent>(_owner, out var comp))
|
||||
return;
|
||||
|
||||
AddStepButton.Disabled = count >= comp.MaxProgramSteps;
|
||||
}
|
||||
|
||||
private void UpdateStart()
|
||||
{
|
||||
if (!_entMan.TryGetComponent<AutodocComponent>(_owner, out var comp))
|
||||
return;
|
||||
|
||||
StartButton.Disabled = _autodoc.GetPatient((_owner, comp)) == null;
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
|
||||
UpdateSteps();
|
||||
UpdateSafety();
|
||||
UpdateStart();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<controls:FancyWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="{Loc 'autodoc-title'}">
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<ScrollContainer MinWidth="600" MinHeight="400" VerticalExpand="True">
|
||||
<BoxContainer Name="Programs" Orientation="Vertical"/> <!-- Populated at runtime -->
|
||||
</ScrollContainer>
|
||||
<BoxContainer Orientation="Horizontal" Margin="5 5 5 5" Align="Center">
|
||||
<Button Name="CreateProgramButton" StyleClasses="OpenRight" Text="{Loc 'autodoc-create-program'}"/>
|
||||
<Button Name="ImportProgramButton" StyleClasses="OpenLeft" Text="{Loc 'autodoc-import-program'}"/>
|
||||
</BoxContainer>
|
||||
<Button Name="AbortButton" MaxWidth="350" Text="{Loc 'autodoc-abort-program'}" Disabled="True"/>
|
||||
</BoxContainer>
|
||||
</controls:FancyWindow>
|
||||
|
|
@ -1,222 +0,0 @@
|
|||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared._Shitmed.Autodoc;
|
||||
using Content.Shared._Shitmed.Autodoc.Components;
|
||||
using Content.Shared._Shitmed.Autodoc.Systems;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Utility;
|
||||
using System.IO;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
|
||||
namespace Content.Client._Shitmed.Autodoc;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class AutodocWindow : FancyWindow
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
[Dependency] private readonly IFileDialogManager _dialogMan = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
[Dependency] private readonly ISerializationManager _serMan = default!;
|
||||
[Dependency] private readonly ILogManager _logMan = default!;
|
||||
|
||||
private SharedAutodocSystem _autodoc;
|
||||
private EntityUid _owner;
|
||||
private bool _active;
|
||||
private int _programCount = 0;
|
||||
private ISawmill _sawmill;
|
||||
|
||||
public event Action<string>? OnCreateProgram;
|
||||
public event Action<int>? OnToggleProgramSafety;
|
||||
public event Action<int>? OnRemoveProgram;
|
||||
public event Action<int, IAutodocStep, int>? OnAddStep;
|
||||
public event Action<int, int>? OnRemoveStep;
|
||||
public event Action<int>? OnStart;
|
||||
public event Action? OnStop;
|
||||
public event Action<AutodocProgram>? OnImportProgram;
|
||||
|
||||
private DialogWindow? _dialog;
|
||||
private AutodocProgramWindow? _currentProgram;
|
||||
|
||||
public AutodocWindow(EntityUid owner, IEntityManager entMan, IPlayerManager player)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_sawmill = _logMan.GetSawmill("autodoc-ui");
|
||||
_autodoc = entMan.System<SharedAutodocSystem>();
|
||||
_owner = owner;
|
||||
|
||||
OnClose += () =>
|
||||
{
|
||||
_dialog?.Close();
|
||||
_currentProgram?.Close();
|
||||
};
|
||||
|
||||
ImportProgramButton.OnPressed += _ =>
|
||||
{
|
||||
ImportProgram();
|
||||
};
|
||||
|
||||
CreateProgramButton.OnPressed += _ =>
|
||||
{
|
||||
if (_dialog != null)
|
||||
{
|
||||
_dialog.MoveToFront();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_entMan.TryGetComponent<AutodocComponent>(_owner, out var comp))
|
||||
return;
|
||||
|
||||
var field = "title";
|
||||
var prompt = Loc.GetString("autodoc-program-title");
|
||||
var placeholder = Loc.GetString("autodoc-program-title-placeholder", ("number", comp.Programs.Count + 1));
|
||||
var entry = new QuickDialogEntry(field, QuickDialogEntryType.ShortText, prompt, placeholder);
|
||||
var entries = new List<QuickDialogEntry> { entry };
|
||||
_dialog = new DialogWindow(CreateProgramButton.Text!, entries);
|
||||
_dialog.OnConfirmed += responses =>
|
||||
{
|
||||
var title = responses[field].Trim();
|
||||
if (title.Length < 1 || title.Length > comp.MaxProgramTitleLength)
|
||||
return;
|
||||
|
||||
OnCreateProgram?.Invoke(title);
|
||||
};
|
||||
|
||||
// prevent MoveToFront being called on a closed window and double closing
|
||||
_dialog.OnClose += () => _dialog = null;
|
||||
};
|
||||
|
||||
AbortButton.AddStyleClass("Caution");
|
||||
AbortButton.OnPressed += _ => OnStop?.Invoke();
|
||||
|
||||
UpdateActive();
|
||||
UpdatePrograms();
|
||||
}
|
||||
|
||||
public void UpdateActive()
|
||||
{
|
||||
if (!_entMan.TryGetComponent<AutodocComponent>(_owner, out var comp))
|
||||
return;
|
||||
|
||||
// UI must be in the inactive state by default, since this wont run when inactive at startup
|
||||
var active = _entMan.HasComponent<ActiveAutodocComponent>(_owner);
|
||||
if (active == _active)
|
||||
return;
|
||||
|
||||
_active = active;
|
||||
|
||||
CreateProgramButton.Disabled = active || _programCount >= comp.MaxPrograms;
|
||||
AbortButton.Disabled = !active;
|
||||
foreach (var button in Programs.Children)
|
||||
{
|
||||
((Button) button).Disabled = active;
|
||||
}
|
||||
|
||||
if (!active)
|
||||
return;
|
||||
|
||||
// close windows that can only be open when inactive
|
||||
_dialog?.Close();
|
||||
_currentProgram?.Close();
|
||||
}
|
||||
|
||||
private void UpdatePrograms()
|
||||
{
|
||||
if (!_entMan.TryGetComponent<AutodocComponent>(_owner, out var comp))
|
||||
return;
|
||||
|
||||
var count = comp.Programs.Count;
|
||||
if (count == _programCount)
|
||||
return;
|
||||
|
||||
_programCount = count;
|
||||
|
||||
CreateProgramButton.Disabled = _active || _programCount >= comp.MaxPrograms;
|
||||
|
||||
Programs.RemoveAllChildren();
|
||||
for (int i = 0; i < comp.Programs.Count; i++)
|
||||
{
|
||||
var button = new Button()
|
||||
{
|
||||
Text = comp.Programs[i].Title
|
||||
};
|
||||
var index = i;
|
||||
button.OnPressed += _ => OpenProgram(index);
|
||||
button.Disabled = _active;
|
||||
Programs.AddChild(button);
|
||||
}
|
||||
}
|
||||
|
||||
private async void ImportProgram()
|
||||
{
|
||||
if (await _dialogMan.OpenFile(new FileDialogFilters(new FileDialogFilters.Group("yml"))) is not {} file)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
using var reader = new StreamReader(file, EncodingHelpers.UTF8);
|
||||
var yamlStream = new YamlStream();
|
||||
yamlStream.Load(reader);
|
||||
var root = yamlStream.Documents[0].RootNode;
|
||||
var program = _serMan.Read<AutodocProgram>(root.ToDataNode(), notNullableOverride: true);
|
||||
OnImportProgram?.Invoke(program);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_sawmill.Error($"Error when importing program: {e}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void OpenProgram(int index)
|
||||
{
|
||||
if (!_entMan.TryGetComponent<AutodocComponent>(_owner, out var comp))
|
||||
return;
|
||||
|
||||
// no editing multiple programs at once
|
||||
if (_currentProgram is {} existing)
|
||||
existing.Close();
|
||||
|
||||
var window = new AutodocProgramWindow(_owner, comp.Programs[index]);
|
||||
window.OnToggleSafety += () => OnToggleProgramSafety?.Invoke(index);
|
||||
window.OnRemoveProgram += () =>
|
||||
{
|
||||
OnRemoveProgram?.Invoke(index);
|
||||
Programs.RemoveChild(index);
|
||||
};
|
||||
window.OnAddStep += (step, stepIndex) => OnAddStep?.Invoke(index, step, stepIndex);
|
||||
window.OnRemoveStep += step => OnRemoveStep?.Invoke(index, step);
|
||||
window.OnStart += () =>
|
||||
{
|
||||
if (_active)
|
||||
return;
|
||||
|
||||
OnStart?.Invoke(index);
|
||||
|
||||
// predict it starting the program
|
||||
_entMan.EnsureComponent<ActiveAutodocComponent>(_owner);
|
||||
};
|
||||
window.OnClose += () => _currentProgram = null;
|
||||
_currentProgram = window;
|
||||
|
||||
window.OpenCentered();
|
||||
}
|
||||
|
||||
protected override void FrameUpdate(FrameEventArgs args)
|
||||
{
|
||||
base.FrameUpdate(args);
|
||||
|
||||
UpdateActive();
|
||||
UpdatePrograms();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<controls:FancyWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="{Loc 'autodoc-add-step-surgery'}"
|
||||
MinSize="600 400">
|
||||
<BoxContainer Orientation="Horizontal" VerticalExpand="True" HorizontalExpand="True">
|
||||
<BoxContainer Orientation="Vertical" MinWidth="200" HorizontalAlignment="Center">
|
||||
<BoxContainer Name="Symmetry" Orientation="Horizontal" HorizontalExpand="True"/> <!-- Populated with a radio option of BodyPartSymmetry values -->
|
||||
<PanelContainer StyleClasses="LowDivider" Margin="0 5 0 5"/>
|
||||
<ScrollContainer VerticalExpand="True" HorizontalExpand="True">
|
||||
<ItemList Name="Parts"/> <!-- Populated with BodyPartType values -->
|
||||
</ScrollContainer>
|
||||
<PanelContainer StyleClasses="LowDivider" Margin="0 5 0 5"/>
|
||||
<Button Name="SubmitButton" Text="{Loc 'autodoc-submit'}" Disabled="True"/>
|
||||
</BoxContainer>
|
||||
<ScrollContainer HorizontalExpand="True">
|
||||
<ItemList Name="Surgeries"/> <!-- Populated with SharedSurgerySystem.AllSurgeries -->
|
||||
</ScrollContainer>
|
||||
</BoxContainer>
|
||||
</controls:FancyWindow>
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared._Shitmed.Autodoc;
|
||||
using Content.Shared._Shitmed.Medical.Surgery;
|
||||
using Content.Shared._Shitmed.Medical.Surgery.Conditions;
|
||||
using Content.Shared.Body.Part;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client._Shitmed.Autodoc;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class PickSurgeryWindow : FancyWindow
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
private readonly SharedSurgerySystem _surgery;
|
||||
|
||||
public event Action<IAutodocStep>? OnAddStep;
|
||||
|
||||
private BodyPartType? _part;
|
||||
private BodyPartSymmetry? _symmetry;
|
||||
private EntProtoId<SurgeryComponent>? _surgeryId;
|
||||
|
||||
public PickSurgeryWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_surgery = _entMan.System<SharedSurgerySystem>();
|
||||
|
||||
OnAddStep += _ => Close();
|
||||
|
||||
var options = new RadioOptions<BodyPartSymmetry?>(RadioOptionsLayout.Horizontal);
|
||||
options.ButtonStyle = "OpenBoth";
|
||||
options.FirstButtonStyle = "OpenRight";
|
||||
options.LastButtonStyle = "OpenLeft";
|
||||
options.AddItem(Loc.GetString("autodoc-body-symmetry-ignored"), null);
|
||||
|
||||
foreach (var symmetry in Enum.GetValues<BodyPartSymmetry>())
|
||||
{
|
||||
var name = Loc.GetString("autodoc-body-symmetry-" + symmetry.ToString());
|
||||
options.AddItem(name, symmetry);
|
||||
}
|
||||
|
||||
Symmetry.AddChild(options);
|
||||
|
||||
options.OnItemSelected += args =>
|
||||
{
|
||||
args.Button.Select(args.Id);
|
||||
_symmetry = args.Button.SelectedValue;
|
||||
UpdateSurgeries();
|
||||
};
|
||||
|
||||
foreach (var part in Enum.GetValues<BodyPartType>())
|
||||
{
|
||||
var name = Loc.GetString("autodoc-body-part-" + part.ToString());
|
||||
Parts.AddItem(name, metadata: part);
|
||||
}
|
||||
|
||||
Parts.OnItemSelected += args =>
|
||||
{
|
||||
if (Parts[args.ItemIndex].Metadata is not BodyPartType part)
|
||||
return;
|
||||
|
||||
_part = part;
|
||||
UpdateSubmit();
|
||||
UpdateSurgeries();
|
||||
};
|
||||
Parts.OnItemDeselected += _ =>
|
||||
{
|
||||
_part = null;
|
||||
SubmitButton.Disabled = true;
|
||||
};
|
||||
|
||||
Surgeries.OnItemSelected += args =>
|
||||
{
|
||||
if (Surgeries[args.ItemIndex].Metadata is not EntProtoId<SurgeryComponent> id)
|
||||
return;
|
||||
|
||||
_surgeryId = id;
|
||||
UpdateSubmit();
|
||||
};
|
||||
Surgeries.OnItemDeselected += _ =>
|
||||
{
|
||||
_surgeryId = null;
|
||||
SubmitButton.Disabled = true;
|
||||
};
|
||||
|
||||
SubmitButton.OnPressed += _ =>
|
||||
{
|
||||
var step = new SurgeryAutodocStep()
|
||||
{
|
||||
Part = _part!.Value,
|
||||
Symmetry = _symmetry,
|
||||
Surgery = _surgeryId!.Value
|
||||
};
|
||||
OnAddStep?.Invoke(step);
|
||||
};
|
||||
|
||||
UpdateSurgeries();
|
||||
}
|
||||
|
||||
// doesn't handle prototype reload so you have to reopen the window to see new surgeries
|
||||
private void UpdateSurgeries()
|
||||
{
|
||||
Surgeries.Clear();
|
||||
|
||||
foreach (var id in _surgery.AllSurgeries)
|
||||
{
|
||||
var name = _proto.Index(id).Name;
|
||||
var protoId = new EntProtoId<SurgeryComponent>(id);
|
||||
if (_part is not BodyPartType part)
|
||||
{
|
||||
Surgeries.AddItem(name, metadata: protoId);
|
||||
continue;
|
||||
}
|
||||
|
||||
var ent = _surgery.GetSingleton(protoId);
|
||||
if (ent is null)
|
||||
continue;
|
||||
|
||||
if (!_entMan.TryGetComponent<SurgeryPartConditionComponent>(ent.Value, out var comp))
|
||||
{
|
||||
Surgeries.AddItem(name, metadata: protoId);
|
||||
continue;
|
||||
}
|
||||
|
||||
var partOk = comp.Part == part;
|
||||
var symmetryOk = (comp.Symmetry == null || _symmetry == null) ? true : comp.Symmetry == _symmetry;
|
||||
|
||||
var passesFilter = (partOk && symmetryOk) ^ comp.Inverse;
|
||||
|
||||
if (passesFilter)
|
||||
Surgeries.AddItem(name, metadata: protoId);
|
||||
}
|
||||
Surgeries.SortItemsByText();
|
||||
}
|
||||
|
||||
private void UpdateSubmit()
|
||||
{
|
||||
// symmetry is optional, others are not
|
||||
SubmitButton.Disabled = _part == null || _surgeryId == null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
using Content.Shared._Shitmed.Autodoc.Systems;
|
||||
|
||||
namespace Content.Client._Shitmed.Autodoc.Systems;
|
||||
|
||||
public sealed class AutodocSystem : SharedAutodocSystem;
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
// DeltaV - When "Fix eating and drinking verbs showing up after a short delay and making your verb UI bounce (#38164)"
|
||||
// was merged from upstream, it moved StomachComponent into shared, causing a duplicate component registered
|
||||
// crash on client startup. I have no idea if me commenting this out is problematic, but i don't think so?
|
||||
|
||||
//namespace Content.Client._Shitmed.Body.Components;
|
||||
//[RegisterComponent]
|
||||
//public sealed partial class StomachComponent : Component { }
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<ui:ChoiceControl
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:ui="clr-namespace:Content.Client._Shitmed.Choice.UI">
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<Button Name="Button" Access="Public"
|
||||
HorizontalExpand="True" VerticalExpand="False"
|
||||
StyleClasses="ButtonSquare" Margin="0">
|
||||
<BoxContainer Orientation="Horizontal" Margin="0">
|
||||
<TextureRect Name="Texture" Access="Public"
|
||||
HorizontalExpand="False" VerticalExpand="False"
|
||||
Margin="1"/>
|
||||
<Control MinWidth="5"/>
|
||||
<RichTextLabel Name="NameLabel" Access="Public" VerticalAlignment="Center"/>
|
||||
</BoxContainer>
|
||||
</Button>
|
||||
</BoxContainer>
|
||||
</ui:ChoiceControl>
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client._Shitmed.Choice.UI;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
[Virtual]
|
||||
public partial class ChoiceControl : Control
|
||||
{
|
||||
public ChoiceControl() => RobustXamlLoader.Load(this);
|
||||
|
||||
public void Set(string name, Texture? texture)
|
||||
{
|
||||
NameLabel.SetMessage(name);
|
||||
Texture.Texture = texture;
|
||||
}
|
||||
|
||||
public void Set(FormattedMessage msg, Texture? texture)
|
||||
{
|
||||
NameLabel.SetMessage(msg);
|
||||
Texture.Texture = texture;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,473 +0,0 @@
|
|||
using Content.Client._Shitmed.Choice.UI;
|
||||
using Content.Client.Administration.UI.CustomControls;
|
||||
using Content.Shared._Shitmed.Medical.Surgery;
|
||||
using Content.Shared._Shitmed.Medical.Surgery.Steps.Parts; // DeltaV - New UI
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Part;
|
||||
using Content.Shared.Humanoid;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface.Controls; // DeltaV - New UI
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client._Shitmed.Medical.Surgery;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class SurgeryBui : BoundUserInterface
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entities = default!;
|
||||
[Dependency] private readonly IPlayerManager _player = default!;
|
||||
|
||||
private readonly SurgerySystem _system;
|
||||
[ViewVariables]
|
||||
private SurgeryWindow? _window;
|
||||
private EntityUid? _part;
|
||||
private bool _isBody;
|
||||
private (EntityUid Ent, EntProtoId Proto)? _surgery;
|
||||
private readonly List<EntProtoId> _previousSurgeries = new();
|
||||
private (EntityUid Ent, TextureButton)? _previousPart; // DeltaV - New UI
|
||||
public SurgeryBui(EntityUid owner, Enum uiKey) : base(owner, uiKey) => _system = _entities.System<SurgerySystem>();
|
||||
|
||||
protected override void ReceiveMessage(BoundUserInterfaceMessage message)
|
||||
{
|
||||
if (_window is null
|
||||
|| message is not SurgeryBuiRefreshMessage)
|
||||
return;
|
||||
|
||||
RefreshUI();
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
if (state is not SurgeryBuiState s)
|
||||
return;
|
||||
|
||||
Update(s);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
if (disposing)
|
||||
_window?.Dispose();
|
||||
}
|
||||
|
||||
private void Update(SurgeryBuiState state)
|
||||
{
|
||||
if (_window == null)
|
||||
{
|
||||
_window = new SurgeryWindow();
|
||||
_window.OnClose += Close;
|
||||
_window.Title = Loc.GetString("surgery-ui-window-title");
|
||||
|
||||
_window.PartsButton.OnPressed += _ =>
|
||||
{
|
||||
_part = null;
|
||||
_isBody = false;
|
||||
_surgery = null;
|
||||
_previousSurgeries.Clear();
|
||||
DeactivateOtherParts(); // DeltaV - New UI
|
||||
View(ViewType.Parts);
|
||||
};
|
||||
|
||||
_window.SurgeriesButton.OnPressed += _ =>
|
||||
{
|
||||
_surgery = null;
|
||||
_previousSurgeries.Clear();
|
||||
|
||||
if (!_entities.TryGetNetEntity(_part, out var netPart)
|
||||
|| State is not SurgeryBuiState s
|
||||
|| !s.Choices.TryGetValue(netPart.Value, out var surgeries))
|
||||
return;
|
||||
|
||||
OnPartPressed(netPart.Value, surgeries);
|
||||
};
|
||||
|
||||
_window.StepsButton.OnPressed += _ =>
|
||||
{
|
||||
if (!_entities.TryGetNetEntity(_part, out var netPart)
|
||||
|| _previousSurgeries.Count == 0)
|
||||
return;
|
||||
|
||||
var last = _previousSurgeries[^1];
|
||||
_previousSurgeries.RemoveAt(_previousSurgeries.Count - 1);
|
||||
|
||||
if (_system.GetSingleton(last) is not { } previousId
|
||||
|| !_entities.TryGetComponent(previousId, out SurgeryComponent? previous))
|
||||
return;
|
||||
|
||||
OnSurgeryPressed((previousId, previous), netPart.Value, last);
|
||||
};
|
||||
}
|
||||
|
||||
_window.Surgeries.RemoveAllChildren();
|
||||
_window.Steps.RemoveAllChildren();
|
||||
_window.Parts.RemoveAllChildren();
|
||||
View(ViewType.Parts);
|
||||
|
||||
var oldSurgery = _surgery;
|
||||
var oldPart = _part;
|
||||
_part = null;
|
||||
_surgery = null;
|
||||
|
||||
var options = new List<(NetEntity netEntity, EntityUid entity, string Name, BodyPartType? PartType)>();
|
||||
foreach (var choice in state.Choices.Keys)
|
||||
if (_entities.TryGetEntity(choice, out var ent))
|
||||
{
|
||||
if (_entities.TryGetComponent(ent, out BodyPartComponent? part))
|
||||
options.Add((choice, ent.Value, _entities.GetComponent<MetaDataComponent>(ent.Value).EntityName, part.PartType));
|
||||
else if (_entities.TryGetComponent(ent, out BodyComponent? body))
|
||||
options.Add((choice, ent.Value, _entities.GetComponent<MetaDataComponent>(ent.Value).EntityName, null));
|
||||
}
|
||||
|
||||
options.Sort((a, b) =>
|
||||
{
|
||||
int GetScore(BodyPartType? partType)
|
||||
{
|
||||
return partType switch
|
||||
{
|
||||
BodyPartType.Head => 1,
|
||||
BodyPartType.Torso => 2,
|
||||
BodyPartType.Arm => 3,
|
||||
BodyPartType.Hand => 4,
|
||||
BodyPartType.Leg => 5,
|
||||
BodyPartType.Foot => 6,
|
||||
// BodyPartType.Tail => 7, No tails yet!
|
||||
BodyPartType.Other => 8,
|
||||
_ => 9
|
||||
};
|
||||
}
|
||||
|
||||
return GetScore(a.PartType) - GetScore(b.PartType);
|
||||
});
|
||||
|
||||
// DeltaV Start - New UI
|
||||
foreach (var textureButton in _window.Buttons)
|
||||
{
|
||||
textureButton.Visible = false;
|
||||
textureButton.StyleIdentifier = "SurgeryTextureButton";
|
||||
}
|
||||
// DeltaV End - New UI
|
||||
|
||||
foreach (var (netEntity, entity, partName, bodyPartType) in options) // DeltaV - New UI
|
||||
{
|
||||
//var netPart = _entities.GetNetEntity(part.Owner);
|
||||
var surgeries = state.Choices[netEntity];
|
||||
|
||||
// Delta Start - New UI
|
||||
var button = GetBodyPartTextureButton(entity, bodyPartType);
|
||||
if (button != null)
|
||||
{
|
||||
button.Visible = true;
|
||||
button.OnPressed += _ => OnPartPressed(netEntity, surgeries);
|
||||
if (_entities.HasComponent<IncisionOpenComponent>(entity))
|
||||
button.StyleIdentifier = "OpenIncision";
|
||||
}
|
||||
else
|
||||
{
|
||||
var partButton = new ChoiceControl();
|
||||
|
||||
partButton.Set(partName, null);
|
||||
partButton.Button.OnPressed += _ => OnPartPressed(netEntity, surgeries);
|
||||
_window.Parts.AddChild(partButton);
|
||||
}
|
||||
// Delta End - New UI
|
||||
|
||||
foreach (var surgeryId in surgeries)
|
||||
{
|
||||
if (_system.GetSingleton(surgeryId) is not { } surgery ||
|
||||
!_entities.TryGetComponent(surgery, out SurgeryComponent? surgeryComp))
|
||||
continue;
|
||||
|
||||
if (oldPart == entity && oldSurgery?.Proto == surgeryId)
|
||||
OnSurgeryPressed((surgery, surgeryComp), netEntity, surgeryId);
|
||||
}
|
||||
|
||||
if (oldPart == entity && oldSurgery == null)
|
||||
OnPartPressed(netEntity, surgeries);
|
||||
}
|
||||
|
||||
|
||||
if (!_window.IsOpen)
|
||||
_window.OpenCentered();
|
||||
}
|
||||
|
||||
private void AddStep(EntProtoId stepId, NetEntity netPart, EntProtoId surgeryId)
|
||||
{
|
||||
if (_window == null
|
||||
|| _system.GetSingleton(stepId) is not { } step)
|
||||
return;
|
||||
|
||||
var stepName = new FormattedMessage();
|
||||
stepName.AddText(_entities.GetComponent<MetaDataComponent>(step).EntityName);
|
||||
var stepButton = new SurgeryStepButton { Step = step };
|
||||
stepButton.Button.OnPressed += _ => SendMessage(new SurgeryStepChosenBuiMsg(netPart, surgeryId, stepId, _isBody));
|
||||
|
||||
_window.Steps.AddChild(stepButton);
|
||||
}
|
||||
|
||||
private void OnSurgeryPressed(Entity<SurgeryComponent> surgery, NetEntity netPart, EntProtoId surgeryId)
|
||||
{
|
||||
if (_window == null)
|
||||
return;
|
||||
|
||||
_part = _entities.GetEntity(netPart);
|
||||
_isBody = _entities.HasComponent<BodyComponent>(_part);
|
||||
_surgery = (surgery, surgeryId);
|
||||
|
||||
_window.Steps.RemoveAllChildren();
|
||||
|
||||
// This apparently does not consider if theres multiple surgery requirements in one surgery. Maybe thats fine.
|
||||
if (surgery.Comp.Requirement is { } requirementId && _system.GetSingleton(requirementId) is { } requirement)
|
||||
{
|
||||
var label = new ChoiceControl();
|
||||
label.Button.OnPressed += _ =>
|
||||
{
|
||||
_previousSurgeries.Add(surgeryId);
|
||||
|
||||
if (_entities.TryGetComponent(requirement, out SurgeryComponent? requirementComp))
|
||||
OnSurgeryPressed((requirement, requirementComp), netPart, requirementId);
|
||||
};
|
||||
|
||||
var msg = new FormattedMessage();
|
||||
var surgeryName = _entities.GetComponent<MetaDataComponent>(requirement).EntityName;
|
||||
msg.AddMarkup($"[bold]{Loc.GetString("surgery-ui-window-require")}: {surgeryName}[/bold]");
|
||||
label.Set(msg, null);
|
||||
|
||||
_window.Steps.AddChild(label);
|
||||
_window.Steps.AddChild(new HSeparator { Margin = new Thickness(0, 0, 0, 1) });
|
||||
}
|
||||
foreach (var stepId in surgery.Comp.Steps)
|
||||
AddStep(stepId, netPart, surgeryId);
|
||||
|
||||
View(ViewType.Steps);
|
||||
RefreshUI();
|
||||
}
|
||||
|
||||
private void OnPartPressed(NetEntity netPart, List<EntProtoId> surgeryIds)
|
||||
{
|
||||
if (_window == null)
|
||||
return;
|
||||
|
||||
_part = _entities.GetEntity(netPart);
|
||||
_isBody = _entities.HasComponent<BodyComponent>(_part);
|
||||
// DeltaV Start - New UI
|
||||
var bodyPart = _entities.GetComponent<BodyPartComponent>(_part.Value);
|
||||
var body = bodyPart.Body!.Value;
|
||||
|
||||
if (_previousPart != null)
|
||||
{
|
||||
(var previousEnt, var previousButton) = _previousPart.Value;
|
||||
if (!_entities.HasComponent<IncisionOpenComponent>(previousEnt))
|
||||
previousButton.StyleIdentifier = "SurgeryTextureButton";
|
||||
}
|
||||
|
||||
var button = GetBodyPartTextureButton(_part.Value, bodyPart.PartType);
|
||||
if (button != null && button.Pressed)
|
||||
{
|
||||
_previousPart = (_part.Value, button);
|
||||
DeactivateOtherParts(button);
|
||||
}
|
||||
else if (button != null && !button.Pressed)
|
||||
{
|
||||
_part = null;
|
||||
_isBody = false;
|
||||
_surgery = null;
|
||||
_previousSurgeries.Clear();
|
||||
View(ViewType.Parts);
|
||||
|
||||
return;
|
||||
}
|
||||
// DeltaV End - New UI
|
||||
|
||||
_window.Surgeries.RemoveAllChildren();
|
||||
|
||||
var surgeries = new List<(Entity<SurgeryComponent> Ent, EntProtoId Id, string Name)>();
|
||||
foreach (var surgeryId in surgeryIds)
|
||||
{
|
||||
if (_system.GetSingleton(surgeryId) is not { } surgery ||
|
||||
!_entities.TryGetComponent(surgery, out SurgeryComponent? surgeryComp))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Begin DeltaV Additions - only show surgeries with completed requirements
|
||||
if (surgeryComp.Requirement is { } reqId && _system.GetSingleton(reqId) is { } reqUid)
|
||||
{
|
||||
if (!_entities.TryGetComponent<SurgeryComponent>(reqUid, out var reqComp) ||
|
||||
!_system.PreviousStepsComplete(body, _part.Value, (reqUid, reqComp), string.Empty)) // step is unused as this is only for checking the requirement
|
||||
{
|
||||
// don't show any surgeries whose requirement isn't complete
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// End DeltaV Additions
|
||||
|
||||
var name = _entities.GetComponent<MetaDataComponent>(surgery).EntityName;
|
||||
surgeries.Add(((surgery, surgeryComp), surgeryId, name));
|
||||
}
|
||||
|
||||
surgeries.Sort((a, b) =>
|
||||
{
|
||||
var priority = a.Ent.Comp.Priority.CompareTo(b.Ent.Comp.Priority);
|
||||
if (priority != 0)
|
||||
return priority;
|
||||
|
||||
return string.Compare(a.Name, b.Name, StringComparison.Ordinal);
|
||||
});
|
||||
|
||||
foreach (var surgery in surgeries)
|
||||
{
|
||||
var surgeryButton = new ChoiceControl();
|
||||
surgeryButton.Set(surgery.Name, null);
|
||||
|
||||
surgeryButton.Button.OnPressed += _ => OnSurgeryPressed(surgery.Ent, netPart, surgery.Id);
|
||||
_window.Surgeries.AddChild(surgeryButton);
|
||||
}
|
||||
|
||||
RefreshUI();
|
||||
View(ViewType.Surgeries);
|
||||
}
|
||||
|
||||
// DeltaV Start - New UI
|
||||
private TextureButton? GetBodyPartTextureButton(EntityUid entity, BodyPartType? partType)
|
||||
{
|
||||
if (_window == null
|
||||
|| !_entities.TryGetComponent(entity, out BodyPartComponent? bodyPart))
|
||||
return null;
|
||||
|
||||
var isLeftPart = bodyPart.Symmetry.HasFlag(BodyPartSymmetry.Left);
|
||||
|
||||
switch (partType)
|
||||
{
|
||||
case BodyPartType.Torso:
|
||||
var isHumanoid = _entities.HasComponent<HumanoidAppearanceComponent>(bodyPart.Body);
|
||||
return isHumanoid ? _window.ChestButton : _window.CarpButton;
|
||||
case BodyPartType.Head:
|
||||
return _window.HeadButton;
|
||||
case BodyPartType.Arm:
|
||||
return isLeftPart ? _window.LArmButton : _window.RArmButton;
|
||||
case BodyPartType.Hand:
|
||||
return isLeftPart ? _window.LHandButton : _window.RHandButton;
|
||||
case BodyPartType.Leg:
|
||||
return isLeftPart ? _window.LLegButton : _window.RLegButton;
|
||||
case BodyPartType.Foot:
|
||||
return isLeftPart ? _window.LFootButton : _window.RFootButton;
|
||||
case BodyPartType.Tail:
|
||||
case BodyPartType.Other:
|
||||
case null:
|
||||
return null;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(partType), partType, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deactivates all other buttons that are currently active.
|
||||
/// </summary>
|
||||
/// <param name="activatedButton">The button that should be the only active button.</param>
|
||||
private void DeactivateOtherParts(TextureButton? activatedButton = null)
|
||||
{
|
||||
if (_window == null)
|
||||
return;
|
||||
|
||||
foreach (var button in _window.Buttons)
|
||||
{
|
||||
if (activatedButton == button)
|
||||
continue;
|
||||
|
||||
button.Pressed = false;
|
||||
}
|
||||
}
|
||||
// DeltaV End - New UI
|
||||
|
||||
private void RefreshUI()
|
||||
{
|
||||
if (_window == null
|
||||
|| !_window.IsOpen
|
||||
|| _part == null
|
||||
|| !_entities.HasComponent<SurgeryComponent>(_surgery?.Ent)
|
||||
|| !_entities.TryGetComponent(_player.LocalEntity ?? EntityUid.Invalid, out SurgeryTargetComponent? surgeryComp)
|
||||
|| !surgeryComp.CanOperate)
|
||||
return;
|
||||
|
||||
var next = _system.GetNextStep(Owner, _part.Value, _surgery.Value.Ent);
|
||||
var i = 0;
|
||||
foreach (var child in _window.Steps.Children)
|
||||
{
|
||||
if (child is not SurgeryStepButton stepButton)
|
||||
continue;
|
||||
|
||||
var status = StepStatus.Incomplete;
|
||||
if (next == null)
|
||||
status = StepStatus.Complete;
|
||||
else if (next.Value.Surgery.Owner != _surgery.Value.Ent)
|
||||
status = StepStatus.Incomplete;
|
||||
else if (next.Value.Step == i)
|
||||
status = StepStatus.Next;
|
||||
else if (i < next.Value.Step)
|
||||
status = StepStatus.Complete;
|
||||
|
||||
stepButton.Button.Disabled = status != StepStatus.Next;
|
||||
|
||||
var stepName = new FormattedMessage();
|
||||
stepName.AddText(_entities.GetComponent<MetaDataComponent>(stepButton.Step).EntityName);
|
||||
|
||||
if (status == StepStatus.Complete)
|
||||
stepButton.Button.Modulate = Color.Green;
|
||||
else
|
||||
{
|
||||
stepButton.Button.Modulate = Color.White;
|
||||
if (_player.LocalEntity is { } player
|
||||
&& status == StepStatus.Next
|
||||
&& !_system.CanPerformStep(player, Owner, _part.Value, stepButton.Step, false, out var popup, out var reason, out _))
|
||||
stepButton.ToolTip = popup;
|
||||
}
|
||||
|
||||
var texture = _entities.GetComponentOrNull<SpriteComponent>(stepButton.Step)?.Icon?.Default;
|
||||
stepButton.Set(stepName, texture);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
private void View(ViewType type)
|
||||
{
|
||||
if (_window == null)
|
||||
return;
|
||||
|
||||
_window.PartsButton.Parent!.Margin = new Thickness(0, 0, 0, 10);
|
||||
|
||||
_window.Parts.Visible = type == ViewType.Parts;
|
||||
_window.PartsButton.Disabled = type == ViewType.Parts;
|
||||
|
||||
_window.Surgeries.Visible = type == ViewType.Surgeries;
|
||||
_window.SurgeriesButton.Disabled = type != ViewType.Steps;
|
||||
|
||||
_window.Steps.Visible = type == ViewType.Steps;
|
||||
_window.StepsButton.Disabled = type != ViewType.Steps || _previousSurgeries.Count == 0;
|
||||
|
||||
if (_entities.TryGetComponent(_part, out MetaDataComponent? partMeta) &&
|
||||
_entities.TryGetComponent(_surgery?.Ent, out MetaDataComponent? surgeryMeta))
|
||||
_window.Title = $"Surgery - {partMeta.EntityName}, {surgeryMeta.EntityName}";
|
||||
else if (partMeta != null)
|
||||
_window.Title = $"Surgery - {partMeta.EntityName}";
|
||||
else
|
||||
_window.Title = "Surgery";
|
||||
}
|
||||
|
||||
private enum ViewType
|
||||
{
|
||||
Parts,
|
||||
Surgeries,
|
||||
Steps
|
||||
}
|
||||
|
||||
private enum StepStatus
|
||||
{
|
||||
Next,
|
||||
Complete,
|
||||
Incomplete
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
<controls:SurgeryStepButton
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client._Shitmed.Medical.Surgery">
|
||||
</controls:SurgeryStepButton>
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
using Content.Client._Shitmed.Choice.UI;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._Shitmed.Medical.Surgery;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class SurgeryStepButton : ChoiceControl
|
||||
{
|
||||
public EntityUid Step { get; set; }
|
||||
|
||||
public SurgeryStepButton()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
using Content.Shared._Shitmed.Medical.Surgery;
|
||||
|
||||
namespace Content.Client._Shitmed.Medical.Surgery;
|
||||
|
||||
public sealed class SurgerySystem : SharedSurgerySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
<controls:FancyWindow
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:customcontrols="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
xmlns:ui="clr-namespace:Content.Client._Shitmed.Medical.Surgery"
|
||||
MinSize="400 400">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" VerticalExpand="True" MinSize="570, 336">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="False" VerticalExpand="False" MinSize="264, 408">
|
||||
<TextureRect Name="Texture" TextureScale="6 6"
|
||||
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIBackground.png" Access="Public"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||
Stretch="KeepAspectCentered" StyleClasses="">
|
||||
<PanelContainer>
|
||||
<TextureButton
|
||||
Name="CarpButton" Scale="8 8" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0 0 0 11"
|
||||
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUICarp.png" Access="Public"/>
|
||||
<TextureButton
|
||||
Name="ChestButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0 0 0 11"
|
||||
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUITorso.png" Access="Public"/>
|
||||
<TextureButton
|
||||
Name="HeadButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0 30 0 0"
|
||||
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIHead.png" Access="Public"/>
|
||||
<TextureButton
|
||||
Name="RArmButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Left" Margin="30 0 0 47"
|
||||
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIRArm.png" Access="Public"/>
|
||||
<TextureButton
|
||||
Name="RHandButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Left" Margin="30 61 0 0"
|
||||
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIRHand.png" Access="Public"/>
|
||||
<TextureButton
|
||||
Name="RLegButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="78 0 0 42"
|
||||
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIRLeg.png" Access="Public"/>
|
||||
<TextureButton
|
||||
Name="RFootButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="54 0 0 30"
|
||||
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUIRFoot.png" Access="Public"/>
|
||||
<TextureButton
|
||||
Name="LArmButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0 0 30 47"
|
||||
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUILArm.png" Access="Public"/>
|
||||
<TextureButton
|
||||
Name="LHandButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0 61 30 0"
|
||||
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUILHand.png" Access="Public"/>
|
||||
<TextureButton
|
||||
Name="LLegButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0 0 78 42"
|
||||
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUILLeg.png" Access="Public"/>
|
||||
<TextureButton
|
||||
Name="LFootButton" Scale="6 6" ToggleMode="True" StyleIdentifier="SurgeryTextureButton" Visible="False"
|
||||
VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0 0 54 30"
|
||||
TexturePath="/Textures/_Shitmed/Interface/SurgeryUI/surgeryUILFoot.png" Access="Public"/>
|
||||
</PanelContainer>
|
||||
</TextureRect>
|
||||
</BoxContainer>
|
||||
<customcontrols:VSeparator StyleClasses="LowDivider" />
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" Margin="0 0 0 10">
|
||||
<Button Name="PartsButton" Access="Public" Text="{Loc 'surgery-ui-window-parts'}"
|
||||
HorizontalExpand="True" StyleClasses="OpenBoth" />
|
||||
<Button Name="SurgeriesButton" Access="Public" Text="{Loc 'surgery-ui-window-surgeries'}"
|
||||
HorizontalExpand="True" StyleClasses="OpenBoth" />
|
||||
<Button Name="StepsButton" Access="Public" Text="{Loc 'surgery-ui-window-steps'}"
|
||||
HorizontalExpand="True" StyleClasses="OpenBoth" />
|
||||
</BoxContainer>
|
||||
<customcontrols:HSeparator />
|
||||
<ScrollContainer VScrollEnabled="True" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer Name="Parts" Access="Public" Orientation="Vertical" Visible="False" />
|
||||
<BoxContainer Name="Surgeries" Access="Public" Orientation="Vertical" Visible="False" />
|
||||
<BoxContainer Name="Steps" Access="Public" Orientation="Vertical" Visible="False" />
|
||||
</ScrollContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</controls:FancyWindow>
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
using Content.Client.UserInterface.Controls; // DeltaV - New UI
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls; // DeltaV - New UI
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._Shitmed.Medical.Surgery;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class SurgeryWindow : FancyWindow
|
||||
{
|
||||
public List<TextureButton> Buttons { get; } = []; // DeltaV - New UI
|
||||
|
||||
public SurgeryWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
// DeltaV Start - New UI
|
||||
Buttons.Add(ChestButton);
|
||||
Buttons.Add(HeadButton);
|
||||
Buttons.Add(LArmButton);
|
||||
Buttons.Add(LHandButton);
|
||||
Buttons.Add(RArmButton);
|
||||
Buttons.Add(RHandButton);
|
||||
Buttons.Add(LLegButton);
|
||||
Buttons.Add(LFootButton);
|
||||
Buttons.Add(RLegButton);
|
||||
Buttons.Add(RFootButton);
|
||||
Buttons.Add(CarpButton);
|
||||
// DeltaV End - New UI
|
||||
}
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
using Content.Shared.Input;
|
||||
using Content.Shared._Shitmed.Targeting;
|
||||
using Content.Shared._Shitmed.Targeting.Events;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Input.Binding;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Client._Shitmed.Targeting;
|
||||
public sealed class TargetingSystem : SharedTargetingSystem
|
||||
{
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
public event Action<TargetingComponent>? TargetingStartup;
|
||||
public event Action? TargetingShutdown;
|
||||
public event Action<TargetBodyPart>? TargetChange;
|
||||
public event Action<TargetingComponent>? PartStatusStartup;
|
||||
public event Action<TargetingComponent>? PartStatusUpdate;
|
||||
public event Action? PartStatusShutdown;
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<TargetingComponent, LocalPlayerAttachedEvent>(HandlePlayerAttached);
|
||||
SubscribeLocalEvent<TargetingComponent, LocalPlayerDetachedEvent>(HandlePlayerDetached);
|
||||
SubscribeLocalEvent<TargetingComponent, ComponentStartup>(OnTargetingStartup);
|
||||
SubscribeLocalEvent<TargetingComponent, ComponentShutdown>(OnTargetingShutdown);
|
||||
SubscribeNetworkEvent<TargetIntegrityChangeEvent>(OnTargetIntegrityChange);
|
||||
|
||||
CommandBinds.Builder
|
||||
.Bind(ContentKeyFunctions.TargetHead,
|
||||
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.Head)))
|
||||
.Bind(ContentKeyFunctions.TargetTorso,
|
||||
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.Torso)))
|
||||
.Bind(ContentKeyFunctions.TargetLeftArm,
|
||||
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.LeftArm)))
|
||||
.Bind(ContentKeyFunctions.TargetLeftHand,
|
||||
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.LeftHand)))
|
||||
.Bind(ContentKeyFunctions.TargetRightArm,
|
||||
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.RightArm)))
|
||||
.Bind(ContentKeyFunctions.TargetRightHand,
|
||||
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.RightHand)))
|
||||
.Bind(ContentKeyFunctions.TargetLeftLeg,
|
||||
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.LeftLeg)))
|
||||
.Bind(ContentKeyFunctions.TargetLeftFoot,
|
||||
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.LeftFoot)))
|
||||
.Bind(ContentKeyFunctions.TargetRightLeg,
|
||||
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.RightLeg)))
|
||||
.Bind(ContentKeyFunctions.TargetRightFoot,
|
||||
InputCmdHandler.FromDelegate((session) => HandleTargetChange(session, TargetBodyPart.RightFoot)))
|
||||
.Register<SharedTargetingSystem>();
|
||||
}
|
||||
|
||||
private void HandlePlayerAttached(EntityUid uid, TargetingComponent component, LocalPlayerAttachedEvent args)
|
||||
{
|
||||
TargetingStartup?.Invoke(component);
|
||||
PartStatusStartup?.Invoke(component);
|
||||
}
|
||||
|
||||
private void HandlePlayerDetached(EntityUid uid, TargetingComponent component, LocalPlayerDetachedEvent args)
|
||||
{
|
||||
TargetingShutdown?.Invoke();
|
||||
PartStatusShutdown?.Invoke();
|
||||
}
|
||||
|
||||
private void OnTargetingStartup(EntityUid uid, TargetingComponent component, ComponentStartup args)
|
||||
{
|
||||
if (_playerManager.LocalEntity != uid)
|
||||
return;
|
||||
|
||||
TargetingStartup?.Invoke(component);
|
||||
PartStatusStartup?.Invoke(component);
|
||||
}
|
||||
|
||||
private void OnTargetingShutdown(EntityUid uid, TargetingComponent component, ComponentShutdown args)
|
||||
{
|
||||
if (_playerManager.LocalEntity != uid)
|
||||
return;
|
||||
|
||||
TargetingShutdown?.Invoke();
|
||||
PartStatusShutdown?.Invoke();
|
||||
}
|
||||
|
||||
private void OnTargetIntegrityChange(TargetIntegrityChangeEvent args)
|
||||
{
|
||||
if (!TryGetEntity(args.Uid, out var uid)
|
||||
|| !_playerManager.LocalEntity.Equals(uid)
|
||||
|| !TryComp(uid, out TargetingComponent? component)
|
||||
|| !args.RefreshUi)
|
||||
return;
|
||||
|
||||
PartStatusUpdate?.Invoke(component);
|
||||
}
|
||||
|
||||
private void HandleTargetChange(ICommonSession? session, TargetBodyPart target)
|
||||
{
|
||||
if (session == null
|
||||
|| session.AttachedEntity is not { } uid
|
||||
|| !TryComp<TargetingComponent>(uid, out var targeting))
|
||||
return;
|
||||
|
||||
TargetChange?.Invoke(target);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
using Content.Client.Gameplay;
|
||||
using Content.Client._Shitmed.UserInterface.Systems.PartStatus.Widgets;
|
||||
using Content.Shared._Shitmed.Targeting;
|
||||
using Content.Client._Shitmed.Targeting;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface.Controllers;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Client.Graphics;
|
||||
|
||||
|
||||
namespace Content.Client._Shitmed.UserInterface.Systems.PartStatus;
|
||||
|
||||
public sealed class PartStatusUIController : UIController, IOnStateEntered<GameplayState>, IOnSystemChanged<TargetingSystem>
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[Dependency] private readonly IEntityNetworkManager _net = default!;
|
||||
private SpriteSystem _spriteSystem = default!;
|
||||
private TargetingComponent? _targetingComponent;
|
||||
private PartStatusControl? PartStatusControl => UIManager.GetActiveUIWidgetOrNull<PartStatusControl>();
|
||||
|
||||
public void OnSystemLoaded(TargetingSystem system)
|
||||
{
|
||||
system.PartStatusStartup += AddPartStatusControl;
|
||||
system.PartStatusShutdown += RemovePartStatusControl;
|
||||
system.PartStatusUpdate += UpdatePartStatusControl;
|
||||
}
|
||||
|
||||
public void OnSystemUnloaded(TargetingSystem system)
|
||||
{
|
||||
system.PartStatusStartup -= AddPartStatusControl;
|
||||
system.PartStatusShutdown -= RemovePartStatusControl;
|
||||
system.PartStatusUpdate -= UpdatePartStatusControl;
|
||||
}
|
||||
|
||||
public void OnStateEntered(GameplayState state)
|
||||
{
|
||||
if (PartStatusControl != null)
|
||||
{
|
||||
PartStatusControl.SetVisible(_targetingComponent != null);
|
||||
|
||||
if (_targetingComponent != null)
|
||||
PartStatusControl.SetTextures(_targetingComponent.BodyStatus);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddPartStatusControl(TargetingComponent component)
|
||||
{
|
||||
_targetingComponent = component;
|
||||
|
||||
if (PartStatusControl != null)
|
||||
{
|
||||
PartStatusControl.SetVisible(_targetingComponent != null);
|
||||
|
||||
if (_targetingComponent != null)
|
||||
PartStatusControl.SetTextures(_targetingComponent.BodyStatus);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void RemovePartStatusControl()
|
||||
{
|
||||
if (PartStatusControl != null)
|
||||
PartStatusControl.SetVisible(false);
|
||||
|
||||
_targetingComponent = null;
|
||||
}
|
||||
|
||||
public void UpdatePartStatusControl(TargetingComponent component)
|
||||
{
|
||||
if (PartStatusControl != null && _targetingComponent != null)
|
||||
PartStatusControl.SetTextures(_targetingComponent.BodyStatus);
|
||||
}
|
||||
|
||||
public Texture GetTexture(SpriteSpecifier specifier)
|
||||
{
|
||||
if (_spriteSystem == null)
|
||||
_spriteSystem = _entManager.System<SpriteSystem>();
|
||||
|
||||
return _spriteSystem.Frame0(specifier);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
<widgets:PartStatusControl
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
xmlns:widgets="clr-namespace:Content.Client._Shitmed.UserInterface.Systems.PartStatus.Widgets"
|
||||
Name="PartStatusIndicator"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center">
|
||||
<Control>
|
||||
<PanelContainer>
|
||||
<TextureRect
|
||||
Name="DollHead"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="64 64"/>
|
||||
<TextureRect
|
||||
Name="DollTorso"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="64 64"/>
|
||||
<TextureRect
|
||||
Name="DollGroin"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="64 64"/>
|
||||
<TextureRect
|
||||
Name="DollLeftArm"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="64 64"/>
|
||||
<TextureRect
|
||||
Name="DollLeftHand"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="64 64"/>
|
||||
<TextureRect
|
||||
Name="DollRightArm"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="64 64"/>
|
||||
<TextureRect
|
||||
Name="DollRightHand"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="64 64"/>
|
||||
<TextureRect
|
||||
Name="DollLeftLeg"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="64 64"/>
|
||||
<TextureRect
|
||||
Name="DollLeftFoot"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="64 64"/>
|
||||
<TextureRect
|
||||
Name="DollRightLeg"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="64 64"/>
|
||||
<TextureRect
|
||||
Name="DollRightFoot"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="64 64"/>
|
||||
</PanelContainer>
|
||||
</Control>
|
||||
</widgets:PartStatusControl>
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
using Content.Client._Shitmed.UserInterface.Systems.PartStatus;
|
||||
using Content.Shared._Shitmed.Targeting;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
|
||||
namespace Content.Client._Shitmed.UserInterface.Systems.PartStatus.Widgets;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class PartStatusControl : UIWidget
|
||||
{
|
||||
private readonly Dictionary<TargetBodyPart, TextureRect> _partStatusControls;
|
||||
private readonly PartStatusUIController _controller;
|
||||
public PartStatusControl()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
_controller = UserInterfaceManager.GetUIController<PartStatusUIController>();
|
||||
_partStatusControls = new Dictionary<TargetBodyPart, TextureRect>
|
||||
{
|
||||
{ TargetBodyPart.Head, DollHead },
|
||||
{ TargetBodyPart.Torso, DollTorso },
|
||||
{ TargetBodyPart.Groin, DollGroin },
|
||||
{ TargetBodyPart.LeftArm, DollLeftArm },
|
||||
{ TargetBodyPart.LeftHand, DollLeftHand },
|
||||
{ TargetBodyPart.RightArm, DollRightArm },
|
||||
{ TargetBodyPart.RightHand, DollRightHand },
|
||||
{ TargetBodyPart.LeftLeg, DollLeftLeg },
|
||||
{ TargetBodyPart.LeftFoot, DollLeftFoot },
|
||||
{ TargetBodyPart.RightLeg, DollRightLeg },
|
||||
{ TargetBodyPart.RightFoot, DollRightFoot }
|
||||
};
|
||||
}
|
||||
|
||||
public void SetTextures(Dictionary<TargetBodyPart, TargetIntegrity> state)
|
||||
{
|
||||
foreach (var (bodyPart, integrity) in state)
|
||||
{
|
||||
string enumName = Enum.GetName(typeof(TargetBodyPart), bodyPart) ?? "Unknown";
|
||||
int enumValue = (int) integrity;
|
||||
var texture = new SpriteSpecifier.Rsi(new ResPath($"/Textures/_Shitmed/Interface/Targeting/Status/{enumName.ToLowerInvariant()}.rsi"), $"{enumName.ToLowerInvariant()}_{enumValue}");
|
||||
_partStatusControls[bodyPart].Texture = _controller.GetTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVisible(bool visible) => this.Visible = visible;
|
||||
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
using Content.Client.Gameplay;
|
||||
using Content.Client._Shitmed.UserInterface.Systems.Targeting.Widgets;
|
||||
using Content.Shared._Shitmed.Targeting;
|
||||
using Content.Client._Shitmed.Targeting;
|
||||
using Content.Shared._Shitmed.Targeting.Events;
|
||||
using Robust.Client.UserInterface.Controllers;
|
||||
using Robust.Client.Player;
|
||||
|
||||
namespace Content.Client._Shitmed.UserInterface.Systems.Targeting;
|
||||
|
||||
public sealed class TargetingUIController : UIController, IOnStateEntered<GameplayState>, IOnSystemChanged<TargetingSystem>
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||
[Dependency] private readonly IEntityNetworkManager _net = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
|
||||
private TargetingComponent? _targetingComponent;
|
||||
private TargetingControl? TargetingControl => UIManager.GetActiveUIWidgetOrNull<TargetingControl>();
|
||||
|
||||
public void OnSystemLoaded(TargetingSystem system)
|
||||
{
|
||||
system.TargetingStartup += AddTargetingControl;
|
||||
system.TargetingShutdown += RemoveTargetingControl;
|
||||
system.TargetChange += CycleTarget;
|
||||
}
|
||||
|
||||
public void OnSystemUnloaded(TargetingSystem system)
|
||||
{
|
||||
system.TargetingStartup -= AddTargetingControl;
|
||||
system.TargetingShutdown -= RemoveTargetingControl;
|
||||
system.TargetChange -= CycleTarget;
|
||||
}
|
||||
|
||||
public void OnStateEntered(GameplayState state)
|
||||
{
|
||||
if (TargetingControl == null)
|
||||
return;
|
||||
|
||||
TargetingControl.SetTargetDollVisible(_targetingComponent != null);
|
||||
|
||||
if (_targetingComponent != null)
|
||||
TargetingControl.SetBodyPartsVisible(_targetingComponent.Target);
|
||||
}
|
||||
|
||||
public void AddTargetingControl(TargetingComponent component)
|
||||
{
|
||||
_targetingComponent = component;
|
||||
|
||||
if (TargetingControl != null)
|
||||
{
|
||||
TargetingControl.SetTargetDollVisible(_targetingComponent != null);
|
||||
|
||||
if (_targetingComponent != null)
|
||||
TargetingControl.SetBodyPartsVisible(_targetingComponent.Target);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void RemoveTargetingControl()
|
||||
{
|
||||
if (TargetingControl != null)
|
||||
TargetingControl.SetTargetDollVisible(false);
|
||||
|
||||
_targetingComponent = null;
|
||||
}
|
||||
|
||||
public void CycleTarget(TargetBodyPart bodyPart)
|
||||
{
|
||||
if (_playerManager.LocalEntity is not { } user
|
||||
|| _entManager.GetComponent<TargetingComponent>(user) is not { } targetingComponent
|
||||
|| TargetingControl == null)
|
||||
return;
|
||||
|
||||
var player = _entManager.GetNetEntity(user);
|
||||
if (bodyPart != targetingComponent.Target)
|
||||
{
|
||||
var msg = new TargetChangeEvent(player, bodyPart);
|
||||
_net.SendSystemNetworkMessage(msg);
|
||||
TargetingControl?.SetBodyPartsVisible(bodyPart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,216 +0,0 @@
|
|||
<widgets:TargetingControl
|
||||
xmlns="https://spacestation14.io"
|
||||
xmlns:widgets="clr-namespace:Content.Client._Shitmed.UserInterface.Systems.Targeting.Widgets"
|
||||
Name="TargetingButton"
|
||||
VerticalExpand="True"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Right">
|
||||
<Control HorizontalAlignment="Right">
|
||||
<TextureRect
|
||||
Name="TargetDoll"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="96 96">
|
||||
<PanelContainer
|
||||
SetSize="57 96"
|
||||
Margin="18 0 0 0"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Left">
|
||||
<PanelContainer
|
||||
SetSize="18 39"
|
||||
Margin="0 7 0 0"
|
||||
HorizontalAlignment="Left">
|
||||
<TextureButton
|
||||
Name="RightArmButton"
|
||||
MinSize="18 30"
|
||||
StyleClasses="TargetDollButtonRightArm"
|
||||
VerticalAlignment="Top">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/rightarm.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="12 24"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"/>
|
||||
</TextureButton>
|
||||
<TextureButton
|
||||
Name="RightHandButton"
|
||||
MinSize="18 18"
|
||||
VerticalAlignment="Bottom"
|
||||
StyleClasses="TargetDollButtonRightHand">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/righthand.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="12 12"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"/>
|
||||
</TextureButton>
|
||||
</PanelContainer>
|
||||
<PanelContainer
|
||||
SetSize="51 90"
|
||||
Margin="0 64 0 0"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Center">
|
||||
<TextureButton
|
||||
Name="HeadButton"
|
||||
MinSize="33 27"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center"
|
||||
StyleClasses="TargetDollButtonHead">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/head.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="27 21"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"/>
|
||||
<!--<PanelContainer
|
||||
SetSize="15 15"
|
||||
Margin="0 9 0 0"
|
||||
HorizontalAlignment="Center">
|
||||
<TextureButton
|
||||
Name="EyesButton"
|
||||
MinSize="15 9"
|
||||
VerticalAlignment="Top"
|
||||
StyleClasses="TargetDollButtonEyes">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/eyes.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="15 9"/>
|
||||
</TextureButton>
|
||||
<TextureButton
|
||||
Name="MouthButton"
|
||||
SetSize="9 6"
|
||||
VerticalAlignment="Bottom"
|
||||
StyleClasses="TargetDollButtonMouth">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/mouth.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="9 6"/>
|
||||
</TextureButton>
|
||||
</PanelContainer>-->
|
||||
</TextureButton>
|
||||
<TextureButton
|
||||
Name="ChestButton"
|
||||
SetSize="33 36"
|
||||
Margin="0 21 0 0"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center"
|
||||
StyleClasses="TargetDollButtonChest">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/torso.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="27 30"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"/>
|
||||
</TextureButton>
|
||||
<PanelContainer
|
||||
MinSize="45 42"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Center">
|
||||
<TextureButton
|
||||
Name="GroinButton"
|
||||
MinSize="33 18"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center"
|
||||
StyleClasses="TargetDollButtonGroin">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/groin.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="27 12"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"/>
|
||||
</TextureButton>
|
||||
<PanelContainer
|
||||
MinSize="24 36"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Right">
|
||||
<TextureButton
|
||||
Name="LeftLegButton"
|
||||
MinSize="18 33"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Left"
|
||||
StyleClasses="TargetDollButtonLeftLeg">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/leftleg.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="12 27"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"/>
|
||||
</TextureButton>
|
||||
<TextureButton
|
||||
Name="LeftFootButton"
|
||||
MinSize="24 12"
|
||||
VerticalAlignment="Bottom"
|
||||
StyleClasses="TargetDollButtonLeftFoot">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/leftfoot.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="18 9"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"/>
|
||||
</TextureButton>
|
||||
</PanelContainer>
|
||||
<PanelContainer
|
||||
MinSize="24 36"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Left">
|
||||
<TextureButton
|
||||
Name="RightLegButton"
|
||||
MinSize="18 33"
|
||||
VerticalAlignment="Top"
|
||||
HorizontalAlignment="Right"
|
||||
StyleClasses="TargetDollButtonRightLeg">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/rightleg.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="12 27"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"/>
|
||||
</TextureButton>
|
||||
<TextureButton
|
||||
Name="RightFootButton"
|
||||
MinSize="24 12"
|
||||
VerticalAlignment="Bottom"
|
||||
HorizontalAlignment="Center"
|
||||
StyleClasses="TargetDollButtonRightFoot">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/rightfoot.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="18 9"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"/>
|
||||
</TextureButton>
|
||||
</PanelContainer>
|
||||
</PanelContainer>
|
||||
</PanelContainer>
|
||||
<PanelContainer
|
||||
SetSize="18 39"
|
||||
Margin="0 7 0 0"
|
||||
HorizontalAlignment="Right">
|
||||
<TextureButton
|
||||
Name="LeftArmButton"
|
||||
MinSize="18 30"
|
||||
StyleClasses="TargetDollButtonLeftArm"
|
||||
VerticalAlignment="Top">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/leftarm.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="12 24"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"/>
|
||||
</TextureButton>
|
||||
<TextureButton
|
||||
Name="LeftHandButton"
|
||||
MinSize="18 18"
|
||||
VerticalAlignment="Bottom"
|
||||
StyleClasses="TargetDollButtonLeftHand">
|
||||
<TextureRect
|
||||
TexturePath="/Textures/_Shitmed/Interface/Targeting/Doll/lefthand.png"
|
||||
Stretch="KeepAspectCentered"
|
||||
SetSize="12 12"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"/>
|
||||
</TextureButton>
|
||||
</PanelContainer>
|
||||
</PanelContainer>
|
||||
</TextureRect>
|
||||
</Control>
|
||||
</widgets:TargetingControl>
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
using System.Linq;
|
||||
using Content.Shared._Shitmed.Targeting;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._Shitmed.UserInterface.Systems.Targeting.Widgets;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class TargetingControl : UIWidget
|
||||
{
|
||||
private readonly TargetingUIController _controller;
|
||||
private readonly Dictionary<TargetBodyPart, TextureButton> _bodyPartControls;
|
||||
|
||||
public TargetingControl()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
_controller = UserInterfaceManager.GetUIController<TargetingUIController>();
|
||||
|
||||
_bodyPartControls = new Dictionary<TargetBodyPart, TextureButton>
|
||||
{
|
||||
// TODO: ADD EYE AND MOUTH TARGETING
|
||||
{ TargetBodyPart.Head, HeadButton },
|
||||
{ TargetBodyPart.Torso, ChestButton },
|
||||
{ TargetBodyPart.Groin, GroinButton },
|
||||
{ TargetBodyPart.LeftArm, LeftArmButton },
|
||||
{ TargetBodyPart.LeftHand, LeftHandButton },
|
||||
{ TargetBodyPart.RightArm, RightArmButton },
|
||||
{ TargetBodyPart.RightHand, RightHandButton },
|
||||
{ TargetBodyPart.LeftLeg, LeftLegButton },
|
||||
{ TargetBodyPart.LeftFoot, LeftFootButton },
|
||||
{ TargetBodyPart.RightLeg, RightLegButton },
|
||||
{ TargetBodyPart.RightFoot, RightFootButton },
|
||||
};
|
||||
|
||||
foreach (var bodyPartButton in _bodyPartControls)
|
||||
{
|
||||
bodyPartButton.Value.MouseFilter = MouseFilterMode.Stop;
|
||||
bodyPartButton.Value.OnPressed += _ => SetActiveBodyPart(bodyPartButton.Key);
|
||||
|
||||
TargetDoll.Texture = Theme.ResolveTexture("target_doll");
|
||||
}
|
||||
}
|
||||
|
||||
private void SetActiveBodyPart(TargetBodyPart bodyPart) => _controller.CycleTarget(bodyPart);
|
||||
|
||||
public void SetBodyPartsVisible(TargetBodyPart bodyPart)
|
||||
{
|
||||
foreach (var bodyPartButton in _bodyPartControls)
|
||||
bodyPartButton.Value.Children.First().Visible = bodyPartButton.Key == bodyPart;
|
||||
}
|
||||
|
||||
protected override void OnThemeUpdated() => TargetDoll.Texture = Theme.ResolveTexture("target_doll");
|
||||
|
||||
public void SetTargetDollVisible(bool visible) => Visible = visible;
|
||||
|
||||
}
|
||||
|
|
@ -47,11 +47,11 @@ public sealed class SaveLoadReparentTest
|
|||
var parts = bodySystem.GetBodyChildren(human).Skip(1).ToArray();
|
||||
var organs = bodySystem.GetBodyOrgans(human).ToArray();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(parts, Is.Not.Empty);
|
||||
Assert.That(organs, Is.Not.Empty);
|
||||
});
|
||||
// Assert.Multiple(() =>
|
||||
// {
|
||||
// Assert.That(parts, Is.Not.Empty);
|
||||
// Assert.That(organs, Is.Not.Empty);
|
||||
// });
|
||||
|
||||
foreach (var (id, component) in parts)
|
||||
{
|
||||
|
|
@ -132,11 +132,11 @@ public sealed class SaveLoadReparentTest
|
|||
parts = bodySystem.GetBodyChildren(human).Skip(1).ToArray();
|
||||
organs = bodySystem.GetBodyOrgans(human).ToArray();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(parts, Is.Not.Empty);
|
||||
Assert.That(organs, Is.Not.Empty);
|
||||
});
|
||||
// Assert.Multiple(() =>
|
||||
// {
|
||||
// Assert.That(parts, Is.Not.Empty);
|
||||
// Assert.That(organs, Is.Not.Empty);
|
||||
// });
|
||||
|
||||
foreach (var (id, component) in parts)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -315,9 +315,7 @@ namespace Content.IntegrationTests.Tests.Buckle
|
|||
await server.WaitAssertion(() =>
|
||||
{
|
||||
// Still buckled
|
||||
//Assert.That(buckle.Buckled); // goob edit
|
||||
// he's not supposed to be buckled with the new falling down system
|
||||
// do i just did this :trollface:
|
||||
Assert.That(buckle.Buckled);
|
||||
|
||||
// Still with items in hand
|
||||
foreach (var hand in hands.Hands.Keys)
|
||||
|
|
|
|||
|
|
@ -87,12 +87,8 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Mobs
|
|||
Assert.That(clientAlertsUI.AlertContainer.ChildCount, Is.GreaterThanOrEqualTo(3));
|
||||
var alertControls = clientAlertsUI.AlertContainer.Children.Select(c => (AlertControl) c);
|
||||
var alertIDs = alertControls.Select(ac => ac.Alert.ID).ToArray();
|
||||
// Goobstation - IPC have BorgHealth instead of HumanHealth
|
||||
var expectedDebugIDs = new[] { "Debug1", "Debug2" };
|
||||
var expectedHealthIDs = new[] { "BorgHealth", "HumanHealth" };
|
||||
|
||||
Assert.That(alertIDs, Is.SupersetOf(expectedDebugIDs));
|
||||
Assert.That(alertIDs, Has.Some.Matches<string>(item => expectedHealthIDs.Contains(item)));
|
||||
var expectedIDs = new[] { "HumanHealth", "Debug1", "Debug2" };
|
||||
Assert.That(alertIDs, Is.SupersetOf(expectedIDs));
|
||||
});
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
|
|
@ -108,12 +104,8 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Mobs
|
|||
Assert.That(clientAlertsUI.AlertContainer.ChildCount, Is.GreaterThanOrEqualTo(2));
|
||||
var alertControls = clientAlertsUI.AlertContainer.Children.Select(c => (AlertControl) c);
|
||||
var alertIDs = alertControls.Select(ac => ac.Alert.ID).ToArray();
|
||||
// Goobstation - IPC have BorgHealth instead of HumanHealth
|
||||
var expectedDebugIDs = new[] { "Debug2" };
|
||||
var expectedHealthIDs = new[] { "BorgHealth", "HumanHealth" };
|
||||
|
||||
Assert.That(alertIDs, Is.SupersetOf(expectedDebugIDs));
|
||||
Assert.That(alertIDs, Has.Some.Matches<string>(item => expectedHealthIDs.Contains(item)));
|
||||
var expectedIDs = new[] { "HumanHealth", "Debug2" };
|
||||
Assert.That(alertIDs, Is.SupersetOf(expectedIDs));
|
||||
});
|
||||
|
||||
await pair.CleanReturnAsync();
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ using Content.Shared.Station.Components;
|
|||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Content.Shared._EE.Silicon.Components; // Goobstation
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.GameRules;
|
||||
|
|
@ -230,15 +229,12 @@ public sealed class NukeOpsTest
|
|||
var totalSeconds = 30;
|
||||
var totalTicks = (int) Math.Ceiling(totalSeconds / server.Timing.TickPeriod.TotalSeconds);
|
||||
var increment = 5;
|
||||
var resp = entMan.GetComponent<RespiratorComponent>(player);
|
||||
var damage = entMan.GetComponent<DamageableComponent>(player);
|
||||
for (var tick = 0; tick < totalTicks; tick += increment)
|
||||
{
|
||||
await pair.RunTicksSync(increment);
|
||||
if (!entMan.HasComponent<SiliconComponent>(player)) // Goobstation - IPC
|
||||
{
|
||||
var resp = entMan.GetComponent<RespiratorComponent>(player);
|
||||
Assert.That(resp.SuffocationCycles, Is.LessThanOrEqualTo(resp.SuffocationCycleThreshold));
|
||||
}
|
||||
Assert.That(resp.SuffocationCycles, Is.LessThanOrEqualTo(resp.SuffocationCycleThreshold));
|
||||
Assert.That(damage.TotalDamage, Is.EqualTo(FixedPoint2.Zero));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Content.Shared.Humanoid.Prototypes;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.IntegrationTests.Tests._Shitmed.Body;
|
||||
|
||||
[TestFixture]
|
||||
public sealed class SpeciesBUiTest
|
||||
{
|
||||
[TestPrototypes]
|
||||
private const string Prototypes = @"
|
||||
- type: entity
|
||||
name: BaseMobSpeciesTest
|
||||
id: BaseMobSpeciesTest
|
||||
parent: BaseMobSpecies
|
||||
";
|
||||
|
||||
private Dictionary<Enum, InterfaceData> GetInterfaces(UserInterfaceComponent comp) =>
|
||||
(Dictionary<Enum, InterfaceData>)
|
||||
typeof(UserInterfaceComponent).GetField("Interfaces", BindingFlags.NonPublic | BindingFlags.Instance)!
|
||||
.GetValue(comp);
|
||||
|
||||
[Test]
|
||||
public async Task AllSpeciesHaveBaseBUiTest()
|
||||
{
|
||||
await using var pair = await PoolManager.GetServerClient(new PoolSettings
|
||||
{
|
||||
Dirty = true,
|
||||
Connected = false
|
||||
});
|
||||
|
||||
var server = pair.Server;
|
||||
var proto = server.ResolveDependency<IPrototypeManager>();
|
||||
var factoryComp = server.ResolveDependency<IComponentFactory>();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
var bUiSys = server.System<SharedUserInterfaceSystem>();
|
||||
|
||||
Assert.That(proto.TryIndex("BaseMobSpeciesTest", out var baseEnt), Is.True);
|
||||
Assert.That(baseEnt, Is.Not.Null);
|
||||
Assert.That(baseEnt.TryGetComponent<UserInterfaceComponent>(out var bUiBase, factoryComp), Is.True);
|
||||
Assert.That(bUiBase, Is.Not.Null);
|
||||
var baseKeys = GetInterfaces(bUiBase).Keys.ToArray();
|
||||
|
||||
foreach (var species in proto.EnumeratePrototypes<SpeciesPrototype>())
|
||||
{
|
||||
var ent = proto.Index(species.Prototype);
|
||||
Assert.That(ent.TryGetComponent<UserInterfaceComponent>(out var bUi, factoryComp), Is.True);
|
||||
Assert.That(bUi, Is.Not.Null);
|
||||
var states = GetInterfaces(bUiBase);
|
||||
foreach (var key in baseKeys)
|
||||
{
|
||||
Assert.That(states.ContainsKey(key), Is.True, $"Species {species.ID} has not UserInterface of type enum.{key.GetType().Name}");
|
||||
}
|
||||
}
|
||||
});
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@ public sealed partial class AdminVerbSystem
|
|||
private static readonly EntProtoId ParadoxCloneRuleId = "ParadoxCloneSpawn";
|
||||
private static readonly EntProtoId DefaultConspiratorRule = "Conspirators"; // Harmony
|
||||
private static readonly EntProtoId DefaultWizardRule = "Wizard";
|
||||
private static readonly EntProtoId DefaultHitmanRule = "HitmanRule";
|
||||
private static readonly EntProtoId DefaultNinjaRule = "NinjaSpawn";
|
||||
private static readonly ProtoId<StartingGearPrototype> PirateGearId = "PirateGear";
|
||||
|
||||
|
|
@ -262,7 +263,22 @@ public sealed partial class AdminVerbSystem
|
|||
};
|
||||
args.Verbs.Add(agent);
|
||||
// End DeltaV Additions
|
||||
|
||||
// start DeltaV Additions - add hitman
|
||||
var hitmanName = Loc.GetString("admin-verb-make-hitman");
|
||||
Verb hitman = new()
|
||||
{
|
||||
Text = hitmanName,
|
||||
Category = VerbCategory.Antag,
|
||||
Icon = new SpriteSpecifier.Rsi(new ResPath("/Textures/_DV/Interface/Misc/job_icons.rsi"), "Hitman"),
|
||||
Act = () =>
|
||||
{
|
||||
_antag.ForceMakeAntag<HitmanRuleComponent>(targetPlayer, DefaultHitmanRule);
|
||||
},
|
||||
Impact = LogImpact.High,
|
||||
Message = string.Join(": ", hitmanName, Loc.GetString("admin-verb-text-make-hitman")),
|
||||
};
|
||||
args.Verbs.Add(hitman);
|
||||
// end DeltaV additions - add hitman
|
||||
// Harmony start
|
||||
var conspiratorName = Loc.GetString("admin-verb-text-make-conspirator");
|
||||
Verb conspirator = new()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server._DV.Access.Systems; // DeltaV - Subdermal ID Cards
|
||||
using Content.Server.Cargo.Components;
|
||||
using Content.Server.Doors.Systems;
|
||||
using Content.Server.Hands.Systems;
|
||||
|
|
@ -57,6 +58,7 @@ public sealed partial class AdminVerbSystem
|
|||
[Dependency] private readonly MetaDataSystem _metaSystem = default!;
|
||||
[Dependency] private readonly GunSystem _gun = default!;
|
||||
[Dependency] private readonly RevenantAnimatedSystem _revenantAnimate = default!; // Imp
|
||||
[Dependency] private readonly SubdermalIdCardSystem _subdermalId = default!; // DeltaV - Subdermal ID Cards
|
||||
|
||||
private void AddTricksVerbs(GetVerbsEvent<Verb> args)
|
||||
{
|
||||
|
|
@ -869,6 +871,11 @@ public sealed partial class AdminVerbSystem
|
|||
}
|
||||
}
|
||||
|
||||
// Begin DeltaV Additions - Subdermal ID chips
|
||||
if (_subdermalId.TryGetIdCard(target, out var idEntity))
|
||||
return idEntity;
|
||||
// End DeltaV Additions - Subdermal ID chips
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||
if (pressure <= Atmospherics.HazardLowPressure)
|
||||
{
|
||||
// Deal damage and ignore resistances. Resistance to pressure damage should be done via pressure protection gear.
|
||||
_damageableSystem.TryChangeDamage(uid, barotrauma.Damage * Atmospherics.LowPressureDamage, true, false, canSever: false, partMultiplier: 0.2f); // Shitmed Change
|
||||
_damageableSystem.TryChangeDamage(uid, barotrauma.Damage * Atmospherics.LowPressureDamage, true, false);
|
||||
|
||||
if (!barotrauma.TakingDamage)
|
||||
{
|
||||
|
|
@ -254,7 +254,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||
var damageScale = MathF.Min(((pressure / Atmospherics.HazardHighPressure) - 1) * Atmospherics.PressureDamageCoefficient, Atmospherics.MaxHighPressureDamage);
|
||||
|
||||
// Deal damage and ignore resistances. Resistance to pressure damage should be done via pressure protection gear.
|
||||
_damageableSystem.TryChangeDamage(uid, barotrauma.Damage * damageScale, true, false, canSever: false); // Shitmed Change
|
||||
_damageableSystem.TryChangeDamage(uid, barotrauma.Damage * damageScale, true, false);
|
||||
|
||||
if (!barotrauma.TakingDamage)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -141,10 +141,7 @@ namespace Content.Server.Body.Commands
|
|||
if (attachAt == default)
|
||||
attachAt = bodySystem.GetBodyChildren(entity, body).First();
|
||||
|
||||
// Shitmed Change Start
|
||||
var slotId = $"{part.Symmetry.ToString().ToLower()} {part.GetHashCode().ToString()}";
|
||||
part.SlotId = part.GetHashCode().ToString();
|
||||
// Shitmed Change End
|
||||
var slotId = part.GetHashCode().ToString();
|
||||
|
||||
if (!bodySystem.TryCreatePartSlotAndAttach(attachAt.Id, slotId, hand, BodyPartType.Hand, attachAt.Component, part))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -98,15 +98,8 @@ namespace Content.Server.Body.Commands
|
|||
return;
|
||||
}
|
||||
|
||||
// Shitmed Change Start
|
||||
var slotId = "";
|
||||
if (part.Symmetry != BodyPartSymmetry.None)
|
||||
slotId = $"{part.Symmetry.ToString().ToLower()} {part.GetHashCode().ToString()}";
|
||||
else
|
||||
slotId = $"{part.GetHashCode().ToString()}";
|
||||
var slotId = $"AttachBodyPartVerb-{partUid}";
|
||||
|
||||
part.SlotId = part.GetHashCode().ToString();
|
||||
// Shitmed Change End
|
||||
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
|
||||
if (body.RootContainer.ContainedEntity != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using System.Numerics;
|
||||
using Content.Server.Ghost;
|
||||
using Content.Server.Humanoid;
|
||||
using Content.Shared._Shitmed.Body.Part;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Events;
|
||||
using Content.Shared.Body.Part;
|
||||
|
|
@ -19,10 +18,6 @@ using Content.Server.Polymorph.Components; // DeltaV
|
|||
using Content.Server.Polymorph.Systems; // DeltaV
|
||||
using Content.Shared.Damage.Components;
|
||||
|
||||
// Shitmed Change
|
||||
using System.Linq;
|
||||
using Content.Shared.Damage;
|
||||
|
||||
namespace Content.Server.Body.Systems;
|
||||
|
||||
public sealed class BodySystem : SharedBodySystem
|
||||
|
|
@ -31,7 +26,6 @@ public sealed class BodySystem : SharedBodySystem
|
|||
[Dependency] private readonly GhostSystem _ghostSystem = default!;
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
[Dependency] private readonly HumanoidAppearanceSystem _humanoidSystem = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!; // Shitmed Change
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly SharedMindSystem _mindSystem = default!;
|
||||
[Dependency] private readonly PolymorphSystem _polymorph = default!;
|
||||
|
|
@ -86,7 +80,7 @@ public sealed class BodySystem : SharedBodySystem
|
|||
}
|
||||
}
|
||||
|
||||
public override void RemovePart( // DeltaV - Made public
|
||||
protected override void RemovePart(
|
||||
Entity<BodyComponent?> bodyEnt,
|
||||
Entity<BodyPartComponent> partEnt,
|
||||
string slotId)
|
||||
|
|
@ -103,31 +97,5 @@ public sealed class BodySystem : SharedBodySystem
|
|||
|
||||
var layers = HumanoidVisualLayersExtension.Sublayers(layer.Value);
|
||||
_humanoidSystem.SetLayersVisibility((bodyEnt, humanoid), layers, visible: false);
|
||||
_appearance.SetData(bodyEnt, layer, true); // Shitmed Change
|
||||
}
|
||||
|
||||
// Shitmed Change Start
|
||||
protected override void ApplyPartMarkings(EntityUid target, BodyPartAppearanceComponent component)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
protected override void RemoveBodyMarkings(EntityUid target, BodyPartAppearanceComponent partAppearance, HumanoidAppearanceComponent bodyAppearance)
|
||||
{
|
||||
foreach (var (visualLayer, markingList) in partAppearance.Markings)
|
||||
foreach (var marking in markingList)
|
||||
_humanoidSystem.RemoveMarking(target, marking.MarkingId, sync: false, humanoid: bodyAppearance);
|
||||
|
||||
Dirty(target, bodyAppearance);
|
||||
}
|
||||
|
||||
protected override void PartRemoveDamage(Entity<BodyComponent?> bodyEnt, Entity<BodyPartComponent> partEnt)
|
||||
{
|
||||
var bleeding = partEnt.Comp.SeverBleeding;
|
||||
if (partEnt.Comp.IsVital)
|
||||
bleeding *= 2f;
|
||||
TryComp<BloodstreamComponent>(bodyEnt, out var bloodstream);
|
||||
_bloodstream.TryModifyBleedAmount((bodyEnt, bloodstream), bleeding);
|
||||
}
|
||||
// Shitmed Change End
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
using Content.Server.Administration.Logs;
|
||||
using Content.Server.Atmos.EntitySystems;
|
||||
using Content.Server.Body.Components;
|
||||
using Content.Shared._Shitmed.Body.Components; // Shitmed Change
|
||||
using Content.Shared._Shitmed.Body.Organ; // Shitmed Change
|
||||
using Content.Server.Chat.Systems;
|
||||
using Content.Shared._DV.Body.Components; // DeltaV - Addition of CPR
|
||||
using Content.Shared.Body.Systems;
|
||||
|
|
@ -29,7 +27,6 @@ using Robust.Shared.Timing;
|
|||
using Content.Shared._DV.CosmicCult.Components; // DeltaV
|
||||
using Content.Shared._Goobstation.Body.Components; // Goobstation
|
||||
|
||||
|
||||
namespace Content.Server.Body.Systems;
|
||||
|
||||
[UsedImplicitly]
|
||||
|
|
@ -84,7 +81,7 @@ public sealed class RespiratorSystem : EntitySystem
|
|||
|
||||
respirator.NextUpdate += respirator.AdjustedUpdateInterval;
|
||||
|
||||
if (_mobState.IsDead(uid) || HasComp<BreathingImmunityComponent>(uid) || HasComp<SpecialBreathingImmunityComponent>(uid)) // Shitmed: BreathingImmunity Goob immunity too
|
||||
if (_mobState.IsDead(uid) || HasComp<SpecialBreathingImmunityComponent>(uid)) // Shitmed: BreathingImmunity Goob immunity too
|
||||
continue;
|
||||
|
||||
// Begin DeltaV Additions
|
||||
|
|
@ -98,8 +95,7 @@ public sealed class RespiratorSystem : EntitySystem
|
|||
UpdateSaturation(uid, multiplier * (float) respirator.UpdateInterval.TotalSeconds, respirator); // DeltaV: use multiplier instead of negating
|
||||
|
||||
if ((!_mobState.IsIncapacitated(uid)
|
||||
|| TryComp<AffectedByCPRComponent>(uid, out var cprComp) && cprComp.IsActive) // DeltaV - Addition of CPR
|
||||
&& !HasComp<DebrainedComponent>(uid)) // Shitmed Change - Cannot breathe in crit or when no brain.
|
||||
|| TryComp<AffectedByCPRComponent>(uid, out var cprComp) && cprComp.IsActive)) // DeltaV - Addition of CPR.
|
||||
{
|
||||
switch (respirator.Status)
|
||||
{
|
||||
|
|
@ -386,8 +382,7 @@ public sealed class RespiratorSystem : EntitySystem
|
|||
if (ent.Comp.SuffocationCycles == 2)
|
||||
_adminLogger.Add(LogType.Asphyxiation, $"{ToPrettyString(ent):entity} started suffocating");
|
||||
|
||||
var suffocationDamage = HasComp<DebrainedComponent>(ent) ? ent.Comp.Damage * 4.5f : ent.Comp.Damage; // Shitmed Change - Increased damage for debrained
|
||||
_damageableSys.ChangeDamage(ent.Owner, suffocationDamage, interruptsDoAfters: false, ignoreResistances: true); // Shitmed Change
|
||||
_damageableSys.ChangeDamage(ent.Owner, ent.Comp.Damage, interruptsDoAfters: false, ignoreResistances: true); // Shitmed Change
|
||||
|
||||
if (ent.Comp.SuffocationCycles < ent.Comp.SuffocationCycleThreshold)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using Content.Shared.CCVar;
|
|||
using Content.Shared.Chat;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Mind;
|
||||
using Content.Shared.Players; // DeltaV - OOC muting
|
||||
using Content.Shared.Players.RateLimiting;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Network;
|
||||
|
|
@ -283,6 +284,11 @@ internal sealed partial class ChatManager : IChatManager
|
|||
return;
|
||||
}
|
||||
|
||||
// DeltaV - OOC muting START
|
||||
if (player.ContentData() is { OocMuted: true })
|
||||
return;
|
||||
// DeltaV END
|
||||
|
||||
Color? colorOverride = null;
|
||||
var wrappedMessage = Loc.GetString("chat-manager-send-ooc-wrap-message", ("playerName",player.Name), ("message", FormattedMessage.EscapeText(message)));
|
||||
if (_adminManager.HasAdminFlag(player, AdminFlags.Admin))
|
||||
|
|
|
|||
|
|
@ -92,6 +92,8 @@ public sealed class ChatSanitizationManager : IChatSanitizationManager
|
|||
Entry("[':", "chatsan-tearfully-smiles"),
|
||||
Entry("('=", "chatsan-tearfully-smiles"),
|
||||
Entry("['=", "chatsan-tearfully-smiles"),
|
||||
Entry("?", "chatsan-confused"), //DeltaV
|
||||
Entry("…", "chatsan-sighs"), //DeltaV (note that ... doesn't work as that turns into a radio message)
|
||||
];
|
||||
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue