Public market + Solutions requests (#1503)

* Add platform markup to trading platform prices

Introduces a PlatformMarkupProcent field to CP14TradingPlatformComponent and applies it to price calculations in both client and server logic. Adds a new public trading platform entity with a higher markup and updates related sprites and metadata.

* Add platform markup percent to selling platforms

Introduces a PlatformMarkupProcent field to CP14SellingPlatformComponent, allowing selling platforms to apply a markup or markdown to item prices. Updates server logic to use this value when calculating payouts and UI state. Adds a new public selling platform entity with a lower markup in the trade_platform.yml prototype.

* Add Brad Potions trading requests prototype

Introduces a new YAML prototype defining multiple cp14TradingRequest entries for the BradPotions faction, each specifying requirements for various potion effects with minimum purity and amount.

* Apply platform markup to selling prices and payouts

Updated the selling request control and platform window to factor in the platform's markup percentage when displaying prices. Adjusted the server-side payout logic to multiply the payout by the platform markup percentage, ensuring consistency between client display and server rewards.

* replace mapping to public platforms

* bug + remove eepy potions request

* Clarify purity requirement in workbench reagent text

Updated the reagent requirement string in both English and Russian locale files to indicate that the required purity is '{$purity}%+' instead of just '{$purity}%'. This clarifies that the purity must be at least the specified percentage.
This commit is contained in:
Red
2025-07-06 00:09:03 +03:00
committed by GitHub
parent ae89cb8821
commit 6570b1b4b6
19 changed files with 358 additions and 42 deletions

View File

@@ -17,7 +17,7 @@ public sealed partial class CP14SellingRequestControl : Control
public event Action? OnSellAttempt;
public CP14SellingRequestControl(ProtoId<CP14TradingRequestPrototype> request, bool active)
public CP14SellingRequestControl(ProtoId<CP14TradingRequestPrototype> request, float markupProcent, bool active)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
@@ -36,7 +36,8 @@ public sealed partial class CP14SellingRequestControl : Control
PriceHolder.RemoveAllChildren();
var economySystem = _entityManager.System<CP14SharedStationEconomySystem>();
var price = economySystem.GetPrice(indexedRequest);
var originalPrice = economySystem.GetPrice(indexedRequest);
var price = (int?)(originalPrice * markupProcent);
PriceHolder.AddChild(new CP14PriceControl(price ?? 10000));
//Rep reward

View File

@@ -127,7 +127,8 @@ public sealed partial class CP14TradingPlatformWindow : DefaultWindow
UnlockCost.Text = _selectedPosition.ReputationLevel.ToString();
BuyPriceHolder.RemoveAllChildren();
BuyPriceHolder.AddChild(new CP14PriceControl(_economySystem.GetPrice(_selectedPosition) ?? 0));
var price = _economySystem.GetPrice(_selectedPosition) * _cachedPlatform.Value.Comp.PlatformMarkupProcent ?? 0;
BuyPriceHolder.AddChild(new CP14PriceControl((int)price));
}
private void DeselectNode()

View File

@@ -5,12 +5,9 @@ using Content.Shared._CP14.Trading.Components;
using Content.Shared._CP14.Trading.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.Player;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Client._CP14.Trading.Selling;
@@ -20,7 +17,6 @@ public sealed partial class CP14SellingPlatformWindow : DefaultWindow
[Dependency] private readonly ILogManager _log = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
[Dependency] private readonly IEntityManager _e = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPlayerManager _player = default!;
private readonly CP14ClientTradingPlatformSystem _tradingSystem;
@@ -47,8 +43,6 @@ public sealed partial class CP14SellingPlatformWindow : DefaultWindow
SellButton.OnPressed += _ => OnSell?.Invoke();
}
public void UpdateState(CP14SellingPlatformUiState state)
{
if (!_e.TryGetComponent<CP14TradingReputationComponent>(_player.LocalEntity, out var repComp))
@@ -114,7 +108,7 @@ public sealed partial class CP14SellingPlatformWindow : DefaultWindow
foreach (var request in _economySystem.GetRequests(faction))
{
var canFullfill = _tradingSystem.CanFulfillRequest(_cachedPlatform.Value, request);
var requestControl = new CP14SellingRequestControl(request, canFullfill);
var requestControl = new CP14SellingRequestControl(request, _cachedPlatform.Value.Comp.PlatformMarkupProcent, canFullfill);
requestControl.OnSellAttempt += () => OnRequestSell?.Invoke((request, faction));
Requests.AddChild(requestControl);

View File

@@ -87,7 +87,7 @@ public sealed partial class CP14WorkbenchWindow : DefaultWindow
if (!skilled)
continue;
}
recipes.Add(entry);
}

View File

@@ -65,7 +65,7 @@ public sealed partial class CP14TradingPlatformSystem : CP14SharedTradingPlatfor
return;
_audio.PlayPvs(ent.Comp.SellSound, Transform(ent).Coordinates);
_cp14Currency.GenerateMoney(balance, Transform(ent).Coordinates);
_cp14Currency.GenerateMoney(balance * ent.Comp.PlatformMarkupProcent, Transform(ent).Coordinates);
SpawnAtPosition(ent.Comp.SellVisual, Transform(ent).Coordinates);
UpdateSellingUIState(ent);
@@ -91,7 +91,7 @@ public sealed partial class CP14TradingPlatformSystem : CP14SharedTradingPlatfor
}
_audio.PlayPvs(ent.Comp.SellSound, Transform(ent).Coordinates);
var price = _economy.GetPrice(indexedRequest) ?? 0;
var price = _economy.GetPrice(indexedRequest) * ent.Comp.PlatformMarkupProcent ?? 0;
_cp14Currency.GenerateMoney(price, Transform(ent).Coordinates);
AddReputation(args.Actor, args.Faction, price * indexedRequest.ReputationCashback);
SpawnAtPosition(ent.Comp.SellVisual, Transform(ent).Coordinates);
@@ -135,7 +135,7 @@ public sealed partial class CP14TradingPlatformSystem : CP14SharedTradingPlatfor
balance += _price.GetPrice(placed);
}
_userInterface.SetUiState(ent.Owner, CP14TradingUiKey.Sell, new CP14SellingPlatformUiState(GetNetEntity(ent), (int)balance));
_userInterface.SetUiState(ent.Owner, CP14TradingUiKey.Sell, new CP14SellingPlatformUiState(GetNetEntity(ent), (int)(balance * ent.Comp.PlatformMarkupProcent)));
}
public bool CanSell(EntityUid uid)
@@ -182,7 +182,7 @@ public sealed partial class CP14TradingPlatformSystem : CP14SharedTradingPlatfor
balance += _price.GetPrice(placedEntity);
}
var price = _economy.GetPrice(position) ?? 10000;
var price = _economy.GetPrice(position) * platform.Comp.PlatformMarkupProcent ?? 10000;
if (balance < price)
{
// Not enough balance to buy the position
@@ -205,7 +205,7 @@ public sealed partial class CP14TradingPlatformSystem : CP14SharedTradingPlatfor
if (indexedPosition.Service is not null)
indexedPosition.Service.Buy(EntityManager, Proto, platform);
AddReputation(user, indexedPosition.Faction, (float)price / 100);
AddReputation(user, indexedPosition.Faction, price / 100);
_audio.PlayPvs(platform.Comp.BuySound, Transform(platform).Coordinates);

View File

@@ -1,3 +1,4 @@
using Content.Shared._CP14.Trading.Systems;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
@@ -6,7 +7,7 @@ namespace Content.Shared._CP14.Trading.Components;
/// <summary>
/// Allows you to sell items by overloading the platform with energy
/// </summary>
[RegisterComponent]
[RegisterComponent, Access(typeof(CP14SharedTradingPlatformSystem))]
public sealed partial class CP14SellingPlatformComponent : Component
{
[DataField]
@@ -17,4 +18,7 @@ public sealed partial class CP14SellingPlatformComponent : Component
[DataField]
public EntProtoId SellVisual = "CP14CashImpact";
[DataField]
public float PlatformMarkupProcent = 1f;
}

View File

@@ -23,4 +23,8 @@ public sealed partial class CP14TradingPlatformComponent : Component
[DataField]
public EntProtoId BuyVisual = "CP14CashImpact";
[DataField]
public float PlatformMarkupProcent = 1f;
}

View File

@@ -60,21 +60,20 @@ public sealed partial class SolutionResource : CP14WorkbenchCraftRequirement
if (!solutionSys.TryGetDrawableSolution(ent, out var soln, out var solution))
continue;
var volume = solution.Volume;
if (volume < Amount)
continue;
foreach (var (id, quantity) in solution.Contents)
{
if (id.Prototype != Reagent)
continue;
if (quantity < Amount)
continue;
//Purity check
if (quantity / volume < Purity)
continue;
solutionSys.RemoveEachReagent(soln.Value, Amount);
solutionSys.Draw(ent, soln.Value, Amount);
return;
}
}

View File

@@ -5,4 +5,4 @@ cp14-workbench-recipe-list = Recipe:
cp14-workbench-cant-craft = Craft failed!
cp14-workbench-reagent-req = {$count}u {$reagent} with {$purity}% purity
cp14-workbench-reagent-req = {$count}u {$reagent} with {$purity}%+ purity

View File

@@ -5,4 +5,4 @@ cp14-workbench-recipe-list = Рецепт:
cp14-workbench-cant-craft = Крафт не удался!
cp14-workbench-reagent-req = {$count}u {$reagent} с {$purity}% чистоты
cp14-workbench-reagent-req = {$count}u {$reagent} с {$purity}%+ чистоты

View File

@@ -4,7 +4,7 @@ meta:
engineVersion: 262.0.0
forkId: ""
forkVersion: ""
time: 06/29/2025 15:19:52
time: 07/05/2025 20:36:44
entityCount: 14807
maps:
- 1
@@ -45802,16 +45802,22 @@ entities:
- type: Transform
pos: -13.03956,-23.368904
parent: 1
- type: CollisionWake
enabled: False
- uid: 8749
components:
- type: Transform
pos: -12.9045105,-23.43637
parent: 1
- type: CollisionWake
enabled: False
- uid: 8750
components:
- type: Transform
pos: -12.915766,-23.20024
parent: 1
- type: CollisionWake
enabled: False
- proto: CP14FoodMeatLambCooked
entities:
- uid: 8751
@@ -46251,6 +46257,8 @@ entities:
- type: Transform
pos: 8.706699,5.6203566
parent: 1
- type: CollisionWake
enabled: False
- proto: CP14KeyTavernHall
entities:
- uid: 8849
@@ -64362,11 +64370,15 @@ entities:
- type: Transform
pos: 30.588495,4.7120843
parent: 1
- type: CollisionWake
enabled: False
- uid: 11432
components:
- type: Transform
pos: 30.442192,4.554663
parent: 1
- type: CollisionWake
enabled: False
- uid: 11433
components:
- type: Transform
@@ -64397,6 +64409,8 @@ entities:
- type: Transform
pos: 30.250874,4.667107
parent: 1
- type: CollisionWake
enabled: False
- uid: 11439
components:
- type: Transform
@@ -64409,6 +64423,8 @@ entities:
- type: Transform
pos: 30.385923,4.7120843
parent: 1
- type: CollisionWake
enabled: False
- proto: CP14Syringe
entities:
- uid: 11441
@@ -65193,12 +65209,6 @@ entities:
parent: 1
- proto: CP14TradingPlatform
entities:
- uid: 7103
components:
- type: Transform
rot: -1.5707963267948966 rad
pos: -9.5,13.5
parent: 1
- uid: 11457
components:
- type: Transform
@@ -65210,14 +65220,15 @@ entities:
rot: 1.5707963267948966 rad
pos: -5.5,21.5
parent: 1
- proto: CP14TradingSellingPlatform
- proto: CP14TradingPlatformPublic
entities:
- uid: 7105
- uid: 7103
components:
- type: Transform
rot: -1.5707963267948966 rad
pos: -11.5,13.5
parent: 1
- proto: CP14TradingSellingPlatform
entities:
- uid: 11512
components:
- type: Transform
@@ -65229,6 +65240,13 @@ entities:
rot: 1.5707963267948966 rad
pos: -3.5,21.5
parent: 1
- proto: CP14TradingSellingPlatformPublic
entities:
- uid: 7105
components:
- type: Transform
pos: -9.5,13.5
parent: 1
- proto: CP14VentCritterMarker
entities:
- uid: 15324
@@ -84025,6 +84043,9 @@ entities:
- type: Transform
pos: 8.5,5.5
parent: 1
- type: ItemPlacer
placedEntities:
- 8848
- uid: 15165
components:
- type: Transform
@@ -84049,6 +84070,13 @@ entities:
rot: -1.5707963267948966 rad
pos: 30.5,4.5
parent: 1
- type: ItemPlacer
placedEntities:
- 11431
- 11432
- 11438
- 11439
- 11440
- proto: CP14WorkbenchAnvil
entities:
- uid: 15170
@@ -84080,6 +84108,11 @@ entities:
- type: Transform
pos: -13.5,-23.5
parent: 1
- type: ItemPlacer
placedEntities:
- 8748
- 8749
- 8750
- proto: CP14WorkbenchFurnace
entities:
- uid: 15176

View File

@@ -4,7 +4,7 @@ meta:
engineVersion: 262.0.0
forkId: ""
forkVersion: ""
time: 07/02/2025 10:28:02
time: 07/05/2025 20:37:15
entityCount: 19196
maps:
- 2
@@ -59352,7 +59352,7 @@ entities:
pos: 14.5,-24.5
parent: 2
- type: Door
secondsUntilStateChange: -13599.846
secondsUntilStateChange: -13613.509
state: Closing
- uid: 1792
components:
@@ -78632,16 +78632,22 @@ entities:
- type: Transform
pos: 4.5506587,-30.291777
parent: 2
- type: CollisionWake
enabled: False
- uid: 2510
components:
- type: Transform
pos: 4.3631587,-30.236221
parent: 2
- type: CollisionWake
enabled: False
- uid: 2511
components:
- type: Transform
pos: 4.4395475,-30.361221
parent: 2
- type: CollisionWake
enabled: False
- proto: CP14FoodMeatLamb
entities:
- uid: 2508
@@ -78668,6 +78674,8 @@ entities:
- type: Transform
pos: 5.3909364,-30.305666
parent: 2
- type: CollisionWake
enabled: False
- proto: CP14FoodTomatoes
entities:
- uid: 1486
@@ -103770,6 +103778,8 @@ entities:
- type: Transform
pos: 0.42527747,-27.375025
parent: 2
- type: CollisionWake
enabled: False
- proto: CP14SafeMerchant1
entities:
- uid: 7835
@@ -104976,18 +104986,15 @@ entities:
rot: -1.5707963267948966 rad
pos: -20.5,-34.5
parent: 2
- uid: 15205
components:
- type: Transform
pos: -29.5,-32.5
parent: 2
- proto: CP14TradingSellingPlatform
- proto: CP14TradingPlatformPublic
entities:
- uid: 3220
components:
- type: Transform
pos: -33.5,-32.5
parent: 2
- proto: CP14TradingSellingPlatform
entities:
- uid: 7817
components:
- type: Transform
@@ -104998,6 +105005,13 @@ entities:
- type: Transform
pos: -20.5,-36.5
parent: 2
- proto: CP14TradingSellingPlatformPublic
entities:
- uid: 5726
components:
- type: Transform
pos: -29.5,-32.5
parent: 2
- proto: CP14VentCritterMarker
entities:
- uid: 2733
@@ -106643,6 +106657,8 @@ entities:
- type: Transform
pos: -33.429523,-42.402264
parent: 2
- type: CollisionWake
enabled: False
- proto: CP14WallStonebrick
entities:
- uid: 1621
@@ -113896,12 +113912,20 @@ entities:
rot: 3.141592653589793 rad
pos: 4.5,-30.5
parent: 2
- type: ItemPlacer
placedEntities:
- 2509
- 2510
- 2511
- uid: 2309
components:
- type: Transform
rot: 3.141592653589793 rad
pos: 5.5,-30.5
parent: 2
- type: ItemPlacer
placedEntities:
- 2282
- proto: CP14WorkbenchFurnace
entities:
- uid: 1797
@@ -113924,11 +113948,17 @@ entities:
rot: -1.5707963267948966 rad
pos: 0.5,-27.5
parent: 2
- type: ItemPlacer
placedEntities:
- 2982
- uid: 8056
components:
- type: Transform
pos: -33.5,-42.5
parent: 2
- type: ItemPlacer
placedEntities:
- 8197
- proto: SpawnPointLatejoin
entities:
- uid: 1315

View File

@@ -49,6 +49,20 @@
# - CP14_RU_Trading
# - CP14_EN_Trading
- type: entity
parent: CP14TradingPlatform
id: CP14TradingPlatformPublic
name: public buying dimensional platform
description: Allows you to trade with the outside world, through retail trade transactions. But since this retail outlet is not bound by contracts with specific merchants, the markup here is terrible.
components:
- type: CP14TradingPlatform
platformMarkupProcent: 1.5
- type: Sprite
layers:
- state: base
- state: old
- state: buy
- type: entity
parent: BaseStructure
id: CP14TradingSellingPlatform
@@ -93,6 +107,20 @@
- LowImpassable
hard: false
- type: entity
parent: CP14TradingSellingPlatform
id: CP14TradingSellingPlatformPublic
name: public selling dimensional platform
description: Allows you to sell any items and structures to the outside world. Fill the platform completely with mana to sell whatever you place on it. But since this retail outlet is not bound by contracts with specific merchants, the markup here is terrible.
components:
- type: CP14SellingPlatform
platformMarkupProcent: 0.5
- type: Sprite
layers:
- state: base
- state: old
- state: sell
- type: entity
id: CP14CashImpact
categories: [ HideSpawnMenu ]

View File

@@ -0,0 +1,219 @@
- type: cp14TradingRequest
id: CP14BasicEffectHealBrute
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectHealBrute
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectDamageBrute
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectDamageBrute
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectHealHeat
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectHealHeat
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectDamageHeat
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectDamageHeat
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectHealCold
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectHealCold
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectDamageCold
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectDamageCold
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectHealPoison
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectHealPoison
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectDamagePoison
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectDamagePoison
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectHealAirloss
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectHealAirloss
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectDamageAirloss
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectDamageAirloss
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectHealManaDepletion
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectHealManaDepletion
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectDamageManaDepletion
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectDamageManaDepletion
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectBloodRestore
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectBloodRestore
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectBloodAbsorption
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectBloodAbsorption
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectSatiateHunger
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectSatiateHunger
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectSatiateThirst
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectSatiateThirst
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectHealMana
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectHealMana
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectDamageMana
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectDamageMana
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectHealStam
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectHealStam
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectDamageStam
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectDamageStam
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectSpeedUp
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectSpeedUp
amount: 10
purity: 0.75
- type: cp14TradingRequest
id: CP14BasicEffectSpeedDown
possibleFactions:
- BradPotions
requirements:
- !type:SolutionResource
reagent: CP14BasicEffectSpeedDown
amount: 10
purity: 0.75

Binary file not shown.

Before

Width:  |  Height:  |  Size: 711 B

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 B

After

Width:  |  Height:  |  Size: 433 B

View File

@@ -13,6 +13,9 @@
{
"name": "buy"
},
{
"name": "old"
},
{
"name": "sell"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 558 B

After

Width:  |  Height:  |  Size: 523 B