Examine Groups (#12400)
* new version * testy2 * working version * new GroupExamineSystem * restructure * restructure again * update icon * adding group examine to prototypes * change examine group title to a localized string Co-authored-by: CommieFlowers <rasmus.cedergren@hotmail.com>
This commit is contained in:
@@ -77,20 +77,11 @@ namespace Content.Server.Armor
|
|||||||
if (armorModifiers == null)
|
if (armorModifiers == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var verb = new ExamineVerb()
|
var examineMarkup = GetArmorExamine(armorModifiers);
|
||||||
{
|
|
||||||
Act = () =>
|
|
||||||
{
|
|
||||||
var markup = GetArmorExamine(armorModifiers);
|
|
||||||
_examine.SendExamineTooltip(args.User, uid, markup, false, false);
|
|
||||||
},
|
|
||||||
Text = Loc.GetString("armor-examinable-verb-text"),
|
|
||||||
Message = Loc.GetString("armor-examinable-verb-message"),
|
|
||||||
Category = VerbCategory.Examine,
|
|
||||||
IconTexture = "/Textures/Interface/VerbIcons/dot.svg.192dpi.png"
|
|
||||||
};
|
|
||||||
|
|
||||||
args.Verbs.Add(verb);
|
_examine.AddDetailedExamineVerb(args, component, examineMarkup, Loc.GetString("armor-examinable-verb-text"), "/Textures/Interface/VerbIcons/dot.svg.192dpi.png", Loc.GetString("armor-examinable-verb-message"));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FormattedMessage GetArmorExamine(DamageModifierSet armorModifiers)
|
private static FormattedMessage GetArmorExamine(DamageModifierSet armorModifiers)
|
||||||
|
|||||||
@@ -118,18 +118,8 @@ public sealed class ClothingSpeedModifierSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var verb = new ExamineVerb()
|
_examine.AddDetailedExamineVerb(args, component, msg, Loc.GetString("clothing-speed-examinable-verb-text"), "/Textures/Interface/VerbIcons/outfit.svg.192dpi.png", Loc.GetString("clothing-speed-examinable-verb-message"));
|
||||||
{
|
|
||||||
Act = () =>
|
|
||||||
{
|
|
||||||
_examine.SendExamineTooltip(args.User, uid, msg, false, false);
|
|
||||||
},
|
|
||||||
Text = Loc.GetString("clothing-speed-examinable-verb-text"),
|
|
||||||
Message = Loc.GetString("clothing-speed-examinable-verb-message"),
|
|
||||||
Category = VerbCategory.Examine,
|
|
||||||
IconTexture = "/Textures/Interface/VerbIcons/outfit.svg.192dpi.png"
|
|
||||||
};
|
|
||||||
|
|
||||||
args.Verbs.Add(verb);
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
175
Content.Shared/Examine/ExamineSystemShared.Group.cs
Normal file
175
Content.Shared/Examine/ExamineSystemShared.Group.cs
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
using Robust.Shared.Utility;
|
||||||
|
using Content.Shared.Verbs;
|
||||||
|
|
||||||
|
namespace Content.Shared.Examine
|
||||||
|
{
|
||||||
|
public abstract partial class ExamineSystemShared : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IComponentFactory _componentFactory = default!;
|
||||||
|
|
||||||
|
public const string DefaultIconTexture = "/Textures/Interface/examine-star.png";
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<GroupExamineComponent, GetVerbsEvent<ExamineVerb>>(OnGroupExamineVerb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when getting verbs on an object with the GroupExamine component. <br/>
|
||||||
|
/// This checks if any of the ExamineGroups are relevant (has 1 or more of the relevant components on the entity)
|
||||||
|
/// and if so, creates an ExamineVerb details button for the ExamineGroup.
|
||||||
|
/// </summary>
|
||||||
|
private void OnGroupExamineVerb(EntityUid uid, GroupExamineComponent component, GetVerbsEvent<ExamineVerb> args)
|
||||||
|
{
|
||||||
|
foreach (var group in component.ExamineGroups)
|
||||||
|
{
|
||||||
|
if (!EntityHasComponent(uid, group.Components))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var examineVerb = new ExamineVerb()
|
||||||
|
{
|
||||||
|
Act = () =>
|
||||||
|
{
|
||||||
|
SendExamineGroup(args.User, args.Target, group);
|
||||||
|
group.Entries.Clear();
|
||||||
|
},
|
||||||
|
Text = group.ContextText,
|
||||||
|
Message = group.HoverMessage,
|
||||||
|
Category = VerbCategory.Examine,
|
||||||
|
IconTexture = group.Icon
|
||||||
|
};
|
||||||
|
|
||||||
|
args.Verbs.Add(examineVerb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the entity <paramref name="uid"/> has any of the listed <paramref name="components"/>.
|
||||||
|
/// </summary>
|
||||||
|
public bool EntityHasComponent(EntityUid uid, List<string> components)
|
||||||
|
{
|
||||||
|
foreach (var comp in components)
|
||||||
|
{
|
||||||
|
if (!_componentFactory.TryGetRegistration(comp, out var componentRegistration))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!HasComp(uid, componentRegistration.Type))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends an ExamineTooltip based on the contents of <paramref name="group"/>
|
||||||
|
/// </summary>
|
||||||
|
public void SendExamineGroup(EntityUid user, EntityUid target, ExamineGroup group)
|
||||||
|
{
|
||||||
|
var message = new FormattedMessage();
|
||||||
|
|
||||||
|
if (group.Title != null)
|
||||||
|
{
|
||||||
|
message.AddMarkup(Loc.GetString(group.Title));
|
||||||
|
message.PushNewline();
|
||||||
|
}
|
||||||
|
message.AddMessage(GetFormattedMessageFromExamineEntries(group.Entries));
|
||||||
|
|
||||||
|
SendExamineTooltip(user, target, message, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <returns>A FormattedMessage based on all <paramref name="entries"/>, sorted.</returns>
|
||||||
|
public static FormattedMessage GetFormattedMessageFromExamineEntries(List<ExamineEntry> entries)
|
||||||
|
{
|
||||||
|
var formattedMessage = new FormattedMessage();
|
||||||
|
entries.Sort((a, b) => (b.Priority.CompareTo(a.Priority)));
|
||||||
|
|
||||||
|
var first = true;
|
||||||
|
|
||||||
|
foreach (var entry in entries)
|
||||||
|
{
|
||||||
|
if (!first)
|
||||||
|
{
|
||||||
|
formattedMessage.PushNewline();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
formattedMessage.AddMessage(entry.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return formattedMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Either sends the details to a GroupExamineComponent if it finds one, or adds a details examine verb itself.
|
||||||
|
/// </summary>
|
||||||
|
public void AddDetailedExamineVerb(GetVerbsEvent<ExamineVerb> verbsEvent, Component component, List<ExamineEntry> entries, string verbText, string iconTexture = DefaultIconTexture, string hoverMessage = "")
|
||||||
|
{
|
||||||
|
// If the entity has the GroupExamineComponent
|
||||||
|
if (TryComp<GroupExamineComponent>(verbsEvent.Target, out var groupExamine))
|
||||||
|
{
|
||||||
|
// Make sure we have the component name as a string
|
||||||
|
var componentName = _componentFactory.GetComponentName(component.GetType());
|
||||||
|
|
||||||
|
foreach (var examineGroup in groupExamine.ExamineGroups)
|
||||||
|
{
|
||||||
|
// If any of the examine groups list of components contain this componentname
|
||||||
|
if (examineGroup.Components.Contains(componentName))
|
||||||
|
{
|
||||||
|
foreach (var entry in examineGroup.Entries)
|
||||||
|
{
|
||||||
|
// If any of the entries already are from your component, dont do anything else - no doubles!
|
||||||
|
if (entry.ComponentName == componentName)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var entry in entries)
|
||||||
|
{
|
||||||
|
// Otherwise, just add all information to the examine groups entries, and stop there.
|
||||||
|
examineGroup.Entries.Add(entry);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var formattedMessage = GetFormattedMessageFromExamineEntries(entries);
|
||||||
|
|
||||||
|
var examineVerb = new ExamineVerb()
|
||||||
|
{
|
||||||
|
Act = () =>
|
||||||
|
{
|
||||||
|
SendExamineTooltip(verbsEvent.User, verbsEvent.Target, formattedMessage, false, false);
|
||||||
|
},
|
||||||
|
Text = verbText,
|
||||||
|
Message = hoverMessage,
|
||||||
|
Category = VerbCategory.Examine,
|
||||||
|
IconTexture = iconTexture
|
||||||
|
};
|
||||||
|
|
||||||
|
verbsEvent.Verbs.Add(examineVerb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Either adds a details examine verb, or sends the details to a GroupExamineComponent if it finds one.
|
||||||
|
/// </summary>
|
||||||
|
public void AddDetailedExamineVerb(GetVerbsEvent<ExamineVerb> verbsEvent, Component component, ExamineEntry entry, string verbText, string iconTexture = DefaultIconTexture, string hoverMessage = "")
|
||||||
|
{
|
||||||
|
AddDetailedExamineVerb(verbsEvent, component, new List<ExamineEntry> { entry }, verbText, iconTexture, hoverMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Either adds a details examine verb, or sends the details to a GroupExamineComponent if it finds one.
|
||||||
|
/// </summary>
|
||||||
|
public void AddDetailedExamineVerb(GetVerbsEvent<ExamineVerb> verbsEvent, Component component, FormattedMessage message, string verbText, string iconTexture = DefaultIconTexture, string hoverMessage = "")
|
||||||
|
{
|
||||||
|
var componentName = _componentFactory.GetComponentName(component.GetType());
|
||||||
|
AddDetailedExamineVerb(verbsEvent, component, new ExamineEntry(componentName, 0f, message), verbText, iconTexture, hoverMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ using static Content.Shared.Interaction.SharedInteractionSystem;
|
|||||||
|
|
||||||
namespace Content.Shared.Examine
|
namespace Content.Shared.Examine
|
||||||
{
|
{
|
||||||
public abstract class ExamineSystemShared : EntitySystem
|
public abstract partial class ExamineSystemShared : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||||
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
||||||
|
|||||||
103
Content.Shared/Examine/GroupExamineComponent.cs
Normal file
103
Content.Shared/Examine/GroupExamineComponent.cs
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Shared.Examine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This component groups examine messages together
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class GroupExamineComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A list of ExamineGroups.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("group")]
|
||||||
|
public List<ExamineGroup> ExamineGroups = new()
|
||||||
|
{
|
||||||
|
new ExamineGroup()
|
||||||
|
{
|
||||||
|
Components = new()
|
||||||
|
{
|
||||||
|
"Armor",
|
||||||
|
"ClothingSpeedModifier",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[DataDefinition]
|
||||||
|
public sealed class ExamineGroup
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The title of the Examine Group, the .
|
||||||
|
/// </summary>
|
||||||
|
[DataField("title")]
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public string? Title;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of ExamineEntries, containing which component it belongs to, which priority it has, and what FormattedMessage it holds.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("entries")]
|
||||||
|
public List<ExamineEntry> Entries = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of all components this ExamineGroup encompasses.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("components")]
|
||||||
|
public List<string> Components = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The icon path for the Examine Group.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("icon")]
|
||||||
|
public string Icon = "/Textures/Interface/examine-star.png";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The text shown in the context verb menu.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("contextText")]
|
||||||
|
public string ContextText = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Details shown when hovering over the button.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("hoverMessage")]
|
||||||
|
public string HoverMessage = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An entry used when showing examine details
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class ExamineEntry
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Which component does this entry relate to?
|
||||||
|
/// </summary>
|
||||||
|
[DataField("component")]
|
||||||
|
public string ComponentName = string.Empty;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// What priority has this entry - entries are sorted high to low.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("priority")]
|
||||||
|
public float Priority = 0f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The FormattedMessage of this entry.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("message")]
|
||||||
|
public FormattedMessage Message = new();
|
||||||
|
|
||||||
|
/// <param name="componentName">Should be set to _componentFactory.GetComponentName(component.GetType()) to properly function.</param>
|
||||||
|
public ExamineEntry(string componentName, float priority, FormattedMessage message)
|
||||||
|
{
|
||||||
|
ComponentName = componentName;
|
||||||
|
Priority = priority;
|
||||||
|
Message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -130,3 +130,4 @@
|
|||||||
modifiers:
|
modifiers:
|
||||||
coefficients:
|
coefficients:
|
||||||
Heat: 0.95
|
Heat: 0.95
|
||||||
|
- type: GroupExamine
|
||||||
|
|||||||
@@ -142,6 +142,7 @@
|
|||||||
Piercing: 0.95
|
Piercing: 0.95
|
||||||
Heat: 0.90
|
Heat: 0.90
|
||||||
Radiation: 0.25
|
Radiation: 0.25
|
||||||
|
- type: GroupExamine
|
||||||
- type: IngestionBlocker
|
- type: IngestionBlocker
|
||||||
- type: Tag
|
- type: Tag
|
||||||
tags:
|
tags:
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
Slash: 0.5
|
Slash: 0.5
|
||||||
Piercing: 0.6
|
Piercing: 0.6
|
||||||
Heat: 0.5
|
Heat: 0.5
|
||||||
|
- type: GroupExamine
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingOuterBaseLarge
|
parent: ClothingOuterBaseLarge
|
||||||
@@ -72,6 +73,7 @@
|
|||||||
Piercing: 0.2
|
Piercing: 0.2
|
||||||
Heat: 0.5
|
Heat: 0.5
|
||||||
Radiation: 0
|
Radiation: 0
|
||||||
|
- type: GroupExamine
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingOuterArmorHeavy
|
parent: ClothingOuterArmorHeavy
|
||||||
@@ -136,6 +138,7 @@
|
|||||||
Heat: 0.9
|
Heat: 0.9
|
||||||
- type: ExplosionResistance
|
- type: ExplosionResistance
|
||||||
damageCoefficient: 0.9
|
damageCoefficient: 0.9
|
||||||
|
- type: GroupExamine
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingOuterBaseLarge
|
parent: ClothingOuterBaseLarge
|
||||||
@@ -156,6 +159,7 @@
|
|||||||
Heat: 0.9
|
Heat: 0.9
|
||||||
- type: ExplosionResistance
|
- type: ExplosionResistance
|
||||||
damageCoefficient: 0.8
|
damageCoefficient: 0.8
|
||||||
|
- type: GroupExamine
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingOuterBaseLarge
|
parent: ClothingOuterBaseLarge
|
||||||
@@ -176,7 +180,8 @@
|
|||||||
Heat: 0.5
|
Heat: 0.5
|
||||||
- type: ExplosionResistance
|
- type: ExplosionResistance
|
||||||
damageCoefficient: 0.65
|
damageCoefficient: 0.65
|
||||||
|
- type: GroupExamine
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingOuterBaseLarge
|
parent: ClothingOuterBaseLarge
|
||||||
id: ClothingOuterArmorChangeling
|
id: ClothingOuterArmorChangeling
|
||||||
@@ -200,3 +205,4 @@
|
|||||||
sprintModifier: 0.65
|
sprintModifier: 0.65
|
||||||
- type: ExplosionResistance
|
- type: ExplosionResistance
|
||||||
damageCoefficient: 0.5
|
damageCoefficient: 0.5
|
||||||
|
- type: GroupExamine
|
||||||
|
|||||||
@@ -73,6 +73,7 @@
|
|||||||
- type: ContainerContainer
|
- type: ContainerContainer
|
||||||
containers:
|
containers:
|
||||||
toggleable-clothing: !type:ContainerSlot {}
|
toggleable-clothing: !type:ContainerSlot {}
|
||||||
|
- type: GroupExamine
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
abstract: true
|
abstract: true
|
||||||
|
|||||||
@@ -481,6 +481,7 @@
|
|||||||
Slash: 0.95
|
Slash: 0.95
|
||||||
Heat: 0.90
|
Heat: 0.90
|
||||||
Radiation: 0.75
|
Radiation: 0.75
|
||||||
|
- type: GroupExamine
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingOuterHardsuitBase
|
parent: ClothingOuterHardsuitBase
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
Piercing: 0.9
|
Piercing: 0.9
|
||||||
Heat: 0.75
|
Heat: 0.75
|
||||||
- type: ExplosionResistance
|
- type: ExplosionResistance
|
||||||
damageCoefficient: 0.65
|
damageCoefficient: 0.65
|
||||||
|
- type: GroupExamine
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingOuterEVASuitBase
|
parent: ClothingOuterEVASuitBase
|
||||||
@@ -59,6 +60,7 @@
|
|||||||
sprintModifier: 0.7
|
sprintModifier: 0.7
|
||||||
- type: TemperatureProtection
|
- type: TemperatureProtection
|
||||||
coefficient: 0.01
|
coefficient: 0.01
|
||||||
|
- type: GroupExamine
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: [ClothingOuterBaseLarge, GeigerCounterClothing]
|
parent: [ClothingOuterBaseLarge, GeigerCounterClothing]
|
||||||
@@ -75,6 +77,7 @@
|
|||||||
Radiation: 0.05
|
Radiation: 0.05
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/OuterClothing/Suits/rad.rsi
|
sprite: Clothing/OuterClothing/Suits/rad.rsi
|
||||||
|
- type: GroupExamine
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingOuterBase
|
parent: ClothingOuterBase
|
||||||
@@ -150,3 +153,4 @@
|
|||||||
- type: ClothingSpeedModifier
|
- type: ClothingSpeedModifier
|
||||||
walkModifier: 0.7
|
walkModifier: 0.7
|
||||||
sprintModifier: 0.75
|
sprintModifier: 0.75
|
||||||
|
- type: GroupExamine
|
||||||
|
|||||||
BIN
Resources/Textures/Interface/examine-star.png
Normal file
BIN
Resources/Textures/Interface/examine-star.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 614 B |
2
Resources/Textures/Interface/examine-star.png.yml
Normal file
2
Resources/Textures/Interface/examine-star.png.yml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
sample:
|
||||||
|
filter: true
|
||||||
Reference in New Issue
Block a user