Skip to content

Commit

Permalink
move rejecting to offerings, remove rescan (automatic now)
Browse files Browse the repository at this point in the history
  • Loading branch information
deltanedas committed Feb 11, 2025
1 parent d022a2e commit 5476033
Show file tree
Hide file tree
Showing 15 changed files with 261 additions and 154 deletions.
5 changes: 1 addition & 4 deletions Content.Client/_DV/Reputation/UI/Contract.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,5 @@
MinHeight="64"
Margin="5">
<Label Name="Title" HorizontalExpand="True"/> <!-- Set in constructor -->
<BoxContainer Orientation="Vertical">
<Button Name="CompleteButton" Text="Complete"/>
<Button Name="RejectButton" Text="Reject"/>
</BoxContainer>
<Button Name="CompleteButton" Text="Complete" Margin="5"/>
</BoxContainer>
4 changes: 0 additions & 4 deletions Content.Client/_DV/Reputation/UI/Contract.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace Content.Client._DV.Reputation.UI;
public sealed partial class Contract : BoxContainer
{
public event Action? OnComplete;
public event Action? OnReject;

public Contract(string title)
{
Expand All @@ -20,8 +19,5 @@ public Contract(string title)
Title.Text = title;

CompleteButton.OnPressed += _ => OnComplete?.Invoke();
RejectButton.OnPressed += _ => OnReject?.Invoke();

OnReject += () => Orphan(); // this will always remove the contract so predict it
}
}
17 changes: 17 additions & 0 deletions Content.Client/_DV/Reputation/UI/ContractOffering.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<BoxContainer xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:rep="clr-namespace:Content.Client._DV.Reputation.UI"
Orientation="Horizontal"
HorizontalExpand="true"
Align="Center"
MinHeight="48"
Margin="5">
<BoxContainer Orientation="Vertical" HorizontalExpand="True" Margin="5">
<Label Name="Title"/> <!-- Set in constructor -->
<rep:UnlockLabel Name="UnlockLabel"/>
</BoxContainer>
<BoxContainer Name="ButtonsContainer" Orientation="Vertical">
<Button Name="AcceptButton" Text="{Loc 'contracts-accept'}"/>
<Button Name="RejectButton" Text="{Loc 'contracts-reject'}"/>
</BoxContainer>
</BoxContainer>
48 changes: 48 additions & 0 deletions Content.Client/_DV/Reputation/UI/ContractOffering.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Content.Shared._DV.Reputation;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;

namespace Content.Client._DV.Reputation.UI;

/// <summary>
/// Contract control placed in a slot that with no contract.
/// </summary>
[GenerateTypedNameReferences]
public sealed partial class ContractOffering : BoxContainer
{
public event Action? OnAccept;
public event Action? OnReject;
public event Action? OnUnlock;

public bool AcceptDisabled
{
get
{
return AcceptButton.Disabled;
}
set
{
AcceptButton.Disabled = value;
}
}

public ContractOffering(OfferingSlot slot)
{
RobustXamlLoader.Load(this);

if (slot.Title is {} title)
Title.Text = title;
else
Title.Visible = false;

UnlockLabel.NextUnlock = slot.NextUnlock;
UnlockLabel.OnUnlock += () => OnUnlock?.Invoke();

OnUnlock += () => ButtonsContainer.Visible = true;
ButtonsContainer.Visible = !UnlockLabel.IsLocked;

AcceptButton.OnPressed += _ => OnAccept?.Invoke();
RejectButton.OnPressed += _ => OnReject?.Invoke();
}
}
1 change: 0 additions & 1 deletion Content.Client/_DV/Reputation/UI/ContractsBUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ protected override void Open()
_window.OnAccept += i => SendMessage(new ContractsAcceptMessage(i));
_window.OnComplete += i => SendMessage(new ContractsCompleteMessage(i));
_window.OnReject += i => SendMessage(new ContractsRejectMessage(i));
_window.OnRescan += () => SendMessage(new ContractsRescanMessage());
_window.OnClose += Close;
_window.OpenCentered();
}
Expand Down
7 changes: 1 addition & 6 deletions Content.Client/_DV/Reputation/UI/ContractsWindow.xaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
MinSize="450 400"
MinSize="500 400"
Title="{Loc 'contracts-menu-title'}">
<BoxContainer Orientation="Vertical">
<controls:StripeBack>
Expand All @@ -16,10 +16,5 @@
<Label Text="{Loc 'contracts-offerings'}" Align="Right" Margin="5"/>
<controls:HLine Color="#404040" Thickness="2" Margin="0 5 0 5"/>
<BoxContainer Name="Offerings" Orientation="Vertical" HorizontalExpand="True" Margin="5"/> <!-- Populated at runtime -->
<BoxContainer Name="RescanContainer" Orientation="Horizontal" Align="Center" Visible="False">
<controls:StripeBack HorizontalExpand="True">
<Button Name="RescanButton" Text="{Loc 'contracts-rescan'}" MaxWidth="150"/>
</controls:StripeBack>
</BoxContainer>
</BoxContainer>
</controls:FancyWindow>
30 changes: 14 additions & 16 deletions Content.Client/_DV/Reputation/UI/ContractsWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@ public sealed partial class ContractsWindow : FancyWindow
public event Action<int>? OnAccept;
public event Action<int>? OnComplete;
public event Action<int>? OnReject;
public event Action? OnRescan;

public EntityUid Owner;

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

RescanButton.OnPressed += _ => OnRescan?.Invoke();
}

public void UpdateState()
Expand All @@ -45,35 +42,36 @@ public void UpdateState()
{
var contract = new Contract(title);
contract.OnComplete += () => OnComplete?.Invoke(index);
contract.OnReject += () => OnReject?.Invoke(index);
Contracts.AddChild(contract);
// TODO: green when objective is complete
}
else
{
var empty = new EmptyContract(comp.Slots[i].NextUnlock);
empty.OnUnlock += UpdateState;
empty.OnUnlock += EnableAccepts;
if (!empty.IsLocked)
slotsFull = false;
Contracts.AddChild(empty);
}
}

Offerings.RemoveAllChildren();
for (int i = 0; i < comp.OfferingTitles.Count; i++)
for (int i = 0; i < comp.OfferingSlots.Count; i++)
{
var index = i;
var offering = comp.OfferingTitles[i];
var button = new Button()
{
Text = offering
};
button.OnPressed += _ => OnAccept?.Invoke(index);
button.Disabled = slotsFull;
Offerings.AddChild(button);
var offering = new ContractOffering(comp.OfferingSlots[i]);
offering.AcceptDisabled = slotsFull;
offering.OnAccept += () => OnAccept?.Invoke(index);
offering.OnReject += () => OnReject?.Invoke(index);
Offerings.AddChild(offering);
}
}

// failsafe incase of bad rng or whatever not giving you anything
RescanContainer.Visible = comp.OfferingTitles.Count == 0;
private void EnableAccepts()
{
foreach (var child in Offerings.Children)
{
((ContractOffering) child).AcceptDisabled = false;
}
}
}
3 changes: 2 additions & 1 deletion Content.Client/_DV/Reputation/UI/EmptyContract.xaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<BoxContainer xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:rep="clr-namespace:Content.Client._DV.Reputation.UI"
Orientation="Vertical"
HorizontalExpand="true"
Align="Center"
MinHeight="64"
Margin="5">
<Label Text="{Loc 'contract-slot-empty'}" HorizontalExpand="True"/>
<Label Name="UnlockLabel" HorizontalExpand="True" Visible="False"/> <!-- Set in UpdateUnlock -->
<rep:UnlockLabel Name="UnlockLabel"/>
</BoxContainer>
48 changes: 3 additions & 45 deletions Content.Client/_DV/Reputation/UI/EmptyContract.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Timing;

namespace Content.Client._DV.Reputation.UI;

Expand All @@ -11,56 +10,15 @@ namespace Content.Client._DV.Reputation.UI;
[GenerateTypedNameReferences]
public sealed partial class EmptyContract : BoxContainer
{
[Dependency] private readonly IGameTiming _timing = default!;

public event Action? OnUnlock;

private TimeSpan? _nextUnlock;
private TimeSpan _nextUpdate;

public bool IsLocked => UnlockLabel.Visible;
public bool IsLocked => UnlockLabel.IsLocked;

public EmptyContract(TimeSpan? nextUnlock)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);

_nextUnlock = nextUnlock;
_nextUpdate = _timing.CurTime;

UpdateUnlock();
}

private void UpdateUnlock()
{
if (_nextUnlock is not {} next)
return;

var now = _timing.CurTime;
if (now >= next)
{
// unlocked now
_nextUnlock = null;
UnlockLabel.Visible = false;
OnUnlock?.Invoke();
return;
}

UnlockLabel.Visible = true;
var remaining = next - now;
var time = $"{remaining.Minutes:00}:{remaining.Seconds:00}";
UnlockLabel.Text = Loc.GetString("contract-next-unlock", ("time", time));
}

protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);

var now = _timing.CurTime;
if (now < _nextUpdate)
return;

_nextUpdate = now + TimeSpan.FromSeconds(1);
UpdateUnlock();
UnlockLabel.NextUnlock = nextUnlock;
UnlockLabel.OnUnlock += () => OnUnlock?.Invoke();
}
}
73 changes: 73 additions & 0 deletions Content.Client/_DV/Reputation/UI/UnlockLabel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Timing;

namespace Content.Client._DV.Reputation.UI;

/// <summary>
/// Label that updates for an unlock timer automatically.
/// </summary>
public sealed class UnlockLabel : Label
{
[Dependency] private readonly IGameTiming _timing = default!;

public event Action? OnUnlock;

private TimeSpan? _nextUnlock;
private TimeSpan _nextUpdate;

public TimeSpan? NextUnlock
{
get
{
return _nextUnlock;
}
set
{
_nextUnlock = value;
_nextUpdate = _timing.CurTime;
UpdateUnlock();
}
}

public bool IsLocked => Visible;

public UnlockLabel()
{
IoCManager.InjectDependencies(this);

Visible = false;
}

private void UpdateUnlock()
{
if (_nextUnlock is not {} next)
return;

var now = _timing.CurTime;
if (now >= next)
{
// unlocked now
_nextUnlock = null;
Visible = false;
OnUnlock?.Invoke();
return;
}

Visible = true;
var remaining = next - now;
var time = $"{remaining.Minutes:00}:{remaining.Seconds:00}";
Text = Loc.GetString("contract-next-unlock", ("time", time));
}

protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);

var now = _timing.CurTime;
if (now < _nextUpdate)
return;

_nextUpdate = now + TimeSpan.FromSeconds(1);
UpdateUnlock();
}
}
31 changes: 28 additions & 3 deletions Content.Shared/_DV/Reputation/ContractsComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ public sealed partial class ContractsComponent : Component
public List<EntityUid?> Offerings = new();

/// <summary>
/// The title of each offering objective.
/// All slots for offerings.
/// </summary>
[DataField, AutoNetworkedField]
public List<string> OfferingTitles = new();
public List<OfferingSlot> OfferingSlots = new();

/// <summary>
/// The objectives for each slot.
Expand All @@ -67,10 +67,16 @@ public sealed partial class ContractsComponent : Component
public TimeSpan CompleteDelay = TimeSpan.FromMinutes(5);

/// <summary>
/// How long you have to wait before you can get a new contract after you reject one.
/// How long you have to wait before you can get a new offering after you reject one.
/// </summary>
[DataField]
public TimeSpan RejectDelay = TimeSpan.FromMinutes(15);

/// <summary>
/// How long you have to wait before you can get a new offering after you accept one.
/// </summary>
[DataField]
public TimeSpan AcceptDelay = TimeSpan.FromMinutes(3);
}

/// <summary>
Expand All @@ -91,3 +97,22 @@ public partial record struct ContractSlot
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan? NextUnlock;
}

/// <summary>
/// An offering slot which can have an available objective.
/// </summary>
[DataDefinition, Serializable, NetSerializable]
public partial record struct OfferingSlot
{
/// <summary>
/// The title of the available objective, or null if locked.
/// </summary>
[DataField]
public string? Title;

/// <summary>
/// When the slot gets unlocked and a new offering is rolled.
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan? NextUnlock;
}
Loading

0 comments on commit 5476033

Please sign in to comment.