Make InteractUsing async, make tools use DoAfter. (#1772)

* Make IInteractUsing async, make tools use DoAfter.

* Disable warning 1998 in Content.Server

* Update Content.Server/GameObjects/Components/AnchorableComponent.cs
This commit is contained in:
Víctor Aguilera Puerto
2020-08-18 14:39:08 +02:00
committed by GitHub
parent bbdfe44224
commit d9ae942759
45 changed files with 195 additions and 100 deletions

View File

@@ -66,7 +66,7 @@ namespace Content.IntegrationTests.Tests.Disposal
DisposalUnitComponent unit;
DisposalEntryComponent entry;
server.Assert(() =>
server.Assert(async () =>
{
var mapManager = IoCManager.Resolve<IMapManager>();
@@ -86,14 +86,14 @@ namespace Content.IntegrationTests.Tests.Disposal
// Can't insert, unanchored and unpowered
var disposalUnitAnchorable = disposalUnit.GetComponent<AnchorableComponent>();
disposalUnitAnchorable.TryUnAnchor(human, null, true);
await disposalUnitAnchorable.TryUnAnchor(human, null, true);
Assert.False(unit.Anchored);
UnitInsertContains(unit, false, human, wrench, disposalUnit, disposalTrunk);
// Anchor the disposal unit
disposalUnitAnchorable.TryAnchor(human, null, true);
await disposalUnitAnchorable.TryAnchor(human, null, true);
Assert.True(disposalUnit.TryGetComponent(out AnchorableComponent anchorableUnit));
Assert.True(anchorableUnit.TryAnchor(human, wrench));
Assert.True(await anchorableUnit.TryAnchor(human, wrench));
Assert.True(unit.Anchored);
// No power

View File

@@ -9,6 +9,7 @@
<OutputPath>..\bin\Content.Server\</OutputPath>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<OutputType Condition="'$(FullRelease)' != 'True'">Exe</OutputType>
<NoWarn>1998</NoWarn>
</PropertyGroup>
<Import Project="..\RobustToolbox\MSBuild\Robust.DefineConstants.targets" />
<ItemGroup>

View File

@@ -1,5 +1,6 @@
#nullable enable
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Interactable;
using Content.Shared.GameObjects.Components.Interactable;
using Content.Shared.Interfaces.GameObjects.Components;
@@ -21,12 +22,12 @@ namespace Content.Server.GameObjects.Components
/// </summary>
/// <param name="user">The user doing the action</param>
/// <param name="utilizing">The tool being used, can be null if forcing it</param>
/// <param name="collidable">The physics component of the owning entity</param>
/// <param name="collidable">The collidable component of the owning entity</param>
/// <param name="force">Whether or not to check if the tool is valid</param>
/// <returns>true if it is valid, false otherwise</returns>
private bool Valid(IEntity user, IEntity? utilizing, [MaybeNullWhen(false)] out ICollidableComponent collidable, bool force = false)
private async Task<bool> Valid(IEntity user, IEntity? utilizing, [MaybeNullWhen(false)] bool force = false)
{
if (!Owner.TryGetComponent(out collidable))
if (!Owner.HasComponent<ICollidableComponent>())
{
return false;
}
@@ -35,7 +36,7 @@ namespace Content.Server.GameObjects.Components
{
if (utilizing == null ||
!utilizing.TryGetComponent(out ToolComponent tool) ||
!tool.UseTool(user, Owner, ToolQuality.Anchoring))
!(await tool.UseTool(user, Owner, 0.5f, ToolQuality.Anchoring)))
{
return false;
}
@@ -51,13 +52,14 @@ namespace Content.Server.GameObjects.Components
/// <param name="utilizing">The tool being used, if any</param>
/// <param name="force">Whether or not to ignore valid tool checks</param>
/// <returns>true if anchored, false otherwise</returns>
public bool TryAnchor(IEntity user, IEntity? utilizing = null, bool force = false)
public async Task<bool> TryAnchor(IEntity user, IEntity? utilizing = null, bool force = false)
{
if (!Valid(user, utilizing, out var physics, force))
if (!(await Valid(user, utilizing, force)))
{
return false;
}
var physics = Owner.GetComponent<ICollidableComponent>();
physics.Anchored = true;
return true;
@@ -70,13 +72,14 @@ namespace Content.Server.GameObjects.Components
/// <param name="utilizing">The tool being used, if any</param>
/// <param name="force">Whether or not to ignore valid tool checks</param>
/// <returns>true if unanchored, false otherwise</returns>
public bool TryUnAnchor(IEntity user, IEntity? utilizing = null, bool force = false)
public async Task<bool> TryUnAnchor(IEntity user, IEntity? utilizing = null, bool force = false)
{
if (!Valid(user, utilizing, out var physics, force))
if (!(await Valid(user, utilizing, force)))
{
return false;
}
var physics = Owner.GetComponent<ICollidableComponent>();
physics.Anchored = false;
return true;
@@ -89,7 +92,7 @@ namespace Content.Server.GameObjects.Components
/// <param name="utilizing">The tool being used, if any</param>
/// <param name="force">Whether or not to ignore valid tool checks</param>
/// <returns>true if toggled, false otherwise</returns>
private bool TryToggleAnchor(IEntity user, IEntity? utilizing = null, bool force = false)
private async Task<bool> TryToggleAnchor(IEntity user, IEntity? utilizing = null, bool force = false)
{
if (!Owner.TryGetComponent(out ICollidableComponent collidable))
{
@@ -97,8 +100,8 @@ namespace Content.Server.GameObjects.Components
}
return collidable.Anchored ?
TryUnAnchor(user, utilizing, force) :
TryAnchor(user, utilizing, force);
await TryUnAnchor(user, utilizing, force) :
await TryAnchor(user, utilizing, force);
}
public override void Initialize()
@@ -107,9 +110,9 @@ namespace Content.Server.GameObjects.Components
Owner.EnsureComponent<CollidableComponent>();
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
return TryToggleAnchor(eventArgs.User, eventArgs.Using);
return await TryToggleAnchor(eventArgs.User, eventArgs.Using);
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
@@ -376,7 +377,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
/// </summary>
/// <param name="args">Data relevant to the event such as the actor which triggered it.</param>
/// <returns></returns>
bool IInteractUsing.InteractUsing(InteractUsingEventArgs args)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs args)
{
if (!args.User.TryGetComponent(out IHandsComponent hands))
{

View File

@@ -1,4 +1,5 @@
using Content.Server.Interfaces;
using System.Threading.Tasks;
using Content.Server.Interfaces;
using Content.Shared.Chemistry;
using Content.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.GameObjects;
@@ -50,7 +51,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
/// </summary>
/// <param name="eventArgs">Attack event args</param>
/// <returns></returns>
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
//Get target solution component
if (!Owner.TryGetComponent<SolutionComponent>(out var targetSolution))

View File

@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
@@ -290,7 +291,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
/// </summary>
/// <param name="args">Data relevant to the event such as the actor which triggered it.</param>
/// <returns></returns>
bool IInteractUsing.InteractUsing(InteractUsingEventArgs args)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs args)
{
if (!args.User.TryGetComponent(out IHandsComponent hands))
{

View File

@@ -1,6 +1,7 @@
#nullable enable
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Interactable;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
@@ -162,10 +163,10 @@ namespace Content.Server.GameObjects.Components.Conveyor
}
}
private bool ToolUsed(IEntity user, ToolComponent tool)
private async Task<bool> ToolUsed(IEntity user, ToolComponent tool)
{
if (!Owner.HasComponent<ItemComponent>() &&
tool.UseTool(user, Owner, ToolQuality.Prying))
await tool.UseTool(user, Owner, 0.5f, ToolQuality.Prying))
{
State = ConveyorState.Loose;
@@ -244,7 +245,7 @@ namespace Content.Server.GameObjects.Components.Conveyor
Disconnect();
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
if (eventArgs.Using.TryGetComponent(out ConveyorSwitchComponent conveyorSwitch))
{
@@ -254,7 +255,7 @@ namespace Content.Server.GameObjects.Components.Conveyor
if (eventArgs.Using.TryGetComponent(out ToolComponent tool))
{
return ToolUsed(eventArgs.User, tool);
return await ToolUsed(eventArgs.User, tool);
}
return false;

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.EntitySystems;
using Content.Shared.GameObjects.Components.Conveyor;
using Content.Shared.Interfaces;
@@ -193,7 +194,7 @@ namespace Content.Server.GameObjects.Components.Conveyor
return NextState();
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
if (eventArgs.Using.TryGetComponent(out ConveyorComponent conveyor))
{

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Interactable;
using Content.Shared.Damage;
using Content.Shared.GameObjects.Components.Interactable;
@@ -32,7 +33,7 @@ namespace Content.Server.GameObjects.Components.Damage
Owner.EnsureComponent<DestructibleComponent>();
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
if (eventArgs.Using.TryGetComponent<ToolComponent>(out var tool))
{

View File

@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
@@ -568,7 +569,7 @@ namespace Content.Server.GameObjects.Components.Disposal
return true;
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
return TryDrop(eventArgs.User, eventArgs.Using);
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Interactable;
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
using Content.Server.GameObjects.Components.VendingMachines;
@@ -379,7 +380,7 @@ namespace Content.Server.GameObjects.Components.Doors
return _powerReceiver.Powered;
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!eventArgs.Using.TryGetComponent<ToolComponent>(out var tool))
return false;
@@ -397,23 +398,28 @@ namespace Content.Server.GameObjects.Components.Doors
}
}
if (!tool.UseTool(eventArgs.User, Owner, ToolQuality.Prying)) return false;
bool AirlockCheck()
{
if (IsBolted())
{
var notify = IoCManager.Resolve<IServerNotifyManager>();
notify.PopupMessage(Owner, eventArgs.User,
Loc.GetString("The airlock's bolts prevent it from being forced!"));
return true;
return false;
}
if (IsPowered())
{
var notify = IoCManager.Resolve<IServerNotifyManager>();
notify.PopupMessage(Owner, eventArgs.User, Loc.GetString("The powered motors block your efforts!"));
return false;
}
return true;
}
if (!await tool.UseTool(eventArgs.User, Owner, 3f, ToolQuality.Prying, AirlockCheck)) return false;
if (State == DoorState.Closed)
Open();
else if (State == DoorState.Open)

View File

@@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Chemistry;
using Content.Shared.Chemistry;
using Content.Shared.Interfaces;
@@ -70,7 +71,7 @@ namespace Content.Server.GameObjects.Components.Fluids
return true;
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!eventArgs.Using.TryGetComponent(out MopComponent mopComponent))
{

View File

@@ -1,4 +1,5 @@
using Content.Server.GameObjects.Components.Damage;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Damage;
using Content.Server.GameObjects.Components.Interactable;
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
using Content.Server.GameObjects.EntitySystems;
@@ -98,12 +99,12 @@ namespace Content.Server.GameObjects.Components.Gravity
return true;
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!eventArgs.Using.TryGetComponent(out WelderComponent tool))
return false;
if (!tool.UseTool(eventArgs.User, Owner, ToolQuality.Welding, 5f))
if (!await tool.UseTool(eventArgs.User, Owner, 2f, ToolQuality.Welding, 5f))
return false;
// Repair generator

View File

@@ -1,4 +1,5 @@
using Content.Server.GameObjects.Components.GUI;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Clothing;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Power;
@@ -57,7 +58,7 @@ namespace Content.Server.GameObjects.Components.Interactable
[ViewVariables]
public bool Activated { get; private set; }
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!eventArgs.Using.HasComponent<BatteryComponent>()) return false;

View File

@@ -34,7 +34,7 @@ namespace Content.Server.GameObjects.Components.Interactable
serializer.DataField(ref _toolComponentNeeded, "toolComponentNeeded", true);
}
public void TryPryTile(IEntity user, GridCoordinates clickLocation)
public async void TryPryTile(IEntity user, GridCoordinates clickLocation)
{
if (!Owner.TryGetComponent<ToolComponent>(out var tool) && _toolComponentNeeded)
return;
@@ -51,7 +51,7 @@ namespace Content.Server.GameObjects.Components.Interactable
if (!tileDef.CanCrowbar) return;
if (_toolComponentNeeded && !tool.UseTool(user, null, ToolQuality.Prying))
if (_toolComponentNeeded && !await tool!.UseTool(user, null, 0f, ToolQuality.Prying))
return;
var underplating = _tileDefinitionManager["underplating"];

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.EntitySystems.DoAfter;
using Content.Shared.Audio;
using Content.Shared.GameObjects.Components.Interactable;
using Content.Shared.GameObjects.EntitySystems;
@@ -89,11 +91,31 @@ namespace Content.Server.GameObjects.Components.Interactable
serializer.DataField(this, collection => UseSoundCollection, "useSoundCollection", string.Empty);
}
public virtual bool UseTool(IEntity user, IEntity target, ToolQuality toolQualityNeeded)
public virtual async Task<bool> UseTool(IEntity user, IEntity target, float doAfterDelay, ToolQuality toolQualityNeeded, Func<bool> doAfterCheck = null)
{
if (!HasQuality(toolQualityNeeded) || !ActionBlockerSystem.CanInteract(user))
return false;
if (doAfterDelay > 0f)
{
var doAfterSystem = EntitySystem.Get<DoAfterSystem>();
var doAfterArgs = new DoAfterEventArgs(user, doAfterDelay / SpeedModifier, default, target)
{
ExtraCheck = doAfterCheck,
BreakOnDamage = false, // TODO: Change this to true once breathing is fixed.
BreakOnStun = true,
BreakOnTargetMove = true,
BreakOnUserMove = true,
NeedHand = true,
};
var result = await doAfterSystem.DoAfter(doAfterArgs);
if (result == DoAfterStatus.Cancelled)
return false;
}
PlayUseSound();
return true;

View File

@@ -1,5 +1,6 @@
#nullable enable
using System;
using System.Threading.Tasks;
using Content.Server.Atmos;
using Content.Server.GameObjects.Components.Chemistry;
using Content.Server.GameObjects.Components.Items.Storage;
@@ -97,16 +98,37 @@ namespace Content.Server.GameObjects.Components.Interactable
return new WelderComponentState(FuelCapacity, Fuel, WelderLit);
}
public override bool UseTool(IEntity user, IEntity target, ToolQuality toolQualityNeeded)
public override async Task<bool> UseTool(IEntity user, IEntity target, float doAfterDelay, ToolQuality toolQualityNeeded, Func<bool>? doAfterCheck = null)
{
var canUse = base.UseTool(user, target, toolQualityNeeded);
bool ExtraCheck()
{
var extraCheck = doAfterCheck?.Invoke() ?? true;
if (!CanWeld(DefaultFuelCost))
{
_notifyManager.PopupMessage(target, user, "Can't weld!");
return false;
}
return extraCheck;
}
var canUse = await base.UseTool(user, target, doAfterDelay, toolQualityNeeded, ExtraCheck);
return toolQualityNeeded.HasFlag(ToolQuality.Welding) ? canUse && TryWeld(DefaultFuelCost, user) : canUse;
}
public bool UseTool(IEntity user, IEntity target, ToolQuality toolQualityNeeded, float fuelConsumed)
public async Task<bool> UseTool(IEntity user, IEntity target, float doAfterDelay, ToolQuality toolQualityNeeded, float fuelConsumed, Func<bool>? doAfterCheck = null)
{
return base.UseTool(user, target, toolQualityNeeded) && TryWeld(fuelConsumed, user);
bool ExtraCheck()
{
var extraCheck = doAfterCheck?.Invoke() ?? true;
return extraCheck && CanWeld(fuelConsumed);
}
return await base.UseTool(user, target, doAfterDelay, toolQualityNeeded, ExtraCheck) && TryWeld(fuelConsumed, user);
}
private bool TryWeld(float value, IEntity? user = null, bool silent = false)
@@ -236,7 +258,7 @@ namespace Content.Server.GameObjects.Components.Interactable
if (TryWeld(5, victim, silent: true))
{
PlaySoundCollection(WeldSoundCollection);
chat.EntityMe(victim, Loc.GetString("welds {0:their} every orifice closed! It looks like {0:theyre} trying to commit suicide!", victim)); //TODO: theyre macro
chat.EntityMe(victim, Loc.GetString("welds {0:their} every orifice closed! It looks like {0:theyre} trying to commit suicide!", victim));
return SuicideKind.Heat;
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Body;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Interactable;
@@ -359,7 +360,7 @@ namespace Content.Server.GameObjects.Components.Items.Storage
return Contents.CanInsert(entity);
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
if (Open)
@@ -377,10 +378,9 @@ namespace Content.Server.GameObjects.Components.Items.Storage
if (!eventArgs.Using.TryGetComponent(out WelderComponent tool))
return false;
if (!tool.UseTool(eventArgs.User, Owner, ToolQuality.Welding, 1f))
if (!await tool.UseTool(eventArgs.User, Owner, 1f, ToolQuality.Welding, 1f))
return false;
IsWeldedShut ^= true;
return true;
}

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces.GameObjects.Components.Items;
@@ -435,7 +436,7 @@ namespace Content.Server.GameObjects.Components.Items.Storage
/// </summary>
/// <param name="eventArgs"></param>
/// <returns>true if inserted, false otherwise</returns>
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
Logger.DebugS(LoggerName, $"Storage (UID {Owner.Uid}) attacked by user (UID {eventArgs.User.Uid}) with entity (UID {eventArgs.Using.Uid}).");

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Body;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
@@ -206,7 +207,7 @@ namespace Content.Server.GameObjects.Components.Kitchen
_userInterface.Open(actor.playerSession);
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!_powered)
{

View File

@@ -1,4 +1,5 @@
using Content.Server.GameObjects.Components.Weapon.Melee;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Weapon.Melee;
using Content.Shared.GameObjects.Components.Damage;
using Content.Shared.Damage;
using Content.Shared.Interfaces.GameObjects.Components;
@@ -30,7 +31,7 @@ namespace Content.Server.GameObjects.Components.Mining
spriteComponent.LayerSetState(0, _random.Pick(SpriteStates));
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
var item = eventArgs.Using;
if (!item.TryGetComponent(out MeleeWeaponComponent meleeWeaponComponent)) return false;

View File

@@ -3,6 +3,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Access;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
@@ -143,7 +144,7 @@ namespace Content.Server.GameObjects.Components.PDA
_appearance?.SetData(PDAVisuals.ScreenLit, _lightOn);
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
var item = eventArgs.Using;
if (!IdSlotEmpty)

View File

@@ -1,4 +1,5 @@
using Content.Shared.GameObjects.Components;
using System.Threading.Tasks;
using Content.Shared.GameObjects.Components;
using Content.Shared.GameObjects.EntitySystems;
using Content.Shared.Interfaces.GameObjects.Components;
using Robust.Server.GameObjects;
@@ -66,7 +67,7 @@ namespace Content.Server.GameObjects.Components.Paper
UpdateUserInterface();
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!eventArgs.Using.HasComponent<WriteComponent>())
return false;

View File

@@ -1,4 +1,5 @@
using Content.Server.GameObjects.Components.GUI;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Shared.GameObjects.Components;
using Content.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.GameObjects;
@@ -21,7 +22,8 @@ namespace Content.Server.GameObjects.Components
serializer.DataField(ref _isPlaceable, "IsPlaceable", true);
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!IsPlaceable)
return false;

View File

@@ -1,3 +1,4 @@
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.Interfaces.GameObjects.Components.Items;
@@ -30,7 +31,7 @@ namespace Content.Server.GameObjects.Components
ContainerManagerComponent.Ensure<ContainerSlot>("potted_plant_hide", Owner, out _);
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
if (_itemContainer.ContainedEntity != null)
{

View File

@@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
@@ -65,7 +66,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
base.OnRemove();
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
var result = TryInsertItem(eventArgs.Using);
if (!result)

View File

@@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Mobs;
@@ -69,7 +70,7 @@ namespace Content.Server.GameObjects.Components.Power.ApcNetComponents.PowerRece
}
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
return InsertBulb(eventArgs.Using);
}

View File

@@ -1,4 +1,5 @@
using Content.Server.GameObjects.Components.Interactable;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Interactable;
using Content.Server.GameObjects.Components.Stack;
using Content.Shared.GameObjects.Components.Interactable;
using Content.Shared.Interfaces.GameObjects.Components;
@@ -34,10 +35,10 @@ namespace Content.Server.GameObjects.Components.Power
serializer.DataField(ref _wireType, "wireType", WireType.HighVoltage);
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!eventArgs.Using.TryGetComponent(out ToolComponent tool)) return false;
if (!tool.UseTool(eventArgs.User, Owner, ToolQuality.Cutting)) return false;
if (!await tool.UseTool(eventArgs.User, Owner, 0.25f, ToolQuality.Cutting)) return false;
Owner.Delete();
var droppedEnt = Owner.EntityManager.SpawnEntity(_wireDroppedOnCutPrototype, eventArgs.ClickLocation);

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Power.ApcNetComponents;
using Content.Server.GameObjects.Components.Stack;
using Content.Shared.GameObjects.Components.Materials;
@@ -149,7 +150,8 @@ namespace Content.Server.GameObjects.Components.Research
OpenUserInterface(actor.playerSession);
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!Owner.TryGetComponent(out MaterialStorageComponent storage)
|| !eventArgs.Using.TryGetComponent(out MaterialComponent material)) return false;

View File

@@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using Content.Shared.GameObjects.Components;
using Content.Shared.GameObjects.EntitySystems;
using Content.Shared.Interfaces;
@@ -61,7 +62,7 @@ namespace Content.Server.GameObjects.Components.Stack
return false;
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
if (eventArgs.Using.TryGetComponent<StackComponent>(out var stack))
{

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Mobs;
@@ -192,7 +193,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee
return true;
}
public bool InteractUsing(InteractUsingEventArgs eventArgs)
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!eventArgs.Using.HasComponent<BatteryComponent>()) return false;

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
@@ -119,7 +120,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
return true;
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
if (eventArgs.Using.HasComponent<AmmoComponent>())
{

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
@@ -136,7 +137,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
return ammo;
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
return TryInsertAmmo(eventArgs.User, eventArgs.Using);
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Weapon.Ranged.Barrels;
@@ -204,7 +205,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition
}
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
return TryInsertAmmo(eventArgs.User, eventArgs.Using);
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
using Content.Shared.GameObjects.EntitySystems;
@@ -291,7 +292,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
return true;
}
public override bool InteractUsing(InteractUsingEventArgs eventArgs)
public override async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
return TryInsertBullet(eventArgs.User, eventArgs.Using);
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
using Content.Shared.Interfaces;
@@ -206,7 +207,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
return true;
}
public override bool InteractUsing(InteractUsingEventArgs eventArgs)
public override async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
return TryInsertBullet(eventArgs);
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
using Content.Shared.GameObjects.Components.Weapons.Ranged.Barrels;
using Content.Shared.GameObjects.EntitySystems;
@@ -231,7 +232,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
return true;
}
public override bool InteractUsing(InteractUsingEventArgs eventArgs)
public override async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
return TryInsertBullet(eventArgs.User, eventArgs.Using);
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Power;
@@ -260,7 +261,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
return true;
}
public override bool InteractUsing(InteractUsingEventArgs eventArgs)
public override async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!eventArgs.Using.HasComponent<BatteryComponent>())
{

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Items.Storage;
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
@@ -344,7 +345,7 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
UpdateAppearance();
}
public override bool InteractUsing(InteractUsingEventArgs eventArgs)
public override async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
{
// Insert magazine
if (eventArgs.Using.TryGetComponent(out RangedMagazineComponent magazineComponent))

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Projectiles;
using Content.Server.GameObjects.Components.Weapon.Ranged.Ammunition;
@@ -186,7 +187,8 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Barrels
}
public abstract bool UseEntity(UseEntityEventArgs eventArgs);
public abstract bool InteractUsing(InteractUsingEventArgs eventArgs);
public abstract Task<bool> InteractUsing(InteractUsingEventArgs eventArgs);
public void ChangeFireSelector(FireRateSelector rateSelector)
{

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Interactable;
using Content.Server.GameObjects.Components.VendingMachines;
using Content.Server.GameObjects.EntitySystems;
@@ -468,11 +469,11 @@ namespace Content.Server.GameObjects.Components
serializer.DataField(ref _layoutId, "LayoutId", null);
}
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
{
if (!eventArgs.Using.TryGetComponent<ToolComponent>(out var tool))
return false;
if (!tool.UseTool(eventArgs.User, Owner, ToolQuality.Screwing))
if (!await tool.UseTool(eventArgs.User, Owner, 0.5f, ToolQuality.Screwing))
return false;
IsPanelOpen = !IsPanelOpen;

View File

@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Movement;
@@ -438,7 +439,7 @@ namespace Content.Server.GameObjects.EntitySystems.Click
/// Uses a weapon/object on an entity
/// Finds components with the InteractUsing interface and calls their function
/// </summary>
public void Interaction(IEntity user, IEntity weapon, IEntity attacked, GridCoordinates clickLocation)
public async Task Interaction(IEntity user, IEntity weapon, IEntity attacked, GridCoordinates clickLocation)
{
var attackMsg = new InteractUsingMessage(user, weapon, attacked, clickLocation);
RaiseLocalEvent(attackMsg);
@@ -458,7 +459,7 @@ namespace Content.Server.GameObjects.EntitySystems.Click
{
foreach (var attackBy in attackBys)
{
if (attackBy.InteractUsing(attackByEventArgs))
if (await attackBy.InteractUsing(attackByEventArgs))
{
// If an InteractUsing returns a status completion we finish our attack
return;

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Content.Server.GameObjects.Components.Construction;
using Content.Server.GameObjects.Components.GUI;
using Content.Server.GameObjects.Components.Interactable;
@@ -76,7 +77,7 @@ namespace Content.Server.GameObjects.EntitySystems
TryStartItemConstruction(placingEnt, msg.PrototypeName);
}
private void HandleToolInteraction(AfterInteractMessage msg)
private async void HandleToolInteraction(AfterInteractMessage msg)
{
if(msg.Handled)
return;
@@ -104,7 +105,7 @@ namespace Content.Server.GameObjects.EntitySystems
// the target entity is in the process of being constructed/deconstructed
if (msg.Attacked.TryGetComponent<ConstructionComponent>(out var constructComp))
{
var result = TryConstructEntity(constructComp, handEnt, msg.User);
var result = await TryConstructEntity(constructComp, handEnt, msg.User);
// TryConstructEntity may delete the existing entity
@@ -367,7 +368,7 @@ namespace Content.Server.GameObjects.EntitySystems
}
}
private bool TryConstructEntity(ConstructionComponent constructionComponent, IEntity handTool, IEntity user)
private async Task<bool> TryConstructEntity(ConstructionComponent constructionComponent, IEntity handTool, IEntity user)
{
var constructEntity = constructionComponent.Owner;
var spriteComponent = constructEntity.GetComponent<SpriteComponent>();
@@ -384,7 +385,7 @@ namespace Content.Server.GameObjects.EntitySystems
var stage = constructPrototype.Stages[constructionComponent.Stage];
if (TryProcessStep(constructEntity, stage.Forward, handTool, user, transformComponent.GridPosition))
if (await TryProcessStep(constructEntity, stage.Forward, handTool, user, transformComponent.GridPosition))
{
constructionComponent.Stage++;
if (constructionComponent.Stage == constructPrototype.Stages.Count - 1)
@@ -406,7 +407,7 @@ namespace Content.Server.GameObjects.EntitySystems
}
}
else if (TryProcessStep(constructEntity, stage.Backward, handTool, user, transformComponent.GridPosition))
else if (await TryProcessStep(constructEntity, stage.Backward, handTool, user, transformComponent.GridPosition))
{
constructionComponent.Stage--;
stage = constructPrototype.Stages[constructionComponent.Stage];
@@ -443,7 +444,7 @@ namespace Content.Server.GameObjects.EntitySystems
}
}
private bool TryProcessStep(IEntity constructEntity, ConstructionStep step, IEntity slapped, IEntity user, GridCoordinates gridCoords)
private async Task<bool> TryProcessStep(IEntity constructEntity, ConstructionStep step, IEntity slapped, IEntity user, GridCoordinates gridCoords)
{
if (step == null)
{
@@ -473,9 +474,9 @@ namespace Content.Server.GameObjects.EntitySystems
// Handle welder manually since tool steps specify fuel amount needed, for some reason.
if (toolStep.ToolQuality.HasFlag(ToolQuality.Welding))
return slapped.TryGetComponent<WelderComponent>(out var welder)
&& welder.UseTool(user, constructEntity, toolStep.ToolQuality, toolStep.Amount);
&& await welder.UseTool(user, constructEntity, toolStep.DoAfterDelay, toolStep.ToolQuality, toolStep.Amount);
return tool.UseTool(user, constructEntity, toolStep.ToolQuality);
return await tool.UseTool(user, constructEntity, toolStep.DoAfterDelay, toolStep.ToolQuality);
default:
throw new NotImplementedException();

View File

@@ -181,11 +181,13 @@ namespace Content.Shared.Construction
public abstract class ConstructionStep
{
public readonly int Amount = 1;
public readonly int Amount;
public readonly float DoAfterDelay;
protected ConstructionStep(int amount)
protected ConstructionStep(int amount, float doAfterDelay = 0f)
{
Amount = amount;
DoAfterDelay = doAfterDelay;
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using JetBrains.Annotations;
using Robust.Shared.GameObjects;
@@ -22,7 +23,7 @@ namespace Content.Shared.Interfaces.GameObjects.Components
/// <summary>
/// Called when using one object on another when user is in range of the target entity.
/// </summary>
bool InteractUsing(InteractUsingEventArgs eventArgs);
Task<bool> InteractUsing(InteractUsingEventArgs eventArgs);
}
public class InteractUsingEventArgs : EventArgs, ITargetedInteractEventArgs