From 074bb78cbd417a54be2a6b465a51f00f3fb38f02 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Mon, 5 Sep 2016 21:11:08 +0200 Subject: [PATCH 1/5] Made Tooltip trait upgradable --- OpenRA.Game/Traits/Player/FrozenActorLayer.cs | 5 +++-- OpenRA.Mods.Common/Traits/Tooltip.cs | 7 +++---- OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs | 4 +++- .../Widgets/Logic/Editor/ActorSelectorLogic.cs | 4 +++- .../Widgets/Logic/Ingame/ProductionTooltipLogic.cs | 8 ++++++-- OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs | 10 +++++++--- 6 files changed, 25 insertions(+), 13 deletions(-) diff --git a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs index 5e1b6a1f37..d63694c053 100644 --- a/OpenRA.Game/Traits/Player/FrozenActorLayer.cs +++ b/OpenRA.Game/Traits/Player/FrozenActorLayer.cs @@ -40,7 +40,7 @@ namespace OpenRA.Traits public ITooltipInfo TooltipInfo { get; private set; } public Player TooltipOwner { get; private set; } - readonly ITooltip tooltip; + readonly ITooltip[] tooltips; public int HP { get; private set; } public DamageState DamageState { get; private set; } @@ -80,7 +80,7 @@ namespace OpenRA.Traits Bounds = self.Bounds; TargetTypes = self.GetEnabledTargetTypes().ToHashSet(); - tooltip = self.TraitsImplementing().FirstOrDefault(); + tooltips = self.TraitsImplementing().ToArray(); health = self.TraitOrDefault(); UpdateVisibility(); @@ -101,6 +101,7 @@ namespace OpenRA.Traits DamageState = health.DamageState; } + var tooltip = tooltips.FirstOrDefault(Exts.IsTraitEnabled); if (tooltip != null) { TooltipInfo = tooltip.TooltipInfo; diff --git a/OpenRA.Mods.Common/Traits/Tooltip.cs b/OpenRA.Mods.Common/Traits/Tooltip.cs index caf690379f..33dcc8505e 100644 --- a/OpenRA.Mods.Common/Traits/Tooltip.cs +++ b/OpenRA.Mods.Common/Traits/Tooltip.cs @@ -13,11 +13,9 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { - public abstract class TooltipInfoBase : ITraitInfo + public abstract class TooltipInfoBase : UpgradableTraitInfo { [Translate] public readonly string Name = ""; - - public abstract object Create(ActorInitializer init); } [Desc("Shown in map editor.")] @@ -61,7 +59,7 @@ namespace OpenRA.Mods.Common.Traits public bool IsOwnerRowVisible { get { return ShowOwnerRow; } } } - public class Tooltip : ITooltip + public class Tooltip : UpgradableTrait, ITooltip { readonly Actor self; readonly TooltipInfo info; @@ -70,6 +68,7 @@ namespace OpenRA.Mods.Common.Traits public Player Owner { get { return self.Owner; } } public Tooltip(Actor self, TooltipInfo info) + : base(info) { this.self = self; this.info = info; diff --git a/OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs b/OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs index dea7b228e8..b3d8e613a7 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorActorPreview.cs @@ -70,7 +70,9 @@ namespace OpenRA.Mods.Common.Traits Footprint = new ReadOnlyDictionary(footprint); } - var tooltip = Info.TraitInfoOrDefault() as TooltipInfoBase ?? Info.TraitInfoOrDefault(); + var tooltip = Info.TraitInfos().FirstOrDefault(Exts.IsTraitEnabled) as TooltipInfoBase + ?? Info.TraitInfos().FirstOrDefault(Exts.IsTraitEnabled); + Tooltip = (tooltip == null ? " < " + Info.Name + " >" : tooltip.Name) + "\n" + owner.Name + " (" + owner.Faction + ")" + "\nID: " + ID + "\nType: " + Info.Name; diff --git a/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs index a6551e8d80..d64640a873 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Editor/ActorSelectorLogic.cs @@ -132,7 +132,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic item.Bounds.Height = preview.Bounds.Height + 2 * preview.Bounds.Y; item.IsVisible = () => true; - var tooltip = actor.TraitInfoOrDefault() as TooltipInfoBase ?? actor.TraitInfoOrDefault(); + var tooltip = actor.TraitInfos().FirstOrDefault(Exts.IsTraitEnabled) as TooltipInfoBase + ?? actor.TraitInfos().FirstOrDefault(Exts.IsTraitEnabled); + item.GetTooltipText = () => (tooltip == null ? "Type: " : tooltip.Name + "\nType: ") + actor.Name; panel.AddChild(item); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs index 630615e129..23b937b40b 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs @@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (actor == null || actor == lastActor) return; - var tooltip = actor.TraitInfo(); + var tooltip = actor.TraitInfos().First(Exts.IsTraitEnabled); var buildable = actor.TraitInfo(); var cost = actor.TraitInfo().Cost; @@ -115,7 +115,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic { ActorInfo ai; if (rules.Actors.TryGetValue(a.ToLowerInvariant(), out ai) && ai.HasTraitInfo()) - return ai.TraitInfo().Name; + { + var actorTooltip = ai.TraitInfos().FirstOrDefault(Exts.IsTraitEnabled); + if (actorTooltip != null) + return actorTooltip.Name; + } return a; } diff --git a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs index afe88e4fa9..8fc3baafb1 100644 --- a/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ViewportControllerWidget.cs @@ -191,9 +191,13 @@ namespace OpenRA.Mods.Common.Widgets if (underCursor != null) { - ActorTooltip = underCursor.TraitsImplementing().First(); - ActorTooltipExtra = underCursor.TraitsImplementing().ToArray(); - TooltipType = WorldTooltipType.Actor; + ActorTooltip = underCursor.TraitsImplementing().FirstOrDefault(Exts.IsTraitEnabled); + if (ActorTooltip != null) + { + ActorTooltipExtra = underCursor.TraitsImplementing().ToArray(); + TooltipType = WorldTooltipType.Actor; + } + return; } From 4f1e7435c2e6161fc249843464d04ba6aa7eebfd Mon Sep 17 00:00:00 2001 From: reaperrr Date: Mon, 5 Sep 2016 21:15:15 +0200 Subject: [PATCH 2/5] Update tooltip when Tick Tank is deployed --- mods/ts/rules/nod-vehicles.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mods/ts/rules/nod-vehicles.yaml b/mods/ts/rules/nod-vehicles.yaml index 159591692b..0c9d5c8501 100644 --- a/mods/ts/rules/nod-vehicles.yaml +++ b/mods/ts/rules/nod-vehicles.yaml @@ -72,6 +72,12 @@ TTNK: Cost: 800 Tooltip: Name: Tick Tank + UpgradeTypes: deployed + UpgradeMaxEnabledLevel: 0 + Tooltip@DEPLOYED: + Name: Tick Tank (deployed) + UpgradeTypes: deployed + UpgradeMinEnabledLevel: 1 Buildable: Queue: Vehicle BuildPaletteOrder: 60 From 00c01615139ab445d4dd0fd95f4aaec251971b8b Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sun, 23 Oct 2016 14:56:24 +0200 Subject: [PATCH 3/5] Show internal name instead of crashing when buildable actor has no tooltip But throw a lint error instead. --- OpenRA.Mods.Common/Lint/CheckTooltips.cs | 35 +++++++++++++++++++ OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + .../Logic/Ingame/ProductionTooltipLogic.cs | 9 ++--- 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 OpenRA.Mods.Common/Lint/CheckTooltips.cs diff --git a/OpenRA.Mods.Common/Lint/CheckTooltips.cs b/OpenRA.Mods.Common/Lint/CheckTooltips.cs new file mode 100644 index 0000000000..e88bae5602 --- /dev/null +++ b/OpenRA.Mods.Common/Lint/CheckTooltips.cs @@ -0,0 +1,35 @@ +#region Copyright & License Information +/* + * Copyright 2007-2016 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System; +using System.Linq; +using OpenRA.Mods.Common.Traits; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Lint +{ + class CheckTooltips : ILintRulesPass + { + public void Run(Action emitError, Action emitWarning, Ruleset rules) + { + foreach (var actorInfo in rules.Actors) + { + var buildable = actorInfo.Value.TraitInfoOrDefault(); + if (buildable == null) + continue; + + var tooltip = actorInfo.Value.TraitInfos().FirstOrDefault(Exts.IsTraitEnabled); + if (tooltip == null) + emitError("The following buildable actor has no (enabled) Tooltip: " + actorInfo.Key); + } + } + } +} diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 689ba58687..1d45daaa43 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -176,6 +176,7 @@ + diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs index 23b937b40b..a4b769a9eb 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs @@ -55,14 +55,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (actor == null || actor == lastActor) return; - var tooltip = actor.TraitInfos().First(Exts.IsTraitEnabled); + var tooltip = actor.TraitInfos().FirstOrDefault(Exts.IsTraitEnabled); + var name = tooltip != null ? tooltip.Name : actor.Name; var buildable = actor.TraitInfo(); var cost = actor.TraitInfo().Cost; - nameLabel.GetText = () => tooltip.Name; + nameLabel.GetText = () => name; var hotkey = palette.TooltipIcon.Hotkey; - var nameWidth = font.Measure(tooltip.Name).X; + var nameWidth = font.Measure(name).X; var hotkeyText = "({0})".F(hotkey.DisplayString()); var hotkeyWidth = hotkey.IsValid() ? font.Measure(hotkeyText).X + 2 * nameLabel.Bounds.X : 0; hotkeyLabel.GetText = () => hotkeyText; @@ -103,7 +104,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic timeLabel.Bounds.X = powerLabel.Bounds.X = costLabel.Bounds.X = timeIcon.Bounds.Right + iconMargin; widget.Bounds.Width = leftWidth + rightWidth + 3 * nameLabel.Bounds.X + timeIcon.Bounds.Width + iconMargin; - var leftHeight = font.Measure(tooltip.Name).Y + requiresFont.Measure(requiresString).Y + descFont.Measure(descString).Y; + var leftHeight = font.Measure(name).Y + requiresFont.Measure(requiresString).Y + descFont.Measure(descString).Y; var rightHeight = font.Measure(powerString).Y + font.Measure(timeString).Y + font.Measure(costString).Y; widget.Bounds.Height = Math.Max(leftHeight, rightHeight) * 3 / 2 + 3 * nameLabel.Bounds.Y; From 11d2ee80dc5928699780d0218a6e9880421762d8 Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sun, 23 Oct 2016 16:16:26 +0200 Subject: [PATCH 4/5] Upgrade tooltip when Mobile Sensor Array is deployed --- mods/ts/rules/shared-vehicles.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mods/ts/rules/shared-vehicles.yaml b/mods/ts/rules/shared-vehicles.yaml index d50b5de29e..1d31650558 100644 --- a/mods/ts/rules/shared-vehicles.yaml +++ b/mods/ts/rules/shared-vehicles.yaml @@ -114,6 +114,12 @@ LPST: Cost: 950 Tooltip: Name: Mobile Sensor Array + UpgradeTypes: deployed + UpgradeMaxEnabledLevel: 0 + Tooltip@DEPLOYED: + Name: Mobile Sensor Array (deployed) + UpgradeTypes: deployed + UpgradeMinEnabledLevel: 1 Health: HP: 600 Armor: From efa6ad64f7305a83d6ea61994da9052a06649b9a Mon Sep 17 00:00:00 2001 From: reaperrr Date: Sun, 23 Oct 2016 18:42:36 +0200 Subject: [PATCH 5/5] Remove now-redundant TooltipInfo check --- .../Widgets/Logic/Ingame/ProductionTooltipLogic.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs index a4b769a9eb..9a7243ca9d 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ProductionTooltipLogic.cs @@ -115,7 +115,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic static string ActorName(Ruleset rules, string a) { ActorInfo ai; - if (rules.Actors.TryGetValue(a.ToLowerInvariant(), out ai) && ai.HasTraitInfo()) + if (rules.Actors.TryGetValue(a.ToLowerInvariant(), out ai)) { var actorTooltip = ai.TraitInfos().FirstOrDefault(Exts.IsTraitEnabled); if (actorTooltip != null)