mirror of
https://github.com/space-wizards/space-station-14.git
synced 2026-06-09 10:06:43 +02:00
d42adbf05d
* Pass 1. * i'm FREE * Prevent hangups. * okay fine here's an attribute for settings, will polish later and prolly remove the overridable thing. * sigh. * fix singular trigger bug so LatheTest doesn't flake. * Remove SystemAttribute usage. * Poke * I used the shotgun. You know why? Cause the shot gun doesn’t miss, and unlike the shitty hybrid taser it stops a criminal in their tracks in two hits. Bang, bang, and they’re fucking done. I use four shots just to make damn sure. Because, once again, I’m not there to coddle a buncha criminal scum sucking f------, I’m there to 1) Survive the fucking round. 2) Guard the armory. So you can absolutely get fucked. If I get unbanned, which I won’t, you can guarantee I will continue to use the shotgun to apprehend criminals. Because it’s quick, clean and effective as fuck. Why in the seven hells would I fuck around with the disabler shots, which take half a clip just to bring someone down, or with the tazer bolts which are slow as balls, impossible to aim and do about next to jack shit, fuck all. The shotgun is the superior law enforcement weapon. Because it stops crime. And it stops crime by reducing the number of criminals roaming the fucking halls. * Change the faulty store test into two tests, one of which is ignored for failing.
262 lines
9.2 KiB
C#
262 lines
9.2 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
using Content.IntegrationTests.Fixtures;
|
|
using Content.Server.Cargo.Components;
|
|
using Content.Server.Cargo.Systems;
|
|
using Content.Server.Nutrition.Components;
|
|
using Content.Server.Nutrition.EntitySystems;
|
|
using Content.Shared.Cargo.Prototypes;
|
|
using Content.Shared.Mobs.Components;
|
|
using Content.Shared.Prototypes;
|
|
using Content.Shared.Stacks;
|
|
using Content.Shared.Whitelist;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.Map;
|
|
using Robust.Shared.Prototypes;
|
|
|
|
namespace Content.IntegrationTests.Tests;
|
|
|
|
[TestFixture]
|
|
public sealed class CargoTest : GameTest
|
|
{
|
|
private static readonly HashSet<ProtoId<CargoProductPrototype>> Ignored =
|
|
[
|
|
// This is ignored because it is explicitly intended to be able to sell for more than it costs.
|
|
new("FunCrateGambling")
|
|
];
|
|
|
|
[Test]
|
|
public async Task NoCargoOrderArbitrage()
|
|
{
|
|
var pair = Pair;
|
|
var server = pair.Server;
|
|
|
|
var testMap = await pair.CreateTestMap();
|
|
|
|
var entManager = server.ResolveDependency<IEntityManager>();
|
|
var protoManager = server.ResolveDependency<IPrototypeManager>();
|
|
var pricing = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<PricingSystem>();
|
|
|
|
await server.WaitAssertion(() =>
|
|
{
|
|
Assert.Multiple(() =>
|
|
{
|
|
foreach (var proto in protoManager.EnumeratePrototypes<CargoProductPrototype>())
|
|
{
|
|
if (Ignored.Contains(proto.ID))
|
|
continue;
|
|
|
|
var ent = entManager.SpawnEntity(proto.Product, testMap.MapCoords);
|
|
var price = pricing.GetPrice(ent);
|
|
|
|
Assert.That(price, Is.AtMost(proto.Cost), $"Found arbitrage on {proto.ID} cargo product! Cost is {proto.Cost} but sell is {price}!");
|
|
entManager.DeleteEntity(ent);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
[Test]
|
|
public async Task NoCargoBountyArbitrageTest()
|
|
{
|
|
var pair = Pair;
|
|
var server = pair.Server;
|
|
|
|
var testMap = await pair.CreateTestMap();
|
|
|
|
var entManager = server.ResolveDependency<IEntityManager>();
|
|
var mapSystem = server.System<SharedMapSystem>();
|
|
var protoManager = server.ResolveDependency<IPrototypeManager>();
|
|
var cargo = entManager.System<CargoSystem>();
|
|
|
|
var bounties = protoManager.EnumeratePrototypes<CargoBountyPrototype>().ToList();
|
|
|
|
await server.WaitAssertion(() =>
|
|
{
|
|
var mapId = testMap.MapId;
|
|
|
|
Assert.Multiple(() =>
|
|
{
|
|
foreach (var proto in protoManager.EnumeratePrototypes<CargoProductPrototype>())
|
|
{
|
|
var ent = entManager.SpawnEntity(proto.Product, new MapCoordinates(Vector2.Zero, mapId));
|
|
|
|
foreach (var bounty in bounties)
|
|
{
|
|
if (cargo.IsBountyComplete(ent, bounty))
|
|
Assert.That(proto.Cost, Is.GreaterThanOrEqualTo(bounty.Reward), $"Found arbitrage on {bounty.ID} cargo bounty! Product {proto.ID} costs {proto.Cost} but fulfills bounty {bounty.ID} with reward {bounty.Reward}!");
|
|
}
|
|
|
|
entManager.DeleteEntity(ent);
|
|
}
|
|
});
|
|
|
|
mapSystem.DeleteMap(mapId);
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public async Task NoStaticPriceAndStackPrice()
|
|
{
|
|
var pair = Pair;
|
|
var server = pair.Server;
|
|
|
|
var protoManager = server.ProtoMan;
|
|
var compFact = server.ResolveDependency<IComponentFactory>();
|
|
|
|
await server.WaitAssertion(() =>
|
|
{
|
|
var protoIds = protoManager.EnumeratePrototypes<EntityPrototype>()
|
|
.Where(p => !p.Abstract)
|
|
.Where(p => !pair.IsTestPrototype(p))
|
|
.Where(p => p.Components.ContainsKey("StaticPrice"))
|
|
.ToList();
|
|
|
|
foreach (var proto in protoIds)
|
|
{
|
|
// Sanity check
|
|
Assert.That(proto.TryGetComponent<StaticPriceComponent>(out var staticPriceComp, compFact), Is.True);
|
|
|
|
if (proto.TryGetComponent<StackPriceComponent>(out var stackPriceComp, compFact) && stackPriceComp.Price > 0)
|
|
{
|
|
Assert.That(staticPriceComp.Price, Is.EqualTo(0),
|
|
$"The prototype {proto} has a StackPriceComponent and StaticPriceComponent whose values are not compatible with each other.");
|
|
}
|
|
|
|
if (proto.HasComponent<StackComponent>(compFact))
|
|
{
|
|
Assert.That(staticPriceComp.Price, Is.EqualTo(0),
|
|
$"The prototype {proto} has a StackComponent and StaticPriceComponent whose values are not compatible with each other.");
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tests to see if any items that are valid for cargo bounties can be sliced into items that
|
|
/// are also valid for the same bounty entry.
|
|
/// </summary>
|
|
[Test]
|
|
public async Task NoSliceableBountyArbitrageTest()
|
|
{
|
|
var pair = Pair;
|
|
var server = pair.Server;
|
|
|
|
var testMap = await pair.CreateTestMap();
|
|
|
|
var entManager = server.ResolveDependency<IEntityManager>();
|
|
var mapSystem = server.System<SharedMapSystem>();
|
|
var mapManager = server.ResolveDependency<IMapManager>();
|
|
var protoManager = server.ResolveDependency<IPrototypeManager>();
|
|
var componentFactory = server.ResolveDependency<IComponentFactory>();
|
|
var whitelist = entManager.System<EntityWhitelistSystem>();
|
|
var cargo = entManager.System<CargoSystem>();
|
|
var sliceableSys = entManager.System<SliceableFoodSystem>();
|
|
|
|
var bounties = protoManager.EnumeratePrototypes<CargoBountyPrototype>().ToList();
|
|
|
|
await server.WaitAssertion(() =>
|
|
{
|
|
var mapId = testMap.MapId;
|
|
var grid = mapManager.CreateGridEntity(mapId);
|
|
var coord = new EntityCoordinates(grid.Owner, 0, 0);
|
|
|
|
var sliceableEntityProtos = protoManager.EnumeratePrototypes<EntityPrototype>()
|
|
.Where(p => !p.Abstract)
|
|
.Where(p => !pair.IsTestPrototype(p))
|
|
.Where(p => p.TryGetComponent<SliceableFoodComponent>(out _, componentFactory))
|
|
.Select(p => p.ID)
|
|
.ToList();
|
|
|
|
foreach (var proto in sliceableEntityProtos)
|
|
{
|
|
var ent = entManager.SpawnEntity(proto, coord);
|
|
var sliceable = entManager.GetComponent<SliceableFoodComponent>(ent);
|
|
|
|
// Check each bounty
|
|
foreach (var bounty in bounties)
|
|
{
|
|
// Check each entry in the bounty
|
|
foreach (var entry in bounty.Entries)
|
|
{
|
|
// See if the entity counts as part of this bounty entry
|
|
if (!cargo.IsValidBountyEntry(ent, entry))
|
|
continue;
|
|
|
|
// Spawn a slice
|
|
var slice = entManager.SpawnEntity(sliceable.Slice, coord);
|
|
|
|
// See if the slice also counts for this bounty entry
|
|
if (!cargo.IsValidBountyEntry(slice, entry))
|
|
{
|
|
entManager.DeleteEntity(slice);
|
|
continue;
|
|
}
|
|
|
|
entManager.DeleteEntity(slice);
|
|
|
|
// If for some reason it can only make one slice, that's okay, I guess
|
|
Assert.That(sliceable.TotalCount, Is.EqualTo(1), $"{proto} counts as part of cargo bounty {bounty.ID} and slices into {sliceable.TotalCount} slices which count for the same bounty!");
|
|
}
|
|
}
|
|
|
|
entManager.DeleteEntity(ent);
|
|
}
|
|
mapSystem.DeleteMap(mapId);
|
|
});
|
|
}
|
|
|
|
[TestPrototypes]
|
|
private const string StackProto = @"
|
|
- type: stack
|
|
id: StackProto
|
|
name: stack-steel
|
|
spawn: StackEnt
|
|
|
|
- type: entity
|
|
id: StackEnt
|
|
components:
|
|
- type: StackPrice
|
|
price: 20
|
|
- type: Stack
|
|
stackType: StackProto
|
|
count: 5
|
|
";
|
|
|
|
[Test]
|
|
public async Task StackPrice()
|
|
{
|
|
var pair = Pair;
|
|
var server = pair.Server;
|
|
var entManager = server.ResolveDependency<IEntityManager>();
|
|
|
|
await server.WaitAssertion(() =>
|
|
{
|
|
var priceSystem = entManager.System<PricingSystem>();
|
|
|
|
var ent = entManager.SpawnEntity("StackEnt", MapCoordinates.Nullspace);
|
|
var price = priceSystem.GetPrice(ent);
|
|
Assert.That(price, Is.EqualTo(100.0));
|
|
});
|
|
}
|
|
|
|
[Test]
|
|
public async Task MobPrice()
|
|
{
|
|
var pair = Pair;
|
|
|
|
var componentFactory = pair.Server.ResolveDependency<IComponentFactory>();
|
|
|
|
await pair.Server.WaitAssertion(() =>
|
|
{
|
|
Assert.Multiple(() =>
|
|
{
|
|
foreach (var (proto, comp) in pair.GetPrototypesWithComponent<MobPriceComponent>())
|
|
{
|
|
Assert.That(proto.TryGetComponent<MobStateComponent>(out _, componentFactory), $"Found MobPriceComponent on {proto.ID}, but no MobStateComponent!");
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|