* - hugbot
- bdy with two arms because it needs two arms to hug
- is constructable from:
- box of hugs
- proximity sensor
- two borg arms
- lots of voice lines
- kinda like a medibot, it chases you down and then hugs you
- except if it's emagged, then it punches you :)
- it has a 2m cooldown per person by default
- MeleeAttackOperator
- Read the doc, but it's an operator which makes the NPC hit a target exactly once assuming it's in range.
- Used to make the hugbot attack
- RaiseEventForOwnerOperator
- Read the doc, but it's an operator which raises an event on the owning NPC.
- Used to make the hugbot hug extra code, specifically for the cooldown
- Changes to existing code:
- `ComponentFilter : UtilityQueryFilter` gets `RetainWithComp` added which, as the name implies, retains entities with the specified comps rather than removing them. Basically, it lets you negate the filter.
- `SpeakOperator : HTNOperator`'s `speech` field can use a `LocalizedDataSet` instead of just a locstring now
- (I updated all of the existing usages for this)
-
* two arms
* wait what if we just used mimebot arms so it doesn't look awful
* smort
66 lines
2.3 KiB
C#
66 lines
2.3 KiB
C#
using Content.Server.NPC.HTN.PrimitiveTasks.Operators.Specific;
|
|
using Content.Shared.Silicons.Bots;
|
|
using Robust.Shared.Timing;
|
|
|
|
namespace Content.Server.Silicons.Bots;
|
|
|
|
/// <summary>
|
|
/// Beyond what <see cref="SharedHugBotSystem"/> does, this system manages the "lifecycle" of
|
|
/// <see cref="RecentlyHuggedByHugBotComponent"/>.
|
|
/// </summary>
|
|
public sealed class HugBotSystem : SharedHugBotSystem
|
|
{
|
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<HugBotComponent, HTNRaisedEvent>(OnHtnRaisedEvent);
|
|
}
|
|
|
|
private void OnHtnRaisedEvent(Entity<HugBotComponent> entity, ref HTNRaisedEvent args)
|
|
{
|
|
if (args.Args is not HugBotDidHugEvent ||
|
|
args.Target is not {} target)
|
|
return;
|
|
|
|
var ev = new HugBotHugEvent(GetNetEntity(entity));
|
|
RaiseLocalEvent(target, ev);
|
|
|
|
ApplyHugBotCooldown(entity, target);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Applies <see cref="RecentlyHuggedByHugBotComponent"/> to <paramref name="target"/> based on the configuration of
|
|
/// <paramref name="hugBot"/>.
|
|
/// </summary>
|
|
public void ApplyHugBotCooldown(Entity<HugBotComponent> hugBot, EntityUid target)
|
|
{
|
|
var hugged = EnsureComp<RecentlyHuggedByHugBotComponent>(target);
|
|
hugged.CooldownCompleteAfter = _gameTiming.CurTime + hugBot.Comp.HugCooldown;
|
|
}
|
|
|
|
public override void Update(float frameTime)
|
|
{
|
|
// Iterate through all RecentlyHuggedByHugBot entities...
|
|
var huggedEntities = AllEntityQuery<RecentlyHuggedByHugBotComponent>();
|
|
while (huggedEntities.MoveNext(out var huggedEnt, out var huggedComp))
|
|
{
|
|
// ... and if their cooldown is complete...
|
|
if (huggedComp.CooldownCompleteAfter <= _gameTiming.CurTime)
|
|
{
|
|
// ... remove it, allowing them to receive the blessing of hugs once more.
|
|
RemCompDeferred<RecentlyHuggedByHugBotComponent>(huggedEnt);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// This event is indirectly raised (by being <see cref="HTNRaisedEvent.Args"/>) on a HugBot when it hugs (or emaggedly
|
|
/// punches) an entity.
|
|
/// </summary>
|
|
[Serializable, DataDefinition]
|
|
public sealed partial class HugBotDidHugEvent : EntityEventArgs;
|