Cargo economy balance (#11123)

Co-authored-by: Visne <39844191+Visne@users.noreply.github.com>
This commit is contained in:
metalgearsloth
2022-09-15 11:53:17 +10:00
committed by GitHub
parent f4c38d74e1
commit ad7a851e27
113 changed files with 615 additions and 58 deletions

View File

@@ -63,7 +63,7 @@ namespace Content.Client.Cargo.UI
Products.RemoveAllChildren();
var products = ProductPrototypes.ToList();
products.Sort((x, y) =>
string.Compare(x.Name, y.Name, StringComparison.Ordinal));
string.Compare(x.Name, y.Name, StringComparison.CurrentCultureIgnoreCase));
var search = SearchBar.Text.Trim().ToLowerInvariant();
foreach (var prototype in products)

View File

@@ -0,0 +1,29 @@
using Content.Client.Eui;
using Content.Shared.Eui;
using Content.Shared.UserInterface;
namespace Content.Client.UserInterface;
public sealed class StatValuesEui : BaseEui
{
private readonly StatsWindow _window;
public StatValuesEui()
{
_window = new StatsWindow();
_window.Title = "Melee stats";
_window.OpenCentered();
_window.OnClose += Closed;
}
public override void HandleMessage(EuiMessageBase msg)
{
base.HandleMessage(msg);
if (msg is not StatValuesEuiMessage eui)
return;
_window.Title = eui.Title;
_window.UpdateValues(eui.Headers, eui.Values);
}
}

View File

@@ -0,0 +1,11 @@
<DefaultWindow xmlns="https://spacestation14.io"
Title="Stats window"
MinSize="600 400">
<BoxContainer Orientation="Vertical">
<ScrollContainer HorizontalExpand="True"
VerticalExpand="True"
SizeFlagsStretchRatio="6">
<GridContainer Name="Values"/>
</ScrollContainer>
</BoxContainer>
</DefaultWindow>

View File

@@ -0,0 +1,48 @@
using Content.Client.Administration.UI.CustomControls;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
namespace Content.Client.UserInterface
{
[GenerateTypedNameReferences]
public sealed partial class StatsWindow : DefaultWindow
{
public StatsWindow()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
}
public void UpdateValues(List<string> headers, List<string[]> values)
{
Values.DisposeAllChildren();
Values.Columns = headers.Count;
for (var i = 0; i < headers.Count; i++)
{
var item = headers[i];
Values.AddChild(new Label()
{
Text = item,
});
}
values.Sort((x, y) => string.Compare(x[0], y[0], StringComparison.CurrentCultureIgnoreCase));
for (var i = 0; i < values.Count; i++)
{
var value = values[i];
for (var j = 0; j < value.Length; j++)
{
Values.AddChild(new Label()
{
Text = value[j],
});
}
}
}
}
}

View File

@@ -13,7 +13,7 @@ namespace Content.IntegrationTests.Tests;
public sealed class CargoTest
{
[Test]
public async Task NoArbitrage()
public async Task NoCargoOrderArbitrage()
{
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings() {NoClient = true});
var server = pairTracker.Pair.Server;
@@ -32,8 +32,13 @@ public sealed class CargoTest
var ent = entManager.SpawnEntity(proto.Product, new MapCoordinates(Vector2.Zero, mapId));
var price = pricing.GetPrice(ent);
Assert.That(price, Is.LessThan(proto.PointCost), $"Found arbitrage on {proto.ID} cargo product!");
Assert.That(price, Is.LessThan(proto.PointCost), $"Found arbitrage on {proto.ID} cargo product! Cost is {proto.PointCost} but sell is {price}!");
entManager.DeleteEntity(ent);
}
mapManager.DeleteMap(mapId);
});
await pairTracker.CleanReturnAsync();
}
}

View File

@@ -15,5 +15,5 @@ public sealed class StationBankAccountComponent : Component
/// How much the bank balance goes up per second, every Delay period. Rounded down when multiplied.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("increasePerSecond")]
public int IncreasePerSecond = 10;
public int IncreasePerSecond = 2;
}

View File

@@ -9,6 +9,7 @@ using Content.Shared.MobState.Components;
using Robust.Shared.Console;
using Robust.Shared.Containers;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.Cargo.Systems;
@@ -111,6 +112,33 @@ public sealed class PricingSystem : EntitySystem
args.Price += component.Price;
}
/// <summary>
/// Get a rough price for an entityprototype. Does not consider contained entities.
/// </summary>
public double GetEstimatedPrice(EntityPrototype prototype, IComponentFactory? factory = null)
{
IoCManager.Resolve(ref factory);
var price = 0.0;
if (prototype.Components.TryGetValue(factory.GetComponentName(typeof(StaticPriceComponent)),
out var staticPriceProto))
{
var staticComp = (StaticPriceComponent) staticPriceProto.Component;
price += staticComp.Price;
}
if (prototype.Components.TryGetValue(factory.GetComponentName(typeof(StackPriceComponent)), out var stackpriceProto) &&
prototype.Components.TryGetValue(factory.GetComponentName(typeof(StackComponent)), out var stackProto))
{
var stackPrice = (StackPriceComponent) stackpriceProto.Component;
var stack = (StackComponent) stackProto.Component;
price += stack.Count * stackPrice.Price;
}
return price;
}
/// <summary>
/// Appraises an entity, returning it's price.
/// </summary>
@@ -123,7 +151,7 @@ public sealed class PricingSystem : EntitySystem
public double GetPrice(EntityUid uid)
{
var ev = new PriceCalculationEvent();
RaiseLocalEvent(uid, ref ev, true);
RaiseLocalEvent(uid, ref ev);
//TODO: Add an OpaqueToAppraisal component or similar for blocking the recursive descent into containers, or preventing material pricing.

View File

@@ -15,6 +15,7 @@ using Robust.Shared.Prototypes;
using Robust.Shared.Player;
using JetBrains.Annotations;
using System.Linq;
using Content.Server.Cargo.Systems;
using Content.Server.Power.Components;
using Robust.Server.Player;

View File

@@ -0,0 +1,144 @@
using Content.Server.Administration;
using Content.Server.Cargo.Systems;
using Content.Server.EUI;
using Content.Shared.Administration;
using Content.Shared.Materials;
using Content.Shared.Research.Prototypes;
using Content.Shared.UserInterface;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Prototypes;
namespace Content.Server.UserInterface;
[AdminCommand(AdminFlags.Debug)]
public sealed class StatValuesCommand : IConsoleCommand
{
public string Command => "showvalues";
public string Description => "Dumps all stats for a particular category into a table.";
public string Help => $"{Command} <cargosell / lathsell>";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (shell.Player is not IPlayerSession pSession)
{
shell.WriteError($"{Command} can't be run on server!");
return;
}
if (args.Length != 1)
{
shell.WriteError($"Invalid number of args, need 1");
return;
}
StatValuesEuiMessage message;
switch (args[0])
{
case "cargosell":
message = GetCargo();
break;
case "lathesell":
message = GetLatheMessage();
break;
default:
shell.WriteError($"{args[0]} is not a valid stat!");
return;
}
var euiManager = IoCManager.Resolve<EuiManager>();
var eui = new StatValuesEui();
euiManager.OpenEui(eui, pSession);
eui.SendMessage(message);
}
private StatValuesEuiMessage GetCargo()
{
// Okay so there's no easy way to do this with how pricing works
// So we'll just get the first value for each prototype ID which is probably good enough for the majority.
var values = new List<string[]>();
var entManager = IoCManager.Resolve<IEntityManager>();
var priceSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<PricingSystem>();
var metaQuery = entManager.GetEntityQuery<MetaDataComponent>();
var prices = new HashSet<string>(256);
foreach (var entity in entManager.GetEntities())
{
if (!metaQuery.TryGetComponent(entity, out var meta))
continue;
var id = meta.EntityPrototype?.ID;
// We'll add it even if we don't have it so we don't have to raise the event again because this is probably faster.
if (id == null || !prices.Add(id))
continue;
var price = priceSystem.GetPrice(entity);
if (price == 0)
continue;
values.Add(new string[]
{
id,
$"{price:0}",
});
}
var state = new StatValuesEuiMessage()
{
Title = "Cargo sell prices",
Headers = new List<string>()
{
"ID",
"Price",
},
Values = values,
};
return state;
}
private StatValuesEuiMessage GetLatheMessage()
{
var values = new List<string[]>();
var protoManager = IoCManager.Resolve<IPrototypeManager>();
var factory = IoCManager.Resolve<IComponentFactory>();
var priceSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<PricingSystem>();
foreach (var proto in protoManager.EnumeratePrototypes<LatheRecipePrototype>())
{
var cost = 0.0;
foreach (var (material, count) in proto.RequiredMaterials)
{
var materialPrice = protoManager.Index<MaterialPrototype>(material).Price;
cost += materialPrice * count;
}
var sell = priceSystem.GetEstimatedPrice(protoManager.Index<EntityPrototype>(proto.Result), factory);
values.Add(new[]
{
proto.ID,
$"{cost:0}",
$"{sell:0}",
});
}
var state = new StatValuesEuiMessage()
{
Title = "Lathe sell prices",
Headers = new List<string>()
{
"ID",
"Cost",
"Sell price",
},
Values = values,
};
return state;
}
}

View File

@@ -0,0 +1,5 @@
using Content.Server.EUI;
namespace Content.Server.UserInterface;
public sealed class StatValuesEui : BaseEui {}

View File

@@ -1,3 +1,4 @@
using Content.Server.Cargo.Systems;
using Content.Server.Popups;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
@@ -21,24 +22,30 @@ namespace Content.Server.VendingMachines
{
public sealed class VendingMachineSystem : SharedVendingMachineSystem
{
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly AccessReaderSystem _accessReader = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly ThrowingSystem _throwingSystem = default!;
[Dependency] private readonly SharedActionsSystem _action = default!;
[Dependency] private readonly AudioSystem _audioSystem = default!;
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
[Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
[Dependency] private readonly AudioSystem _audioSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedActionsSystem _action = default!;
[Dependency] private readonly PricingSystem _pricing = default!;
[Dependency] private readonly ThrowingSystem _throwingSystem = default!;
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
private ISawmill _sawmill = default!;
public override void Initialize()
{
base.Initialize();
_sawmill = Logger.GetSawmill("vending");
SubscribeLocalEvent<VendingMachineComponent, PowerChangedEvent>(OnPowerChanged);
SubscribeLocalEvent<VendingMachineComponent, BreakageEventArgs>(OnBreak);
SubscribeLocalEvent<VendingMachineComponent, GotEmaggedEvent>(OnEmagged);
SubscribeLocalEvent<VendingMachineComponent, DamageChangedEvent>(OnDamage);
SubscribeLocalEvent<VendingMachineComponent, PriceCalculationEvent>(OnVendingPrice);
SubscribeLocalEvent<VendingMachineComponent, ActivatableUIOpenAttemptEvent>(OnActivatableUIOpenAttempt);
SubscribeLocalEvent<VendingMachineComponent, BoundUIOpenedEvent>(OnBoundUIOpened);
@@ -47,6 +54,24 @@ namespace Content.Server.VendingMachines
SubscribeLocalEvent<VendingMachineComponent, VendingMachineSelfDispenseEvent>(OnSelfDispense);
}
private void OnVendingPrice(EntityUid uid, VendingMachineComponent component, ref PriceCalculationEvent args)
{
var price = 0.0;
foreach (var (id, entry) in component.Inventory)
{
if (!_prototypeManager.TryIndex<EntityPrototype>(entry.ID, out var proto))
{
_sawmill.Error($"Unable to find entity prototype {entry.ID} on {ToPrettyString(uid)} vending.");
continue;
}
price += entry.Amount * _pricing.GetEstimatedPrice(proto, _factory);
}
args.Price += price;
}
protected override void OnComponentInit(EntityUid uid, SharedVendingMachineComponent sharedComponent, ComponentInit args)
{
base.OnComponentInit(uid, sharedComponent, args);

View File

@@ -1,4 +1,5 @@
using System.Linq;
using Content.Server.Cargo.Systems;
using Content.Server.Damage.Systems;
using Content.Server.Examine;
using Content.Server.Interaction;
@@ -23,6 +24,7 @@ using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
using SharedGunSystem = Content.Shared.Weapons.Ranged.Systems.SharedGunSystem;
@@ -33,12 +35,35 @@ public sealed partial class GunSystem : SharedGunSystem
[Dependency] private readonly IComponentFactory _factory = default!;
[Dependency] private readonly ExamineSystem _examine = default!;
[Dependency] private readonly InteractionSystem _interaction = default!;
[Dependency] private readonly PricingSystem _pricing = default!;
[Dependency] private readonly StaminaSystem _stamina = default!;
[Dependency] private readonly StunSystem _stun = default!;
public const float DamagePitchVariation = MeleeWeaponSystem.DamagePitchVariation;
public const float GunClumsyChance = 0.5f;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<BallisticAmmoProviderComponent, PriceCalculationEvent>(OnBallisticPrice);
}
private void OnBallisticPrice(EntityUid uid, BallisticAmmoProviderComponent component, ref PriceCalculationEvent args)
{
if (string.IsNullOrEmpty(component.FillProto) || component.UnspawnedCount == 0)
return;
if (!ProtoManager.TryIndex<EntityPrototype>(component.FillProto, out var proto))
{
Sawmill.Error($"Unable to find fill prototype for price on {component.FillProto} on {ToPrettyString(uid)}");
return;
}
// Probably good enough for most.
var price = _pricing.GetEstimatedPrice(proto);
args.Price += price * component.UnspawnedCount;
}
public override void Shoot(GunComponent gun, List<IShootable> ammo, EntityCoordinates fromCoordinates, EntityCoordinates toCoordinates, EntityUid? user = null)
{
// Try a clumsy roll

View File

@@ -12,7 +12,7 @@ public sealed class CargoShuttleComponent : Component
public TimeSpan? NextCall;
[ViewVariables(VVAccess.ReadWrite), DataField("cooldown")]
public float Cooldown = 150f;
public float Cooldown = 30f;
[ViewVariables]
public bool CanRecall;

View File

@@ -0,0 +1,18 @@
using Content.Shared.Eui;
using Robust.Shared.Serialization;
namespace Content.Shared.UserInterface;
/// <summary>
/// It's a message not a state because it's for debugging and it makes it easier to bootstrap more data dumping.
/// </summary>
[Serializable, NetSerializable]
public sealed class StatValuesEuiMessage : EuiMessageBase
{
/// <summary>
/// Titles for the window.
/// </summary>
public string Title = string.Empty;
public List<string> Headers = new();
public List<string[]> Values = new();
}

View File

@@ -15,6 +15,8 @@
containers:
bodypart: !type:Container
ents: []
- type: StaticPrice
price: 50
# For primates mainly
- type: entity
@@ -79,6 +81,8 @@
- type: Sprite
netsync: false
sprite: Mobs/Species/Human/organs.rsi
- type: StaticPrice
price: 50
- type: entity
id: OrganAnimalLungs

View File

@@ -13,6 +13,8 @@
containers:
bodypart: !type:Container
ents: []
- type: StaticPrice
price: 100
- type: entity
id: TorsoHuman

View File

@@ -11,6 +11,8 @@
containers:
bodypart: !type:Container
ents: []
- type: StaticPrice
price: 100
- type: entity
id: LeftArmBorg

View File

@@ -12,6 +12,8 @@
containers:
bodypart: !type:Container
ents: []
- type: StaticPrice
price: 20
- type: entity
id: TorsoSkeleton

View File

@@ -12,6 +12,8 @@
containers:
bodypart: !type:Container
ents: []
- type: StaticPrice
price: 100
- type: entity
id: TorsoSlime

View File

@@ -13,6 +13,8 @@
containers:
bodypart: !type:Container
ents: []
- type: StaticPrice
price: 100
- type: entity
id: TorsoVox

View File

@@ -54,6 +54,6 @@
sprite: Objects/Vehicles/atv.rsi
state: vehicle
product: CrateFunATV
cost: 6000
cost: 1500
category: Fun
group: market

View File

@@ -4,7 +4,7 @@
sprite: Mobs/Animals/bee.rsi
state: 0
product: CrateNPCBee
cost: 1000
cost: 4000
category: Livestock
group: market
@@ -14,7 +14,7 @@
sprite: Mobs/Animals/butterfly.rsi
state: butterfly
product: CrateNPCButterflies
cost: 1000
cost: 2500
category: Livestock
group: market
@@ -34,7 +34,7 @@
sprite: Mobs/Animals/chicken.rsi
state: icon-1
product: CrateNPCChicken
cost: 1500
cost: 2500
category: Livestock
group: market
@@ -44,7 +44,7 @@
sprite: Mobs/Animals/duck.rsi
state: icon-0
product: CrateNPCDuck
cost: 2000
cost: 3500
category: Livestock
group: market
@@ -114,7 +114,7 @@
sprite: Mobs/Animals/mouse.rsi
state: icon-0
product: CrateNPCMouse
cost: 1500
cost: 2500
category: Livestock
group: market
@@ -124,7 +124,7 @@
sprite: Mobs/Animals/parrot.rsi
state: parrot
product: CrateNPCParrot
cost: 1000
cost: 2000
category: Livestock
group: market
@@ -144,6 +144,6 @@
sprite: Mobs/Animals/snake.rsi
state: snake
product: CrateNPCSnake
cost: 1000
cost: 2000
category: Livestock
group: market

View File

@@ -4,7 +4,7 @@
sprite: Objects/Specific/Medical/firstaidkits.rsi
state: firstaid
product: CrateMedicalSupplies
cost: 1000
cost: 2400
category: Medical
group: market
@@ -14,6 +14,6 @@
sprite: Objects/Specific/Chemistry/beaker.rsi
state: beaker
product: CrateChemistrySupplies
cost: 500
cost: 650
category: Medical
group: market

View File

@@ -24,7 +24,7 @@
sprite: Objects/Weapons/Guns/Battery/disabler.rsi
state: base
product: CrateSecurityNonlethal
cost: 1500
cost: 2100
category: Security
group: market

View File

@@ -40,6 +40,8 @@
interfaces:
- key: enum.StorageUiKey.Key
type: StorageBoundUserInterface
- type: StaticPrice
price: 80
- type: entity
abstract: true

View File

@@ -31,6 +31,8 @@
enum.ToggleVisuals.Layer:
True: {state: icon-on}
False: {state: icon}
- type: StaticPrice
price: 200
- type: entity
parent: ClothingShoesBootsMag

View File

@@ -8,3 +8,5 @@
- type: Tag
tags:
- WhitelistChameleon
- type: StaticPrice
price: 15

View File

@@ -14,6 +14,8 @@
- type: SpaceGarbage
- type: Sprite
netsync: false
- type: StaticPrice
price: 50
# This base type is used to cover all of the "obvious" things that should be doable to open-package food.
# Practically this means injection.

View File

@@ -1,6 +1,3 @@
- type: Tag
id: Cigarette
- type: entity
id: Cigarette
parent: BaseCigar

View File

@@ -15,6 +15,8 @@
- Trash
- type: Recyclable
- type: SpaceGarbage
- type: StaticPrice
price: 5
# Base for all cigars and cigarettes.
- type: entity

View File

@@ -13,4 +13,4 @@
tags:
- DroneUsable
- type: StaticPrice
price: 75
price: 100

View File

@@ -12,7 +12,7 @@
tags:
- DroneUsable
- type: StaticPrice
price: 75
price: 100
- type: entity
parent: BaseComputerCircuitboard

View File

@@ -12,3 +12,5 @@
sprite: Objects/Misc/module.rsi
state: mainboard
netsync: false
- type: StaticPrice
price: 100

View File

@@ -10,6 +10,8 @@
sprite: Objects/Misc/module.rsi
state: charger_APC
netsync: false
- type: StaticPrice
price: 100
# Wallmount Substation
- type: entity
@@ -22,6 +24,8 @@
sprite: Objects/Misc/module.rsi
state: charger_APC
netsync: false
- type: StaticPrice
price: 100
# Wallmount Generator
- type: entity
@@ -34,6 +38,8 @@
sprite: Objects/Misc/module.rsi
state: charger_APC
netsync: false
- type: StaticPrice
price: 100
# APU
- type: entity
@@ -46,6 +52,8 @@
sprite: Objects/Misc/module.rsi
state: charger_APC
netsync: false
- type: StaticPrice
price: 100
# Solar Tracker Electronics
- type: entity
@@ -58,3 +66,5 @@
sprite: Objects/Misc/module.rsi
state: generic
netsync: false
- type: StaticPrice
price: 100

View File

@@ -11,3 +11,5 @@
state: signaller
- type: Signaller
- type: UseDelay
- type: StaticPrice
price: 40

View File

@@ -25,6 +25,8 @@
delayOptions: [3, 5, 10, 15, 30]
initialBeepDelay: 0
beepSound: /Audio/Machines/Nuke/general_beep.ogg
- type: StaticPrice
price: 40
- type: entity
parent: TimerTrigger
@@ -39,3 +41,5 @@
components:
- type: TriggerOnSignal
- type: SignalReceiver
- type: StaticPrice
price: 40

View File

@@ -33,3 +33,5 @@
sprite: Objects/Devices/Holoprojectors/atmos.rsi
state: icon
netsync: false
- type: StaticPrice
price: 80

View File

@@ -81,6 +81,8 @@
containers:
BeakerSlotA: !type:ContainerSlot
BeakerSlotB: !type:ContainerSlot
- type: StaticPrice
price: 60
- type: entity
name: flash payload

View File

@@ -18,6 +18,8 @@
type: InstrumentBoundUserInterface
- type: Item
size: 24
- type: StaticPrice
price: 200
#These are for instruments that are larger, can't be picked up, or have collision
- type: entity
@@ -67,6 +69,8 @@
- HighImpassable
- MidImpassable
- BulletImpassable
- type: StaticPrice
price: 300
- type: entity
parent: BasePlaceableInstrument

View File

@@ -27,6 +27,8 @@
Quantity: 3
- ReagentId: MindbreakerToxin
Quantity: 2
- type: StaticPrice
price: 5
- type: entity
parent: Crayon

View File

@@ -175,7 +175,7 @@
components:
- type: Material
materials:
ReinforcedPlasmaGlass: 500
ReinforcedPlasmaGlass: 100
- type: Stack
stackType: ReinforcedPlasmaGlass
- type: Sprite

View File

@@ -64,7 +64,7 @@
components:
- type: Material
materials:
Plasma: 500
Plasma: 100
- type: Stack
stackType: Plasma
- type: Sprite

View File

@@ -28,7 +28,7 @@
- type: entity
parent: PartBase
id: PartRodMetal
name: metals rods
name: metal rods
suffix: Full
components:
- type: Stack
@@ -53,6 +53,10 @@
outputs:
- Lattice
- FloorReinforced
- type: StaticPrice
price: 0
- type: StackPrice
price: 5
- type: entity
parent: PartRodMetal

View File

@@ -19,6 +19,8 @@
quickEquip: true
slots:
- neck
- type: StaticPrice
price: 100
- type: entity
id: BedsheetBlack

View File

@@ -10,3 +10,5 @@
- type: Tag
tags:
- ProximitySensor
- type: StaticPrice
price: 40

View File

@@ -12,3 +12,5 @@
state: jar
netsync: false
- type: AMEFuelContainer
- type: StaticPrice
price: 500

View File

@@ -11,3 +11,5 @@
sprite: Objects/Power/AME/ame_part.rsi
state: box
- type: AMEPart
- type: StaticPrice
price: 500

View File

@@ -28,6 +28,8 @@
- DroneUsable
- type: Appearance
- type: PowerCellVisuals
- type: StaticPrice
price: 100
- type: entity
name: potato battery

View File

@@ -50,6 +50,9 @@
parent: BaseShield
id: RiotShield
description: A large tower shield. Good for controlling crowds.
components:
- type: StaticPrice
price: 100
- type: entity
name: riot laser shield

View File

@@ -10,6 +10,8 @@
netsync: true
- type: Item
size: 2
- type: StaticPrice
price: 20
- type: entity
parent: SeedBase

View File

@@ -61,6 +61,8 @@
sprite: Objects/Tools/Hydroponics/scythe.rsi
slots:
- back
- type: StaticPrice
price: 40
- type: entity
name: hatchet

View File

@@ -19,3 +19,5 @@
receiveFrequencyId: SuitSensor
- type: WirelessNetworkConnection
range: 500
- type: StaticPrice
price: 500

View File

@@ -8,6 +8,9 @@
- type: Item
sprite: Objects/Specific/Medical/medical.rsi
heldPrefix: ointment
# Inherited
- type: StaticPrice
price: 0
- type: entity
name: ointment
@@ -35,6 +38,8 @@
stackType: Ointment
max: 10
count: 10
- type: StackPrice
price: 10
- type: entity
name: bruise pack
@@ -61,6 +66,8 @@
stackType: Brutepack
max: 10
count: 10
- type: StackPrice
price: 10
- type: entity
name: roll of gauze
@@ -91,6 +98,8 @@
stackType: Gauze
max: 10
count: 10
- type: StackPrice
price: 10
- type: entity
id: Gauze1

View File

@@ -72,6 +72,8 @@
containers:
entity_storage: !type:Container
paper_label: !type:ContainerSlot
- type: StaticPrice
price: 50
- type: entity
id: BodyBag_Folded

View File

@@ -7,6 +7,8 @@
components:
- type: Sprite
netsync: false
- type: StaticPrice
price: 60
# Cautery

View File

@@ -54,3 +54,5 @@
- type: Appearance
visuals:
- type: DeployableBarrierVisualizer
- type: StaticPrice
price: 200

View File

@@ -30,3 +30,5 @@
- type: Tag
tags:
- DroneUsable
- type: StaticPrice
price: 80

View File

@@ -78,6 +78,8 @@
damage:
types:
Blunt: 5
- type: StaticPrice
price: 30
- type: entity
name: beaker
@@ -113,6 +115,8 @@
- type: SolutionContainerVisuals
maxFillLevels: 6
fillBaseName: beakerlarge
- type: StaticPrice
price: 40
- type: entity
name: cryostasis beaker
@@ -205,6 +209,8 @@
- type: SolutionContainerVisuals
maxFillLevels: 1
fillBaseName: dropper
- type: StaticPrice
price: 40
- type: entity
name: syringe

View File

@@ -18,3 +18,5 @@
whitelist:
tags:
- PaintableAirlock
- type: StaticPrice
price: 40

View File

@@ -52,6 +52,8 @@
- type: Appearance
visuals:
- type: FlashLightVisualizer
- type: StaticPrice
price: 40
- type: entity
name: seclite

View File

@@ -20,3 +20,5 @@
- type: Tag
tags:
- DroneUsable
- type: StaticPrice
price: 100

View File

@@ -22,3 +22,5 @@
- type: Tag
tags:
- DroneUsable
- type: StaticPrice
price: 60

View File

@@ -35,6 +35,8 @@
- type: Item
sprite: Objects/Tools/wirecutters.rsi
- type: LatticeCutting
- type: StaticPrice
price: 40
- type: entity
name: screwdriver
@@ -71,6 +73,8 @@
available:
- enum.DamageStateVisualLayers.Base:
screwdriver: Rainbow
- type: StaticPrice
price: 40
- type: entity
name: wrench
@@ -100,6 +104,8 @@
- Anchoring
useSound:
path: /Audio/Items/ratchet.ogg
- type: StaticPrice
price: 40
- type: entity
name: crowbar
@@ -131,6 +137,8 @@
useSound:
path: /Audio/Items/crowbar.ogg
- type: TilePrying
- type: StaticPrice
price: 40
- type: entity
name: emergency crowbar
@@ -190,6 +198,8 @@
- type: Tag
tags:
- DroneUsable
- type: StaticPrice
price: 60
- type: entity
name: power drill
@@ -229,6 +239,8 @@
path: /Audio/Items/drill_use.ogg
changeSound:
path: /Audio/Items/change_drill.ogg
- type: StaticPrice
price: 60
- type: entity
name: RCD
@@ -249,6 +261,8 @@
quickEquip: false
slots:
- Belt
- type: StaticPrice
price: 100
- type: entity
name: RCD Ammo
@@ -263,6 +277,8 @@
- type: Item
sprite: Objects/Tools/rcd.rsi
heldPrefix: ammo
- type: StaticPrice
price: 60
- type: entity
name: shovel

View File

@@ -51,6 +51,8 @@
color: orange
- type: Appearance
- type: RequiresEyeProtection
- type: StaticPrice
price: 40
- type: entity
name: industrial welding tool

View File

@@ -16,3 +16,5 @@
map: ["enum.AmmoVisualLayers.Base"]
- type: Appearance
- type: SpentAmmoVisuals
- type: StaticPrice
price: 20

View File

@@ -19,6 +19,8 @@
map: ["enum.AmmoVisualLayers.Base"]
- type: Appearance
- type: SpentAmmoVisuals
- type: StaticPrice
price: 10
- type: entity
id: CartridgeCaselessRifle

View File

@@ -18,6 +18,8 @@
map: ["enum.AmmoVisualLayers.Base"]
- type: Appearance
- type: SpentAmmoVisuals
- type: StaticPrice
price: 10
- type: entity
id: CartridgeMinigun

View File

@@ -18,6 +18,8 @@
map: ["enum.AmmoVisualLayers.Base"]
- type: Appearance
- type: SpentAmmoVisuals
- type: StaticPrice
price: 10
- type: entity
id: CartridgeLightRifle

View File

@@ -18,6 +18,8 @@
map: ["enum.AmmoVisualLayers.Base"]
- type: Appearance
- type: SpentAmmoVisuals
- type: StaticPrice
price: 10
- type: entity
id: CartridgeMagnum

View File

@@ -18,6 +18,8 @@
map: ["enum.AmmoVisualLayers.Base"]
- type: Appearance
- type: SpentAmmoVisuals
- type: StaticPrice
price: 10
- type: entity
id: CartridgePistol

View File

@@ -18,6 +18,8 @@
map: ["enum.AmmoVisualLayers.Base"]
- type: Appearance
- type: SpentAmmoVisuals
- type: StaticPrice
price: 10
- type: entity
id: CartridgeRifle

View File

@@ -17,6 +17,8 @@
map: ["enum.AmmoVisualLayers.Base"]
- type: SpentAmmoVisuals
- type: Appearance
- type: StaticPrice
price: 5
- type: entity
id: CartridgeCap

View File

@@ -18,6 +18,8 @@
netsync: false
sprite: Objects/Weapons/Guns/Ammunition/Explosives/explosives.rsi
state: rpg
- type: StaticPrice
price: 20
- type: entity
id: CartridgeRocketSlow
@@ -36,6 +38,8 @@
- type: Sprite
sprite: Objects/Weapons/Guns/Ammunition/Explosives/explosives.rsi
state: frag
- type: StaticPrice
price: 20
# Grenades

View File

@@ -29,6 +29,8 @@
steps: 5
zeroVisible: false
- type: Appearance
- type: StaticPrice
price: 500
- type: entity
id: BaseWeaponBatterySmall

View File

@@ -17,6 +17,8 @@
path: /Audio/Weapons/Guns/Gunshots/lmg.ogg
soundEmpty:
path: /Audio/Weapons/Guns/Empty/lmg_empty.ogg
- type: StaticPrice
price: 500
# No chamber because HMG may want its own
- type: entity

View File

@@ -51,6 +51,8 @@
containers:
gun_magazine: !type:ContainerSlot
gun_chamber: !type:ContainerSlot
- type: StaticPrice
price: 500
- type: entity
name: L6 SAW

View File

@@ -14,6 +14,8 @@
- Back
- type: Item
size: 60
- type: StaticPrice
price: 500
- type: entity
name: china lake

View File

@@ -55,6 +55,8 @@
steps: 1
zeroVisible: true
- type: Appearance
- type: StaticPrice
price: 500
- type: entity
name: viper

View File

@@ -38,6 +38,8 @@
path: /Audio/Weapons/Guns/MagOut/revolver_magout.ogg
soundInsert:
path: /Audio/Weapons/Guns/MagIn/revolver_magin.ogg
- type: StaticPrice
price: 500
- type: entity
name: Deckard

View File

@@ -46,6 +46,8 @@
containers:
gun_magazine: !type:ContainerSlot
gun_chamber: !type:ContainerSlot
- type: StaticPrice
price: 500
- type: entity
name: AKMS

View File

@@ -49,6 +49,8 @@
containers:
gun_magazine: !type:ContainerSlot
gun_chamber: !type:ContainerSlot
- type: StaticPrice
price: 500
- type: entity
name: Atreides

View File

@@ -42,6 +42,8 @@
containers:
ballistic-ammo: !type:Container
ents: []
- type: StaticPrice
price: 500
- type: entity
name: Bulldog
@@ -96,6 +98,8 @@
steps: 1
zeroVisible: true
- type: Appearance
- type: StaticPrice
price: 500
- type: entity
name: double-barreled shotgun

View File

@@ -36,6 +36,8 @@
containers:
ballistic-ammo: !type:Container
ents: []
- type: StaticPrice
price: 500
- type: entity
name: Kardashev-Mosin

View File

@@ -45,6 +45,8 @@
enum.ToggleVisuals.Layer:
True: {state: stunbaton_on}
False: {state: stunbaton_off}
- type: StaticPrice
price: 100
- type: entity
name: flash
@@ -67,6 +69,8 @@
size: 5
sprite: Objects/Weapons/Melee/flash.rsi
- type: ItemCooldown
- type: StaticPrice
price: 40
- type: entity
name: portable flasher

View File

@@ -6,7 +6,7 @@
- type: Item
size: 5
- type: StaticPrice
price: 5
price: 20
- type: Clickable
- type: InteractionOutline
- type: MovedByPressure

View File

@@ -59,3 +59,5 @@
machine_board: !type:Container
machine_parts: !type:Container
ReagentDispenser-beaker: !type:ContainerSlot
- type: StaticPrice
price: 1000

View File

@@ -99,5 +99,7 @@
mode: NoSprite
- type: PaintableAirlock
group: Standard
- type: StaticPrice
price: 150
placement:
mode: SnapgridCenter

View File

@@ -99,6 +99,8 @@
node: Firelock
- type: WallMount
arc: 360
- type: StaticPrice
price: 150
- type: entity
id: FirelockGlass
@@ -152,3 +154,5 @@
occludes: false
- type: Physics
canCollide: false
- type: StaticPrice
price: 100

View File

@@ -111,6 +111,8 @@
- type: Construction
graph: Windoor
node: windoor
- type: StaticPrice
price: 100
- type: entity
id: BaseSecureWindoor

View File

@@ -40,6 +40,8 @@
- !type:PlaySoundBehavior
sound:
path: /Audio/Effects/metalbreak.ogg
- type: StaticPrice
price: 50
- type: entity
name: chair

View File

@@ -55,6 +55,8 @@
key: rollerbed
- type: RollerbedVisualizer
key: rollerbed
- type: StaticPrice
price: 200
- type: entity
id: CheapRollerBed

View File

@@ -33,6 +33,8 @@
bodyBroken: arcade
- type: Anchorable
- type: Pullable
- type: StaticPrice
price: 300
- type: entity
id: SpaceVillainArcade

View File

@@ -53,3 +53,5 @@
containers:
board: !type:Container
ents: []
- type: StaticPrice
price: 400

View File

@@ -63,3 +63,5 @@
enum.CloningPodStatus.Gore: pod_g
enum.CloningPodStatus.Idle: pod_0
- type: Climbable
- type: StaticPrice
price: 1000

View File

@@ -85,6 +85,8 @@
anchored: true
- type: Pullable
- type: Lathe
- type: StaticPrice
price: 800
- type: entity
parent: [ BaseMachinePowered, ConstructibleMachine ]

View File

@@ -48,6 +48,8 @@
range: 2
sound:
path: /Audio/Ambience/Objects/gas_hiss.ogg
- type: StaticPrice
price: 100
#Note: The PipeDirection of the PipeNode should be the south-facing version, because the entity starts at an angle of 0 (south)

View File

@@ -246,6 +246,8 @@
!type:PipeNode
nodeGroupID: Pipe
pipeDirection: South
- type: StaticPrice
price: 500
- type: entity
parent: BaseGasThermoMachine

View File

@@ -74,6 +74,8 @@
- type: ContainerContainer
containers:
DisposalUnit: !type:Container
- type: StaticPrice
price: 100
- type: entity
id: DisposalUnit

View File

@@ -67,6 +67,8 @@
maxIntensity: 100
intensitySlope: 2
totalIntensity: 200
- type: StaticPrice
price: 500
# Base Wallmount Generator

View File

@@ -92,6 +92,8 @@
- !type:DoActsBehavior
acts: [ "Destruction" ]
- type: StationInfiniteBatteryTarget
- type: StaticPrice
price: 500
# APC under construction
- type: entity

Some files were not shown because too many files have changed in this diff Show More