NanoTrasen might send Gifts to the station via Cargo (#16556)

* Rebase Cargo Gifts

* Remove Chaos values from gifts (for now)

* Translate CargoGifts, rename fields

* Fix gift errors, detect missing products

* Fix order Id, some crate IDs

* Fix get Station. Gifts for Sec, Med, Fire, spacing

* Minimum players for various gifts

# Conflicts:
#	Resources/Prototypes/GameRules/cargo_gifts.yml
This commit is contained in:
Tom Leys
2023-05-23 09:55:27 +12:00
committed by GitHub
parent d45e48b149
commit db81e59013
10 changed files with 514 additions and 6 deletions

View File

@@ -14,6 +14,7 @@ using Content.Shared.Cargo.Prototypes;
using Content.Shared.Database;
using Content.Shared.GameTicking;
using Content.Server.Paper;
using Content.Shared.Access.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Players;
@@ -243,7 +244,7 @@ namespace Content.Server.Cargo.Systems
return new CargoOrderData(id, args.ProductId, args.Amount, args.Requester, args.Reason);
}
private int GetOutstandingOrderCount(StationCargoOrderDatabaseComponent component)
public int GetOutstandingOrderCount(StationCargoOrderDatabaseComponent component)
{
var amount = 0;
@@ -285,7 +286,31 @@ namespace Content.Server.Cargo.Systems
}
}
public bool TryAddOrder(StationCargoOrderDatabaseComponent component, CargoOrderData data)
public bool AddAndApproveOrder(StationCargoOrderDatabaseComponent component, string productId, int qty, string sender, string description, string dest)
{
if (!_prototypeManager.HasIndex<CargoProductPrototype>(productId))
{
_sawmill.Warning($"CargoSystem.Orders could not find CargoProductPrototype for '{productId}' in {description}.");
// Pretend that it worked OK, since we don't want the caller to try again.
return true;
}
// Make an order
var id = GenerateOrderId(component);
var order = new CargoOrderData(id, productId, qty, sender, description);
// Approve it now
order.SetApproverData(new IdCardComponent(){FullName = dest, JobTitle = sender});
// Log order addition
_adminLogger.Add(LogType.Action, LogImpact.Low,
$"AddAndApproveOrder {description} added order [orderId:{order.OrderId}, quantity:{order.OrderQuantity}, product:{order.ProductId}, requester:{order.Requester}, reason:{order.Reason}]");
// Add it to the list
return TryAddOrder(component, order);
}
private bool TryAddOrder(StationCargoOrderDatabaseComponent component, CargoOrderData data)
{
component.Orders.Add(data);
UpdateOrders(component);
@@ -294,7 +319,7 @@ namespace Content.Server.Cargo.Systems
private int GenerateOrderId(StationCargoOrderDatabaseComponent orderDB)
{
// We need an arbitrary unique ID to idenitfy orders, since they may
// We need an arbitrary unique ID to identify orders, since they may
// want to be cancelled later.
return ++orderDB.NumOrdersCreated;
}

View File

@@ -282,7 +282,7 @@ public sealed partial class CargoSystem
var numToShip = order.OrderQuantity - order.NumDispatched;
if (numToShip > spaceRemaining)
{
// We won't be able to fit the whole oder on, so make one
// We won't be able to fit the whole order on, so make one
// which represents the space we do have left:
var reducedOrder = new CargoOrderData(order.OrderId,
order.ProductId, spaceRemaining, order.Requester, order.Reason);

View File

@@ -0,0 +1,55 @@
using Content.Server.StationEvents.Events;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.StationEvents.Components;
/// <summary>
/// Used an event that gifts the station with certian cargo
/// </summary>
[RegisterComponent, Access(typeof(CargoGiftsRule))]
public sealed class CargoGiftsRuleComponent : Component
{
/// <summary>
/// The base announcement string (which then incorporates the strings below)
/// </summary>
[DataField("announce"), ViewVariables(VVAccess.ReadWrite)]
public string Announce = "cargo-gifts-event-announcement";
/// <summary>
/// What is being sent
/// </summary>
[DataField("description"), ViewVariables(VVAccess.ReadWrite)]
public string Description = "cargo-gift-default-description";
/// <summary>
/// Sender of the gifts
/// </summary>
[DataField("sender"), ViewVariables(VVAccess.ReadWrite)]
public string Sender = "cargo-gift-default-sender";
/// <summary>
/// Destination of the gifts (who they get sent to on the station)
/// </summary>
[DataField("dest"), ViewVariables(VVAccess.ReadWrite)]
public string Dest = "cargo-gift-default-dest";
/// <summary>
/// Cargo that you would like gifted to the station, with the quantity for each
/// Use Ids from cargoProduct Prototypes
/// </summary>
[DataField("gifts"), ViewVariables(VVAccess.ReadWrite)]
public Dictionary<string, int> Gifts = new Dictionary<string, int>();
/// <summary>
/// How much space (minimum) you want to leave in the order database for supply to actually do their work
/// </summary>
[DataField("orderSpaceToLeave"), ViewVariables(VVAccess.ReadWrite)]
public int OrderSpaceToLeave = 5;
/// <summary>
/// Time until we consider next lot of gifts (if supply is overflowing with orders)
/// </summary>
[DataField("timeUntilNextGifts"), ViewVariables(VVAccess.ReadWrite)]
public float TimeUntilNextGifts = 10.0f;
}

View File

@@ -0,0 +1,84 @@
using System.Linq;
using Content.Server.Anomaly;
using Content.Server.Cargo.Components;
using Content.Server.Cargo.Systems;
using Content.Server.GameTicking;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Server.StationEvents.Components;
using Content.Shared.Access.Components;
using Content.Shared.Administration.Logs;
using Content.Shared.Cargo;
using Content.Shared.Cargo.Prototypes;
using Content.Shared.Database;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Utility;
namespace Content.Server.StationEvents.Events;
public sealed class CargoGiftsRule : StationEventSystem<CargoGiftsRuleComponent>
{
[Dependency] private readonly CargoSystem _cargoSystem = default!;
[Dependency] private readonly StationSystem _stationSystem = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly GameTicker _ticker = default!;
protected override void Added(EntityUid uid, CargoGiftsRuleComponent component, GameRuleComponent gameRule, GameRuleAddedEvent args)
{
base.Added(uid, component, gameRule, args);
var str = Loc.GetString(component.Announce,
("sender", Loc.GetString(component.Sender)), ("description", Loc.GetString(component.Description)), ("dest", Loc.GetString(component.Dest)));
ChatSystem.DispatchGlobalAnnouncement(str, colorOverride: Color.FromHex("#18abf5"));
}
/// <summary>
/// Called on an active gamerule entity in the Update function
/// </summary>
protected override void ActiveTick(EntityUid uid, CargoGiftsRuleComponent component, GameRuleComponent gameRule, float frameTime)
{
if (component.Gifts.Count == 0)
{
return;
}
if (component.TimeUntilNextGifts > 0)
{
component.TimeUntilNextGifts -= frameTime;
return;
}
component.TimeUntilNextGifts = 30f;
if (!TryGetRandomStation(out var station, HasComp<StationCargoOrderDatabaseComponent>))
return;
if (!TryComp<StationCargoOrderDatabaseComponent>(station, out var cargoDb))
{
return;
}
// Add some presents
int outstanding = _cargoSystem.GetOutstandingOrderCount(cargoDb);
while (outstanding < cargoDb.Capacity - component.OrderSpaceToLeave && component.Gifts.Count > 0)
{
// I wish there was a nice way to pop this
var (productId, qty) = component.Gifts.First();
component.Gifts.Remove(productId);
if (!_cargoSystem.AddAndApproveOrder(cargoDb, productId, qty, Loc.GetString(component.Sender), Loc.GetString(component.Description), Loc.GetString(component.Dest)))
{
break;
}
}
if (component.Gifts.Count == 0)
{
// We're done here!
_ticker.EndGameRule(uid, gameRule);
}
}
}

View File

@@ -0,0 +1,23 @@
cargo-gifts-event-announcement = Congratulations! { $sender } has decided to send { $description } to the station { $dest }. Look for it in your next cargo shipment.
cargo-gift-default-description = A bundle of gifts
cargo-gift-default-sender = NanoTrasen
cargo-gift-default-dest = Cargo Dept.
cargo-gift-dest-bar = bar
cargo-gift-dest-eng = Engineering Dept
cargo-gift-dest-supp = Cargo Dept
cargo-gift-dest-janitor = Service Dept
cargo-gift-dest-med = Medical Dept
cargo-gift-dest-sec = Security Dept
cargo-gift-pizza-small = A small pizza party
cargo-gift-pizza-large = A large pizza party
cargo-gift-eng = Repair Materials
cargo-gift-vending = Vending machines refills
cargo-gift-cleaning = Cleaning equipment
cargo-gift-medical-supply = Medical supplies
cargo-gift-space-protection = Space Hazard Protection
cargo-gift-fire-protection = Fire Protection
cargo-gift-security-guns = Lethal Weapons
cargo-gift-security-riot = Riot Gear

View File

@@ -28,6 +28,16 @@
category: Emergency
group: market
- type: cargoProduct
id: EmergencyInternalsLarge
icon:
sprite: Clothing/Mask/breath.rsi
state: icon
product: CrateEmergencyInternalsLarge
cost: 2000
category: Emergency
group: market
- type: cargoProduct
id: EmergencyRadiation
icon:

View File

@@ -8,6 +8,16 @@
category: Food
group: market
- type: cargoProduct
id: FoodPizzaLarge
icon:
sprite: Objects/Consumable/Food/Baked/pizza.rsi
state: margherita
product: CrateFoodPizzaLarge
cost: 1800
category: Food
group: market
- type: cargoProduct
id: FoodMRE
icon:
@@ -47,3 +57,23 @@
cost: 750
category: Food
group: market
- type: cargoProduct
id: FoodSoftdrinks
icon:
sprite: Objects/Consumable/Drinks/beerglass.rsi
state: icon
product: CrateFoodSoftdrinks
cost: 1200
category: Food
group: market
- type: cargoProduct
id: FoodSoftdrinksLarge
icon:
sprite: Objects/Consumable/Drinks/beerglass.rsi
state: icon
product: CrateFoodSoftdrinksLarge
cost: 2400
category: Food
group: market

View File

@@ -33,6 +33,7 @@
- type: entity
id: CrateEmergencyInternals
parent: CrateInternals
name: Emergency Suits
components:
- type: StorageFill
contents:
@@ -42,11 +43,29 @@
amount: 3
- id: OxygenTankFilled
amount: 3
- id: EmergencyOxygenTankFilled
- id: NitrogenTankFilled
amount: 3
- id: ClothingOuterSuitEmergency
amount: 3
- type: entity
id: CrateEmergencyInternalsLarge
parent: CrateInternals
name: Emergency Suits (Large)
components:
- type: StorageFill
contents:
- id: ClothingMaskGas
amount: 12
- id: ClothingMaskBreath
amount: 12
- id: OxygenTankFilled
amount: 12
- id: NitrogenTankFilled
amount: 12
- id: ClothingOuterSuitEmergency
amount: 12
- type: entity
id: CrateSlimepersonLifeSupport
parent: CrateInternals

View File

@@ -10,6 +10,19 @@
- id: LidSalami
prob: 0.01
- type: entity
id: CrateFoodPizzaLarge
parent: CratePlastic
components:
- type: StorageFill
contents:
- id: FoodBoxPizzaFilled
amount: 16
- id: KnifePlastic
amount: 4
- id: LidSalami
prob: 0.04
- type: entity
id: CrateFoodMRE
parent: CratePlastic
@@ -91,3 +104,42 @@
amount: 2
- id: DrinkCreamCarton
amount: 2
- type: entity
id: CrateFoodSoftdrinks
parent: CratePlastic
components:
- type: StorageFill
contents:
- id: DrinkColaCan
amount: 4
- id: DrinkGrapeCan
amount: 2
- id: DrinkRootBeerCan
amount: 2
- id: DrinkIcedTeaCan
amount: 2
- id: DrinkLemonLimeCan
amount: 2
- id: DrinkFourteenLokoCan
amount: 2
- type: entity
id: CrateFoodSoftdrinksLarge
parent: CratePlastic
components:
- type: StorageFill
contents:
- id: DrinkColaCan
amount: 8
- id: DrinkGrapeCan
amount: 4
- id: DrinkRootBeerCan
amount: 4
- id: DrinkIcedTeaCan
amount: 4
- id: DrinkLemonLimeCan
amount: 4
- id: DrinkFourteenLokoCan
amount: 4

View File

@@ -0,0 +1,210 @@
- type: entity
id: GiftsPizzaPartySmall
parent: BaseGameRule
noSpawn: true
components:
- type: StationEvent
weight: 10
startDelay: 10
duration: 120
earliestStart: 20
- type: CargoGiftsRule
description: cargo-gift-pizza-small
sender: cargo-gift-default-sender
dest: cargo-gift-dest-bar
gifts:
FoodPizzaLarge: 1 # 16 pizzas
FoodBarSupply: 1
FoodSoftdrinks: 1
CrateVendingMachineRestockRobustSoftdrinks: 1
- type: entity
id: GiftsPizzaPartyLarge
parent: BaseGameRule
noSpawn: true
components:
- type: StationEvent
weight: 6
startDelay: 10
duration: 240
minimumPlayers: 50
earliestStart: 40
- type: CargoGiftsRule
description: cargo-gift-pizza-large
sender: cargo-gift-default-sender
dest: cargo-gift-dest-bar
gifts:
FoodPizzaLarge: 4 # 64 pizzas
FoodBarSupply: 1
FoodSoftdrinksLarge: 1
- type: entity
id: GiftsEngineering
parent: BaseGameRule
noSpawn: true
components:
- type: StationEvent
weight: 4
startDelay: 10
duration: 240
earliestStart: 30
minimumPlayers: 10
- type: CargoGiftsRule
description: cargo-gift-eng
sender: cargo-gift-default-sender
dest: cargo-gift-dest-eng
gifts:
EngineeringCableBulk: 1
AirlockKit: 1
MaterialSteel: 1
MaterialPlasteel: 1
MaterialGlass: 1
CrateVendingMachineRestockEngineering: 1
- type: entity
id: GiftsVendingRestock
parent: BaseGameRule
noSpawn: true
components:
- type: StationEvent
weight: 4
startDelay: 10
duration: 120
minimumPlayers: 40
earliestStart: 30
- type: CargoGiftsRule
description: cargo-gift-vending
sender: cargo-gift-default-sender
dest: cargo-gift-dest-supp
gifts:
CrateVendingMachineRestockHotDrinks: 3
CrateVendingMachineRestockBooze: 1
CrateVendingMachineRestockNutriMax: 1
CrateVendingMachineRestockRobustSoftdrinks: 2
CrateVendingMachineRestockVendomat: 1
CrateVendingMachineRestockGetmoreChocolateCorp: 1
- type: entity
id: GiftsJanitor
parent: BaseGameRule
noSpawn: true
components:
- type: StationEvent
weight: 8
startDelay: 10
duration: 120
minimumPlayers: 30
earliestStart: 20
- type: CargoGiftsRule
description: cargo-gift-cleaning
sender: cargo-gift-default-sender
dest: cargo-gift-dest-janitor
gifts:
ServiceJanitorial: 2
ServiceLightsReplacement: 2
ServiceJanitorBiosuit: 1
- type: entity
id: GiftsMedical
parent: BaseGameRule
noSpawn: true
components:
- type: StationEvent
weight: 8
startDelay: 10
duration: 120
earliestStart: 20
minimumPlayers: 30
- type: CargoGiftsRule
description: cargo-gift-medical-supply
sender: cargo-gift-default-sender
dest: cargo-gift-dest-med
gifts:
MedicalSupplies: 1
MedicalChemistrySupplies: 1
EmergencyBruteKit: 1
EmergencyAdvancedKit: 1
MedicalBiosuit: 1
- type: entity
id: GiftsSpacingSupplies
parent: BaseGameRule
noSpawn: true
components:
- type: StationEvent
weight: 6
startDelay: 10
duration: 120
earliestStart: 10
minimumPlayers: 40
- type: CargoGiftsRule
description: cargo-gift-space-protection
sender: cargo-gift-default-sender
dest: cargo-gift-dest-supp
gifts:
EmergencyInternalsLarge: 2
EmergencyInflatablewall: 1
EmergencyAdvancedKit: 1
MedicalBiosuit: 1
EmergencyO2Kit: 1
- type: entity
id: GiftsFireProtection
parent: BaseGameRule
noSpawn: true
components:
- type: StationEvent
weight: 3
startDelay: 10
duration: 120
earliestStart: 20
minimumPlayers: 40
- type: CargoGiftsRule
description: cargo-gift-fire-protection
sender: cargo-gift-default-sender
dest: cargo-gift-dest-supp
gifts:
EmergencyFire: 2
EmergencyBurnKit: 1
EmergencyBruteKit: 1
- type: entity
id: GiftsSecurityGuns
parent: BaseGameRule
noSpawn: true
components:
- type: StationEvent
weight: 2
startDelay: 10
duration: 120
earliestStart: 20
minimumPlayers: 50
- type: CargoGiftsRule
description: cargo-gift-security-guns
sender: cargo-gift-default-sender
dest: cargo-gift-dest-sec
gifts:
CrateSecurityArmor: 3
ArmorySmg: 1
ArmoryShotgun: 1
ArmoryLaser: 1
- type: entity
id: GiftsSecurityRiot
parent: BaseGameRule
noSpawn: true
components:
- type: StationEvent
weight: 4
startDelay: 10
duration: 120
earliestStart: 20
minimumPlayers: 50
- type: CargoGiftsRule
description: cargo-gift-security-riot
sender: cargo-gift-default-sender
dest: cargo-gift-dest-sec
gifts:
SecurityRiot: 2
CrateRestraints: 2
CrateSecurityNonlethal: 2