Skip to content

Commit

Permalink
Merge pull request #247 from TGRCdev/revenant-animate-action
Browse files Browse the repository at this point in the history
Added the revenant Animate action
  • Loading branch information
formlessnameless authored Sep 14, 2024
2 parents 1dbf5f8 + 7d00480 commit 161d448
Show file tree
Hide file tree
Showing 30 changed files with 815 additions and 9 deletions.
20 changes: 20 additions & 0 deletions Content.Client/Revenant/RevenantAnimatedComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Robust.Client.GameObjects;
using Robust.Shared.GameStates;

namespace Content.Client.Revenant;

[RegisterComponent, NetworkedComponent]
public sealed partial class RevenantAnimatedComponent : Component
{
[DataField, ViewVariables(VVAccess.ReadOnly)]
public float Accumulator = 0f;

[DataField, ViewVariables(VVAccess.ReadOnly)]
public Entity<PointLightComponent>? LightOverlay;

[DataField, ViewVariables(VVAccess.ReadWrite)]
public Color LightColor = Color.MediumPurple;

[DataField, ViewVariables(VVAccess.ReadWrite)]
public float LightRadius = 2f;
}
50 changes: 50 additions & 0 deletions Content.Client/Revenant/RevenantAnimatedSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Robust.Client.GameObjects;
using Robust.Shared.Map;

namespace Content.Client.Revenant;

public sealed class RevenantAnimatedSystem : EntitySystem
{
[Dependency] private readonly SharedPointLightSystem _lights = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<RevenantAnimatedComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<RevenantAnimatedComponent, ComponentShutdown>(OnShutdown);
}

public override void Update(float frameTime)
{
base.Update(frameTime);

var enumerator = EntityQueryEnumerator<RevenantAnimatedComponent>();

while (enumerator.MoveNext(out var uid, out var comp))
{
if (comp.LightOverlay == null)
continue;
comp.Accumulator += frameTime;
_lights.SetEnergy(comp.LightOverlay.Value.Owner, 2f * Math.Abs((float)Math.Sin(0.25 * Math.PI * comp.Accumulator)), comp.LightOverlay.Value.Comp);
}
}

private void OnStartup(EntityUid uid, RevenantAnimatedComponent comp, ComponentStartup args)
{
var lightEnt = Spawn(null, new EntityCoordinates(uid, 0, 0));
var light = AddComp<PointLightComponent>(lightEnt);

comp.LightOverlay = (lightEnt, light);

_lights.SetEnabled(lightEnt, true, light);
_lights.SetColor(lightEnt, comp.LightColor, light);
_lights.SetRadius(lightEnt, comp.LightRadius, light);
}

private void OnShutdown(EntityUid uid, RevenantAnimatedComponent comp, ComponentShutdown args)
{
if (comp.LightOverlay != null)
Del(comp.LightOverlay);
}
}
42 changes: 42 additions & 0 deletions Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using Content.Server.Hands.Systems;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.Revenant.Components;
using Content.Server.Revenant.EntitySystems;
using Content.Server.Stack;
using Content.Server.Station.Components;
using Content.Server.Station.Systems;
Expand All @@ -25,6 +27,7 @@
using Content.Shared.Doors.Components;
using Content.Shared.Hands.Components;
using Content.Shared.Inventory;
using Content.Shared.Item;
using Content.Shared.PDA;
using Content.Shared.Stacks;
using Content.Shared.Verbs;
Expand Down Expand Up @@ -55,6 +58,7 @@ public sealed partial class AdminVerbSystem
[Dependency] private readonly SharedTransformSystem _xformSystem = default!;
[Dependency] private readonly MetaDataSystem _metaSystem = default!;
[Dependency] private readonly GunSystem _gun = default!;
[Dependency] private readonly RevenantAnimatedSystem _revenantAnimate = default!;

private void AddTricksVerbs(GetVerbsEvent<Verb> args)
{
Expand Down Expand Up @@ -734,6 +738,42 @@ private void AddTricksVerbs(GetVerbsEvent<Verb> args)
};
args.Verbs.Add(setCapacity);
}

if (TryComp<ItemComponent>(args.Target, out var item))
{
Verb makeAnimate = new()
{
Text = "Animate Item",
Category = VerbCategory.Tricks,
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/Actions/animate.png")),
Act = () =>
{
_revenantAnimate.TryAnimateObject(args.Target, TimeSpan.FromSeconds(60));
},
Impact = LogImpact.High,
Message = Loc.GetString("admin-trick-make-animate-description"),
Priority = (int) TricksVerbPriorities.MakeAnimate,
};
args.Verbs.Add(makeAnimate);
}

if (TryComp<RevenantAnimatedComponent>(args.Target, out var animate))
{
Verb makeInanimate = new()
{
Text = "Inanimate Item",
Category = VerbCategory.Tricks,
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/Actions/inanimate.png")),
Act = () =>
{
_revenantAnimate.InanimateTarget(args.Target, animate);
},
Impact = LogImpact.High,
Message = Loc.GetString("admin-trick-make-inanimate-description"),
Priority = (int) TricksVerbPriorities.MakeInanimate,
};
args.Verbs.Add(makeInanimate);
}
}

private void RefillEquippedTanks(EntityUid target, Gas gasType)
Expand Down Expand Up @@ -879,5 +919,7 @@ public enum TricksVerbPriorities
SnapJoints = -27,
MakeMinigun = -28,
SetBulletAmount = -29,
MakeAnimate = -30,
MakeInanimate = -31,
}
}
15 changes: 15 additions & 0 deletions Content.Server/Explosion/EntitySystems/TriggerSystem.OnUse.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Content.Server.Explosion.Components;
using Content.Shared.Examine;
using Content.Shared.Explosion.Components;
using Content.Shared.Interaction;
using Content.Shared.Interaction.Events;
using Content.Shared.Popups;
using Content.Shared.Sticky;
Expand All @@ -15,12 +16,26 @@ public sealed partial class TriggerSystem
private void InitializeOnUse()
{
SubscribeLocalEvent<OnUseTimerTriggerComponent, UseInHandEvent>(OnTimerUse);
SubscribeLocalEvent<OnUseTimerTriggerComponent, UserActivateInWorldEvent>(OnUseSelf);
SubscribeLocalEvent<OnUseTimerTriggerComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<OnUseTimerTriggerComponent, GetVerbsEvent<AlternativeVerb>>(OnGetAltVerbs);
SubscribeLocalEvent<OnUseTimerTriggerComponent, EntityStuckEvent>(OnStuck);
SubscribeLocalEvent<RandomTimerTriggerComponent, MapInitEvent>(OnRandomTimerTriggerMapInit);
}

private void OnUseSelf(EntityUid uid, OnUseTimerTriggerComponent comp, UserActivateInWorldEvent args)
{
// Allow grenades to activate themselves (if they're posessed or ghost role)

if (args.Handled)
return;

if (args.Target != uid)
return;

StartTimer((uid, comp), uid);
}

private void OnStuck(EntityUid uid, OnUseTimerTriggerComponent component, ref EntityStuckEvent args)
{
if (!component.StartOnStick)
Expand Down
25 changes: 25 additions & 0 deletions Content.Server/NPC/HTN/Preconditions/ActiveTimerPrecondition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Content.Shared.Explosion.Components;

namespace Content.Server.NPC.HTN.Preconditions;

/// <summary>
/// Checks for the presence of <see cref="ActiveTimerTriggerComponent"/>
/// </summary>
public sealed partial class ActiveTimerPrecondition : HTNPrecondition
{
[Dependency] private readonly IEntityManager _entManager = default!;

/// <summary>
/// When true, passes this precondition when the entity has an active timer.
/// Otherwise, passes this precondition when the entity does not have an active timer.
/// </summary>
[DataField]
public bool Active = true;

public override bool IsMet(NPCBlackboard blackboard)
{
var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);

return Active == _entManager.HasComponent<ActiveTimerTriggerComponent>(owner);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public override bool IsMet(NPCBlackboard blackboard)
{
var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);

return IsInContainer && _container.IsEntityInContainer(owner) ||
!IsInContainer && !_container.IsEntityInContainer(owner);
return IsInContainer == _container.IsEntityInContainer(owner);
}
}
20 changes: 20 additions & 0 deletions Content.Server/NPC/HTN/Preconditions/ThrownPrecondition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Content.Shared.Throwing;

namespace Content.Server.NPC.HTN.Preconditions;

/// <summary>
/// Checks if the owner is being thrown or not
/// </summary>
public sealed partial class ThrownPrecondition : HTNPrecondition
{
[Dependency] private readonly IEntityManager _entMan = default!;

[ViewVariables(VVAccess.ReadWrite)] [DataField] public bool IsBeingThrown = true;

public override bool IsMet(NPCBlackboard blackboard)
{
var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);

return IsBeingThrown == _entMan.HasComponent<ThrownItemComponent>(owner);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;

namespace Content.Server.NPC.HTN.PrimitiveTasks.Operators.Interactions;

public sealed partial class InteractionActivateSelfOperator : HTNOperator
{
[Dependency] private readonly IEntityManager _entManager = default!;

/// <summary>
/// If this alt-interaction started a do_after where does the key get stored.
/// </summary>
[DataField("idleKey")]
public string IdleKey = "IdleTime";

public override async Task<(bool Valid, Dictionary<string, object>? Effects)> Plan(NPCBlackboard blackboard, CancellationToken cancelToken)
{
return new(true, new Dictionary<string, object>()
{
{ IdleKey, 1f }
});
}

public override HTNOperatorStatus Update(NPCBlackboard blackboard, float frameTime)
{
var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);
var intSystem = _entManager.System<SharedInteractionSystem>();
var count = 0;

if (_entManager.TryGetComponent<DoAfterComponent>(owner, out var doAfter))
{
count = doAfter.DoAfters.Count;
}

var result = intSystem.InteractionActivate(owner, owner);

// Interaction started a doafter so set the idle time to it.
if (result && doAfter != null && count != doAfter.DoAfters.Count)
{
var wait = doAfter.DoAfters.First().Value.Args.Delay;
blackboard.SetValue(IdleKey, (float) wait.TotalSeconds + 0.5f);
}
else
{
blackboard.SetValue(IdleKey, 1f);
}

return result ? HTNOperatorStatus.Finished : HTNOperatorStatus.Failed;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;

namespace Content.Server.NPC.HTN.PrimitiveTasks.Operators.Interactions;

public sealed partial class InteractionActivateTargetOperator : HTNOperator
{
[Dependency] private readonly IEntityManager _entManager = default!;

[DataField("targetKey")]
public string Key = "Target";

/// <summary>
/// If this alt-interaction started a do_after where does the key get stored.
/// </summary>
[DataField("idleKey")]
public string IdleKey = "IdleTime";

public override async Task<(bool Valid, Dictionary<string, object>? Effects)> Plan(NPCBlackboard blackboard, CancellationToken cancelToken)
{
return new(true, new Dictionary<string, object>()
{
{ IdleKey, 1f }
});
}

public override HTNOperatorStatus Update(NPCBlackboard blackboard, float frameTime)
{
var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);
var target = blackboard.GetValue<EntityUid>(Key);
var intSystem = _entManager.System<SharedInteractionSystem>();
var count = 0;

if (_entManager.TryGetComponent<DoAfterComponent>(owner, out var doAfter))
{
count = doAfter.DoAfters.Count;
}

var result = intSystem.InteractionActivate(owner, target);

// Interaction started a doafter so set the idle time to it.
if (result && doAfter != null && count != doAfter.DoAfters.Count)
{
var wait = doAfter.DoAfters.First().Value.Args.Delay;
blackboard.SetValue(IdleKey, (float) wait.TotalSeconds + 0.5f);
}
else
{
blackboard.SetValue(IdleKey, 1f);
}

return result ? HTNOperatorStatus.Finished : HTNOperatorStatus.Failed;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using Content.Shared.Inventory;

namespace Content.Server.NPC.HTN.PrimitiveTasks.Operators.Interactions;

public sealed partial class JumpInSlotsOperator : HTNOperator
{
private InventorySystem _inventory = default!;

[DataField("targetKey")]
public string Key = "Target";

/// <summary>
/// If true, a failed attempt to jump into slots will still return <see cref="HTNOperatorStatus.Finished"/>
/// </summary>
[DataField]
public bool IgnoreFail = false;

public override void Initialize(IEntitySystemManager sysManager)
{
base.Initialize(sysManager);

_inventory = sysManager.GetEntitySystem<InventorySystem>();
}

public override HTNOperatorStatus Update(NPCBlackboard blackboard, float frameTime)
{
var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);
var target = blackboard.GetValue<EntityUid>(Key);

var result = _inventory.TryJumpIntoSlots(owner, target);

return result || IgnoreFail ? HTNOperatorStatus.Finished : HTNOperatorStatus.Failed;
}
}
Loading

0 comments on commit 161d448

Please sign in to comment.