Fancy Verb Menu & Verb API Refactor (#928)

This commit is contained in:
Pieter-Jan Briers
2020-05-23 03:09:44 +02:00
committed by GitHub
parent 4527fc9e84
commit cad59d2cb4
33 changed files with 1099 additions and 399 deletions
@@ -216,21 +216,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
[Verb]
private sealed class FillTargetVerb : Verb<SolutionComponent>
{
protected override string GetText(IEntity user, SolutionComponent component)
{
if(!user.TryGetComponent<HandsComponent>(out var hands))
return "<I SHOULD BE INVISIBLE>";
if(hands.GetActiveHand == null)
return "<I SHOULD BE INVISIBLE>";
var heldEntityName = hands.GetActiveHand.Owner?.Prototype?.Name ?? "<Item>";
var myName = component.Owner.Prototype?.Name ?? "<Item>";
return $"Transfer liquid from [{heldEntityName}] to [{myName}].";
}
protected override VerbVisibility GetVisibility(IEntity user, SolutionComponent component)
protected override void GetData(IEntity user, SolutionComponent component, VerbData data)
{
if (user.TryGetComponent<HandsComponent>(out var hands))
{
@@ -238,13 +224,20 @@ namespace Content.Server.GameObjects.Components.Chemistry
{
if (hands.GetActiveHand.Owner.TryGetComponent<SolutionComponent>(out var solution))
{
if ((solution.Capabilities & SolutionCaps.PourOut) != 0 && (component.Capabilities & SolutionCaps.PourIn) != 0)
return VerbVisibility.Visible;
if ((solution.Capabilities & SolutionCaps.PourOut) != 0 &&
(component.Capabilities & SolutionCaps.PourIn) != 0)
{
var heldEntityName = hands.GetActiveHand.Owner?.Prototype?.Name ?? "<Item>";
var myName = component.Owner.Prototype?.Name ?? "<Item>";
data.Text= $"Transfer liquid from [{heldEntityName}] to [{myName}].";
return;
}
}
}
}
return VerbVisibility.Invisible;
data.Visibility = VerbVisibility.Invisible;
}
protected override void Activate(IEntity user, SolutionComponent component)
@@ -269,7 +262,6 @@ namespace Content.Server.GameObjects.Components.Chemistry
var transferSolution = handSolutionComp.SplitSolution(transferQuantity);
component.TryAddSolution(transferSolution);
}
}
@@ -304,21 +296,7 @@ namespace Content.Server.GameObjects.Components.Chemistry
[Verb]
private sealed class EmptyTargetVerb : Verb<SolutionComponent>
{
protected override string GetText(IEntity user, SolutionComponent component)
{
if (!user.TryGetComponent<HandsComponent>(out var hands))
return "<I SHOULD BE INVISIBLE>";
if (hands.GetActiveHand == null)
return "<I SHOULD BE INVISIBLE>";
var heldEntityName = hands.GetActiveHand.Owner?.Prototype?.Name ?? "<Item>";
var myName = component.Owner.Prototype?.Name ?? "<Item>";
return $"Transfer liquid from [{myName}] to [{heldEntityName}].";
}
protected override VerbVisibility GetVisibility(IEntity user, SolutionComponent component)
protected override void GetData(IEntity user, SolutionComponent component, VerbData data)
{
if (user.TryGetComponent<HandsComponent>(out var hands))
{
@@ -326,13 +304,20 @@ namespace Content.Server.GameObjects.Components.Chemistry
{
if (hands.GetActiveHand.Owner.TryGetComponent<SolutionComponent>(out var solution))
{
if ((solution.Capabilities & SolutionCaps.PourIn) != 0 && (component.Capabilities & SolutionCaps.PourOut) != 0)
return VerbVisibility.Visible;
if ((solution.Capabilities & SolutionCaps.PourIn) != 0 &&
(component.Capabilities & SolutionCaps.PourOut) != 0)
{
var heldEntityName = hands.GetActiveHand.Owner?.Prototype?.Name ?? "<Item>";
var myName = component.Owner.Prototype?.Name ?? "<Item>";
data.Text = $"Transfer liquid from [{myName}] to [{heldEntityName}].";
return;
}
}
}
}
return VerbVisibility.Invisible;
data.Visibility = VerbVisibility.Invisible;
}
protected override void Activate(IEntity user, SolutionComponent component)
@@ -19,19 +19,18 @@ namespace Content.Server.GameObjects.Components.Fluids
[Verb]
private sealed class FillTargetVerb : Verb<CanSpillComponent>
{
protected override string GetText(IEntity user, CanSpillComponent component)
protected override void GetData(IEntity user, CanSpillComponent component, VerbData data)
{
return "Spill liquid";
}
protected override VerbVisibility GetVisibility(IEntity user, CanSpillComponent component)
{
if (component.Owner.TryGetComponent(out SolutionComponent solutionComponent))
if (!component.Owner.TryGetComponent(out SolutionComponent solutionComponent))
{
return solutionComponent.CurrentVolume > ReagentUnit.Zero ? VerbVisibility.Visible : VerbVisibility.Disabled;
data.Visibility = VerbVisibility.Invisible;
return;
}
return VerbVisibility.Invisible;
data.Text = "Spill liquid";
data.Visibility = solutionComponent.CurrentVolume > ReagentUnit.Zero
? VerbVisibility.Visible
: VerbVisibility.Disabled;
}
protected override void Activate(IEntity user, CanSpillComponent component)
@@ -250,14 +250,17 @@ namespace Content.Server.GameObjects.Components.Interactable
[Verb]
public sealed class EjectCellVerb : Verb<HandheldLightComponent>
{
protected override string GetText(IEntity user, HandheldLightComponent component)
protected override void GetData(IEntity user, HandheldLightComponent component, VerbData data)
{
return component.Cell == null ? "Eject cell (cell missing)" : "Eject cell";
}
protected override VerbVisibility GetVisibility(IEntity user, HandheldLightComponent component)
{
return component.Cell == null ? VerbVisibility.Disabled : VerbVisibility.Visible;
if (component.Cell == null)
{
data.Text = "Eject cell (cell missing)";
data.Visibility = VerbVisibility.Disabled;
}
else
{
data.Text = "Eject cell";
}
}
protected override void Activate(IEntity user, HandheldLightComponent component)
@@ -328,16 +328,9 @@ namespace Content.Server.GameObjects.Components
[Verb]
private sealed class LockToggleVerb : Verb<EntityStorageComponent>
{
/// <inheritdoc />
protected override string GetText(IEntity user, EntityStorageComponent component)
protected override void GetData(IEntity user, EntityStorageComponent component, VerbData data)
{
return component._locked ? "Unlock" : "Lock";
}
/// <inheritdoc />
protected override VerbVisibility GetVisibility(IEntity user, EntityStorageComponent component)
{
return VerbVisibility.Visible;
data.Text = component._locked ? "Unlock" : "Lock";
}
/// <inheritdoc />
@@ -350,16 +343,15 @@ namespace Content.Server.GameObjects.Components
[Verb]
private sealed class OpenToggleVerb : Verb<EntityStorageComponent>
{
/// <inheritdoc />
protected override string GetText(IEntity user, EntityStorageComponent component)
protected override void GetData(IEntity user, EntityStorageComponent component, VerbData data)
{
return component.Open ? "Close" : "Open";
}
if (component.NoDoor)
{
data.Visibility = VerbVisibility.Invisible;
return;
}
/// <inheritdoc />
protected override VerbVisibility GetVisibility(IEntity user, EntityStorageComponent component)
{
return component.NoDoor ? VerbVisibility.Invisible : VerbVisibility.Visible;
data.Text = component.Open ? "Close" : "Open";
}
/// <inheritdoc />
@@ -113,23 +113,15 @@ namespace Content.Server.GameObjects
[Verb]
public sealed class PickUpVerb : Verb<ItemComponent>
{
protected override string GetText(IEntity user, ItemComponent component)
{
if (user.TryGetComponent(out HandsComponent hands) && hands.IsHolding(component.Owner))
{
return "Pick Up (Already Holding)";
}
return "Pick Up";
}
protected override VerbVisibility GetVisibility(IEntity user, ItemComponent component)
protected override void GetData(IEntity user, ItemComponent component, VerbData data)
{
if (ContainerHelpers.IsInContainer(component.Owner) || !component.CanPickup(user))
{
return VerbVisibility.Invisible;
data.Visibility = VerbVisibility.Invisible;
return;
}
return VerbVisibility.Visible;
data.Text = "Pick Up";
}
protected override void Activate(IEntity user, ItemComponent component)
@@ -128,14 +128,10 @@ namespace Content.Server.GameObjects.Components.Medical
[Verb]
public sealed class EnterVerb : Verb<MedicalScannerComponent>
{
protected override string GetText(IEntity user, MedicalScannerComponent component)
protected override void GetData(IEntity user, MedicalScannerComponent component, VerbData data)
{
return "Enter";
}
protected override VerbVisibility GetVisibility(IEntity user, MedicalScannerComponent component)
{
return component.IsOccupied ? VerbVisibility.Invisible : VerbVisibility.Visible;
data.Text = "Enter";
data.Visibility = component.IsOccupied ? VerbVisibility.Invisible : VerbVisibility.Visible;
}
protected override void Activate(IEntity user, MedicalScannerComponent component)
@@ -147,14 +143,10 @@ namespace Content.Server.GameObjects.Components.Medical
[Verb]
public sealed class EjectVerb : Verb<MedicalScannerComponent>
{
protected override string GetText(IEntity user, MedicalScannerComponent component)
protected override void GetData(IEntity user, MedicalScannerComponent component, VerbData data)
{
return "Eject";
}
protected override VerbVisibility GetVisibility(IEntity user, MedicalScannerComponent component)
{
return component.IsOccupied ? VerbVisibility.Visible : VerbVisibility.Invisible;
data.Text = "Eject";
data.Visibility = component.IsOccupied ? VerbVisibility.Visible : VerbVisibility.Invisible;
}
protected override void Activate(IEntity user, MedicalScannerComponent component)
@@ -58,28 +58,22 @@ namespace Content.Server.GameObjects.Components.Power.Chargers
[Verb]
private sealed class InsertVerb : Verb<PowerCellChargerComponent>
{
protected override string GetText(IEntity user, PowerCellChargerComponent component)
{
if (!user.TryGetComponent(out HandsComponent handsComponent) || handsComponent.GetActiveHand == null)
{
return "Insert";
}
return $"Insert {handsComponent.GetActiveHand.Owner.Name}";
}
protected override VerbVisibility GetVisibility(IEntity user, PowerCellChargerComponent component)
protected override void GetData(IEntity user, PowerCellChargerComponent component, VerbData data)
{
if (!user.TryGetComponent(out HandsComponent handsComponent))
{
return VerbVisibility.Invisible;
data.Visibility = VerbVisibility.Invisible;
return;
}
if (component._container.ContainedEntity != null || handsComponent.GetActiveHand == null)
{
return VerbVisibility.Disabled;
data.Visibility = VerbVisibility.Disabled;
data.Text = "Insert";
return;
}
return VerbVisibility.Visible;
data.Text = $"Insert {handsComponent.GetActiveHand.Owner.Name}";
}
protected override void Activate(IEntity user, PowerCellChargerComponent component)
@@ -102,22 +96,16 @@ namespace Content.Server.GameObjects.Components.Power.Chargers
[Verb]
private sealed class EjectVerb : Verb<PowerCellChargerComponent>
{
protected override string GetText(IEntity user, PowerCellChargerComponent component)
protected override void GetData(IEntity user, PowerCellChargerComponent component, VerbData data)
{
if (component._container.ContainedEntity == null)
{
return "Eject";
data.Text = "Eject";
data.Visibility = VerbVisibility.Disabled;
return;
}
return $"Eject {component._container.ContainedEntity.Name}";
}
protected override VerbVisibility GetVisibility(IEntity user, PowerCellChargerComponent component)
{
if (component._container.ContainedEntity == null)
{
return VerbVisibility.Disabled;
}
return VerbVisibility.Visible;
data.Text = $"Eject {component._container.ContainedEntity.Name}";
}
protected override void Activate(IEntity user, PowerCellChargerComponent component)
@@ -48,28 +48,27 @@ namespace Content.Server.GameObjects.Components.Power.Chargers
[Verb]
private sealed class InsertVerb : Verb<WeaponCapacitorChargerComponent>
{
protected override string GetText(IEntity user, WeaponCapacitorChargerComponent component)
{
if (!user.TryGetComponent(out HandsComponent handsComponent) || handsComponent.GetActiveHand == null)
{
return "Insert";
}
return $"Insert {handsComponent.GetActiveHand.Owner.Name}";
}
protected override VerbVisibility GetVisibility(IEntity user, WeaponCapacitorChargerComponent component)
protected override void GetData(IEntity user, WeaponCapacitorChargerComponent component, VerbData data)
{
if (!user.TryGetComponent(out HandsComponent handsComponent))
{
return VerbVisibility.Invisible;
data.Visibility = VerbVisibility.Invisible;
return;
}
if (component._container.ContainedEntity != null || handsComponent.GetActiveHand == null)
if (handsComponent.GetActiveHand == null)
{
return VerbVisibility.Disabled;
data.Visibility = VerbVisibility.Disabled;
data.Text = "Insert";
return;
}
return VerbVisibility.Visible;
if (component._container.ContainedEntity != null)
{
data.Visibility = VerbVisibility.Disabled;
}
data.Text = $"Insert {handsComponent.GetActiveHand.Owner.Name}";
}
protected override void Activate(IEntity user, WeaponCapacitorChargerComponent component)
@@ -92,22 +91,16 @@ namespace Content.Server.GameObjects.Components.Power.Chargers
[Verb]
private sealed class EjectVerb : Verb<WeaponCapacitorChargerComponent>
{
protected override string GetText(IEntity user, WeaponCapacitorChargerComponent component)
protected override void GetData(IEntity user, WeaponCapacitorChargerComponent component, VerbData data)
{
if (component._container.ContainedEntity == null)
{
return "Eject";
data.Visibility = VerbVisibility.Disabled;
data.Text = "Eject";
return;
}
return $"Eject {component._container.ContainedEntity.Name}";
}
protected override VerbVisibility GetVisibility(IEntity user, WeaponCapacitorChargerComponent component)
{
if (component._container.ContainedEntity == null)
{
return VerbVisibility.Disabled;
}
return VerbVisibility.Visible;
data.Text = $"Eject {component._container.ContainedEntity.Name}";
}
protected override void Activate(IEntity user, WeaponCapacitorChargerComponent component)
@@ -35,16 +35,11 @@ namespace Content.Server.GameObjects.Components
[Verb]
public sealed class RotateVerb : Verb<RotatableComponent>
{
protected override string GetText(IEntity user, RotatableComponent component)
protected override void GetData(IEntity user, RotatableComponent component, VerbData data)
{
return "Rotate clockwise";
}
protected override string GetCategory(IEntity user, RotatableComponent component) => "Rotate";
protected override VerbVisibility GetVisibility(IEntity user, RotatableComponent component)
{
return VerbVisibility.Visible;
data.CategoryData = VerbCategories.Rotate;
data.Text = "Rotate clockwise";
data.IconTexture = "/Textures/UserInterface/VerbIcons/rotate_cw.svg.96dpi.png";
}
protected override void Activate(IEntity user, RotatableComponent component)
@@ -56,16 +51,11 @@ namespace Content.Server.GameObjects.Components
[Verb]
public sealed class RotateCounterVerb : Verb<RotatableComponent>
{
protected override string GetText(IEntity user, RotatableComponent component)
protected override void GetData(IEntity user, RotatableComponent component, VerbData data)
{
return "Rotate counter-clockwise";
}
protected override string GetCategory(IEntity user, RotatableComponent component) => "Rotate";
protected override VerbVisibility GetVisibility(IEntity user, RotatableComponent component)
{
return VerbVisibility.Visible;
data.CategoryData = VerbCategories.Rotate;
data.Text = "Rotate counter-clockwise";
data.IconTexture = "/Textures/UserInterface/VerbIcons/rotate_cw.svg.96dpi.png";
}
protected override void Activate(IEntity user, RotatableComponent component)
@@ -266,14 +266,16 @@ namespace Content.Server.GameObjects.Components.Weapon.Ranged.Projectile
[Verb]
public sealed class EjectMagazineVerb : Verb<BallisticMagazineWeaponComponent>
{
protected override string GetText(IEntity user, BallisticMagazineWeaponComponent component)
protected override void GetData(IEntity user, BallisticMagazineWeaponComponent component, VerbData data)
{
return component.Magazine == null ? "Eject magazine (magazine missing)" : "Eject magazine";
}
if (component.Magazine == null)
{
data.Text = "Eject magazine (magazine missing)";
data.Visibility = VerbVisibility.Disabled;
return;
}
protected override VerbVisibility GetVisibility(IEntity user, BallisticMagazineWeaponComponent component)
{
return component.Magazine == null ? VerbVisibility.Disabled : VerbVisibility.Visible;
data.Text = "Eject magazine";
}
protected override void Activate(IEntity user, BallisticMagazineWeaponComponent component)
@@ -12,9 +12,9 @@ namespace Content.Server.GameObjects.EntitySystems
{
public class VerbSystem : EntitySystem
{
#pragma warning disable 649
#pragma warning disable 649
[Dependency] private readonly IEntityManager _entityManager;
#pragma warning restore 649
#pragma warning restore 649
public override void Initialize()
{
@@ -90,19 +90,19 @@ namespace Content.Server.GameObjects.EntitySystems
var userEntity = player.AttachedEntity;
var data = new List<VerbsResponseMessage.VerbData>();
var data = new List<VerbsResponseMessage.NetVerbData>();
//Get verbs, component dependent.
foreach (var (component, verb) in VerbUtility.GetVerbs(entity))
{
if (verb.RequireInteractionRange && !VerbUtility.InVerbUseRange(userEntity, entity))
continue;
if (VerbUtility.IsVerbInvisible(verb, userEntity, component, out var vis))
var verbData = verb.GetData(userEntity, component);
if (verbData.IsInvisible)
continue;
// TODO: These keys being giant strings is inefficient as hell.
data.Add(new VerbsResponseMessage.VerbData(verb.GetText(userEntity, component),
$"{component.GetType()}:{verb.GetType()}", verb.GetCategory(userEntity, component),
vis == VerbVisibility.Visible));
data.Add(new VerbsResponseMessage.NetVerbData(verbData, $"{component.GetType()}:{verb.GetType()}"));
}
//Get global verbs. Visible for all entities regardless of their components.
@@ -110,14 +110,15 @@ namespace Content.Server.GameObjects.EntitySystems
{
if (globalVerb.RequireInteractionRange && !VerbUtility.InVerbUseRange(userEntity, entity))
continue;
if (VerbUtility.IsVerbInvisible(globalVerb, userEntity, entity, out var vis))
var verbData = globalVerb.GetData(userEntity, entity);
if (verbData.IsInvisible)
continue;
data.Add(new VerbsResponseMessage.VerbData(globalVerb.GetText(userEntity, entity),
globalVerb.GetType().ToString(), globalVerb.GetCategory(userEntity, entity), vis == VerbVisibility.Visible));
data.Add(new VerbsResponseMessage.NetVerbData(verbData, globalVerb.GetType().ToString()));
}
var response = new VerbsResponseMessage(data, req.EntityUid);
var response = new VerbsResponseMessage(data.ToArray(), req.EntityUid);
RaiseNetworkEvent(response, player.ConnectedClient);
}
}
+26 -15
View File
@@ -1,53 +1,64 @@
using Content.Server.GameObjects;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.GameObjects.Components.Nutrition;
using Content.Server.GameObjects.Components.Observer;
using Content.Server.Players;
using Content.Shared.GameObjects;
using Robust.Server.Console;
using Robust.Server.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
namespace Content.Server.GlobalVerbs
{
[GlobalVerb]
public class ControlMobVerb : GlobalVerb
{
public override string GetText(IEntity user, IEntity target) => "Control Mob";
public override string GetCategory(IEntity user, IEntity target) => "Debug";
public override bool RequireInteractionRange => false;
public override VerbVisibility GetVisibility(IEntity user, IEntity target)
public override void GetData(IEntity user, IEntity target, VerbData data)
{
data.Visibility = VerbVisibility.Invisible;
var groupController = IoCManager.Resolve<IConGroupController>();
if (user == target) return VerbVisibility.Invisible;
if (user == target)
{
return;
}
if (user.TryGetComponent<IActorComponent>(out var player))
{
if (!user.HasComponent<MindComponent>() || !target.HasComponent<MindComponent>())
return VerbVisibility.Invisible;
{
return;
}
if (groupController.CanCommand(player.playerSession, "controlmob"))
return VerbVisibility.Visible;
{
data.Visibility = VerbVisibility.Visible;
data.Text = "Control Mob";
data.CategoryData = VerbCategories.Debug;
}
}
return VerbVisibility.Invisible;
}
public override void Activate(IEntity user, IEntity target)
{
var userMind = user.GetComponent<IActorComponent>().playerSession.ContentData().Mind;
var groupController = IoCManager.Resolve<IConGroupController>();
var player = user.GetComponent<IActorComponent>().playerSession;
if (!groupController.CanCommand(player, "controlmob"))
{
return;
}
var userMind = player.ContentData().Mind;
var targetMind = target.GetComponent<MindComponent>();
var oldEntity = userMind.CurrentEntity;
targetMind.Mind?.TransferTo(null);
userMind.TransferTo(target);
if(oldEntity.HasComponent<GhostComponent>())
if (oldEntity.HasComponent<GhostComponent>())
oldEntity.Delete();
}
}
+13 -9
View File
@@ -14,24 +14,29 @@ namespace Content.Server.GlobalVerbs
[GlobalVerb]
class RejuvenateVerb : GlobalVerb
{
public override string GetText(IEntity user, IEntity target) => "Rejuvenate";
public override string GetCategory(IEntity user, IEntity target) => "Debug";
public override bool RequireInteractionRange => false;
public override VerbVisibility GetVisibility(IEntity user, IEntity target)
public override void GetData(IEntity user, IEntity target, VerbData data)
{
data.Text = "Rejuvenate";
data.CategoryData = VerbCategories.Debug;
data.Visibility = VerbVisibility.Invisible;
var groupController = IoCManager.Resolve<IConGroupController>();
if (user.TryGetComponent<IActorComponent>(out var player))
{
if (!target.HasComponent<DamageableComponent>() && !target.HasComponent<HungerComponent>() && !target.HasComponent<ThirstComponent>())
return VerbVisibility.Invisible;
if (!target.HasComponent<DamageableComponent>() && !target.HasComponent<HungerComponent>() &&
!target.HasComponent<ThirstComponent>())
{
return;
}
if (groupController.CanCommand(player.playerSession, "rejuvenate"))
return VerbVisibility.Visible;
{
data.Visibility = VerbVisibility.Visible;
}
}
return VerbVisibility.Invisible;
}
public override void Activate(IEntity user, IEntity target)
@@ -42,7 +47,6 @@ namespace Content.Server.GlobalVerbs
if (groupController.CanCommand(player.playerSession, "rejuvenate"))
PerformRejuvenate(target);
}
}
public static void PerformRejuvenate(IEntity target)
{