using Robust.Shared.Physics.Components;
using Robust.Shared.Prototypes;
using System.Numerics;
+using Robust.Shared.Map;
namespace Content.Server.Fluids.EntitySystems;
base.Initialize();
SubscribeLocalEvent<SprayComponent, AfterInteractEvent>(OnAfterInteract);
+ SubscribeLocalEvent<SprayComponent, UserActivateInWorldEvent>(OnActivateInWorld);
+ }
+
+ private void OnActivateInWorld(Entity<SprayComponent> entity, ref UserActivateInWorldEvent args)
+ {
+ if (args.Handled)
+ return;
+
+ args.Handled = true;
+
+ var targetMapPos = _transform.GetMapCoordinates(GetEntityQuery<TransformComponent>().GetComponent(args.Target));
+
+ Spray(entity, args.User, targetMapPos);
}
private void OnAfterInteract(Entity<SprayComponent> entity, ref AfterInteractEvent args)
args.Handled = true;
+ var clickPos = _transform.ToMapCoordinates(args.ClickLocation);
+
+ Spray(entity, args.User, clickPos);
+ }
+
+ public void Spray(Entity<SprayComponent> entity, EntityUid user, MapCoordinates mapcoord)
+ {
if (!_solutionContainer.TryGetSolution(entity.Owner, SprayComponent.SolutionName, out var soln, out var solution))
return;
- var ev = new SprayAttemptEvent(args.User);
+ var ev = new SprayAttemptEvent(user);
RaiseLocalEvent(entity, ref ev);
if (ev.Cancelled)
return;
- if (!TryComp<UseDelayComponent>(entity, out var useDelay)
- || _useDelay.IsDelayed((entity, useDelay)))
+ if (TryComp<UseDelayComponent>(entity, out var useDelay)
+ && _useDelay.IsDelayed((entity, useDelay)))
return;
if (solution.Volume <= 0)
{
- _popupSystem.PopupEntity(Loc.GetString("spray-component-is-empty-message"), entity.Owner, args.User);
+ _popupSystem.PopupEntity(Loc.GetString("spray-component-is-empty-message"), entity.Owner, user);
return;
}
var xformQuery = GetEntityQuery<TransformComponent>();
- var userXform = xformQuery.GetComponent(args.User);
+ var userXform = xformQuery.GetComponent(user);
var userMapPos = _transform.GetMapCoordinates(userXform);
- var clickMapPos = args.ClickLocation.ToMap(EntityManager, _transform);
+ var clickMapPos = mapcoord;
var diffPos = clickMapPos.Position - userMapPos.Position;
if (diffPos == Vector2.Zero || diffPos == Vector2Helpers.NaN)
var amount = Math.Max(Math.Min((solution.Volume / entity.Comp.TransferAmount).Int(), entity.Comp.VaporAmount), 1);
var spread = entity.Comp.VaporSpread / amount;
- // TODO: Just use usedelay homie.
- var cooldownTime = 0f;
for (var i = 0; i < amount; i++)
{
// impulse direction is defined in world-coordinates, not local coordinates
var impulseDirection = rotation.ToVec();
var time = diffLength / entity.Comp.SprayVelocity;
- cooldownTime = MathF.Max(time, cooldownTime);
- _vapor.Start(ent, vaporXform, impulseDirection * diffLength, entity.Comp.SprayVelocity, target, time, args.User);
+ _vapor.Start(ent, vaporXform, impulseDirection * diffLength, entity.Comp.SprayVelocity, target, time, user);
- if (TryComp<PhysicsComponent>(args.User, out var body))
+ if (TryComp<PhysicsComponent>(user, out var body))
{
- if (_gravity.IsWeightless(args.User, body))
- _physics.ApplyLinearImpulse(args.User, -impulseDirection.Normalized() * entity.Comp.PushbackAmount, body: body);
+ if (_gravity.IsWeightless(user, body))
+ _physics.ApplyLinearImpulse(user, -impulseDirection.Normalized() * entity.Comp.PushbackAmount, body: body);
}
}
_audio.PlayPvs(entity.Comp.SpraySound, entity, entity.Comp.SpraySound.Params.WithVariation(0.125f));
- _useDelay.SetLength(entity.Owner, TimeSpan.FromSeconds(cooldownTime));
- _useDelay.TryResetDelay((entity, useDelay));
+ if (useDelay != null)
+ _useDelay.TryResetDelay((entity, useDelay));
}
}
petting-success-mimebot = You pet {THE($target)} on {POSS-ADJ($target)} cold metal head.
petting-success-cleanbot = You pet {THE($target)} on {POSS-ADJ($target)} damp metal head.
petting-success-medibot = You pet {THE($target)} on {POSS-ADJ($target)} sterile metal head.
+petting-success-firebot = You pet {THE($target)} on {POSS-ADJ($target)} warm metal head.
petting-success-generic-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} metal head.
petting-success-salvage-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} dirty metal head.
petting-success-engineer-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} reflective metal head.
petting-failure-cleanbot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy mopping!
petting-failure-mimebot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy miming!
petting-failure-medibot = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} syringe nearly stabs your hand!
+petting-failure-firebot = You reach out to pet {THE($target)}, but {SUBJECT($target)} sprays you in the face before you can get close!
petting-failure-generic-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy stating laws!
petting-failure-salvage-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy drilling!
petting-failure-engineer-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy repairing!
--- /dev/null
+- type: htnCompound
+ id: FirebotCompound
+ branches:
+ - tasks:
+ - !type:HTNCompoundTask
+ task: DouseFireTargetCompound
+ - tasks:
+ - !type:HTNCompoundTask
+ task: IdleCompound
+
+- type: htnCompound
+ id: DouseFireTargetCompound
+ branches:
+ - tasks:
+ - !type:HTNPrimitiveTask
+ operator: !type:UtilityOperator
+ proto: NearbyOnFire
+
+ - !type:HTNPrimitiveTask
+ operator: !type:SpeakOperator
+ speech: firebot-fire-detected
+ hidden: true
+
+ - !type:HTNPrimitiveTask
+ operator: !type:MoveToOperator
+ pathfindInPlanning: true
+ removeKeyOnFinish: false
+ targetKey: TargetCoordinates
+ pathfindKey: TargetPathfind
+ rangeKey: InteractRange
+
+ - !type:HTNPrimitiveTask
+ preconditions:
+ - !type:TargetInRangePrecondition
+ targetKey: Target
+ rangeKey: InteractRange
+ operator: !type:InteractWithOperator
+ targetKey: Target
+ services:
+ - !type:UtilityService
+ id: FireService
+ proto: NearbyOnFire
+ key: Target
+