Files
tbd-station-14/Content.Server/Storage/EntitySystems/SpawnItemsOnUseSystem.cs
brainfood1183 e4d5e7f1ae Spray Paint (Review Ready) (#23003)
* Spray Paint (Draft)

* paint colors, paints in maints loot, cargo crate of paints.

* fix

* remove paint (sort of)

* moved paintcleaner into own system

* Moved paint to server (had to unfortunately)

* doafter now breaks when moving away.

* cant paint mobstatecomp

* loads of fixes

* fixes

* fixes

* nopaintshadercomp

* fixes

* fix

* use locale for paint remove string

* remove nopaintshadercomponent and use blacklist

* remove enabled.true from visualizer

* paint doafter event.

* add verbs for paint and remove paint and icon for paint verb.

* fixes

* no longer replaces shader when shader exists.

* replace forloop with foreach, check shader before adding and removing.

* paint doafter now separate so no copy paste code

* Entities in sprayed targets item slots are also now correctly sprayed.

* fix

* fix

* fix airlock psray painter now removes painted before painting door.

* spray paints now use openablecomponent.

* fix

* fix damn accesstypes.

* fix

* fix
2024-03-18 15:29:48 -06:00

100 lines
3.7 KiB
C#

using Content.Server.Administration.Logs;
using Content.Server.Cargo.Systems;
using Content.Server.Storage.Components;
using Content.Shared.Database;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction.Events;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Random;
using static Content.Shared.Storage.EntitySpawnCollection;
namespace Content.Server.Storage.EntitySystems
{
public sealed class SpawnItemsOnUseSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly PricingSystem _pricing = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SpawnItemsOnUseComponent, UseInHandEvent>(OnUseInHand);
SubscribeLocalEvent<SpawnItemsOnUseComponent, PriceCalculationEvent>(CalculatePrice, before: new[] { typeof(PricingSystem) });
}
private void CalculatePrice(EntityUid uid, SpawnItemsOnUseComponent component, ref PriceCalculationEvent args)
{
var ungrouped = CollectOrGroups(component.Items, out var orGroups);
foreach (var entry in ungrouped)
{
var protUid = Spawn(entry.PrototypeId, MapCoordinates.Nullspace);
// Calculate the average price of the possible spawned items
args.Price += _pricing.GetPrice(protUid) * entry.SpawnProbability * entry.GetAmount(getAverage: true);
EntityManager.DeleteEntity(protUid);
}
foreach (var group in orGroups)
{
foreach (var entry in group.Entries)
{
var protUid = Spawn(entry.PrototypeId, MapCoordinates.Nullspace);
// Calculate the average price of the possible spawned items
args.Price += _pricing.GetPrice(protUid) *
(entry.SpawnProbability / group.CumulativeProbability) *
entry.GetAmount(getAverage: true);
EntityManager.DeleteEntity(protUid);
}
}
args.Handled = true;
}
private void OnUseInHand(EntityUid uid, SpawnItemsOnUseComponent component, UseInHandEvent args)
{
if (args.Handled)
return;
// If starting with zero or less uses, this component is a no-op
if (component.Uses <= 0)
return;
var coords = Transform(args.User).Coordinates;
var spawnEntities = GetSpawns(component.Items, _random);
EntityUid? entityToPlaceInHands = null;
foreach (var proto in spawnEntities)
{
entityToPlaceInHands = Spawn(proto, coords);
_adminLogger.Add(LogType.EntitySpawn, LogImpact.Low, $"{ToPrettyString(args.User)} used {ToPrettyString(uid)} which spawned {ToPrettyString(entityToPlaceInHands.Value)}");
}
component.Uses--;
// Delete entity only if component was successfully used
if (component.Uses <= 0)
{
args.Handled = true;
EntityManager.DeleteEntity(uid);
}
if (entityToPlaceInHands != null)
{
_hands.PickupOrDrop(args.User, entityToPlaceInHands.Value);
_audio.PlayPvs(component.Sound, entityToPlaceInHands.Value);
}
}
}
}