Skip to content

Commit

Permalink
Photocopier refactor episode 2
Browse files Browse the repository at this point in the history
  • Loading branch information
TheArturZh committed Jun 27, 2023
1 parent f195c40 commit ea33a55
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 97 deletions.
13 changes: 6 additions & 7 deletions Content.Client/SS220/ButtScan/UI/ButtScanWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,15 @@ public sealed partial class ButtScanWindow : PaperWindow
private readonly Thickness _buttRectMargin = new(25, 25);

public readonly TextureRect ButtTextureRect;
private readonly Control Layers;

public ButtScanWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);

Layers = new Control();
Layers.HorizontalExpand = true;
Layers.VerticalExpand = true;
var layers = new Control();
layers.HorizontalExpand = true;
layers.VerticalExpand = true;

ButtTextureRect = new TextureRect();
ButtTextureRect.Stretch = TextureRect.StretchMode.Scale;
Expand All @@ -40,10 +39,10 @@ public ButtScanWindow()
ButtTextureRect.HorizontalAlignment = HAlignment.Center;
ButtTextureRect.VerticalAlignment = VAlignment.Center;

PaperBackground.AddChild(Layers);
PaperBackground.AddChild(layers);
ScrollingContents.Orphan();
Layers.AddChild(ButtTextureRect);
Layers.AddChild(ScrollingContents);
layers.AddChild(ButtTextureRect);
layers.AddChild(ScrollingContents);
}

public void InitVisuals(ButtScanComponent scan, PaperVisualsComponent visuals)
Expand Down
6 changes: 0 additions & 6 deletions Content.Client/SS220/Photocopier/PhotocopierBoundUi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ protected override void Open()
_window.CopyButtonPressed += OnCopyButtonPressed;
_window.EjectButtonPressed += OnEjectButtonPressed;
_window.StopButtonPressed += OnStopButtonPressed;
_window.RefreshButtonPressed += OnRefreshButtonPressed;
}

private void OnRefreshButtonPressed()
{
SendMessage(new PhotocopierRefreshUiMessage());
}

private void OnPrintButtonPressed(int amount, FormDescriptor descriptor)
Expand Down
12 changes: 1 addition & 11 deletions Content.Client/SS220/Photocopier/UI/PhotocopierWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,6 @@
HorizontalAlignment="Right"
Align="End">

<ui:IconButton
Name="RefreshButton"
Margin="0 0 2 0"
SetWidth="64"
IconTexture="/Textures/SS220/Interface/Misc/alternate-sync.png"
HorizontalExpand="True"
VerticalExpand="True"
ToolTip="{Loc 'photocopier-ui-refresh-button'}"
StyleClasses="OpenRight"/>
<ui:IconButton
Name="EjectButton"
Margin="0 0"
Expand All @@ -118,8 +109,7 @@
Disabled="True"
HorizontalExpand="True"
VerticalExpand="True"
ToolTip="{Loc 'photocopier-ui-eject-button'}"
StyleClasses="OpenLeft"/>
ToolTip="{Loc 'photocopier-ui-eject-button'}"/>
</BoxContainer>
</BoxContainer>
<Button Name="CopyButton"
Expand Down
2 changes: 0 additions & 2 deletions Content.Client/SS220/Photocopier/UI/PhotocopierWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public sealed partial class PhotocopierWindow : FancyWindow
public event Action? StopButtonPressed;
public event Action<int>? CopyButtonPressed;
public event Action<int, FormDescriptor>? PrintButtonPressed;
public event Action? RefreshButtonPressed;

// State
private int _copyAmount = 1;
Expand Down Expand Up @@ -69,7 +68,6 @@ public PhotocopierWindow()
EjectButton.OnPressed += _ => EjectButtonPressed?.Invoke();
CopyButton.OnPressed += _ => CopyButtonPressed?.Invoke(_copyAmount);
StopButton.OnPressed += _ => StopButtonPressed?.Invoke();
RefreshButton.OnPressed += _ => RefreshButtonPressed?.Invoke();
SearchBar.OnTextChanged += _ => RepopulateTreeWithAvailableCollections();
}

Expand Down
96 changes: 46 additions & 50 deletions Content.Server/SS220/Photocopier/PhotocopierSystem.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt

using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Server.Chat.Systems;
using Content.Shared.SS220.Photocopier;
using Content.Shared.Containers.ItemSlots;
Expand All @@ -18,8 +17,8 @@
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Popups;
using Content.Shared.SS220.ButtScan;
using Content.Shared.SS220.ShapeCollisionTracker;
using Robust.Shared.Containers;
using Robust.Shared.Physics.Systems;
using Robust.Server.GameObjects;
using Robust.Shared.Prototypes;

Expand All @@ -32,8 +31,6 @@ public sealed partial class PhotocopierSystem : EntitySystem
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly EntityLookupSystem _entityLookup = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly PopupSystem _popup = default!;
Expand All @@ -56,14 +53,14 @@ public override void Initialize()
SubscribeLocalEvent<PhotocopierComponent, EntRemovedFromContainerMessage>(OnItemSlotChanged);
SubscribeLocalEvent<PhotocopierComponent, PowerChangedEvent>(OnPowerChanged);
SubscribeLocalEvent<PhotocopierComponent, GotEmaggedEvent>(OnEmagged);
SubscribeLocalEvent<PhotocopierComponent, ShapeCollisionTrackerUpdatedEvent>(OnCollisionChanged);

// UI
SubscribeLocalEvent<PhotocopierComponent, AfterActivatableUIOpenEvent>(OnToggleInterface);
SubscribeLocalEvent<PhotocopierComponent, PhotocopierPrintMessage>(OnPrintButtonPressed);
SubscribeLocalEvent<PhotocopierComponent, PhotocopierCopyMessage>(OnCopyButtonPressed);
SubscribeLocalEvent<PhotocopierComponent, PhotocopierStopMessage>(OnStopButtonPressed);
SubscribeLocalEvent<PhotocopierComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<PhotocopierComponent, PhotocopierRefreshUiMessage>(OnRefreshUiMessage);
}

/// <inheritdoc/>
Expand All @@ -81,41 +78,6 @@ public override void Update(float frameTime)
}
}

/// <summary>
/// Try to get a HumanoidAppearanceComponent of one of the creatures that are on top of the photocopier at the moment.
/// Returns null if there are none.
/// </summary>
private bool TryGetHumanoidOnTop(
EntityUid uid,
[NotNullWhen(true)] out HumanoidAppearanceComponent? humanoidAppearance)
{
if (!TryComp<TransformComponent>(uid, out var xform))
{
humanoidAppearance = null;
return false;
}

var map = xform.MapID;
var bounds = _physics.GetWorldAABB(uid);

// We shrink the box greatly to ensure it only intersects with the objects that are on top of the photocopier.
// May be a hack, but at least it works reliably (on my computer)

// lerp alpha (effective alpha will be twice as big since we perform lerp on both corners)
const float shrinkCoefficient = 0.4f;
// lerp corners towards each other
var boundsTR = bounds.TopRight;
var boundsBL = bounds.BottomLeft;
bounds.TopRight = (boundsBL - boundsTR) * shrinkCoefficient + boundsTR;
bounds.BottomLeft = (boundsTR - boundsBL) * shrinkCoefficient + boundsBL;

var intersecting = _entityLookup.GetComponentsIntersecting<HumanoidAppearanceComponent>(
map, bounds, LookupFlags.Dynamic | LookupFlags.Sundries);

humanoidAppearance = intersecting.Count > 0 ? intersecting.ElementAt(0) : null;
return humanoidAppearance is not null;
}

/// <summary>
/// Tries to get toner cartridge from toner cartridge slot of specified component
/// </summary>
Expand Down Expand Up @@ -146,6 +108,37 @@ private void OnComponentRemove(EntityUid uid, PhotocopierComponent component, Co
_itemSlots.RemoveItemSlot(uid, component.TonerSlot);
}

private void OnCollisionChanged(
EntityUid uid,
PhotocopierComponent component,
ShapeCollisionTrackerUpdatedEvent args)
{
if (component.EntityOnTop is { } currentEntity &&
component.HumanoidAppearanceOnTop is not null &&
args.Colliding.Contains(currentEntity) &&
!Deleted(currentEntity))
{
return;
}
else
{
component.EntityOnTop = null;
component.HumanoidAppearanceOnTop = null;
}

foreach (var otherEntity in args.Colliding)
{
if (!TryComp<HumanoidAppearanceComponent>(otherEntity, out var humanoidAppearance))
continue;

component.HumanoidAppearanceOnTop = humanoidAppearance;
component.EntityOnTop = otherEntity;
break;
}

UpdateUserInterface(uid, component);
}

private void OnToggleInterface(EntityUid uid, PhotocopierComponent component, AfterActivatableUIOpenEvent args)
{
UpdateUserInterface(uid, component);
Expand Down Expand Up @@ -204,12 +197,13 @@ private void OnCopyButtonPressed(EntityUid uid, PhotocopierComponent component,
if (TryQueueCopySlot(uid, component, args.Amount))
return;

if (!TryGetHumanoidOnTop(uid, out var humanoidOnScanner))
if (component.EntityOnTop is not { } entityOnTop ||
component.HumanoidAppearanceOnTop is not { } humanoidAppearanceOnTop)
return;

TryQueueCopyPhysicalButt(uid, component, humanoidOnScanner, args.Amount);
TryQueueCopyPhysicalButt(uid, component, humanoidAppearanceOnTop, args.Amount);
if (HasComp<EmaggedComponent>(uid))
BurnButt(humanoidOnScanner.Owner, uid, component);
BurnButt(entityOnTop, uid, component);
}

private void OnPrintButtonPressed(EntityUid uid, PhotocopierComponent component, PhotocopierPrintMessage args)
Expand Down Expand Up @@ -239,11 +233,6 @@ private void OnStopButtonPressed(EntityUid uid, PhotocopierComponent component,
StopPrinting(uid, component);
}

private void OnRefreshUiMessage(EntityUid uid, PhotocopierComponent component, PhotocopierRefreshUiMessage args)
{
UpdateUserInterface(uid, component);
}

private void OnEmagged(EntityUid uid, PhotocopierComponent component, ref GotEmaggedEvent args)
{
_audio.PlayPvs(component.EmagSound, uid);
Expand All @@ -252,6 +241,13 @@ private void OnEmagged(EntityUid uid, PhotocopierComponent component, ref GotEma

#endregion

private bool IsHumanoidOnTop(PhotocopierComponent component)
{
return component.HumanoidAppearanceOnTop is not null &&
component.EntityOnTop is { } entityOnTop &&
!Deleted(entityOnTop);
}

/// <summary>
/// Makes the photocopier burn the butt of a mob.
/// </summary>
Expand Down Expand Up @@ -399,7 +395,7 @@ private void ProcessPrinting(EntityUid uid, float frameTime, PhotocopierComponen
if (component.IsCopyingPhysicalButt)
{
// If there is no butt or someones else butt is in the way - stop copying.
if (!TryGetHumanoidOnTop(uid, out var humanoid)
if (component.HumanoidAppearanceOnTop is not { } humanoid
|| component.ButtSpecies != humanoid.Species)
{
StopPrinting(uid, component);
Expand Down Expand Up @@ -501,7 +497,7 @@ private void UpdateUserInterface(EntityUid uid, PhotocopierComponent? component
}

var isPaperInserted = component.PaperSlot.Item is not null;
var assIsOnScanner = TryGetHumanoidOnTop(uid, out _);
var assIsOnScanner = IsHumanoidOnTop(component);

var state = new PhotocopierUiState(
component.PaperSlot.Locked,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using System.Collections.Immutable;
using Content.Shared.Physics;
using Content.Shared.SS220.ShapeCollisionTracker;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events;
using Robust.Shared.Physics.Systems;

namespace Content.Server.SS220.ShapeCollisionTracker;

public sealed class ShapeCollisionTrackerSystem : EntitySystem
{
[Dependency] private readonly SharedBroadphaseSystem _broadphase = default!;
[Dependency] private readonly FixtureSystem _fixtures = default!;

/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<ShapeCollisionTrackerComponent, StartCollideEvent>(OnStartCollide);
SubscribeLocalEvent<ShapeCollisionTrackerComponent, EndCollideEvent>(OnEndCollide);
SubscribeLocalEvent<ShapeCollisionTrackerComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<ShapeCollisionTrackerComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<ShapeCollisionTrackerComponent, AnchorStateChangedEvent>(OnAnchor);
}

private void OnAnchor(
EntityUid uid,
ShapeCollisionTrackerComponent component,
ref AnchorStateChangedEvent args)
{
component.Enabled = !component.RequiresAnchored ||
args.Anchored;

if (!component.Enabled)
{
component.Colliding.Clear();
}
// Re-check for contacts as we cleared them.
else if (TryComp<PhysicsComponent>(uid, out var body))
{
_broadphase.RegenerateContacts(uid, body);
}
}

private void OnStartCollide(
EntityUid uid,
ShapeCollisionTrackerComponent component,
ref StartCollideEvent args)
{
if (args.OurFixture.ID != ShapeCollisionTrackerComponent.FixtureID)
return;

component.Colliding.Add(args.OtherEntity);
RaiseLocalEvent(uid, new ShapeCollisionTrackerUpdatedEvent(component.Colliding.ToImmutableHashSet()));
}

private void OnEndCollide(
EntityUid uid,
ShapeCollisionTrackerComponent component,
ref EndCollideEvent args)
{
if (args.OurFixture.ID != ShapeCollisionTrackerComponent.FixtureID)
return;

component.Colliding.Remove(args.OtherEntity);
RaiseLocalEvent(uid, new ShapeCollisionTrackerUpdatedEvent(component.Colliding.ToImmutableHashSet()));
}

private void OnMapInit(
EntityUid uid,
ShapeCollisionTrackerComponent component,
MapInitEvent args)
{
component.Enabled = !component.RequiresAnchored ||
EntityManager.GetComponent<TransformComponent>(uid).Anchored;

if (!TryComp<PhysicsComponent>(uid, out _))
return;

_fixtures.TryCreateFixture(
uid,
component.Shape,
ShapeCollisionTrackerComponent.FixtureID,
hard: false,
collisionLayer: (int) (CollisionGroup.MidImpassable | CollisionGroup.LowImpassable | CollisionGroup.HighImpassable));
}

private static void OnShutdown(
EntityUid uid,
ShapeCollisionTrackerComponent component,
ComponentShutdown args)
{
component.Colliding.Clear();
}
}
Loading

0 comments on commit ea33a55

Please sign in to comment.