mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 18:31:17 +03:00
* SpawnAtPosition gaming * SpawnAtPosition gaming: gun edition * spawnnexttoordrop, restore unused gun dep.
134 lines
5.1 KiB
C#
134 lines
5.1 KiB
C#
using Content.Shared.Actions;
|
|
using Content.Shared.Cloning.Events;
|
|
using Content.Shared.DoAfter;
|
|
using Content.Shared.Nutrition.EntitySystems;
|
|
using Robust.Shared.Serialization;
|
|
using Content.Shared.Popups;
|
|
using Robust.Shared.Network;
|
|
using Content.Shared.Nutrition.Components;
|
|
using Content.Shared.Stacks;
|
|
|
|
namespace Content.Shared.Sericulture;
|
|
|
|
/// <summary>
|
|
/// Allows mobs to produce materials with <see cref="SericultureComponent"/>.
|
|
/// </summary>
|
|
public abstract partial class SharedSericultureSystem : EntitySystem
|
|
{
|
|
// Managers
|
|
[Dependency] private INetManager _netManager = default!;
|
|
|
|
// Systems
|
|
[Dependency] private SharedActionsSystem _actionsSystem = default!;
|
|
[Dependency] private SharedDoAfterSystem _doAfterSystem = default!;
|
|
[Dependency] private HungerSystem _hungerSystem = default!;
|
|
[Dependency] private SharedPopupSystem _popupSystem = default!;
|
|
[Dependency] private SharedStackSystem _stackSystem = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<SericultureComponent, MapInitEvent>(OnMapInit);
|
|
SubscribeLocalEvent<SericultureComponent, ComponentShutdown>(OnCompRemove);
|
|
SubscribeLocalEvent<SericultureComponent, SericultureActionEvent>(OnSericultureStart);
|
|
SubscribeLocalEvent<SericultureComponent, SericultureDoAfterEvent>(OnSericultureDoAfter);
|
|
SubscribeLocalEvent<SericultureComponent, CloningEvent>(OnClone);
|
|
}
|
|
|
|
private void OnClone(Entity<SericultureComponent> ent, ref CloningEvent args)
|
|
{
|
|
if (!args.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name))
|
|
return;
|
|
|
|
// Make sure to set the datafields before adding the component so that the correct action gets spawned on map init.
|
|
var cloneComp = Factory.GetComponent<SericultureComponent>();
|
|
cloneComp.PopupText = ent.Comp.PopupText;
|
|
cloneComp.EntityProduced = ent.Comp.EntityProduced;
|
|
cloneComp.Action = ent.Comp.Action;
|
|
cloneComp.ProductionLength = ent.Comp.ProductionLength;
|
|
cloneComp.HungerCost = ent.Comp.HungerCost;
|
|
cloneComp.MinHungerThreshold = ent.Comp.MinHungerThreshold;
|
|
AddComp(args.CloneUid, cloneComp, true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Giveths the action to preform sericulture on the entity
|
|
/// </summary>
|
|
private void OnMapInit(EntityUid uid, SericultureComponent comp, MapInitEvent args)
|
|
{
|
|
_actionsSystem.AddAction(uid, ref comp.ActionEntity, comp.Action);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Takeths away the action to preform sericulture from the entity.
|
|
/// </summary>
|
|
private void OnCompRemove(EntityUid uid, SericultureComponent comp, ComponentShutdown args)
|
|
{
|
|
_actionsSystem.RemoveAction(uid, comp.ActionEntity);
|
|
}
|
|
|
|
private void OnSericultureStart(EntityUid uid, SericultureComponent comp, SericultureActionEvent args)
|
|
{
|
|
if (!TryComp<HungerComponent>(uid, out var hungerComp)
|
|
|| _hungerSystem.IsHungerBelowState(uid,
|
|
comp.MinHungerThreshold,
|
|
_hungerSystem.GetHunger(hungerComp) - comp.HungerCost,
|
|
hungerComp))
|
|
{
|
|
_popupSystem.PopupEntity(Loc.GetString(comp.PopupText), uid, uid);
|
|
return;
|
|
}
|
|
|
|
var doAfter = new DoAfterArgs(EntityManager, uid, comp.ProductionLength, new SericultureDoAfterEvent(), uid)
|
|
{ // I'm not sure if more things should be put here, but imo ideally it should probably be set in the component/YAML. Not sure if this is currently possible.
|
|
BreakOnMove = true,
|
|
BlockDuplicate = true,
|
|
BreakOnDamage = true,
|
|
CancelDuplicate = true,
|
|
};
|
|
|
|
_doAfterSystem.TryStartDoAfter(doAfter);
|
|
}
|
|
|
|
|
|
private void OnSericultureDoAfter(EntityUid uid, SericultureComponent comp, SericultureDoAfterEvent args)
|
|
{
|
|
if (args.Cancelled || args.Handled || comp.Deleted)
|
|
return;
|
|
|
|
if (!TryComp<HungerComponent>(uid,
|
|
out var hungerComp) // A check, just incase the doafter is somehow performed when the entity is not in the right hunger state.
|
|
|| _hungerSystem.IsHungerBelowState(uid,
|
|
comp.MinHungerThreshold,
|
|
_hungerSystem.GetHunger(hungerComp) - comp.HungerCost,
|
|
hungerComp))
|
|
{
|
|
_popupSystem.PopupEntity(Loc.GetString(comp.PopupText), uid, uid);
|
|
return;
|
|
}
|
|
|
|
_hungerSystem.ModifyHunger(uid, -comp.HungerCost, hungerComp);
|
|
|
|
if (!_netManager.IsClient) // Have to do this because spawning stuff in shared is CBT.
|
|
{
|
|
var newEntity = SpawnNextToOrDrop(comp.EntityProduced, uid);
|
|
|
|
_stackSystem.TryMergeToHands(newEntity, uid);
|
|
}
|
|
|
|
args.Repeat = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Should be relayed upon using the action.
|
|
/// </summary>
|
|
public sealed partial class SericultureActionEvent : InstantActionEvent { }
|
|
|
|
/// <summary>
|
|
/// Is relayed at the end of the sericulturing doafter.
|
|
/// </summary>
|
|
[Serializable, NetSerializable]
|
|
public sealed partial class SericultureDoAfterEvent : SimpleDoAfterEvent { }
|
|
|