SurplusBundleSystem.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. using System.Linq;
  2. using Content.Server.Storage.EntitySystems;
  3. using Content.Server.Store.Systems;
  4. using Content.Shared.FixedPoint;
  5. using Content.Shared.Store;
  6. using Content.Shared.Store.Components;
  7. using Robust.Shared.Random;
  8. namespace Content.Server.Traitor.Uplink.SurplusBundle;
  9. public sealed class SurplusBundleSystem : EntitySystem
  10. {
  11. [Dependency] private readonly IRobustRandom _random = default!;
  12. [Dependency] private readonly EntityStorageSystem _entityStorage = default!;
  13. [Dependency] private readonly StoreSystem _store = default!;
  14. public override void Initialize()
  15. {
  16. base.Initialize();
  17. SubscribeLocalEvent<SurplusBundleComponent, MapInitEvent>(OnMapInit);
  18. }
  19. private void OnMapInit(EntityUid uid, SurplusBundleComponent component, MapInitEvent args)
  20. {
  21. if (!TryComp<StoreComponent>(uid, out var store))
  22. return;
  23. FillStorage((uid, component, store));
  24. }
  25. private void FillStorage(Entity<SurplusBundleComponent, StoreComponent> ent)
  26. {
  27. var cords = Transform(ent).Coordinates;
  28. var content = GetRandomContent(ent);
  29. foreach (var item in content)
  30. {
  31. var dode = Spawn(item.ProductEntity, cords);
  32. _entityStorage.Insert(dode, ent);
  33. }
  34. }
  35. // wow, is this leetcode reference?
  36. private List<ListingData> GetRandomContent(Entity<SurplusBundleComponent, StoreComponent> ent)
  37. {
  38. var ret = new List<ListingData>();
  39. var listings = _store.GetAvailableListings(ent, null, ent.Comp2.Categories)
  40. .OrderBy(p => p.Cost.Values.Sum())
  41. .ToList();
  42. if (listings.Count == 0)
  43. return ret;
  44. var totalCost = FixedPoint2.Zero;
  45. var index = 0;
  46. while (totalCost < ent.Comp1.TotalPrice)
  47. {
  48. // All data is sorted in price descending order
  49. // Find new item with the lowest acceptable price
  50. // All expansive items will be before index, all acceptable after
  51. var remainingBudget = ent.Comp1.TotalPrice - totalCost;
  52. while (listings[index].Cost.Values.Sum() > remainingBudget)
  53. {
  54. index++;
  55. if (index >= listings.Count)
  56. {
  57. // Looks like no cheap items left
  58. // It shouldn't be case for ss14 content
  59. // Because there are 1 TC items
  60. return ret;
  61. }
  62. }
  63. // Select random listing and add into crate
  64. var randomIndex = _random.Next(index, listings.Count);
  65. var randomItem = listings[randomIndex];
  66. ret.Add(randomItem);
  67. totalCost += randomItem.Cost.Values.Sum();
  68. }
  69. return ret;
  70. }
  71. }