Files
crystall-punk-14/Content.Shared/_CP14/Workplace/CP14SharedWorkplaceSystem.cs
2025-05-22 21:39:36 +03:00

149 lines
4.7 KiB
C#

using Content.Shared.UserInterface;
using Robust.Shared.Prototypes;
namespace Content.Shared._CP14.Workplace;
public abstract partial class CP14SharedWorkplaceSystem : EntitySystem
{
[Dependency] private readonly SharedUserInterfaceSystem _userInterface = default!;
[Dependency] private readonly IPrototypeManager _proto = default!;
/// <summary>
/// All recipes are stored here in the dictionary.
/// These are by design readonly entities for which events are called to collect information on them.
/// </summary>
private Dictionary<EntProtoId, Entity<CP14WorkplaceRecipeComponent>> _cachedRecipes = new();
public override void Initialize()
{
base.Initialize();
CacheAllRecipes();
SubscribeLocalEvent<CP14WorkplaceComponent, BeforeActivatableUIOpenEvent>(OnBeforeUIOpen);
SubscribeLocalEvent<CP14WorkplaceComponent, CP14WorkplaceCraftMessage>(OnCraftAttempt);
SubscribeLocalEvent<CP14WorkplaceComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<PrototypesReloadedEventArgs>(OnPrototypeReload);
}
private void OnBeforeUIOpen(Entity<CP14WorkplaceComponent> ent, ref BeforeActivatableUIOpenEvent args)
{
UpdateUIState(ent, args.User);
}
private void OnCraftAttempt(Entity<CP14WorkplaceComponent> ent, ref CP14WorkplaceCraftMessage args)
{
if (!_cachedRecipes.TryGetValue(args.Recipe, out var cachedRecipe))
return;
if (!ent.Comp.CachedRecipes.Contains(cachedRecipe))
return;
}
private void OnMapInit(Entity<CP14WorkplaceComponent> ent, ref MapInitEvent args)
{
CacheWorkplaceRecipes(ent);
}
private void OnPrototypeReload(PrototypesReloadedEventArgs ev)
{
if (!ev.WasModified<EntityPrototype>())
return;
CacheAllRecipes();
var query = EntityQueryEnumerator<CP14WorkplaceComponent>();
while (query.MoveNext(out var uid, out var workplace))
{
CacheWorkplaceRecipes((uid, workplace));
}
}
private void UpdateUIState(Entity<CP14WorkplaceComponent> entity, EntityUid user)
{
var recipes = new List<CP14WorkplaceRecipeEntry>();
foreach (var recipe in entity.Comp.CachedRecipes)
{
var proto = MetaData(recipe).EntityPrototype;
if (proto is null)
continue;
var entry = new CP14WorkplaceRecipeEntry(proto);
recipes.Add(entry);
}
_userInterface.SetUiState(entity.Owner, CP14WorkplaceUiKey.Key, new CP14WorkplaceState(GetNetEntity(user), GetNetEntity(entity), recipes));
}
public bool CheckCraftable(EntProtoId recipe, EntityUid? workplace, EntityUid? user)
{
if (!TryComp<CP14WorkplaceComponent>(workplace, out var workplaceComp))
return false;
if (!_cachedRecipes.TryGetValue(recipe, out var cachedRecipe))
return false;
return CheckCraftable(cachedRecipe, workplace, user);
}
public bool CheckCraftable(EntityUid recipe, EntityUid? workplace, EntityUid? user)
{
if (user is null || workplace is null)
return false;
var ev = new CP14WorkplaceRequirementsPass(user.Value, workplace.Value, recipe);
RaiseLocalEvent(recipe, ev);
if (ev.Cancelled)
return false;
return true;
}
private void CacheAllRecipes()
{
//Delete all old cached recipes entity
foreach (var recipe in _cachedRecipes.Values)
{
QueueDel(recipe);
}
var allEnts = _proto.EnumeratePrototypes<EntityPrototype>();
foreach (var recipe in allEnts)
{
if (!recipe.Components.TryGetComponent(CP14WorkplaceRecipeComponent.CompName, out var compData) || compData is not CP14WorkplaceRecipeComponent recipeComp)
continue;
if (_cachedRecipes.ContainsKey(recipe.ID))
continue;
var ent = Spawn(recipe.ID);
var entComp = EnsureComp<CP14WorkplaceRecipeComponent>(ent);
_cachedRecipes.Add(recipe.ID, (ent, entComp));
}
}
private void CacheWorkplaceRecipes(Entity<CP14WorkplaceComponent> entity)
{
entity.Comp.CachedRecipes.Clear();
foreach (var recipe in _cachedRecipes.Values)
{
if (!entity.Comp.Tags.Contains(recipe.Comp.Tag))
continue;
entity.Comp.CachedRecipes.Add(recipe);
}
}
}
public sealed class CP14WorkplaceRequirementsPass(EntityUid user, EntityUid workplace, EntityUid recipe)
: CancellableEntityEventArgs
{
public EntityUid User { get; } = user;
public EntityUid Workplace { get; } = workplace;
public EntityUid Recipe { get; } = recipe;
}