Skip to content

Commit

Permalink
[Port] Discounts In Uplink / Скидки В Аплинке (#11)
Browse files Browse the repository at this point in the history
* add: uplink discount

* test

* tweak
  • Loading branch information
Spatison authored Aug 27, 2024
1 parent 959b3d2 commit b3d7b95
Show file tree
Hide file tree
Showing 13 changed files with 196 additions and 2 deletions.
4 changes: 4 additions & 0 deletions Content.Client/Store/Ui/StoreMenu.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ private void AddListingGui(ListingData listing)
}

var newListing = new StoreListingControl(listing, GetListingPriceString(listing), hasBalance, texture);

if (listing.DiscountValue > 0) // WD EDIT
newListing.StoreItemBuyButton.AddStyleClass("ButtonColorRed");

newListing.StoreItemBuyButton.OnButtonDown += args
=> OnListingButtonPressed?.Invoke(args, listing);

Expand Down
8 changes: 8 additions & 0 deletions Content.Server/Store/Systems/StoreSystem.Ui.cs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,14 @@ private void OnBuyRequest(EntityUid uid, StoreComponent component, StoreBuyListi
listing.PurchaseAmount++; //track how many times something has been purchased
_audio.PlayEntity(component.BuySuccessSound, msg.Session, uid); //cha-ching!

//WD EDIT START
if (listing.SaleLimit != 0 && listing.DiscountValue > 0 && listing.PurchaseAmount >= listing.SaleLimit)
{
listing.DiscountValue = 0;
listing.Cost = listing.OldCost;
}
//WD EDIT END

UpdateUserInterface(buyer, uid, component);
}

Expand Down
6 changes: 5 additions & 1 deletion Content.Server/Store/Systems/StoreSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Robust.Server.GameObjects;
using Robust.Shared.Prototypes;
using System.Linq;
using Content.Server._White.StoreDiscount;
using Robust.Shared.Utility;

namespace Content.Server.Store.Systems;
Expand All @@ -22,6 +23,7 @@ public sealed partial class StoreSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly StoreDiscountSystem _storeDiscount = default!; // WD EDIT

public override void Initialize()
{
Expand Down Expand Up @@ -199,6 +201,8 @@ public void InitializeFromPreset(StorePresetPrototype preset, EntityUid uid, Sto
if (component.Balance == new Dictionary<string, FixedPoint2>() && preset.InitialBalance != null) //if we don't have a value stored, use the preset
TryAddCurrency(preset.InitialBalance, uid, component);

_storeDiscount.ApplyDiscounts(component.Listings, preset); // WD EDIT

var ui = _ui.GetUiOrNull(uid, StoreUiKey.Key);
if (ui != null)
{
Expand All @@ -225,7 +229,7 @@ public CurrencyInsertAttemptEvent(EntityUid user, EntityUid target, EntityUid us


/// <summary>
/// Nyano/DeltaV Code. For penguin bombs and what not.
/// Nyano/DeltaV Code. For penguin bombs and what not.
/// Raised on an item when it is purchased.
/// An item may need to set it upself up for its purchaser.
/// For example, to make sure it isn't hostile to them or
Expand Down
53 changes: 53 additions & 0 deletions Content.Server/_White/StoreDiscount/StoreDiscountSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.Linq;
using Content.Shared.FixedPoint;
using Content.Shared.Store;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;

namespace Content.Server._White.StoreDiscount;

public sealed class StoreDiscountSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;

public void ApplyDiscounts(IEnumerable<ListingData> listings, StorePresetPrototype store)
{
if (!store.Sales.Enabled)
return;

var count = _random.Next(store.Sales.MinItems, store.Sales.MaxItems + 1);

listings = listings
.Where(l => !l.SaleBlacklist && l.Cost.Any(x => x.Value > 1)
&& store.Categories.Overlaps(ChangedFormatCategories(l.Categories)))
.OrderBy(_ => _random.Next()).Take(count).ToList();

foreach (var listing in listings)
{
var sale = GetDiscount(store.Sales.MinMultiplier, store.Sales.MaxMultiplier);
var newCost = listing.Cost.ToDictionary(x => x.Key,
x => FixedPoint2.New(Math.Max(1, (int) MathF.Round(x.Value.Float() * sale))));

if (listing.Cost.All(x => x.Value.Int() == newCost[x.Key].Int()))
continue;

var key = listing.Cost.First(x => x.Value > 0).Key;
listing.OldCost = listing.Cost;
listing.DiscountValue = 100 - (newCost[key] / listing.Cost[key] * 100).Int();
listing.Cost = newCost;
listing.Categories = new() {store.Sales.SalesCategory};
}
}

private IEnumerable<string> ChangedFormatCategories(List<ProtoId<StoreCategoryPrototype>> categories)
{
var modified = from p in categories select p.Id;

return modified;
}

private float GetDiscount(float minMultiplier, float maxMultiplier)
{
return _random.NextFloat() * (maxMultiplier - minMultiplier) + minMultiplier;
}
}
7 changes: 7 additions & 0 deletions Content.Shared/Store/ListingLocalisationHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ public static string GetLocalisedNameOrEntityName(ListingData listingData, IProt
else if (listingData.ProductEntity != null)
name = prototypeManager.Index(listingData.ProductEntity.Value).Name;

// WD START
if (listingData.DiscountValue > 0)
name += " " + Loc.GetString("store-sales-amount", ("amount", listingData.DiscountValue));
else if (listingData.OldCost.Count > 0)
name += " " + Loc.GetString("store-sales-over");
// WD END

return name;
}

Expand Down
22 changes: 22 additions & 0 deletions Content.Shared/Store/ListingPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ public partial class ListingData : IEquatable<ListingData>, ICloneable
[DataField]
public TimeSpan RestockTime = TimeSpan.Zero;

// WD START
[DataField]
public int SaleLimit = 3;

[DataField]
public bool SaleBlacklist;

public int DiscountValue;

public Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> OldCost = new();

[DataField]
public List<string> Components = new();
// WD END

public bool Equals(ListingData? listing)
{
if (listing == null)
Expand Down Expand Up @@ -166,6 +181,13 @@ public object Clone()
ProductEvent = ProductEvent,
PurchaseAmount = PurchaseAmount,
RestockTime = RestockTime,
// WD START
SaleLimit = SaleLimit,
SaleBlacklist = SaleBlacklist,
DiscountValue = DiscountValue,
OldCost = OldCost,
Components = Components,
// WD END
};
}
}
Expand Down
6 changes: 6 additions & 0 deletions Content.Shared/Store/StorePresetPrototype.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Shared._White.StoreDiscount;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
Expand Down Expand Up @@ -38,4 +39,9 @@ public sealed partial class StorePresetPrototype : IPrototype
/// </summary>
[DataField("currencyWhitelist", customTypeSerializer: typeof(PrototypeIdHashSetSerializer<CurrencyPrototype>))]
public HashSet<string> CurrencyWhitelist { get; private set; } = new();

// WD EDIT START
[DataField]
public SalesSpecifier Sales { get; private set; } = new();
// WD EDIT END
}
38 changes: 38 additions & 0 deletions Content.Shared/_White/StoreDiscount/SalesSpecifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
namespace Content.Shared._White.StoreDiscount;

[DataDefinition]
public sealed partial class SalesSpecifier
{
[DataField]
public bool Enabled { get; private set; }

[DataField]
public float MinMultiplier { get; private set; }

[DataField]
public float MaxMultiplier { get; private set; }

[DataField]
public int MinItems { get; private set; }

[DataField]
public int MaxItems { get; private set; }

[DataField]
public string SalesCategory { get; private set; } = string.Empty;

public SalesSpecifier()
{
}

public SalesSpecifier(bool enabled, float minMultiplier, float maxMultiplier, int minItems, int maxItems,
string salesCategory)
{
Enabled = enabled;
MinMultiplier = minMultiplier;
MaxMultiplier = maxMultiplier;
MinItems = minItems;
MaxItems = maxItems;
SalesCategory = salesCategory;
}
}
2 changes: 2 additions & 0 deletions Resources/Locale/en-US/_white/store/sales.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
store-sales-amount = [DISCOUNT] { $amount }%!
store-sales-over = [The sale is over]
2 changes: 2 additions & 0 deletions Resources/Locale/ru-RU/_white/store/sales.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
store-sales-amount = [СКИДКА] { $amount }%!
store-sales-over = [Скидка закончилась]
Loading

0 comments on commit b3d7b95

Please sign in to comment.