Merge branch 'master' into ed-27-05-2025-upstream-sync
This commit is contained in:
@@ -208,9 +208,6 @@ namespace Content.Client.Construction.UI
|
||||
{
|
||||
foreach (var recipe in actualRecipes)
|
||||
{
|
||||
if (!recipe.Prototype.CrystallPunkAllowed) //CrystallEdge clearing recipes
|
||||
continue;
|
||||
|
||||
var protoView = new EntityPrototypeView()
|
||||
{
|
||||
Scale = new Vector2(1.2f),
|
||||
@@ -265,6 +262,9 @@ namespace Content.Client.Construction.UI
|
||||
|
||||
foreach (var recipe in _prototypeManager.EnumeratePrototypes<ConstructionPrototype>())
|
||||
{
|
||||
if (!recipe.CrystallPunkAllowed) //CrystallEdge filter vanilla recipes
|
||||
continue;
|
||||
|
||||
if (recipe.Hide)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
using Content.Shared._CP14.Trading.Systems;
|
||||
|
||||
namespace Content.Client._CP14.Trading;
|
||||
|
||||
public sealed partial class CP14ClientStationEconomySystem : CP14SharedStationEconomySystem
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
using Content.Shared._CP14.Trading.Systems;
|
||||
|
||||
namespace Content.Client._CP14.Trading;
|
||||
|
||||
public sealed partial class CP14ClientTradingPlatformSystem : CP14SharedTradingPlatformSystem
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<Control xmlns="https://spacestation14.io" HorizontalExpand="True">
|
||||
<BoxContainer Name="MainContainer"
|
||||
Orientation="Horizontal"
|
||||
HorizontalExpand="True">
|
||||
<Button Name="MainButton"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True"
|
||||
StyleClasses="OpenRight"
|
||||
Margin="0 0 -1 0">
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" HorizontalAlignment="Right">
|
||||
<TextureRect VerticalAlignment="Center" Visible="True" HorizontalAlignment="Center" Margin="0 0 8 0" TextureScale="2, 2" TexturePath="/Textures/_CP14/Interface/Misc/star.png"/>
|
||||
<Label Name="SkillTreeLabel" Margin="-5 0 0 0"/>
|
||||
</BoxContainer>
|
||||
</Button>
|
||||
<PanelContainer Name="ColorPanel"
|
||||
VerticalExpand="True"
|
||||
SetWidth="7"
|
||||
Margin="0 1 0 0" />
|
||||
</BoxContainer>
|
||||
</Control>
|
||||
@@ -0,0 +1,23 @@
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._CP14.Trading;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14TradingFactionButtonControl : Control
|
||||
{
|
||||
public event Action? OnPressed;
|
||||
|
||||
public CP14TradingFactionButtonControl(Color color, string label, FixedPoint2 reputation)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
|
||||
ColorPanel.PanelOverride = new StyleBoxFlat { BackgroundColor = color };
|
||||
SkillTreeLabel.Text = $"{reputation} {label}";
|
||||
|
||||
MainButton.OnPressed += args => OnPressed?.Invoke();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Content.Shared._CP14.Trading;
|
||||
using Content.Shared._CP14.Trading.Systems;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client._CP14.Trading;
|
||||
|
||||
public sealed class CP14TradingPlatformBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
|
||||
{
|
||||
private CP14TradingPlatformWindow? _window;
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = this.CreateWindow<CP14TradingPlatformWindow>();
|
||||
|
||||
_window.OnUnlock += pos => SendMessage(new CP14TradingPositionUnlockAttempt(pos));
|
||||
_window.OnBuy += pos => SendMessage(new CP14TradingPositionBuyAttempt(pos));
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case CP14TradingPlatformUiState storeState:
|
||||
_window?.UpdateState(storeState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
96
Content.Client/_CP14/Trading/CP14TradingPlatformWindow.xaml
Normal file
96
Content.Client/_CP14/Trading/CP14TradingPlatformWindow.xaml
Normal file
@@ -0,0 +1,96 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
|
||||
xmlns:parallax="clr-namespace:Content.Client.Parallax"
|
||||
xmlns:nodeTree="clr-namespace:Content.Client._CP14.UserInterface.Systems.NodeTree"
|
||||
Name="Window"
|
||||
Title="{Loc 'cp14-trading-ui-title'}"
|
||||
MinSize="1200 800"
|
||||
SetSize="1200 800">
|
||||
|
||||
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" VerticalExpand="True">
|
||||
<!-- Selected Location -->
|
||||
<BoxContainer Margin="10 10 10 10" MaxWidth="340" SetWidth="340" Orientation="Vertical"
|
||||
HorizontalExpand="False" VerticalExpand="True">
|
||||
<!-- Location View -->
|
||||
<PanelContainer Name="BackPanel" HorizontalAlignment="Center">
|
||||
<PanelContainer.PanelOverride>
|
||||
<graphics:StyleBoxTexture Modulate="#1B1B1E" PatchMarginBottom="10" PatchMarginLeft="10"
|
||||
PatchMarginRight="10" PatchMarginTop="10" />
|
||||
</PanelContainer.PanelOverride>
|
||||
<BoxContainer HorizontalExpand="True" VerticalExpand="True">
|
||||
<TextureRect Stretch="Scale" Name="LocationView" SetSize="64 64" HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" MinSize="64 64"
|
||||
HorizontalExpand="True" VerticalExpand="True" Access="Public" />
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
<customControls:HSeparator StyleClasses="HighDivider" Margin="0 15 0 10" />
|
||||
<!-- Location Data -->
|
||||
<BoxContainer Name="NodeViewContainer" Orientation="Vertical" VerticalExpand="True">
|
||||
<ScrollContainer HScrollEnabled="False" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="False" VerticalExpand="True">
|
||||
<BoxContainer Name="InfoContainer" Orientation="Vertical" HorizontalExpand="True"
|
||||
VerticalExpand="True">
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<Label Name="Name" Access="Public" StyleClasses="LabelHeadingBigger" VAlign="Center"
|
||||
HorizontalExpand="True" HorizontalAlignment="Center" />
|
||||
</BoxContainer>
|
||||
<!-- Description -->
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<RichTextLabel Name="Description" HorizontalExpand="True" Access="Public" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</ScrollContainer>
|
||||
<Control MinHeight="5" />
|
||||
<customControls:HSeparator StyleClasses="HighDivider" Margin="0 15 0 10" />
|
||||
|
||||
<!-- Buttons -->
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
|
||||
|
||||
<BoxContainer Name="UnlockBox" Orientation="Horizontal" HorizontalExpand="True" Visible="True">
|
||||
<Button Name="UnlockButton" Text="{Loc 'cp14-trading-ui-button-unlock'}"
|
||||
ToolTip="{Loc 'cp14-trading-ui-button-unlock-tooltip'}" StyleClasses="OpenRight"
|
||||
HorizontalExpand="True" MinHeight="35" Access="Public"/>
|
||||
<BoxContainer SetWidth="100" MaxWidth="100" Orientation="Horizontal">
|
||||
<TextureRect VerticalAlignment="Center" Margin="20 0 5 0" HorizontalAlignment="Left" TextureScale="2, 2" TexturePath="/Textures/_CP14/Interface/Misc/star.png"/>
|
||||
<RichTextLabel Name="UnlockCost" Access="Public" Text="0"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<BoxContainer Name="BuyBox" Orientation="Horizontal" HorizontalExpand="True" Visible="True">
|
||||
<Button Name="BuyButton" Text="{Loc 'cp14-trading-ui-button-buy'}"
|
||||
ToolTip="{Loc 'cp14-trading-ui-button-buy-tooltip'}" StyleClasses="OpenRight"
|
||||
HorizontalExpand="True" MinHeight="35" Access="Public"/>
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<BoxContainer SetWidth="100" Name="BuyPriceHolder" VerticalAlignment="Center" HorizontalExpand="True" HorizontalAlignment="Center" />
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
|
||||
<customControls:VSeparator StyleClasses="LowDivider" />
|
||||
|
||||
<!-- Demiplane map Tree -->
|
||||
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer HorizontalExpand="True">
|
||||
<Label Name="TreeName" Access="Public" StyleClasses="LabelHeadingBigger" VAlign="Center"
|
||||
HorizontalExpand="True" HorizontalAlignment="Center" />
|
||||
</BoxContainer>
|
||||
<PanelContainer Margin="10 10 10 10" HorizontalExpand="True" VerticalExpand="True" RectClipContent="True">
|
||||
<parallax:ParallaxControl Name="ParallaxBackground" ScaleX="4" ScaleY="4"
|
||||
ParallaxPrototype="KettleStation" Access="Public" SpeedX="10" SpeedY="5" />
|
||||
<BoxContainer Margin="10 10 10 10" Orientation="Horizontal" HorizontalExpand="True"
|
||||
VerticalExpand="True">
|
||||
<nodeTree:CP14NodeTreeGraphControl Name="GraphControl" HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch" Access="Public" />
|
||||
</BoxContainer>
|
||||
<!-- Tree Tabs -->
|
||||
<BoxContainer Margin="10 10 10 10" VerticalAlignment="Top" HorizontalAlignment="Right" Orientation="Vertical" VerticalExpand="True">
|
||||
<BoxContainer Name="TreeTabsContainer" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" Access="Public"/>
|
||||
</BoxContainer>
|
||||
</PanelContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
254
Content.Client/_CP14/Trading/CP14TradingPlatformWindow.xaml.cs
Normal file
254
Content.Client/_CP14/Trading/CP14TradingPlatformWindow.xaml.cs
Normal file
@@ -0,0 +1,254 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Client._CP14.UserInterface;
|
||||
using Content.Client._CP14.UserInterface.Systems.NodeTree;
|
||||
using Content.Shared._CP14.Trading;
|
||||
using Content.Shared._CP14.Trading.Components;
|
||||
using Content.Shared._CP14.Trading.Prototypes;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Client.Utility;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client._CP14.Trading;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14TradingPlatformWindow : 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!;
|
||||
|
||||
private readonly CP14ClientTradingPlatformSystem _tradingSystem;
|
||||
private readonly CP14ClientStationEconomySystem _economySystem;
|
||||
private readonly SharedAudioSystem _audio = default!;
|
||||
|
||||
private CP14TradingPlatformUiState? _cacheState;
|
||||
private Entity<CP14TradingReputationComponent>? _cachedUser;
|
||||
private Entity<CP14TradingPlatformComponent>? _cachedPlatform;
|
||||
|
||||
private IEnumerable<CP14TradingPositionPrototype> _allPositions = [];
|
||||
private IEnumerable<CP14TradingFactionPrototype> _allFactions = [];
|
||||
|
||||
private ProtoId<CP14TradingFactionPrototype>? _selectedFaction;
|
||||
private CP14TradingPositionPrototype? _selectedPosition;
|
||||
|
||||
public event Action<ProtoId<CP14TradingPositionPrototype>>? OnUnlock;
|
||||
public event Action<ProtoId<CP14TradingPositionPrototype>>? OnBuy;
|
||||
|
||||
private ISawmill Sawmill { get; init; }
|
||||
|
||||
public CP14TradingPlatformWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
Sawmill = _log.GetSawmill("cp14_trading");
|
||||
|
||||
CacheSkillProto();
|
||||
_proto.PrototypesReloaded += _ => CacheSkillProto();
|
||||
if (_cachedUser is not null)
|
||||
{
|
||||
foreach (var (f, _) in _cachedUser.Value.Comp.Reputation)
|
||||
{
|
||||
if (_proto.TryIndex(f, out var indexedFaction))
|
||||
{
|
||||
SelectFaction(indexedFaction);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_tradingSystem = _e.System<CP14ClientTradingPlatformSystem>();
|
||||
_economySystem = _e.System<CP14ClientStationEconomySystem>();
|
||||
_audio = _e.System<SharedAudioSystem>();
|
||||
|
||||
GraphControl.OnOffsetChanged += offset =>
|
||||
{
|
||||
ParallaxBackground.Offset = -offset * 0.25f + new Vector2(1000, 1000); //hardcoding is bad
|
||||
};
|
||||
GraphControl.OnNodeSelected += SelectNode;
|
||||
UnlockButton.OnPressed += UnlockPressed;
|
||||
BuyButton.OnPressed += BuyPressed;
|
||||
}
|
||||
|
||||
private void UnlockPressed(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
if (_selectedPosition is null)
|
||||
return;
|
||||
|
||||
OnUnlock?.Invoke(_selectedPosition);
|
||||
|
||||
if (_cachedUser is not null)
|
||||
_audio.PlayGlobal(new SoundCollectionSpecifier("CP14CoinImpact"), _cachedUser.Value);
|
||||
}
|
||||
|
||||
private void BuyPressed(BaseButton.ButtonEventArgs obj)
|
||||
{
|
||||
if (_selectedPosition is null)
|
||||
return;
|
||||
|
||||
OnBuy?.Invoke(_selectedPosition.ID);
|
||||
}
|
||||
|
||||
private void SelectNode(CP14NodeTreeElement? node)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
DeselectNode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_cacheState == null)
|
||||
{
|
||||
Sawmill.Error("Tried to select node without a cached state.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_proto.TryIndex<CP14TradingPositionPrototype>(node.NodeKey, out var indexedPosition))
|
||||
return;
|
||||
|
||||
SelectNode(indexedPosition);
|
||||
}
|
||||
|
||||
private void SelectNode(CP14TradingPositionPrototype? node)
|
||||
{
|
||||
if (node is null || _cachedUser is null || _cachedPlatform is null)
|
||||
{
|
||||
DeselectNode();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_cacheState == null)
|
||||
{
|
||||
Sawmill.Error("Tried to select node without a cached state.");
|
||||
return;
|
||||
}
|
||||
|
||||
_selectedPosition = node;
|
||||
var unlocked = _cachedUser.Value.Comp.UnlockedPositions;
|
||||
|
||||
Name.Text = _tradingSystem.GetTradeName(_selectedPosition);
|
||||
Description.Text = _tradingSystem.GetTradeDescription(_selectedPosition);
|
||||
|
||||
LocationView.Texture = _selectedPosition.Icon.Frame0();
|
||||
UnlockButton.Disabled = !_tradingSystem.CanUnlockPosition((_cachedUser.Value.Owner, _cachedUser.Value.Comp), _selectedPosition);
|
||||
BuyButton.Disabled = !unlocked.Contains(_selectedPosition);
|
||||
|
||||
UnlockCost.Text = _selectedPosition.UnlockReputationCost.ToString();
|
||||
|
||||
BuyPriceHolder.RemoveAllChildren();
|
||||
BuyPriceHolder.AddChild(new CP14PriceControl(_economySystem.GetPrice(_selectedPosition) ?? 0));
|
||||
}
|
||||
|
||||
private void DeselectNode()
|
||||
{
|
||||
Name.Text = string.Empty;
|
||||
Description.Text = string.Empty;
|
||||
LocationView.Texture = null;
|
||||
UnlockButton.Disabled = true;
|
||||
}
|
||||
|
||||
private void CacheSkillProto()
|
||||
{
|
||||
_allPositions = _proto.EnumeratePrototypes<CP14TradingPositionPrototype>();
|
||||
_allFactions = _proto.EnumeratePrototypes<CP14TradingFactionPrototype>().OrderBy(tree => Loc.GetString(tree.Name));
|
||||
}
|
||||
|
||||
public void UpdateState(CP14TradingPlatformUiState state)
|
||||
{
|
||||
_cacheState = state;
|
||||
var ent = _e.GetEntity(state.User);
|
||||
|
||||
if (!_e.TryGetComponent<CP14TradingReputationComponent>(ent, out var repComp))
|
||||
return;
|
||||
|
||||
_cachedUser = (ent, repComp);
|
||||
|
||||
var plat = _e.GetEntity(state.Platform);
|
||||
if (!_e.TryGetComponent<CP14TradingPlatformComponent>(plat, out var platComp))
|
||||
return;
|
||||
|
||||
_cachedPlatform = (plat, platComp);
|
||||
UpdateGraphControl();
|
||||
}
|
||||
|
||||
private void UpdateGraphControl()
|
||||
{
|
||||
if (_cachedUser is null)
|
||||
return;
|
||||
|
||||
HashSet<CP14NodeTreeElement> nodeTreeElements = new();
|
||||
var edges = new HashSet<(string, string)>();
|
||||
foreach (var position in _allPositions)
|
||||
{
|
||||
if (position.Faction != _selectedFaction)
|
||||
continue;
|
||||
|
||||
var unlocked = _cachedUser.Value.Comp.UnlockedPositions;
|
||||
var gained = unlocked.Contains(position);
|
||||
var active = _tradingSystem.CanUnlockPosition((_cachedUser.Value.Owner, _cachedUser.Value.Comp), position);
|
||||
var node = new CP14NodeTreeElement(position.ID, gained, active, position.UiPosition * 66, position.Icon);
|
||||
nodeTreeElements.Add(node);
|
||||
if (position.Prerequisite != null)
|
||||
{
|
||||
edges.Add((position.Prerequisite, position.ID));
|
||||
}
|
||||
}
|
||||
|
||||
GraphControl.UpdateState(
|
||||
new CP14NodeTreeUiState(
|
||||
nodeTreeElements,
|
||||
edges: edges,
|
||||
frameIcon: new SpriteSpecifier.Rsi(
|
||||
new ResPath("/Textures/_CP14/Interface/NodeTree/trading.rsi"),
|
||||
"frame"),
|
||||
hoveredIcon: new SpriteSpecifier.Rsi(
|
||||
new ResPath("/Textures/_CP14/Interface/NodeTree/trading.rsi"),
|
||||
"hovered"),
|
||||
selectedIcon: new SpriteSpecifier.Rsi(
|
||||
new ResPath("/Textures/_CP14/Interface/NodeTree/trading.rsi"),
|
||||
"selected"),
|
||||
learnedIcon: new SpriteSpecifier.Rsi(
|
||||
new ResPath("/Textures/_CP14/Interface/NodeTree/trading.rsi"),
|
||||
"learned"),
|
||||
activeLineColor: new Color(172, 102, 190),
|
||||
lineColor: new Color(83, 40, 121)
|
||||
)
|
||||
);
|
||||
|
||||
//Faction tabs update
|
||||
TreeTabsContainer.RemoveAllChildren();
|
||||
foreach (var (faction, rep) in _cachedUser.Value.Comp.Reputation)
|
||||
{
|
||||
if (!_proto.TryIndex(faction, out var indexedFaction))
|
||||
continue;
|
||||
var factionButton = new CP14TradingFactionButtonControl(
|
||||
indexedFaction.Color,
|
||||
Loc.GetString(indexedFaction.Name),
|
||||
rep);
|
||||
|
||||
factionButton.OnPressed += () =>
|
||||
{
|
||||
SelectFaction(indexedFaction);
|
||||
};
|
||||
|
||||
TreeTabsContainer.AddChild(factionButton);
|
||||
}
|
||||
SelectNode(_selectedPosition);
|
||||
}
|
||||
|
||||
private void SelectFaction(CP14TradingFactionPrototype faction)
|
||||
{
|
||||
_selectedFaction = faction;
|
||||
TreeName.Text = Loc.GetString("cp14-trading-faction-prefix") + " " + Loc.GetString(faction.Name);
|
||||
UpdateGraphControl();
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using Content.Shared._CP14.Cargo;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client._CP14.TravelingStoreShip;
|
||||
|
||||
public sealed class CP14StoreBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
private CP14StoreWindow? _window;
|
||||
|
||||
public CP14StoreBoundUserInterface(EntityUid owner, [NotNull] Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_window = this.CreateWindow<CP14StoreWindow>();
|
||||
}
|
||||
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case CP14StoreUiState storeState:
|
||||
_window?.UpdateUI(storeState);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<Control xmlns="https://spacestation14.io">
|
||||
<Button Name="ProductButton" Access="Public">
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<EntityPrototypeView Name="EntityView"
|
||||
MinSize="48 48"
|
||||
MaxSize="48 48"
|
||||
Scale="2,2"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Visible="False"/>
|
||||
<TextureRect Name="View"
|
||||
MinSize="48 48"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Stretch="KeepAspectCentered"
|
||||
Visible="False"/>
|
||||
<BoxContainer Orientation="Vertical">
|
||||
<RichTextLabel Name="SpecialLabel" Text="{Loc 'cp14-store-ui-tab-special'}" VerticalAlignment="Center" Access="Public" Visible="False" />
|
||||
<RichTextLabel Name="ProductName" VerticalAlignment="Center" Access="Public" />
|
||||
</BoxContainer>
|
||||
<BoxContainer Name="PriceHolder" VerticalAlignment="Center" HorizontalExpand="True" HorizontalAlignment="Right" />
|
||||
</BoxContainer>
|
||||
</Button>
|
||||
</Control>
|
||||
@@ -1,40 +0,0 @@
|
||||
using Content.Shared._CP14.Cargo;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._CP14.TravelingStoreShip;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14StoreProductControl : Control
|
||||
{
|
||||
[Dependency] private readonly IEntityManager _entity = default!;
|
||||
|
||||
private readonly SpriteSystem _sprite;
|
||||
|
||||
public CP14StoreProductControl(CP14StoreUiProductEntry entry)
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
_sprite = _entity.System<SpriteSystem>();
|
||||
|
||||
PriceHolder.RemoveAllChildren();
|
||||
PriceHolder.AddChild(new CP14PriceControl(entry.Price));
|
||||
ProductName.Text = $"[bold]{entry.Name}[/bold]";
|
||||
|
||||
SpecialLabel.Visible = entry.Special;
|
||||
|
||||
if (entry.Icon is not null)
|
||||
{
|
||||
View.Visible = true;
|
||||
View.Texture = _sprite.Frame0(entry.Icon);
|
||||
}
|
||||
else if (entry.EntityView is not null)
|
||||
{
|
||||
EntityView.Visible = true;
|
||||
EntityView.SetPrototype(entry.EntityView);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Name="Window"
|
||||
Title=""
|
||||
MinSize="800 600"
|
||||
SetSize="800 600">
|
||||
<BoxContainer Orientation="Horizontal">
|
||||
<BoxContainer HorizontalExpand="True" VerticalExpand="True" Orientation="Horizontal">
|
||||
<!-- Product list (left side UI) -->
|
||||
<TabContainer MinWidth="400" Name="Tabs" HorizontalExpand="True" VerticalExpand="True" MinSize="0 200">
|
||||
<ScrollContainer HorizontalExpand="True" VerticalExpand="True" MinSize="0 200">
|
||||
<BoxContainer Name="BuyProductsContainer" Orientation="Vertical" HorizontalExpand="True"/>
|
||||
</ScrollContainer>
|
||||
<ScrollContainer HorizontalExpand="True" VerticalExpand="True" MinSize="0 200">
|
||||
<BoxContainer Name="SellProductsContainer" Orientation="Vertical" HorizontalExpand="True"/>
|
||||
</ScrollContainer>
|
||||
</TabContainer>
|
||||
<!-- Station trading data (right side UI) -->
|
||||
<BoxContainer MinWidth="400" Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" Margin="0 0 10 0">
|
||||
<controls:StripeBack>
|
||||
<PanelContainer>
|
||||
<Label Text="{Loc 'cp14-store-ui-order'}" Align="Center" Margin="0 5 0 3"/>
|
||||
</PanelContainer>
|
||||
</controls:StripeBack>
|
||||
<Label Name="TravelTimeLabel" Text="00:00" HorizontalAlignment="Center" HorizontalExpand="True" Margin="0 15 0 0"/>
|
||||
<controls:HLine Color="#404040" Thickness="2" Margin="0 5"/>
|
||||
<RichTextLabel Name="SelectedName" HorizontalExpand="True" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="5"/>
|
||||
<RichTextLabel Name="SelectedDesc" HorizontalExpand="True" VerticalExpand="True" VerticalAlignment="Top" Margin="5"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
@@ -1,60 +0,0 @@
|
||||
using Content.Shared._CP14.Cargo;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client._CP14.TravelingStoreShip;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14StoreWindow : DefaultWindow
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
public CP14StoreWindow()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
Tabs.SetTabTitle(0, Loc.GetString("cp14-store-ui-tab-buy"));
|
||||
Tabs.SetTabTitle(1, Loc.GetString("cp14-store-ui-tab-sell"));
|
||||
}
|
||||
|
||||
public void UpdateUI(CP14StoreUiState state)
|
||||
{
|
||||
Window.Title = Loc.GetString("cp14-store-ui-title", ("name", state.ShopName));
|
||||
UpdateProducts(state);
|
||||
}
|
||||
|
||||
private void UpdateProducts(CP14StoreUiState state)
|
||||
{
|
||||
BuyProductsContainer.RemoveAllChildren();
|
||||
SellProductsContainer.RemoveAllChildren();
|
||||
|
||||
foreach (var product in state.ProductsBuy)
|
||||
{
|
||||
var control = new CP14StoreProductControl(product);
|
||||
control.ProductButton.OnPressed += _ =>
|
||||
{
|
||||
SelectProduct(product);
|
||||
};
|
||||
BuyProductsContainer.AddChild(control);
|
||||
}
|
||||
|
||||
foreach (var product in state.ProductsSell)
|
||||
{
|
||||
var control = new CP14StoreProductControl(product);
|
||||
control.ProductButton.OnPressed += _ =>
|
||||
{
|
||||
SelectProduct(product);
|
||||
};
|
||||
SellProductsContainer.AddChild(control);
|
||||
}
|
||||
}
|
||||
|
||||
private void SelectProduct(CP14StoreUiProductEntry? entry)
|
||||
{
|
||||
SelectedName.Text = entry is null ? string.Empty : $"[bold]{entry.Value.Name}[/bold]";
|
||||
SelectedDesc.Text = entry is null ? string.Empty : entry.Value.Desc;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Client._CP14.TravelingStoreShip;
|
||||
namespace Content.Client._CP14.UserInterface;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CP14PriceControl : Control
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared._CP14.Cargo.Prototype;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Content.Shared._CP14.Trading.Prototypes;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.IntegrationTests.Tests._CP14;
|
||||
@@ -16,7 +15,6 @@ public sealed class CP14CargoTest
|
||||
await using var pair = await PoolManager.GetServerClient();
|
||||
var server = pair.Server;
|
||||
|
||||
var compFactory = server.ResolveDependency<IComponentFactory>();
|
||||
var protoManager = server.ResolveDependency<IPrototypeManager>();
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
@@ -25,10 +23,9 @@ public sealed class CP14CargoTest
|
||||
{
|
||||
HashSet<string> existedCodes = new();
|
||||
|
||||
foreach (var proto in protoManager.EnumeratePrototypes<CP14StoreBuyPositionPrototype>())
|
||||
foreach (var proto in protoManager.EnumeratePrototypes<CP14TradingPositionPrototype>())
|
||||
{
|
||||
Assert.That(!existedCodes.Contains(proto.Code), $"Repeated purchasing code {proto.Code} of the {proto}");
|
||||
existedCodes.Add(proto.Code);
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,6 +16,7 @@ using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Linq;
|
||||
using Content.Server._CP14.Trading;
|
||||
using Content.Shared.Research.Prototypes;
|
||||
|
||||
namespace Content.Server.Cargo.Systems;
|
||||
@@ -260,7 +261,9 @@ public sealed class PricingSystem : EntitySystem
|
||||
{
|
||||
double price = 0;
|
||||
|
||||
if (HasComp<MaterialComponent>(uid) &&
|
||||
//CP14 We take materials into account when calculating the price in any case.
|
||||
var proto = MetaData(uid).EntityPrototype?.ID ?? "";
|
||||
if ((HasComp<MaterialComponent>(uid) || proto.StartsWith("CP14")) &&
|
||||
TryComp<PhysicalCompositionComponent>(uid, out var composition))
|
||||
{
|
||||
var matPrice = GetMaterialPrice(composition);
|
||||
@@ -277,7 +280,8 @@ public sealed class PricingSystem : EntitySystem
|
||||
{
|
||||
double price = 0;
|
||||
|
||||
if (prototype.Components.ContainsKey(Factory.GetComponentName<MaterialComponent>()) &&
|
||||
//CP14 We take materials into account when calculating the price in any case.
|
||||
if ((prototype.Components.ContainsKey(Factory.GetComponentName<MaterialComponent>()) || prototype.ID.StartsWith("CP14")) &&
|
||||
prototype.Components.TryGetValue(Factory.GetComponentName<PhysicalCompositionComponent>(), out var composition))
|
||||
{
|
||||
var compositionComp = (PhysicalCompositionComponent) composition.Component;
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
using Content.Shared._CP14.Cargo;
|
||||
using Content.Shared._CP14.Cargo.Prototype;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server._CP14.Cargo.BuyServices;
|
||||
|
||||
public sealed partial class CP14RerollSpecialPositionsService : CP14StoreBuyService
|
||||
{
|
||||
[DataField] public int RerollBuy;
|
||||
[DataField] public int RerollSell;
|
||||
|
||||
public override void Buy(EntityManager entManager, IPrototypeManager prototype, Entity<CP14TradingPortalComponent> portal)
|
||||
{
|
||||
var randomSystem = IoCManager.Resolve<IRobustRandom>();
|
||||
var cargoSystem = entManager.System<CP14CargoSystem>();
|
||||
|
||||
if (RerollBuy > 0)
|
||||
{
|
||||
var removed = 0;
|
||||
for (var i = 0; i < RerollBuy; i++)
|
||||
{
|
||||
if (portal.Comp.CurrentSpecialBuyPositions.Count == 0)
|
||||
break;
|
||||
removed++;
|
||||
var position = randomSystem.Pick(portal.Comp.CurrentSpecialBuyPositions);
|
||||
portal.Comp.CurrentSpecialBuyPositions.Remove(position.Key);
|
||||
}
|
||||
|
||||
cargoSystem.AddRandomBuySpecialPosition(portal, removed);
|
||||
}
|
||||
|
||||
if (RerollSell > 0)
|
||||
{
|
||||
var removed = 0;
|
||||
for (var i = 0; i < RerollSell; i++)
|
||||
{
|
||||
if (portal.Comp.CurrentSpecialSellPositions.Count == 0)
|
||||
break;
|
||||
removed++;
|
||||
var position = randomSystem.Pick(portal.Comp.CurrentSpecialSellPositions);
|
||||
portal.Comp.CurrentSpecialSellPositions.Remove(position.Key);
|
||||
}
|
||||
|
||||
cargoSystem.AddRandomSellSpecialPosition(portal, removed);
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetName(IPrototypeManager protoMan)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public override EntProtoId? GetEntityView(IPrototypeManager protoManager)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override SpriteSpecifier? GetTexture(IPrototypeManager protoManager)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
using Content.Server.Storage.Components;
|
||||
using Content.Shared._CP14.Cargo;
|
||||
using Content.Shared.Storage.Components;
|
||||
|
||||
namespace Content.Server._CP14.Cargo;
|
||||
|
||||
public sealed partial class CP14CargoSystem
|
||||
{
|
||||
private void InitializePortals()
|
||||
{
|
||||
SubscribeLocalEvent<CP14TradingPortalComponent, MapInitEvent>(OnTradePortalMapInit);
|
||||
|
||||
SubscribeLocalEvent<CP14TradingPortalComponent, StorageAfterCloseEvent>(OnTradePortalClose);
|
||||
SubscribeLocalEvent<CP14TradingPortalComponent, StorageAfterOpenEvent>(OnTradePortalOpen);
|
||||
}
|
||||
|
||||
private void UpdatePortals(float frameTime)
|
||||
{
|
||||
var query = EntityQueryEnumerator<CP14TradingPortalComponent, EntityStorageComponent>();
|
||||
while (query.MoveNext(out var ent, out var portal, out var storage))
|
||||
{
|
||||
if (portal.ProcessFinishTime == TimeSpan.Zero || portal.ProcessFinishTime >= _timing.CurTime)
|
||||
continue;
|
||||
|
||||
portal.ProcessFinishTime = TimeSpan.Zero;
|
||||
|
||||
SellingThings((ent, portal), storage);
|
||||
TopUpBalance((ent, portal), storage);
|
||||
BuyThings((ent, portal), storage);
|
||||
CashOut((ent, portal), storage);
|
||||
ThrowAllItems((ent, portal), storage);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTradePortalMapInit(Entity<CP14TradingPortalComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
AddRoundstartTradingPositions(ent);
|
||||
UpdateStaticPositions(ent);
|
||||
|
||||
ent.Comp.CurrentSpecialBuyPositions.Clear();
|
||||
ent.Comp.CurrentSpecialSellPositions.Clear();
|
||||
AddRandomBuySpecialPosition(ent, ent.Comp.SpecialBuyPositionCount);
|
||||
AddRandomSellSpecialPosition(ent, ent.Comp.SpecialSellPositionCount);
|
||||
}
|
||||
|
||||
private void OnTradePortalClose(Entity<CP14TradingPortalComponent> ent, ref StorageAfterCloseEvent args)
|
||||
{
|
||||
ent.Comp.ProcessFinishTime = _timing.CurTime + ent.Comp.Delay;
|
||||
}
|
||||
|
||||
private void OnTradePortalOpen(Entity<CP14TradingPortalComponent> ent, ref StorageAfterOpenEvent args)
|
||||
{
|
||||
ent.Comp.ProcessFinishTime = TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
using System.Text;
|
||||
using Content.Shared._CP14.Cargo;
|
||||
using Content.Shared.UserInterface;
|
||||
|
||||
namespace Content.Server._CP14.Cargo;
|
||||
|
||||
public sealed partial class CP14CargoSystem
|
||||
{
|
||||
public void InitializeUI()
|
||||
{
|
||||
SubscribeLocalEvent<CP14TradingInfoBoardComponent, BeforeActivatableUIOpenEvent>(OnBeforeUIOpen);
|
||||
}
|
||||
|
||||
private void TryInitStore(Entity<CP14TradingInfoBoardComponent> ent)
|
||||
{
|
||||
//TODO: more accurate way to find the trading portal, without lookup
|
||||
var entitiesInRange = _lookup.GetEntitiesInRange<CP14TradingPortalComponent>(Transform(ent).Coordinates, 2);
|
||||
foreach (var trading in entitiesInRange)
|
||||
{
|
||||
ent.Comp.TradingPortal = trading;
|
||||
ent.Comp.CahcedFaction = trading.Comp.Faction;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBeforeUIOpen(Entity<CP14TradingInfoBoardComponent> ent, ref BeforeActivatableUIOpenEvent args)
|
||||
{
|
||||
//TODO: If you open a store on a mapping, and initStore() it, the entity will throw an error when you try to save the grid\map.
|
||||
|
||||
if (ent.Comp.TradingPortal is null)
|
||||
TryInitStore(ent);
|
||||
|
||||
UpdateUIProducts(ent);
|
||||
}
|
||||
|
||||
private void UpdateUIProducts(Entity<CP14TradingInfoBoardComponent> ent)
|
||||
{
|
||||
if (ent.Comp.TradingPortal is null)
|
||||
return;
|
||||
|
||||
if (!TryComp<CP14TradingPortalComponent>(ent.Comp.TradingPortal.Value, out var tradePortalComp))
|
||||
return;
|
||||
|
||||
var prodBuy = new HashSet<CP14StoreUiProductEntry>();
|
||||
var prodSell = new HashSet<CP14StoreUiProductEntry>();
|
||||
|
||||
//Add special buy positions
|
||||
foreach (var (proto, price) in tradePortalComp.CurrentSpecialBuyPositions)
|
||||
{
|
||||
var name = proto.NameOverride is null ? proto.Service.GetName(_proto) : Loc.GetString(proto.NameOverride);
|
||||
var desc = new StringBuilder();
|
||||
desc.Append("\n" + Loc.GetString("cp14-store-buy-hint", ("name", name), ("code", "[color=yellow][bold]#" + proto.Code + "[/bold][/color]")));
|
||||
|
||||
prodBuy.Add(new CP14StoreUiProductEntry(proto.ID, proto.IconOverride ?? proto.Service.GetTexture(_proto), proto.Service.GetEntityView(_proto), name, desc.ToString(), price, true));
|
||||
}
|
||||
|
||||
//Add static buy positions
|
||||
foreach (var (proto, price) in tradePortalComp.CurrentBuyPositions)
|
||||
{
|
||||
var name = proto.NameOverride is null ? proto.Service.GetName(_proto) : Loc.GetString(proto.NameOverride);
|
||||
var desc = new StringBuilder();
|
||||
desc.Append("\n" + Loc.GetString("cp14-store-buy-hint", ("name", name), ("code", "[color=yellow][bold]#" + proto.Code + "[/bold][/color]")));
|
||||
|
||||
prodBuy.Add(new CP14StoreUiProductEntry(proto.ID, proto.IconOverride ?? proto.Service.GetTexture(_proto), proto.Service.GetEntityView(_proto), name, desc.ToString(), price, false));
|
||||
}
|
||||
|
||||
//Add special sell positions
|
||||
foreach (var (proto, price) in tradePortalComp.CurrentSpecialSellPositions)
|
||||
{
|
||||
var name = proto.NameOverride is null ? proto.Service.GetName(_proto) : Loc.GetString(proto.NameOverride);
|
||||
|
||||
var desc = new StringBuilder();
|
||||
desc.Append("\n" + Loc.GetString("cp14-store-sell-hint", ("name", name)));
|
||||
|
||||
prodSell.Add(new CP14StoreUiProductEntry(
|
||||
proto.ID,
|
||||
proto.Service.GetTexture(_proto),
|
||||
proto.Service.GetEntityView(_proto),
|
||||
name,
|
||||
desc.ToString(),
|
||||
price,
|
||||
true));
|
||||
}
|
||||
|
||||
//Add static sell positions
|
||||
foreach (var (proto, price) in tradePortalComp.CurrentSellPositions)
|
||||
{
|
||||
var name = proto.NameOverride is null ? proto.Service.GetName(_proto) : Loc.GetString(proto.NameOverride);
|
||||
|
||||
var desc = new StringBuilder();
|
||||
desc.Append("\n" + Loc.GetString("cp14-store-sell-hint", ("name", name)));
|
||||
|
||||
prodSell.Add(new CP14StoreUiProductEntry(
|
||||
proto.ID,
|
||||
proto.Service.GetTexture(_proto),
|
||||
proto.Service.GetEntityView(_proto),
|
||||
name,
|
||||
desc.ToString(),
|
||||
price,
|
||||
false));
|
||||
}
|
||||
|
||||
var shopName = ":3";
|
||||
//Get shop name
|
||||
if (ent.Comp.CahcedFaction is not null && _proto.TryIndex(ent.Comp.CahcedFaction.Value, out var indexedShop))
|
||||
{
|
||||
shopName = Loc.GetString(indexedShop.Name);
|
||||
}
|
||||
|
||||
_userInterface.SetUiState(ent.Owner, CP14StoreUiKey.Key, new CP14StoreUiState(shopName, prodBuy, prodSell));
|
||||
}
|
||||
}
|
||||
@@ -1,317 +0,0 @@
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Server._CP14.Currency;
|
||||
using Content.Server.Storage.Components;
|
||||
using Content.Server.Storage.EntitySystems;
|
||||
using Content.Shared._CP14.Cargo;
|
||||
using Content.Shared._CP14.Cargo.Prototype;
|
||||
using Content.Shared._CP14.Currency;
|
||||
using Content.Shared.Paper;
|
||||
using Content.Shared.Stacks;
|
||||
using Content.Shared.Throwing;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._CP14.Cargo;
|
||||
|
||||
public sealed partial class CP14CargoSystem : CP14SharedCargoSystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _userInterface = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private readonly CP14CurrencySystem _currency = default!;
|
||||
[Dependency] private readonly EntityStorageSystem _entityStorage = default!;
|
||||
[Dependency] private readonly ThrowingSystem _throwing = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
|
||||
private IEnumerable<CP14StoreBuyPositionPrototype>? _buyProto;
|
||||
private IEnumerable<CP14StoreSellPositionPrototype>? _sellProto;
|
||||
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
InitializeUI();
|
||||
InitializePortals();
|
||||
|
||||
_buyProto = _proto.EnumeratePrototypes<CP14StoreBuyPositionPrototype>();
|
||||
_sellProto = _proto.EnumeratePrototypes<CP14StoreSellPositionPrototype>();
|
||||
|
||||
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnProtoReload);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
UpdatePortals(frameTime);
|
||||
}
|
||||
|
||||
private void OnProtoReload(PrototypesReloadedEventArgs ev)
|
||||
{
|
||||
_buyProto = _proto.EnumeratePrototypes<CP14StoreBuyPositionPrototype>();
|
||||
_sellProto = _proto.EnumeratePrototypes<CP14StoreSellPositionPrototype>();
|
||||
}
|
||||
|
||||
private void AddRoundstartTradingPositions(Entity<CP14TradingPortalComponent> portal)
|
||||
{
|
||||
if (_buyProto is not null)
|
||||
{
|
||||
foreach (var buy in _buyProto)
|
||||
{
|
||||
if (buy.RoundstartAvailable)
|
||||
portal.Comp.AvailableBuyPosition.Add(buy);
|
||||
}
|
||||
}
|
||||
|
||||
if (_sellProto is not null)
|
||||
{
|
||||
foreach (var sell in _sellProto)
|
||||
{
|
||||
if (sell.RoundstartAvailable)
|
||||
portal.Comp.AvailableSellPosition.Add(sell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateStaticPositions(Entity<CP14TradingPortalComponent> portal)
|
||||
{
|
||||
portal.Comp.CurrentBuyPositions.Clear();
|
||||
portal.Comp.CurrentSellPositions.Clear();
|
||||
|
||||
//Add static positions + cash special ones
|
||||
foreach (var buyPos in portal.Comp.AvailableBuyPosition)
|
||||
{
|
||||
if (buyPos.Special)
|
||||
continue;
|
||||
|
||||
if (buyPos.Factions.Count > 0 && !buyPos.Factions.Contains(portal.Comp.Faction))
|
||||
continue;
|
||||
|
||||
portal.Comp.CurrentBuyPositions.Add(buyPos, buyPos.Price);
|
||||
}
|
||||
|
||||
foreach (var sellPos in portal.Comp.AvailableSellPosition)
|
||||
{
|
||||
if (sellPos.Special)
|
||||
continue;
|
||||
|
||||
if (sellPos.Factions.Count > 0 && !sellPos.Factions.Contains(portal.Comp.Faction))
|
||||
continue;
|
||||
|
||||
portal.Comp.CurrentSellPositions.Add(sellPos, sellPos.Price);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRandomBuySpecialPosition(Entity<CP14TradingPortalComponent> portal, int count)
|
||||
{
|
||||
if (_buyProto is null)
|
||||
return;
|
||||
|
||||
var availableSpecialBuyPositions = new List<CP14StoreBuyPositionPrototype>();
|
||||
foreach (var buyPos in _buyProto)
|
||||
{
|
||||
if (!buyPos.Special)
|
||||
continue;
|
||||
|
||||
if (portal.Comp.CurrentSpecialBuyPositions.ContainsKey(buyPos))
|
||||
continue;
|
||||
|
||||
if (buyPos.Factions.Count > 0 && !buyPos.Factions.Contains(portal.Comp.Faction))
|
||||
continue;
|
||||
|
||||
availableSpecialBuyPositions.Add(buyPos);
|
||||
}
|
||||
|
||||
_random.Shuffle(availableSpecialBuyPositions);
|
||||
|
||||
var added = 0;
|
||||
foreach (var buyPos in availableSpecialBuyPositions)
|
||||
{
|
||||
if (added >= count)
|
||||
break;
|
||||
portal.Comp.CurrentSpecialBuyPositions.Add(buyPos, buyPos.Price);
|
||||
added++;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRandomSellSpecialPosition(Entity<CP14TradingPortalComponent> portal, int count)
|
||||
{
|
||||
if (_sellProto is null)
|
||||
return;
|
||||
|
||||
var availableSpecialSellPositions = new List<CP14StoreSellPositionPrototype>();
|
||||
foreach (var sellPos in _sellProto)
|
||||
{
|
||||
if (!sellPos.Special)
|
||||
continue;
|
||||
|
||||
if (portal.Comp.CurrentSpecialSellPositions.ContainsKey(sellPos))
|
||||
continue;
|
||||
|
||||
if (sellPos.Factions.Count > 0 && !sellPos.Factions.Contains(portal.Comp.Faction))
|
||||
continue;
|
||||
|
||||
availableSpecialSellPositions.Add(sellPos);
|
||||
}
|
||||
|
||||
_random.Shuffle(availableSpecialSellPositions);
|
||||
|
||||
var added = 0;
|
||||
foreach (var sellPos in availableSpecialSellPositions)
|
||||
{
|
||||
if (added >= count)
|
||||
break;
|
||||
portal.Comp.CurrentSpecialSellPositions.Add(sellPos, sellPos.Price);
|
||||
added++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sell all the items we can, and replenish the internal balance
|
||||
/// </summary>
|
||||
private void SellingThings(Entity<CP14TradingPortalComponent> portal, EntityStorageComponent storage)
|
||||
{
|
||||
var containedEntities = storage.Contents.ContainedEntities.ToHashSet();
|
||||
//var ev = new BeforeSellEntities(ref portal.Comp.EntitiesInPortal);
|
||||
//RaiseLocalEvent(ev);
|
||||
|
||||
foreach (var sellPos in portal.Comp.CurrentSellPositions)
|
||||
{
|
||||
//WHILE = sell all we can
|
||||
while (sellPos.Key.Service.TrySell(EntityManager, containedEntities))
|
||||
{
|
||||
portal.Comp.Balance += sellPos.Value;
|
||||
}
|
||||
}
|
||||
|
||||
List<CP14StoreSellPositionPrototype> toRemove = new();
|
||||
foreach (var sellPos in portal.Comp.CurrentSpecialSellPositions)
|
||||
{
|
||||
//IF = only 1 try
|
||||
if (sellPos.Key.Service.TrySell(EntityManager, containedEntities))
|
||||
{
|
||||
portal.Comp.Balance += sellPos.Value;
|
||||
toRemove.Add(sellPos.Key);
|
||||
}
|
||||
}
|
||||
|
||||
//Remove this special position from the list and add new random one
|
||||
foreach (var position in toRemove)
|
||||
{
|
||||
portal.Comp.CurrentSpecialSellPositions.Remove(position);
|
||||
AddRandomSellSpecialPosition(portal, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Take all the money from the portal, and credit it to the internal balance
|
||||
/// </summary>
|
||||
private void TopUpBalance(Entity<CP14TradingPortalComponent> portal, EntityStorageComponent storage)
|
||||
{
|
||||
//Get all currency in portal
|
||||
var cash = 0;
|
||||
foreach (var stored in storage.Contents.ContainedEntities)
|
||||
{
|
||||
if (TryComp<CP14CurrencyComponent>(stored, out var currency))
|
||||
{
|
||||
//fix currency calculation
|
||||
var c = currency.Currency;
|
||||
|
||||
if (TryComp<StackComponent>(stored, out var stack))
|
||||
c *= stack.Count;
|
||||
|
||||
cash += c;
|
||||
QueueDel(stored);
|
||||
}
|
||||
}
|
||||
|
||||
portal.Comp.Balance += cash;
|
||||
}
|
||||
|
||||
private void BuyThings(Entity<CP14TradingPortalComponent> portal, EntityStorageComponent storage)
|
||||
{
|
||||
//Reading all papers in portal
|
||||
List<KeyValuePair<CP14StoreBuyPositionPrototype, int>> requests = new();
|
||||
foreach (var stored in storage.Contents.ContainedEntities)
|
||||
{
|
||||
if (!TryComp<PaperComponent>(stored, out var paper))
|
||||
continue;
|
||||
|
||||
var splittedText = paper.Content.Split("#");
|
||||
foreach (var fragment in splittedText)
|
||||
{
|
||||
foreach (var buyPosition in portal.Comp.CurrentBuyPositions)
|
||||
{
|
||||
if (fragment.StartsWith(buyPosition.Key.Code))
|
||||
requests.Add(buyPosition);
|
||||
}
|
||||
|
||||
foreach (var buyPosition in portal.Comp.CurrentSpecialBuyPositions)
|
||||
{
|
||||
if (fragment.StartsWith(buyPosition.Key.Code))
|
||||
requests.Add(buyPosition);
|
||||
}
|
||||
}
|
||||
|
||||
QueueDel(stored);
|
||||
}
|
||||
|
||||
//Trying to spend inner money to buy requested things
|
||||
foreach (var request in requests)
|
||||
{
|
||||
if (portal.Comp.Balance < request.Value)
|
||||
continue;
|
||||
|
||||
portal.Comp.Balance -= request.Value;
|
||||
|
||||
if (!_proto.TryIndex<CP14StoreBuyPositionPrototype>(request.Key, out var indexedBuyed))
|
||||
continue;
|
||||
|
||||
//Remove this position from the list and add new random one
|
||||
if (request.Key.Special)
|
||||
{
|
||||
portal.Comp.CurrentSpecialBuyPositions.Remove(request.Key);
|
||||
AddRandomBuySpecialPosition(portal, 1);
|
||||
}
|
||||
|
||||
indexedBuyed.Service.Buy(EntityManager, _proto, portal);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transform all the accumulated balance into physical money, which we will give to the players.
|
||||
/// </summary>
|
||||
private void CashOut(Entity<CP14TradingPortalComponent> portal, EntityStorageComponent storage)
|
||||
{
|
||||
var coins = _currency.GenerateMoney(portal.Comp.Balance, Transform(portal).Coordinates);
|
||||
foreach (var coin in coins)
|
||||
{
|
||||
_entityStorage.Insert(coin, portal, storage);
|
||||
}
|
||||
portal.Comp.Balance = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return all items to the map
|
||||
/// </summary>
|
||||
private void ThrowAllItems(Entity<CP14TradingPortalComponent> portal, EntityStorageComponent storage)
|
||||
{
|
||||
var containedEntities = storage.Contents.ContainedEntities.ToList();
|
||||
|
||||
_entityStorage.OpenStorage(portal, storage);
|
||||
|
||||
var xform = Transform(portal);
|
||||
var rotation = xform.LocalRotation;
|
||||
foreach (var stored in containedEntities)
|
||||
{
|
||||
_transform.AttachToGridOrMap(stored);
|
||||
var targetThrowPosition = xform.Coordinates.Offset(rotation.ToWorldVec() * 1);
|
||||
_throwing.TryThrow(stored, targetThrowPosition.Offset(new Vector2(_random.NextFloat(-0.5f, 0.5f), _random.NextFloat(-0.5f, 0.5f))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using Content.Shared._CP14.Currency;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Stacks;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Map;
|
||||
@@ -12,6 +13,7 @@ namespace Content.Server._CP14.Currency;
|
||||
|
||||
public sealed partial class CP14CurrencySystem
|
||||
{
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
private void InitializeConverter()
|
||||
{
|
||||
SubscribeLocalEvent<CP14CurrencyConverterComponent, GetVerbsEvent<Verb>>(OnGetVerb);
|
||||
@@ -115,14 +117,14 @@ public sealed partial class CP14CurrencySystem
|
||||
|
||||
private void OnInteractUsing(Entity<CP14CurrencyConverterComponent> ent, ref InteractUsingEvent args)
|
||||
{
|
||||
if (!TryComp<CP14CurrencyComponent>(args.Used, out var currency))
|
||||
if (!_tag.HasTag(args.Used, ent.Comp.CoinTag))
|
||||
return;
|
||||
|
||||
if (ent.Comp.Whitelist is not null && !_whitelist.IsValid(ent.Comp.Whitelist, args.Used))
|
||||
return;
|
||||
|
||||
var delta = GetTotalCurrencyRecursive(args.Used);
|
||||
ent.Comp.Balance += delta;
|
||||
var delta = _price.GetPrice(args.Used);
|
||||
ent.Comp.Balance += (int)delta;
|
||||
QueueDel(args.Used);
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("cp14-currency-converter-insert", ("cash", delta)), ent, args.User);
|
||||
@@ -130,9 +132,9 @@ public sealed partial class CP14CurrencySystem
|
||||
}
|
||||
|
||||
public HashSet<EntityUid> GenerateMoney(EntProtoId currencyType,
|
||||
int target,
|
||||
double target,
|
||||
EntityCoordinates coordinates,
|
||||
out int remainder)
|
||||
out double remainder)
|
||||
{
|
||||
remainder = target;
|
||||
HashSet<EntityUid> spawns = new();
|
||||
@@ -155,7 +157,7 @@ public sealed partial class CP14CurrencySystem
|
||||
}
|
||||
|
||||
public HashSet<EntityUid> GenerateMoney(
|
||||
int target,
|
||||
double target,
|
||||
EntityCoordinates coordinates)
|
||||
{
|
||||
HashSet<EntityUid> coins = new();
|
||||
@@ -204,9 +206,9 @@ public sealed partial class CP14CurrencySystem
|
||||
return coins;
|
||||
}
|
||||
|
||||
private bool ProcessEntity(EntityUid ent, ref int remainder, HashSet<EntityUid> spawns)
|
||||
private bool ProcessEntity(EntityUid ent, ref double remainder, HashSet<EntityUid> spawns)
|
||||
{
|
||||
var singleCurrency = GetTotalCurrencyRecursive(ent);
|
||||
var singleCurrency = _price.GetPrice(ent);
|
||||
|
||||
if (singleCurrency > remainder)
|
||||
{
|
||||
@@ -229,15 +231,15 @@ public sealed partial class CP14CurrencySystem
|
||||
private void AdjustStack(EntityUid ent,
|
||||
StackComponent stack,
|
||||
StackPrototype stackProto,
|
||||
float singleCurrency,
|
||||
ref int remainder)
|
||||
double singleCurrency,
|
||||
ref double remainder)
|
||||
{
|
||||
var singleStackCurrency = singleCurrency / stack.Count;
|
||||
var stackLeftSpace = stackProto.MaxCount - stack.Count;
|
||||
|
||||
if (stackLeftSpace is not null)
|
||||
{
|
||||
var addedStack = MathF.Min((float)stackLeftSpace, MathF.Floor(remainder / singleStackCurrency));
|
||||
var addedStack = MathF.Min((float)stackLeftSpace, MathF.Floor((float)(remainder / singleStackCurrency)));
|
||||
|
||||
if (addedStack > 0)
|
||||
{
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
using Content.Server.Cargo.Systems;
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Stack;
|
||||
using Content.Server.Storage.Components;
|
||||
using Content.Shared._CP14.Currency;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Stacks;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Server.Audio;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Currency;
|
||||
@@ -19,6 +16,7 @@ public sealed partial class CP14CurrencySystem : CP14SharedCurrencySystem
|
||||
[Dependency] private readonly StackSystem _stack = default!;
|
||||
[Dependency] private readonly AudioSystem _audio = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly PricingSystem _price = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -27,46 +25,13 @@ public sealed partial class CP14CurrencySystem : CP14SharedCurrencySystem
|
||||
InitializeConverter();
|
||||
|
||||
SubscribeLocalEvent<CP14CurrencyExaminableComponent, ExaminedEvent>(OnExamine);
|
||||
|
||||
SubscribeLocalEvent<CP14CurrencyComponent, CP14GetCurrencyEvent>(OnGetCurrency);
|
||||
SubscribeLocalEvent<ContainerManagerComponent, CP14GetCurrencyEvent>(OnContainerGetCurrency);
|
||||
}
|
||||
|
||||
private void OnGetCurrency(Entity<CP14CurrencyComponent> ent, ref CP14GetCurrencyEvent args)
|
||||
{
|
||||
if (args.CheckedEntities.Contains(ent))
|
||||
return;
|
||||
|
||||
var total = ent.Comp.Currency;
|
||||
if (TryComp<StackComponent>(ent, out var stack))
|
||||
{
|
||||
total *= stack.Count;
|
||||
}
|
||||
|
||||
args.Currency += total;
|
||||
args.CheckedEntities.Add(ent);
|
||||
}
|
||||
|
||||
private void OnContainerGetCurrency(Entity<ContainerManagerComponent> ent, ref CP14GetCurrencyEvent args)
|
||||
{
|
||||
var total = 0;
|
||||
foreach (var container in ent.Comp.Containers.Values)
|
||||
{
|
||||
foreach (var containedEnt in container.ContainedEntities)
|
||||
{
|
||||
total += GetTotalCurrencyRecursive(containedEnt);
|
||||
}
|
||||
}
|
||||
|
||||
args.Currency += total;
|
||||
}
|
||||
|
||||
private void OnExamine(Entity<CP14CurrencyExaminableComponent> currency, ref ExaminedEvent args)
|
||||
{
|
||||
var total = GetTotalCurrencyRecursive(currency);
|
||||
|
||||
var price = _price.GetPrice(currency);
|
||||
var push = Loc.GetString("cp14-currency-examine-title");
|
||||
push += GetCurrencyPrettyString(total);
|
||||
push += GetCurrencyPrettyString((int)price);
|
||||
args.PushMarkup(push);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using Content.Server.Cargo.Components;
|
||||
using Content.Server.Item;
|
||||
using Content.Shared._CP14.ModularCraft;
|
||||
using Content.Shared._CP14.ModularCraft.Components;
|
||||
using Content.Shared._CP14.ModularCraft.Prototypes;
|
||||
using Content.Shared.Throwing;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Materials;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -182,6 +184,36 @@ public sealed class CP14ModularCraftSystem : CP14SharedModularCraftSystem
|
||||
|
||||
var indexedPart = _proto.Index(partProto);
|
||||
|
||||
if (TryComp<PhysicalCompositionComponent>(part, out var partMaterial))
|
||||
{
|
||||
var startMaterial = EnsureComp<PhysicalCompositionComponent>(start);
|
||||
|
||||
//Merge materials
|
||||
foreach (var (material, count) in partMaterial.MaterialComposition)
|
||||
{
|
||||
if (startMaterial.MaterialComposition.TryGetValue(material, out var existingCount))
|
||||
startMaterial.MaterialComposition[material] = existingCount + count;
|
||||
else
|
||||
startMaterial.MaterialComposition[material] = count;
|
||||
}
|
||||
|
||||
//Merge solutions
|
||||
foreach (var (sol, count) in partMaterial.ChemicalComposition)
|
||||
{
|
||||
if (startMaterial.ChemicalComposition.TryGetValue(sol, out var existingCount))
|
||||
startMaterial.ChemicalComposition[sol] = existingCount + count;
|
||||
else
|
||||
startMaterial.ChemicalComposition[sol] = count;
|
||||
}
|
||||
}
|
||||
|
||||
if (TryComp<StaticPriceComponent>(part, out var staticPartPrice))
|
||||
{
|
||||
var startStaticPrice = EnsureComp<StaticPriceComponent>(start);
|
||||
|
||||
startStaticPrice.Price += staticPartPrice.Price;
|
||||
}
|
||||
|
||||
foreach (var modifier in indexedPart.Modifiers)
|
||||
{
|
||||
modifier.Effect(EntityManager, start, part);
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
using Content.Server._CP14.Objectives.Systems;
|
||||
using Content.Shared.Objectives;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Objectives.Components;
|
||||
|
||||
[RegisterComponent, Access(typeof(CP14TownSendConditionSystem))]
|
||||
public sealed partial class CP14TownSendConditionComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public ProtoId<StealTargetGroupPrototype> CollectGroup;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum number of items you need to steal to fulfill a objective
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int MinCollectionSize = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of items you need to steal to fulfill a objective
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int MaxCollectionSize = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Target collection size after calculation
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int CollectionSize;
|
||||
|
||||
/// <summary>
|
||||
/// how many items have already been sent to the city
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int CollectionSent = 0;
|
||||
|
||||
[DataField(required: true)]
|
||||
public LocId ObjectiveText;
|
||||
|
||||
[DataField(required: true)]
|
||||
public LocId ObjectiveDescription;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Server._CP14.Objectives.Components;
|
||||
using Content.Server.Cargo.Systems;
|
||||
using Content.Server.Objectives.Components;
|
||||
using Content.Shared._CP14.Currency;
|
||||
using Content.Shared.Interaction;
|
||||
@@ -16,6 +17,7 @@ public sealed class CP14CurrencyCollectConditionSystem : EntitySystem
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
[Dependency] private readonly SharedObjectivesSystem _objectives = default!;
|
||||
[Dependency] private readonly CP14SharedCurrencySystem _currency = default!;
|
||||
[Dependency] private readonly PricingSystem _price = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -40,15 +42,16 @@ public sealed class CP14CurrencyCollectConditionSystem : EntitySystem
|
||||
|
||||
private float GetProgress(MindComponent mind, CP14CurrencyCollectConditionComponent condition)
|
||||
{
|
||||
var count = 0;
|
||||
double count = 0;
|
||||
|
||||
if (mind.OwnedEntity is null)
|
||||
return 0;
|
||||
|
||||
count += _currency.GetTotalCurrencyRecursive(mind.OwnedEntity.Value);
|
||||
count += _price.GetPrice(mind.OwnedEntity.Value);
|
||||
count -= _price.GetPrice(mind.OwnedEntity.Value, false); //We don't want to count the price of the entity itself.
|
||||
|
||||
var result = count / (float)condition.Currency;
|
||||
result = Math.Clamp(result, 0, 1);
|
||||
return result;
|
||||
return (float)result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
using Content.Server._CP14.Objectives.Components;
|
||||
using Content.Shared._CP14.Cargo;
|
||||
using Content.Shared.Objectives.Components;
|
||||
using Content.Shared.Objectives.Systems;
|
||||
using Content.Shared.Stacks;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server._CP14.Objectives.Systems;
|
||||
|
||||
public sealed class CP14TownSendConditionSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
[Dependency] private readonly SharedObjectivesSystem _objectives = default!;
|
||||
|
||||
private EntityQuery<StealTargetComponent> _stealQuery;
|
||||
private EntityQuery<StackComponent> _stackQuery;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_stealQuery = GetEntityQuery<StealTargetComponent>();
|
||||
_stackQuery = GetEntityQuery<StackComponent>();
|
||||
|
||||
SubscribeLocalEvent<CP14TownSendConditionComponent, ObjectiveAfterAssignEvent>(OnAfterAssign);
|
||||
SubscribeLocalEvent<CP14TownSendConditionComponent, ObjectiveGetProgressEvent>(OnGetProgress);
|
||||
|
||||
SubscribeLocalEvent<BeforeSellEntities>(OnBeforeSell);
|
||||
}
|
||||
|
||||
private void OnBeforeSell(BeforeSellEntities ev)
|
||||
{
|
||||
var query = EntityQueryEnumerator<CP14TownSendConditionComponent>();
|
||||
|
||||
HashSet<EntityUid> removed = new();
|
||||
while (query.MoveNext(out var uid, out var condition))
|
||||
{
|
||||
foreach (var sentEnt in ev.Sent)
|
||||
{
|
||||
if (condition.CollectionSent >= condition.CollectionSize)
|
||||
continue;
|
||||
|
||||
if (!_stealQuery.TryComp(sentEnt, out var stealTarget))
|
||||
continue;
|
||||
|
||||
if (stealTarget.StealGroup != condition.CollectGroup)
|
||||
continue;
|
||||
|
||||
if (_stackQuery.TryComp(sentEnt, out var stack))
|
||||
{
|
||||
condition.CollectionSent += stack.Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
condition.CollectionSent++;
|
||||
}
|
||||
|
||||
if (!removed.Contains(sentEnt))
|
||||
removed.Add(sentEnt);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var remove in removed)
|
||||
{
|
||||
ev.Sent.Remove(remove);
|
||||
QueueDel(remove);
|
||||
}
|
||||
}
|
||||
|
||||
//Set the visual, name, icon for the objective.
|
||||
private void OnAfterAssign(Entity<CP14TownSendConditionComponent> condition, ref ObjectiveAfterAssignEvent args)
|
||||
{
|
||||
condition.Comp.CollectionSize = _random.Next(condition.Comp.MinCollectionSize, condition.Comp.MaxCollectionSize);
|
||||
|
||||
var group = _proto.Index(condition.Comp.CollectGroup);
|
||||
|
||||
var title = Loc.GetString(condition.Comp.ObjectiveText, ("itemName", Loc.GetString(group.Name)), ("count", condition.Comp.CollectionSize));
|
||||
var description = Loc.GetString(condition.Comp.ObjectiveDescription, ("itemName", Loc.GetString(group.Name)), ("count", condition.Comp.CollectionSize));
|
||||
|
||||
_metaData.SetEntityName(condition.Owner, title, args.Meta);
|
||||
_metaData.SetEntityDescription(condition.Owner, description, args.Meta);
|
||||
_objectives.SetIcon(condition.Owner, group.Sprite, args.Objective);
|
||||
}
|
||||
|
||||
private void OnGetProgress(Entity<CP14TownSendConditionComponent> condition, ref ObjectiveGetProgressEvent args)
|
||||
{
|
||||
var result = (float)condition.Comp.CollectionSent / (float)condition.Comp.CollectionSize;
|
||||
result = Math.Clamp(result, 0, 1);
|
||||
args.Progress = result;
|
||||
}
|
||||
}
|
||||
20
Content.Server/_CP14/Trading/CP14SellingPlatformComponent.cs
Normal file
20
Content.Server/_CP14/Trading/CP14SellingPlatformComponent.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Trading;
|
||||
|
||||
/// <summary>
|
||||
/// Allows you to sell items by overloading the platform with energy
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14SellingPlatformComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public SoundSpecifier SellSound = new SoundPathSpecifier("/Audio/_CP14/Effects/cash.ogg")
|
||||
{
|
||||
Params = AudioParams.Default.WithVariation(0.1f),
|
||||
};
|
||||
|
||||
[DataField]
|
||||
public EntProtoId SellVisual = "CP14CashImpact";
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using Content.Server.Cargo.Systems;
|
||||
using Content.Shared.Weapons.Melee;
|
||||
|
||||
namespace Content.Server._CP14.Trading;
|
||||
|
||||
public sealed partial class CP14StationEconomySystem
|
||||
{
|
||||
private void InitPriceEvents()
|
||||
{
|
||||
SubscribeLocalEvent<MeleeWeaponComponent, PriceCalculationEvent>(OnMeleeWeaponPriceCalculation);
|
||||
}
|
||||
|
||||
private void OnMeleeWeaponPriceCalculation(Entity<MeleeWeaponComponent> ent, ref PriceCalculationEvent args)
|
||||
{
|
||||
//double price = 0;
|
||||
//var dps = ent.Comp.Damage.GetTotal() * ent.Comp.AttackRate;
|
||||
//if (dps <= 0)
|
||||
// return;
|
||||
//
|
||||
//price += dps.Value;
|
||||
//
|
||||
//if (ent.Comp.ResetOnHandSelected == false)
|
||||
// price *= 1.5; // If the weapon doesn't reset on hand selection, it's more valuable.
|
||||
//
|
||||
//if (ent.Comp.AltDisarm)
|
||||
// price *= 1.5; // If the weapon has an alt disarm, it's more valuable.
|
||||
//
|
||||
//args.Price += price * 0.1f;
|
||||
}
|
||||
}
|
||||
54
Content.Server/_CP14/Trading/CP14StationEconomySystem.cs
Normal file
54
Content.Server/_CP14/Trading/CP14StationEconomySystem.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using Content.Server.Cargo.Systems;
|
||||
using Content.Server.Station.Events;
|
||||
using Content.Shared._CP14.Trading.BuyServices;
|
||||
using Content.Shared._CP14.Trading.Components;
|
||||
using Content.Shared._CP14.Trading.Prototypes;
|
||||
using Content.Shared._CP14.Trading.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server._CP14.Trading;
|
||||
|
||||
public sealed partial class CP14StationEconomySystem : CP14SharedStationEconomySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly PricingSystem _price = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
InitPriceEvents();
|
||||
|
||||
SubscribeLocalEvent<CP14StationEconomyComponent, StationPostInitEvent>(OnStationPostInit);
|
||||
}
|
||||
|
||||
private void OnStationPostInit(Entity<CP14StationEconomyComponent> ent, ref StationPostInitEvent args)
|
||||
{
|
||||
UpdatePricing(ent);
|
||||
}
|
||||
|
||||
private void UpdatePricing(Entity<CP14StationEconomyComponent> ent)
|
||||
{
|
||||
ent.Comp.Pricing.Clear();
|
||||
foreach (var trade in _proto.EnumeratePrototypes<CP14TradingPositionPrototype>())
|
||||
{
|
||||
double price = 0;
|
||||
switch (trade.Service)
|
||||
{
|
||||
case CP14BuyItemsService buyItems:
|
||||
if (!_proto.TryIndex(buyItems.Product, out var indexedProduct))
|
||||
break;
|
||||
price += _price.GetEstimatedPrice(indexedProduct) * buyItems.Count;
|
||||
break;
|
||||
}
|
||||
|
||||
price += trade.PriceMarkup;
|
||||
|
||||
//Random fluctuation
|
||||
price *= 1 + _random.NextFloat(trade.PriceFluctuation);
|
||||
|
||||
ent.Comp.Pricing.TryAdd(trade, (int) price);
|
||||
}
|
||||
Dirty(ent);
|
||||
}
|
||||
}
|
||||
125
Content.Server/_CP14/Trading/CP14TradingPlatformSystem.cs
Normal file
125
Content.Server/_CP14/Trading/CP14TradingPlatformSystem.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using Content.Server._CP14.Currency;
|
||||
using Content.Server._CP14.MagicEnergy;
|
||||
using Content.Server.Cargo.Systems;
|
||||
using Content.Shared._CP14.MagicEnergy;
|
||||
using Content.Shared._CP14.Trading.Components;
|
||||
using Content.Shared._CP14.Trading.Prototypes;
|
||||
using Content.Shared._CP14.Trading.Systems;
|
||||
using Content.Shared.Mobs.Components;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Placeable;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server._CP14.Trading;
|
||||
|
||||
public sealed partial class CP14TradingPlatformSystem : CP14SharedTradingPlatformSystem
|
||||
{
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly PricingSystem _price = default!;
|
||||
[Dependency] private readonly CP14CurrencySystem _cp14Currency = default!;
|
||||
[Dependency] private readonly CP14StationEconomySystem _economy = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly CP14MagicEnergySystem _magicEnergy = default!;
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CP14TradingPlatformComponent, CP14TradingPositionBuyAttempt>(OnBuyAttempt);
|
||||
SubscribeLocalEvent<CP14SellingPlatformComponent, CP14MagicEnergyOverloadEvent>(OnMagicOverload);
|
||||
}
|
||||
|
||||
private void OnMagicOverload(Entity<CP14SellingPlatformComponent> ent, ref CP14MagicEnergyOverloadEvent args)
|
||||
{
|
||||
_magicEnergy.ClearEnergy(ent.Owner);
|
||||
|
||||
if (!TryComp<ItemPlacerComponent>(ent, out var itemPlacer))
|
||||
return;
|
||||
|
||||
double price = 0;
|
||||
foreach (var placed in itemPlacer.PlacedEntities)
|
||||
{
|
||||
if (HasComp<MobStateComponent>(placed))
|
||||
continue;
|
||||
|
||||
var placedPrice = _price.GetPrice(placed);
|
||||
|
||||
if (placedPrice <= 0)
|
||||
continue;
|
||||
|
||||
price += placedPrice;
|
||||
QueueDel(placed);
|
||||
}
|
||||
|
||||
_audio.PlayPvs(ent.Comp.SellSound, Transform(ent).Coordinates);
|
||||
_cp14Currency.GenerateMoney(price, Transform(ent).Coordinates);
|
||||
SpawnAtPosition(ent.Comp.SellVisual, Transform(ent).Coordinates);
|
||||
}
|
||||
|
||||
private void OnBuyAttempt(Entity<CP14TradingPlatformComponent> ent, ref CP14TradingPositionBuyAttempt args)
|
||||
{
|
||||
TryBuyPosition(args.Actor, ent, args.Position);
|
||||
UpdateUIState(ent, args.Actor);
|
||||
}
|
||||
|
||||
public bool TryBuyPosition(Entity<CP14TradingReputationComponent?> user, Entity<CP14TradingPlatformComponent> platform, ProtoId<CP14TradingPositionPrototype> position)
|
||||
{
|
||||
if (!CanBuyPosition(user, platform!, position))
|
||||
return false;
|
||||
|
||||
if (!Proto.TryIndex(position, out var indexedPosition))
|
||||
return false;
|
||||
|
||||
if (!Resolve(user.Owner, ref user.Comp, false))
|
||||
return false;
|
||||
|
||||
if (!TryComp<ItemPlacerComponent>(platform, out var itemPlacer))
|
||||
return false;
|
||||
|
||||
//Top up balance
|
||||
double balance = 0;
|
||||
foreach (var placedEntity in itemPlacer.PlacedEntities)
|
||||
{
|
||||
if (!_tag.HasTag(placedEntity, platform.Comp.CoinTag))
|
||||
continue;
|
||||
balance += _price.GetPrice(placedEntity);
|
||||
}
|
||||
|
||||
var price = _economy.GetPrice(position) ?? 10000;
|
||||
if (balance < price)
|
||||
{
|
||||
// Not enough balance to buy the position
|
||||
_popup.PopupEntity(Loc.GetString("cp14-trading-failure-popup-money"), platform);
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var placedEntity in itemPlacer.PlacedEntities)
|
||||
{
|
||||
if (!_tag.HasTag(placedEntity, platform.Comp.CoinTag))
|
||||
continue;
|
||||
QueueDel(placedEntity);
|
||||
}
|
||||
|
||||
balance -= price;
|
||||
|
||||
platform.Comp.NextBuyTime = Timing.CurTime + TimeSpan.FromSeconds(1f);
|
||||
Dirty(platform);
|
||||
|
||||
if (indexedPosition.Service is not null)
|
||||
indexedPosition.Service.Buy(EntityManager, Proto, platform);
|
||||
user.Comp.Reputation[indexedPosition.Faction] += (float)price / 10;
|
||||
Dirty(user);
|
||||
|
||||
_audio.PlayPvs(platform.Comp.BuySound, Transform(platform).Coordinates);
|
||||
|
||||
//return the change
|
||||
_cp14Currency.GenerateMoney(balance, Transform(platform).Coordinates);
|
||||
SpawnAtPosition(platform.Comp.BuyVisual, Transform(platform).Coordinates);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ public sealed partial class ArmorComponent : Component
|
||||
/// to determine the monetary value of the armor
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float PriceMultiplier = 1;
|
||||
public float PriceMultiplier = 0.25f; //CP14 1 -> 0.25 (different economy)
|
||||
|
||||
/// <summary>
|
||||
/// If true, you can examine the armor to see the protection. If false, the verb won't appear.
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
namespace Content.Shared._CP14.Cargo;
|
||||
|
||||
public class CP14SharedCargoSystem : EntitySystem
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// is called in just before the goods are shipped into town, and before the profit on them is calculated. It allows you to edit the list of sent items.
|
||||
/// </summary>
|
||||
public sealed class BeforeSellEntities : EntityEventArgs
|
||||
{
|
||||
public HashSet<EntityUid> Sent;
|
||||
|
||||
public BeforeSellEntities(ref HashSet<EntityUid> sent)
|
||||
{
|
||||
Sent = sent;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using Content.Shared._CP14.Workbench;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.Cargo;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum CP14StoreUiKey
|
||||
{
|
||||
Key,
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14StoreUiState : BoundUserInterfaceState
|
||||
{
|
||||
public readonly string ShopName;
|
||||
public readonly HashSet<CP14StoreUiProductEntry> ProductsBuy;
|
||||
public readonly HashSet<CP14StoreUiProductEntry> ProductsSell;
|
||||
|
||||
public CP14StoreUiState(string name, HashSet<CP14StoreUiProductEntry> productsBuy, HashSet<CP14StoreUiProductEntry> productsSell)
|
||||
{
|
||||
ShopName = name;
|
||||
ProductsBuy = productsBuy;
|
||||
ProductsSell = productsSell;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public readonly struct CP14StoreUiProductEntry : IEquatable<CP14StoreUiProductEntry>
|
||||
{
|
||||
public readonly string ProtoId;
|
||||
public readonly SpriteSpecifier? Icon;
|
||||
public readonly EntProtoId? EntityView;
|
||||
public readonly string Name;
|
||||
public readonly string Desc;
|
||||
public readonly int Price;
|
||||
public readonly bool Special;
|
||||
|
||||
public CP14StoreUiProductEntry(string protoId, SpriteSpecifier? icon, EntProtoId? entityView, string name, string desc, int price, bool special)
|
||||
{
|
||||
ProtoId = protoId;
|
||||
Icon = icon;
|
||||
EntityView = entityView;
|
||||
Name = name;
|
||||
Desc = desc;
|
||||
Price = price;
|
||||
Special = special;
|
||||
}
|
||||
|
||||
public bool Equals(CP14StoreUiProductEntry other)
|
||||
{
|
||||
return ProtoId == other.ProtoId;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is CP14StoreUiProductEntry other && Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(ProtoId, Icon, Name, Desc, Price);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using Content.Shared._CP14.Cargo.Prototype;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Cargo;
|
||||
|
||||
/// <summary>
|
||||
/// Allows users to view information on faction trading opportunities
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14TradingInfoBoardComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public EntityUid? TradingPortal = null;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<CP14StoreFactionPrototype>? CahcedFaction;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
using Content.Shared._CP14.Cargo.Prototype;
|
||||
using Content.Shared.Destructible.Thresholds;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Cargo;
|
||||
|
||||
/// <summary>
|
||||
/// Add to the station so ...
|
||||
/// </summary>
|
||||
[NetworkedComponent, RegisterComponent, AutoGenerateComponentPause, AutoGenerateComponentState]
|
||||
public sealed partial class CP14TradingPortalComponent : Component
|
||||
{
|
||||
[DataField(required: true), AutoNetworkedField]
|
||||
public ProtoId<CP14StoreFactionPrototype> Faction = default;
|
||||
|
||||
[DataField]
|
||||
public EntityCoordinates? TradingPosition = null;
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public TimeSpan Delay = TimeSpan.FromSeconds(3f);
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
[AutoPausedField]
|
||||
public TimeSpan ProcessFinishTime = TimeSpan.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Available to random selecting and pusharing
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public HashSet<CP14StoreBuyPositionPrototype> AvailableBuyPosition = new();
|
||||
|
||||
/// <summary>
|
||||
/// Available to random selecting and pusharing
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public HashSet<CP14StoreSellPositionPrototype> AvailableSellPosition = new();
|
||||
|
||||
/// <summary>
|
||||
/// Fixed prices and positions of the current flight
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Dictionary<CP14StoreBuyPositionPrototype, int> CurrentBuyPositions = new(); //Proto, price
|
||||
|
||||
[DataField]
|
||||
public Dictionary<CP14StoreBuyPositionPrototype, int> CurrentSpecialBuyPositions = new(); //Proto, price
|
||||
|
||||
[DataField]
|
||||
public int SpecialBuyPositionCount = 2;
|
||||
|
||||
[DataField]
|
||||
public Dictionary<CP14StoreSellPositionPrototype, int> CurrentSellPositions = new(); //Proto, price
|
||||
|
||||
[DataField]
|
||||
public Dictionary<CP14StoreSellPositionPrototype, int> CurrentSpecialSellPositions = new(); //Proto, price
|
||||
|
||||
[DataField]
|
||||
public int SpecialSellPositionCount = 2;
|
||||
|
||||
[DataField]
|
||||
public int Balance = 0;
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.Cargo.Prototype.BuyServices;
|
||||
|
||||
public sealed partial class CP14UnlockPositionsService : CP14StoreBuyService
|
||||
{
|
||||
[DataField]
|
||||
public HashSet<ProtoId<CP14StoreBuyPositionPrototype>> AddBuyPositions = new();
|
||||
|
||||
[DataField]
|
||||
public HashSet<ProtoId<CP14StoreSellPositionPrototype>> AddSellPositions = new();
|
||||
|
||||
[DataField]
|
||||
public HashSet<ProtoId<CP14StoreBuyPositionPrototype>> RemoveBuyPositions = new();
|
||||
|
||||
[DataField]
|
||||
public HashSet<ProtoId<CP14StoreSellPositionPrototype>> RemoveSellPositions = new();
|
||||
|
||||
[DataField]
|
||||
public SpriteSpecifier? Icon = null;
|
||||
|
||||
[DataField]
|
||||
public LocId Name = string.Empty;
|
||||
|
||||
public override void Buy(EntityManager entManager, IPrototypeManager prototype, Entity<CP14TradingPortalComponent> portal)
|
||||
{
|
||||
foreach (var buy in AddBuyPositions)
|
||||
{
|
||||
if (!prototype.TryIndex(buy, out var indexedBuy))
|
||||
continue;
|
||||
|
||||
portal.Comp.AvailableBuyPosition.Add(indexedBuy);
|
||||
}
|
||||
|
||||
foreach (var sell in AddSellPositions)
|
||||
{
|
||||
if (!prototype.TryIndex(sell, out var indexedSell))
|
||||
continue;
|
||||
|
||||
portal.Comp.AvailableSellPosition.Add(indexedSell);
|
||||
}
|
||||
|
||||
foreach (var rBuy in RemoveBuyPositions)
|
||||
{
|
||||
if (!prototype.TryIndex(rBuy, out var indexedBuy))
|
||||
continue;
|
||||
|
||||
if (!portal.Comp.AvailableBuyPosition.Contains(indexedBuy))
|
||||
continue;
|
||||
|
||||
portal.Comp.AvailableBuyPosition.Remove(indexedBuy);
|
||||
}
|
||||
|
||||
foreach (var rSell in RemoveSellPositions)
|
||||
{
|
||||
if (!prototype.TryIndex(rSell, out var indexedSell))
|
||||
continue;
|
||||
|
||||
if (!portal.Comp.AvailableSellPosition.Contains(indexedSell))
|
||||
continue;
|
||||
|
||||
portal.Comp.AvailableSellPosition.Remove(indexedSell);
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetName(IPrototypeManager protoMan)
|
||||
{
|
||||
return Loc.GetString(Name);
|
||||
}
|
||||
|
||||
public override EntProtoId? GetEntityView(IPrototypeManager protoManager)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override SpriteSpecifier? GetTexture(IPrototypeManager protoManager)
|
||||
{
|
||||
return Icon;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.Cargo.Prototype;
|
||||
|
||||
/// <summary>
|
||||
/// Stores the price and product/service pair that players can buy.
|
||||
/// </summary>
|
||||
[Prototype("storePositionBuy")]
|
||||
public sealed partial class CP14StoreBuyPositionPrototype : IPrototype
|
||||
{
|
||||
[IdDataField, ViewVariables]
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
[DataField(required: true)]
|
||||
public int Price = 100;
|
||||
|
||||
/// <summary>
|
||||
/// a unique code that can be used to purchase items.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public string Code = string.Empty;
|
||||
|
||||
[DataField(required: true, serverOnly: true)]
|
||||
public CP14StoreBuyService Service = default!;
|
||||
|
||||
[DataField]
|
||||
public SpriteSpecifier? IconOverride;
|
||||
|
||||
[DataField]
|
||||
public LocId? NameOverride;
|
||||
|
||||
[DataField]
|
||||
public bool RoundstartAvailable = true;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this item will randomly appear under the ‘Special Offer’ heading. With a chance to show up every time the ship arrives.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool Special;
|
||||
|
||||
[DataField]
|
||||
public HashSet<ProtoId<CP14StoreFactionPrototype>> Factions = new();
|
||||
}
|
||||
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
[MeansImplicitUse]
|
||||
public abstract partial class CP14StoreBuyService
|
||||
{
|
||||
public abstract void Buy(EntityManager entManager, IPrototypeManager prototype, Entity<CP14TradingPortalComponent> portal);
|
||||
|
||||
public abstract string GetName(IPrototypeManager protoMan);
|
||||
|
||||
/// <summary>
|
||||
/// You can specify an icon generated from an entity. It will support layering, colour changes and other layer options. Return null to disable.
|
||||
/// </summary>
|
||||
public abstract EntProtoId? GetEntityView(IPrototypeManager protoManager);
|
||||
|
||||
/// <summary>
|
||||
/// You can specify the texture directly. Return null to disable.
|
||||
/// </summary>
|
||||
public abstract SpriteSpecifier? GetTexture(IPrototypeManager protoManager);
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Cargo.Prototype;
|
||||
|
||||
[Prototype("storeFaction")]
|
||||
public sealed partial class CP14StoreFactionPrototype : IPrototype
|
||||
{
|
||||
[IdDataField, ViewVariables]
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
[DataField(required: true)]
|
||||
public LocId Name = string.Empty;
|
||||
|
||||
[DataField]
|
||||
public LocId Desc = string.Empty;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
using Content.Shared.Destructible.Thresholds;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.Cargo.Prototype;
|
||||
|
||||
/// <summary>
|
||||
/// Stores the price and product/service pair that players can buy.
|
||||
/// </summary>
|
||||
[Prototype("storePositionSell")]
|
||||
public sealed partial class CP14StoreSellPositionPrototype : IPrototype
|
||||
{
|
||||
[IdDataField, ViewVariables]
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
[DataField(required: true)]
|
||||
public int Price = 100;
|
||||
|
||||
[DataField(required: true, serverOnly: true)]
|
||||
public CP14StoreSellService Service = default!;
|
||||
|
||||
[DataField]
|
||||
public SpriteSpecifier? IconOverride;
|
||||
|
||||
[DataField]
|
||||
public LocId? NameOverride;
|
||||
|
||||
[DataField]
|
||||
public bool RoundstartAvailable = true;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this item will randomly appear under the ‘Special Offer’ heading. With a chance to show up every time the ship arrives.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool Special;
|
||||
|
||||
[DataField]
|
||||
public HashSet<ProtoId<CP14StoreFactionPrototype>> Factions = new();
|
||||
}
|
||||
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
[MeansImplicitUse]
|
||||
public abstract partial class CP14StoreSellService
|
||||
{
|
||||
public abstract bool TrySell(EntityManager entManager, HashSet<EntityUid> entities);
|
||||
|
||||
public abstract string GetName(IPrototypeManager protoMan);
|
||||
|
||||
/// <summary>
|
||||
/// You can specify an icon generated from an entity. It will support layering, colour changes and other layer options. Return null to disable.
|
||||
/// </summary>
|
||||
public abstract EntProtoId? GetEntityView(IPrototypeManager protoManager);
|
||||
|
||||
/// <summary>
|
||||
/// You can specify the texture directly. Return null to disable.
|
||||
/// </summary>
|
||||
public abstract SpriteSpecifier? GetTexture(IPrototypeManager protoManager);
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.Cargo.Prototype.SellServices;
|
||||
|
||||
public sealed partial class CP14SellPrototypeService : CP14StoreSellService
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public EntProtoId Proto;
|
||||
|
||||
[DataField]
|
||||
public int Count = 1;
|
||||
|
||||
public override bool TrySell(EntityManager entManager, HashSet<EntityUid> entities)
|
||||
{
|
||||
HashSet<EntityUid> suitable = new();
|
||||
|
||||
var needCount = Count;
|
||||
foreach (var ent in entities)
|
||||
{
|
||||
if (needCount <= 0)
|
||||
break;
|
||||
|
||||
if (!entManager.TryGetComponent<MetaDataComponent>(ent, out var metaData))
|
||||
continue;
|
||||
|
||||
if (metaData.EntityPrototype is null)
|
||||
continue;
|
||||
|
||||
if (metaData.EntityPrototype != Proto)
|
||||
continue;
|
||||
|
||||
suitable.Add(ent);
|
||||
needCount -= 1;
|
||||
}
|
||||
|
||||
if (needCount > 0)
|
||||
return false;
|
||||
|
||||
foreach (var selledEnt in suitable)
|
||||
{
|
||||
entManager.DeleteEntity(selledEnt);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string GetName(IPrototypeManager protoMan)
|
||||
{
|
||||
if (!protoMan.TryIndex(Proto, out var proto))
|
||||
return ":3";
|
||||
|
||||
return $"{proto.Name} x{Count}";
|
||||
}
|
||||
|
||||
public override EntProtoId? GetEntityView(IPrototypeManager protoManager)
|
||||
{
|
||||
return Proto;
|
||||
}
|
||||
|
||||
public override SpriteSpecifier? GetTexture(IPrototypeManager protoManager)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
using Content.Shared.Stacks;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.Cargo.Prototype.SellServices;
|
||||
|
||||
public sealed partial class CP14SellStackService : CP14StoreSellService
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public ProtoId<StackPrototype> StackId;
|
||||
|
||||
[DataField(required: true)]
|
||||
public int Count = 1;
|
||||
|
||||
public override bool TrySell(EntityManager entManager, HashSet<EntityUid> entities)
|
||||
{
|
||||
var stackSystem = entManager.System<SharedStackSystem>();
|
||||
|
||||
Dictionary<Entity<StackComponent>, int> suitable = new();
|
||||
|
||||
var needCount = Count;
|
||||
foreach (var ent in entities)
|
||||
{
|
||||
if (needCount <= 0)
|
||||
break;
|
||||
|
||||
if (!entManager.TryGetComponent<StackComponent>(ent, out var stack) || stack.StackTypeId != StackId.Id)
|
||||
continue;
|
||||
|
||||
var consumed = Math.Min(needCount, stack.Count);
|
||||
suitable.Add((ent,stack), consumed);
|
||||
needCount -= consumed;
|
||||
}
|
||||
|
||||
if (needCount > 0)
|
||||
return false;
|
||||
|
||||
foreach (var selledEnt in suitable)
|
||||
{
|
||||
if (selledEnt.Key.Comp.Count == selledEnt.Value)
|
||||
{
|
||||
entities.Remove(selledEnt.Key);
|
||||
entManager.DeleteEntity(selledEnt.Key);
|
||||
}
|
||||
else
|
||||
{
|
||||
stackSystem.Use(selledEnt.Key, selledEnt.Value);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string GetName(IPrototypeManager protoMan)
|
||||
{
|
||||
if (!protoMan.TryIndex(StackId, out var proto))
|
||||
return ":3";
|
||||
|
||||
return $"{Loc.GetString(proto.Name)} x{Count}";
|
||||
}
|
||||
|
||||
public override EntProtoId? GetEntityView(IPrototypeManager protoManager)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override SpriteSpecifier? GetTexture(IPrototypeManager protoManager)
|
||||
{
|
||||
if (!protoManager.TryIndex(StackId, out var proto))
|
||||
return null;
|
||||
|
||||
return proto.Icon;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
using Content.Shared.Stacks;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.Cargo.Prototype.SellServices;
|
||||
|
||||
public sealed partial class CP14SellWhitelistService : CP14StoreSellService
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public EntityWhitelist Whitelist = new();
|
||||
|
||||
[DataField(required: true)]
|
||||
public int Count = 1;
|
||||
|
||||
[DataField(required: true)]
|
||||
public LocId Name = string.Empty;
|
||||
|
||||
[DataField(required: true)]
|
||||
public SpriteSpecifier? Sprite = null;
|
||||
|
||||
public override bool TrySell(EntityManager entManager, HashSet<EntityUid> entities)
|
||||
{
|
||||
var whitelistSystem = entManager.System<EntityWhitelistSystem>();
|
||||
|
||||
HashSet<EntityUid> suitable = new();
|
||||
|
||||
var needCount = Count;
|
||||
foreach (var ent in entities)
|
||||
{
|
||||
if (needCount <= 0)
|
||||
break;
|
||||
|
||||
if (!whitelistSystem.IsValid(Whitelist, ent))
|
||||
continue;
|
||||
|
||||
var count = 1;
|
||||
|
||||
if (entManager.TryGetComponent<StackComponent>(ent, out var stack))
|
||||
count = stack.Count;
|
||||
|
||||
suitable.Add(ent);
|
||||
needCount -= count;
|
||||
}
|
||||
|
||||
if (needCount > 0)
|
||||
return false;
|
||||
|
||||
foreach (var selledEnt in suitable)
|
||||
{
|
||||
entities.Remove(selledEnt);
|
||||
entManager.DeleteEntity(selledEnt);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string GetName(IPrototypeManager protoMan)
|
||||
{
|
||||
return $"{Loc.GetString(Name)} x{Count}";
|
||||
}
|
||||
|
||||
public override EntProtoId? GetEntityView(IPrototypeManager protoManager)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override SpriteSpecifier? GetTexture(IPrototypeManager protoManager)
|
||||
{
|
||||
return Sprite;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace Content.Shared._CP14.Currency;
|
||||
|
||||
/// <summary>
|
||||
/// Reflects the market value of an item, to guide players through the economy.
|
||||
/// </summary>
|
||||
|
||||
[RegisterComponent, Access(typeof(CP14SharedCurrencySystem))]
|
||||
public sealed partial class CP14CurrencyComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public int Currency = 1;
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Currency;
|
||||
|
||||
@@ -22,4 +24,7 @@ public sealed partial class CP14CurrencyConverterComponent : Component
|
||||
|
||||
[DataField]
|
||||
public SoundSpecifier InsertSound = new SoundCollectionSpecifier("CP14Coins");
|
||||
|
||||
[DataField]
|
||||
public ProtoId<TagPrototype> CoinTag = "CP14Coin";
|
||||
}
|
||||
|
||||
@@ -36,19 +36,4 @@ public partial class CP14SharedCurrencySystem : EntitySystem
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public int GetTotalCurrencyRecursive(EntityUid uid)
|
||||
{
|
||||
var ev = new CP14GetCurrencyEvent();
|
||||
RaiseLocalEvent(uid, ev);
|
||||
|
||||
return (int)(ev.Currency * ev.Multiplier);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class CP14GetCurrencyEvent(int currency = 0, int multiplier = 1) : EntityEventArgs
|
||||
{
|
||||
public HashSet<EntityUid> CheckedEntities = new();
|
||||
public int Currency = currency;
|
||||
public float Multiplier = multiplier;
|
||||
}
|
||||
|
||||
@@ -112,6 +112,24 @@ public abstract class SharedCP14MagicEnergySystem : EntitySystem
|
||||
UpdateMagicAlert((ent, ent.Comp));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set energy to 0
|
||||
/// </summary>
|
||||
public void ClearEnergy(Entity<CP14MagicEnergyContainerComponent?> ent)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp, false))
|
||||
return;
|
||||
|
||||
var oldEnergy = ent.Comp.Energy;
|
||||
|
||||
ent.Comp.Energy = 0;
|
||||
|
||||
if (oldEnergy != 0)
|
||||
RaiseLocalEvent(ent, new CP14MagicEnergyLevelChangeEvent(oldEnergy, 0, ent.Comp.MaxEnergy));
|
||||
|
||||
UpdateMagicAlert((ent, ent.Comp));
|
||||
}
|
||||
|
||||
public void TransferEnergy(Entity<CP14MagicEnergyContainerComponent?> sender,
|
||||
Entity<CP14MagicEnergyContainerComponent?> receiver,
|
||||
FixedPoint2 energy,
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
using Content.Shared.Chemistry.Components.SolutionManager;
|
||||
using Content.Shared.Chemistry.EntitySystems;
|
||||
|
||||
namespace Content.Shared._CP14.MagicSpell.Spells;
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the thermal energy of all the solutions inside the container.
|
||||
/// </summary>
|
||||
public sealed partial class CP14AdjustAllSolutionThermalEnergy : CP14SpellEffect
|
||||
{
|
||||
/// <summary>
|
||||
/// The change in energy.
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public float Delta;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum temperature this effect can reach.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float? MinTemp;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum temperature this effect can reach.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float? MaxTemp;
|
||||
|
||||
public override void Effect(EntityManager entManager, CP14SpellEffectBaseArgs args)
|
||||
{
|
||||
var solutionContainer = entManager.System<SharedSolutionContainerSystem>();
|
||||
|
||||
if (!entManager.TryGetComponent<SolutionContainerManagerComponent>(args.Target, out var solutionComp))
|
||||
return;
|
||||
|
||||
var target = new Entity<SolutionContainerManagerComponent?>(args.Target.Value, solutionComp);
|
||||
foreach (var (_, solution) in solutionContainer.EnumerateSolutions(target))
|
||||
{
|
||||
if (solution.Comp.Solution.Volume == 0)
|
||||
continue;
|
||||
|
||||
var maxTemp = MaxTemp ?? float.PositiveInfinity;
|
||||
var minTemp = Math.Max(MinTemp ?? 0, 0);
|
||||
var oldTemp = solution.Comp.Solution.Temperature;
|
||||
|
||||
if (Delta > 0 && oldTemp >= maxTemp)
|
||||
continue;
|
||||
if (Delta < 0 && oldTemp <= minTemp)
|
||||
continue;
|
||||
|
||||
var heatCap = solution.Comp.Solution.GetHeatCapacity(null);
|
||||
var deltaT = Delta / heatCap;
|
||||
|
||||
solutionContainer.SetTemperature(solution, Math.Clamp(oldTemp + deltaT, minTemp, maxTemp));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using Content.Shared.Materials;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Material;
|
||||
|
||||
[RegisterComponent]
|
||||
public sealed partial class CP14MaterialComponent : Component
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public Dictionary<ProtoId<MaterialPrototype>, int> Materials = new();
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using System.Text;
|
||||
using Content.Shared.Examine;
|
||||
using Content.Shared.Stacks;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Material;
|
||||
|
||||
public sealed partial class CP14MaterialSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CP14MaterialComponent, ExaminedEvent>(OnMaterialExamined);
|
||||
}
|
||||
|
||||
private void OnMaterialExamined(Entity<CP14MaterialComponent> ent, ref ExaminedEvent args)
|
||||
{
|
||||
TryComp<StackComponent>(ent, out var stack);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.Append($"{Loc.GetString("cp14-material-examine")}\n");
|
||||
foreach (var material in ent.Comp.Materials)
|
||||
{
|
||||
if (!_proto.TryIndex(material.Key, out var indexedMaterial))
|
||||
continue;
|
||||
|
||||
var count = material.Value;
|
||||
if (stack is not null)
|
||||
count *= stack.Count;
|
||||
|
||||
sb.Append($"[color={indexedMaterial.Color.ToHex()}]{Loc.GetString(indexedMaterial.Name)}[/color] ({count})\n");
|
||||
}
|
||||
args.PushMarkup(sb.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
using Content.Shared._CP14.Trading.Prototypes;
|
||||
using Content.Shared.Stacks;
|
||||
using Content.Shared.Storage.EntitySystems;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.Cargo.Prototype.BuyServices;
|
||||
namespace Content.Shared._CP14.Trading.BuyServices;
|
||||
|
||||
public sealed partial class CP14BuyItemsService : CP14StoreBuyService
|
||||
{
|
||||
@@ -15,14 +16,11 @@ public sealed partial class CP14BuyItemsService : CP14StoreBuyService
|
||||
|
||||
public override void Buy(EntityManager entManager,
|
||||
IPrototypeManager prototype,
|
||||
Entity<CP14TradingPortalComponent> portal)
|
||||
EntityUid platform)
|
||||
{
|
||||
var storageSystem = entManager.System<SharedEntityStorageSystem>();
|
||||
|
||||
for (var i = 0; i < Count; i++)
|
||||
{
|
||||
var spawned = entManager.Spawn(Product);
|
||||
storageSystem.Insert(spawned, portal);
|
||||
entManager.SpawnNextToOrDrop(Product, platform);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,13 +36,11 @@ public sealed partial class CP14BuyItemsService : CP14StoreBuyService
|
||||
return Count > 0 ? $"{indexedProduct.Name} x{count}" : indexedProduct.Name;
|
||||
}
|
||||
|
||||
public override EntProtoId? GetEntityView(IPrototypeManager protoManager)
|
||||
public override string GetDesc(IPrototypeManager protoMan)
|
||||
{
|
||||
return Product;
|
||||
}
|
||||
if (!protoMan.TryIndex(Product, out var indexedProduct))
|
||||
return string.Empty;
|
||||
|
||||
public override SpriteSpecifier? GetTexture(IPrototypeManager protoManager)
|
||||
{
|
||||
return null;
|
||||
return indexedProduct.Description;
|
||||
}
|
||||
}
|
||||
21
Content.Shared/_CP14/Trading/CP14TradingUI.cs
Normal file
21
Content.Shared/_CP14/Trading/CP14TradingUI.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.Trading;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum CP14TradingUiKey
|
||||
{
|
||||
Key,
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14TradingPlatformUiState(NetEntity user, NetEntity platform) : BoundUserInterfaceState
|
||||
{
|
||||
public NetEntity User = user;
|
||||
public NetEntity Platform = platform;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public readonly struct CP14TradingProductEntry
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Content.Shared._CP14.Trading.Prototypes;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Trading.Components;
|
||||
|
||||
/// <summary>
|
||||
/// The server calculates all prices for all product items, saves them in this component at the station,
|
||||
/// and synchronizes the data with the client for the entire round.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class CP14StationEconomyComponent : Component
|
||||
{
|
||||
[DataField, AutoNetworkedField]
|
||||
public Dictionary<ProtoId<CP14TradingPositionPrototype>, int> Pricing = new();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Content.Shared._CP14.Trading.Prototypes;
|
||||
using Content.Shared._CP14.Trading.Systems;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Trading.Components;
|
||||
|
||||
[RegisterComponent, Access(typeof(CP14SharedTradingPlatformSystem))]
|
||||
public sealed partial class CP14TradingContractComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public TimeSpan Delay = TimeSpan.FromSeconds(2);
|
||||
|
||||
[DataField]
|
||||
public ProtoId<CP14TradingFactionPrototype> Faction;
|
||||
|
||||
[DataField]
|
||||
public float StartReputation = 1f;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Content.Shared._CP14.Trading.Systems;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Trading.Components;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(CP14SharedTradingPlatformSystem))]
|
||||
public sealed partial class CP14TradingPlatformComponent : Component
|
||||
{
|
||||
[DataField, AutoNetworkedField]
|
||||
public TimeSpan NextBuyTime = TimeSpan.Zero;
|
||||
|
||||
[DataField]
|
||||
public SoundSpecifier BuySound = new SoundPathSpecifier("/Audio/_CP14/Effects/cash.ogg")
|
||||
{
|
||||
Params = AudioParams.Default.WithVariation(0.1f)
|
||||
};
|
||||
|
||||
[DataField]
|
||||
public ProtoId<TagPrototype> CoinTag = "CP14Coin";
|
||||
|
||||
[DataField]
|
||||
public EntProtoId BuyVisual = "CP14CashImpact";
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using Content.Shared._CP14.Trading.Prototypes;
|
||||
using Content.Shared._CP14.Trading.Systems;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Trading.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Reflects the entity's level of reputation, debts, and balance sheet in the “outside” world.
|
||||
/// Used for personal progression in trading systems
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(CP14SharedTradingPlatformSystem))]
|
||||
public sealed partial class CP14TradingReputationComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// is both a reputation counter for each faction and an indicator of whether that faction is unlocked for that player.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public Dictionary<ProtoId<CP14TradingFactionPrototype>, FixedPoint2> Reputation = new();
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public HashSet<ProtoId<CP14TradingPositionPrototype>> UnlockedPositions = new();
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Trading.Prototypes;
|
||||
|
||||
[Prototype("cp14TradingFaction")]
|
||||
public sealed partial class CP14TradingFactionPrototype : IPrototype
|
||||
{
|
||||
[IdDataField] public string ID { get; private set; } = default!;
|
||||
|
||||
[DataField(required: true)]
|
||||
public LocId Name = default!;
|
||||
|
||||
[DataField]
|
||||
public Color Color = Color.White;
|
||||
|
||||
/// <summary>
|
||||
/// If not null, this faction is automatically unlocked for players, and grants the specified amount of reputation to unlock the first positions.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float? RoundStart = null;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.FixedPoint;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared._CP14.Trading.Prototypes;
|
||||
|
||||
[Prototype("cp14TradingPosition")]
|
||||
public sealed partial class CP14TradingPositionPrototype : IPrototype
|
||||
{
|
||||
[IdDataField] public string ID { get; private set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Service Title. If you leave null, the name will try to generate from first Service.GetName()
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public LocId? Name;
|
||||
|
||||
/// <summary>
|
||||
/// Service Description. If you leave null, the description will try to generate from first Service.GetDescription()
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public LocId? Desc;
|
||||
|
||||
/// <summary>
|
||||
/// Icon for UI. If you leave null, the icon will try to generate from first Service.GetTexture()
|
||||
/// </summary>
|
||||
[DataField(required: true)]
|
||||
public SpriteSpecifier Icon = default!;
|
||||
|
||||
[DataField(required: true)]
|
||||
public ProtoId<CP14TradingFactionPrototype> Faction;
|
||||
|
||||
[DataField]
|
||||
public FixedPoint2 UnlockReputationCost = 1f;
|
||||
|
||||
[DataField(required: true)]
|
||||
public Vector2 UiPosition = default!;
|
||||
|
||||
[DataField(required: true)]
|
||||
public CP14StoreBuyService? Service = null;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<CP14TradingPositionPrototype>? Prerequisite;
|
||||
|
||||
[DataField]
|
||||
public int PriceMarkup = 1;
|
||||
|
||||
/// <summary>
|
||||
/// each round prices will differ within +X percent of the calculated value
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float PriceFluctuation = 0.2f;
|
||||
}
|
||||
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
[MeansImplicitUse]
|
||||
public abstract partial class CP14StoreBuyService
|
||||
{
|
||||
public abstract void Buy(EntityManager entManager, IPrototypeManager prototype, EntityUid platform);
|
||||
|
||||
public abstract string GetName(IPrototypeManager protoMan);
|
||||
|
||||
public abstract string GetDesc(IPrototypeManager protoMan);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Content.Shared._CP14.Trading.Components;
|
||||
using Content.Shared._CP14.Trading.Prototypes;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared._CP14.Trading.Systems;
|
||||
|
||||
public abstract partial class CP14SharedStationEconomySystem : EntitySystem
|
||||
{
|
||||
public int? GetPrice(ProtoId<CP14TradingPositionPrototype> position)
|
||||
{
|
||||
var query = EntityQueryEnumerator<CP14StationEconomyComponent>();
|
||||
|
||||
while (query.MoveNext(out var uid, out var economy))
|
||||
{
|
||||
if (!economy.Pricing.TryGetValue(position, out var price))
|
||||
return null;
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using Content.Shared._CP14.Trading.Components;
|
||||
using Content.Shared._CP14.Trading.Prototypes;
|
||||
using Content.Shared.UserInterface;
|
||||
|
||||
namespace Content.Shared._CP14.Trading.Systems;
|
||||
|
||||
public abstract partial class CP14SharedTradingPlatformSystem
|
||||
{
|
||||
private void InitializeUI()
|
||||
{
|
||||
SubscribeLocalEvent<CP14TradingPlatformComponent, CP14TradingPositionUnlockAttempt>(OnUnlockAttempt);
|
||||
SubscribeLocalEvent<CP14TradingPlatformComponent, BeforeActivatableUIOpenEvent>(OnBeforeUIOpen);
|
||||
}
|
||||
|
||||
private void OnUnlockAttempt(Entity<CP14TradingPlatformComponent> ent, ref CP14TradingPositionUnlockAttempt args)
|
||||
{
|
||||
TryUnlockPosition(args.Actor, args.Position);
|
||||
UpdateUIState(ent, args.Actor);
|
||||
}
|
||||
|
||||
private void OnBeforeUIOpen(Entity<CP14TradingPlatformComponent> ent, ref BeforeActivatableUIOpenEvent args)
|
||||
{
|
||||
UpdateUIState(ent, args.User);
|
||||
}
|
||||
|
||||
public string GetTradeDescription(CP14TradingPositionPrototype position)
|
||||
{
|
||||
if (position.Desc != null)
|
||||
return Loc.GetString(position.Desc);
|
||||
|
||||
if (position.Service is null)
|
||||
return string.Empty;
|
||||
|
||||
return position.Service.GetDesc(Proto);
|
||||
}
|
||||
|
||||
public string GetTradeName(CP14TradingPositionPrototype position)
|
||||
{
|
||||
if (position.Name != null)
|
||||
return Loc.GetString(position.Name);
|
||||
|
||||
if (position.Service is null)
|
||||
return string.Empty;
|
||||
|
||||
return position.Service.GetName(Proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
using Content.Shared._CP14.Trading.Components;
|
||||
using Content.Shared._CP14.Trading.Prototypes;
|
||||
using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Popups;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Shared._CP14.Trading.Systems;
|
||||
|
||||
public abstract partial class CP14SharedTradingPlatformSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedUserInterfaceSystem _userInterface = default!;
|
||||
[Dependency] protected readonly IPrototypeManager Proto = default!;
|
||||
[Dependency] protected readonly IGameTiming Timing = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly INetManager _net = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
InitializeUI();
|
||||
|
||||
SubscribeLocalEvent<CP14TradingReputationComponent, MapInitEvent>(OnReputationMapInit);
|
||||
SubscribeLocalEvent<CP14TradingContractComponent, UseInHandEvent>(OnContractUse);
|
||||
}
|
||||
|
||||
private void OnReputationMapInit(Entity<CP14TradingReputationComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
foreach (var faction in Proto.EnumeratePrototypes<CP14TradingFactionPrototype>())
|
||||
{
|
||||
if (faction.RoundStart is not null)
|
||||
{
|
||||
ent.Comp.Reputation[faction] = ent.Comp.Reputation.GetValueOrDefault(faction, 0f) + faction.RoundStart.Value;
|
||||
}
|
||||
}
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
private void OnContractUse(Entity<CP14TradingContractComponent> ent, ref UseInHandEvent args)
|
||||
{
|
||||
if (!Proto.TryIndex(ent.Comp.Faction, out var indexedFaction))
|
||||
return;
|
||||
|
||||
var repComp = EnsureComp<CP14TradingReputationComponent>(args.User);
|
||||
repComp.Reputation.TryAdd(ent.Comp.Faction, ent.Comp.StartReputation);
|
||||
_popup.PopupPredicted(Loc.GetString("cp14-trading-contract-use", ("name", Loc.GetString(indexedFaction.Name))), args.User, args.User);
|
||||
if (_net.IsServer)
|
||||
QueueDel(ent);
|
||||
}
|
||||
|
||||
protected void UpdateUIState(Entity<CP14TradingPlatformComponent> ent, EntityUid user)
|
||||
{
|
||||
if (!TryComp<CP14TradingReputationComponent>(user, out var repComp))
|
||||
return;
|
||||
|
||||
_userInterface.SetUiState(ent.Owner, CP14TradingUiKey.Key, new CP14TradingPlatformUiState(GetNetEntity(user), GetNetEntity(ent)));
|
||||
}
|
||||
|
||||
public bool TryUnlockPosition(Entity<CP14TradingReputationComponent?> user, ProtoId<CP14TradingPositionPrototype> position)
|
||||
{
|
||||
if (!CanUnlockPosition(user, position))
|
||||
return false;
|
||||
|
||||
if (!Proto.TryIndex(position, out var indexedPosition))
|
||||
return false;
|
||||
|
||||
if (!Resolve(user.Owner, ref user.Comp, false))
|
||||
return false;
|
||||
|
||||
user.Comp.Reputation[indexedPosition.Faction] -= indexedPosition.UnlockReputationCost;
|
||||
user.Comp.UnlockedPositions.Add(position);
|
||||
Dirty(user);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CanUnlockPosition(Entity<CP14TradingReputationComponent?> user, ProtoId<CP14TradingPositionPrototype> position)
|
||||
{
|
||||
if (!Resolve(user.Owner, ref user.Comp, false))
|
||||
return false;
|
||||
|
||||
if (!Proto.TryIndex(position, out var indexedPosition))
|
||||
return false;
|
||||
|
||||
if (!user.Comp.Reputation.ContainsKey(indexedPosition.Faction))
|
||||
return false;
|
||||
|
||||
if (user.Comp.UnlockedPositions.Contains(position))
|
||||
return false;
|
||||
|
||||
if (indexedPosition.Prerequisite is not null && !user.Comp.UnlockedPositions.Contains(indexedPosition.Prerequisite.Value))
|
||||
return false;
|
||||
|
||||
return user.Comp.Reputation.GetValueOrDefault(indexedPosition.Faction, 0f) >= indexedPosition.UnlockReputationCost;
|
||||
}
|
||||
|
||||
public bool CanBuyPosition(Entity<CP14TradingReputationComponent?> user, Entity<CP14TradingPlatformComponent?> platform, ProtoId<CP14TradingPositionPrototype> position)
|
||||
{
|
||||
if (!Resolve(user.Owner, ref user.Comp, false))
|
||||
return false;
|
||||
if (!Resolve(platform.Owner, ref platform.Comp, false))
|
||||
return false;
|
||||
|
||||
if (!user.Comp.UnlockedPositions.Contains(position))
|
||||
return false;
|
||||
|
||||
if (Timing.CurTime < platform.Comp.NextBuyTime)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14TradingPositionUnlockAttempt(ProtoId<CP14TradingPositionPrototype> position) : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly ProtoId<CP14TradingPositionPrototype> Position = position;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CP14TradingPositionBuyAttempt(ProtoId<CP14TradingPositionPrototype> position) : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly ProtoId<CP14TradingPositionPrototype> Position = position;
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
* https://github.com/space-wizards/space-station-14/blob/master/LICENSE.TXT
|
||||
*/
|
||||
|
||||
using Content.Shared._CP14.Material;
|
||||
using Content.Shared._CP14.Workbench.Prototypes;
|
||||
using Content.Shared.Materials;
|
||||
using Content.Shared.Stacks;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -31,12 +29,12 @@ public sealed partial class MaterialResource : CP14WorkbenchCraftRequirement
|
||||
var count = 0;
|
||||
foreach (var ent in placedEntities)
|
||||
{
|
||||
if (!entManager.TryGetComponent<CP14MaterialComponent>(ent, out var material))
|
||||
if (!entManager.TryGetComponent<PhysicalCompositionComponent>(ent, out var material))
|
||||
continue;
|
||||
|
||||
entManager.TryGetComponent<StackComponent>(ent, out var stack);
|
||||
|
||||
foreach (var (key, value) in material.Materials)
|
||||
foreach (var (key, value) in material.MaterialComposition)
|
||||
{
|
||||
if (key != Material)
|
||||
continue;
|
||||
@@ -65,12 +63,12 @@ public sealed partial class MaterialResource : CP14WorkbenchCraftRequirement
|
||||
var requiredCount = Count;
|
||||
foreach (var placedEntity in placedEntities)
|
||||
{
|
||||
if (!entManager.TryGetComponent<CP14MaterialComponent>(placedEntity, out var material))
|
||||
if (!entManager.TryGetComponent<PhysicalCompositionComponent>(placedEntity, out var material))
|
||||
continue;
|
||||
|
||||
entManager.TryGetComponent<StackComponent>(placedEntity, out var stack);
|
||||
|
||||
foreach (var mat in material.Materials)
|
||||
foreach (var mat in material.MaterialComposition)
|
||||
{
|
||||
if (mat.Key != Material)
|
||||
continue;
|
||||
|
||||
@@ -82,3 +82,13 @@
|
||||
license: "CC0-1.0"
|
||||
copyright: 'Created by Fenodyrie on Freesound.org'
|
||||
source: "https://freesound.org/people/Fenodyrie/sounds/583950/"
|
||||
|
||||
- files: ["coin_impact1.ogg", "coin_impact2.ogg", "coin_impact3.ogg", "coin_impact4.ogg"]
|
||||
license: "CC-BY-NC-4.0"
|
||||
copyright: 'Created by Timbre on Freesound.org'
|
||||
source: "https://freesound.org/people/Timbre/sounds/103219/"
|
||||
|
||||
- files: ["cash.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: 'Created by Zott820 on Freesound.org'
|
||||
source: "https://freesound.org/people/Zott820/sounds/209578/"
|
||||
BIN
Resources/Audio/_CP14/Effects/cash.ogg
Normal file
BIN
Resources/Audio/_CP14/Effects/cash.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Effects/coin_impact1.ogg
Normal file
BIN
Resources/Audio/_CP14/Effects/coin_impact1.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Effects/coin_impact2.ogg
Normal file
BIN
Resources/Audio/_CP14/Effects/coin_impact2.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Effects/coin_impact3.ogg
Normal file
BIN
Resources/Audio/_CP14/Effects/coin_impact3.ogg
Normal file
Binary file not shown.
@@ -8,6 +8,21 @@
|
||||
copyright: "Taken from https://freesound.org/"
|
||||
source: "https://freesound.org/people/spookymodem/sounds/202100/"
|
||||
|
||||
- files: ["goblin_talk1.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Taken from https://freesound.org/"
|
||||
source: "https://freesound.org/people/spookymodem/sounds/249813/"
|
||||
|
||||
- files: ["goblin_talk2.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Created by 999999990 from https://freesound.org/"
|
||||
source: "https://freesound.org/people/999999990/sounds/320345/"
|
||||
|
||||
- files: ["goblin_talk3.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Taken from https://freesound.org/"
|
||||
source: "https://freesound.org/people/spookymodem/sounds/249813/"
|
||||
|
||||
- files: ["goblin_sleep.ogg"]
|
||||
license: "CC0-1.0"
|
||||
copyright: "Taken from https://freesound.org/"
|
||||
|
||||
BIN
Resources/Audio/_CP14/Voice/Goblin/goblin_talk1.ogg
Normal file
BIN
Resources/Audio/_CP14/Voice/Goblin/goblin_talk1.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Voice/Goblin/goblin_talk2.ogg
Normal file
BIN
Resources/Audio/_CP14/Voice/Goblin/goblin_talk2.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/_CP14/Voice/Goblin/goblin_talk3.ogg
Normal file
BIN
Resources/Audio/_CP14/Voice/Goblin/goblin_talk3.ogg
Normal file
Binary file not shown.
@@ -15,9 +15,7 @@ tickrate = 30
|
||||
port = 1212
|
||||
bindto = "::,0.0.0.0"
|
||||
max_connections = 100
|
||||
|
||||
[status]
|
||||
max_connections = 10
|
||||
log_late_msg = false
|
||||
|
||||
[game]
|
||||
hostname = "⚔️ CrystallEdge ⚔️"
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
cp14-buy-position-reroll-buy = Reroll purchase offers
|
||||
cp14-buy-position-reroll-sell = Reroll sales offers
|
||||
@@ -1,4 +0,0 @@
|
||||
cp14-tracker-header = Round statistic:
|
||||
|
||||
cp14-tracker-demiplane-open = Demiplanes opened
|
||||
cp14-tracker-demiplane-deaths = Players died in demiplanes
|
||||
@@ -1,11 +0,0 @@
|
||||
cp14-faction-name-helmir = Helmir's descendants
|
||||
cp14-faction-desc-helmir = TODO
|
||||
|
||||
cp14-faction-name-sylphoria = The winds of Sylphoria
|
||||
cp14-faction-desc-sylphoria = TODO
|
||||
|
||||
cp14-faction-name-spice-stream = Spice Stream
|
||||
cp14-faction-desc-spice-stream = TODO
|
||||
|
||||
cp14-faction-name-brad-family = Brad's imperial family
|
||||
cp14-faction-desc-brad-family = TODO
|
||||
@@ -1,40 +0,0 @@
|
||||
cp14-store-buy-hint = To purchase "{$name}", leave your money and order in the trade box: Any paper that says {$code} on it will do.
|
||||
|
||||
cp14-store-buy-alchemy-unlock-t1-name = Trade Alliance: Alchemists
|
||||
cp14-store-buy-alchemy-unlock-t1-desc = The Alchemists Guild of the Kingdom of Klanir is willing to include the settlement in their trade route in return for small gifts and payment.
|
||||
|
||||
cp14-store-buy-alchemy-vials-name = Alchemical vials
|
||||
cp14-store-buy-alchemy-vials-desc = Now the shortage of potion vessels is no longer a problem! After all, for a rather modest price, you can order batches of shiny vials directly from the best artisans! Random alchemical devices as a gift.
|
||||
|
||||
cp14-store-buy-alchemy-bureaucracy-name = Bureaucratic reserve
|
||||
cp14-store-buy-alchemy-bureaucracy-desc = Pens, ink pots and a big stack of paper. In folders of different colors, or without folders at all: because we make sure that you can choose the option that is most comfortable for you.
|
||||
|
||||
cp14-store-buy-alchemy-farm-seeds-name = Seeds for farming
|
||||
cp14-store-buy-alchemy-farm-seeds-desc = A set of different seeds, for farming of all kinds! Don't limit yourself, buy several boxes at once, just in case the farmers eat everything and don't have any food left to process into seeds.
|
||||
|
||||
cp14-store-buy-alchemy-demiplan-name = 5 demiplane Keys
|
||||
cp14-store-buy-alchemy-demiplan-desc = Unstable pocket dimensions in which doom or riches may await you. What could be better for your adventurers?
|
||||
|
||||
cp14-store-buy-wood-name = Wood stockpile
|
||||
cp14-store-buy-wood-desc = Fresh wood with delivery to your settlement! Do you live in a region where trees do not grow? Or you simply do not have the working hands to go and cut them yourself? We are ready to do it for you! Or rather, for your money.
|
||||
|
||||
cp14-store-buy-fabric-name = Stock of textiles
|
||||
cp14-store-buy-fabric-desc = A large supply of fabric and thread, to make exquisite outfits or other tools. Only today, only now, only for the last six months.
|
||||
|
||||
cp14-store-buy-energy-name = Energy reserve
|
||||
cp14-store-buy-energy-desc = Energy crystals in both medium and small sizes, and in addition, mana manipulation gauntlets. A complete set to power your energy devices.
|
||||
|
||||
cp14-store-buy-cheese-name = Cheese stockpile
|
||||
cp14-store-buy-cheese-desc = Cows don't like to sail on ships, but their cheese is quite fond of traveling! So pay its way to your table!
|
||||
|
||||
cp14-store-buy-copper-name = 10 copper bars
|
||||
cp14-store-buy-copper-desc = Looking for quality copper ingots? Our copper ingots are suitable for all needs, whether it is blacksmithing or coinage. Order right now, before they are sold out by craftsmen from all over the empire.
|
||||
|
||||
cp14-store-buy-iron-name = 10 iron bars
|
||||
cp14-store-buy-iron-desc = Durable, reliable and versatile metal for the most daring projects! Do you need armor, weapons, or fasteners? The highest grade iron ingots are at your service. This is the foundation of your success!
|
||||
|
||||
cp14-store-buy-gold-name = 10 gold bars
|
||||
cp14-store-buy-gold-desc = For those who appreciate luxury and elegance. Bars of the purest gold for jewelry, inlay or investment in the future. Gold is always in the price, and our delivery is always on time!
|
||||
|
||||
cp14-store-buy-guidebook-name = Educational books
|
||||
cp14-store-buy-guidebook-desc = Have you run out of specialists in key areas? No problem, with this set of training literature you can make even an infant a professional, and put him to work for the good of the Empire! (OOC: There are only books for the blacksmith so far.)
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
# Buy
|
||||
|
||||
|
||||
cp14-store-service-unlock-sell = Unlocks the ability to sell:
|
||||
cp14-store-service-unlock-buy = Unlocks the ability to buy:
|
||||
|
||||
# Sell
|
||||
|
||||
cp14-store-service-sell-entities = Sale items:
|
||||
@@ -1,11 +0,0 @@
|
||||
cp14-store-ui-title = Trading outpost "{$name}"
|
||||
cp14-store-ui-order = More info
|
||||
|
||||
cp14-store-ui-next-travel-out = Before departure:
|
||||
cp14-store-ui-next-travel-in = Before arrival:
|
||||
|
||||
cp14-store-ui-tab-buy = Buying
|
||||
cp14-store-ui-tab-sell = Selling
|
||||
cp14-store-ui-tab-special = [bold][color=#eba346]One-off offer![/color][/bold]
|
||||
|
||||
cp14-store-sell-hint = To sell {$name}, put the item you want in the trade cabinet, and close it. Our people will figure out what's what, pick up the item, and send you the money through the same sales cabinet.
|
||||
3
Resources/Locale/en-US/_CP14/trading/factions.ftl
Normal file
3
Resources/Locale/en-US/_CP14/trading/factions.ftl
Normal file
@@ -0,0 +1,3 @@
|
||||
cp14-trade-faction-contracts = Zellasian Trade Guild
|
||||
cp14-trade-faction-victoria-gardens = Victoria Gardens
|
||||
cp14-trade-faction-brad-potions = Brad's marvelous potions
|
||||
14
Resources/Locale/en-US/_CP14/trading/ui.ftl
Normal file
14
Resources/Locale/en-US/_CP14/trading/ui.ftl
Normal file
@@ -0,0 +1,14 @@
|
||||
cp14-trading-ui-button-unlock = Unlock contract
|
||||
cp14-trading-ui-button-unlock-tooltip = You contract to purchase the specified equipment or service by spending your reputation. After that, you can buy that equipment or service with money in unlimited quantities.
|
||||
|
||||
cp14-trading-ui-button-buy = Buy
|
||||
cp14-trading-ui-button-buy-tooltip = You spend the funds on the trading platform and buy the specified equipment or service from the selected vendor, which also increases your reputation. The equipment will be instantly delivered to you by spatial magic, and the service will be rendered as soon as possible.
|
||||
|
||||
|
||||
cp14-trading-ui-title = Empire Trade link Platform
|
||||
cp14-trading-ui-cooldown = Cooldown:
|
||||
cp14-trading-faction-prefix = Trading with:
|
||||
|
||||
cp14-trading-failure-popup-money = Not enough funds on the platform!
|
||||
|
||||
cp14-trading-contract-use = Trade with "{$name}" unlocked!
|
||||
@@ -1,2 +0,0 @@
|
||||
cp14-buy-position-reroll-buy = Реролл предложений покупки
|
||||
cp14-buy-position-reroll-sell = Реролл предложений продажи
|
||||
@@ -1,4 +0,0 @@
|
||||
cp14-tracker-header = Статистика раунда:
|
||||
|
||||
cp14-tracker-demiplane-open = Открыто демипланов
|
||||
cp14-tracker-demiplane-deaths = Умерло игроков в демипланах
|
||||
@@ -1,11 +0,0 @@
|
||||
cp14-faction-name-helmir = Хельмировы потомки
|
||||
cp14-faction-desc-helmir = TODO
|
||||
|
||||
cp14-faction-name-sylphoria = Ветра Сильфории
|
||||
cp14-faction-desc-sylphoria = TODO
|
||||
|
||||
cp14-faction-name-spice-stream = Поток пряностей
|
||||
cp14-faction-desc-spice-stream = TODO
|
||||
|
||||
cp14-faction-name-brad-family = Имперская семья Брада
|
||||
cp14-faction-desc-brad-family = TODO
|
||||
@@ -1,40 +0,0 @@
|
||||
cp14-store-buy-hint = Чтобы приобрести "{$name}", оставьте деньги и ваш заказ в торговом ящике: Подойдет любая бумага, на которой будет написано {$code}
|
||||
|
||||
cp14-store-buy-alchemy-unlock-t1-name = Торговый союз: Алхимики
|
||||
cp14-store-buy-alchemy-unlock-t1-desc = Гильдия алхимиков королевства Кланира готова включить поселение в свой торговый путь взамен на небольшие дары и оплату.
|
||||
|
||||
cp14-store-buy-alchemy-vials-name = Алхимические пузырьки
|
||||
cp14-store-buy-alchemy-vials-desc = Теперь проблема дефицита емкостей для зелий больше не проблема! Ведь по довольно скромной цене вы можете заказывать партии блестящих склянок прямо от лучших ремесленников! Случайные алхимические приборы в подарок.
|
||||
|
||||
cp14-store-buy-alchemy-bureaucracy-name = Бюрократический запас
|
||||
cp14-store-buy-alchemy-bureaucracy-desc = Ручки, чернильницы и большая пачка бумаги. В папках разных цветов, и вовсе без папок: ведь мы заботимся о том, чтобы вы могли выбирать тот вариант, который вам комфортнее.
|
||||
|
||||
cp14-store-buy-alchemy-farm-seeds-name = Семена для фермерства
|
||||
cp14-store-buy-alchemy-farm-seeds-desc = Набор разных семян, для фермерства всех видов! Не ограничивайте себя, купите сразу несколько ящиков, на случай, если фермеры все съедят и не оставят еды на переработку в семена.
|
||||
|
||||
cp14-store-buy-alchemy-demiplan-name = 5 ключей демиплана
|
||||
cp14-store-buy-alchemy-demiplan-desc = Нестабильные карманные измерения, в котором вас может поджидать гибель или богатства. Что может быть лучше для ваших авантюристов?
|
||||
|
||||
cp14-store-buy-wood-name = Запас древесины
|
||||
cp14-store-buy-wood-desc = Свежая древесина с доставкой до вашего поселения! Вы живете в краю где не растут деревья? Или у вас просто нет рабочих рук, чтобы пойти и нарубить их самостоятельно? Мы готовы сделать это за вас! Точнее, за ваши деньги.
|
||||
|
||||
cp14-store-buy-fabric-name = Запас текстиля
|
||||
cp14-store-buy-fabric-desc = Большой запас ткани и ниток, для производства изысканнейших нарядов или другого инструментария. Только сегодня, только сейчас, только последние полгода.
|
||||
|
||||
cp14-store-buy-energy-name = Энергетический запас
|
||||
cp14-store-buy-energy-desc = Энергетические кристаллы и средних, и малых размеров, и в добавок - перчатки манипулирования маной. Полный комплект, чтобы обеспечивать ваши энергоприборы энергией.
|
||||
|
||||
cp14-store-buy-cheese-name = Запас сыра
|
||||
cp14-store-buy-cheese-desc = Коровки не любят плавать на кораблях, а вот их сыр вполне любит путешествия! Так оплатите же ему дорогу к вашему столу!
|
||||
|
||||
cp14-store-buy-copper-name = 10 слитков меди
|
||||
cp14-store-buy-copper-desc = Ищете качественные медные слитки? Наши медные слитки подходят для всех нужд, будь то кузнечное дело или чеканка монет. Заказывайте прямо сейчас, пока их не раскупили мастера со всех уголков империи!
|
||||
|
||||
cp14-store-buy-iron-name = 10 слитков железа
|
||||
cp14-store-buy-iron-desc = Прочный, надежный и универсальный металл для самых смелых проектов! Нужна броня, оружие или элементы креплений? Железные слитки в высшей пробе к вашим услугам. Это основа вашего успеха!
|
||||
|
||||
cp14-store-buy-gold-name = 10 слитков золота
|
||||
cp14-store-buy-gold-desc = Для тех, кто ценит роскошь и изящество. Слитки чистейшего золота для украшений, инкрустации или инвестиций в будущее. Золото всегда в цене, а наша доставка — всегда в срок!
|
||||
|
||||
cp14-store-buy-guidebook-name = Обучающие книги
|
||||
cp14-store-buy-guidebook-desc = У вас закончились специалисты в ключевых областях? Не проблема, с этим набором учебной литературы вы сможете сделать профессионалом даже младенца, и заставить его работать на благо Империи! (ООС: Тут пока что только книги для кузнеца)
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
# Buy
|
||||
|
||||
cp14-store-service-unlock-sell = Разблокирует возможность продажи:
|
||||
cp14-store-service-unlock-buy = Разблокирует возможность покупки:
|
||||
|
||||
# Sell
|
||||
|
||||
cp14-store-service-sell-entities = Продажа предметов:
|
||||
@@ -1,11 +0,0 @@
|
||||
cp14-store-ui-title = Торговый аванпост "{$name}"
|
||||
cp14-store-ui-order = Дополнительная информация
|
||||
|
||||
cp14-store-ui-next-travel-out = До отправления:
|
||||
cp14-store-ui-next-travel-in = До прибытия:
|
||||
|
||||
cp14-store-ui-tab-buy = Покупка
|
||||
cp14-store-ui-tab-sell = Продажа
|
||||
cp14-store-ui-tab-special = [bold][color=#eba346]Разовое предложение![/color][/bold]
|
||||
|
||||
cp14-store-sell-hint = Чтобы продать {$name}, засуньте необходимый товар в торговый шкаф, и закройте его. Наши люди разберутся что к чему, заберут товар и отправят вам деньги через этот же торговый шкаф.
|
||||
3
Resources/Locale/ru-RU/_CP14/trading/factions.ftl
Normal file
3
Resources/Locale/ru-RU/_CP14/trading/factions.ftl
Normal file
@@ -0,0 +1,3 @@
|
||||
cp14-trade-faction-contracts = Торговая гильдия Зелласиан
|
||||
cp14-trade-faction-victoria-gardens = Сады Виктории
|
||||
cp14-trade-faction-brad-potions = Великолепные зелья Брада
|
||||
14
Resources/Locale/ru-RU/_CP14/trading/ui.ftl
Normal file
14
Resources/Locale/ru-RU/_CP14/trading/ui.ftl
Normal file
@@ -0,0 +1,14 @@
|
||||
cp14-trading-ui-button-unlock = Разблокировать контракт
|
||||
cp14-trading-ui-button-unlock-tooltip = Вы заключаете контракт, затрачивая на это свою репутацию. После этого, вы можете покупать это снаряжение или услугу за деньги в неограниченном количестве.
|
||||
|
||||
cp14-trading-ui-button-buy = Купить
|
||||
cp14-trading-ui-button-buy-tooltip = Вы тратите средства, расположенные на торговой платформе и закупаете указанное снаряжение или услугу у выбранного продавца, что так же увеличивает вашу репутацию. Снаряжение будет мгновенно доставлено вам путем пространственной магии, а услуга оказана в ближайшее время.
|
||||
|
||||
|
||||
cp14-trading-ui-title = Платформа торговой связи с империей
|
||||
cp14-trading-ui-cooldown = Перезарядка:
|
||||
cp14-trading-faction-prefix = Торговля с:
|
||||
|
||||
cp14-trading-failure-popup-money = Недостаточно средств на платформе!
|
||||
|
||||
cp14-trading-contract-use = Торговля с "{$name}" разблокирована!
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,7 @@
|
||||
amount: 1.5
|
||||
- !type:PlantAdjustHealth
|
||||
amount: 0.75
|
||||
pricePerUnit: 2
|
||||
pricePerUnit: 0.2
|
||||
|
||||
- type: reagent
|
||||
id: Vitamin #Anything "healthy"
|
||||
@@ -53,7 +53,7 @@
|
||||
amount: 0.5
|
||||
- !type:PlantAdjustHealth
|
||||
amount: 1.5
|
||||
pricePerUnit: 2.5
|
||||
pricePerUnit: 0.25
|
||||
|
||||
- type: reagent
|
||||
id: Protein #Meat and beans
|
||||
@@ -78,7 +78,7 @@
|
||||
- !type:OrganType
|
||||
type: CP14Vampire
|
||||
shouldHave: false
|
||||
pricePerUnit: 3
|
||||
pricePerUnit: 0.3
|
||||
|
||||
- type: reagent
|
||||
id: Sugar #Candy and grains
|
||||
|
||||
@@ -1,275 +0,0 @@
|
||||
- type: storePositionBuy
|
||||
id: AlchemyVials
|
||||
code: VIALS
|
||||
price: 40
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Specific/Alchemy/vial_medium.rsi
|
||||
state: vial
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledAlchemy
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledAlchemy
|
||||
name: alchemical vials chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14VialTiny
|
||||
amount: 5
|
||||
- id: CP14VialSmall
|
||||
amount: 5
|
||||
- id: CP14VialMedium
|
||||
amount: 5
|
||||
- id: CP14GlassShard #Lol. Something broken
|
||||
prob: 0.2
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14VialSmallHealingBrute
|
||||
code: HEAL_BRUTE
|
||||
price: 50
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Specific/Alchemy/vial_small.rsi
|
||||
state: vial
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledSmallHealingBrute
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledSmallHealingBrute
|
||||
name: healing potions chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14VialSmallHealingBrute
|
||||
amount: 5
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14VialSmallHealingPoison
|
||||
code: HEAL_POISON
|
||||
price: 50
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Specific/Alchemy/vial_small.rsi
|
||||
state: vial
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledSmallHealingPoison
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledSmallHealingPoison
|
||||
name: antidote potions chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14VialSmallHealingPoison
|
||||
amount: 5
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14VialSmallHealingAirloss
|
||||
code: HEAL_AIRLOSS
|
||||
price: 50
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Specific/Alchemy/vial_small.rsi
|
||||
state: vial
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledSmallHealingAirloss
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledSmallHealingAirloss
|
||||
name: airloss healing potions chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14VialSmallHealingAirloss
|
||||
amount: 5
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14VialSmallHealingBlood
|
||||
code: HEAL_BLOOD
|
||||
price: 50
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Specific/Alchemy/vial_small.rsi
|
||||
state: vial
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledSmallHealingBlood
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledSmallHealingBlood
|
||||
name: blood restoration potions chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14VialSmallHealingBlood
|
||||
amount: 5
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14VialSmallHealingMana
|
||||
code: HEAL_MANA
|
||||
price: 70
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Specific/Alchemy/vial_small.rsi
|
||||
state: vial
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledSmallHealingMana
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledSmallHealingMana
|
||||
name: mana potions chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14VialSmallHealingMana
|
||||
amount: 5
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14VialSmallHealingManaDepletion
|
||||
code: HEAL_MANA_DEPLETION
|
||||
price: 70
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Specific/Alchemy/vial_small.rsi
|
||||
state: vial
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledSmallHealingManaDepletion
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledSmallHealingManaDepletion
|
||||
name: mana-depletion potions chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14VialSmallHealingManaDepletion
|
||||
amount: 5
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14VialSmallSpeedUp
|
||||
code: SPEED_UP
|
||||
price: 70
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Specific/Alchemy/vial_small.rsi
|
||||
state: vial
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledSmallSpeedUp
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledSmallSpeedUp
|
||||
name: accseleration potions chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14VialSmallSpeedUp
|
||||
amount: 5
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14VialSmallRainbow
|
||||
code: FUNNY_POTION
|
||||
price: 100
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Specific/Alchemy/vial_small.rsi
|
||||
state: vial
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledSmallRainbow
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledSmallRainbow
|
||||
name: funny potions chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14VialSmallRainbow
|
||||
amount: 5
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: Candles
|
||||
code: CANDLES
|
||||
price: 100
|
||||
iconOverride:
|
||||
sprite: Objects/Misc/candles.rsi
|
||||
state: loadout
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledCandles
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledCandles
|
||||
name: candles chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14CandleRed
|
||||
amount: 2
|
||||
- id: CP14CandleBlue
|
||||
amount: 2
|
||||
- id: CP14CandleBlack
|
||||
amount: 2
|
||||
- id: CP14CandleGreen
|
||||
amount: 2
|
||||
- id: CP14CandlePurple
|
||||
amount: 2
|
||||
- id: CP14CandleRedSmall
|
||||
amount: 2
|
||||
- id: CP14CandleBlueSmall
|
||||
amount: 2
|
||||
- id: CP14CandleBlackSmall
|
||||
amount: 2
|
||||
- id: CP14CandleGreenSmall
|
||||
amount: 2
|
||||
- id: CP14CandlePurpleSmall
|
||||
amount: 2
|
||||
|
||||
- type: storePositionBuy
|
||||
id: SmokePowder
|
||||
code: TOBACCO
|
||||
price: 80
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Misc/reagent_fillings.rsi
|
||||
state: tobacco_small
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledSmokePowder
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledSmokePowder
|
||||
name: smoking powder chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14GroundTobacco
|
||||
amount: 10
|
||||
- id: CP14GroundSage
|
||||
amount: 5
|
||||
@@ -1,14 +0,0 @@
|
||||
- type: storePositionSell
|
||||
id: CP14AlchemicalHerbals
|
||||
price: 50
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14SellWhitelistService
|
||||
whitelist:
|
||||
tags:
|
||||
- CP14AlchemicalHerbals
|
||||
count: 10
|
||||
name: cp14-entity-group-alchemical-herbals
|
||||
sprite:
|
||||
sprite: _CP14/Objects/Flora/Wild/store_position.rsi
|
||||
state: sell
|
||||
@@ -1,89 +0,0 @@
|
||||
- type: storePositionSell
|
||||
id: CP14BloodFlower
|
||||
special: true
|
||||
price: 200
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14SellPrototypeService
|
||||
proto: CP14BloodFlower
|
||||
count: 20
|
||||
|
||||
- type: storePositionSell
|
||||
id: CP14AgaricMushroom
|
||||
special: true
|
||||
price: 200
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14SellPrototypeService
|
||||
proto: CP14AgaricMushroom
|
||||
count: 20
|
||||
|
||||
- type: storePositionSell
|
||||
id: CP14ChromiumSlime
|
||||
special: true
|
||||
price: 600
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14SellPrototypeService
|
||||
proto: CP14ChromiumSlime
|
||||
count: 20
|
||||
|
||||
- type: storePositionSell
|
||||
id: CP14WildSage
|
||||
special: true
|
||||
price: 200
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14SellPrototypeService
|
||||
proto: CP14WildSage
|
||||
count: 20
|
||||
|
||||
- type: storePositionSell
|
||||
id: CP14LumiMushroom
|
||||
special: true
|
||||
price: 400
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14SellPrototypeService
|
||||
proto: CP14LumiMushroom
|
||||
count: 20
|
||||
|
||||
- type: storePositionSell
|
||||
id: CP14BlueAmanita
|
||||
special: true
|
||||
price: 200
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14SellPrototypeService
|
||||
proto: CP14BlueAmanita
|
||||
count: 20
|
||||
|
||||
- type: storePositionSell
|
||||
id: CP14Dayflin
|
||||
special: true
|
||||
price: 200
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14SellPrototypeService
|
||||
proto: CP14Dayflin
|
||||
count: 20
|
||||
|
||||
- type: storePositionSell
|
||||
id: CP14AirLily
|
||||
special: true
|
||||
price: 300
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14SellPrototypeService
|
||||
proto: CP14AirLily
|
||||
count: 20
|
||||
|
||||
- type: storePositionSell
|
||||
id: CP14BaseAlchemyBomb
|
||||
special: true
|
||||
price: 250
|
||||
factions:
|
||||
- BradFamily
|
||||
service: !type:CP14SellPrototypeService
|
||||
proto: CP14BaseAlchemyBomb
|
||||
count: 3
|
||||
@@ -1,21 +0,0 @@
|
||||
- type: storePositionBuy
|
||||
id: RerollSell
|
||||
code: REROLL_SELL
|
||||
price: 20
|
||||
nameOverride: cp14-buy-position-reroll-sell
|
||||
iconOverride:
|
||||
sprite: _CP14/Interface/Misc/reroll.rsi
|
||||
state: reroll
|
||||
service: !type:CP14RerollSpecialPositionsService
|
||||
rerollSell: 5
|
||||
|
||||
#- type: storePositionBuy #Неактуально, т.к. позиций таких нет
|
||||
# id: RerollBuy
|
||||
# code: REROLL_BUY
|
||||
# price: 20
|
||||
# nameOverride: cp14-buy-position-reroll-buy
|
||||
# iconOverride:
|
||||
# sprite: _CP14/Interface/Misc/reroll.rsi
|
||||
# state: reroll
|
||||
# service: !type:CP14RerollSpecialPositionsService
|
||||
# rerollBuy: 5
|
||||
@@ -1,99 +0,0 @@
|
||||
- type: storePositionBuy
|
||||
id: CP14ModularIronArrow
|
||||
code: ARROW
|
||||
price: 100
|
||||
factions:
|
||||
- HelmirWeapon
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14ModularIronArrow
|
||||
count: 6
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14ModularIronAxe
|
||||
code: AXE
|
||||
price: 150
|
||||
factions:
|
||||
- HelmirWeapon
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14ModularIronAxe
|
||||
count: 3
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14ModularIronDagger
|
||||
code: DAGGER
|
||||
price: 150
|
||||
factions:
|
||||
- HelmirWeapon
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14ModularIronDagger
|
||||
count: 7
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14ModularIronHammer
|
||||
code: HAMMER
|
||||
price: 150
|
||||
factions:
|
||||
- HelmirWeapon
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14ModularIronHammer
|
||||
count: 5
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14ModularIronMace
|
||||
code: MACE
|
||||
price: 150
|
||||
factions:
|
||||
- HelmirWeapon
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14ModularIronMace
|
||||
count: 5
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14ModularIronPickaxe
|
||||
code: PICKAXE
|
||||
price: 150
|
||||
factions:
|
||||
- HelmirWeapon
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14ModularIronPickaxe
|
||||
count: 5
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14ModularIronShovel
|
||||
code: SHOVEL
|
||||
price: 150
|
||||
factions:
|
||||
- HelmirWeapon
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14ModularIronShovel
|
||||
count: 5
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14ModularIronSickle
|
||||
code: SICKLE
|
||||
price: 150
|
||||
factions:
|
||||
- HelmirWeapon
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14ModularIronSickle
|
||||
count: 7
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14ModularIronSpear
|
||||
code: SPEAR
|
||||
price: 150
|
||||
factions:
|
||||
- HelmirWeapon
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14ModularIronSpear
|
||||
count: 5
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14ModularIronSword
|
||||
code: SWORD
|
||||
price: 150
|
||||
factions:
|
||||
- HelmirWeapon
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14ModularIronSword
|
||||
count: 5
|
||||
@@ -1,169 +0,0 @@
|
||||
- type: storePositionBuy
|
||||
id: FarmSeeds
|
||||
code: SEEDS
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Specific/Farming/seeds.rsi
|
||||
state: seeds
|
||||
price: 70
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledFarmSeeds
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledFarmSeeds
|
||||
name: farm seeds chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14SeedWheat
|
||||
amount: 3
|
||||
- id: CP14SeedPumpkin
|
||||
amount: 3
|
||||
- id: CP14SeedCabbage
|
||||
amount: 3
|
||||
- id: CP14SeedCucumber
|
||||
amount: 3
|
||||
- id: CP14SeedTomato
|
||||
amount: 3
|
||||
- id: CP14SeedPepper
|
||||
amount: 3
|
||||
- id: CP14SeedCotton
|
||||
amount: 3
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: Cheese
|
||||
code: CHEESE
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Consumable/Food/cheese.rsi
|
||||
state: cheese_wheel
|
||||
price: 100
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledCheese
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledCheese
|
||||
name: cheese chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14FoodCheeseWheel
|
||||
amount: 5
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: Wood
|
||||
code: WOOD
|
||||
price: 50
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenPlanks10
|
||||
count: 5
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: Fabric
|
||||
code: FABRIC
|
||||
price: 30
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14Cloth10
|
||||
count: 3
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CP14String
|
||||
code: STRINGS
|
||||
price: 30
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14String
|
||||
count: 5
|
||||
|
||||
- type: storePositionBuy
|
||||
id: CopperBar
|
||||
code: COPPER
|
||||
price: 250
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14CopperBar10
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: IronBar
|
||||
code: IRON
|
||||
price: 500
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14IronBar10
|
||||
|
||||
|
||||
- type: storePositionBuy
|
||||
id: GoldBar
|
||||
code: GOLD
|
||||
price: 2000
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14GoldBar10
|
||||
|
||||
- type: storePositionBuy
|
||||
id: Bureaucracy
|
||||
code: PAPER
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Bureaucracy/paper.rsi
|
||||
state: folder_red
|
||||
price: 100
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledBureaucracy
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledBureaucracy
|
||||
name: bureaucracy chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14PaperFolderBlue
|
||||
amount: 5
|
||||
- id: CP14PaperFolderRed
|
||||
amount: 5
|
||||
- id: CP14Paper
|
||||
amount: 5
|
||||
- id: CP14PenFeather
|
||||
amount: 3
|
||||
|
||||
- type: storePositionBuy
|
||||
id: EnergyCrystals
|
||||
code: ENERGY
|
||||
iconOverride:
|
||||
sprite: _CP14/Objects/Specific/Thaumaturgy/powerline_gauntlet.rsi
|
||||
state: icon
|
||||
price: 150
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14BuyItemsService
|
||||
product: CP14WoodenChestFilledEnergyCrystals
|
||||
|
||||
- type: entity
|
||||
parent: CP14WoodenChest
|
||||
id: CP14WoodenChestFilledEnergyCrystals
|
||||
name: energy crystals chest
|
||||
components:
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- id: CP14EnergyCrystalMediumEmpty
|
||||
amount: 5
|
||||
- id: CP14ManaOperationGlove
|
||||
amount: 2
|
||||
@@ -1,45 +0,0 @@
|
||||
# ANCHORABLE PROBLEMS
|
||||
|
||||
#- type: storePositionBuy
|
||||
# id: DwarfBeer
|
||||
# code: BEER_DWARF
|
||||
# special: true
|
||||
# nameOverride: cp14-reagent-name-dwarfbeer
|
||||
# price: 150
|
||||
# factions:
|
||||
# - SpiceStream
|
||||
# service: !type:CP14BuyItemsService
|
||||
# product: CP14CraneBarrelDwarfBeer
|
||||
#
|
||||
#- type: storePositionBuy
|
||||
# id: BeerGerbil
|
||||
# code: BEER_BREEZE
|
||||
# special: true
|
||||
# nameOverride: cp14-reagent-name-breeze
|
||||
# price: 70
|
||||
# factions:
|
||||
# - SpiceStream
|
||||
# service: !type:CP14BuyItemsService
|
||||
# product: CP14CraneBarrelSmallBeerBreeze
|
||||
#
|
||||
#- type: storePositionBuy
|
||||
# id: AleBottomless
|
||||
# code: BEER_BOTTOMLESS
|
||||
# special: true
|
||||
# nameOverride: cp14-reagent-name-bottomless
|
||||
# price: 70
|
||||
# factions:
|
||||
# - SpiceStream
|
||||
# service: !type:CP14BuyItemsService
|
||||
# product: CP14CraneBarrelSmallAleBottomless
|
||||
#
|
||||
#- type: storePositionBuy
|
||||
# id: WineZellasian
|
||||
# code: WINE_ZELLASIAN
|
||||
# special: true
|
||||
# nameOverride: cp14-reagent-name-zellasian-pleasure
|
||||
# price: 150
|
||||
# factions:
|
||||
# - SpiceStream
|
||||
# service: !type:CP14BuyItemsService
|
||||
# product: CP14CraneBarrelWineZellasianPleasure
|
||||
@@ -1,94 +0,0 @@
|
||||
- type: storePositionSell
|
||||
id: CopperBars
|
||||
price: 150
|
||||
factions:
|
||||
- SpiceStream
|
||||
- HelmirWeapon
|
||||
service: !type:CP14SellStackService
|
||||
stackId: CP14CopperBar
|
||||
count: 10
|
||||
|
||||
- type: storePositionSell
|
||||
id: CopperOre
|
||||
price: 20
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14SellStackService
|
||||
stackId: CP14OreCopper
|
||||
count: 10
|
||||
|
||||
- type: storePositionSell
|
||||
id: IronBars
|
||||
price: 300
|
||||
factions:
|
||||
- SpiceStream
|
||||
- HelmirWeapon
|
||||
service: !type:CP14SellStackService
|
||||
stackId: CP14IronBar
|
||||
count: 10
|
||||
|
||||
- type: storePositionSell
|
||||
id: IronOre
|
||||
price: 30
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14SellStackService
|
||||
stackId: CP14OreIron
|
||||
count: 10
|
||||
|
||||
- type: storePositionSell
|
||||
id: GoldBars
|
||||
price: 1200
|
||||
factions:
|
||||
- SpiceStream
|
||||
- HelmirWeapon
|
||||
service: !type:CP14SellStackService
|
||||
stackId: CP14GoldBar
|
||||
count: 10
|
||||
|
||||
- type: storePositionSell
|
||||
id: GoldOre
|
||||
price: 120
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14SellStackService
|
||||
stackId: CP14OreGold
|
||||
count: 10
|
||||
|
||||
- type: storePositionSell
|
||||
id: MithrilBars
|
||||
price: 2500
|
||||
factions:
|
||||
- SpiceStream
|
||||
- HelmirWeapon
|
||||
service: !type:CP14SellStackService
|
||||
stackId: CP14MithrilBar
|
||||
count: 10
|
||||
|
||||
- type: storePositionSell
|
||||
id: MithrilOre
|
||||
price: 250
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14SellStackService
|
||||
stackId: CP14OreMithril
|
||||
count: 10
|
||||
|
||||
- type: storePositionSell
|
||||
id: Wood
|
||||
price: 5
|
||||
factions:
|
||||
- SpiceStream
|
||||
- HelmirWeapon
|
||||
service: !type:CP14SellStackService
|
||||
stackId: CP14WoodenPlanks
|
||||
count: 30
|
||||
|
||||
- type: storePositionSell
|
||||
id: Glass
|
||||
price: 100
|
||||
factions:
|
||||
- SpiceStream
|
||||
service: !type:CP14SellStackService
|
||||
stackId: CP14GlassSheet
|
||||
count: 10
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user